summaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/m5mols/m5mols_core.c3
-rw-r--r--drivers/media/i2c/ov5640.c200
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c3
-rw-r--r--drivers/media/i2c/tc358743.c14
4 files changed, 124 insertions, 96 deletions
diff --git a/drivers/media/i2c/m5mols/m5mols_core.c b/drivers/media/i2c/m5mols/m5mols_core.c
index de295114ca48..21666d705e37 100644
--- a/drivers/media/i2c/m5mols/m5mols_core.c
+++ b/drivers/media/i2c/m5mols/m5mols_core.c
@@ -764,7 +764,8 @@ static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
if (ret) {
- info->set_power(&client->dev, 0);
+ if (info->set_power)
+ info->set_power(&client->dev, 0);
return ret;
}
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 54687fbc1f64..449078504a6f 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -34,6 +34,8 @@
#define OV5640_REG_SYS_RESET02 0x3002
#define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006
#define OV5640_REG_SYS_CTRL0 0x3008
+#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42
+#define OV5640_REG_SYS_CTRL0_SW_PWUP 0x02
#define OV5640_REG_CHIP_ID 0x300a
#define OV5640_REG_IO_MIPI_CTRL00 0x300e
#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
@@ -274,8 +276,7 @@ static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
/* YUV422 UYVY VGA@30fps */
static const struct reg_value ov5640_init_setting_30fps_VGA[] = {
{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
- {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
- {0x3630, 0x36, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0},
{0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
{0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
@@ -759,7 +760,7 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
* +->| PLL Root Div | - reg 0x3037, bit 4
* +-+------------+
* | +---------+
- * +->| Bit Div | - reg 0x3035, bits 0-3
+ * +->| Bit Div | - reg 0x3034, bits 0-3
* +-+-------+
* | +-------------+
* +->| SCLK Div | - reg 0x3108, bits 0-1
@@ -1173,6 +1174,12 @@ static int ov5640_load_regs(struct ov5640_dev *sensor,
val = regs->val;
mask = regs->mask;
+ /* remain in power down mode for DVP */
+ if (regs->reg_addr == OV5640_REG_SYS_CTRL0 &&
+ val == OV5640_REG_SYS_CTRL0_SW_PWUP &&
+ sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
+ continue;
+
if (mask)
ret = ov5640_mod_reg(sensor, reg_addr, mask, val);
else
@@ -1328,31 +1335,9 @@ static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
if (ret)
return ret;
- /*
- * enable VSYNC/HREF/PCLK DVP control lines
- * & D[9:6] DVP data lines
- *
- * PAD OUTPUT ENABLE 01
- * - 6: VSYNC output enable
- * - 5: HREF output enable
- * - 4: PCLK output enable
- * - [3:0]: D[9:6] output enable
- */
- ret = ov5640_write_reg(sensor,
- OV5640_REG_PAD_OUTPUT_ENABLE01,
- on ? 0x7f : 0);
- if (ret)
- return ret;
-
- /*
- * enable D[5:0] DVP data lines
- *
- * PAD OUTPUT ENABLE 02
- * - [7:2]: D[5:0] output enable
- */
- return ov5640_write_reg(sensor,
- OV5640_REG_PAD_OUTPUT_ENABLE02,
- on ? 0xfc : 0);
+ return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ?
+ OV5640_REG_SYS_CTRL0_SW_PWUP :
+ OV5640_REG_SYS_CTRL0_SW_PWDN);
}
static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
@@ -2051,6 +2036,95 @@ static void ov5640_set_power_off(struct ov5640_dev *sensor)
clk_disable_unprepare(sensor->xclk);
}
+static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on)
+{
+ int ret;
+
+ if (!on) {
+ /* Reset MIPI bus settings to their default values. */
+ ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58);
+ ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x04);
+ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x00);
+ return 0;
+ }
+
+ /*
+ * Power up MIPI HS Tx and LS Rx; 2 data lanes mode
+ *
+ * 0x300e = 0x40
+ * [7:5] = 010 : 2 data lanes mode (see FIXME note in
+ * "ov5640_set_stream_mipi()")
+ * [4] = 0 : Power up MIPI HS Tx
+ * [3] = 0 : Power up MIPI LS Rx
+ * [2] = 0 : MIPI interface disabled
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40);
+ if (ret)
+ return ret;
+
+ /*
+ * Gate clock and set LP11 in 'no packets mode' (idle)
+ *
+ * 0x4800 = 0x24
+ * [5] = 1 : Gate clock when 'no packets'
+ * [2] = 1 : MIPI bus in LP11 when 'no packets'
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x24);
+ if (ret)
+ return ret;
+
+ /*
+ * Set data lanes and clock in LP11 when 'sleeping'
+ *
+ * 0x3019 = 0x70
+ * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping'
+ * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping'
+ * [4] = 1 : MIPI clock lane in LP11 when 'sleeping'
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x70);
+ if (ret)
+ return ret;
+
+ /* Give lanes some time to coax into LP11 state. */
+ usleep_range(500, 1000);
+
+ return 0;
+}
+
+static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on)
+{
+ int ret;
+
+ if (!on) {
+ /* Reset settings to their default values. */
+ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x00);
+ ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0x00);
+ return 0;
+ }
+
+ /*
+ * enable VSYNC/HREF/PCLK DVP control lines
+ * & D[9:6] DVP data lines
+ *
+ * PAD OUTPUT ENABLE 01
+ * - 6: VSYNC output enable
+ * - 5: HREF output enable
+ * - 4: PCLK output enable
+ * - [3:0]: D[9:6] output enable
+ */
+ ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x7f);
+ if (ret)
+ return ret;
+
+ /*
+ * enable D[5:0] DVP data lines
+ *
+ * PAD OUTPUT ENABLE 02
+ * - [7:2]: D[5:0] output enable
+ */
+ return ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0xfc);
+}
+
static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
{
int ret = 0;
@@ -2063,67 +2137,17 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
ret = ov5640_restore_mode(sensor);
if (ret)
goto power_off;
+ }
- /* We're done here for DVP bus, while CSI-2 needs setup. */
- if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
- return 0;
-
- /*
- * Power up MIPI HS Tx and LS Rx; 2 data lanes mode
- *
- * 0x300e = 0x40
- * [7:5] = 010 : 2 data lanes mode (see FIXME note in
- * "ov5640_set_stream_mipi()")
- * [4] = 0 : Power up MIPI HS Tx
- * [3] = 0 : Power up MIPI LS Rx
- * [2] = 0 : MIPI interface disabled
- */
- ret = ov5640_write_reg(sensor,
- OV5640_REG_IO_MIPI_CTRL00, 0x45);
- if (ret)
- goto power_off;
-
- /*
- * Gate clock and set LP11 in 'no packets mode' (idle)
- *
- * 0x4800 = 0x24
- * [5] = 1 : Gate clock when 'no packets'
- * [2] = 1 : MIPI bus in LP11 when 'no packets'
- */
- ret = ov5640_write_reg(sensor,
- OV5640_REG_MIPI_CTRL00, 0x24);
- if (ret)
- goto power_off;
-
- /*
- * Set data lanes and clock in LP11 when 'sleeping'
- *
- * 0x3019 = 0x70
- * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping'
- * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping'
- * [4] = 1 : MIPI clock lane in LP11 when 'sleeping'
- */
- ret = ov5640_write_reg(sensor,
- OV5640_REG_PAD_OUTPUT00, 0x70);
- if (ret)
- goto power_off;
-
- /* Give lanes some time to coax into LP11 state. */
- usleep_range(500, 1000);
-
- } else {
- if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) {
- /* Reset MIPI bus settings to their default values. */
- ov5640_write_reg(sensor,
- OV5640_REG_IO_MIPI_CTRL00, 0x58);
- ov5640_write_reg(sensor,
- OV5640_REG_MIPI_CTRL00, 0x04);
- ov5640_write_reg(sensor,
- OV5640_REG_PAD_OUTPUT00, 0x00);
- }
+ if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
+ ret = ov5640_set_power_mipi(sensor, on);
+ else
+ ret = ov5640_set_power_dvp(sensor, on);
+ if (ret)
+ goto power_off;
+ if (!on)
ov5640_set_power_off(sensor);
- }
return 0;
@@ -3171,8 +3195,8 @@ static int ov5640_probe(struct i2c_client *client)
free_ctrls:
v4l2_ctrl_handler_free(&sensor->ctrls.handler);
entity_cleanup:
- mutex_destroy(&sensor->lock);
media_entity_cleanup(&sensor->sd.entity);
+ mutex_destroy(&sensor->lock);
return ret;
}
@@ -3182,9 +3206,9 @@ static int ov5640_remove(struct i2c_client *client)
struct ov5640_dev *sensor = to_ov5640_dev(sd);
v4l2_async_unregister_subdev(&sensor->sd);
- mutex_destroy(&sensor->lock);
media_entity_cleanup(&sensor->sd.entity);
v4l2_ctrl_handler_free(&sensor->ctrls.handler);
+ mutex_destroy(&sensor->lock);
return 0;
}
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index 42805dfbffeb..06edbe8749c6 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -2327,11 +2327,12 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr,
if (rval < 0) {
if (rval != -EBUSY && rval != -EAGAIN)
pm_runtime_set_active(&client->dev);
- pm_runtime_put(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
return -ENODEV;
}
if (smiapp_read_nvm(sensor, sensor->nvm)) {
+ pm_runtime_put(&client->dev);
dev_err(&client->dev, "nvm read failed\n");
return -ENODEV;
}
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index dbbab75f135e..cff99cf61ed4 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -919,8 +919,8 @@ static const struct cec_adap_ops tc358743_cec_adap_ops = {
.adap_monitor_all_enable = tc358743_cec_adap_monitor_all_enable,
};
-static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus,
- bool *handled)
+static void tc358743_cec_handler(struct v4l2_subdev *sd, u16 intstatus,
+ bool *handled)
{
struct tc358743_state *state = to_state(sd);
unsigned int cec_rxint, cec_txint;
@@ -953,7 +953,8 @@ static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus,
cec_transmit_attempt_done(state->cec_adap,
CEC_TX_STATUS_ERROR);
}
- *handled = true;
+ if (handled)
+ *handled = true;
}
if ((intstatus & MASK_CEC_RINT) &&
(cec_rxint & MASK_CECRIEND)) {
@@ -968,7 +969,8 @@ static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus,
msg.msg[i] = v & 0xff;
}
cec_received_msg(state->cec_adap, &msg);
- *handled = true;
+ if (handled)
+ *handled = true;
}
i2c_wr16(sd, INTSTATUS,
intstatus & (MASK_CEC_RINT | MASK_CEC_TINT));
@@ -1432,7 +1434,7 @@ static int tc358743_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
#ifdef CONFIG_VIDEO_TC358743_CEC
if (intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)) {
- tc358743_cec_isr(sd, intstatus, handled);
+ tc358743_cec_handler(sd, intstatus, handled);
i2c_wr16(sd, INTSTATUS,
intstatus & (MASK_CEC_RINT | MASK_CEC_TINT));
intstatus &= ~(MASK_CEC_RINT | MASK_CEC_TINT);
@@ -1461,7 +1463,7 @@ static int tc358743_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
static irqreturn_t tc358743_irq_handler(int irq, void *dev_id)
{
struct tc358743_state *state = dev_id;
- bool handled;
+ bool handled = false;
tc358743_isr(&state->sd, 0, &handled);