Loading drivers/media/platform/msm/ais/sensor/msm_sensor.c +122 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,12 @@ * GNU General Public License for more details. */ #include <media/v4l2-subdev.h> #include <media/v4l2-dev.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-device.h> #include <media/v4l2-fh.h> #include <media/v4l2-event.h> #include "msm_sensor.h" #include "msm_sd.h" #include "msm_cci.h" Loading @@ -21,6 +27,7 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) #define MAX_SENSOR_V4l2_EVENTS 100 static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl; static struct msm_camera_i2c_fn_t msm_sensor_secure_func_tbl; Loading Loading @@ -404,12 +411,26 @@ static long msm_sensor_subdev_do_ioctl( { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; switch (cmd) { case VIDIOC_MSM_SENSOR_CFG32: cmd = VIDIOC_MSM_SENSOR_CFG; case VIDIOC_DQEVENT: { if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); } break; case VIDIOC_SUBSCRIBE_EVENT: pr_debug("msm_sensor_subdev_do_ioctl:VIDIOC_SUBSCRIBE_EVENT"); return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); case VIDIOC_UNSUBSCRIBE_EVENT: return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); default: return msm_sensor_subdev_ioctl(sd, cmd, arg); pr_debug("msm_sensor.c msm_sensor_subdev_do_ioctl"); return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } } Loading Loading @@ -1467,8 +1488,107 @@ static int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, return 0; } static u32 msm_sensor_evt_mask_to_sensor_event(u32 evt_mask) { u32 evt_id = SENSOR_EVENT_SUBS_MASK_NONE; switch (evt_mask) { case SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS: evt_id = SENSOR_EVENT_SIGNAL_STATUS; break; default: evt_id = SENSOR_EVENT_SUBS_MASK_NONE; break; } return evt_id; } static int msm_sensor_subscribe_event_mask(struct v4l2_fh *fh, struct v4l2_event_subscription *sub, int evt_mask_index, u32 evt_id, bool subscribe_flag) { int rc = 0; sub->type = evt_id; if (subscribe_flag) rc = v4l2_event_subscribe(fh, sub, MAX_SENSOR_V4l2_EVENTS, NULL); else rc = v4l2_event_unsubscribe(fh, sub); if (rc != 0) { pr_err("%s: Subs event_type =0x%x failed\n", __func__, sub->type); return rc; } return rc; } static int msm_sensor_process_event_subscription(struct v4l2_fh *fh, struct v4l2_event_subscription *sub, bool subscribe_flag) { int rc = 0, evt_mask_index = 0; u32 evt_mask = sub->type; u32 evt_id = 0; if (SENSOR_EVENT_SUBS_MASK_NONE == evt_mask) { pr_err("%s: Subs event_type is None=0x%x\n", __func__, evt_mask); return 0; } evt_mask_index = SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS; if (evt_mask & (1<<evt_mask_index)) { evt_id = msm_sensor_evt_mask_to_sensor_event( evt_mask_index); rc = msm_sensor_subscribe_event_mask(fh, sub, evt_mask_index, evt_id, subscribe_flag); if (rc != 0) { pr_err("%s: Subs event index:%d failed\n", __func__, evt_mask_index); return rc; } } return rc; } int msm_sensor_send_event(struct msm_sensor_ctrl_t *s_ctrl, uint32_t event_type, struct msm_sensor_event_data *event_data) { struct v4l2_event sensor_event; memset(&sensor_event, 0, sizeof(struct v4l2_event)); sensor_event.id = 0; sensor_event.type = event_type; memcpy(&sensor_event.u.data[0], event_data, sizeof(struct msm_sensor_event_data)); v4l2_event_queue(s_ctrl->msm_sd.sd.devnode, &sensor_event); return 0; } static int msm_sensor_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { return msm_sensor_process_event_subscription(fh, sub, true); } static int msm_sensor_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { return msm_sensor_process_event_subscription(fh, sub, false); } static struct v4l2_subdev_core_ops msm_sensor_subdev_core_ops = { .ioctl = msm_sensor_subdev_ioctl, .subscribe_event = msm_sensor_subscribe_event, .unsubscribe_event = msm_sensor_unsubscribe_event, .s_power = msm_sensor_power, }; Loading drivers/media/platform/msm/ais/sensor/msm_sensor.h +9 −1 Original line number Diff line number Diff line Loading @@ -90,10 +90,18 @@ struct msm_sensor_ctrl_t { uint32_t set_mclk_23880000; uint8_t is_csid_tg_mode; uint32_t is_secure; /* Interrupt GPIOs */ struct gpio gpio_array[1]; /* device status and Flags */ int irq; struct msm_sensor_init_t s_init; /* worker to handle interrupts */ struct delayed_work irq_delayed_work; }; int msm_sensor_send_event(struct msm_sensor_ctrl_t *s_ctrl, uint32_t event_type, struct msm_sensor_event_data *event_data); int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp); int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl); Loading drivers/media/platform/msm/ais/sensor/msm_sensor_driver.c +106 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ static int32_t msm_sensor_driver_create_v4l_subdev s_ctrl->sensordata->sensor_name); v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev); s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0); s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; Loading @@ -143,6 +144,8 @@ static int32_t msm_sensor_driver_create_v4l_subdev return rc; } msm_cam_copy_v4l2_subdev_fops(&msm_sensor_v4l2_subdev_fops); msm_sensor_v4l2_subdev_fops.unlocked_ioctl = msm_sensor_subdev_fops_ioctl; #ifdef CONFIG_COMPAT msm_sensor_v4l2_subdev_fops.compat_ioctl32 = msm_sensor_subdev_fops_ioctl; Loading Loading @@ -627,6 +630,56 @@ static void msm_sensor_fill_sensor_info(struct msm_sensor_ctrl_t *s_ctrl, strlcpy(entity_name, s_ctrl->msm_sd.sd.entity.name, MAX_SENSOR_NAME); } static irqreturn_t bridge_irq(int irq, void *dev) { struct msm_sensor_ctrl_t *s_ctrl = dev; pr_err("msm_sensor_driver: received bridge interrupt:0x%x", s_ctrl->sensordata->slave_info->sensor_slave_addr); schedule_delayed_work(&s_ctrl->irq_delayed_work, msecs_to_jiffies(0)); return IRQ_HANDLED; } static void bridge_irq_delay_work(struct work_struct *work) { struct msm_sensor_ctrl_t *s_ctrl; struct msm_camera_i2c_client *sensor_i2c_client; struct msm_camera_slave_info *slave_info; const char *sensor_name; struct msm_sensor_event_data sensor_event; s_ctrl = container_of(work, struct msm_sensor_ctrl_t, irq_delayed_work.work); if (!s_ctrl) { pr_err("%s:%d failed: %pK\n", __func__, __LINE__, s_ctrl); goto exit_queue; } sensor_i2c_client = s_ctrl->sensor_i2c_client; slave_info = s_ctrl->sensordata->slave_info; sensor_name = s_ctrl->sensordata->sensor_name; if (!sensor_i2c_client || !slave_info || !sensor_name) { pr_err("%s:%d failed: %pK %pK %pK\n", __func__, __LINE__, sensor_i2c_client, slave_info, sensor_name); goto exit_queue; } mutex_lock(s_ctrl->msm_sensor_mutex); /* Fill the sensor event */ sensor_event.sensor_slave_addr = slave_info->sensor_slave_addr; /* Queue the event */ msm_sensor_send_event(s_ctrl, SENSOR_EVENT_SIGNAL_STATUS, &sensor_event); mutex_unlock(s_ctrl->msm_sensor_mutex); exit_queue: pr_err("Work IRQ exit"); } /* static function definition */ int32_t msm_sensor_driver_probe(void *setting, struct msm_sensor_info_t *probed_info, char *entity_name) Loading Loading @@ -928,6 +981,57 @@ CSID_TG: msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name); if (slave_info->gpio_intr_config.gpio_num != -1) { /* Configure INTB interrupt */ s_ctrl->gpio_array[0].gpio = slave_info->gpio_intr_config.gpio_num; s_ctrl->gpio_array[0].flags = 0; /* Only setup IRQ1 for now... */ INIT_DELAYED_WORK(&s_ctrl->irq_delayed_work, bridge_irq_delay_work); rc = gpio_request_array(&s_ctrl->gpio_array[0], 1); if (rc < 0) { pr_err("%s: Failed to request irq_gpio %d", __func__, rc); goto cancel_work; } if (gpio_is_valid(s_ctrl->gpio_array[0].gpio)) { rc |= gpio_direction_input( s_ctrl->gpio_array[0].gpio); if (rc) { pr_err("%s: Failed gpio_direction irq %d", __func__, rc); goto cancel_work; } else { pr_err("sensor probe IRQ direction succeeded"); } } s_ctrl->irq = gpio_to_irq(s_ctrl->gpio_array[0].gpio); if (s_ctrl->irq) { rc = request_irq(s_ctrl->irq, bridge_irq, IRQF_ONESHOT | (slave_info-> gpio_intr_config.gpio_trigger), "qcom,camera", s_ctrl); if (rc) { pr_err("%s: Failed request_irq %d", __func__, rc); goto cancel_work; } } else { pr_err("%s: Failed gpio_to_irq %d", __func__, rc); rc = -EINVAL; goto cancel_work; } /* Keep irq enabled */ pr_err("msm_sensor_driver.c irq number = %d", s_ctrl->irq); } /* Set probe succeeded flag to 1 so that no other camera shall * probed on this slot Loading @@ -935,6 +1039,8 @@ CSID_TG: s_ctrl->is_probe_succeed = 1; return rc; cancel_work: cancel_delayed_work(&s_ctrl->irq_delayed_work); free_camera_info: kfree(camera_info); free_slave_info: Loading Loading @@ -1120,7 +1226,6 @@ static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl) /* Store sensor control structure in static database */ g_sctrl[s_ctrl->id] = s_ctrl; CDBG("g_sctrl[%d] %pK", s_ctrl->id, g_sctrl[s_ctrl->id]); return rc; FREE_DT_DATA: Loading Loading @@ -1173,7 +1278,6 @@ static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev) /* Fill platform device id*/ pdev->id = s_ctrl->id; /* Fill device in power info */ s_ctrl->sensordata->power_info.dev = &pdev->dev; Loading include/uapi/media/ais/msm_ais_sensor.h +21 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,27 @@ enum cci_i2c_master_t { MASTER_MAX, }; struct msm_sensor_event_data { uint16_t sensor_slave_addr; }; enum msm_sensor_event_mask_index { SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS = 2, }; #define SENSOR_EVENT_SUBS_MASK_NONE 0 #define SENSOR_EVENT_SUBS_MASK_SIGNAL_STATUS \ (1 << SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS) enum msm_sensor_event_idx { SENSOR_SIGNAL_STATUS = 2, SENSOR_EVENT_MAX = 15 }; #define SENSOR_EVENT_BASE (V4L2_EVENT_PRIVATE_START) #define SENSOR_EVENT_SIGNAL_STATUS (SENSOR_EVENT_BASE + SENSOR_SIGNAL_STATUS) struct msm_camera_i2c_array_write_config { struct msm_camera_i2c_reg_setting conf_array; uint16_t slave_addr; Loading include/uapi/media/ais/msm_ais_sensor_sdk.h +8 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,11 @@ struct msm_sensor_id_info_t { unsigned short sensor_id_mask; }; struct msm_camera_sensor_gpio_intr_config { int gpio_num; uint32_t gpio_trigger; }; struct msm_camera_sensor_slave_info { char sensor_name[32]; char eeprom_name[32]; Loading @@ -300,6 +305,9 @@ struct msm_camera_sensor_slave_info { unsigned char is_init_params_valid; struct msm_sensor_init_params sensor_init_params; enum msm_sensor_output_format_t output_format; struct msm_camera_sensor_gpio_intr_config gpio_intr_config; unsigned int camera_sensor_device_id; }; struct msm_camera_i2c_reg_array { Loading Loading
drivers/media/platform/msm/ais/sensor/msm_sensor.c +122 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,12 @@ * GNU General Public License for more details. */ #include <media/v4l2-subdev.h> #include <media/v4l2-dev.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-device.h> #include <media/v4l2-fh.h> #include <media/v4l2-event.h> #include "msm_sensor.h" #include "msm_sd.h" #include "msm_cci.h" Loading @@ -21,6 +27,7 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) #define MAX_SENSOR_V4l2_EVENTS 100 static struct msm_camera_i2c_fn_t msm_sensor_cci_func_tbl; static struct msm_camera_i2c_fn_t msm_sensor_secure_func_tbl; Loading Loading @@ -404,12 +411,26 @@ static long msm_sensor_subdev_do_ioctl( { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; switch (cmd) { case VIDIOC_MSM_SENSOR_CFG32: cmd = VIDIOC_MSM_SENSOR_CFG; case VIDIOC_DQEVENT: { if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); } break; case VIDIOC_SUBSCRIBE_EVENT: pr_debug("msm_sensor_subdev_do_ioctl:VIDIOC_SUBSCRIBE_EVENT"); return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); case VIDIOC_UNSUBSCRIBE_EVENT: return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); default: return msm_sensor_subdev_ioctl(sd, cmd, arg); pr_debug("msm_sensor.c msm_sensor_subdev_do_ioctl"); return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } } Loading Loading @@ -1467,8 +1488,107 @@ static int msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, return 0; } static u32 msm_sensor_evt_mask_to_sensor_event(u32 evt_mask) { u32 evt_id = SENSOR_EVENT_SUBS_MASK_NONE; switch (evt_mask) { case SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS: evt_id = SENSOR_EVENT_SIGNAL_STATUS; break; default: evt_id = SENSOR_EVENT_SUBS_MASK_NONE; break; } return evt_id; } static int msm_sensor_subscribe_event_mask(struct v4l2_fh *fh, struct v4l2_event_subscription *sub, int evt_mask_index, u32 evt_id, bool subscribe_flag) { int rc = 0; sub->type = evt_id; if (subscribe_flag) rc = v4l2_event_subscribe(fh, sub, MAX_SENSOR_V4l2_EVENTS, NULL); else rc = v4l2_event_unsubscribe(fh, sub); if (rc != 0) { pr_err("%s: Subs event_type =0x%x failed\n", __func__, sub->type); return rc; } return rc; } static int msm_sensor_process_event_subscription(struct v4l2_fh *fh, struct v4l2_event_subscription *sub, bool subscribe_flag) { int rc = 0, evt_mask_index = 0; u32 evt_mask = sub->type; u32 evt_id = 0; if (SENSOR_EVENT_SUBS_MASK_NONE == evt_mask) { pr_err("%s: Subs event_type is None=0x%x\n", __func__, evt_mask); return 0; } evt_mask_index = SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS; if (evt_mask & (1<<evt_mask_index)) { evt_id = msm_sensor_evt_mask_to_sensor_event( evt_mask_index); rc = msm_sensor_subscribe_event_mask(fh, sub, evt_mask_index, evt_id, subscribe_flag); if (rc != 0) { pr_err("%s: Subs event index:%d failed\n", __func__, evt_mask_index); return rc; } } return rc; } int msm_sensor_send_event(struct msm_sensor_ctrl_t *s_ctrl, uint32_t event_type, struct msm_sensor_event_data *event_data) { struct v4l2_event sensor_event; memset(&sensor_event, 0, sizeof(struct v4l2_event)); sensor_event.id = 0; sensor_event.type = event_type; memcpy(&sensor_event.u.data[0], event_data, sizeof(struct msm_sensor_event_data)); v4l2_event_queue(s_ctrl->msm_sd.sd.devnode, &sensor_event); return 0; } static int msm_sensor_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { return msm_sensor_process_event_subscription(fh, sub, true); } static int msm_sensor_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { return msm_sensor_process_event_subscription(fh, sub, false); } static struct v4l2_subdev_core_ops msm_sensor_subdev_core_ops = { .ioctl = msm_sensor_subdev_ioctl, .subscribe_event = msm_sensor_subscribe_event, .unsubscribe_event = msm_sensor_unsubscribe_event, .s_power = msm_sensor_power, }; Loading
drivers/media/platform/msm/ais/sensor/msm_sensor.h +9 −1 Original line number Diff line number Diff line Loading @@ -90,10 +90,18 @@ struct msm_sensor_ctrl_t { uint32_t set_mclk_23880000; uint8_t is_csid_tg_mode; uint32_t is_secure; /* Interrupt GPIOs */ struct gpio gpio_array[1]; /* device status and Flags */ int irq; struct msm_sensor_init_t s_init; /* worker to handle interrupts */ struct delayed_work irq_delayed_work; }; int msm_sensor_send_event(struct msm_sensor_ctrl_t *s_ctrl, uint32_t event_type, struct msm_sensor_event_data *event_data); int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp); int msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl); Loading
drivers/media/platform/msm/ais/sensor/msm_sensor_driver.c +106 −2 Original line number Diff line number Diff line Loading @@ -132,6 +132,7 @@ static int32_t msm_sensor_driver_create_v4l_subdev s_ctrl->sensordata->sensor_name); v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev); s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; media_entity_init(&s_ctrl->msm_sd.sd.entity, 0, NULL, 0); s_ctrl->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; Loading @@ -143,6 +144,8 @@ static int32_t msm_sensor_driver_create_v4l_subdev return rc; } msm_cam_copy_v4l2_subdev_fops(&msm_sensor_v4l2_subdev_fops); msm_sensor_v4l2_subdev_fops.unlocked_ioctl = msm_sensor_subdev_fops_ioctl; #ifdef CONFIG_COMPAT msm_sensor_v4l2_subdev_fops.compat_ioctl32 = msm_sensor_subdev_fops_ioctl; Loading Loading @@ -627,6 +630,56 @@ static void msm_sensor_fill_sensor_info(struct msm_sensor_ctrl_t *s_ctrl, strlcpy(entity_name, s_ctrl->msm_sd.sd.entity.name, MAX_SENSOR_NAME); } static irqreturn_t bridge_irq(int irq, void *dev) { struct msm_sensor_ctrl_t *s_ctrl = dev; pr_err("msm_sensor_driver: received bridge interrupt:0x%x", s_ctrl->sensordata->slave_info->sensor_slave_addr); schedule_delayed_work(&s_ctrl->irq_delayed_work, msecs_to_jiffies(0)); return IRQ_HANDLED; } static void bridge_irq_delay_work(struct work_struct *work) { struct msm_sensor_ctrl_t *s_ctrl; struct msm_camera_i2c_client *sensor_i2c_client; struct msm_camera_slave_info *slave_info; const char *sensor_name; struct msm_sensor_event_data sensor_event; s_ctrl = container_of(work, struct msm_sensor_ctrl_t, irq_delayed_work.work); if (!s_ctrl) { pr_err("%s:%d failed: %pK\n", __func__, __LINE__, s_ctrl); goto exit_queue; } sensor_i2c_client = s_ctrl->sensor_i2c_client; slave_info = s_ctrl->sensordata->slave_info; sensor_name = s_ctrl->sensordata->sensor_name; if (!sensor_i2c_client || !slave_info || !sensor_name) { pr_err("%s:%d failed: %pK %pK %pK\n", __func__, __LINE__, sensor_i2c_client, slave_info, sensor_name); goto exit_queue; } mutex_lock(s_ctrl->msm_sensor_mutex); /* Fill the sensor event */ sensor_event.sensor_slave_addr = slave_info->sensor_slave_addr; /* Queue the event */ msm_sensor_send_event(s_ctrl, SENSOR_EVENT_SIGNAL_STATUS, &sensor_event); mutex_unlock(s_ctrl->msm_sensor_mutex); exit_queue: pr_err("Work IRQ exit"); } /* static function definition */ int32_t msm_sensor_driver_probe(void *setting, struct msm_sensor_info_t *probed_info, char *entity_name) Loading Loading @@ -928,6 +981,57 @@ CSID_TG: msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name); if (slave_info->gpio_intr_config.gpio_num != -1) { /* Configure INTB interrupt */ s_ctrl->gpio_array[0].gpio = slave_info->gpio_intr_config.gpio_num; s_ctrl->gpio_array[0].flags = 0; /* Only setup IRQ1 for now... */ INIT_DELAYED_WORK(&s_ctrl->irq_delayed_work, bridge_irq_delay_work); rc = gpio_request_array(&s_ctrl->gpio_array[0], 1); if (rc < 0) { pr_err("%s: Failed to request irq_gpio %d", __func__, rc); goto cancel_work; } if (gpio_is_valid(s_ctrl->gpio_array[0].gpio)) { rc |= gpio_direction_input( s_ctrl->gpio_array[0].gpio); if (rc) { pr_err("%s: Failed gpio_direction irq %d", __func__, rc); goto cancel_work; } else { pr_err("sensor probe IRQ direction succeeded"); } } s_ctrl->irq = gpio_to_irq(s_ctrl->gpio_array[0].gpio); if (s_ctrl->irq) { rc = request_irq(s_ctrl->irq, bridge_irq, IRQF_ONESHOT | (slave_info-> gpio_intr_config.gpio_trigger), "qcom,camera", s_ctrl); if (rc) { pr_err("%s: Failed request_irq %d", __func__, rc); goto cancel_work; } } else { pr_err("%s: Failed gpio_to_irq %d", __func__, rc); rc = -EINVAL; goto cancel_work; } /* Keep irq enabled */ pr_err("msm_sensor_driver.c irq number = %d", s_ctrl->irq); } /* Set probe succeeded flag to 1 so that no other camera shall * probed on this slot Loading @@ -935,6 +1039,8 @@ CSID_TG: s_ctrl->is_probe_succeed = 1; return rc; cancel_work: cancel_delayed_work(&s_ctrl->irq_delayed_work); free_camera_info: kfree(camera_info); free_slave_info: Loading Loading @@ -1120,7 +1226,6 @@ static int32_t msm_sensor_driver_parse(struct msm_sensor_ctrl_t *s_ctrl) /* Store sensor control structure in static database */ g_sctrl[s_ctrl->id] = s_ctrl; CDBG("g_sctrl[%d] %pK", s_ctrl->id, g_sctrl[s_ctrl->id]); return rc; FREE_DT_DATA: Loading Loading @@ -1173,7 +1278,6 @@ static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev) /* Fill platform device id*/ pdev->id = s_ctrl->id; /* Fill device in power info */ s_ctrl->sensordata->power_info.dev = &pdev->dev; Loading
include/uapi/media/ais/msm_ais_sensor.h +21 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,27 @@ enum cci_i2c_master_t { MASTER_MAX, }; struct msm_sensor_event_data { uint16_t sensor_slave_addr; }; enum msm_sensor_event_mask_index { SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS = 2, }; #define SENSOR_EVENT_SUBS_MASK_NONE 0 #define SENSOR_EVENT_SUBS_MASK_SIGNAL_STATUS \ (1 << SENSOR_EVENT_MASK_INDEX_SIGNAL_STATUS) enum msm_sensor_event_idx { SENSOR_SIGNAL_STATUS = 2, SENSOR_EVENT_MAX = 15 }; #define SENSOR_EVENT_BASE (V4L2_EVENT_PRIVATE_START) #define SENSOR_EVENT_SIGNAL_STATUS (SENSOR_EVENT_BASE + SENSOR_SIGNAL_STATUS) struct msm_camera_i2c_array_write_config { struct msm_camera_i2c_reg_setting conf_array; uint16_t slave_addr; Loading
include/uapi/media/ais/msm_ais_sensor_sdk.h +8 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,11 @@ struct msm_sensor_id_info_t { unsigned short sensor_id_mask; }; struct msm_camera_sensor_gpio_intr_config { int gpio_num; uint32_t gpio_trigger; }; struct msm_camera_sensor_slave_info { char sensor_name[32]; char eeprom_name[32]; Loading @@ -300,6 +305,9 @@ struct msm_camera_sensor_slave_info { unsigned char is_init_params_valid; struct msm_sensor_init_params sensor_init_params; enum msm_sensor_output_format_t output_format; struct msm_camera_sensor_gpio_intr_config gpio_intr_config; unsigned int camera_sensor_device_id; }; struct msm_camera_i2c_reg_array { Loading