-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrf_sysfs.c
183 lines (161 loc) · 6.79 KB
/
rf_sysfs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "rf_sysfs.h"
#include "rf_module.h"
ssize_t show_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
int off = 0;
u8 reg;
u8 regval[5];
for (reg = CONFIG_REG; reg <= FIFO_STATUS_REG; reg++) {
switch (reg) {
case CONFIG_REG:
case EN_AA_REG:
case EN_RXADDR_REG:
case SETUP_AW_REG :
case SETUP_RETR_REG:
case RF_CH_REG:
case RF_SETUP_REG:
case STATUS_REG:
case OBSERVE_TX_REG:
case CD_REG:
case RX_PW_P0_REG:
case RX_PW_P1_REG:
case RX_PW_P2_REG:
case RX_PW_P3_REG:
case RX_PW_P4_REG:
case RX_PW_P5_REG:
case FIFO_STATUS_REG:
case RX_ADDR_P2_REG:
case RX_ADDR_P3_REG:
case RX_ADDR_P4_REG:
case RX_ADDR_P5_REG:
read_reg(spi, reg, regval, 1);
off += scnprintf(buf + off, PAGE_SIZE - off, "%02x:%02x\n", reg, regval[0]);
break;
case TX_ADDR_REG:
case RX_ADDR_P0_REG:
case RX_ADDR_P1_REG:
do {
u8 aw;
read_reg(spi, SETUP_AW_REG, &aw, 1);
aw += 2;
read_reg(spi, reg, regval, 5);
switch (aw) {
case 3:
off += scnprintf(buf + off, PAGE_SIZE - off, "%02x:%02x%02x%02x\n", reg,
regval[0], regval[1], regval[2]);
break;
case 4:
off += scnprintf(buf + off, PAGE_SIZE - off, "%02x:%02x%02x%02x%02x\n", reg,
regval[0], regval[1], regval[2], regval[3]);
break;
case 5:
off += scnprintf(buf + off, PAGE_SIZE - off, "%02x:%02x%02x%02x%02x%02x\n", reg,
regval[0], regval[1], regval[2], regval[3], regval[4]);
break;
}
} while (0);
break;
default:
_DEBUG("Unknwon register addr %02x", reg);
break;
}
}
for (reg = DYNPD_REG; reg <= FEATURE_REG; reg++) {
read_reg(spi, reg, regval, 1);
off += scnprintf(buf + off, PAGE_SIZE - off, "%02x:%02x\n", reg, regval[0]);
}
return off;
}
ssize_t store_reg(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
#ifdef DEBUG
int i;
int rval;
u8 regaddr;
/* The maximum allowed is 5 bytes, used in setting TX_ADDR for example
* for each byte in string we have 2 chars, (e.g. FF) so 10 chars, plus 1 for '\0'*/
char regval_str[11];
int rvlen;
char hexstr[3]; /* hold hexadecimal strings for a while */
u8 regval[5];
rval = sscanf(buf, "%hhx:%11s", ®addr, regval_str);
if (rval != 2) {
dev_err(dev, "%s: Bad format. Use REG_ADDR:REG_VAL", attr->attr.name);
return -EINVAL;
}
rvlen = strlen(regval_str) / 2;
for (i = 0; i < rvlen; i++) {
sscanf(®val_str[i*2], "%2s", hexstr);
sscanf(hexstr, "%hhx", ®val[i]);
}
write_reg(to_spi_device(dev), regaddr, regval, rvlen);
return count;
#else
return -ENOSYS;
#endif
}
ssize_t show_statistics(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = to_spi_device(dev);
struct rf_data *rf = spi_get_drvdata(spi);
return snprintf(buf, PAGE_SIZE,
"TX kbps: %5lu\n"
"RX kbps: %5lu\n"
"TX count: %5lu\n"
"RX count: %5lu\n",
rf->tx_kbps,
rf->rx_kbps,
rf->txcount,
rf->rxcount);
}
ssize_t show_config(struct device *dev, struct device_attribute *attr, char *buf)
{
u8 regval;
unsigned off = 0;
struct spi_device *spi = to_spi_device(dev);
read_reg(spi, RF_SETUP_REG, ®val, 1);
if (IS_SETTED(BIT(5), regval))
off += snprintf(buf + off, PAGE_SIZE - off,
"Data rate: 250kbps\n");
else if (IS_SETTED(BIT(3), regval))
off += snprintf(buf + off, PAGE_SIZE - off,
"Data rate: 2mbps\n");
else
off += snprintf(buf + off, PAGE_SIZE - off,
"Data rate: 1mbps\n");
switch ((regval & 0x6) >> 1) { /* get bit 1 and 2 */
case 0: /* 00 */
off += snprintf(buf + off, PAGE_SIZE - off,
"Outputpower: -18dBm\n");
break;
case 1: /* 01 */
off += snprintf(buf + off, PAGE_SIZE - off,
"Outputpower: -12dBm\n");
break;
case 2: /* 10 */
off += snprintf(buf + off, PAGE_SIZE - off,
"Outputpower: -6dBm\n");
break;
case 3: /* 11 */
off += snprintf(buf + off, PAGE_SIZE - off,
"Outputpower: 0dBm\n");
break;
}
read_reg(spi, RF_CH_REG, ®val, 1);
off += snprintf(buf + off, PAGE_SIZE - off,
"Channel: %u\n", regval);
read_reg(spi, SETUP_AW_REG, ®val, 1);
off += snprintf(buf + off, PAGE_SIZE - off,
"Address width: %u\n", regval + 2);
read_reg(spi, FEATURE_REG, ®val, 1);
off += snprintf(buf + off, PAGE_SIZE - off,
"EN_DPL: %u\n"
"EN_ACK_PAY: %u\n"
"EN_DYN_ACK: %u\n",
(IS_SETTED(BIT(2), regval) ? 1 : 0),
(IS_SETTED(BIT(1), regval) ? 1 : 0),
(IS_SETTED(BIT(0), regval) ? 1 : 0));
return off;
}