aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-11-27 07:10:40 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-29 14:53:43 -0500
commit2fe3e2ee72ef17daad1d3769321bb7dd69a003a9 (patch)
tree1d2e7a225417759a5ad55408d76416af5e7e6eb8 /drivers/media/video/em28xx
parentf502e861849ade3a128964410c87acedf437a6a1 (diff)
V4L/DVB (9764): em28xx: Add support for suspend the device when not used
Several chips may be turned off when the device is not used, like audio, video and dvb demods. This patch adds a gpio callback at the core structs to allow turning off such devices. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c21
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c8
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c2
-rw-r--r--drivers/media/video/em28xx/em28xx.h3
5 files changed, 21 insertions, 15 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index be78485c1664..a4b61e5a7635 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1456,7 +1456,7 @@ void em28xx_pre_card_setup(struct em28xx *dev)
1456 em28xx_set_mode(dev, EM28XX_ANALOG_MODE); 1456 em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
1457 1457
1458 /* Unlock device */ 1458 /* Unlock device */
1459 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 1459 em28xx_set_mode(dev, EM28XX_SUSPEND);
1460} 1460}
1461 1461
1462static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) 1462static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 71a1aaaa982e..c3ff8ad416e6 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -737,12 +737,14 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
737 if (!gpio) 737 if (!gpio)
738 return rc; 738 return rc;
739 739
740 em28xx_write_reg(dev, 0x48, 0x00); 740 if (dev->mode != EM28XX_SUSPEND) {
741 if (dev->mode == EM28XX_ANALOG_MODE) 741 em28xx_write_reg(dev, 0x48, 0x00);
742 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); 742 if (dev->mode == EM28XX_ANALOG_MODE)
743 else 743 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
744 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); 744 else
745 msleep(6); 745 em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
746 msleep(6);
747 }
746 748
747 /* Send GPIO reset sequences specified at board entry */ 749 /* Send GPIO reset sequences specified at board entry */
748 while (gpio->sleep >= 0) { 750 while (gpio->sleep >= 0) {
@@ -767,9 +769,12 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode)
767 if (dev->mode == set_mode) 769 if (dev->mode == set_mode)
768 return 0; 770 return 0;
769 771
770 if (set_mode == EM28XX_MODE_UNDEFINED) { 772 if (set_mode == EM28XX_SUSPEND) {
771 dev->mode = set_mode; 773 dev->mode = set_mode;
772 return 0; 774
775 /* FIXME: add suspend support for ac97 */
776
777 return em28xx_gpio_set(dev, dev->board.suspend_gpio);
773 } 778 }
774 779
775 dev->mode = set_mode; 780 dev->mode = set_mode;
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 09c15cc088a6..211156d458f0 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -161,7 +161,7 @@ static int stop_streaming(struct em28xx_dvb *dvb)
161 161
162 em28xx_uninit_isoc(dev); 162 em28xx_uninit_isoc(dev);
163 163
164 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 164 em28xx_set_mode(dev, EM28XX_SUSPEND);
165 165
166 return 0; 166 return 0;
167} 167}
@@ -215,7 +215,7 @@ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
215 if (acquire) 215 if (acquire)
216 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 216 return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
217 else 217 else
218 return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 218 return em28xx_set_mode(dev, EM28XX_SUSPEND);
219} 219}
220 220
221/* ------------------------------------------------------------------ */ 221/* ------------------------------------------------------------------ */
@@ -466,12 +466,12 @@ static int dvb_init(struct em28xx *dev)
466 if (result < 0) 466 if (result < 0)
467 goto out_free; 467 goto out_free;
468 468
469 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 469 em28xx_set_mode(dev, EM28XX_SUSPEND);
470 printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); 470 printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
471 return 0; 471 return 0;
472 472
473out_free: 473out_free:
474 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 474 em28xx_set_mode(dev, EM28XX_SUSPEND);
475 kfree(dvb); 475 kfree(dvb);
476 dev->dvb = NULL; 476 dev->dvb = NULL;
477 return result; 477 return result;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 87e9f1d7a958..efa4c8253223 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1697,7 +1697,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
1697 1697
1698 /* do this before setting alternate! */ 1698 /* do this before setting alternate! */
1699 em28xx_uninit_isoc(dev); 1699 em28xx_uninit_isoc(dev);
1700 em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); 1700 em28xx_set_mode(dev, EM28XX_SUSPEND);
1701 1701
1702 /* set alternate 0 */ 1702 /* set alternate 0 */
1703 dev->alt = 0; 1703 dev->alt = 0;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index b2b41b3635e2..b505d44fed87 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -160,7 +160,7 @@
160#define EM2800_I2C_WRITE_TIMEOUT 20 160#define EM2800_I2C_WRITE_TIMEOUT 20
161 161
162enum em28xx_mode { 162enum em28xx_mode {
163 EM28XX_MODE_UNDEFINED, 163 EM28XX_SUSPEND,
164 EM28XX_ANALOG_MODE, 164 EM28XX_ANALOG_MODE,
165 EM28XX_DIGITAL_MODE, 165 EM28XX_DIGITAL_MODE,
166}; 166};
@@ -336,6 +336,7 @@ struct em28xx_board {
336 unsigned int tda9887_conf; 336 unsigned int tda9887_conf;
337 337
338 struct em28xx_reg_seq *dvb_gpio; 338 struct em28xx_reg_seq *dvb_gpio;
339 struct em28xx_reg_seq *suspend_gpio;
339 340
340 unsigned int is_em2800:1; 341 unsigned int is_em2800:1;
341 unsigned int has_msp34xx:1; 342 unsigned int has_msp34xx:1;