aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/adv7180.c3
-rw-r--r--drivers/media/i2c/adv7511-v4l2.c91
-rw-r--r--drivers/media/i2c/adv7604.c97
-rw-r--r--drivers/media/i2c/adv7842.c135
-rw-r--r--drivers/media/i2c/alvium-csi2.c5
-rw-r--r--drivers/media/i2c/ds90ub953.c5
-rw-r--r--drivers/media/i2c/ds90ub960.c7
-rw-r--r--drivers/media/i2c/dw9768.c15
-rw-r--r--drivers/media/i2c/gc0308.c4
-rw-r--r--drivers/media/i2c/gc05a2.c10
-rw-r--r--drivers/media/i2c/gc08a3.c10
-rw-r--r--drivers/media/i2c/gc2145.c41
-rw-r--r--drivers/media/i2c/hi556.c2
-rw-r--r--drivers/media/i2c/imx219.c10
-rw-r--r--drivers/media/i2c/imx283.c10
-rw-r--r--drivers/media/i2c/imx290.c40
-rw-r--r--drivers/media/i2c/imx415.c3
-rw-r--r--drivers/media/i2c/max96717.c6
-rw-r--r--drivers/media/i2c/mt9p031.c96
-rw-r--r--drivers/media/i2c/ov01a10.c6
-rw-r--r--drivers/media/i2c/ov08x40.c181
-rw-r--r--drivers/media/i2c/ov2740.c7
-rw-r--r--drivers/media/i2c/ov5640.c2
-rw-r--r--drivers/media/i2c/ov5645.c278
-rw-r--r--drivers/media/i2c/ov5670.c2
-rw-r--r--drivers/media/i2c/ov5675.c4
-rw-r--r--drivers/media/i2c/ov64a40.c10
-rw-r--r--drivers/media/i2c/ov772x.c2
-rw-r--r--drivers/media/i2c/ov7740.c2
-rw-r--r--drivers/media/i2c/ov8856.c2
-rw-r--r--drivers/media/i2c/ov8858.c9
-rw-r--r--drivers/media/i2c/ov9650.c2
-rw-r--r--drivers/media/i2c/ov9734.c2
-rw-r--r--drivers/media/i2c/st-mipid02.c117
-rw-r--r--drivers/media/i2c/tc358743.c40
-rw-r--r--drivers/media/i2c/thp7312.c5
-rw-r--r--drivers/media/i2c/ths7303.c2
-rw-r--r--drivers/media/i2c/vgxy61.c2
-rw-r--r--drivers/media/i2c/video-i2c.c4
39 files changed, 743 insertions, 526 deletions
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 819ff9f7c90f..ff7dfa0278a7 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1440,7 +1440,8 @@ static int adv7180_probe(struct i2c_client *client)
return ret;
}
- if (of_property_read_bool(np, "adv,force-bt656-4"))
+ if (of_property_read_bool(np, "adv,force-bt656-4") ||
+ of_property_read_bool(np, "adi,force-bt656-4"))
state->force_bt656_4 = true;
if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) {
diff --git a/drivers/media/i2c/adv7511-v4l2.c b/drivers/media/i2c/adv7511-v4l2.c
index e9406d552699..4036972af3a6 100644
--- a/drivers/media/i2c/adv7511-v4l2.c
+++ b/drivers/media/i2c/adv7511-v4l2.c
@@ -116,6 +116,9 @@ struct adv7511_state {
unsigned edid_detect_counter;
struct workqueue_struct *work_queue;
struct delayed_work edid_handler; /* work entry */
+
+ struct dentry *debugfs_dir;
+ struct v4l2_debugfs_if *infoframes;
};
static void adv7511_check_monitor_present_status(struct v4l2_subdev *sd);
@@ -483,27 +486,25 @@ static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
return 256 - csum;
}
-static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_infoframe *cri)
+static int read_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri,
+ u8 *buffer)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct device *dev = &client->dev;
- union hdmi_infoframe frame;
- u8 buffer[32];
u8 len;
int i;
if (!(adv7511_rd(sd, cri->present_reg) & cri->present_mask)) {
v4l2_info(sd, "%s infoframe not transmitted\n", cri->desc);
- return;
+ return 0;
}
memcpy(buffer, cri->header, sizeof(cri->header));
len = buffer[2];
- if (len + 4 > sizeof(buffer)) {
+ if (len + 4 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len);
- return;
+ return 0;
}
if (cri->payload_addr >= 0x100) {
@@ -516,21 +517,38 @@ static void log_infoframe(struct v4l2_subdev *sd, const struct adv7511_cfg_read_
buffer[3] = 0;
buffer[3] = hdmi_infoframe_checksum(buffer, len + 4);
- if (hdmi_infoframe_unpack(&frame, buffer, len + 4) < 0) {
- v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc);
+ return len + 4;
+}
+
+static void log_infoframe(struct v4l2_subdev *sd,
+ const struct adv7511_cfg_read_infoframe *cri)
+{
+ union hdmi_infoframe frame;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct device *dev = &client->dev;
+ u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ int len = read_infoframe(sd, cri, buffer);
+
+ if (len <= 0)
+ return;
+
+ if (hdmi_infoframe_unpack(&frame, buffer, len) < 0) {
+ v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+ __func__, cri->desc);
return;
}
hdmi_infoframe_log(KERN_INFO, dev, &frame);
}
+static const struct adv7511_cfg_read_infoframe cri[] = {
+ { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
+ { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
+ { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
+};
+
static void adv7511_log_infoframes(struct v4l2_subdev *sd)
{
- static const struct adv7511_cfg_read_infoframe cri[] = {
- { "AVI", 0x44, 0x10, { 0x82, 2, 13 }, 0x55 },
- { "Audio", 0x44, 0x08, { 0x84, 1, 10 }, 0x73 },
- { "SDP", 0x40, 0x40, { 0x83, 1, 25 }, 0x103 },
- };
int i;
for (i = 0; i < ARRAY_SIZE(cri); i++)
@@ -1693,6 +1711,34 @@ static bool adv7511_check_edid_status(struct v4l2_subdev *sd)
return false;
}
+static ssize_t
+adv7511_debugfs_if_read(u32 type, void *priv,
+ struct file *filp, char __user *ubuf, size_t count, loff_t *ppos)
+{
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ struct v4l2_subdev *sd = priv;
+ int index;
+ int len;
+
+ switch (type) {
+ case V4L2_DEBUGFS_IF_AVI:
+ index = 0;
+ break;
+ case V4L2_DEBUGFS_IF_AUDIO:
+ index = 1;
+ break;
+ case V4L2_DEBUGFS_IF_SPD:
+ index = 2;
+ break;
+ default:
+ return 0;
+ }
+ len = read_infoframe(sd, &cri[index], buf);
+ if (len > 0)
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+ return len < 0 ? 0 : len;
+}
+
static int adv7511_registered(struct v4l2_subdev *sd)
{
struct adv7511_state *state = get_adv7511_state(sd);
@@ -1700,9 +1746,16 @@ static int adv7511_registered(struct v4l2_subdev *sd)
int err;
err = cec_register_adapter(state->cec_adap, &client->dev);
- if (err)
+ if (err) {
cec_delete_adapter(state->cec_adap);
- return err;
+ return err;
+ }
+
+ state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+ state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+ V4L2_DEBUGFS_IF_SPD, sd, adv7511_debugfs_if_read);
+ return 0;
}
static void adv7511_unregistered(struct v4l2_subdev *sd)
@@ -1710,6 +1763,10 @@ static void adv7511_unregistered(struct v4l2_subdev *sd)
struct adv7511_state *state = get_adv7511_state(sd);
cec_unregister_adapter(state->cec_adap);
+ v4l2_debugfs_if_free(state->infoframes);
+ state->infoframes = NULL;
+ debugfs_remove_recursive(state->debugfs_dir);
+ state->debugfs_dir = NULL;
}
static const struct v4l2_subdev_internal_ops adv7511_int_ops = {
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index 272945a878b3..e271782b7b70 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -42,7 +42,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7604/10/11/12 video decoder driver");
-MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
MODULE_AUTHOR("Mats Randgaard <mats.randgaard@cisco.com>");
MODULE_LICENSE("GPL");
@@ -193,6 +193,9 @@ struct adv76xx_state {
struct delayed_work delayed_work_enable_hotplug;
bool restart_stdi_once;
+ struct dentry *debugfs_dir;
+ struct v4l2_debugfs_if *infoframes;
+
/* CEC */
struct cec_adapter *cec_adap;
u8 cec_addr[ADV76XX_MAX_ADDRS];
@@ -1405,12 +1408,13 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
- false, timings))
+ false, adv76xx_get_dv_timings_cap(sd, -1), timings))
return 0;
if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
- false, state->aspect_ratio, timings))
+ false, state->aspect_ratio,
+ adv76xx_get_dv_timings_cap(sd, -1), timings))
return 0;
v4l2_dbg(2, debug, sd,
@@ -2458,10 +2462,9 @@ static const struct adv76xx_cfg_read_infoframe adv76xx_cri[] = {
{ "Vendor", 0x10, 0xec, 0x54 }
};
-static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index,
- union hdmi_infoframe *frame)
+static int adv76xx_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
{
- uint8_t buffer[32];
u8 len;
int i;
@@ -2472,27 +2475,20 @@ static int adv76xx_read_infoframe(struct v4l2_subdev *sd, int index,
}
for (i = 0; i < 3; i++)
- buffer[i] = infoframe_read(sd,
- adv76xx_cri[index].head_addr + i);
+ buf[i] = infoframe_read(sd, adv76xx_cri[index].head_addr + i);
- len = buffer[2] + 1;
+ len = buf[2] + 1;
- if (len + 3 > sizeof(buffer)) {
+ if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__,
adv76xx_cri[index].desc, len);
return -ENOENT;
}
for (i = 0; i < len; i++)
- buffer[i + 3] = infoframe_read(sd,
- adv76xx_cri[index].payload_addr + i);
-
- if (hdmi_infoframe_unpack(frame, buffer, len + 3) < 0) {
- v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__,
- adv76xx_cri[index].desc);
- return -ENOENT;
- }
- return 0;
+ buf[i + 3] = infoframe_read(sd,
+ adv76xx_cri[index].payload_addr + i);
+ return len + 3;
}
static void adv76xx_log_infoframes(struct v4l2_subdev *sd)
@@ -2505,10 +2501,19 @@ static void adv76xx_log_infoframes(struct v4l2_subdev *sd)
}
for (i = 0; i < ARRAY_SIZE(adv76xx_cri); i++) {
- union hdmi_infoframe frame;
struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ union hdmi_infoframe frame;
+ int len;
- if (!adv76xx_read_infoframe(sd, i, &frame))
+ len = adv76xx_read_infoframe_buf(sd, i, buffer);
+ if (len < 0)
+ continue;
+
+ if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+ v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+ __func__, adv76xx_cri[i].desc);
+ else
hdmi_infoframe_log(KERN_INFO, &client->dev, &frame);
}
}
@@ -2694,6 +2699,41 @@ static int adv76xx_subscribe_event(struct v4l2_subdev *sd,
}
}
+static ssize_t
+adv76xx_debugfs_if_read(u32 type, void *priv, struct file *filp,
+ char __user *ubuf, size_t count, loff_t *ppos)
+{
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ struct v4l2_subdev *sd = priv;
+ int index;
+ int len;
+
+ if (!is_hdmi(sd))
+ return 0;
+
+ switch (type) {
+ case V4L2_DEBUGFS_IF_AVI:
+ index = 0;
+ break;
+ case V4L2_DEBUGFS_IF_AUDIO:
+ index = 1;
+ break;
+ case V4L2_DEBUGFS_IF_SPD:
+ index = 2;
+ break;
+ case V4L2_DEBUGFS_IF_HDMI:
+ index = 3;
+ break;
+ default:
+ return 0;
+ }
+
+ len = adv76xx_read_infoframe_buf(sd, index, buf);
+ if (len > 0)
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+ return len < 0 ? 0 : len;
+}
+
static int adv76xx_registered(struct v4l2_subdev *sd)
{
struct adv76xx_state *state = to_state(sd);
@@ -2701,9 +2741,16 @@ static int adv76xx_registered(struct v4l2_subdev *sd)
int err;
err = cec_register_adapter(state->cec_adap, &client->dev);
- if (err)
+ if (err) {
cec_delete_adapter(state->cec_adap);
- return err;
+ return err;
+ }
+ state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+ state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+ V4L2_DEBUGFS_IF_SPD | V4L2_DEBUGFS_IF_HDMI, sd,
+ adv76xx_debugfs_if_read);
+ return 0;
}
static void adv76xx_unregistered(struct v4l2_subdev *sd)
@@ -2711,6 +2758,10 @@ static void adv76xx_unregistered(struct v4l2_subdev *sd)
struct adv76xx_state *state = to_state(sd);
cec_unregister_adapter(state->cec_adap);
+ v4l2_debugfs_if_free(state->infoframes);
+ state->infoframes = NULL;
+ debugfs_remove_recursive(state->debugfs_dir);
+ state->debugfs_dir = NULL;
}
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/i2c/adv7842.c b/drivers/media/i2c/adv7842.c
index 014fc913225c..5545cd23e113 100644
--- a/drivers/media/i2c/adv7842.c
+++ b/drivers/media/i2c/adv7842.c
@@ -38,7 +38,7 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7842 video decoder driver");
-MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
+MODULE_AUTHOR("Hans Verkuil <hansverk@cisco.com>");
MODULE_AUTHOR("Martin Bugge <marbugge@cisco.com>");
MODULE_LICENSE("GPL");
@@ -114,6 +114,9 @@ struct adv7842_state {
bool restart_stdi_once;
bool hdmi_port_a;
+ struct dentry *debugfs_dir;
+ struct v4l2_debugfs_if *infoframes;
+
/* i2c clients */
struct i2c_client *i2c_sdp_io;
struct i2c_client *i2c_sdp;
@@ -1431,14 +1434,15 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
}
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
- (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
- (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
- false, timings))
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+ false, adv7842_get_dv_timings_cap(sd), timings))
return 0;
if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
- (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
- (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
- false, state->aspect_ratio, timings))
+ (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+ (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+ false, state->aspect_ratio,
+ adv7842_get_dv_timings_cap(sd), timings))
return 0;
v4l2_dbg(2, debug, sd,
@@ -2565,58 +2569,65 @@ struct adv7842_cfg_read_infoframe {
u8 payload_addr;
};
-static void log_infoframe(struct v4l2_subdev *sd, const struct adv7842_cfg_read_infoframe *cri)
+static const struct adv7842_cfg_read_infoframe adv7842_cri[] = {
+ { "AVI", 0x01, 0xe0, 0x00 },
+ { "Audio", 0x02, 0xe3, 0x1c },
+ { "SDP", 0x04, 0xe6, 0x2a },
+ { "Vendor", 0x10, 0xec, 0x54 }
+};
+
+static int adv7842_read_infoframe_buf(struct v4l2_subdev *sd, int index,
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN])
{
- int i;
- u8 buffer[32];
- union hdmi_infoframe frame;
- u8 len;
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct device *dev = &client->dev;
+ const struct adv7842_cfg_read_infoframe *cri = &adv7842_cri[index];
+ int len, i;
if (!(io_read(sd, 0x60) & cri->present_mask)) {
- v4l2_info(sd, "%s infoframe not received\n", cri->desc);
- return;
+ v4l2_dbg(1, debug, sd,
+ "%s infoframe not received\n", cri->desc);
+ return -ENOENT;
}
for (i = 0; i < 3; i++)
- buffer[i] = infoframe_read(sd, cri->head_addr + i);
+ buf[i] = infoframe_read(sd, cri->head_addr + i);
- len = buffer[2] + 1;
+ len = buf[2] + 1;
- if (len + 3 > sizeof(buffer)) {
- v4l2_err(sd, "%s: invalid %s infoframe length %d\n", __func__, cri->desc, len);
- return;
+ if (len + 3 > V4L2_DEBUGFS_IF_MAX_LEN) {
+ v4l2_err(sd, "%s: invalid %s infoframe length %d\n",
+ __func__, cri->desc, len);
+ return -ENOENT;
}
for (i = 0; i < len; i++)
- buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i);
-
- if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) {
- v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc);
- return;
- }
-
- hdmi_infoframe_log(KERN_INFO, dev, &frame);
+ buf[i + 3] = infoframe_read(sd, cri->payload_addr + i);
+ return len + 3;
}
static void adv7842_log_infoframes(struct v4l2_subdev *sd)
{
- int i;
- static const struct adv7842_cfg_read_infoframe cri[] = {
- { "AVI", 0x01, 0xe0, 0x00 },
- { "Audio", 0x02, 0xe3, 0x1c },
- { "SDP", 0x04, 0xe6, 0x2a },
- { "Vendor", 0x10, 0xec, 0x54 }
- };
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct device *dev = &client->dev;
+ union hdmi_infoframe frame;
+ u8 buffer[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ int len, i;
if (!(hdmi_read(sd, 0x05) & 0x80)) {
v4l2_info(sd, "receive DVI-D signal, no infoframes\n");
return;
}
- for (i = 0; i < ARRAY_SIZE(cri); i++)
- log_infoframe(sd, &cri[i]);
+ for (i = 0; i < ARRAY_SIZE(adv7842_cri); i++) {
+ len = adv7842_read_infoframe_buf(sd, i, buffer);
+ if (len < 0)
+ continue;
+
+ if (hdmi_infoframe_unpack(&frame, buffer, len) < 0)
+ v4l2_err(sd, "%s: unpack of %s infoframe failed\n",
+ __func__, adv7842_cri[i].desc);
+ else
+ hdmi_infoframe_log(KERN_INFO, dev, &frame);
+ }
}
#if 0
@@ -3263,6 +3274,41 @@ static int adv7842_subscribe_event(struct v4l2_subdev *sd,
}
}
+static ssize_t
+adv7842_debugfs_if_read(u32 type, void *priv, struct file *filp,
+ char __user *ubuf, size_t count, loff_t *ppos)
+{
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ struct v4l2_subdev *sd = priv;
+ int index;
+ int len;
+
+ if (!is_hdmi(sd))
+ return 0;
+
+ switch (type) {
+ case V4L2_DEBUGFS_IF_AVI:
+ index = 0;
+ break;
+ case V4L2_DEBUGFS_IF_AUDIO:
+ index = 1;
+ break;
+ case V4L2_DEBUGFS_IF_SPD:
+ index = 2;
+ break;
+ case V4L2_DEBUGFS_IF_HDMI:
+ index = 3;
+ break;
+ default:
+ return 0;
+ }
+
+ len = adv7842_read_infoframe_buf(sd, index, buf);
+ if (len > 0)
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+ return len < 0 ? 0 : len;
+}
+
static int adv7842_registered(struct v4l2_subdev *sd)
{
struct adv7842_state *state = to_state(sd);
@@ -3270,8 +3316,15 @@ static int adv7842_registered(struct v4l2_subdev *sd)
int err;
err = cec_register_adapter(state->cec_adap, &client->dev);
- if (err)
+ if (err) {
cec_delete_adapter(state->cec_adap);
+ } else {
+ state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+ state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI | V4L2_DEBUGFS_IF_AUDIO |
+ V4L2_DEBUGFS_IF_SPD | V4L2_DEBUGFS_IF_HDMI, sd,
+ adv7842_debugfs_if_read);
+ }
return err;
}
@@ -3280,6 +3333,10 @@ static void adv7842_unregistered(struct v4l2_subdev *sd)
struct adv7842_state *state = to_state(sd);
cec_unregister_adapter(state->cec_adap);
+ v4l2_debugfs_if_free(state->infoframes);
+ state->infoframes = NULL;
+ debugfs_remove_recursive(state->debugfs_dir);
+ state->debugfs_dir = NULL;
}
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c
index 5ddfd3dcb188..05b708bd0a64 100644
--- a/drivers/media/i2c/alvium-csi2.c
+++ b/drivers/media/i2c/alvium-csi2.c
@@ -16,7 +16,6 @@
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -2240,8 +2239,6 @@ free_ctrls:
static const struct v4l2_subdev_core_ops alvium_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops alvium_video_ops = {
@@ -2289,7 +2286,7 @@ static int alvium_subdev_init(struct alvium_dev *alvium)
v4l2_i2c_subdev_init(sd, client, &alvium_subdev_ops);
sd->internal_ops = &alvium_internal_ops;
- sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
alvium->pad.flags = MEDIA_PAD_FL_SOURCE;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c
index 16f88db14981..8b028a84f5bc 100644
--- a/drivers/media/i2c/ds90ub953.c
+++ b/drivers/media/i2c/ds90ub953.c
@@ -24,7 +24,6 @@
#include <media/i2c/ds90ub9xx.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>
@@ -717,8 +716,6 @@ static const struct v4l2_subdev_pad_ops ub953_pad_ops = {
static const struct v4l2_subdev_core_ops ub953_subdev_core_ops = {
.log_status = ub953_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_ops ub953_subdev_ops = {
@@ -1246,7 +1243,7 @@ static int ub953_subdev_init(struct ub953_data *priv)
priv->sd.internal_ops = &ub953_internal_ops;
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;
+ V4L2_SUBDEV_FL_STREAMS;
priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
priv->sd.entity.ops = &ub953_entity_ops;
diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
index ffe5f25f8647..33f362a00875 100644
--- a/drivers/media/i2c/ds90ub960.c
+++ b/drivers/media/i2c/ds90ub960.c
@@ -48,7 +48,6 @@
#include <media/i2c/ds90ub9xx.h>
#include <media/mipi-csi2.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -1286,7 +1285,7 @@ static int ub960_rxport_get_strobe_pos(struct ub960_data *priv,
clk_delay += v & UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK;
- ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
+ ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
if (ret)
return ret;
@@ -3085,8 +3084,6 @@ static int ub960_log_status(struct v4l2_subdev *sd)
static const struct v4l2_subdev_core_ops ub960_subdev_core_ops = {
.log_status = ub960_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_internal_ops ub960_internal_ops = {
@@ -3667,7 +3664,7 @@ static int ub960_create_subdev(struct ub960_data *priv)
}
priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_STREAMS;
+ V4L2_SUBDEV_FL_STREAMS;
priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
priv->sd.entity.ops = &ub960_entity_ops;
diff --git a/drivers/media/i2c/dw9768.c b/drivers/media/i2c/dw9768.c
index 18ef2b35c9aa..3a4d100b9199 100644
--- a/drivers/media/i2c/dw9768.c
+++ b/drivers/media/i2c/dw9768.c
@@ -374,7 +374,8 @@ static int dw9768_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
static int dw9768_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
- pm_runtime_put(sd->dev);
+ pm_runtime_mark_last_busy(sd->dev);
+ pm_runtime_put_autosuspend(sd->dev);
return 0;
}
@@ -471,10 +472,9 @@ static int dw9768_probe(struct i2c_client *client)
* to be powered on in an ACPI system. Similarly for power off in
* remove.
*/
- pm_runtime_enable(dev);
full_power = (is_acpi_node(dev_fwnode(dev)) &&
acpi_dev_state_d0(dev)) ||
- (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
+ (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM));
if (full_power) {
ret = dw9768_runtime_resume(dev);
if (ret < 0) {
@@ -484,23 +484,26 @@ static int dw9768_probe(struct i2c_client *client)
pm_runtime_set_active(dev);
}
+ pm_runtime_enable(dev);
ret = v4l2_async_register_subdev(&dw9768->sd);
if (ret < 0) {
dev_err(dev, "failed to register V4L2 subdev: %d", ret);
goto err_power_off;
}
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_use_autosuspend(dev);
pm_runtime_idle(dev);
return 0;
err_power_off:
+ pm_runtime_disable(dev);
if (full_power) {
dw9768_runtime_suspend(dev);
pm_runtime_set_suspended(dev);
}
err_clean_entity:
- pm_runtime_disable(dev);
media_entity_cleanup(&dw9768->sd.entity);
err_free_handler:
v4l2_ctrl_handler_free(&dw9768->ctrls);
@@ -517,12 +520,12 @@ static void dw9768_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(&dw9768->sd);
v4l2_ctrl_handler_free(&dw9768->ctrls);
media_entity_cleanup(&dw9768->sd.entity);
+ pm_runtime_disable(dev);
if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
- (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
+ (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM))) {
dw9768_runtime_suspend(dev);
pm_runtime_set_suspended(dev);
}
- pm_runtime_disable(dev);
}
static const struct of_device_id dw9768_of_table[] = {
diff --git a/drivers/media/i2c/gc0308.c b/drivers/media/i2c/gc0308.c
index fa754a8a39a6..069f42785b3c 100644
--- a/drivers/media/i2c/gc0308.c
+++ b/drivers/media/i2c/gc0308.c
@@ -18,7 +18,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -987,8 +986,6 @@ static const struct v4l2_ctrl_ops gc0308_ctrl_ops = {
static const struct v4l2_subdev_core_ops gc0308_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = gc0308_g_register,
.s_register = gc0308_s_register,
@@ -1338,7 +1335,6 @@ static int gc0308_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&gc0308->sd, client, &gc0308_subdev_ops);
gc0308->sd.internal_ops = &gc0308_internal_ops;
gc0308->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- gc0308->sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
ret = gc0308_init_controls(gc0308);
if (ret)
diff --git a/drivers/media/i2c/gc05a2.c b/drivers/media/i2c/gc05a2.c
index 0413c557e594..3f7f3d5abeeb 100644
--- a/drivers/media/i2c/gc05a2.c
+++ b/drivers/media/i2c/gc05a2.c
@@ -24,7 +24,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -1059,13 +1058,7 @@ static const struct v4l2_subdev_pad_ops gc05a2_subdev_pad_ops = {
.get_selection = gc05a2_get_selection,
};
-static const struct v4l2_subdev_core_ops gc05a2_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_ops gc05a2_subdev_ops = {
- .core = &gc05a2_core_ops,
.video = &gc05a2_video_ops,
.pad = &gc05a2_subdev_pad_ops,
};
@@ -1271,8 +1264,7 @@ static int gc05a2_probe(struct i2c_client *client)
return dev_err_probe(dev, ret,
"failed to init controls\n");
- gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
gc05a2->pad.flags = MEDIA_PAD_FL_SOURCE;
gc05a2->sd.dev = &client->dev;
gc05a2->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
diff --git a/drivers/media/i2c/gc08a3.c b/drivers/media/i2c/gc08a3.c
index 84de5cff958d..938709a677b6 100644
--- a/drivers/media/i2c/gc08a3.c
+++ b/drivers/media/i2c/gc08a3.c
@@ -24,7 +24,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -1001,13 +1000,7 @@ static const struct v4l2_subdev_pad_ops gc08a3_subdev_pad_ops = {
.get_selection = gc08a3_get_selection,
};
-static const struct v4l2_subdev_core_ops gc08a3_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_ops gc08a3_subdev_ops = {
- .core = &gc08a3_core_ops,
.video = &gc08a3_video_ops,
.pad = &gc08a3_subdev_pad_ops,
};
@@ -1247,8 +1240,7 @@ static int gc08a3_probe(struct i2c_client *client)
goto err_power_off;
}
- gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ gc08a3->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
gc08a3->pad.flags = MEDIA_PAD_FL_SOURCE;
gc08a3->sd.dev = &client->dev;
gc08a3->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
diff --git a/drivers/media/i2c/gc2145.c b/drivers/media/i2c/gc2145.c
index 667bb756d056..ba02161d46e7 100644
--- a/drivers/media/i2c/gc2145.c
+++ b/drivers/media/i2c/gc2145.c
@@ -21,7 +21,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
@@ -899,9 +898,11 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145,
return ret;
}
-static int gc2145_start_streaming(struct gc2145 *gc2145,
- struct v4l2_subdev_state *state)
+static int gc2145_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
const struct gc2145_format *gc2145_format;
struct v4l2_mbus_framefmt *fmt;
@@ -967,8 +968,11 @@ err_rpm_put:
return ret;
}
-static void gc2145_stop_streaming(struct gc2145 *gc2145)
+static int gc2145_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct gc2145 *gc2145 = to_gc2145(sd);
struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd);
int ret = 0;
@@ -983,22 +987,6 @@ static void gc2145_stop_streaming(struct gc2145 *gc2145)
pm_runtime_mark_last_busy(&client->dev);
pm_runtime_put_autosuspend(&client->dev);
-}
-
-static int gc2145_set_stream(struct v4l2_subdev *sd, int enable)
-{
- struct gc2145 *gc2145 = to_gc2145(sd);
- struct v4l2_subdev_state *state;
- int ret = 0;
-
- state = v4l2_subdev_lock_and_get_active_state(sd);
-
- if (enable)
- ret = gc2145_start_streaming(gc2145, state);
- else
- gc2145_stop_streaming(gc2145);
-
- v4l2_subdev_unlock_state(state);
return ret;
}
@@ -1123,13 +1111,8 @@ static const u8 test_pattern_val[] = {
GC2145_TEST_UNIFORM | GC2145_TEST_BLACK,
};
-static const struct v4l2_subdev_core_ops gc2145_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_video_ops gc2145_video_ops = {
- .s_stream = gc2145_set_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops gc2145_pad_ops = {
@@ -1138,10 +1121,11 @@ static const struct v4l2_subdev_pad_ops gc2145_pad_ops = {
.set_fmt = gc2145_set_pad_format,
.get_selection = gc2145_get_selection,
.enum_frame_size = gc2145_enum_frame_size,
+ .enable_streams = gc2145_enable_streams,
+ .disable_streams = gc2145_disable_streams,
};
static const struct v4l2_subdev_ops gc2145_subdev_ops = {
- .core = &gc2145_core_ops,
.video = &gc2145_video_ops,
.pad = &gc2145_pad_ops,
};
@@ -1407,8 +1391,7 @@ static int gc2145_probe(struct i2c_client *client)
goto error_power_off;
/* Initialize subdev */
- gc2145->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ gc2145->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
gc2145->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
/* Initialize source pad */
diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c
index f31f9886c924..3ac42d1ab8b4 100644
--- a/drivers/media/i2c/hi556.c
+++ b/drivers/media/i2c/hi556.c
@@ -644,7 +644,7 @@ struct hi556 {
/* Current mode */
const struct hi556_mode *cur_mode;
- /* To serialize asynchronus callbacks */
+ /* To serialize asynchronous callbacks */
struct mutex mutex;
/* True if the device has been identified */
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index e78a80b2bb2e..2d54cea113e1 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -26,7 +26,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
@@ -922,11 +921,6 @@ static int imx219_init_state(struct v4l2_subdev *sd,
return 0;
}
-static const struct v4l2_subdev_core_ops imx219_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_video_ops imx219_video_ops = {
.s_stream = imx219_set_stream,
};
@@ -940,7 +934,6 @@ static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
};
static const struct v4l2_subdev_ops imx219_subdev_ops = {
- .core = &imx219_core_ops,
.video = &imx219_video_ops,
.pad = &imx219_pad_ops,
};
@@ -1166,8 +1159,7 @@ static int imx219_probe(struct i2c_client *client)
goto error_power_off;
/* Initialize subdev */
- imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
/* Initialize source pad */
diff --git a/drivers/media/i2c/imx283.c b/drivers/media/i2c/imx283.c
index 94276f4f2d83..f676faf4b301 100644
--- a/drivers/media/i2c/imx283.c
+++ b/drivers/media/i2c/imx283.c
@@ -32,7 +32,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
@@ -1284,11 +1283,6 @@ static int imx283_get_selection(struct v4l2_subdev *sd,
}
}
-static const struct v4l2_subdev_core_ops imx283_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_video_ops imx283_video_ops = {
.s_stream = v4l2_subdev_s_stream_helper,
};
@@ -1308,7 +1302,6 @@ static const struct v4l2_subdev_internal_ops imx283_internal_ops = {
};
static const struct v4l2_subdev_ops imx283_subdev_ops = {
- .core = &imx283_core_ops,
.video = &imx283_video_ops,
.pad = &imx283_pad_ops,
};
@@ -1548,8 +1541,7 @@ static int imx283_probe(struct i2c_client *client)
goto error_pm;
/* Initialize subdev */
- imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ imx283->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
imx283->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
imx283->sd.internal_ops = &imx283_internal_ops;
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index 458905dfb3e1..f5ee6bd3b52d 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -24,7 +24,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -78,7 +77,6 @@
#define IMX290_ADBIT2 CCI_REG8(0x317c)
#define IMX290_ADBIT2_10BIT 0x12
#define IMX290_ADBIT2_12BIT 0x00
-#define IMX290_CHIP_ID CCI_REG16_LE(0x319a)
#define IMX290_ADBIT3 CCI_REG8(0x31ec)
#define IMX290_ADBIT3_10BIT 0x37
#define IMX290_ADBIT3_12BIT 0x0e
@@ -1211,11 +1209,6 @@ static int imx290_entity_init_state(struct v4l2_subdev *subdev,
return 0;
}
-static const struct v4l2_subdev_core_ops imx290_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_video_ops imx290_video_ops = {
.s_stream = imx290_set_stream,
};
@@ -1229,7 +1222,6 @@ static const struct v4l2_subdev_pad_ops imx290_pad_ops = {
};
static const struct v4l2_subdev_ops imx290_subdev_ops = {
- .core = &imx290_core_ops,
.video = &imx290_video_ops,
.pad = &imx290_pad_ops,
};
@@ -1250,11 +1242,20 @@ static int imx290_subdev_init(struct imx290 *imx290)
imx290->current_mode = &imx290_modes_ptr(imx290)[0];
+ /*
+ * After linking the subdev with the imx290 instance, we are allowed to
+ * use the pm_runtime functions. Decrease the PM usage count. The device
+ * will get suspended after the autosuspend delay, turning the power
+ * off. However, the communication happening in imx290_ctrl_update()
+ * will already be prevented even before the delay.
+ */
v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
- imx290->sd.internal_ops = &imx290_internal_ops;
- imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
imx290->sd.dev = imx290->dev;
+ pm_runtime_mark_last_busy(imx290->dev);
+ pm_runtime_put_autosuspend(imx290->dev);
+
+ imx290->sd.internal_ops = &imx290_internal_ops;
+ imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
imx290->sd.entity.ops = &imx290_subdev_entity_ops;
imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
@@ -1580,6 +1581,16 @@ static int imx290_probe(struct i2c_client *client)
pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);
+ /*
+ * Make sure the sensor is available, in STANDBY and not streaming
+ * before the V4L2 subdev is initialized.
+ */
+ ret = imx290_stop_streaming(imx290);
+ if (ret) {
+ ret = dev_err_probe(dev, ret, "Could not initialize device\n");
+ goto err_pm;
+ }
+
/* Initialize the V4L2 subdev. */
ret = imx290_subdev_init(imx290);
if (ret)
@@ -1599,13 +1610,6 @@ static int imx290_probe(struct i2c_client *client)
goto err_subdev;
}
- /*
- * Decrease the PM usage count. The device will get suspended after the
- * autosuspend delay, turning the power off.
- */
- pm_runtime_mark_last_busy(dev);
- pm_runtime_put_autosuspend(dev);
-
return 0;
err_subdev:
diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c
index a20b0db330d3..3f7924aa1bd3 100644
--- a/drivers/media/i2c/imx415.c
+++ b/drivers/media/i2c/imx415.c
@@ -1113,8 +1113,7 @@ static int imx415_subdev_init(struct imx415 *sensor)
if (ret)
return ret;
- sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
sensor->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&sensor->subdev.entity, 1, &sensor->pad);
diff --git a/drivers/media/i2c/max96717.c b/drivers/media/i2c/max96717.c
index 4e85b8eb1e77..9259d58ba734 100644
--- a/drivers/media/i2c/max96717.c
+++ b/drivers/media/i2c/max96717.c
@@ -697,8 +697,10 @@ static int max96717_subdev_init(struct max96717_priv *priv)
priv->pads[MAX96717_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);
- if (ret)
- return dev_err_probe(dev, ret, "Failed to init pads\n");
+ if (ret) {
+ dev_err_probe(dev, ret, "Failed to init pads\n");
+ goto err_free_ctrl;
+ }
ret = v4l2_subdev_init_finalize(&priv->sd);
if (ret) {
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c
index d8735c246e52..4ef5fb06131d 100644
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -17,14 +17,12 @@
#include <linux/log2.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_graph.h>
#include <linux/pm.h>
+#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
-#include <media/i2c/mt9p031.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@@ -113,18 +111,25 @@
#define MT9P031_TEST_PATTERN_RED 0xa2
#define MT9P031_TEST_PATTERN_BLUE 0xa3
+struct mt9p031_model_info {
+ u32 code;
+};
+
struct mt9p031 {
struct v4l2_subdev subdev;
struct media_pad pad;
struct v4l2_rect crop; /* Sensor window */
struct v4l2_mbus_framefmt format;
- struct mt9p031_platform_data *pdata;
struct mutex power_lock; /* lock to protect power_count */
int power_count;
struct clk *clk;
struct regulator_bulk_data regulators[3];
+ unsigned int pixclk_pol:1;
+ int ext_freq;
+ int target_freq;
+
u32 code;
struct aptina_pll pll;
unsigned int clk_div;
@@ -225,7 +230,6 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
};
struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
- struct mt9p031_platform_data *pdata = mt9p031->pdata;
unsigned long ext_freq;
int ret;
@@ -233,7 +237,7 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
if (IS_ERR(mt9p031->clk))
return PTR_ERR(mt9p031->clk);
- ret = clk_set_rate(mt9p031->clk, pdata->ext_freq);
+ ret = clk_set_rate(mt9p031->clk, mt9p031->ext_freq);
if (ret < 0)
return ret;
@@ -245,7 +249,7 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
if (ext_freq > limits.ext_clock_max) {
unsigned int div;
- div = DIV_ROUND_UP(ext_freq, pdata->target_freq);
+ div = DIV_ROUND_UP(ext_freq, mt9p031->target_freq);
div = roundup_pow_of_two(div) / 2;
mt9p031->clk_div = min_t(unsigned int, div, 64);
@@ -255,7 +259,7 @@ static int mt9p031_clk_setup(struct mt9p031 *mt9p031)
}
mt9p031->pll.ext_clock = ext_freq;
- mt9p031->pll.pix_clock = pdata->target_freq;
+ mt9p031->pll.pix_clock = mt9p031->target_freq;
mt9p031->use_pll = true;
return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
@@ -376,7 +380,7 @@ static int __mt9p031_set_power(struct mt9p031 *mt9p031, bool on)
}
/* Configure the pixel clock polarity */
- if (mt9p031->pdata && mt9p031->pdata->pixclk_pol) {
+ if (mt9p031->pixclk_pol) {
ret = mt9p031_write(client, MT9P031_PIXEL_CLOCK_CONTROL,
MT9P031_PIXEL_CLOCK_INVERT);
if (ret < 0)
@@ -1057,53 +1061,41 @@ static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = {
* Driver initialization and probing
*/
-static struct mt9p031_platform_data *
-mt9p031_get_pdata(struct i2c_client *client)
+static int mt9p031_parse_properties(struct mt9p031 *mt9p031, struct device *dev)
{
- struct mt9p031_platform_data *pdata = NULL;
- struct device_node *np;
struct v4l2_fwnode_endpoint endpoint = {
.bus_type = V4L2_MBUS_PARALLEL
};
+ struct fwnode_handle *np;
+ int ret;
- if (!IS_ENABLED(CONFIG_OF) || !client->dev.of_node)
- return client->dev.platform_data;
-
- np = of_graph_get_endpoint_by_regs(client->dev.of_node, 0, -1);
+ np = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
if (!np)
- return NULL;
-
- if (v4l2_fwnode_endpoint_parse(of_fwnode_handle(np), &endpoint) < 0)
- goto done;
+ return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
- pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- goto done;
+ ret = v4l2_fwnode_endpoint_parse(np, &endpoint);
+ fwnode_handle_put(np);
+ if (ret)
+ return dev_err_probe(dev, -EINVAL, "could not parse endpoint\n");
- of_property_read_u32(np, "input-clock-frequency", &pdata->ext_freq);
- of_property_read_u32(np, "pixel-clock-frequency", &pdata->target_freq);
+ fwnode_property_read_u32(np, "input-clock-frequency",
+ &mt9p031->ext_freq);
+ fwnode_property_read_u32(np, "pixel-clock-frequency",
+ &mt9p031->target_freq);
- pdata->pixclk_pol = !!(endpoint.bus.parallel.flags &
- V4L2_MBUS_PCLK_SAMPLE_RISING);
+ mt9p031->pixclk_pol = !!(endpoint.bus.parallel.flags &
+ V4L2_MBUS_PCLK_SAMPLE_RISING);
-done:
- of_node_put(np);
- return pdata;
+ return 0;
}
static int mt9p031_probe(struct i2c_client *client)
{
- struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client);
struct i2c_adapter *adapter = client->adapter;
struct mt9p031 *mt9p031;
unsigned int i;
int ret;
- if (pdata == NULL) {
- dev_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
dev_warn(&client->dev,
"I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
@@ -1114,10 +1106,13 @@ static int mt9p031_probe(struct i2c_client *client)
if (mt9p031 == NULL)
return -ENOMEM;
- mt9p031->pdata = pdata;
+ ret = mt9p031_parse_properties(mt9p031, &client->dev);
+ if (ret)
+ return ret;
+
mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF;
mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC;
- mt9p031->code = (uintptr_t)i2c_get_match_data(client);
+ mt9p031->code = (uintptr_t)device_get_match_data(&client->dev);
mt9p031->regulators[0].supply = "vdd";
mt9p031->regulators[1].supply = "vdd_io";
@@ -1145,8 +1140,8 @@ static int mt9p031_probe(struct i2c_client *client)
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pdata->target_freq,
- pdata->target_freq, 1, pdata->target_freq);
+ V4L2_CID_PIXEL_RATE, mt9p031->target_freq,
+ mt9p031->target_freq, 1, mt9p031->target_freq);
v4l2_ctrl_new_std_menu_items(&mt9p031->ctrls, &mt9p031_ctrl_ops,
V4L2_CID_TEST_PATTERN,
ARRAY_SIZE(mt9p031_test_pattern_menu) - 1, 0,
@@ -1213,18 +1208,18 @@ static void mt9p031_remove(struct i2c_client *client)
mutex_destroy(&mt9p031->power_lock);
}
-static const struct i2c_device_id mt9p031_id[] = {
- { "mt9p006", MEDIA_BUS_FMT_SGRBG12_1X12 },
- { "mt9p031", MEDIA_BUS_FMT_SGRBG12_1X12 },
- { "mt9p031m", MEDIA_BUS_FMT_Y12_1X12 },
- { /* sentinel */ }
+static const struct mt9p031_model_info mt9p031_models_bayer = {
+ .code = MEDIA_BUS_FMT_SGRBG12_1X12
+};
+
+static const struct mt9p031_model_info mt9p031_models_mono = {
+ .code = MEDIA_BUS_FMT_Y12_1X12
};
-MODULE_DEVICE_TABLE(i2c, mt9p031_id);
static const struct of_device_id mt9p031_of_match[] = {
- { .compatible = "aptina,mt9p006", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 },
- { .compatible = "aptina,mt9p031", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 },
- { .compatible = "aptina,mt9p031m", .data = (void *)MEDIA_BUS_FMT_Y12_1X12 },
+ { .compatible = "aptina,mt9p006", .data = &mt9p031_models_bayer },
+ { .compatible = "aptina,mt9p031", .data = &mt9p031_models_bayer },
+ { .compatible = "aptina,mt9p031m", .data = &mt9p031_models_mono },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mt9p031_of_match);
@@ -1236,7 +1231,6 @@ static struct i2c_driver mt9p031_i2c_driver = {
},
.probe = mt9p031_probe,
.remove = mt9p031_remove,
- .id_table = mt9p031_id,
};
module_i2c_driver(mt9p031_i2c_driver);
diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c
index 0b9fb1ddbe59..141cb6f75b55 100644
--- a/drivers/media/i2c/ov01a10.c
+++ b/drivers/media/i2c/ov01a10.c
@@ -13,7 +13,6 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#define OV01A10_LINK_FREQ_400MHZ 400000000ULL
@@ -804,8 +803,6 @@ static int ov01a10_get_selection(struct v4l2_subdev *sd,
static const struct v4l2_subdev_core_ops ov01a10_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops ov01a10_video_ops = {
@@ -892,8 +889,7 @@ static int ov01a10_probe(struct i2c_client *client)
}
ov01a10->sd.state_lock = ov01a10->ctrl_handler.lock;
- ov01a10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
- V4L2_SUBDEV_FL_HAS_EVENTS;
+ ov01a10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov01a10->sd.entity.ops = &ov01a10_subdev_entity_ops;
ov01a10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ov01a10->pad.flags = MEDIA_PAD_FL_SOURCE;
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index 7ead3c720e0e..b9682264e2f5 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -3,10 +3,13 @@
#include <linux/unaligned.h>
#include <linux/acpi.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
+#include <linux/gpio/consumer.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -1215,7 +1218,7 @@ static const char * const ov08x40_test_pattern_menu[] = {
/* Configurations for supported link frequencies */
#define OV08X40_LINK_FREQ_400MHZ 400000000ULL
#define OV08X40_SCLK_96MHZ 96000000ULL
-#define OV08X40_EXT_CLK 19200000
+#define OV08X40_XVCLK 19200000
#define OV08X40_DATA_LANES 4
/*
@@ -1279,6 +1282,12 @@ static const struct ov08x40_mode supported_modes[] = {
},
};
+static const char * const ov08x40_supply_names[] = {
+ "dovdd", /* Digital I/O power */
+ "avdd", /* Analog power */
+ "dvdd", /* Digital core power */
+};
+
struct ov08x40 {
struct v4l2_subdev sd;
struct media_pad pad;
@@ -1291,6 +1300,10 @@ struct ov08x40 {
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *exposure;
+ struct clk *xvclk;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(ov08x40_supply_names)];
+
/* Current mode */
const struct ov08x40_mode *cur_mode;
@@ -1303,6 +1316,61 @@ struct ov08x40 {
#define to_ov08x40(_sd) container_of(_sd, struct ov08x40, sd)
+static int ov08x40_power_on(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov08x40 *ov08x = to_ov08x40(sd);
+ int ret;
+
+ if (is_acpi_node(dev_fwnode(dev)))
+ return 0;
+
+ ret = clk_prepare_enable(ov08x->xvclk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable xvclk\n");
+ return ret;
+ }
+
+ if (ov08x->reset_gpio) {
+ gpiod_set_value_cansleep(ov08x->reset_gpio, 1);
+ usleep_range(1000, 2000);
+ }
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ov08x40_supply_names),
+ ov08x->supplies);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable regulators\n");
+ goto disable_clk;
+ }
+
+ gpiod_set_value_cansleep(ov08x->reset_gpio, 0);
+ usleep_range(1500, 1800);
+
+ return 0;
+
+disable_clk:
+ gpiod_set_value_cansleep(ov08x->reset_gpio, 1);
+ clk_disable_unprepare(ov08x->xvclk);
+
+ return ret;
+}
+
+static int ov08x40_power_off(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct ov08x40 *ov08x = to_ov08x40(sd);
+
+ if (is_acpi_node(dev_fwnode(dev)))
+ return 0;
+
+ gpiod_set_value_cansleep(ov08x->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(ov08x40_supply_names),
+ ov08x->supplies);
+ clk_disable_unprepare(ov08x->xvclk);
+
+ return 0;
+}
+
/* Read registers up to 4 at a time */
static int ov08x40_read_reg(struct ov08x40 *ov08x,
u16 reg, u32 len, u32 *val)
@@ -1339,15 +1407,13 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x,
return 0;
}
-static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg,
- u16 last_reg, u8 val)
+static int __ov08x40_burst_fill_regs(struct i2c_client *client, u16 first_reg,
+ u16 last_reg, size_t num_regs, u8 val)
{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
struct i2c_msg msgs;
- size_t i, num_regs;
+ size_t i;
int ret;
- num_regs = last_reg - first_reg + 1;
msgs.addr = client->addr;
msgs.flags = 0;
msgs.len = 2 + num_regs;
@@ -1373,6 +1439,31 @@ static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg,
return 0;
}
+static int ov08x40_burst_fill_regs(struct ov08x40 *ov08x, u16 first_reg,
+ u16 last_reg, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
+ size_t num_regs, num_write_regs;
+ int ret;
+
+ num_regs = last_reg - first_reg + 1;
+ num_write_regs = num_regs;
+
+ if (client->adapter->quirks && client->adapter->quirks->max_write_len)
+ num_write_regs = client->adapter->quirks->max_write_len - 2;
+
+ while (first_reg < last_reg) {
+ ret = __ov08x40_burst_fill_regs(client, first_reg, last_reg,
+ num_write_regs, val);
+ if (ret)
+ return ret;
+
+ first_reg += num_write_regs;
+ }
+
+ return 0;
+}
+
/* Write registers up to 4 at a time */
static int ov08x40_write_reg(struct ov08x40 *ov08x,
u16 reg, u32 len, u32 __val)
@@ -2049,7 +2140,7 @@ static void ov08x40_free_controls(struct ov08x40 *ov08x)
mutex_destroy(&ov08x->mutex);
}
-static int ov08x40_check_hwcfg(struct device *dev)
+static int ov08x40_check_hwcfg(struct ov08x40 *ov08x, struct device *dev)
{
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
@@ -2058,21 +2149,46 @@ static int ov08x40_check_hwcfg(struct device *dev)
struct fwnode_handle *fwnode = dev_fwnode(dev);
unsigned int i, j;
int ret;
- u32 ext_clk;
+ u32 xvclk_rate;
if (!fwnode)
return -ENXIO;
- ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
- &ext_clk);
- if (ret) {
- dev_err(dev, "can't get clock frequency");
- return ret;
+ if (!is_acpi_node(fwnode)) {
+ ov08x->xvclk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ov08x->xvclk)) {
+ dev_err(dev, "could not get xvclk clock (%pe)\n",
+ ov08x->xvclk);
+ return PTR_ERR(ov08x->xvclk);
+ }
+
+ xvclk_rate = clk_get_rate(ov08x->xvclk);
+
+ ov08x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(ov08x->reset_gpio))
+ return PTR_ERR(ov08x->reset_gpio);
+
+ for (i = 0; i < ARRAY_SIZE(ov08x40_supply_names); i++)
+ ov08x->supplies[i].supply = ov08x40_supply_names[i];
+
+ ret = devm_regulator_bulk_get(dev,
+ ARRAY_SIZE(ov08x40_supply_names),
+ ov08x->supplies);
+ if (ret)
+ return ret;
+ } else {
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
+ &xvclk_rate);
+ if (ret) {
+ dev_err(dev, "can't get clock frequency");
+ return ret;
+ }
}
- if (ext_clk != OV08X40_EXT_CLK) {
+ if (xvclk_rate != OV08X40_XVCLK) {
dev_err(dev, "external clock %d is not supported",
- ext_clk);
+ xvclk_rate);
return -EINVAL;
}
@@ -2120,32 +2236,37 @@ out_err:
}
static int ov08x40_probe(struct i2c_client *client)
-{
- struct ov08x40 *ov08x;
+{ struct ov08x40 *ov08x;
int ret;
bool full_power;
+ ov08x = devm_kzalloc(&client->dev, sizeof(*ov08x), GFP_KERNEL);
+ if (!ov08x)
+ return -ENOMEM;
+
/* Check HW config */
- ret = ov08x40_check_hwcfg(&client->dev);
+ ret = ov08x40_check_hwcfg(ov08x, &client->dev);
if (ret) {
dev_err(&client->dev, "failed to check hwcfg: %d", ret);
return ret;
}
- ov08x = devm_kzalloc(&client->dev, sizeof(*ov08x), GFP_KERNEL);
- if (!ov08x)
- return -ENOMEM;
-
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops);
full_power = acpi_dev_state_d0(&client->dev);
if (full_power) {
+ ret = ov08x40_power_on(&client->dev);
+ if (ret) {
+ dev_err(&client->dev, "failed to power on\n");
+ return ret;
+ }
+
/* Check module identity */
ret = ov08x40_identify_module(ov08x);
if (ret) {
dev_err(&client->dev, "failed to find sensor: %d\n", ret);
- return ret;
+ goto probe_power_off;
}
}
@@ -2154,7 +2275,7 @@ static int ov08x40_probe(struct i2c_client *client)
ret = ov08x40_init_controls(ov08x);
if (ret)
- return ret;
+ goto probe_power_off;
/* Initialize subdev */
ov08x->sd.internal_ops = &ov08x40_internal_ops;
@@ -2187,6 +2308,9 @@ error_media_entity:
error_handler_free:
ov08x40_free_controls(ov08x);
+probe_power_off:
+ ov08x40_power_off(&client->dev);
+
return ret;
}
@@ -2201,6 +2325,8 @@ static void ov08x40_remove(struct i2c_client *client)
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
+
+ ov08x40_power_off(&client->dev);
}
#ifdef CONFIG_ACPI
@@ -2212,10 +2338,17 @@ static const struct acpi_device_id ov08x40_acpi_ids[] = {
MODULE_DEVICE_TABLE(acpi, ov08x40_acpi_ids);
#endif
+static const struct of_device_id ov08x40_of_match[] = {
+ { .compatible = "ovti,ov08x40" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ov08x40_of_match);
+
static struct i2c_driver ov08x40_i2c_driver = {
.driver = {
.name = "ov08x40",
.acpi_match_table = ACPI_PTR(ov08x40_acpi_ids),
+ .of_match_table = ov08x40_of_match,
},
.probe = ov08x40_probe,
.remove = ov08x40_remove,
diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c
index bd0b2f0f0d45..c484b753a718 100644
--- a/drivers/media/i2c/ov2740.c
+++ b/drivers/media/i2c/ov2740.c
@@ -530,7 +530,7 @@ struct ov2740 {
/* Current mode */
const struct ov2740_mode *cur_mode;
- /* NVM data inforamtion */
+ /* NVM data information */
struct nvm_data *nvm;
/* Supported modes */
@@ -1132,7 +1132,8 @@ static int ov2740_check_hwcfg(struct device *dev)
*/
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep)
- return -EPROBE_DEFER;
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "waiting for fwnode graph endpoint\n");
ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
if (ret) {
@@ -1330,7 +1331,7 @@ static int ov2740_probe(struct i2c_client *client)
ret = ov2740_check_hwcfg(dev);
if (ret)
- return dev_err_probe(dev, ret, "failed to check HW configuration\n");
+ return ret;
ov2740->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(ov2740->reset_gpio)) {
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index c1d3fce4a7d3..da5cb5f45a4f 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -377,7 +377,7 @@ struct reg_value {
struct ov5640_timings {
/* Analog crop rectangle. */
struct v4l2_rect analog_crop;
- /* Visibile crop: from analog crop top-left corner. */
+ /* Visible crop: from analog crop top-left corner. */
struct v4l2_rect crop;
/* Total pixels per line: width + fixed hblank. */
u32 htot;
diff --git a/drivers/media/i2c/ov5645.c b/drivers/media/i2c/ov5645.c
index 0c32bd2940ec..004d0ee5c3f5 100644
--- a/drivers/media/i2c/ov5645.c
+++ b/drivers/media/i2c/ov5645.c
@@ -88,7 +88,6 @@ struct ov5645 {
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_fwnode_endpoint ep;
- struct v4l2_mbus_framefmt fmt;
struct v4l2_rect crop;
struct clk *xclk;
@@ -105,8 +104,6 @@ struct ov5645 {
u8 timing_tc_reg20;
u8 timing_tc_reg21;
- struct mutex power_lock; /* lock to protect power state */
-
struct gpio_desc *enable_gpio;
struct gpio_desc *rst_gpio;
};
@@ -781,11 +778,8 @@ static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl)
struct ov5645, ctrls);
int ret;
- mutex_lock(&ov5645->power_lock);
- if (!pm_runtime_get_if_in_use(ov5645->dev)) {
- mutex_unlock(&ov5645->power_lock);
+ if (!pm_runtime_get_if_in_use(ov5645->dev))
return 0;
- }
switch (ctrl->id) {
case V4L2_CID_SATURATION:
@@ -816,7 +810,6 @@ static int ov5645_s_ctrl(struct v4l2_ctrl *ctrl)
pm_runtime_mark_last_busy(ov5645->dev);
pm_runtime_put_autosuspend(ov5645->dev);
- mutex_unlock(&ov5645->power_lock);
return ret;
}
@@ -855,49 +848,6 @@ static int ov5645_enum_frame_size(struct v4l2_subdev *subdev,
return 0;
}
-static struct v4l2_mbus_framefmt *
-__ov5645_get_pad_format(struct ov5645 *ov5645,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad,
- enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_state_get_format(sd_state, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &ov5645->fmt;
- default:
- return NULL;
- }
-}
-
-static int ov5645_get_format(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct ov5645 *ov5645 = to_ov5645(sd);
-
- format->format = *__ov5645_get_pad_format(ov5645, sd_state,
- format->pad,
- format->which);
- return 0;
-}
-
-static struct v4l2_rect *
-__ov5645_get_pad_crop(struct ov5645 *ov5645,
- struct v4l2_subdev_state *sd_state,
- unsigned int pad, enum v4l2_subdev_format_whence which)
-{
- switch (which) {
- case V4L2_SUBDEV_FORMAT_TRY:
- return v4l2_subdev_state_get_crop(sd_state, pad);
- case V4L2_SUBDEV_FORMAT_ACTIVE:
- return &ov5645->crop;
- default:
- return NULL;
- }
-}
-
static int ov5645_set_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *format)
@@ -908,33 +858,30 @@ static int ov5645_set_format(struct v4l2_subdev *sd,
const struct ov5645_mode_info *new_mode;
int ret;
- __crop = __ov5645_get_pad_crop(ov5645, sd_state, format->pad,
- format->which);
-
+ __crop = v4l2_subdev_state_get_crop(sd_state, 0);
new_mode = v4l2_find_nearest_size(ov5645_mode_info_data,
- ARRAY_SIZE(ov5645_mode_info_data),
- width, height,
- format->format.width, format->format.height);
+ ARRAY_SIZE(ov5645_mode_info_data),
+ width, height, format->format.width,
+ format->format.height);
__crop->width = new_mode->width;
__crop->height = new_mode->height;
if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- ret = v4l2_ctrl_s_ctrl_int64(ov5645->pixel_clock,
- new_mode->pixel_clock);
+ ret = __v4l2_ctrl_s_ctrl_int64(ov5645->pixel_clock,
+ new_mode->pixel_clock);
if (ret < 0)
return ret;
- ret = v4l2_ctrl_s_ctrl(ov5645->link_freq,
- new_mode->link_freq);
+ ret = __v4l2_ctrl_s_ctrl(ov5645->link_freq,
+ new_mode->link_freq);
if (ret < 0)
return ret;
ov5645->current_mode = new_mode;
}
- __format = __ov5645_get_pad_format(ov5645, sd_state, format->pad,
- format->which);
+ __format = v4l2_subdev_state_get_format(sd_state, 0);
__format->width = __crop->width;
__format->height = __crop->height;
__format->code = MEDIA_BUS_FMT_UYVY8_1X16;
@@ -949,11 +896,15 @@ static int ov5645_set_format(struct v4l2_subdev *sd,
static int ov5645_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *sd_state)
{
- struct v4l2_subdev_format fmt = { 0 };
-
- fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
- fmt.format.width = 1920;
- fmt.format.height = 1080;
+ struct v4l2_subdev_format fmt = {
+ .which = V4L2_SUBDEV_FORMAT_TRY,
+ .pad = 0,
+ .format = {
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .width = ov5645_mode_info_data[1].width,
+ .height = ov5645_mode_info_data[1].height,
+ },
+ };
ov5645_set_format(subdev, sd_state, &fmt);
@@ -964,82 +915,88 @@ static int ov5645_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_selection *sel)
{
- struct ov5645 *ov5645 = to_ov5645(sd);
-
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
- sel->r = *__ov5645_get_pad_crop(ov5645, sd_state, sel->pad,
- sel->which);
+ sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
return 0;
}
-static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable)
+static int ov5645_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
- struct ov5645 *ov5645 = to_ov5645(subdev);
+ struct ov5645 *ov5645 = to_ov5645(sd);
int ret;
- if (enable) {
- ret = pm_runtime_resume_and_get(ov5645->dev);
- if (ret < 0)
- return ret;
+ ret = pm_runtime_resume_and_get(ov5645->dev);
+ if (ret < 0)
+ return ret;
- ret = ov5645_set_register_array(ov5645,
+ ret = ov5645_set_register_array(ov5645,
ov5645->current_mode->data,
ov5645->current_mode->data_size);
- if (ret < 0) {
- dev_err(ov5645->dev, "could not set mode %dx%d\n",
- ov5645->current_mode->width,
- ov5645->current_mode->height);
- goto err_rpm_put;
- }
- ret = v4l2_ctrl_handler_setup(&ov5645->ctrls);
- if (ret < 0) {
- dev_err(ov5645->dev, "could not sync v4l2 controls\n");
- goto err_rpm_put;
- }
-
- ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45);
- if (ret < 0)
- goto err_rpm_put;
-
- ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
- OV5645_SYSTEM_CTRL0_START);
- if (ret < 0)
- goto err_rpm_put;
- } else {
- ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40);
- if (ret < 0)
- goto stream_off_rpm_put;
+ if (ret < 0) {
+ dev_err(ov5645->dev, "could not set mode %dx%d\n",
+ ov5645->current_mode->width,
+ ov5645->current_mode->height);
+ goto err_rpm_put;
+ }
+ ret = __v4l2_ctrl_handler_setup(&ov5645->ctrls);
+ if (ret < 0) {
+ dev_err(ov5645->dev, "could not sync v4l2 controls\n");
+ goto err_rpm_put;
+ }
- ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
- OV5645_SYSTEM_CTRL0_STOP);
+ ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45);
+ if (ret < 0)
+ goto err_rpm_put;
- goto stream_off_rpm_put;
- }
+ ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
+ OV5645_SYSTEM_CTRL0_START);
+ if (ret < 0)
+ goto err_rpm_put;
return 0;
err_rpm_put:
pm_runtime_put_sync(ov5645->dev);
return ret;
+}
+
+static int ov5645_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct ov5645 *ov5645 = to_ov5645(sd);
+ int ret;
+
+ ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40);
+ if (ret < 0)
+ goto rpm_put;
-stream_off_rpm_put:
+ ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,
+ OV5645_SYSTEM_CTRL0_STOP);
+
+rpm_put:
pm_runtime_mark_last_busy(ov5645->dev);
pm_runtime_put_autosuspend(ov5645->dev);
+
return ret;
}
static const struct v4l2_subdev_video_ops ov5645_video_ops = {
- .s_stream = ov5645_s_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops ov5645_subdev_pad_ops = {
.enum_mbus_code = ov5645_enum_mbus_code,
.enum_frame_size = ov5645_enum_frame_size,
- .get_fmt = ov5645_get_format,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = ov5645_set_format,
.get_selection = ov5645_get_selection,
+ .enable_streams = ov5645_enable_streams,
+ .disable_streams = ov5645_disable_streams,
};
static const struct v4l2_subdev_ops ov5645_subdev_ops = {
@@ -1069,51 +1026,44 @@ static int ov5645_probe(struct i2c_client *client)
ov5645->dev = dev;
endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
- if (!endpoint) {
- dev_err(dev, "endpoint node not found\n");
- return -EINVAL;
- }
+ if (!endpoint)
+ return dev_err_probe(dev, -EINVAL,
+ "endpoint node not found\n");
ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
&ov5645->ep);
of_node_put(endpoint);
- if (ret < 0) {
- dev_err(dev, "parsing endpoint node failed\n");
- return ret;
- }
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "parsing endpoint node failed\n");
- if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {
- dev_err(dev, "invalid bus type, must be CSI2\n");
- return -EINVAL;
- }
+ if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY)
+ return dev_err_probe(dev, -EINVAL,
+ "invalid bus type, must be CSI2\n");
/* get system clock (xclk) */
ov5645->xclk = devm_clk_get(dev, NULL);
- if (IS_ERR(ov5645->xclk)) {
- dev_err(dev, "could not get xclk");
- return PTR_ERR(ov5645->xclk);
- }
+ if (IS_ERR(ov5645->xclk))
+ return dev_err_probe(dev, PTR_ERR(ov5645->xclk),
+ "could not get xclk");
ret = of_property_read_u32(dev->of_node, "clock-frequency", &xclk_freq);
- if (ret) {
- dev_err(dev, "could not get xclk frequency\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "could not get xclk frequency\n");
/* external clock must be 24MHz, allow 1% tolerance */
- if (xclk_freq < 23760000 || xclk_freq > 24240000) {
- dev_err(dev, "external clock frequency %u is not supported\n",
- xclk_freq);
- return -EINVAL;
- }
+ if (xclk_freq < 23760000 || xclk_freq > 24240000)
+ return dev_err_probe(dev, -EINVAL,
+ "unsupported xclk frequency %u\n",
+ xclk_freq);
ret = clk_set_rate(ov5645->xclk, xclk_freq);
- if (ret) {
- dev_err(dev, "could not set xclk frequency\n");
- return ret;
- }
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "could not set xclk frequency\n");
for (i = 0; i < OV5645_NUM_SUPPLIES; i++)
ov5645->supplies[i].supply = ov5645_supply_name[i];
@@ -1124,18 +1074,14 @@ static int ov5645_probe(struct i2c_client *client)
return ret;
ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
- if (IS_ERR(ov5645->enable_gpio)) {
- dev_err(dev, "cannot get enable gpio\n");
- return PTR_ERR(ov5645->enable_gpio);
- }
+ if (IS_ERR(ov5645->enable_gpio))
+ return dev_err_probe(dev, PTR_ERR(ov5645->enable_gpio),
+ "cannot get enable gpio\n");
ov5645->rst_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
- if (IS_ERR(ov5645->rst_gpio)) {
- dev_err(dev, "cannot get reset gpio\n");
- return PTR_ERR(ov5645->rst_gpio);
- }
-
- mutex_init(&ov5645->power_lock);
+ if (IS_ERR(ov5645->rst_gpio))
+ return dev_err_probe(dev, PTR_ERR(ov5645->rst_gpio),
+ "cannot get reset gpio\n");
v4l2_ctrl_handler_init(&ov5645->ctrls, 9);
v4l2_ctrl_new_std(&ov5645->ctrls, &ov5645_ctrl_ops,
@@ -1170,9 +1116,8 @@ static int ov5645_probe(struct i2c_client *client)
ov5645->sd.ctrl_handler = &ov5645->ctrls;
if (ov5645->ctrls.error) {
- dev_err(dev, "%s: control initialization error %d\n",
- __func__, ov5645->ctrls.error);
ret = ov5645->ctrls.error;
+ dev_err_probe(dev, ret, "failed to add controls\n");
goto free_ctrl;
}
@@ -1180,12 +1125,12 @@ static int ov5645_probe(struct i2c_client *client)
ov5645->sd.internal_ops = &ov5645_internal_ops;
ov5645->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov5645->pad.flags = MEDIA_PAD_FL_SOURCE;
- ov5645->sd.dev = &client->dev;
+ ov5645->sd.dev = dev;
ov5645->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&ov5645->sd.entity, 1, &ov5645->pad);
if (ret < 0) {
- dev_err(dev, "could not register media entity\n");
+ dev_err_probe(dev, ret, "could not register media entity\n");
goto free_ctrl;
}
@@ -1195,14 +1140,14 @@ static int ov5645_probe(struct i2c_client *client)
ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_HIGH, &chip_id_high);
if (ret < 0 || chip_id_high != OV5645_CHIP_ID_HIGH_BYTE) {
- dev_err(dev, "could not read ID high\n");
ret = -ENODEV;
+ dev_err_probe(dev, ret, "could not read ID high\n");
goto power_down;
}
ret = ov5645_read_reg(ov5645, OV5645_CHIP_ID_LOW, &chip_id_low);
if (ret < 0 || chip_id_low != OV5645_CHIP_ID_LOW_BYTE) {
- dev_err(dev, "could not read ID low\n");
ret = -ENODEV;
+ dev_err_probe(dev, ret, "could not read ID low\n");
goto power_down;
}
@@ -1211,24 +1156,31 @@ static int ov5645_probe(struct i2c_client *client)
ret = ov5645_read_reg(ov5645, OV5645_AEC_PK_MANUAL,
&ov5645->aec_pk_manual);
if (ret < 0) {
- dev_err(dev, "could not read AEC/AGC mode\n");
ret = -ENODEV;
+ dev_err_probe(dev, ret, "could not read AEC/AGC mode\n");
goto power_down;
}
ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG20,
&ov5645->timing_tc_reg20);
if (ret < 0) {
- dev_err(dev, "could not read vflip value\n");
ret = -ENODEV;
+ dev_err_probe(dev, ret, "could not read vflip value\n");
goto power_down;
}
ret = ov5645_read_reg(ov5645, OV5645_TIMING_TC_REG21,
&ov5645->timing_tc_reg21);
if (ret < 0) {
- dev_err(dev, "could not read hflip value\n");
ret = -ENODEV;
+ dev_err_probe(dev, ret, "could not read hflip value\n");
+ goto power_down;
+ }
+
+ ov5645->sd.state_lock = ov5645->ctrls.lock;
+ ret = v4l2_subdev_init_finalize(&ov5645->sd);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "subdev init error\n");
goto power_down;
}
@@ -1236,11 +1188,9 @@ static int ov5645_probe(struct i2c_client *client)
pm_runtime_get_noresume(dev);
pm_runtime_enable(dev);
- ov5645_init_state(&ov5645->sd, NULL);
-
- ret = v4l2_async_register_subdev(&ov5645->sd);
+ ret = v4l2_async_register_subdev_sensor(&ov5645->sd);
if (ret < 0) {
- dev_err(dev, "could not register v4l2 device\n");
+ dev_err_probe(dev, ret, "could not register v4l2 device\n");
goto err_pm_runtime;
}
@@ -1254,13 +1204,13 @@ static int ov5645_probe(struct i2c_client *client)
err_pm_runtime:
pm_runtime_disable(dev);
pm_runtime_put_noidle(dev);
+ v4l2_subdev_cleanup(&ov5645->sd);
power_down:
ov5645_set_power_off(dev);
free_entity:
media_entity_cleanup(&ov5645->sd.entity);
free_ctrl:
v4l2_ctrl_handler_free(&ov5645->ctrls);
- mutex_destroy(&ov5645->power_lock);
return ret;
}
@@ -1271,13 +1221,13 @@ static void ov5645_remove(struct i2c_client *client)
struct ov5645 *ov5645 = to_ov5645(sd);
v4l2_async_unregister_subdev(&ov5645->sd);
+ v4l2_subdev_cleanup(sd);
media_entity_cleanup(&ov5645->sd.entity);
v4l2_ctrl_handler_free(&ov5645->ctrls);
pm_runtime_disable(ov5645->dev);
if (!pm_runtime_status_suspended(ov5645->dev))
ov5645_set_power_off(ov5645->dev);
pm_runtime_set_suspended(ov5645->dev);
- mutex_destroy(&ov5645->power_lock);
}
static const struct i2c_device_id ov5645_id[] = {
diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c
index f051045d340f..c54bbc207189 100644
--- a/drivers/media/i2c/ov5670.c
+++ b/drivers/media/i2c/ov5670.c
@@ -1879,7 +1879,7 @@ struct ov5670 {
struct gpio_desc *pwdn_gpio; /* PWDNB pin. */
struct gpio_desc *reset_gpio; /* XSHUTDOWN pin. */
- /* To serialize asynchronus callbacks */
+ /* To serialize asynchronous callbacks */
struct mutex mutex;
/* True if the device has been identified */
diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c
index 2833b14ee139..c1081deffc2f 100644
--- a/drivers/media/i2c/ov5675.c
+++ b/drivers/media/i2c/ov5675.c
@@ -510,7 +510,7 @@ struct ov5675 {
/* Current mode */
const struct ov5675_mode *cur_mode;
- /* To serialize asynchronus callbacks */
+ /* To serialize asynchronous callbacks */
struct mutex mutex;
/* True if the device has been identified */
@@ -732,7 +732,7 @@ static int ov5675_set_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE:
/* 4 least significant bits of expsoure are fractional part
* val = val << 4
- * for ov5675, the unit of exposure is differnt from other
+ * for ov5675, the unit of exposure is different from other
* OmniVision sensors, its exposure value is twice of the
* register value, the exposure should be divided by 2 before
* set register, e.g. val << 3.
diff --git a/drivers/media/i2c/ov64a40.c b/drivers/media/i2c/ov64a40.c
index 541bf74581d2..a5da4fe47e0b 100644
--- a/drivers/media/i2c/ov64a40.c
+++ b/drivers/media/i2c/ov64a40.c
@@ -18,7 +18,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>
@@ -3200,13 +3199,7 @@ static const struct v4l2_subdev_pad_ops ov64a40_pad_ops = {
.get_selection = ov64a40_get_selection,
};
-static const struct v4l2_subdev_core_ops ov64a40_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_ops ov64a40_subdev_ops = {
- .core = &ov64a40_core_ops,
.video = &ov64a40_video_ops,
.pad = &ov64a40_pad_ops,
};
@@ -3605,8 +3598,7 @@ static int ov64a40_probe(struct i2c_client *client)
/* Initialize subdev */
ov64a40->sd.internal_ops = &ov64a40_internal_ops;
- ov64a40->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE
- | V4L2_SUBDEV_FL_HAS_EVENTS;
+ ov64a40->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
ov64a40->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
ov64a40->pad.flags = MEDIA_PAD_FL_SOURCE;
diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c
index 3b0fdb3c70c0..062e1023a411 100644
--- a/drivers/media/i2c/ov772x.c
+++ b/drivers/media/i2c/ov772x.c
@@ -269,7 +269,7 @@
#define AF_8x 0x08 /* Add frame when AGC reaches 8x gain */
#define AF_16x 0x0c /* Add frame when AGC reaches 16x gain */
/* AEC max step control */
-#define AEC_NO_LIMIT 0x01 /* 0 : AEC incease step has limit */
+#define AEC_NO_LIMIT 0x01 /* 0 : AEC increase step has limit */
/* 1 : No limit to AEC increase step */
/* CLKRC */
/* Input clock divider register */
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index 0830676e5d5a..1f1c0de8e510 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -117,7 +117,7 @@ struct ov7740 {
struct v4l2_ctrl *brightness;
struct v4l2_ctrl *contrast;
- struct mutex mutex; /* To serialize asynchronus callbacks */
+ struct mutex mutex; /* To serialize asynchronous callbacks */
struct gpio_desc *resetb_gpio;
struct gpio_desc *pwdn_gpio;
diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
index 3b94338f55ed..e6704d018248 100644
--- a/drivers/media/i2c/ov8856.c
+++ b/drivers/media/i2c/ov8856.c
@@ -1435,7 +1435,7 @@ struct ov8856 {
/* Application specified mbus format */
u32 cur_mbus_index;
- /* To serialize asynchronus callbacks */
+ /* To serialize asynchronous callbacks */
struct mutex mutex;
/* lanes index */
diff --git a/drivers/media/i2c/ov8858.c b/drivers/media/i2c/ov8858.c
index 326f50a5ab51..95f9ae794846 100644
--- a/drivers/media/i2c/ov8858.c
+++ b/drivers/media/i2c/ov8858.c
@@ -24,7 +24,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>
@@ -1500,13 +1499,7 @@ static const struct v4l2_subdev_pad_ops ov8858_pad_ops = {
.set_fmt = ov8858_set_fmt,
};
-static const struct v4l2_subdev_core_ops ov8858_core_ops = {
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
static const struct v4l2_subdev_ops ov8858_subdev_ops = {
- .core = &ov8858_core_ops,
.video = &ov8858_video_ops,
.pad = &ov8858_pad_ops,
};
@@ -1917,7 +1910,7 @@ static int ov8858_probe(struct i2c_client *client)
return ret;
sd = &ov8858->subdev;
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
ov8858->pad.flags = MEDIA_PAD_FL_SOURCE;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
ret = media_entity_pads_init(&sd->entity, 1, &ov8858->pad);
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 56df97c9886b..026ea34d6291 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -286,7 +286,7 @@ static const struct i2c_rv ov965x_init_regs[] = {
{ REG_COM5, 0x00 }, /* System clock options */
{ REG_COM2, 0x01 }, /* Output drive, soft sleep mode */
{ REG_COM10, 0x00 }, /* Slave mode, HREF vs HSYNC, signals negate */
- { REG_EDGE, 0xa6 }, /* Edge enhancement treshhold and factor */
+ { REG_EDGE, 0xa6 }, /* Edge enhancement threshold and factor */
{ REG_COM16, 0x02 }, /* Color matrix coeff double option */
{ REG_COM17, 0x08 }, /* Single frame out, banding filter */
{ 0x16, 0x06 },
diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c
index bf9e2adbff34..cae3aeefb616 100644
--- a/drivers/media/i2c/ov9734.c
+++ b/drivers/media/i2c/ov9734.c
@@ -335,7 +335,7 @@ struct ov9734 {
/* Current mode */
const struct ov9734_mode *cur_mode;
- /* To serialize asynchronus callbacks */
+ /* To serialize asynchronous callbacks */
struct mutex mutex;
};
diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
index b947a55281f0..f08db3cfe076 100644
--- a/drivers/media/i2c/st-mipid02.c
+++ b/drivers/media/i2c/st-mipid02.c
@@ -14,6 +14,7 @@
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
+#include <linux/pm_runtime.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <media/mipi-csi2.h>
@@ -67,9 +68,6 @@ static const u32 mipid02_supported_fmt_codes[] = {
MEDIA_BUS_FMT_YUYV8_1X16, MEDIA_BUS_FMT_YVYU8_1X16,
MEDIA_BUS_FMT_UYVY8_1X16, MEDIA_BUS_FMT_VYUY8_1X16,
MEDIA_BUS_FMT_RGB565_1X16, MEDIA_BUS_FMT_BGR888_1X24,
- MEDIA_BUS_FMT_RGB565_2X8_LE, MEDIA_BUS_FMT_RGB565_2X8_BE,
- MEDIA_BUS_FMT_YUYV8_2X8, MEDIA_BUS_FMT_YVYU8_2X8,
- MEDIA_BUS_FMT_UYVY8_2X8, MEDIA_BUS_FMT_VYUY8_2X8,
MEDIA_BUS_FMT_Y8_1X8, MEDIA_BUS_FMT_JPEG_1X8
};
@@ -100,6 +98,7 @@ struct mipid02_dev {
/* remote source */
struct v4l2_async_notifier notifier;
struct v4l2_subdev *s_subdev;
+ u16 s_subdev_pad_id;
/* registers */
struct {
u8 clk_lane_reg1;
@@ -138,12 +137,6 @@ static int bpp_from_code(__u32 code)
case MEDIA_BUS_FMT_UYVY8_1X16:
case MEDIA_BUS_FMT_VYUY8_1X16:
case MEDIA_BUS_FMT_RGB565_1X16:
- case MEDIA_BUS_FMT_YUYV8_2X8:
- case MEDIA_BUS_FMT_YVYU8_2X8:
- case MEDIA_BUS_FMT_UYVY8_2X8:
- case MEDIA_BUS_FMT_VYUY8_2X8:
- case MEDIA_BUS_FMT_RGB565_2X8_LE:
- case MEDIA_BUS_FMT_RGB565_2X8_BE:
return 16;
case MEDIA_BUS_FMT_BGR888_1X24:
return 24;
@@ -175,16 +168,10 @@ static u8 data_type_from_code(__u32 code)
case MEDIA_BUS_FMT_YVYU8_1X16:
case MEDIA_BUS_FMT_UYVY8_1X16:
case MEDIA_BUS_FMT_VYUY8_1X16:
- case MEDIA_BUS_FMT_YUYV8_2X8:
- case MEDIA_BUS_FMT_YVYU8_2X8:
- case MEDIA_BUS_FMT_UYVY8_2X8:
- case MEDIA_BUS_FMT_VYUY8_2X8:
return MIPI_CSI2_DT_YUV422_8B;
case MEDIA_BUS_FMT_BGR888_1X24:
return MIPI_CSI2_DT_RGB888;
case MEDIA_BUS_FMT_RGB565_1X16:
- case MEDIA_BUS_FMT_RGB565_2X8_LE:
- case MEDIA_BUS_FMT_RGB565_2X8_BE:
return MIPI_CSI2_DT_RGB565;
default:
return 0;
@@ -248,8 +235,10 @@ static void mipid02_apply_reset(struct mipid02_dev *bridge)
usleep_range(5000, 10000);
}
-static int mipid02_set_power_on(struct mipid02_dev *bridge)
+static int mipid02_set_power_on(struct device *dev)
{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct mipid02_dev *bridge = to_mipid02_dev(sd);
struct i2c_client *client = bridge->i2c_client;
int ret;
@@ -282,10 +271,15 @@ xclk_off:
return ret;
}
-static void mipid02_set_power_off(struct mipid02_dev *bridge)
+static int mipid02_set_power_off(struct device *dev)
{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct mipid02_dev *bridge = to_mipid02_dev(sd);
+
regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies);
clk_disable_unprepare(bridge->xclk);
+
+ return 0;
}
static int mipid02_detect(struct mipid02_dev *bridge)
@@ -447,15 +441,19 @@ static int mipid02_configure_from_code(struct mipid02_dev *bridge,
return 0;
}
-static int mipid02_stream_disable(struct mipid02_dev *bridge)
+static int mipid02_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct mipid02_dev *bridge = to_mipid02_dev(sd);
struct i2c_client *client = bridge->i2c_client;
int ret = -EINVAL;
if (!bridge->s_subdev)
goto error;
- ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 0);
+ ret = v4l2_subdev_disable_streams(bridge->s_subdev,
+ bridge->s_subdev_pad_id, BIT(0));
if (ret)
goto error;
@@ -465,6 +463,10 @@ static int mipid02_stream_disable(struct mipid02_dev *bridge)
cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret);
if (ret)
goto error;
+
+ pm_runtime_mark_last_busy(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
+
error:
if (ret)
dev_err(&client->dev, "failed to stream off %d", ret);
@@ -472,33 +474,36 @@ error:
return ret;
}
-static int mipid02_stream_enable(struct mipid02_dev *bridge)
+static int mipid02_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct mipid02_dev *bridge = to_mipid02_dev(sd);
struct i2c_client *client = bridge->i2c_client;
- struct v4l2_subdev_state *state;
struct v4l2_mbus_framefmt *fmt;
int ret = -EINVAL;
if (!bridge->s_subdev)
- goto error;
+ return ret;
memset(&bridge->r, 0, sizeof(bridge->r));
- state = v4l2_subdev_lock_and_get_active_state(&bridge->sd);
fmt = v4l2_subdev_state_get_format(state, MIPID02_SINK_0);
/* build registers content */
ret = mipid02_configure_from_rx(bridge, fmt);
if (ret)
- goto error;
+ return ret;
ret = mipid02_configure_from_tx(bridge);
if (ret)
- goto error;
+ return ret;
ret = mipid02_configure_from_code(bridge, fmt);
if (ret)
- goto error;
+ return ret;
- v4l2_subdev_unlock_state(state);
+ ret = pm_runtime_resume_and_get(&client->dev);
+ if (ret < 0)
+ return ret;
/* write mipi registers */
cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1,
@@ -524,33 +529,20 @@ static int mipid02_stream_enable(struct mipid02_dev *bridge)
if (ret)
goto error;
- ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 1);
+ ret = v4l2_subdev_enable_streams(bridge->s_subdev,
+ bridge->s_subdev_pad_id, BIT(0));
if (ret)
goto error;
return 0;
error:
- dev_err(&client->dev, "failed to stream on %d", ret);
- mipid02_stream_disable(bridge);
-
- return ret;
-}
-
-static int mipid02_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct mipid02_dev *bridge = to_mipid02_dev(sd);
- struct i2c_client *client = bridge->i2c_client;
- int ret = 0;
-
- dev_dbg(&client->dev, "%s : requested %d\n", __func__, enable);
-
- ret = enable ? mipid02_stream_enable(bridge) :
- mipid02_stream_disable(bridge);
- if (ret)
- dev_err(&client->dev, "failed to stream %s (%d)\n",
- enable ? "enable" : "disable", ret);
+ cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1, 0, &ret);
+ cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret);
+ cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret);
+ pm_runtime_mark_last_busy(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
return ret;
}
@@ -640,13 +632,15 @@ static int mipid02_set_fmt(struct v4l2_subdev *sd,
}
static const struct v4l2_subdev_video_ops mipid02_video_ops = {
- .s_stream = mipid02_s_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops mipid02_pad_ops = {
.enum_mbus_code = mipid02_enum_mbus_code,
.get_fmt = v4l2_subdev_get_fmt,
.set_fmt = mipid02_set_fmt,
+ .enable_streams = mipid02_enable_streams,
+ .disable_streams = mipid02_disable_streams,
};
static const struct v4l2_subdev_ops mipid02_subdev_ops = {
@@ -692,6 +686,7 @@ static int mipid02_async_bound(struct v4l2_async_notifier *notifier,
}
bridge->s_subdev = s_subdev;
+ bridge->s_subdev_pad_id = source_pad;
return 0;
}
@@ -875,7 +870,7 @@ static int mipid02_probe(struct i2c_client *client)
}
/* enable clock, power and reset device if available */
- ret = mipid02_set_power_on(bridge);
+ ret = mipid02_set_power_on(&client->dev);
if (ret)
goto entity_cleanup;
@@ -897,6 +892,15 @@ static int mipid02_probe(struct i2c_client *client)
goto power_off;
}
+ /* Enable runtime PM and turn off the device */
+ pm_runtime_set_active(dev);
+ pm_runtime_get_noresume(&client->dev);
+ pm_runtime_enable(dev);
+
+ pm_runtime_set_autosuspend_delay(&client->dev, 1000);
+ pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_put_autosuspend(&client->dev);
+
ret = v4l2_async_register_subdev(&bridge->sd);
if (ret < 0) {
dev_err(&client->dev, "v4l2_async_register_subdev failed %d",
@@ -911,8 +915,10 @@ static int mipid02_probe(struct i2c_client *client)
unregister_notifier:
v4l2_async_nf_unregister(&bridge->notifier);
v4l2_async_nf_cleanup(&bridge->notifier);
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
power_off:
- mipid02_set_power_off(bridge);
+ mipid02_set_power_off(&client->dev);
entity_cleanup:
media_entity_cleanup(&bridge->sd.entity);
@@ -927,7 +933,11 @@ static void mipid02_remove(struct i2c_client *client)
v4l2_async_nf_unregister(&bridge->notifier);
v4l2_async_nf_cleanup(&bridge->notifier);
v4l2_async_unregister_subdev(&bridge->sd);
- mipid02_set_power_off(bridge);
+
+ pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ mipid02_set_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
media_entity_cleanup(&bridge->sd.entity);
}
@@ -937,10 +947,15 @@ static const struct of_device_id mipid02_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, mipid02_dt_ids);
+static const struct dev_pm_ops mipid02_pm_ops = {
+ RUNTIME_PM_OPS(mipid02_set_power_off, mipid02_set_power_on, NULL)
+};
+
static struct i2c_driver mipid02_i2c_driver = {
.driver = {
.name = "st-mipid02",
.of_match_table = mipid02_dt_ids,
+ .pm = pm_ptr(&mipid02_pm_ops),
},
.probe = mipid02_probe,
.remove = mipid02_remove,
diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c
index 65d58ddf0287..c50d4e85dfd1 100644
--- a/drivers/media/i2c/tc358743.c
+++ b/drivers/media/i2c/tc358743.c
@@ -87,6 +87,10 @@ struct tc358743_state {
struct timer_list timer;
struct work_struct work_i2c_poll;
+ /* debugfs */
+ struct dentry *debugfs_dir;
+ struct v4l2_debugfs_if *infoframes;
+
/* edid */
u8 edid_blocks_written;
@@ -430,12 +434,35 @@ static void tc358743_erase_bksv(struct v4l2_subdev *sd)
/* --------------- AVI infoframe --------------- */
+static ssize_t
+tc358743_debugfs_if_read(u32 type, void *priv, struct file *filp,
+ char __user *ubuf, size_t count, loff_t *ppos)
+{
+ u8 buf[V4L2_DEBUGFS_IF_MAX_LEN] = {};
+ struct v4l2_subdev *sd = priv;
+ int len;
+
+ if (!is_hdmi(sd))
+ return 0;
+
+ if (type != V4L2_DEBUGFS_IF_AVI)
+ return 0;
+
+ i2c_rd(sd, PK_AVI_0HEAD, buf, PK_AVI_16BYTE - PK_AVI_0HEAD + 1);
+ len = buf[2] + 4;
+ if (len > V4L2_DEBUGFS_IF_MAX_LEN)
+ len = -ENOENT;
+ if (len > 0)
+ len = simple_read_from_buffer(ubuf, count, ppos, buf, len);
+ return len < 0 ? 0 : len;
+}
+
static void print_avi_infoframe(struct v4l2_subdev *sd)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct device *dev = &client->dev;
union hdmi_infoframe frame;
- u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
+ u8 buffer[HDMI_INFOFRAME_SIZE(AVI)] = {};
if (!is_hdmi(sd)) {
v4l2_info(sd, "DVI-D signal - AVI infoframe not supported\n");
@@ -2161,6 +2188,11 @@ static int tc358743_probe(struct i2c_client *client)
if (err < 0)
goto err_work_queues;
+ state->debugfs_dir = debugfs_create_dir(sd->name, v4l2_debugfs_root());
+ state->infoframes = v4l2_debugfs_if_alloc(state->debugfs_dir,
+ V4L2_DEBUGFS_IF_AVI, sd,
+ tc358743_debugfs_if_read);
+
v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
client->addr << 1, client->adapter->name);
@@ -2168,8 +2200,10 @@ static int tc358743_probe(struct i2c_client *client)
err_work_queues:
cec_unregister_adapter(state->cec_adap);
- if (!state->i2c_client->irq)
+ if (!state->i2c_client->irq) {
+ del_timer(&state->timer);
flush_work(&state->work_i2c_poll);
+ }
cancel_delayed_work(&state->delayed_work_enable_hotplug);
mutex_destroy(&state->confctl_mutex);
err_hdl:
@@ -2188,6 +2222,8 @@ static void tc358743_remove(struct i2c_client *client)
flush_work(&state->work_i2c_poll);
}
cancel_delayed_work_sync(&state->delayed_work_enable_hotplug);
+ v4l2_debugfs_if_free(state->infoframes);
+ debugfs_remove_recursive(state->debugfs_dir);
cec_unregister_adapter(state->cec_adap);
v4l2_async_unregister_subdev(sd);
v4l2_device_unregister_subdev(sd);
diff --git a/drivers/media/i2c/thp7312.c b/drivers/media/i2c/thp7312.c
index c77440ff098c..8852c56431fe 100644
--- a/drivers/media/i2c/thp7312.c
+++ b/drivers/media/i2c/thp7312.c
@@ -27,7 +27,6 @@
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
@@ -879,8 +878,6 @@ static int thp7312_init_state(struct v4l2_subdev *sd,
static const struct v4l2_subdev_core_ops thp7312_core_ops = {
.log_status = v4l2_ctrl_subdev_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
};
static const struct v4l2_subdev_video_ops thp7312_video_ops = {
@@ -2127,7 +2124,7 @@ static int thp7312_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&thp7312->sd, client, &thp7312_subdev_ops);
thp7312->sd.internal_ops = &thp7312_internal_ops;
- thp7312->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ thp7312->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
thp7312->pad.flags = MEDIA_PAD_FL_SOURCE;
thp7312->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index 7526fabc7ee4..b7cedc5b3e8e 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -7,7 +7,7 @@
* Author: Chaithrika U S <chaithrika@ti.com>
*
* Contributors:
- * Hans Verkuil <hans.verkuil@cisco.com>
+ * Hans Verkuil <hansverk@cisco.com>
* Lad, Prabhakar <prabhakar.lad@ti.com>
* Martin Bugge <marbugge@cisco.com>
*
diff --git a/drivers/media/i2c/vgxy61.c b/drivers/media/i2c/vgxy61.c
index 409d2d4ffb4b..d77468c8587b 100644
--- a/drivers/media/i2c/vgxy61.c
+++ b/drivers/media/i2c/vgxy61.c
@@ -1617,7 +1617,7 @@ static int vgxy61_detect(struct vgxy61_dev *sensor)
ret = cci_read(sensor->regmap, VGXY61_REG_NVM, &st, NULL);
if (ret < 0)
- return st;
+ return ret;
if (st != VGXY61_NVM_OK)
dev_warn(&client->dev, "Bad nvm state got %u\n", (u8)st);
diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c
index 56dbe07a1c99..036a6375627a 100644
--- a/drivers/media/i2c/video-i2c.c
+++ b/drivers/media/i2c/video-i2c.c
@@ -566,8 +566,6 @@ static const struct vb2_ops video_i2c_video_qops = {
.buf_queue = buffer_queue,
.start_streaming = start_streaming,
.stop_streaming = stop_streaming,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
};
static int video_i2c_querycap(struct file *file, void *priv,
@@ -798,13 +796,13 @@ static int video_i2c_probe(struct i2c_client *client)
queue->min_queued_buffers = 1;
queue->ops = &video_i2c_video_qops;
queue->mem_ops = &vb2_vmalloc_memops;
+ queue->lock = &data->queue_lock;
ret = vb2_queue_init(queue);
if (ret < 0)
goto error_unregister_device;
data->vdev.queue = queue;
- data->vdev.queue->lock = &data->queue_lock;
snprintf(data->vdev.name, sizeof(data->vdev.name),
"I2C %d-%d Transport Video",