aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tw9910.c
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2009-12-11 09:34:50 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:24 -0500
commit607e5ad8d596495341fa0a13e0a23121ee6053b6 (patch)
tree83b1d3b8dcc28c9be134aefeec14fbb4fdd32682 /drivers/media/video/tw9910.c
parent06f292e4806fcec2e7b2356c41241f5b6c4e3afb (diff)
V4L/DVB (13655): tw9910: Add power control
Power down internal blocks when not streaming. Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/tw9910.c')
-rw-r--r--drivers/media/video/tw9910.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 80b214efb24e..c21acedcf027 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -181,6 +181,14 @@
181 * but all register content remain unchanged. 181 * but all register content remain unchanged.
182 * This bit is self-resetting. 182 * This bit is self-resetting.
183 */ 183 */
184#define ACNTL1_PDN_MASK 0x0e
185#define CLK_PDN 0x08 /* system clock power down */
186#define Y_PDN 0x04 /* Luma ADC power down */
187#define C_PDN 0x02 /* Chroma ADC power down */
188
189/* ACNTL2 */
190#define ACNTL2_PDN_MASK 0x40
191#define PLL_PDN 0x40 /* PLL power down */
184 192
185/* VBICNTL */ 193/* VBICNTL */
186 194
@@ -478,10 +486,31 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command,
478 486
479static void tw9910_reset(struct i2c_client *client) 487static void tw9910_reset(struct i2c_client *client)
480{ 488{
481 i2c_smbus_write_byte_data(client, ACNTL1, SRESET); 489 tw9910_mask_set(client, ACNTL1, SRESET, SRESET);
482 msleep(1); 490 msleep(1);
483} 491}
484 492
493static int tw9910_power(struct i2c_client *client, int enable)
494{
495 int ret;
496 u8 acntl1;
497 u8 acntl2;
498
499 if (enable) {
500 acntl1 = 0;
501 acntl2 = 0;
502 } else {
503 acntl1 = CLK_PDN | Y_PDN | C_PDN;
504 acntl2 = PLL_PDN;
505 }
506
507 ret = tw9910_mask_set(client, ACNTL1, ACNTL1_PDN_MASK, acntl1);
508 if (ret < 0)
509 return ret;
510
511 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
512}
513
485static const struct tw9910_scale_ctrl* 514static const struct tw9910_scale_ctrl*
486tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) 515tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
487{ 516{
@@ -520,8 +549,8 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
520{ 549{
521 struct i2c_client *client = sd->priv; 550 struct i2c_client *client = sd->priv;
522 struct tw9910_priv *priv = to_tw9910(client); 551 struct tw9910_priv *priv = to_tw9910(client);
523
524 u8 val; 552 u8 val;
553 int ret;
525 554
526 if (!enable) { 555 if (!enable) {
527 switch (priv->revision) { 556 switch (priv->revision) {
@@ -549,7 +578,11 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
549 priv->scale->height); 578 priv->scale->height);
550 } 579 }
551 580
552 return tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val); 581 ret = tw9910_mask_set(client, OPFORM, OEN_TRI_SEL_MASK, val);
582 if (ret < 0)
583 return ret;
584
585 return tw9910_power(client, enable);
553} 586}
554 587
555static int tw9910_set_bus_param(struct soc_camera_device *icd, 588static int tw9910_set_bus_param(struct soc_camera_device *icd,