diff options
author | Jean Delvare <khali@linux-fr.org> | 2009-05-13 15:48:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-16 17:21:11 -0400 |
commit | c668f32dca105d876e51862a003a302fa61e4ae4 (patch) | |
tree | 5a71742ecd4e6a1c48f77977e5e2f6d129ffb566 /drivers/media/video/ir-kbd-i2c.c | |
parent | 1df8e9861cf9fac5737ccb61c7f7fefa77711d40 (diff) |
V4L/DVB (11844): ir-kbd-i2c: Switch to the new-style device binding model
Let card drivers probe for IR receiver devices and instantiate them if
found. Ultimately it would be better if we could stop probing
completely, but I suspect this won't be possible for all card types.
There's certainly room for cleanups. For example, some drivers are
sharing I2C adapter IDs, so they also had to share the list of I2C
addresses being probed for an IR receiver. Now that each driver
explicitly says which addresses should be probed, maybe some addresses
can be dropped from some drivers.
Also, the special cases in saa7134-i2c should probably be handled on a
per-board basis. This would be more efficient and less risky than always
probing extra addresses on all boards. I'll give it a try later.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 200 |
1 files changed, 34 insertions, 166 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index ba341e6fb2da..cb833a63041c 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -74,7 +74,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, | |||
74 | int start, range, toggle, dev, code, ircode; | 74 | int start, range, toggle, dev, code, ircode; |
75 | 75 | ||
76 | /* poll IR chip */ | 76 | /* poll IR chip */ |
77 | if (size != i2c_master_recv(&ir->c,buf,size)) | 77 | if (size != i2c_master_recv(ir->c, buf, size)) |
78 | return -EIO; | 78 | return -EIO; |
79 | 79 | ||
80 | /* split rc5 data block ... */ | 80 | /* split rc5 data block ... */ |
@@ -137,7 +137,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
137 | unsigned char b; | 137 | unsigned char b; |
138 | 138 | ||
139 | /* poll IR chip */ | 139 | /* poll IR chip */ |
140 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 140 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
141 | dprintk(1,"read error\n"); | 141 | dprintk(1,"read error\n"); |
142 | return -EIO; | 142 | return -EIO; |
143 | } | 143 | } |
@@ -151,7 +151,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
151 | unsigned char b; | 151 | unsigned char b; |
152 | 152 | ||
153 | /* poll IR chip */ | 153 | /* poll IR chip */ |
154 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 154 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
155 | dprintk(1,"read error\n"); | 155 | dprintk(1,"read error\n"); |
156 | return -EIO; | 156 | return -EIO; |
157 | } | 157 | } |
@@ -171,7 +171,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
171 | unsigned char buf[4]; | 171 | unsigned char buf[4]; |
172 | 172 | ||
173 | /* poll IR chip */ | 173 | /* poll IR chip */ |
174 | if (4 != i2c_master_recv(&ir->c,buf,4)) { | 174 | if (4 != i2c_master_recv(ir->c, buf, 4)) { |
175 | dprintk(1,"read error\n"); | 175 | dprintk(1,"read error\n"); |
176 | return -EIO; | 176 | return -EIO; |
177 | } | 177 | } |
@@ -195,7 +195,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
195 | unsigned char b; | 195 | unsigned char b; |
196 | 196 | ||
197 | /* poll IR chip */ | 197 | /* poll IR chip */ |
198 | if (1 != i2c_master_recv(&ir->c,&b,1)) { | 198 | if (1 != i2c_master_recv(ir->c, &b, 1)) { |
199 | dprintk(1,"read error\n"); | 199 | dprintk(1,"read error\n"); |
200 | return -EIO; | 200 | return -EIO; |
201 | } | 201 | } |
@@ -222,12 +222,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
222 | u32 *ir_key, u32 *ir_raw) | 222 | u32 *ir_key, u32 *ir_raw) |
223 | { | 223 | { |
224 | unsigned char subaddr, key, keygroup; | 224 | unsigned char subaddr, key, keygroup; |
225 | struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0, | 225 | struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, |
226 | .buf = &subaddr, .len = 1}, | 226 | .buf = &subaddr, .len = 1}, |
227 | { .addr = ir->c.addr, .flags = I2C_M_RD, | 227 | { .addr = ir->c->addr, .flags = I2C_M_RD, |
228 | .buf = &key, .len = 1} }; | 228 | .buf = &key, .len = 1} }; |
229 | subaddr = 0x0d; | 229 | subaddr = 0x0d; |
230 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 230 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
231 | dprintk(1, "read error\n"); | 231 | dprintk(1, "read error\n"); |
232 | return -EIO; | 232 | return -EIO; |
233 | } | 233 | } |
@@ -237,7 +237,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, | |||
237 | 237 | ||
238 | subaddr = 0x0b; | 238 | subaddr = 0x0b; |
239 | msg[1].buf = &keygroup; | 239 | msg[1].buf = &keygroup; |
240 | if (2 != i2c_transfer(ir->c.adapter, msg, 2)) { | 240 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { |
241 | dprintk(1, "read error\n"); | 241 | dprintk(1, "read error\n"); |
242 | return -EIO; | 242 | return -EIO; |
243 | } | 243 | } |
@@ -286,7 +286,7 @@ static void ir_work(struct work_struct *work) | |||
286 | 286 | ||
287 | /* MSI TV@nywhere Plus requires more frequent polling | 287 | /* MSI TV@nywhere Plus requires more frequent polling |
288 | otherwise it will miss some keypresses */ | 288 | otherwise it will miss some keypresses */ |
289 | if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30) | 289 | if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30) |
290 | polling_interval = 50; | 290 | polling_interval = 50; |
291 | 291 | ||
292 | ir_key_poll(ir); | 292 | ir_key_poll(ir); |
@@ -295,34 +295,15 @@ static void ir_work(struct work_struct *work) | |||
295 | 295 | ||
296 | /* ----------------------------------------------------------------------- */ | 296 | /* ----------------------------------------------------------------------- */ |
297 | 297 | ||
298 | static int ir_attach(struct i2c_adapter *adap, int addr, | 298 | static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) |
299 | unsigned short flags, int kind); | ||
300 | static int ir_detach(struct i2c_client *client); | ||
301 | static int ir_probe(struct i2c_adapter *adap); | ||
302 | |||
303 | static struct i2c_driver driver = { | ||
304 | .driver = { | ||
305 | .name = "ir-kbd-i2c", | ||
306 | }, | ||
307 | .id = I2C_DRIVERID_INFRARED, | ||
308 | .attach_adapter = ir_probe, | ||
309 | .detach_client = ir_detach, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_client client_template = | ||
313 | { | ||
314 | .name = "unset", | ||
315 | .driver = &driver | ||
316 | }; | ||
317 | |||
318 | static int ir_attach(struct i2c_adapter *adap, int addr, | ||
319 | unsigned short flags, int kind) | ||
320 | { | 299 | { |
321 | IR_KEYTAB_TYPE *ir_codes = NULL; | 300 | IR_KEYTAB_TYPE *ir_codes = NULL; |
322 | char *name; | 301 | char *name; |
323 | int ir_type; | 302 | int ir_type; |
324 | struct IR_i2c *ir; | 303 | struct IR_i2c *ir; |
325 | struct input_dev *input_dev; | 304 | struct input_dev *input_dev; |
305 | struct i2c_adapter *adap = client->adapter; | ||
306 | unsigned short addr = client->addr; | ||
326 | int err; | 307 | int err; |
327 | 308 | ||
328 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); | 309 | ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); |
@@ -332,14 +313,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
332 | goto err_out_free; | 313 | goto err_out_free; |
333 | } | 314 | } |
334 | 315 | ||
335 | ir->c = client_template; | 316 | ir->c = client; |
336 | ir->input = input_dev; | 317 | ir->input = input_dev; |
337 | 318 | i2c_set_clientdata(client, ir); | |
338 | ir->c.adapter = adap; | ||
339 | ir->c.addr = addr; | ||
340 | snprintf(ir->c.name, sizeof(ir->c.name), "ir-kbd"); | ||
341 | |||
342 | i2c_set_clientdata(&ir->c, ir); | ||
343 | 319 | ||
344 | switch(addr) { | 320 | switch(addr) { |
345 | case 0x64: | 321 | case 0x64: |
@@ -414,24 +390,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
414 | snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); | 390 | snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); |
415 | ir->ir_codes = ir_codes; | 391 | ir->ir_codes = ir_codes; |
416 | 392 | ||
417 | /* register i2c device | ||
418 | * At device register, IR codes may be changed to be | ||
419 | * board dependent. | ||
420 | */ | ||
421 | err = i2c_attach_client(&ir->c); | ||
422 | if (err) | ||
423 | goto err_out_free; | ||
424 | |||
425 | /* If IR not supported or disabled, unregisters driver */ | ||
426 | if (ir->get_key == NULL) { | ||
427 | err = -ENODEV; | ||
428 | goto err_out_detach; | ||
429 | } | ||
430 | |||
431 | /* Phys addr can only be set after attaching (for ir->c.dev) */ | ||
432 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 393 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
433 | dev_name(&ir->c.adapter->dev), | 394 | dev_name(&adap->dev), |
434 | dev_name(&ir->c.dev)); | 395 | dev_name(&client->dev)); |
435 | 396 | ||
436 | /* init + register input device */ | 397 | /* init + register input device */ |
437 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); | 398 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
@@ -441,7 +402,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
441 | 402 | ||
442 | err = input_register_device(ir->input); | 403 | err = input_register_device(ir->input); |
443 | if (err) | 404 | if (err) |
444 | goto err_out_detach; | 405 | goto err_out_free; |
445 | 406 | ||
446 | printk(DEVNAME ": %s detected at %s [%s]\n", | 407 | printk(DEVNAME ": %s detected at %s [%s]\n", |
447 | ir->input->name, ir->input->phys, adap->name); | 408 | ir->input->name, ir->input->phys, adap->name); |
@@ -452,135 +413,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
452 | 413 | ||
453 | return 0; | 414 | return 0; |
454 | 415 | ||
455 | err_out_detach: | ||
456 | i2c_detach_client(&ir->c); | ||
457 | err_out_free: | 416 | err_out_free: |
458 | input_free_device(input_dev); | 417 | input_free_device(input_dev); |
459 | kfree(ir); | 418 | kfree(ir); |
460 | return err; | 419 | return err; |
461 | } | 420 | } |
462 | 421 | ||
463 | static int ir_detach(struct i2c_client *client) | 422 | static int ir_remove(struct i2c_client *client) |
464 | { | 423 | { |
465 | struct IR_i2c *ir = i2c_get_clientdata(client); | 424 | struct IR_i2c *ir = i2c_get_clientdata(client); |
466 | 425 | ||
467 | /* kill outstanding polls */ | 426 | /* kill outstanding polls */ |
468 | cancel_delayed_work_sync(&ir->work); | 427 | cancel_delayed_work_sync(&ir->work); |
469 | 428 | ||
470 | /* unregister devices */ | 429 | /* unregister device */ |
471 | input_unregister_device(ir->input); | 430 | input_unregister_device(ir->input); |
472 | i2c_detach_client(&ir->c); | ||
473 | 431 | ||
474 | /* free memory */ | 432 | /* free memory */ |
475 | kfree(ir); | 433 | kfree(ir); |
476 | return 0; | 434 | return 0; |
477 | } | 435 | } |
478 | 436 | ||
479 | static int ir_probe(struct i2c_adapter *adap) | 437 | static const struct i2c_device_id ir_kbd_id[] = { |
480 | { | 438 | /* Generic entry for any IR receiver */ |
481 | 439 | { "ir_video", 0 }, | |
482 | /* The external IR receiver is at i2c address 0x34 (0x35 for | 440 | /* IR device specific entries could be added here */ |
483 | reads). Future Hauppauge cards will have an internal | 441 | { } |
484 | receiver at 0x30 (0x31 for reads). In theory, both can be | 442 | }; |
485 | fitted, and Hauppauge suggest an external overrides an | ||
486 | internal. | ||
487 | |||
488 | That's why we probe 0x1a (~0x34) first. CB | ||
489 | */ | ||
490 | |||
491 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | ||
492 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 }; | ||
493 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
494 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; | ||
495 | static const int probe_cx23885[] = { 0x6b, -1 }; | ||
496 | const int *probe; | ||
497 | struct i2c_msg msg = { | ||
498 | .flags = I2C_M_RD, | ||
499 | .len = 0, | ||
500 | .buf = NULL, | ||
501 | }; | ||
502 | int i, rc; | ||
503 | |||
504 | switch (adap->id) { | ||
505 | case I2C_HW_B_BT848: | ||
506 | probe = probe_bttv; | ||
507 | break; | ||
508 | case I2C_HW_B_CX2341X: | ||
509 | probe = probe_bttv; | ||
510 | break; | ||
511 | case I2C_HW_SAA7134: | ||
512 | probe = probe_saa7134; | ||
513 | break; | ||
514 | case I2C_HW_B_EM28XX: | ||
515 | probe = probe_em28XX; | ||
516 | break; | ||
517 | case I2C_HW_B_CX2388x: | ||
518 | probe = probe_cx88; | ||
519 | break; | ||
520 | case I2C_HW_B_CX23885: | ||
521 | probe = probe_cx23885; | ||
522 | break; | ||
523 | default: | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | for (i = 0; -1 != probe[i]; i++) { | ||
528 | msg.addr = probe[i]; | ||
529 | rc = i2c_transfer(adap, &msg, 1); | ||
530 | dprintk(1,"probe 0x%02x @ %s: %s\n", | ||
531 | probe[i], adap->name, | ||
532 | (1 == rc) ? "yes" : "no"); | ||
533 | if (1 == rc) { | ||
534 | ir_attach(adap, probe[i], 0, 0); | ||
535 | return 0; | ||
536 | } | ||
537 | } | ||
538 | |||
539 | /* Special case for MSI TV@nywhere Plus remote */ | ||
540 | if (adap->id == I2C_HW_SAA7134) { | ||
541 | u8 temp; | ||
542 | |||
543 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
544 | respond to probes unless we read something from | ||
545 | an existing device. Weird... */ | ||
546 | |||
547 | msg.addr = 0x50; | ||
548 | rc = i2c_transfer(adap, &msg, 1); | ||
549 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
550 | msg.addr, adap->name, | ||
551 | (1 == rc) ? "yes" : "no"); | ||
552 | |||
553 | /* Now do the probe. The controller does not respond | ||
554 | to 0-byte reads, so we use a 1-byte read instead. */ | ||
555 | msg.addr = 0x30; | ||
556 | msg.len = 1; | ||
557 | msg.buf = &temp; | ||
558 | rc = i2c_transfer(adap, &msg, 1); | ||
559 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
560 | msg.addr, adap->name, | ||
561 | (1 == rc) ? "yes" : "no"); | ||
562 | if (1 == rc) | ||
563 | ir_attach(adap, msg.addr, 0, 0); | ||
564 | } | ||
565 | |||
566 | /* Special case for AVerMedia Cardbus remote */ | ||
567 | if (adap->id == I2C_HW_SAA7134) { | ||
568 | unsigned char subaddr, data; | ||
569 | struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, | ||
570 | .buf = &subaddr, .len = 1}, | ||
571 | { .addr = 0x40, .flags = I2C_M_RD, | ||
572 | .buf = &data, .len = 1} }; | ||
573 | subaddr = 0x0d; | ||
574 | rc = i2c_transfer(adap, msg, 2); | ||
575 | dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", | ||
576 | msg[0].addr, subaddr, adap->name, | ||
577 | (2 == rc) ? "yes" : "no"); | ||
578 | if (2 == rc) | ||
579 | ir_attach(adap, msg[0].addr, 0, 0); | ||
580 | } | ||
581 | 443 | ||
582 | return 0; | 444 | static struct i2c_driver driver = { |
583 | } | 445 | .driver = { |
446 | .name = "ir-kbd-i2c", | ||
447 | }, | ||
448 | .probe = ir_probe, | ||
449 | .remove = ir_remove, | ||
450 | .id_table = ir_kbd_id, | ||
451 | }; | ||
584 | 452 | ||
585 | /* ----------------------------------------------------------------------- */ | 453 | /* ----------------------------------------------------------------------- */ |
586 | 454 | ||