aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorFrank Schaefer <fschaefer.oss@googlemail.com>2013-03-26 12:38:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-28 16:37:45 -0400
commita3ea4bf98bc8499e64b619808fcca09ca3eb4e2f (patch)
tree0e4e41e215a6008bd6f0131a7dd90350223f9147 /drivers/media/usb
parent80f23305ba43f9eda9596092735bffc283b9ae8d (diff)
[media] em28xx: add support for em25xx i2c bus B read/write/check device operations
The webcam "SpeedLink VAD Laplace" (em2765 + ov2640) uses a special algorithm for i2c communication with the sensor, which is connected to a second i2c bus. We don't know yet how to find out which devices support/use it. It's very likely used by all em25xx and em276x+ bridges. Tests with other em28xx chips (em2820, em2882/em2883) show, that this algorithm always succeeds there although no slave device is connected. The algorithm likely also works for real i2c client devices (OV2640 uses SCCB), because the Windows driver seems to use it for probing Samsung and Kodak sensors. Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c8
-rw-r--r--drivers/media/usb/em28xx/em28xx-i2c.c236
-rw-r--r--drivers/media/usb/em28xx/em28xx.h10
3 files changed, 212 insertions, 42 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index cb7cdd322702..033b6cb5fbe8 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -3139,15 +3139,19 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
3139 rt_mutex_init(&dev->i2c_bus_lock); 3139 rt_mutex_init(&dev->i2c_bus_lock);
3140 3140
3141 /* register i2c bus 0 */ 3141 /* register i2c bus 0 */
3142 retval = em28xx_i2c_register(dev, 0); 3142 if (dev->board.is_em2800)
3143 retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM2800);
3144 else
3145 retval = em28xx_i2c_register(dev, 0, EM28XX_I2C_ALGO_EM28XX);
3143 if (retval < 0) { 3146 if (retval < 0) {
3144 em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n", 3147 em28xx_errdev("%s: em28xx_i2c_register bus 0 - error [%d]!\n",
3145 __func__, retval); 3148 __func__, retval);
3146 goto unregister_dev; 3149 goto unregister_dev;
3147 } 3150 }
3148 3151
3152 /* register i2c bus 1 */
3149 if (dev->def_i2c_bus) { 3153 if (dev->def_i2c_bus) {
3150 retval = em28xx_i2c_register(dev, 1); 3154 retval = em28xx_i2c_register(dev, 1, EM28XX_I2C_ALGO_EM28XX);
3151 if (retval < 0) { 3155 if (retval < 0) {
3152 em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n", 3156 em28xx_errdev("%s: em28xx_i2c_register bus 1 - error [%d]!\n",
3153 __func__, retval); 3157 __func__, retval);
diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c
index 704f283d34ab..4851cc2e4a4d 100644
--- a/drivers/media/usb/em28xx/em28xx-i2c.c
+++ b/drivers/media/usb/em28xx/em28xx-i2c.c
@@ -5,6 +5,7 @@
5 Markus Rechberger <mrechberger@gmail.com> 5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@infradead.org> 6 Mauro Carvalho Chehab <mchehab@infradead.org>
7 Sascha Sommer <saschasommer@freenet.de> 7 Sascha Sommer <saschasommer@freenet.de>
8 Copyright (C) 2013 Frank Schäfer <fschaefer.oss@googlemail.com>
8 9
9 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
@@ -279,6 +280,183 @@ static int em28xx_i2c_check_for_device(struct em28xx *dev, u16 addr)
279} 280}
280 281
281/* 282/*
283 * em25xx_bus_B_send_bytes
284 * write bytes to the i2c device
285 */
286static int em25xx_bus_B_send_bytes(struct em28xx *dev, u16 addr, u8 *buf,
287 u16 len)
288{
289 int ret;
290
291 if (len < 1 || len > 64)
292 return -EOPNOTSUPP;
293 /*
294 * NOTE: limited by the USB ctrl message constraints
295 * Zero length reads always succeed, even if no device is connected
296 */
297
298 /* Set register and write value */
299 ret = dev->em28xx_write_regs_req(dev, 0x06, addr, buf, len);
300 if (ret != len) {
301 if (ret < 0) {
302 em28xx_warn("writing to i2c device at 0x%x failed (error=%i)\n",
303 addr, ret);
304 return ret;
305 } else {
306 em28xx_warn("%i bytes write to i2c device at 0x%x requested, but %i bytes written\n",
307 len, addr, ret);
308 return -EIO;
309 }
310 }
311 /* Check success */
312 ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
313 /*
314 * NOTE: the only error we've seen so far is
315 * 0x01 when the slave device is not present
316 */
317 if (!ret)
318 return len;
319 else if (ret > 0)
320 return -ENODEV;
321
322 return ret;
323 /*
324 * NOTE: With chip types (other chip IDs) which actually don't support
325 * this operation, it seems to succeed ALWAYS ! (even if there is no
326 * slave device or even no second i2c bus provided)
327 */
328}
329
330/*
331 * em25xx_bus_B_recv_bytes
332 * read bytes from the i2c device
333 */
334static int em25xx_bus_B_recv_bytes(struct em28xx *dev, u16 addr, u8 *buf,
335 u16 len)
336{
337 int ret;
338
339 if (len < 1 || len > 64)
340 return -EOPNOTSUPP;
341 /*
342 * NOTE: limited by the USB ctrl message constraints
343 * Zero length reads always succeed, even if no device is connected
344 */
345
346 /* Read value */
347 ret = dev->em28xx_read_reg_req_len(dev, 0x06, addr, buf, len);
348 if (ret < 0) {
349 em28xx_warn("reading from i2c device at 0x%x failed (error=%i)\n",
350 addr, ret);
351 return ret;
352 }
353 /*
354 * NOTE: some devices with two i2c busses have the bad habit to return 0
355 * bytes if we are on bus B AND there was no write attempt to the
356 * specified slave address before AND no device is present at the
357 * requested slave address.
358 * Anyway, the next check will fail with -ENODEV in this case, so avoid
359 * spamming the system log on device probing and do nothing here.
360 */
361
362 /* Check success */
363 ret = dev->em28xx_read_reg_req(dev, 0x08, 0x0000);
364 /*
365 * NOTE: the only error we've seen so far is
366 * 0x01 when the slave device is not present
367 */
368 if (!ret)
369 return len;
370 else if (ret > 0)
371 return -ENODEV;
372
373 return ret;
374 /*
375 * NOTE: With chip types (other chip IDs) which actually don't support
376 * this operation, it seems to succeed ALWAYS ! (even if there is no
377 * slave device or even no second i2c bus provided)
378 */
379}
380
381/*
382 * em25xx_bus_B_check_for_device()
383 * check if there is a i2c device at the supplied address
384 */
385static int em25xx_bus_B_check_for_device(struct em28xx *dev, u16 addr)
386{
387 u8 buf;
388 int ret;
389
390 ret = em25xx_bus_B_recv_bytes(dev, addr, &buf, 1);
391 if (ret < 0)
392 return ret;
393
394 return 0;
395 /*
396 * NOTE: With chips which do not support this operation,
397 * it seems to succeed ALWAYS ! (even if no device connected)
398 */
399}
400
401static inline int i2c_check_for_device(struct em28xx_i2c_bus *i2c_bus, u16 addr)
402{
403 struct em28xx *dev = i2c_bus->dev;
404 int rc = -EOPNOTSUPP;
405
406 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
407 rc = em28xx_i2c_check_for_device(dev, addr);
408 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
409 rc = em2800_i2c_check_for_device(dev, addr);
410 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
411 rc = em25xx_bus_B_check_for_device(dev, addr);
412 if (rc == -ENODEV) {
413 if (i2c_debug)
414 printk(" no device\n");
415 }
416 return rc;
417}
418
419static inline int i2c_recv_bytes(struct em28xx_i2c_bus *i2c_bus,
420 struct i2c_msg msg)
421{
422 struct em28xx *dev = i2c_bus->dev;
423 u16 addr = msg.addr << 1;
424 int byte, rc = -EOPNOTSUPP;
425
426 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
427 rc = em28xx_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
428 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
429 rc = em2800_i2c_recv_bytes(dev, addr, msg.buf, msg.len);
430 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
431 rc = em25xx_bus_B_recv_bytes(dev, addr, msg.buf, msg.len);
432 if (i2c_debug) {
433 for (byte = 0; byte < msg.len; byte++)
434 printk(" %02x", msg.buf[byte]);
435 }
436 return rc;
437}
438
439static inline int i2c_send_bytes(struct em28xx_i2c_bus *i2c_bus,
440 struct i2c_msg msg, int stop)
441{
442 struct em28xx *dev = i2c_bus->dev;
443 u16 addr = msg.addr << 1;
444 int byte, rc = -EOPNOTSUPP;
445
446 if (i2c_debug) {
447 for (byte = 0; byte < msg.len; byte++)
448 printk(" %02x", msg.buf[byte]);
449 }
450 if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX)
451 rc = em28xx_i2c_send_bytes(dev, addr, msg.buf, msg.len, stop);
452 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800)
453 rc = em2800_i2c_send_bytes(dev, addr, msg.buf, msg.len);
454 else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)
455 rc = em25xx_bus_B_send_bytes(dev, addr, msg.buf, msg.len);
456 return rc;
457}
458
459/*
282 * em28xx_i2c_xfer() 460 * em28xx_i2c_xfer()
283 * the main i2c transfer function 461 * the main i2c transfer function
284 */ 462 */
@@ -288,7 +466,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
288 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 466 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
289 struct em28xx *dev = i2c_bus->dev; 467 struct em28xx *dev = i2c_bus->dev;
290 unsigned bus = i2c_bus->bus; 468 unsigned bus = i2c_bus->bus;
291 int addr, rc, i, byte; 469 int addr, rc, i;
292 u8 reg; 470 u8 reg;
293 471
294 rc = rt_mutex_trylock(&dev->i2c_bus_lock); 472 rc = rt_mutex_trylock(&dev->i2c_bus_lock);
@@ -296,7 +474,8 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
296 return rc; 474 return rc;
297 475
298 /* Switch I2C bus if needed */ 476 /* Switch I2C bus if needed */
299 if (bus != dev->cur_i2c_bus) { 477 if (bus != dev->cur_i2c_bus &&
478 i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) {
300 if (bus == 1) 479 if (bus == 1)
301 reg = EM2874_I2C_SECONDARY_BUS_SELECT; 480 reg = EM2874_I2C_SECONDARY_BUS_SELECT;
302 else 481 else
@@ -319,45 +498,17 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
319 i == num - 1 ? "stop" : "nonstop", 498 i == num - 1 ? "stop" : "nonstop",
320 addr, msgs[i].len); 499 addr, msgs[i].len);
321 if (!msgs[i].len) { /* no len: check only for device presence */ 500 if (!msgs[i].len) { /* no len: check only for device presence */
322 if (dev->board.is_em2800) 501 rc = i2c_check_for_device(i2c_bus, addr);
323 rc = em2800_i2c_check_for_device(dev, addr);
324 else
325 rc = em28xx_i2c_check_for_device(dev, addr);
326 if (rc == -ENODEV) { 502 if (rc == -ENODEV) {
327 if (i2c_debug)
328 printk(" no device\n");
329 rt_mutex_unlock(&dev->i2c_bus_lock); 503 rt_mutex_unlock(&dev->i2c_bus_lock);
330 return rc; 504 return rc;
331 } 505 }
332 } else if (msgs[i].flags & I2C_M_RD) { 506 } else if (msgs[i].flags & I2C_M_RD) {
333 /* read bytes */ 507 /* read bytes */
334 if (dev->board.is_em2800) 508 rc = i2c_recv_bytes(i2c_bus, msgs[i]);
335 rc = em2800_i2c_recv_bytes(dev, addr,
336 msgs[i].buf,
337 msgs[i].len);
338 else
339 rc = em28xx_i2c_recv_bytes(dev, addr,
340 msgs[i].buf,
341 msgs[i].len);
342 if (i2c_debug) {
343 for (byte = 0; byte < msgs[i].len; byte++)
344 printk(" %02x", msgs[i].buf[byte]);
345 }
346 } else { 509 } else {
347 /* write bytes */ 510 /* write bytes */
348 if (i2c_debug) { 511 rc = i2c_send_bytes(i2c_bus, msgs[i], i == num - 1);
349 for (byte = 0; byte < msgs[i].len; byte++)
350 printk(" %02x", msgs[i].buf[byte]);
351 }
352 if (dev->board.is_em2800)
353 rc = em2800_i2c_send_bytes(dev, addr,
354 msgs[i].buf,
355 msgs[i].len);
356 else
357 rc = em28xx_i2c_send_bytes(dev, addr,
358 msgs[i].buf,
359 msgs[i].len,
360 i == num - 1);
361 } 512 }
362 if (rc < 0) { 513 if (rc < 0) {
363 if (i2c_debug) 514 if (i2c_debug)
@@ -633,12 +784,17 @@ error:
633static u32 functionality(struct i2c_adapter *i2c_adap) 784static u32 functionality(struct i2c_adapter *i2c_adap)
634{ 785{
635 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data; 786 struct em28xx_i2c_bus *i2c_bus = i2c_adap->algo_data;
636 struct em28xx *dev = i2c_bus->dev;
637 787
638 u32 func_flags = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 788 if ((i2c_bus->algo_type == EM28XX_I2C_ALGO_EM28XX) ||
639 if (dev->board.is_em2800) 789 (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM25XX_BUS_B)) {
640 func_flags &= ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA; 790 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
641 return func_flags; 791 } else if (i2c_bus->algo_type == EM28XX_I2C_ALGO_EM2800) {
792 return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) &
793 ~I2C_FUNC_SMBUS_WRITE_BLOCK_DATA;
794 }
795
796 WARN(1, "Unknown i2c bus algorithm.\n");
797 return 0;
642} 798}
643 799
644static struct i2c_algorithm em28xx_algo = { 800static struct i2c_algorithm em28xx_algo = {
@@ -712,7 +868,8 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus)
712 * em28xx_i2c_register() 868 * em28xx_i2c_register()
713 * register i2c bus 869 * register i2c bus
714 */ 870 */
715int em28xx_i2c_register(struct em28xx *dev, unsigned bus) 871int em28xx_i2c_register(struct em28xx *dev, unsigned bus,
872 enum em28xx_i2c_algo_type algo_type)
716{ 873{
717 int retval; 874 int retval;
718 875
@@ -727,6 +884,7 @@ int em28xx_i2c_register(struct em28xx *dev, unsigned bus)
727 strcpy(dev->i2c_adap[bus].name, dev->name); 884 strcpy(dev->i2c_adap[bus].name, dev->name);
728 885
729 dev->i2c_bus[bus].bus = bus; 886 dev->i2c_bus[bus].bus = bus;
887 dev->i2c_bus[bus].algo_type = algo_type;
730 dev->i2c_bus[bus].dev = dev; 888 dev->i2c_bus[bus].dev = dev;
731 dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus]; 889 dev->i2c_adap[bus].algo_data = &dev->i2c_bus[bus];
732 i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev); 890 i2c_set_adapdata(&dev->i2c_adap[bus], &dev->v4l2_dev);
diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
index 4c667fd1661d..aeee896f8149 100644
--- a/drivers/media/usb/em28xx/em28xx.h
+++ b/drivers/media/usb/em28xx/em28xx.h
@@ -461,10 +461,17 @@ struct em28xx_fh {
461 enum v4l2_buf_type type; 461 enum v4l2_buf_type type;
462}; 462};
463 463
464enum em28xx_i2c_algo_type {
465 EM28XX_I2C_ALGO_EM28XX = 0,
466 EM28XX_I2C_ALGO_EM2800,
467 EM28XX_I2C_ALGO_EM25XX_BUS_B,
468};
469
464struct em28xx_i2c_bus { 470struct em28xx_i2c_bus {
465 struct em28xx *dev; 471 struct em28xx *dev;
466 472
467 unsigned bus; 473 unsigned bus;
474 enum em28xx_i2c_algo_type algo_type;
468}; 475};
469 476
470 477
@@ -651,7 +658,8 @@ struct em28xx_ops {
651 658
652/* Provided by em28xx-i2c.c */ 659/* Provided by em28xx-i2c.c */
653void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus); 660void em28xx_do_i2c_scan(struct em28xx *dev, unsigned bus);
654int em28xx_i2c_register(struct em28xx *dev, unsigned bus); 661int em28xx_i2c_register(struct em28xx *dev, unsigned bus,
662 enum em28xx_i2c_algo_type algo_type);
655int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus); 663int em28xx_i2c_unregister(struct em28xx *dev, unsigned bus);
656 664
657/* Provided by em28xx-core.c */ 665/* Provided by em28xx-core.c */