mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 09:43:59 +08:00
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>
This commit is contained in:
parent
f502e86184
commit
2fe3e2ee72
@ -1456,7 +1456,7 @@ void em28xx_pre_card_setup(struct em28xx *dev)
|
|||||||
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
|
em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
|
||||||
|
|
||||||
/* Unlock device */
|
/* 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)
|
static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
|
||||||
|
@ -737,12 +737,14 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio)
|
|||||||
if (!gpio)
|
if (!gpio)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
em28xx_write_reg(dev, 0x48, 0x00);
|
if (dev->mode != EM28XX_SUSPEND) {
|
||||||
if (dev->mode == EM28XX_ANALOG_MODE)
|
em28xx_write_reg(dev, 0x48, 0x00);
|
||||||
em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
|
if (dev->mode == EM28XX_ANALOG_MODE)
|
||||||
else
|
em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67);
|
||||||
em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
|
else
|
||||||
msleep(6);
|
em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37);
|
||||||
|
msleep(6);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send GPIO reset sequences specified at board entry */
|
/* Send GPIO reset sequences specified at board entry */
|
||||||
while (gpio->sleep >= 0) {
|
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)
|
if (dev->mode == set_mode)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (set_mode == EM28XX_MODE_UNDEFINED) {
|
if (set_mode == EM28XX_SUSPEND) {
|
||||||
dev->mode = set_mode;
|
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;
|
dev->mode = set_mode;
|
||||||
|
@ -161,7 +161,7 @@ static int stop_streaming(struct em28xx_dvb *dvb)
|
|||||||
|
|
||||||
em28xx_uninit_isoc(dev);
|
em28xx_uninit_isoc(dev);
|
||||||
|
|
||||||
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
|
em28xx_set_mode(dev, EM28XX_SUSPEND);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -215,7 +215,7 @@ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
|
|||||||
if (acquire)
|
if (acquire)
|
||||||
return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
|
return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
|
||||||
else
|
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)
|
if (result < 0)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
|
em28xx_set_mode(dev, EM28XX_SUSPEND);
|
||||||
printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
|
printk(KERN_INFO "Successfully loaded em28xx-dvb\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
|
em28xx_set_mode(dev, EM28XX_SUSPEND);
|
||||||
kfree(dvb);
|
kfree(dvb);
|
||||||
dev->dvb = NULL;
|
dev->dvb = NULL;
|
||||||
return result;
|
return result;
|
||||||
|
@ -1697,7 +1697,7 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
|
|||||||
|
|
||||||
/* do this before setting alternate! */
|
/* do this before setting alternate! */
|
||||||
em28xx_uninit_isoc(dev);
|
em28xx_uninit_isoc(dev);
|
||||||
em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED);
|
em28xx_set_mode(dev, EM28XX_SUSPEND);
|
||||||
|
|
||||||
/* set alternate 0 */
|
/* set alternate 0 */
|
||||||
dev->alt = 0;
|
dev->alt = 0;
|
||||||
|
@ -160,7 +160,7 @@
|
|||||||
#define EM2800_I2C_WRITE_TIMEOUT 20
|
#define EM2800_I2C_WRITE_TIMEOUT 20
|
||||||
|
|
||||||
enum em28xx_mode {
|
enum em28xx_mode {
|
||||||
EM28XX_MODE_UNDEFINED,
|
EM28XX_SUSPEND,
|
||||||
EM28XX_ANALOG_MODE,
|
EM28XX_ANALOG_MODE,
|
||||||
EM28XX_DIGITAL_MODE,
|
EM28XX_DIGITAL_MODE,
|
||||||
};
|
};
|
||||||
@ -336,6 +336,7 @@ struct em28xx_board {
|
|||||||
unsigned int tda9887_conf;
|
unsigned int tda9887_conf;
|
||||||
|
|
||||||
struct em28xx_reg_seq *dvb_gpio;
|
struct em28xx_reg_seq *dvb_gpio;
|
||||||
|
struct em28xx_reg_seq *suspend_gpio;
|
||||||
|
|
||||||
unsigned int is_em2800:1;
|
unsigned int is_em2800:1;
|
||||||
unsigned int has_msp34xx:1;
|
unsigned int has_msp34xx:1;
|
||||||
|
Loading…
Reference in New Issue
Block a user