blob: 109e7db3442062a8639cc8febf721db08909084c [file] [log] [blame]
/* Copyright (C) 2021-2022 Mediatek Inc. */
#include "atenl.h"
int atenl_reg_read(struct atenl *an, u32 offset, u32 *res)
{
char dir[64], buf[16];
unsigned long val;
int fd, ret;
/* write offset into regidx */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regidx",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", offset);
if (snprintf_error(sizeof(buf), ret))
goto out;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
close(fd);
/* read value from regval */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regval",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_RDONLY);
if (fd < 0)
return fd;
ret = read(fd, buf, sizeof(buf) - 1);
if (ret < 0)
goto out;
buf[ret] = 0;
val = strtoul(buf, NULL, 16);
if (val > (u32) -1)
return -EINVAL;
*res = val;
ret = 0;
out:
close(fd);
return ret;
}
int atenl_reg_write(struct atenl *an, u32 offset, u32 val)
{
char dir[64], buf[16];
int fd, ret;
/* write offset into regidx */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regidx",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", offset);
if (snprintf_error(sizeof(buf), ret))
goto out;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
close(fd);
/* write value into regval */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regval",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", val);
if (snprintf_error(sizeof(buf), ret))
goto out;
buf[ret] = 0;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
ret = 0;
out:
close(fd);
return ret;
}
int atenl_rf_read(struct atenl *an, u32 wf_sel, u32 offset, u32 *res)
{
char dir[64], buf[16];
unsigned long val;
int fd, ret;
u32 regidx;
/* merge wf_sel and offset into regidx */
regidx = FIELD_PREP(GENMASK(31, 28), wf_sel) |
FIELD_PREP(GENMASK(27, 0), offset);
/* write regidx */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regidx",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", regidx);
if (snprintf_error(sizeof(buf), ret))
goto out;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
close(fd);
/* read from rf_regval */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/rf_regval",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_RDONLY);
if (fd < 0)
return fd;
ret = read(fd, buf, sizeof(buf) - 1);
if (ret < 0)
goto out;
buf[ret] = 0;
val = strtoul(buf, NULL, 16);
if (val > (u32) -1)
return -EINVAL;
*res = val;
ret = 0;
out:
close(fd);
return ret;
}
int atenl_rf_write(struct atenl *an, u32 wf_sel, u32 offset, u32 val)
{
char dir[64], buf[16];
int fd, ret;
u32 regidx;
/* merge wf_sel and offset into regidx */
regidx = FIELD_PREP(GENMASK(31, 28), wf_sel) |
FIELD_PREP(GENMASK(27, 0), offset);
/* write regidx */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/regidx",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", regidx);
if (snprintf_error(sizeof(buf), ret))
goto out;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
close(fd);
/* write value into rf_val */
ret = snprintf(dir, sizeof(dir),
"/sys/kernel/debug/ieee80211/phy%d/mt76/rf_regval",
an->main_phy_idx);
if (snprintf_error(sizeof(dir), ret))
return ret;
fd = open(dir, O_WRONLY);
if (fd < 0)
return fd;
ret = snprintf(buf, sizeof(buf), "0x%x", val);
if (snprintf_error(sizeof(buf), ret))
goto out;
buf[ret] = 0;
lseek(fd, 0, SEEK_SET);
write(fd, buf, sizeof(buf));
ret = 0;
out:
close(fd);
return ret;
}