omap24xx cbus: fix ioctls
[openwrt/openwrt.git] / target / linux / omap24xx / patches-2.6.36 / 510-retu-tahvo-user-debugging.patch
1 ---
2 drivers/cbus/Kconfig | 8 +++
3 drivers/cbus/retu-user.c | 117 +++++++++++++++++++++++++++++++++++++++++++++-
4 drivers/cbus/tahvo-user.c | 75 +++++++++++++++++++++++++++++
5 3 files changed, 198 insertions(+), 2 deletions(-)
6
7 --- linux-2.6.36-rc4.orig/drivers/cbus/Kconfig
8 +++ linux-2.6.36-rc4/drivers/cbus/Kconfig
9 @@ -28,6 +28,10 @@ config CBUS_TAHVO_USER
10 If you want support for Tahvo's user space read/write etc. functions,
11 you should say Y here.
12
13 +config CBUS_TAHVO_USER_DEBUG
14 + depends on CBUS_TAHVO_USER
15 + bool "Enable Tahvo user space interface debugging"
16 +
17 config CBUS_TAHVO_USB
18 depends on CBUS_TAHVO && USB
19 tristate "Support for Tahvo USB transceiver"
20 @@ -56,6 +60,10 @@ config CBUS_RETU_USER
21 If you want support for Retu's user space read/write etc. functions,
22 you should say Y here.
23
24 +config CBUS_RETU_USER_DEBUG
25 + depends on CBUS_RETU_USER
26 + bool "Enable Retu user space interface debugging"
27 +
28 config CBUS_RETU_POWERBUTTON
29 depends on CBUS_RETU
30 bool "Support for Retu power button"
31 --- linux-2.6.36-rc4.orig/drivers/cbus/retu-user.c
32 +++ linux-2.6.36-rc4/drivers/cbus/retu-user.c
33 @@ -46,6 +46,12 @@
34
35 #define PFX "retu-user: "
36
37 +#ifdef CONFIG_CBUS_RETU_USER_DEBUG
38 +# define dprintk(fmt, x...) printk(KERN_DEBUG PFX fmt, x)
39 +#else
40 +# define dprintk(fmt, x...) do { } while (0)
41 +#endif
42 +
43 /* Bitmap for marking the interrupt sources as having the handlers */
44 static u32 retu_irq_bits;
45
46 @@ -105,6 +111,94 @@ static const u8 retu_access_bits[] = {
47 3
48 };
49
50 +#ifdef CONFIG_CBUS_RETU_USER_DEBUG
51 +static const char * reg_access_text(unsigned int reg)
52 +{
53 + if (WARN_ON(reg >= ARRAY_SIZE(retu_access_bits)))
54 + return "X";
55 + switch (retu_access_bits[reg]) {
56 + case READ_ONLY:
57 + return "R";
58 + case WRITE_ONLY:
59 + return "W";
60 + case READ_WRITE:
61 + return "RW";
62 + case TOGGLE:
63 + return "T";
64 + }
65 + return "X";
66 +}
67 +
68 +static const char * reg_name(unsigned int reg)
69 +{
70 + static const char *names[] = {
71 + [RETU_REG_ASICR] = "ASIC ID & revision",
72 + [RETU_REG_IDR] = "Interrupt ID",
73 + [RETU_REG_IMR] = "Interrupt mask",
74 + [RETU_REG_RTCDSR] = "RTC seconds register",
75 + [RETU_REG_RTCHMR] = "RTC hours and minutes register",
76 + [RETU_REG_RTCHMAR] = "hours and minutes alarm and time set register",
77 + [RETU_REG_RTCCALR] = "RTC calibration register",
78 + [RETU_REG_ADCR] = "ADC result",
79 + [RETU_REG_ADCSCR] = "ADC sample ctrl",
80 + [RETU_REG_CC1] = "Common control register 1",
81 + [RETU_REG_CC2] = "Common control register 2",
82 + [RETU_REG_CTRL_CLR] = "Regulator clear register",
83 + [RETU_REG_CTRL_SET] = "Regulator set register",
84 + [RETU_REG_STATUS] = "Status register",
85 + [RETU_REG_WATCHDOG] = "Watchdog register",
86 + [RETU_REG_AUDTXR] = "Audio Codec Tx register",
87 + [0x14] = "Charger detect?",
88 + };
89 + const char *name;
90 +
91 + if (reg >= ARRAY_SIZE(names))
92 + return "";
93 + name = names[reg];
94 + if (!name)
95 + return "";
96 + return name;
97 +}
98 +
99 +static const char * adc_chan_name(unsigned int chan)
100 +{
101 + static const char *names[] = {
102 + [0x05] = "Headset hook detect",
103 + };
104 + const char *name;
105 +
106 + if (chan >= ARRAY_SIZE(names))
107 + return "";
108 + name = names[chan];
109 + if (!name)
110 + return "";
111 + return name;
112 +}
113 +
114 +static const char * retu_irq_name(unsigned int id)
115 +{
116 + static const char *names[] = {
117 + [RETU_INT_PWR] = "Power",
118 + [RETU_INT_CHAR] = "Char",
119 + [RETU_INT_RTCS] = "RTCS",
120 + [RETU_INT_RTCM] = "RTCM",
121 + [RETU_INT_RTCD] = "RTCD",
122 + [RETU_INT_RTCA] = "RTCA",
123 + [RETU_INT_HOOK] = "Hook",
124 + [RETU_INT_HEAD] = "Head",
125 + [RETU_INT_ADCS] = "ADC timer",
126 + };
127 + const char *name;
128 +
129 + if (id >= ARRAY_SIZE(names))
130 + return "";
131 + name = names[id];
132 + if (!name)
133 + return "";
134 + return name;
135 +}
136 +#endif
137 +
138 /*
139 * The handler for all RETU interrupts.
140 *
141 @@ -157,6 +251,8 @@ static int retu_user_subscribe_to_irq(in
142 /* Mark that this interrupt has a handler */
143 retu_irq_bits |= 1 << id;
144
145 + dprintk("Subscribed to IRQ %d (%s)\n", id, retu_irq_name(id));
146 +
147 return 0;
148 }
149
150 @@ -216,6 +312,10 @@ static int retu_user_write_with_mask(u32
151
152 /* Generate new value */
153 tmp = (tmp & ~MASK(field)) | (value & MASK(field));
154 +
155 + dprintk("{WRITE %s} 0x%02X(%s) <= msk 0x%04X, val 0x%04X ==> res 0x%04X\n",
156 + reg_name(reg), reg, reg_access_text(reg), MASK(field), value, tmp);
157 +
158 /* Write data to RETU */
159 retu_write_reg(reg, tmp);
160 spin_unlock_irqrestore(&retu_lock, flags);
161 @@ -244,6 +344,9 @@ static u32 retu_user_read_with_mask(u32
162 /* Read the register */
163 value = retu_read_reg(reg) & mask;
164
165 + dprintk("{READ %s} 0x%02X(%s) <= msk 0x%04X ==> res 0x%04X\n",
166 + reg_name(reg), reg, reg_access_text(reg), mask, value);
167 +
168 /* Right justify value */
169 while (!(mask & 1)) {
170 value = value >> 1;
171 @@ -273,7 +376,7 @@ static int retu_close(struct inode *inod
172 static long retu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
173 {
174 struct retu_tahvo_write_parms par;
175 - int ret;
176 + int ret, result;
177
178 switch (cmd) {
179 case URT_IOCT_IRQ_SUBSCR:
180 @@ -290,7 +393,15 @@ static long retu_ioctl(struct file *filp
181 printk(KERN_ERR "copy_to_user failed: %d\n", ret);
182 break;
183 case RETU_IOCH_ADC_READ:
184 - return retu_read_adc(arg);
185 + result = retu_read_adc(arg);
186 + if (result >= 0) {
187 + dprintk("{READ-ADC %s} chan 0x%02lX ==> result 0x%04X\n",
188 + adc_chan_name(arg), arg, result);
189 + } else {
190 + dprintk("{READ-ADC %s} chan 0x%02lX ==> failed %d\n",
191 + adc_chan_name(arg), arg, result);
192 + }
193 + return result;
194 default:
195 return -ENOIOCTLCMD;
196 }
197 @@ -332,6 +443,8 @@ static ssize_t retu_read(struct file *fi
198 list_move(&irq->node, &retu_irqs_reserve);
199 spin_unlock_irqrestore(&retu_irqs_lock, flags);
200
201 + dprintk("{IRQ %s} %d delivered\n", retu_irq_name(irq_id), (int)irq_id);
202 +
203 ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
204 sizeof(irq_id));
205 if (ret)
206 --- linux-2.6.36-rc4.orig/drivers/cbus/tahvo-user.c
207 +++ linux-2.6.36-rc4/drivers/cbus/tahvo-user.c
208 @@ -46,6 +46,12 @@
209
210 #define PFX "tahvo-user: "
211
212 +#ifdef CONFIG_CBUS_TAHVO_USER_DEBUG
213 +# define dprintk(fmt, x...) printk(KERN_DEBUG PFX fmt, x)
214 +#else
215 +# define dprintk(fmt, x...) do { } while (0)
216 +#endif
217 +
218 /* Bitmap for marking the interrupt sources as having the handlers */
219 static u32 tahvo_irq_bits;
220
221 @@ -87,6 +93,64 @@ static const u8 tahvo_access_bits[] = {
222 1
223 };
224
225 +#ifdef CONFIG_CBUS_TAHVO_USER_DEBUG
226 +static const char * reg_access_text(unsigned int reg)
227 +{
228 + if (WARN_ON(reg >= ARRAY_SIZE(tahvo_access_bits)))
229 + return "X";
230 + switch (tahvo_access_bits[reg]) {
231 + case READ_ONLY:
232 + return "R";
233 + case WRITE_ONLY:
234 + return "W";
235 + case READ_WRITE:
236 + return "RW";
237 + case TOGGLE:
238 + return "T";
239 + }
240 + return "X";
241 +}
242 +
243 +static const char * reg_name(unsigned int reg)
244 +{
245 + static const char *names[] = {
246 + [TAHVO_REG_ASICR] = "ASIC ID & revision",
247 + [TAHVO_REG_IDR] = "Interrupt ID",
248 + [TAHVO_REG_IDSR] = "Interrupt status",
249 + [TAHVO_REG_IMR] = "Interrupt mask",
250 + [TAHVO_REG_LEDPWMR] = "LED PWM",
251 + [TAHVO_REG_USBR] = "USB control",
252 + [0x04] = "Charge current control?",
253 + [0x08] = "Charge ctl 1?",
254 + [0x0C] = "Charge ctl 2?",
255 + [0x0D] = "Battery current ADC?",
256 + };
257 + const char *name;
258 +
259 + if (reg >= ARRAY_SIZE(names))
260 + return "";
261 + name = names[reg];
262 + if (!name)
263 + return "";
264 + return name;
265 +}
266 +
267 +static const char * tahvo_irq_name(unsigned int id)
268 +{
269 + static const char *names[] = {
270 + [TAHVO_INT_VBUSON] = "VBUSON",
271 + };
272 + const char *name;
273 +
274 + if (id >= ARRAY_SIZE(names))
275 + return "";
276 + name = names[id];
277 + if (!name)
278 + return "";
279 + return name;
280 +}
281 +#endif
282 +
283 /*
284 * The handler for all TAHVO interrupts.
285 *
286 @@ -142,6 +206,8 @@ static int tahvo_user_subscribe_to_irq(i
287 /* Mark that this interrupt has a handler */
288 tahvo_irq_bits |= 1 << id;
289
290 + dprintk("Subscribed to IRQ %d (%s)\n", id, tahvo_irq_name(id));
291 +
292 return 0;
293 }
294
295 @@ -200,6 +266,10 @@ static int tahvo_user_write_with_mask(u3
296 }
297 /* Generate a new value */
298 tmp = (tmp & ~MASK(field)) | (value & MASK(field));
299 +
300 + dprintk("{WRITE %s} 0x%02X(%s) <= msk 0x%04X, val 0x%04X ==> res 0x%04X\n",
301 + reg_name(reg), reg, reg_access_text(reg), MASK(field), value, tmp);
302 +
303 /* Write data to TAHVO */
304 tahvo_write_reg(reg, tmp);
305 spin_unlock_irqrestore(&tahvo_lock, flags);
306 @@ -228,6 +298,9 @@ static u32 tahvo_user_read_with_mask(u32
307 /* Read the register */
308 value = tahvo_read_reg(reg) & mask;
309
310 + dprintk("{READ %s} 0x%02X(%s) <= msk 0x%04X ==> res 0x%04X\n",
311 + reg_name(reg), reg, reg_access_text(reg), mask, value);
312 +
313 /* Right justify value */
314 while (!(mask & 1)) {
315 value = value >> 1;
316 @@ -314,6 +387,8 @@ static ssize_t tahvo_read(struct file *f
317 list_move(&irq->node, &tahvo_irqs_reserve);
318 spin_unlock_irqrestore(&tahvo_irqs_lock, flags);
319
320 + dprintk("{IRQ %s} %d delivered\n", tahvo_irq_name(irq_id), (int)irq_id);
321 +
322 ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
323 sizeof(irq_id));
324 if (ret)