diff options
author | Frank Schaefer <fschaefer.oss@googlemail.com> | 2013-12-02 01:06:51 +0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-12-10 22:08:40 +0400 |
commit | 07e4de3004ecedd67c72708d6c0fe69c51317f79 (patch) | |
tree | 88db52a8971a45ffb0ded44bb7afa39268876c98 /drivers/media/usb | |
parent | 7b2f25c0b073479fa1afea3ae65dd9d9f0da5586 (diff) | |
download | linux-07e4de3004ecedd67c72708d6c0fe69c51317f79.tar.xz |
[media] em28xx: add support for GPO controlled analog capturing LEDs
Some devices are equipped with a capturing status LED that needs to be
switched on/off explicitly via a GPO port.
Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-core.c | 69 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx.h | 9 |
2 files changed, 46 insertions, 32 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index fc157af5234a..31d6ab2555f2 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -608,46 +608,51 @@ int em28xx_capture_start(struct em28xx *dev, int start) dev->chip_id == CHIP_ID_EM2884 || dev->chip_id == CHIP_ID_EM28174) { /* The Transport Stream Enable Register moved in em2874 */ - if (!start) { - rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, - 0x00, - EM2874_TS1_CAPTURE_ENABLE); - return rc; - } - - /* Enable Transport Stream */ rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, - EM2874_TS1_CAPTURE_ENABLE, + start ? + EM2874_TS1_CAPTURE_ENABLE : 0x00, EM2874_TS1_CAPTURE_ENABLE); - return rc; - } - + } else { + /* FIXME: which is the best order? */ + /* video registers are sampled by VREF */ + rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, + start ? 0x10 : 0x00, 0x10); + if (rc < 0) + return rc; - /* FIXME: which is the best order? */ - /* video registers are sampled by VREF */ - rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, - start ? 0x10 : 0x00, 0x10); - if (rc < 0) - return rc; + if (start) { + if (dev->board.is_webcam) + rc = em28xx_write_reg(dev, 0x13, 0x0c); - if (!start) { - /* disable video capture */ - rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); - return rc; - } + /* Enable video capture */ + rc = em28xx_write_reg(dev, 0x48, 0x00); - if (dev->board.is_webcam) - rc = em28xx_write_reg(dev, 0x13, 0x0c); + if (dev->mode == EM28XX_ANALOG_MODE) + rc = em28xx_write_reg(dev, + EM28XX_R12_VINENABLE, 0x67); + else + rc = em28xx_write_reg(dev, + EM28XX_R12_VINENABLE, 0x37); - /* enable video capture */ - rc = em28xx_write_reg(dev, 0x48, 0x00); + msleep(6); + } else { + /* disable video capture */ + rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); + } + } - if (dev->mode == EM28XX_ANALOG_MODE) - rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); - else - rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); + if (rc < 0) + return rc; - msleep(6); + /* Switch (explicitly controlled) analog capturing LED on/off */ + if ((dev->mode == EM28XX_ANALOG_MODE) + && dev->board.analog_capturing_led) { + struct em28xx_led *led = dev->board.analog_capturing_led; + em28xx_write_reg_bits(dev, led->gpio_reg, + (!start ^ led->inverted) ? + ~led->gpio_mask : led->gpio_mask, + led->gpio_mask); + } return rc; } diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index f8726ad5d0a8..8003c2f7bb96 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -374,6 +374,12 @@ enum em28xx_adecoder { EM28XX_TVAUDIO, }; +struct em28xx_led { + u8 gpio_reg; + u8 gpio_mask; + bool inverted; +}; + struct em28xx_board { char *name; int vchannels; @@ -410,6 +416,9 @@ struct em28xx_board { struct em28xx_input input[MAX_EM28XX_INPUT]; struct em28xx_input radio; char *ir_codes; + + /* LEDs that need to be controlled explicitly */ + struct em28xx_led *analog_capturing_led; }; struct em28xx_eeprom { |