static long msm_ispif_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); return msm_ispif_subdev_ioctl(sd, cmd, arg); }
static long msm_sensor_init_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { int32_t rc = 0; struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct sensor_init_cfg_data32 *u32 = (struct sensor_init_cfg_data32 *)arg; struct sensor_init_cfg_data sensor_init_data; switch (cmd) { case VIDIOC_MSM_SENSOR_INIT_CFG32: memset(&sensor_init_data, 0, sizeof(sensor_init_data)); sensor_init_data.cfgtype = u32->cfgtype; sensor_init_data.cfg.setting = compat_ptr(u32->cfg.setting); cmd = VIDIOC_MSM_SENSOR_INIT_CFG; rc = msm_sensor_init_subdev_ioctl(sd, cmd, &sensor_init_data); if (rc < 0) { pr_err("%s:%d VIDIOC_MSM_SENSOR_INIT_CFG failed", __func__, __LINE__); return rc; } u32->probed_info = sensor_init_data.probed_info; strlcpy(u32->entity_name, sensor_init_data.entity_name, sizeof(sensor_init_data.entity_name)); return 0; default: return msm_sensor_init_subdev_ioctl(sd, cmd, arg); } }
static long msm_tcs_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct msm_tcs_cfg_data32 *u32 = (struct msm_tcs_cfg_data32 *)arg; struct msm_tcs_cfg_data tcs_data; void __user *parg = (void __user *)arg; CDBG("Enter\n"); switch (cmd) { case VIDIOC_MSM_TCS_CFG32: cmd = VIDIOC_MSM_TCS_CFG; switch (u32->cfgtype) { case CFG_TCS_INIT: case CFG_TCS_ON: case CFG_TCS_OFF: case CFG_GET_TCS: case CFG_TCS_THREAD_ON: case CFG_TCS_THREAD_PAUSE: case CFG_TCS_THREAD_RESTART: case CFG_TCS_THREAD_OFF: case CFG_TCS_AAT_MODE: break; default: tcs_data.cfgtype = u32->cfgtype; parg = &tcs_data; break; } } return msm_tcs_subdev_ioctl(sd, cmd, parg); }
static long subdev_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); return v4l2_subdev_call(sd, core, compat_ioctl32, cmd, arg); }
static int subdev_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_subdev_fh *subdev_fh; #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity *entity = NULL; #endif int ret; subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); if (subdev_fh == NULL) return -ENOMEM; ret = subdev_fh_init(subdev_fh, sd); if (ret) { kfree(subdev_fh); return ret; } v4l2_fh_init(&subdev_fh->vfh, vdev); v4l2_fh_add(&subdev_fh->vfh); file->private_data = &subdev_fh->vfh; #if defined(CONFIG_MEDIA_CONTROLLER) if (sd->v4l2_dev->mdev) { entity = media_entity_get(&sd->entity); if (!entity) { ret = -EBUSY; goto err; } } #endif if (sd->internal_ops && sd->internal_ops->open) { ret = sd->internal_ops->open(sd, subdev_fh); if (ret < 0) goto err; } return 0; err: #if defined(CONFIG_MEDIA_CONTROLLER) if (entity) media_entity_put(entity); #endif v4l2_fh_del(&subdev_fh->vfh); v4l2_fh_exit(&subdev_fh->vfh); subdev_fh_free(subdev_fh); kfree(subdev_fh); return ret; }
static long msm_sensor_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); switch (cmd) { case VIDIOC_MSM_SENSOR_CFG32: cmd = VIDIOC_MSM_SENSOR_CFG; default: return msm_sensor_subdev_ioctl(sd, cmd, arg); } }
static long msm_flash_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { int32_t rc = 0; struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct msm_flash_cfg_data_t32 *u32 = (struct msm_flash_cfg_data_t32 *)arg; struct msm_flash_cfg_data_t flash_data; struct msm_flash_init_info_t32 flash_init_info32; struct msm_flash_init_info_t flash_init_info; CDBG("Enter"); flash_data.cfg_type = u32->cfg_type; switch (cmd) { case VIDIOC_MSM_FLASH_CFG32: cmd = VIDIOC_MSM_FLASH_CFG; switch (flash_data.cfg_type) { case CFG_FLASH_OFF: case CFG_FLASH_LOW: case CFG_FLASH_HIGH: flash_data.cfg.settings = compat_ptr(u32->cfg.settings); break; case CFG_FLASH_INIT: flash_data.cfg.flash_init_info = &flash_init_info; if (copy_from_user(&flash_init_info32, (void *)compat_ptr(u32->cfg.flash_init_info), sizeof(struct msm_flash_init_info_t32))) { pr_err("%s copy_from_user failed %d\n", __func__, __LINE__); return -EFAULT; } flash_init_info.flash_driver_type = flash_init_info32.flash_driver_type; flash_init_info.settings = compat_ptr(flash_init_info32.settings); flash_init_info.power_setting_array = compat_ptr( flash_init_info32.power_setting_array); break; default: break; } break; default: return msm_flash_subdev_ioctl(sd, cmd, arg); } rc = msm_flash_subdev_ioctl(sd, cmd, &flash_data); CDBG("Exit"); return rc; }
static unsigned int subdev_poll(struct file *file, poll_table *wait) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *fh = file->private_data; if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return POLLERR; poll_wait(file, &fh->wait, wait); if (v4l2_event_pending(fh)) return POLLPRI; return 0; }
static long msm_cpp_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { 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_DQEVENT: if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case 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); case VIDIOC_MSM_CPP_GET_INST_INFO: { uint32_t i; struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd); struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg; struct msm_cpp_frame_info_t inst_info; memset(&inst_info, 0 , sizeof(struct msm_cpp_frame_info_t)); for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) { if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) { inst_info.inst_id = i; break; } } if (copy_to_user( (void __user *)ioctl_ptr->ioctl_ptr, &inst_info, sizeof(struct msm_cpp_frame_info_t))) { return -EINVAL; } } break; default: return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } return 0; }
static int subdev_close(struct file *file) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); v4l2_subdev_call(sd, file, close, subdev_fh); #if defined(CONFIG_MEDIA_CONTROLLER) if (sd->v4l2_dev->mdev) media_entity_put(&sd->entity); #endif v4l2_fh_del(vfh); v4l2_fh_exit(vfh); subdev_fh_free(subdev_fh); kfree(subdev_fh); file->private_data = NULL; return 0; }
static long msm_isp_subdev_do_ioctl( struct file *file, unsigned int cmd, void *arg) { 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_DQEVENT: if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case 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 v4l2_subdev_call(sd, core, ioctl, cmd, arg); } }
static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; #if defined(CPTCFG_VIDEO_V4L2_SUBDEV_API) struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); int rval; #endif switch (cmd) { case VIDIOC_QUERYCTRL: return v4l2_queryctrl(vfh->ctrl_handler, arg); case VIDIOC_QUERY_EXT_CTRL: return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg); case VIDIOC_QUERYMENU: return v4l2_querymenu(vfh->ctrl_handler, arg); case VIDIOC_G_CTRL: return v4l2_g_ctrl(vfh->ctrl_handler, arg); case VIDIOC_S_CTRL: return v4l2_s_ctrl(vfh, vfh->ctrl_handler, arg); case VIDIOC_G_EXT_CTRLS: return v4l2_g_ext_ctrls(vfh->ctrl_handler, arg); case VIDIOC_S_EXT_CTRLS: return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, arg); case VIDIOC_TRY_EXT_CTRLS: return v4l2_try_ext_ctrls(vfh->ctrl_handler, arg); case VIDIOC_DQEVENT: if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case 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); #ifdef CPTCFG_VIDEO_ADV_DEBUG case VIDIOC_DBG_G_REGISTER: { struct v4l2_dbg_register *p = arg; if (!capable(CAP_SYS_ADMIN)) return -EPERM; return v4l2_subdev_call(sd, core, g_register, p); } case VIDIOC_DBG_S_REGISTER: { struct v4l2_dbg_register *p = arg; if (!capable(CAP_SYS_ADMIN)) return -EPERM; return v4l2_subdev_call(sd, core, s_register, p); } #endif case VIDIOC_LOG_STATUS: { int ret; pr_info("%s: ================= START STATUS =================\n", sd->name); ret = v4l2_subdev_call(sd, core, log_status); pr_info("%s: ================== END STATUS ==================\n", sd->name); return ret; } #if defined(CPTCFG_VIDEO_V4L2_SUBDEV_API) case VIDIOC_SUBDEV_G_FMT: { struct v4l2_subdev_format *format = arg; rval = check_format(sd, format); if (rval) return rval; return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh->pad, format); } case VIDIOC_SUBDEV_S_FMT: { struct v4l2_subdev_format *format = arg; rval = check_format(sd, format); if (rval) return rval; return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); } case VIDIOC_SUBDEV_G_CROP: { struct v4l2_subdev_crop *crop = arg; struct v4l2_subdev_selection sel; rval = check_crop(sd, crop); if (rval) return rval; memset(&sel, 0, sizeof(sel)); sel.which = crop->which; sel.pad = crop->pad; sel.target = V4L2_SEL_TGT_CROP; rval = v4l2_subdev_call( sd, pad, get_selection, subdev_fh->pad, &sel); crop->rect = sel.r; return rval; } case VIDIOC_SUBDEV_S_CROP: { struct v4l2_subdev_crop *crop = arg; struct v4l2_subdev_selection sel; rval = check_crop(sd, crop); if (rval) return rval; memset(&sel, 0, sizeof(sel)); sel.which = crop->which; sel.pad = crop->pad; sel.target = V4L2_SEL_TGT_CROP; sel.r = crop->rect; rval = v4l2_subdev_call( sd, pad, set_selection, subdev_fh->pad, &sel); crop->rect = sel.r; return rval; } case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { struct v4l2_subdev_mbus_code_enum *code = arg; if (code->which != V4L2_SUBDEV_FORMAT_TRY && code->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (code->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh->pad, code); } case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { struct v4l2_subdev_frame_size_enum *fse = arg; if (fse->which != V4L2_SUBDEV_FORMAT_TRY && fse->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (fse->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh->pad, fse); } case VIDIOC_SUBDEV_G_FRAME_INTERVAL: { struct v4l2_subdev_frame_interval *fi = arg; if (fi->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, video, g_frame_interval, arg); } case VIDIOC_SUBDEV_S_FRAME_INTERVAL: { struct v4l2_subdev_frame_interval *fi = arg; if (fi->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, video, s_frame_interval, arg); } case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { struct v4l2_subdev_frame_interval_enum *fie = arg; if (fie->which != V4L2_SUBDEV_FORMAT_TRY && fie->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (fie->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh->pad, fie); } case VIDIOC_SUBDEV_G_SELECTION: { struct v4l2_subdev_selection *sel = arg; rval = check_selection(sd, sel); if (rval) return rval; return v4l2_subdev_call( sd, pad, get_selection, subdev_fh->pad, sel); } case VIDIOC_SUBDEV_S_SELECTION: { struct v4l2_subdev_selection *sel = arg; rval = check_selection(sd, sel); if (rval) return rval; return v4l2_subdev_call( sd, pad, set_selection, subdev_fh->pad, sel); } case VIDIOC_G_EDID: { struct v4l2_subdev_edid *edid = arg; rval = check_edid(sd, edid); if (rval) return rval; return v4l2_subdev_call(sd, pad, get_edid, edid); } case VIDIOC_S_EDID: { struct v4l2_subdev_edid *edid = arg; rval = check_edid(sd, edid); if (rval) return rval; return v4l2_subdev_call(sd, pad, set_edid, edid); } case VIDIOC_SUBDEV_DV_TIMINGS_CAP: { struct v4l2_dv_timings_cap *cap = arg; if (cap->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, dv_timings_cap, cap); } case VIDIOC_SUBDEV_ENUM_DV_TIMINGS: { struct v4l2_enum_dv_timings *dvt = arg; if (dvt->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_dv_timings, dvt); } case VIDIOC_SUBDEV_QUERY_DV_TIMINGS: return v4l2_subdev_call(sd, video, query_dv_timings, arg); case VIDIOC_SUBDEV_G_DV_TIMINGS: return v4l2_subdev_call(sd, video, g_dv_timings, arg); case VIDIOC_SUBDEV_S_DV_TIMINGS: return v4l2_subdev_call(sd, video, s_dv_timings, arg); #endif default: return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } return 0; }
static int subdev_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_subdev_fh *subdev_fh; #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity *entity = NULL; #endif int ret; if (!sd->initialized) return -EAGAIN; subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); if (subdev_fh == NULL) return -ENOMEM; ret = subdev_fh_init(subdev_fh, sd); if (ret) { kfree(subdev_fh); return ret; } ret = v4l2_fh_init(&subdev_fh->vfh, vdev); if (ret) goto err; if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) { ret = v4l2_event_init(&subdev_fh->vfh); if (ret) goto err; ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents); if (ret) goto err; } v4l2_fh_add(&subdev_fh->vfh); file->private_data = &subdev_fh->vfh; #if defined(CONFIG_MEDIA_CONTROLLER) if (sd->v4l2_dev->mdev) { entity = media_entity_get(&sd->entity); if (!entity) { ret = -EBUSY; goto err; } } #endif ret = v4l2_subdev_call(sd, file, open, subdev_fh); if (ret < 0 && ret != -ENOIOCTLCMD) goto err; return 0; err: #if defined(CONFIG_MEDIA_CONTROLLER) if (entity) media_entity_put(entity); #endif v4l2_fh_del(&subdev_fh->vfh); v4l2_fh_exit(&subdev_fh->vfh); subdev_fh_free(subdev_fh); kfree(subdev_fh); return ret; }
static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_fh *vfh = file->private_data; #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); #endif switch (cmd) { case VIDIOC_QUERYCTRL: return v4l2_subdev_queryctrl(sd, arg); case VIDIOC_QUERYMENU: return v4l2_subdev_querymenu(sd, arg); case VIDIOC_G_CTRL: return v4l2_subdev_g_ctrl(sd, arg); case VIDIOC_S_CTRL: return v4l2_subdev_s_ctrl(sd, arg); case VIDIOC_G_EXT_CTRLS: return v4l2_subdev_g_ext_ctrls(sd, arg); case VIDIOC_S_EXT_CTRLS: return v4l2_subdev_s_ext_ctrls(sd, arg); case VIDIOC_TRY_EXT_CTRLS: return v4l2_subdev_try_ext_ctrls(sd, arg); case VIDIOC_DQEVENT: if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) return -ENOIOCTLCMD; return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); case 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); #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) case VIDIOC_SUBDEV_G_FMT: { struct v4l2_subdev_format *format = arg; if (format->which != V4L2_SUBDEV_FORMAT_TRY && format->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (format->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format); } case VIDIOC_SUBDEV_S_FMT: { struct v4l2_subdev_format *format = arg; if (format->which != V4L2_SUBDEV_FORMAT_TRY && format->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (format->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format); } case VIDIOC_SUBDEV_G_CROP: { struct v4l2_subdev_crop *crop = arg; if (crop->which != V4L2_SUBDEV_FORMAT_TRY && crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (crop->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop); } case VIDIOC_SUBDEV_S_CROP: { struct v4l2_subdev_crop *crop = arg; if (crop->which != V4L2_SUBDEV_FORMAT_TRY && crop->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; if (crop->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop); } case VIDIOC_SUBDEV_ENUM_MBUS_CODE: { struct v4l2_subdev_mbus_code_enum *code = arg; if (code->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh, code); } case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: { struct v4l2_subdev_frame_size_enum *fse = arg; if (fse->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh, fse); } case VIDIOC_SUBDEV_G_FRAME_INTERVAL: return v4l2_subdev_call(sd, video, g_frame_interval, arg); case VIDIOC_SUBDEV_S_FRAME_INTERVAL: return v4l2_subdev_call(sd, video, s_frame_interval, arg); case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: { struct v4l2_subdev_frame_interval_enum *fie = arg; if (fie->pad >= sd->entity.num_pads) return -EINVAL; return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh, fie); } #endif default: return v4l2_subdev_call(sd, core, ioctl, cmd, arg); } return 0; }