diff options
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 166 |
1 files changed, 58 insertions, 108 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9703d3d351f9..0085567a1421 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * Christoph Bartelmus <lirc@bartelmus.de> | 8 | * Christoph Bartelmus <lirc@bartelmus.de> |
9 | * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by | 9 | * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by |
10 | * Ulrich Mueller <ulrich.mueller42@web.de> | 10 | * Ulrich Mueller <ulrich.mueller42@web.de> |
11 | * modified for em2820 based USB TV tuners by | ||
12 | * Markus Rechberger <mrechberger@gmail.com> | ||
11 | * | 13 | * |
12 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
@@ -37,10 +39,9 @@ | |||
37 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
38 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
39 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
40 | |||
41 | #include <asm/semaphore.h> | 42 | #include <asm/semaphore.h> |
42 | |||
43 | #include <media/ir-common.h> | 43 | #include <media/ir-common.h> |
44 | #include <media/ir-kbd-i2c.h> | ||
44 | 45 | ||
45 | /* Mark Phalan <phalanm@o2.ie> */ | 46 | /* Mark Phalan <phalanm@o2.ie> */ |
46 | static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | 47 | static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { |
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { | |||
81 | [ 28 ] = KEY_MEDIA, /* PC/TV */ | 82 | [ 28 ] = KEY_MEDIA, /* PC/TV */ |
82 | }; | 83 | }; |
83 | 84 | ||
84 | static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = { | ||
85 | [ 0x3 ] = KEY_POWER, | ||
86 | [ 0x6f ] = KEY_MUTE, | ||
87 | [ 0x10 ] = KEY_BACKSPACE, /* Recall */ | ||
88 | |||
89 | [ 0x11 ] = KEY_KP0, | ||
90 | [ 0x4 ] = KEY_KP1, | ||
91 | [ 0x5 ] = KEY_KP2, | ||
92 | [ 0x6 ] = KEY_KP3, | ||
93 | [ 0x8 ] = KEY_KP4, | ||
94 | [ 0x9 ] = KEY_KP5, | ||
95 | [ 0xa ] = KEY_KP6, | ||
96 | [ 0xc ] = KEY_KP7, | ||
97 | [ 0xd ] = KEY_KP8, | ||
98 | [ 0xe ] = KEY_KP9, | ||
99 | [ 0x12 ] = KEY_KPDOT, /* 100+ */ | ||
100 | |||
101 | [ 0x7 ] = KEY_VOLUMEUP, | ||
102 | [ 0xb ] = KEY_VOLUMEDOWN, | ||
103 | [ 0x1a ] = KEY_KPPLUS, | ||
104 | [ 0x18 ] = KEY_KPMINUS, | ||
105 | [ 0x15 ] = KEY_UP, | ||
106 | [ 0x1d ] = KEY_DOWN, | ||
107 | [ 0xf ] = KEY_CHANNELUP, | ||
108 | [ 0x13 ] = KEY_CHANNELDOWN, | ||
109 | [ 0x48 ] = KEY_ZOOM, | ||
110 | |||
111 | [ 0x1b ] = KEY_VIDEO, /* Video source */ | ||
112 | [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */ | ||
113 | [ 0x19 ] = KEY_SEARCH, /* Auto Scan */ | ||
114 | |||
115 | [ 0x4b ] = KEY_RECORD, | ||
116 | [ 0x46 ] = KEY_PLAY, | ||
117 | [ 0x45 ] = KEY_PAUSE, /* Pause */ | ||
118 | [ 0x44 ] = KEY_STOP, | ||
119 | [ 0x40 ] = KEY_FORWARD, /* Forward ? */ | ||
120 | [ 0x42 ] = KEY_REWIND, /* Backward ? */ | ||
121 | |||
122 | }; | ||
123 | |||
124 | struct IR { | ||
125 | struct i2c_client c; | ||
126 | struct input_dev *input; | ||
127 | struct ir_input_state ir; | ||
128 | |||
129 | struct work_struct work; | ||
130 | struct timer_list timer; | ||
131 | char phys[32]; | ||
132 | int (*get_key)(struct IR*, u32*, u32*); | ||
133 | }; | ||
134 | |||
135 | /* ----------------------------------------------------------------------- */ | 85 | /* ----------------------------------------------------------------------- */ |
136 | /* insmod parameters */ | 86 | /* insmod parameters */ |
137 | 87 | ||
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */ | |||
144 | 94 | ||
145 | /* ----------------------------------------------------------------------- */ | 95 | /* ----------------------------------------------------------------------- */ |
146 | 96 | ||
147 | static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 97 | static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
148 | { | 98 | { |
149 | unsigned char buf[3]; | 99 | unsigned char buf[3]; |
150 | int start, toggle, dev, code; | 100 | int start, toggle, dev, code; |
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
171 | return 1; | 121 | return 1; |
172 | } | 122 | } |
173 | 123 | ||
174 | static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 124 | static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
175 | { | 125 | { |
176 | unsigned char b; | 126 | unsigned char b; |
177 | 127 | ||
178 | /* poll IR chip */ | 128 | /* poll IR chip */ |
179 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 129 | if (1 != i2c_master_recv(&ir->c,&b,1)) { |
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
185 | return 1; | 135 | return 1; |
186 | } | 136 | } |
187 | 137 | ||
188 | static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 138 | static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
189 | { | 139 | { |
190 | unsigned char b; | 140 | unsigned char b; |
191 | 141 | ||
192 | /* poll IR chip */ | 142 | /* poll IR chip */ |
193 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 143 | if (1 != i2c_master_recv(&ir->c,&b,1)) { |
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
205 | return 1; | 155 | return 1; |
206 | } | 156 | } |
207 | 157 | ||
208 | static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | 158 | static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
209 | { | 159 | { |
210 | unsigned char b; | 160 | unsigned char b; |
211 | 161 | ||
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
216 | } | 166 | } |
217 | 167 | ||
218 | /* it seems that 0xFE indicates that a button is still hold | 168 | /* it seems that 0xFE indicates that a button is still hold |
219 | down, while 0xFF indicates that no button is hold | 169 | down, while 0xff indicates that no button is hold |
220 | down. 0xFE sequences are sometimes interrupted by 0xFF */ | 170 | down. 0xfe sequences are sometimes interrupted by 0xFF */ |
221 | 171 | ||
222 | dprintk(2,"key %02x\n", b); | 172 | dprintk(2,"key %02x\n", b); |
223 | 173 | ||
224 | if (b == 0xFF) | 174 | if (b == 0xff) |
225 | return 0; | 175 | return 0; |
226 | 176 | ||
227 | if (b == 0xFE) | 177 | if (b == 0xfe) |
228 | /* keep old data */ | 178 | /* keep old data */ |
229 | return 1; | 179 | return 1; |
230 | 180 | ||
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) | |||
233 | return 1; | 183 | return 1; |
234 | } | 184 | } |
235 | 185 | ||
236 | static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw) | ||
237 | { | ||
238 | unsigned char b; | ||
239 | |||
240 | /* poll IR chip */ | ||
241 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | ||
242 | dprintk(1,"read error\n"); | ||
243 | return -EIO; | ||
244 | } | ||
245 | |||
246 | /* no button press */ | ||
247 | if (b==0) | ||
248 | return 0; | ||
249 | |||
250 | /* repeating */ | ||
251 | if (b & 0x80) | ||
252 | return 1; | ||
253 | |||
254 | *ir_key = b; | ||
255 | *ir_raw = b; | ||
256 | return 1; | ||
257 | } | ||
258 | /* ----------------------------------------------------------------------- */ | 186 | /* ----------------------------------------------------------------------- */ |
259 | 187 | ||
260 | static void ir_key_poll(struct IR *ir) | 188 | static void ir_key_poll(struct IR_i2c *ir) |
261 | { | 189 | { |
262 | static u32 ir_key, ir_raw; | 190 | static u32 ir_key, ir_raw; |
263 | int rc; | 191 | int rc; |
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir) | |||
278 | 206 | ||
279 | static void ir_timer(unsigned long data) | 207 | static void ir_timer(unsigned long data) |
280 | { | 208 | { |
281 | struct IR *ir = (struct IR*)data; | 209 | struct IR_i2c *ir = (struct IR_i2c*)data; |
282 | schedule_work(&ir->work); | 210 | schedule_work(&ir->work); |
283 | } | 211 | } |
284 | 212 | ||
285 | static void ir_work(void *data) | 213 | static void ir_work(void *data) |
286 | { | 214 | { |
287 | struct IR *ir = data; | 215 | struct IR_i2c *ir = data; |
288 | ir_key_poll(ir); | 216 | ir_key_poll(ir); |
289 | mod_timer(&ir->timer, jiffies+HZ/10); | 217 | mod_timer(&ir->timer, jiffies+HZ/10); |
290 | } | 218 | } |
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client); | |||
297 | static int ir_probe(struct i2c_adapter *adap); | 225 | static int ir_probe(struct i2c_adapter *adap); |
298 | 226 | ||
299 | static struct i2c_driver driver = { | 227 | static struct i2c_driver driver = { |
300 | .name = "ir remote kbd driver", | 228 | .name = "ir remote kbd driver", |
301 | .id = I2C_DRIVERID_EXP3, /* FIXME */ | 229 | .id = I2C_DRIVERID_EXP3, /* FIXME */ |
302 | .flags = I2C_DF_NOTIFY, | 230 | .flags = I2C_DF_NOTIFY, |
303 | .attach_adapter = ir_probe, | 231 | .attach_adapter = ir_probe, |
304 | .detach_client = ir_detach, | 232 | .detach_client = ir_detach, |
305 | }; | 233 | }; |
306 | 234 | ||
307 | static struct i2c_client client_template = | 235 | static struct i2c_client client_template = |
308 | { | 236 | { |
309 | .name = "unset", | 237 | .name = "unset", |
310 | .driver = &driver | 238 | .driver = &driver |
311 | }; | 239 | }; |
312 | 240 | ||
313 | static int ir_attach(struct i2c_adapter *adap, int addr, | 241 | static int ir_attach(struct i2c_adapter *adap, int addr, |
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
316 | IR_KEYTAB_TYPE *ir_codes = NULL; | 244 | IR_KEYTAB_TYPE *ir_codes = NULL; |
317 | char *name; | 245 | char *name; |
318 | int ir_type; | 246 | int ir_type; |
319 | struct IR *ir; | 247 | struct IR_i2c *ir; |
320 | struct input_dev *input_dev; | 248 | struct input_dev *input_dev; |
321 | 249 | ||
322 | ir = kzalloc(sizeof(struct IR), GFP_KERNEL); | 250 | ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL); |
323 | input_dev = input_allocate_device(); | 251 | input_dev = input_allocate_device(); |
324 | if (!ir || !input_dev) { | 252 | if (!ir || !input_dev) { |
325 | kfree(ir); | 253 | kfree(ir); |
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
361 | ir_codes = ir_codes_empty; | 289 | ir_codes = ir_codes_empty; |
362 | break; | 290 | break; |
363 | case 0x7a: | 291 | case 0x7a: |
364 | name = "Purple TV"; | 292 | case 0x47: |
365 | ir->get_key = get_key_purpletv; | 293 | /* Handled by saa7134-input */ |
294 | name = "SAA713x remote"; | ||
366 | ir_type = IR_TYPE_OTHER; | 295 | ir_type = IR_TYPE_OTHER; |
367 | ir_codes = ir_codes_purpletv; | ||
368 | break; | 296 | break; |
369 | default: | 297 | default: |
370 | /* shouldn't happen */ | 298 | /* shouldn't happen */ |
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
373 | return -1; | 301 | return -1; |
374 | } | 302 | } |
375 | 303 | ||
376 | /* register i2c device */ | 304 | /* Sets name */ |
377 | i2c_attach_client(&ir->c); | ||
378 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 305 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); |
306 | ir->ir_codes=ir_codes; | ||
307 | |||
308 | /* register i2c device | ||
309 | * At device register, IR codes may be changed to be | ||
310 | * board dependent. | ||
311 | */ | ||
312 | i2c_attach_client(&ir->c); | ||
313 | |||
314 | /* If IR not supported or disabled, unregisters driver */ | ||
315 | if (ir->get_key == NULL) { | ||
316 | i2c_detach_client(&ir->c); | ||
317 | kfree(ir); | ||
318 | return -1; | ||
319 | } | ||
320 | |||
321 | /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */ | ||
379 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 322 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
380 | ir->c.adapter->dev.bus_id, | 323 | ir->c.adapter->dev.bus_id, |
381 | ir->c.dev.bus_id); | 324 | ir->c.dev.bus_id); |
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
386 | input_dev->name = ir->c.name; | 329 | input_dev->name = ir->c.name; |
387 | input_dev->phys = ir->phys; | 330 | input_dev->phys = ir->phys; |
388 | 331 | ||
332 | /* register event device */ | ||
389 | input_register_device(ir->input); | 333 | input_register_device(ir->input); |
390 | 334 | ||
391 | /* start polling via eventd */ | 335 | /* start polling via eventd */ |
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
400 | 344 | ||
401 | static int ir_detach(struct i2c_client *client) | 345 | static int ir_detach(struct i2c_client *client) |
402 | { | 346 | { |
403 | struct IR *ir = i2c_get_clientdata(client); | 347 | struct IR_i2c *ir = i2c_get_clientdata(client); |
404 | 348 | ||
405 | /* kill outstanding polls */ | 349 | /* kill outstanding polls */ |
406 | del_timer(&ir->timer); | 350 | del_timer(&ir->timer); |
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap) | |||
428 | */ | 372 | */ |
429 | 373 | ||
430 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | 374 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; |
431 | static const int probe_saa7134[] = { 0x7a, -1 }; | 375 | static const int probe_saa7134[] = { 0x7a, 0x47, -1 }; |
376 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
432 | const int *probe = NULL; | 377 | const int *probe = NULL; |
433 | struct i2c_client c; char buf; int i,rc; | 378 | struct i2c_client c; |
379 | unsigned char buf; | ||
380 | int i,rc; | ||
434 | 381 | ||
435 | switch (adap->id) { | 382 | switch (adap->id) { |
436 | case I2C_HW_B_BT848: | 383 | case I2C_HW_B_BT848: |
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap) | |||
439 | case I2C_HW_SAA7134: | 386 | case I2C_HW_SAA7134: |
440 | probe = probe_saa7134; | 387 | probe = probe_saa7134; |
441 | break; | 388 | break; |
389 | case I2C_HW_B_EM28XX: | ||
390 | probe = probe_em28XX; | ||
391 | break; | ||
442 | } | 392 | } |
443 | if (NULL == probe) | 393 | if (NULL == probe) |
444 | return 0; | 394 | return 0; |
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap) | |||
447 | c.adapter = adap; | 397 | c.adapter = adap; |
448 | for (i = 0; -1 != probe[i]; i++) { | 398 | for (i = 0; -1 != probe[i]; i++) { |
449 | c.addr = probe[i]; | 399 | c.addr = probe[i]; |
450 | rc = i2c_master_recv(&c,&buf,1); | 400 | rc = i2c_master_recv(&c,&buf,0); |
451 | dprintk(1,"probe 0x%02x @ %s: %s\n", | 401 | dprintk(1,"probe 0x%02x @ %s: %s\n", |
452 | probe[i], adap->name, | 402 | probe[i], adap->name, |
453 | (1 == rc) ? "yes" : "no"); | 403 | (0 == rc) ? "yes" : "no"); |
454 | if (1 == rc) { | 404 | if (0 == rc) { |
455 | ir_attach(adap,probe[i],0,0); | 405 | ir_attach(adap,probe[i],0,0); |
456 | break; | 406 | break; |
457 | } | 407 | } |