From 2fe3e2ee72ef17daad1d3769321bb7dd69a003a9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 27 Nov 2008 09:10:40 -0300 Subject: [PATCH] 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 --- drivers/media/video/em28xx/em28xx-cards.c | 2 +- drivers/media/video/em28xx/em28xx-core.c | 21 +++++++++++++-------- drivers/media/video/em28xx/em28xx-dvb.c | 8 ++++---- drivers/media/video/em28xx/em28xx-video.c | 2 +- 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 be78485..a4b61e5 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) em28xx_set_mode(dev, EM28XX_ANALOG_MODE); /* Unlock device */ - em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + em28xx_set_mode(dev, EM28XX_SUSPEND); } 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 71a1aaa..c3ff8ad 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) if (!gpio) return rc; - em28xx_write_reg(dev, 0x48, 0x00); - if (dev->mode == EM28XX_ANALOG_MODE) - em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); - else - em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); - msleep(6); + if (dev->mode != EM28XX_SUSPEND) { + em28xx_write_reg(dev, 0x48, 0x00); + if (dev->mode == EM28XX_ANALOG_MODE) + em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); + else + em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); + msleep(6); + } /* Send GPIO reset sequences specified at board entry */ while (gpio->sleep >= 0) { @@ -767,9 +769,12 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) if (dev->mode == set_mode) return 0; - if (set_mode == EM28XX_MODE_UNDEFINED) { + if (set_mode == EM28XX_SUSPEND) { dev->mode = set_mode; - return 0; + + /* FIXME: add suspend support for ac97 */ + + return em28xx_gpio_set(dev, dev->board.suspend_gpio); } dev->mode = set_mode; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 09c15cc..211156d 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) em28xx_uninit_isoc(dev); - em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + em28xx_set_mode(dev, EM28XX_SUSPEND); return 0; } @@ -215,7 +215,7 @@ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) if (acquire) return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); else - return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + return em28xx_set_mode(dev, EM28XX_SUSPEND); } /* ------------------------------------------------------------------ */ @@ -466,12 +466,12 @@ static int dvb_init(struct em28xx *dev) if (result < 0) goto out_free; - em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + em28xx_set_mode(dev, EM28XX_SUSPEND); printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); return 0; out_free: - em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + em28xx_set_mode(dev, EM28XX_SUSPEND); kfree(dvb); dev->dvb = NULL; return result; diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 87e9f1d..efa4c82 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) /* do this before setting alternate! */ em28xx_uninit_isoc(dev); - em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); + em28xx_set_mode(dev, EM28XX_SUSPEND); /* set alternate 0 */ dev->alt = 0; diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index b2b41b3..b505d44 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -160,7 +160,7 @@ #define EM2800_I2C_WRITE_TIMEOUT 20 enum em28xx_mode { - EM28XX_MODE_UNDEFINED, + EM28XX_SUSPEND, EM28XX_ANALOG_MODE, EM28XX_DIGITAL_MODE, }; @@ -336,6 +336,7 @@ struct em28xx_board { unsigned int tda9887_conf; struct em28xx_reg_seq *dvb_gpio; + struct em28xx_reg_seq *suspend_gpio; unsigned int is_em2800:1; unsigned int has_msp34xx:1; -- 2.7.4