diff --git a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c index 410f14f744aa..b3ac21b502ee 100644 --- a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.c @@ -43,6 +43,10 @@ * 2. support remote raw sensor s_power and s_stream control by cif * 3. support vicap multi channel to multi ISP mode * + * V3.05.00 + * 1. unified use __v4l2_ctrl_handler_setup in the xxx_start_stream + * 2. support subscribe hot plug detect v4l2 event + * */ #include #include @@ -70,7 +74,7 @@ #include "maxim2c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(3, 0x04, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(3, 0x05, 0x00) #define MAXIM2C_NAME "maxim2c" @@ -118,6 +122,20 @@ static int maxim2c_check_local_chipid(maxim2c_t *maxim2c) return -ENODEV; } +static void maxim2c_hot_plug_event_report(maxim2c_t *maxim2c, int data) +{ + struct v4l2_subdev *sd = &maxim2c->subdev; + struct device *dev = &maxim2c->client->dev; + struct v4l2_event evt_hot_plug = { + .type = V4L2_EVENT_HOT_PLUG, + .u.data[0] = data, + }; + + dev_dbg(dev, "%s data %d\n", __func__, data); + + v4l2_event_queue(sd->devnode, &evt_hot_plug); +} + static irqreturn_t maxim2c_hot_plug_detect_irq_handler(int irq, void *dev_id) { maxim2c_t *maxim2c = dev_id; @@ -205,6 +223,7 @@ static void maxim2c_hot_plug_state_check_work(struct work_struct *work) dev_dbg(dev, "lock state: current = 0x%02x, last = 0x%02x\n", curr_lock_state, last_lock_state); + maxim2c_hot_plug_event_report(maxim2c, curr_lock_state); maxim2c->link_lock_state = curr_lock_state; } diff --git a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h index 22c2340b5a5e..c7dc362bef75 100644 --- a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_drv.h @@ -9,12 +9,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -32,6 +34,10 @@ /* power supply numbers */ #define MAXIM2C_NUM_SUPPLIES 2 +/* Private v4l2 event */ +#define V4L2_EVENT_HOT_PLUG \ + (V4L2_EVENT_PRIVATE_START + 0x10) + enum { MAXIM2C_HOT_PLUG_OUT = 0, MAXIM2C_HOT_PLUG_IN, diff --git a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c index ccf2003929ab..fb20341e67c5 100644 --- a/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c +++ b/drivers/media/i2c/maxim/local/maxim2c/maxim2c_v4l2.c @@ -580,9 +580,7 @@ static int __maxim2c_start_stream(maxim2c_t *maxim2c) } /* In case these controls are set before streaming */ - mutex_unlock(&maxim2c->mutex); - ret = v4l2_ctrl_handler_setup(&maxim2c->ctrl_handler); - mutex_lock(&maxim2c->mutex); + ret = __v4l2_ctrl_handler_setup(&maxim2c->ctrl_handler); if (ret) return ret; @@ -710,9 +708,7 @@ static int maxim2c_g_frame_interval(struct v4l2_subdev *sd, maxim2c_t *maxim2c = v4l2_get_subdevdata(sd); const struct maxim2c_mode *mode = maxim2c->cur_mode; - mutex_lock(&maxim2c->mutex); fi->interval = mode->max_fps; - mutex_unlock(&maxim2c->mutex); return 0; } @@ -816,10 +812,7 @@ static int maxim2c_get_fmt(struct v4l2_subdev *sd, fmt->format.height = mode->height; fmt->format.code = mode->bus_fmt; fmt->format.field = V4L2_FIELD_NONE; - if (fmt->pad < PAD_MAX && fmt->pad >= PAD0) - fmt->reserved[0] = mode->vc[fmt->pad]; - else - fmt->reserved[0] = mode->vc[PAD0]; + fmt->reserved[0] = mode->vc[fmt->pad]; } mutex_unlock(&maxim2c->mutex); @@ -966,6 +959,17 @@ static int maxim2c_g_mbus_config(struct v4l2_subdev *sd, } #endif /* LINUX_VERSION_CODE */ +static int maxim2c_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_HOT_PLUG: + return v4l2_event_subscribe(fh, sub, 0, NULL); + default: + return -EINVAL; + } +} + #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_internal_ops maxim2c_internal_ops = { .open = maxim2c_open, @@ -974,6 +978,8 @@ static const struct v4l2_subdev_internal_ops maxim2c_internal_ops = { static const struct v4l2_subdev_core_ops maxim2c_core_ops = { .s_power = maxim2c_s_power, + .subscribe_event = maxim2c_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, .ioctl = maxim2c_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = maxim2c_compat_ioctl32, @@ -1103,7 +1109,7 @@ int maxim2c_v4l2_subdev_init(maxim2c_t *maxim2c) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sd->internal_ops = &maxim2c_internal_ops; - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; #endif #if defined(CONFIG_MEDIA_CONTROLLER) diff --git a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c index 1b5489a2ecb1..18ff79e79cd4 100644 --- a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c +++ b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c @@ -66,6 +66,10 @@ * 2. support remote raw sensor s_power and s_stream control by cif * 3. support vicap multi channel to multi ISP mode * + * V3.05.00 + * 1. unified use __v4l2_ctrl_handler_setup in the xxx_start_stream + * 2. support subscribe hot plug detect v4l2 event + * */ #include #include @@ -93,7 +97,7 @@ #include "maxim4c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(3, 0x04, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(3, 0x05, 0x00) #define MAXIM4C_NAME "maxim4c" diff --git a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c index e00e205b8fc5..7ad74a107bb7 100644 --- a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c +++ b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c @@ -580,9 +580,7 @@ static int __maxim4c_start_stream(maxim4c_t *maxim4c) } /* In case these controls are set before streaming */ - mutex_unlock(&maxim4c->mutex); - ret = v4l2_ctrl_handler_setup(&maxim4c->ctrl_handler); - mutex_lock(&maxim4c->mutex); + ret = __v4l2_ctrl_handler_setup(&maxim4c->ctrl_handler); if (ret) return ret; @@ -710,9 +708,7 @@ static int maxim4c_g_frame_interval(struct v4l2_subdev *sd, maxim4c_t *maxim4c = v4l2_get_subdevdata(sd); const struct maxim4c_mode *mode = maxim4c->cur_mode; - mutex_lock(&maxim4c->mutex); fi->interval = mode->max_fps; - mutex_unlock(&maxim4c->mutex); return 0; } diff --git a/drivers/media/i2c/maxim/remote/dummy.c b/drivers/media/i2c/maxim/remote/dummy.c index a8e693df8409..c6039ffbb668 100644 --- a/drivers/media/i2c/maxim/remote/dummy.c +++ b/drivers/media/i2c/maxim/remote/dummy.c @@ -26,7 +26,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x02) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x03) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -360,9 +360,7 @@ static int __sensor_start_stream(struct sensor *sensor) } /* In case these controls are set before streaming */ - mutex_unlock(&sensor->mutex); - ret = v4l2_ctrl_handler_setup(&sensor->ctrl_handler); - mutex_lock(&sensor->mutex); + ret = __v4l2_ctrl_handler_setup(&sensor->ctrl_handler); if (ret) return ret; @@ -717,9 +715,7 @@ static int sensor_g_frame_interval(struct v4l2_subdev *sd, struct sensor *sensor = v4l2_get_subdevdata(sd); const struct sensor_mode *mode = sensor->cur_mode; - mutex_lock(&sensor->mutex); fi->interval = mode->max_fps; - mutex_unlock(&sensor->mutex); return 0; } diff --git a/drivers/media/i2c/maxim/remote/os04a10.c b/drivers/media/i2c/maxim/remote/os04a10.c index 2a7c63ccf06e..46ad2ad43cdc 100644 --- a/drivers/media/i2c/maxim/remote/os04a10.c +++ b/drivers/media/i2c/maxim/remote/os04a10.c @@ -28,7 +28,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x01) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -2262,9 +2262,7 @@ static int __os04a10_start_stream(struct os04a10 *os04a10) return ret; /* In case these controls are set before streaming */ - mutex_unlock(&os04a10->mutex); ret = __v4l2_ctrl_handler_setup(&os04a10->ctrl_handler); - mutex_lock(&os04a10->mutex); if (ret) return ret; diff --git a/drivers/media/i2c/maxim/remote/ov231x.c b/drivers/media/i2c/maxim/remote/ov231x.c index 0a592f6e3173..f336466012ef 100644 --- a/drivers/media/i2c/maxim/remote/ov231x.c +++ b/drivers/media/i2c/maxim/remote/ov231x.c @@ -24,7 +24,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x02) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -495,9 +495,7 @@ static int __ov231x_start_stream(struct ov231x *ov231x) } /* In case these controls are set before streaming */ - mutex_unlock(&ov231x->mutex); - ret = v4l2_ctrl_handler_setup(&ov231x->ctrl_handler); - mutex_lock(&ov231x->mutex); + ret = __v4l2_ctrl_handler_setup(&ov231x->ctrl_handler); if (ret) return ret; @@ -580,9 +578,7 @@ static int ov231x_g_frame_interval(struct v4l2_subdev *sd, struct ov231x *ov231x = v4l2_get_subdevdata(sd); const struct ov231x_mode *mode = ov231x->cur_mode; - mutex_lock(&ov231x->mutex); fi->interval = mode->max_fps; - mutex_unlock(&ov231x->mutex); return 0; } diff --git a/drivers/media/i2c/maxim/remote/ox01f10.c b/drivers/media/i2c/maxim/remote/ox01f10.c index c69bd6b125a9..4e3d14d9ec06 100644 --- a/drivers/media/i2c/maxim/remote/ox01f10.c +++ b/drivers/media/i2c/maxim/remote/ox01f10.c @@ -24,7 +24,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x02) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -495,9 +495,7 @@ static int __ox01f10_start_stream(struct ox01f10 *ox01f10) } /* In case these controls are set before streaming */ - mutex_unlock(&ox01f10->mutex); - ret = v4l2_ctrl_handler_setup(&ox01f10->ctrl_handler); - mutex_lock(&ox01f10->mutex); + ret = __v4l2_ctrl_handler_setup(&ox01f10->ctrl_handler); if (ret) return ret; @@ -580,9 +578,7 @@ static int ox01f10_g_frame_interval(struct v4l2_subdev *sd, struct ox01f10 *ox01f10 = v4l2_get_subdevdata(sd); const struct ox01f10_mode *mode = ox01f10->cur_mode; - mutex_lock(&ox01f10->mutex); fi->interval = mode->max_fps; - mutex_unlock(&ox01f10->mutex); return 0; } diff --git a/drivers/media/i2c/maxim/remote/ox03j10.c b/drivers/media/i2c/maxim/remote/ox03j10.c index 847291a23632..5e02e5e265ca 100644 --- a/drivers/media/i2c/maxim/remote/ox03j10.c +++ b/drivers/media/i2c/maxim/remote/ox03j10.c @@ -24,7 +24,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x00, 0x02) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -495,9 +495,7 @@ static int __ox03j10_start_stream(struct ox03j10 *ox03j10) } /* In case these controls are set before streaming */ - mutex_unlock(&ox03j10->mutex); - ret = v4l2_ctrl_handler_setup(&ox03j10->ctrl_handler); - mutex_lock(&ox03j10->mutex); + ret = __v4l2_ctrl_handler_setup(&ox03j10->ctrl_handler); if (ret) return ret; @@ -580,9 +578,7 @@ static int ox03j10_g_frame_interval(struct v4l2_subdev *sd, struct ox03j10 *ox03j10 = v4l2_get_subdevdata(sd); const struct ox03j10_mode *mode = ox03j10->cur_mode; - mutex_lock(&ox03j10->mutex); fi->interval = mode->max_fps; - mutex_unlock(&ox03j10->mutex); return 0; } diff --git a/drivers/media/i2c/maxim/remote/sc320at.c b/drivers/media/i2c/maxim/remote/sc320at.c index 041aaaaa4f78..695c7ae7879e 100644 --- a/drivers/media/i2c/maxim/remote/sc320at.c +++ b/drivers/media/i2c/maxim/remote/sc320at.c @@ -24,7 +24,7 @@ #include "maxim_remote.h" -#define DRIVER_VERSION KERNEL_VERSION(1, 0x01, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(1, 0x01, 0x01) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -495,9 +495,7 @@ static int __sc320at_start_stream(struct sc320at *sc320at) } /* In case these controls are set before streaming */ - mutex_unlock(&sc320at->mutex); - ret = v4l2_ctrl_handler_setup(&sc320at->ctrl_handler); - mutex_lock(&sc320at->mutex); + ret = __v4l2_ctrl_handler_setup(&sc320at->ctrl_handler); if (ret) return ret; @@ -580,9 +578,7 @@ static int sc320at_g_frame_interval(struct v4l2_subdev *sd, struct sc320at *sc320at = v4l2_get_subdevdata(sd); const struct sc320at_mode *mode = sc320at->cur_mode; - mutex_lock(&sc320at->mutex); fi->interval = mode->max_fps; - mutex_unlock(&sc320at->mutex); return 0; }