diff options
Diffstat (limited to 'drivers/media/video/ir-kbd-i2c.c')
-rw-r--r-- | drivers/media/video/ir-kbd-i2c.c | 222 |
1 files changed, 54 insertions, 168 deletions
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 092c7da0f37a..86f2fefe1edf 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 | const char *name = NULL; |
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,13 +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 | |||
341 | i2c_set_clientdata(&ir->c, ir); | ||
342 | 319 | ||
343 | switch(addr) { | 320 | switch(addr) { |
344 | case 0x64: | 321 | case 0x64: |
@@ -403,44 +380,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
403 | ir_codes = ir_codes_avermedia_cardbus; | 380 | ir_codes = ir_codes_avermedia_cardbus; |
404 | break; | 381 | break; |
405 | default: | 382 | default: |
406 | /* shouldn't happen */ | 383 | dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr); |
407 | printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr); | ||
408 | err = -ENODEV; | 384 | err = -ENODEV; |
409 | goto err_out_free; | 385 | goto err_out_free; |
410 | } | 386 | } |
411 | 387 | ||
412 | /* Sets name */ | 388 | /* Let the caller override settings */ |
413 | snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); | 389 | if (client->dev.platform_data) { |
414 | ir->ir_codes = ir_codes; | 390 | const struct IR_i2c_init_data *init_data = |
391 | client->dev.platform_data; | ||
415 | 392 | ||
416 | /* register i2c device | 393 | ir_codes = init_data->ir_codes; |
417 | * At device register, IR codes may be changed to be | 394 | name = init_data->name; |
418 | * board dependent. | 395 | ir->get_key = init_data->get_key; |
419 | */ | 396 | } |
420 | err = i2c_attach_client(&ir->c); | ||
421 | if (err) | ||
422 | goto err_out_free; | ||
423 | 397 | ||
424 | /* If IR not supported or disabled, unregisters driver */ | 398 | /* Make sure we are all setup before going on */ |
425 | if (ir->get_key == NULL) { | 399 | if (!name || !ir->get_key || !ir_codes) { |
400 | dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n", | ||
401 | addr); | ||
426 | err = -ENODEV; | 402 | err = -ENODEV; |
427 | goto err_out_detach; | 403 | goto err_out_free; |
428 | } | 404 | } |
429 | 405 | ||
430 | /* Phys addr can only be set after attaching (for ir->c.dev) */ | 406 | /* Sets name */ |
407 | snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name); | ||
408 | ir->ir_codes = ir_codes; | ||
409 | |||
431 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", | 410 | snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", |
432 | dev_name(&ir->c.adapter->dev), | 411 | dev_name(&adap->dev), |
433 | dev_name(&ir->c.dev)); | 412 | dev_name(&client->dev)); |
434 | 413 | ||
435 | /* init + register input device */ | 414 | /* init + register input device */ |
436 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); | 415 | ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes); |
437 | input_dev->id.bustype = BUS_I2C; | 416 | input_dev->id.bustype = BUS_I2C; |
438 | input_dev->name = ir->c.name; | 417 | input_dev->name = ir->name; |
439 | input_dev->phys = ir->phys; | 418 | input_dev->phys = ir->phys; |
440 | 419 | ||
441 | err = input_register_device(ir->input); | 420 | err = input_register_device(ir->input); |
442 | if (err) | 421 | if (err) |
443 | goto err_out_detach; | 422 | goto err_out_free; |
444 | 423 | ||
445 | printk(DEVNAME ": %s detected at %s [%s]\n", | 424 | printk(DEVNAME ": %s detected at %s [%s]\n", |
446 | ir->input->name, ir->input->phys, adap->name); | 425 | ir->input->name, ir->input->phys, adap->name); |
@@ -451,135 +430,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
451 | 430 | ||
452 | return 0; | 431 | return 0; |
453 | 432 | ||
454 | err_out_detach: | ||
455 | i2c_detach_client(&ir->c); | ||
456 | err_out_free: | 433 | err_out_free: |
457 | input_free_device(input_dev); | 434 | input_free_device(input_dev); |
458 | kfree(ir); | 435 | kfree(ir); |
459 | return err; | 436 | return err; |
460 | } | 437 | } |
461 | 438 | ||
462 | static int ir_detach(struct i2c_client *client) | 439 | static int ir_remove(struct i2c_client *client) |
463 | { | 440 | { |
464 | struct IR_i2c *ir = i2c_get_clientdata(client); | 441 | struct IR_i2c *ir = i2c_get_clientdata(client); |
465 | 442 | ||
466 | /* kill outstanding polls */ | 443 | /* kill outstanding polls */ |
467 | cancel_delayed_work_sync(&ir->work); | 444 | cancel_delayed_work_sync(&ir->work); |
468 | 445 | ||
469 | /* unregister devices */ | 446 | /* unregister device */ |
470 | input_unregister_device(ir->input); | 447 | input_unregister_device(ir->input); |
471 | i2c_detach_client(&ir->c); | ||
472 | 448 | ||
473 | /* free memory */ | 449 | /* free memory */ |
474 | kfree(ir); | 450 | kfree(ir); |
475 | return 0; | 451 | return 0; |
476 | } | 452 | } |
477 | 453 | ||
478 | static int ir_probe(struct i2c_adapter *adap) | 454 | static const struct i2c_device_id ir_kbd_id[] = { |
479 | { | 455 | /* Generic entry for any IR receiver */ |
480 | 456 | { "ir_video", 0 }, | |
481 | /* The external IR receiver is at i2c address 0x34 (0x35 for | 457 | /* IR device specific entries could be added here */ |
482 | reads). Future Hauppauge cards will have an internal | 458 | { } |
483 | receiver at 0x30 (0x31 for reads). In theory, both can be | 459 | }; |
484 | fitted, and Hauppauge suggest an external overrides an | ||
485 | internal. | ||
486 | |||
487 | That's why we probe 0x1a (~0x34) first. CB | ||
488 | */ | ||
489 | |||
490 | static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; | ||
491 | static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 }; | ||
492 | static const int probe_em28XX[] = { 0x30, 0x47, -1 }; | ||
493 | static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 }; | ||
494 | static const int probe_cx23885[] = { 0x6b, -1 }; | ||
495 | const int *probe; | ||
496 | struct i2c_msg msg = { | ||
497 | .flags = I2C_M_RD, | ||
498 | .len = 0, | ||
499 | .buf = NULL, | ||
500 | }; | ||
501 | int i, rc; | ||
502 | |||
503 | switch (adap->id) { | ||
504 | case I2C_HW_B_BT848: | ||
505 | probe = probe_bttv; | ||
506 | break; | ||
507 | case I2C_HW_B_CX2341X: | ||
508 | probe = probe_bttv; | ||
509 | break; | ||
510 | case I2C_HW_SAA7134: | ||
511 | probe = probe_saa7134; | ||
512 | break; | ||
513 | case I2C_HW_B_EM28XX: | ||
514 | probe = probe_em28XX; | ||
515 | break; | ||
516 | case I2C_HW_B_CX2388x: | ||
517 | probe = probe_cx88; | ||
518 | break; | ||
519 | case I2C_HW_B_CX23885: | ||
520 | probe = probe_cx23885; | ||
521 | break; | ||
522 | default: | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | for (i = 0; -1 != probe[i]; i++) { | ||
527 | msg.addr = probe[i]; | ||
528 | rc = i2c_transfer(adap, &msg, 1); | ||
529 | dprintk(1,"probe 0x%02x @ %s: %s\n", | ||
530 | probe[i], adap->name, | ||
531 | (1 == rc) ? "yes" : "no"); | ||
532 | if (1 == rc) { | ||
533 | ir_attach(adap, probe[i], 0, 0); | ||
534 | return 0; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | /* Special case for MSI TV@nywhere Plus remote */ | ||
539 | if (adap->id == I2C_HW_SAA7134) { | ||
540 | u8 temp; | ||
541 | |||
542 | /* MSI TV@nywhere Plus controller doesn't seem to | ||
543 | respond to probes unless we read something from | ||
544 | an existing device. Weird... */ | ||
545 | |||
546 | msg.addr = 0x50; | ||
547 | rc = i2c_transfer(adap, &msg, 1); | ||
548 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
549 | msg.addr, adap->name, | ||
550 | (1 == rc) ? "yes" : "no"); | ||
551 | |||
552 | /* Now do the probe. The controller does not respond | ||
553 | to 0-byte reads, so we use a 1-byte read instead. */ | ||
554 | msg.addr = 0x30; | ||
555 | msg.len = 1; | ||
556 | msg.buf = &temp; | ||
557 | rc = i2c_transfer(adap, &msg, 1); | ||
558 | dprintk(1, "probe 0x%02x @ %s: %s\n", | ||
559 | msg.addr, adap->name, | ||
560 | (1 == rc) ? "yes" : "no"); | ||
561 | if (1 == rc) | ||
562 | ir_attach(adap, msg.addr, 0, 0); | ||
563 | } | ||
564 | |||
565 | /* Special case for AVerMedia Cardbus remote */ | ||
566 | if (adap->id == I2C_HW_SAA7134) { | ||
567 | unsigned char subaddr, data; | ||
568 | struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0, | ||
569 | .buf = &subaddr, .len = 1}, | ||
570 | { .addr = 0x40, .flags = I2C_M_RD, | ||
571 | .buf = &data, .len = 1} }; | ||
572 | subaddr = 0x0d; | ||
573 | rc = i2c_transfer(adap, msg, 2); | ||
574 | dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n", | ||
575 | msg[0].addr, subaddr, adap->name, | ||
576 | (2 == rc) ? "yes" : "no"); | ||
577 | if (2 == rc) | ||
578 | ir_attach(adap, msg[0].addr, 0, 0); | ||
579 | } | ||
580 | 460 | ||
581 | return 0; | 461 | static struct i2c_driver driver = { |
582 | } | 462 | .driver = { |
463 | .name = "ir-kbd-i2c", | ||
464 | }, | ||
465 | .probe = ir_probe, | ||
466 | .remove = ir_remove, | ||
467 | .id_table = ir_kbd_id, | ||
468 | }; | ||
583 | 469 | ||
584 | /* ----------------------------------------------------------------------- */ | 470 | /* ----------------------------------------------------------------------- */ |
585 | 471 | ||