diff --git a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c index 53785ee1e89d..8da9fdd775d5 100644 --- a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c +++ b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.c @@ -136,6 +136,20 @@ static int maxim4c_check_local_chipid(maxim4c_t *maxim4c) return -ENODEV; } +static void maxim4c_hot_plug_event_report(maxim4c_t *maxim4c, int data) +{ + struct v4l2_subdev *sd = &maxim4c->subdev; + struct device *dev = &maxim4c->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 maxim4c_hot_plug_detect_irq_handler(int irq, void *dev_id) { maxim4c_t *maxim4c = dev_id; @@ -223,6 +237,7 @@ static void maxim4c_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); + maxim4c_hot_plug_event_report(maxim4c, curr_lock_state); maxim4c->link_lock_state = curr_lock_state; } diff --git a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.h b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.h index df355dff0755..9ea41c7ba3d5 100644 --- a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_drv.h +++ b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_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 MAXIM4C_NUM_SUPPLIES 2 +/* Private v4l2 event */ +#define V4L2_EVENT_HOT_PLUG \ + (V4L2_EVENT_PRIVATE_START + 0x10) + enum { MAXIM4C_HOT_PLUG_OUT = 0, MAXIM4C_HOT_PLUG_IN, diff --git a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c index d517f5b71adb..c434290722b6 100644 --- a/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c +++ b/drivers/media/i2c/maxim/local/maxim4c/maxim4c_v4l2.c @@ -779,10 +779,7 @@ static int maxim4c_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(&maxim4c->mutex); @@ -925,6 +922,17 @@ static int maxim4c_g_mbus_config(struct v4l2_subdev *sd, } #endif /* LINUX_VERSION_CODE */ +static int maxim4c_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 maxim4c_internal_ops = { .open = maxim4c_open, @@ -933,6 +941,8 @@ static const struct v4l2_subdev_internal_ops maxim4c_internal_ops = { static const struct v4l2_subdev_core_ops maxim4c_core_ops = { .s_power = maxim4c_s_power, + .subscribe_event = maxim4c_subscribe_event, + .unsubscribe_event = v4l2_event_subdev_unsubscribe, .ioctl = maxim4c_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = maxim4c_compat_ioctl32, @@ -1062,7 +1072,7 @@ int maxim4c_v4l2_subdev_init(maxim4c_t *maxim4c) #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sd->internal_ops = &maxim4c_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)