diff options
author | Kuninori Morimoto <morimoto.kuninori@renesas.com> | 2009-12-11 09:34:50 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-16 06:27:24 -0500 |
commit | 607e5ad8d596495341fa0a13e0a23121ee6053b6 (patch) | |
tree | 83b1d3b8dcc28c9be134aefeec14fbb4fdd32682 /drivers | |
parent | 06f292e4806fcec2e7b2356c41241f5b6c4e3afb (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')
-rw-r--r-- | drivers/media/video/tw9910.c | 39 |
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 | ||
479 | static void tw9910_reset(struct i2c_client *client) | 487 | static 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 | ||
493 | static 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 | |||
485 | static const struct tw9910_scale_ctrl* | 514 | static const struct tw9910_scale_ctrl* |
486 | tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) | 515 | tw9910_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 | ||
555 | static int tw9910_set_bus_param(struct soc_camera_device *icd, | 588 | static int tw9910_set_bus_param(struct soc_camera_device *icd, |