diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-27 07:10:40 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:43 -0500 |
commit | 2fe3e2ee72ef17daad1d3769321bb7dd69a003a9 (patch) | |
tree | 1d2e7a225417759a5ad55408d76416af5e7e6eb8 /drivers/media/video/em28xx | |
parent | f502e861849ade3a128964410c87acedf437a6a1 (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.c | 2 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 21 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 8 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 2 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 3 |
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 | ||
1462 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | 1462 | static 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 | ||
473 | out_free: | 473 | out_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 | ||
162 | enum em28xx_mode { | 162 | enum 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; |