static int adv7180_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct adv7180_state *state = to_state(sd); v4l2_async_unregister_subdev(sd); if (state->irq > 0) free_irq(client->irq, state); media_entity_cleanup(&sd->entity); adv7180_exit_controls(state); if (state->chip_info->flags & ADV7180_FLAG_I2P) i2c_unregister_device(state->vpp_client); if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) i2c_unregister_device(state->csi_client); mutex_destroy(&state->mutex); return 0; }
static int lm3554_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct lm3554_priv *p_lm3554_priv = to_lm3554_priv(sd); struct camera_flash_platform_data *pdata = p_lm3554_priv->platform_data; int ret; media_entity_cleanup(&p_lm3554_priv->sd.entity); v4l2_device_unregister_subdev(sd); del_timer_sync(&p_lm3554_priv->flash_off_delay); ret = set_gpio_output(pdata->gpio_strobe, "flash", 0); if (ret < 0) goto fail; kfree(p_lm3554_priv); return 0; fail: dev_err(&client->dev, "gpio request/direction_output fail"); return ret; }
static int lm3556_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct lm3556_priv *p_lm3556_priv = to_lm3556_priv(sd); int ret; media_entity_cleanup(&p_lm3556_priv->sd.entity); v4l2_device_unregister_subdev(sd); ret = gpio_direction_output(GP_LM3556_FLASH_STROBE, 0); if (ret < 0) dev_err(&client->dev, "failed to set strobe on remove"); ret = gpio_direction_output(GP_LM3556_FLASH_RESET, 0); if (ret < 0) dev_err(&client->dev, "failed to set reset on remove"); gpio_free(GP_LM3556_FLASH_RESET); gpio_free(GP_LM3556_FLASH_STROBE); kfree(p_lm3556_priv); return 0; }
int hwcam_dev_create( struct device* dev, int* dev_num) { int rc = 0; struct v4l2_device* v4l2 = NULL; struct video_device* vdev = NULL; struct media_device* mdev = NULL; hwcam_dev_t* cam = NULL; cam = kzalloc(sizeof(hwcam_dev_t), GFP_KERNEL); if (WARN_ON(!cam)) { rc = -ENOMEM; goto init_end; } v4l2 = &cam->v4l2; vdev = video_device_alloc(); if (!vdev) { rc = -ENOMEM; goto video_alloc_fail; } mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!mdev) { rc = -ENOMEM; goto media_alloc_fail; } strlcpy(mdev->model, HWCAM_MODEL_USER, sizeof(mdev->model)); mdev->dev = dev; rc = media_device_register(mdev); if (rc < 0) { goto media_register_fail; } rc = media_entity_init(&vdev->entity, 0, NULL, 0); if (rc < 0) { goto entity_init_fail; } v4l2->mdev = mdev; v4l2->notify = NULL; rc = v4l2_device_register(dev, v4l2); if (rc < 0) { goto v4l2_register_fail; } strlcpy(vdev->name, "hwcam-userdev", sizeof(vdev->name)); vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; vdev->entity.group_id = HWCAM_DEVICE_GROUP_ID; vdev->v4l2_dev = v4l2; vdev->release = video_device_release; vdev->fops = &s_fops_hwcam_dev; vdev->ioctl_ops = &s_iops_hwcam_dev; vdev->minor = -1; vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (rc < 0) { goto video_register_fail; } cam_debug("video dev name %s %s",vdev->dev.kobj.name,vdev->name); mutex_init(&cam->lock); vdev->lock = &cam->lock; vdev->entity.name = video_device_node_name(vdev); video_set_drvdata(vdev, cam); cam->vdev = vdev; cam->mdev = mdev; cam->intf.vtbl = &s_vtbl_hwcam_dev; *dev_num = vdev->num; goto init_end; video_register_fail: v4l2_device_unregister(v4l2); v4l2_register_fail: media_entity_cleanup(&vdev->entity); entity_init_fail: media_device_unregister(mdev); media_register_fail: kzfree(mdev); media_alloc_fail: video_device_release(vdev); video_alloc_fail: kzfree(cam); init_end: return rc; }
int camera_init_v4l2(struct device *dev, unsigned int *session) { struct msm_video_device *pvdev; struct v4l2_device *v4l2_dev; int rc = 0; pvdev = kzalloc(sizeof(struct msm_video_device), GFP_KERNEL); if (WARN_ON(!pvdev)) { rc = -ENOMEM; goto init_end; } pvdev->vdev = video_device_alloc(); if (WARN_ON(!pvdev->vdev)) { rc = -ENOMEM; goto video_fail; } v4l2_dev = kzalloc(sizeof(struct v4l2_device), GFP_KERNEL); if (WARN_ON(!v4l2_dev)) { rc = -ENOMEM; goto v4l2_fail; } #if defined(CONFIG_MEDIA_CONTROLLER) v4l2_dev->mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!v4l2_dev->mdev) { rc = -ENOMEM; goto mdev_fail; } strlcpy(v4l2_dev->mdev->model, MSM_CAMERA_NAME, sizeof(v4l2_dev->mdev->model)); v4l2_dev->mdev->dev = dev; rc = media_device_register(v4l2_dev->mdev); if (WARN_ON(rc < 0)) goto media_fail; rc = media_entity_init(&pvdev->vdev->entity, 0, NULL, 0); if (WARN_ON(rc < 0)) goto entity_fail; pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID; #endif v4l2_dev->notify = NULL; pvdev->vdev->v4l2_dev = v4l2_dev; rc = v4l2_device_register(dev, pvdev->vdev->v4l2_dev); if (WARN_ON(rc < 0)) goto register_fail; strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name)); pvdev->vdev->release = video_device_release; pvdev->vdev->fops = &camera_v4l2_fops; pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops; pvdev->vdev->minor = -1; pvdev->vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(pvdev->vdev, VFL_TYPE_GRABBER, -1); if (WARN_ON(rc < 0)) goto video_register_fail; #if defined(CONFIG_MEDIA_CONTROLLER) /* FIXME: How to get rid of this messy? */ pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev); #endif *session = pvdev->vdev->num; atomic_set(&pvdev->opened, 0); atomic_set(&pvdev->stream_cnt, 0); video_set_drvdata(pvdev->vdev, pvdev); device_init_wakeup(&pvdev->vdev->dev, 1); if(!cam_wakelock_init) { cam_wakelock_init = 1; wake_lock_init(&cam_wakelock, WAKE_LOCK_SUSPEND, "cam_wakelock"); } goto init_end; video_register_fail: v4l2_device_unregister(pvdev->vdev->v4l2_dev); register_fail: #if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&pvdev->vdev->entity); entity_fail: media_device_unregister(v4l2_dev->mdev); media_fail: kzfree(v4l2_dev->mdev); mdev_fail: #endif kzfree(v4l2_dev); v4l2_fail: video_device_release(pvdev->vdev); video_fail: kzfree(pvdev); init_end: return rc; }
/* * omap4iss_ipipe_cleanup - IPIPE module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. */ void omap4iss_ipipe_cleanup(struct iss_device *iss) { struct iss_ipipe_device *ipipe = &iss->ipipe; media_entity_cleanup(&ipipe->subdev.entity); }
int fimc_isp_video_device_register(struct fimc_isp *isp, struct v4l2_device *v4l2_dev, enum v4l2_buf_type type) { struct vb2_queue *q = &isp->video_capture.vb_queue; struct fimc_is_video *iv; struct video_device *vdev; int ret; if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) iv = &isp->video_capture; else return -ENOSYS; mutex_init(&isp->video_lock); INIT_LIST_HEAD(&iv->pending_buf_q); INIT_LIST_HEAD(&iv->active_buf_q); iv->format = fimc_isp_find_format(NULL, NULL, 0); iv->pixfmt.width = IS_DEFAULT_WIDTH; iv->pixfmt.height = IS_DEFAULT_HEIGHT; iv->pixfmt.pixelformat = iv->format->fourcc; iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB; iv->reqbufs_count = 0; memset(q, 0, sizeof(*q)); q->type = type; q->io_modes = VB2_MMAP | VB2_USERPTR; q->ops = &isp_video_capture_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct isp_video_buf); q->drv_priv = isp; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->lock = &isp->video_lock; ret = vb2_queue_init(q); if (ret < 0) return ret; vdev = &iv->ve.vdev; memset(vdev, 0, sizeof(*vdev)); snprintf(vdev->name, sizeof(vdev->name), "fimc-is-isp.%s", type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? "capture" : "output"); vdev->queue = q; vdev->fops = &isp_video_fops; vdev->ioctl_ops = &isp_video_ioctl_ops; vdev->v4l2_dev = v4l2_dev; vdev->minor = -1; vdev->release = video_device_release_empty; vdev->lock = &isp->video_lock; iv->pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&vdev->entity, 1, &iv->pad); if (ret < 0) return ret; video_set_drvdata(vdev, isp); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { media_entity_cleanup(&vdev->entity); return ret; } v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", vdev->name, video_device_node_name(vdev)); return 0; }
static void atomisp_subdev_cleanup_entities(struct atomisp_sub_device *asd) { v4l2_ctrl_handler_free(&asd->ctrl_handler); media_entity_cleanup(&asd->subdev.entity); }
int fimc_isp_subdev_create(struct fimc_isp *isp) { const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops; struct v4l2_ctrl_handler *handler = &isp->ctrls.handler; struct v4l2_subdev *sd = &isp->subdev; struct fimc_isp_ctrls *ctrls = &isp->ctrls; int ret; mutex_init(&isp->subdev_lock); v4l2_subdev_init(sd, &fimc_is_subdev_ops); sd->owner = THIS_MODULE; sd->grp_id = GRP_ID_FIMC_IS; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(sd->name, sizeof(sd->name), "FIMC-IS-ISP"); isp->subdev_pads[FIMC_ISP_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK; isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE; isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, FIMC_ISP_SD_PADS_NUM, isp->subdev_pads, 0); if (ret) return ret; v4l2_ctrl_handler_init(handler, 20); ctrls->saturation = v4l2_ctrl_new_std(handler, ops, V4L2_CID_SATURATION, -2, 2, 1, 0); ctrls->brightness = v4l2_ctrl_new_std(handler, ops, V4L2_CID_BRIGHTNESS, -4, 4, 1, 0); ctrls->contrast = v4l2_ctrl_new_std(handler, ops, V4L2_CID_CONTRAST, -2, 2, 1, 0); ctrls->sharpness = v4l2_ctrl_new_std(handler, ops, V4L2_CID_SHARPNESS, -2, 2, 1, 0); ctrls->hue = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HUE, -2, 2, 1, 0); ctrls->auto_wb = v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE, 8, ~0x14e, V4L2_WHITE_BALANCE_AUTO); ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE_ABSOLUTE, -4, 4, 1, 0); ctrls->exp_metering = v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_EXPOSURE_METERING, 3, ~0xf, V4L2_EXPOSURE_METERING_AVERAGE); v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_POWER_LINE_FREQUENCY, V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, V4L2_CID_POWER_LINE_FREQUENCY_AUTO); /* ISO sensitivity */ ctrls->auto_iso = v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_ISO_SENSITIVITY_AUTO, 1, 0, V4L2_ISO_SENSITIVITY_AUTO); ctrls->iso = v4l2_ctrl_new_int_menu(handler, ops, V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1, ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu); ctrls->aewb_lock = v4l2_ctrl_new_std(handler, ops, V4L2_CID_3A_LOCK, 0, 0x3, 0, 0); /* TODO: Add support for NEGATIVE_COLOR option */ ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR + 1, ~0x1000f, V4L2_COLORFX_NONE); if (handler->error) { media_entity_cleanup(&sd->entity); return handler->error; } v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, V4L2_ISO_SENSITIVITY_MANUAL, false); sd->ctrl_handler = handler; sd->internal_ops = &fimc_is_subdev_internal_ops; sd->entity.ops = &fimc_is_subdev_media_ops; v4l2_set_subdevdata(sd, isp); __isp_subdev_set_default_format(isp); return 0; }
static int __devinit lm3556_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err; struct lm3556_priv *p_lm3556_priv; p_lm3556_priv = kzalloc(sizeof(*p_lm3556_priv), GFP_KERNEL); if (!p_lm3556_priv) { dev_err(&client->dev, "out of memory\n"); return -ENOMEM; } v4l2_i2c_subdev_init(&(p_lm3556_priv->sd), client, &lm3556_ops); p_lm3556_priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; p_lm3556_priv->sd.entity.ops = &lm3556_entity_ops; p_lm3556_priv->timeout = LM3556_DEFAULT_TIMEOUT; p_lm3556_priv->mode = ATOMISP_FLASH_MODE_OFF; err = media_entity_init(&p_lm3556_priv->sd.entity, 0, NULL, 0); if (err) { dev_err(&client->dev, "error initialize a media entity.\n"); goto fail1; } mutex_init(&p_lm3556_priv->i2c_mutex); err = gpio_request(GP_LM3556_FLASH_STROBE, "lm3556 strobe"); if (err) { dev_err(&client->dev, "unable to claim lm3556 strobe gpio\n"); goto fail2; } err = gpio_export(GP_LM3556_FLASH_STROBE, 0); if (err) { dev_err(&client->dev, "unable to export lm3556 strobe gpio\n"); goto fail3; } err = gpio_request(GP_LM3556_FLASH_RESET, "lm3556 reset"); if (err) { dev_err(&client->dev, "unable to claim flash lm3556 reset gpio\n"); goto fail3; } err = gpio_export(GP_LM3556_FLASH_RESET, 0); if (err) { dev_err(&client->dev, "unable to export lm3556 reset gpio\n"); goto fail4; } err = lm3556_detect(client); if (err) { dev_err(&client->dev, "device not found\n"); goto fail4; } return 0; fail4: gpio_free(GP_LM3556_FLASH_RESET); fail3: gpio_free(GP_LM3556_FLASH_STROBE); fail2: media_entity_cleanup(&p_lm3556_priv->sd.entity); fail1: v4l2_device_unregister_subdev(&p_lm3556_priv->sd); kfree(p_lm3556_priv); return err; }
void vsp1_entity_destroy(struct vsp1_entity *entity) { if (entity->subdev.ctrl_handler) v4l2_ctrl_handler_free(entity->subdev.ctrl_handler); media_entity_cleanup(&entity->subdev.entity); }
int register_tx_isp_vic_device(struct platform_device *pdev, struct v4l2_device *v4l2_dev) { struct tx_isp_subdev_platform_data *pdata = pdev->dev.platform_data; struct tx_isp_vic_driver *vsd = NULL; struct resource *res = NULL; struct v4l2_subdev *sd = NULL; struct media_pad *pads = NULL; struct media_entity *me = NULL; struct proc_dir_entry *proc; int ret; if(!pdata){ v4l2_err(v4l2_dev, "The platform_data of csi is NULL!\n"); ret = -ISP_ERROR; goto exit; }; vsd = (struct tx_isp_vic_driver *)kzalloc(sizeof(*vsd), GFP_KERNEL); if(!vsd){ v4l2_err(v4l2_dev, "Failed to allocate sensor device\n"); ret = -ISP_ERROR; goto exit; } vsd->pdata = pdata; vsd->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if(res){ res = request_mem_region(res->start, res->end - res->start + 1, dev_name(&pdev->dev)); if (!res) { v4l2_err(v4l2_dev, "Not enough memory for resources\n"); ret = -EBUSY; goto mem_region_failed; } vsd->base = ioremap(res->start, res->end - res->start + 1); if (!vsd->base) { v4l2_err(v4l2_dev, "Unable to ioremap registers!\n"); ret = -ENXIO; goto ioremap_failed; } } vsd->res = res; sd = &vsd->sd; pads = vsd->pads; me = &sd->entity; v4l2_subdev_init(sd, &vic_subdev_ops); strlcpy(sd->name, "TX-ISP-VIC-SUBDEV ", sizeof(sd->name)); sd->grp_id = pdata->grp_id ; /* group ID for isp subdevs */ v4l2_set_subdevdata(sd, vsd); pads[TX_ISP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; pads[TX_ISP_PAD_LINK].flags = MEDIA_PAD_FL_SINK; me->ops = &vic_media_ops; // me->parent = v4l2_dev->mdev; ret = media_entity_init(me, TX_ISP_PADS_NUM, pads, 0); if (ret < 0){ v4l2_err(v4l2_dev, "Failed to init media entity!\n"); ret = -ISP_ERROR; goto entity_init_failed; } ret = v4l2_device_register_subdev(v4l2_dev, sd); if (ret < 0){ v4l2_err(v4l2_dev, "Failed to register vic-subdev!\n"); ret = -ISP_ERROR; goto register_failed; } ret = isp_vic_init_clk(vsd); if(ret < 0){ v4l2_err(v4l2_dev, "Failed to init isp's clks!\n"); ret = -ISP_ERROR; } dump_vsd=vsd; /* creat the node of printing isp info */ proc = jz_proc_mkdir("vic"); if (!proc) { vsd->proc_vic = NULL; v4l2_err(v4l2_dev, "create dev_attr_isp_info failed!\n"); } else { vsd->proc_vic = proc; } proc_create_data("isp_vic_frd", S_IRUGO, proc, &isp_vic_frd_fops, (void *)vsd); return ISP_SUCCESS; register_failed: media_entity_cleanup(me); entity_init_failed: if(vsd->base) iounmap(vsd->base); ioremap_failed: if(res) release_mem_region(res->start,res->end - res->start + 1); mem_region_failed: kfree(vsd); exit: return ret; }
static int mt9m032_setup_pll(struct mt9m032 *sensor) { static const struct aptina_pll_limits limits = { .ext_clock_min = 8000000, .ext_clock_max = 16500000, .int_clock_min = 2000000, .int_clock_max = 24000000, .out_clock_min = 322000000, .out_clock_max = 693000000, .pix_clock_max = 99000000, .n_min = 1, .n_max = 64, .m_min = 16, .m_max = 255, .p1_min = 6, .p1_max = 7, }; struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); struct mt9m032_platform_data *pdata = sensor->pdata; struct aptina_pll pll; u16 reg_val; int ret; pll.ext_clock = pdata->ext_clock; pll.pix_clock = pdata->pix_clock; ret = aptina_pll_calculate(&client->dev, &limits, &pll); if (ret < 0) return ret; sensor->pix_clock = pdata->pix_clock; ret = mt9m032_write(client, MT9M032_PLL_CONFIG1, (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT) | ((pll.n - 1) & MT9M032_PLL_CONFIG1_PREDIV_MASK)); if (!ret) ret = mt9m032_write(client, MT9P031_PLL_CONTROL, MT9P031_PLL_CONTROL_PWRON | MT9P031_PLL_CONTROL_USEPLL); if (!ret) /* more reserved, Continuous, Master Mode */ ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8000 | MT9M032_READ_MODE1_STROBE_START_EXP | MT9M032_READ_MODE1_STROBE_END_SHUTTER); if (!ret) { reg_val = (pll.p1 == 6 ? MT9M032_FORMATTER1_PLL_P1_6 : 0) | MT9M032_FORMATTER1_PARALLEL | 0x001e; /* 14-bit */ ret = mt9m032_write(client, MT9M032_FORMATTER1, reg_val); } return ret; } /* ----------------------------------------------------------------------------- * Subdev pad operations */ static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_mbus_code_enum *code) { if (code->index != 0) return -EINVAL; code->code = V4L2_MBUS_FMT_Y8_1X8; return 0; } static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_frame_size_enum *fse) { if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8) return -EINVAL; fse->min_width = MT9M032_COLUMN_SIZE_DEF; fse->max_width = MT9M032_COLUMN_SIZE_DEF; fse->min_height = MT9M032_ROW_SIZE_DEF; fse->max_height = MT9M032_ROW_SIZE_DEF; return 0; } /** * __mt9m032_get_pad_crop() - get crop rect * @sensor: pointer to the sensor struct * @fh: file handle for getting the try crop rect from * @which: select try or active crop rect * * Returns a pointer the current active or fh relative try crop rect */ static struct v4l2_rect * __mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: return v4l2_subdev_get_try_crop(fh, 0); case V4L2_SUBDEV_FORMAT_ACTIVE: return &sensor->crop; default: return NULL; } } /** * __mt9m032_get_pad_format() - get format * @sensor: pointer to the sensor struct * @fh: file handle for getting the try format from * @which: select try or active format * * Returns a pointer the current active or fh relative try format */ static struct v4l2_mbus_framefmt * __mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh, enum v4l2_subdev_format_whence which) { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: return v4l2_subdev_get_try_format(fh, 0); case V4L2_SUBDEV_FORMAT_ACTIVE: return &sensor->format; default: return NULL; } } static int mt9m032_get_pad_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) { struct mt9m032 *sensor = to_mt9m032(subdev); mutex_lock(&sensor->lock); fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); mutex_unlock(&sensor->lock); return 0; } static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_format *fmt) { struct mt9m032 *sensor = to_mt9m032(subdev); int ret; mutex_lock(&sensor->lock); if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { ret = -EBUSY; goto done; } /* Scaling is not supported, the format is thus fixed. */ fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); ret = 0; done: mutex_unlock(&sensor->lock); return ret; } static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_crop *crop) { struct mt9m032 *sensor = to_mt9m032(subdev); mutex_lock(&sensor->lock); crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which); mutex_unlock(&sensor->lock); return 0; } static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, struct v4l2_subdev_crop *crop) { struct mt9m032 *sensor = to_mt9m032(subdev); struct v4l2_mbus_framefmt *format; struct v4l2_rect *__crop; struct v4l2_rect rect; int ret = 0; mutex_lock(&sensor->lock); if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) { ret = -EBUSY; goto done; } /* Clamp the crop rectangle boundaries and align them to a multiple of 2 * pixels to ensure a GRBG Bayer pattern. */ rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN, MT9M032_COLUMN_START_MAX); rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN, MT9M032_ROW_START_MAX); rect.width = clamp(ALIGN(crop->rect.width, 2), MT9M032_COLUMN_SIZE_MIN, MT9M032_COLUMN_SIZE_MAX); rect.height = clamp(ALIGN(crop->rect.height, 2), MT9M032_ROW_SIZE_MIN, MT9M032_ROW_SIZE_MAX); rect.width = min(rect.width, MT9M032_PIXEL_ARRAY_WIDTH - rect.left); rect.height = min(rect.height, MT9M032_PIXEL_ARRAY_HEIGHT - rect.top); __crop = __mt9m032_get_pad_crop(sensor, fh, crop->which); if (rect.width != __crop->width || rect.height != __crop->height) { /* Reset the output image size if the crop rectangle size has * been modified. */ format = __mt9m032_get_pad_format(sensor, fh, crop->which); format->width = rect.width; format->height = rect.height; } *__crop = rect; crop->rect = rect; if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) ret = mt9m032_update_geom_timing(sensor); done: mutex_unlock(&sensor->lock); return ret; } static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev, struct v4l2_subdev_frame_interval *fi) { struct mt9m032 *sensor = to_mt9m032(subdev); mutex_lock(&sensor->lock); memset(fi, 0, sizeof(*fi)); fi->interval = sensor->frame_interval; mutex_unlock(&sensor->lock); return 0; } static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev, struct v4l2_subdev_frame_interval *fi) { struct mt9m032 *sensor = to_mt9m032(subdev); int ret; mutex_lock(&sensor->lock); if (sensor->streaming) { ret = -EBUSY; goto done; } /* Avoid divisions by 0. */ if (fi->interval.denominator == 0) fi->interval.denominator = 1; ret = mt9m032_update_timing(sensor, &fi->interval); if (!ret) sensor->frame_interval = fi->interval; done: mutex_unlock(&sensor->lock); return ret; } static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming) { struct mt9m032 *sensor = to_mt9m032(subdev); int ret; mutex_lock(&sensor->lock); ret = update_formatter2(sensor, streaming); if (!ret) sensor->streaming = streaming; mutex_unlock(&sensor->lock); return ret; } /* ----------------------------------------------------------------------------- * V4L2 subdev core operations */ #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9m032_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { struct mt9m032 *sensor = to_mt9m032(sd); struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); int val; if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; if (reg->match.addr != client->addr) return -ENODEV; val = mt9m032_read(client, reg->reg); if (val < 0) return -EIO; reg->size = 2; reg->val = val; return 0; } static int mt9m032_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) { struct mt9m032 *sensor = to_mt9m032(sd); struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) return -EINVAL; if (reg->match.addr != client->addr) return -ENODEV; return mt9m032_write(client, reg->reg, reg->val); } #endif /* ----------------------------------------------------------------------------- * V4L2 subdev control operations */ static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT) | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT) | MT9M032_READ_MODE2_ROW_BLC | 0x0007; return mt9m032_write(client, MT9M032_READ_MODE2, reg_val); } static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); int digital_gain_val; /* in 1/8th (0..127) */ int analog_mul; /* 0 or 1 */ int analog_gain_val; /* in 1/16th. (0..63) */ u16 reg_val; digital_gain_val = 51; /* from setup example */ if (val < 63) { analog_mul = 0; analog_gain_val = val; } else { analog_mul = 1; analog_gain_val = val / 2; } /* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */ /* overall_gain = a_gain * (1 + digital_gain_val / 8) */ reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK) << MT9M032_GAIN_DIGITAL_SHIFT) | ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT) | (analog_gain_val & MT9M032_GAIN_ANALOG_MASK); return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val); } static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl) { if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) { /* round because of multiplier used for values >= 63 */ ctrl->val &= ~1; } return 0; } static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl) { struct mt9m032 *sensor = container_of(ctrl->handler, struct mt9m032, ctrls); struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev); int ret; switch (ctrl->id) { case V4L2_CID_GAIN: return mt9m032_set_gain(sensor, ctrl->val); case V4L2_CID_HFLIP: /* case V4L2_CID_VFLIP: -- In the same cluster */ return update_read_mode2(sensor, sensor->vflip->val, sensor->hflip->val); case V4L2_CID_EXPOSURE: ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH, (ctrl->val >> 16) & 0xffff); if (ret < 0) return ret; return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW, ctrl->val & 0xffff); } return 0; } static struct v4l2_ctrl_ops mt9m032_ctrl_ops = { .s_ctrl = mt9m032_set_ctrl, .try_ctrl = mt9m032_try_ctrl, }; /* -------------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops mt9m032_core_ops = { #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9m032_g_register, .s_register = mt9m032_s_register, #endif }; static const struct v4l2_subdev_video_ops mt9m032_video_ops = { .s_stream = mt9m032_s_stream, .g_frame_interval = mt9m032_get_frame_interval, .s_frame_interval = mt9m032_set_frame_interval, }; static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = { .enum_mbus_code = mt9m032_enum_mbus_code, .enum_frame_size = mt9m032_enum_frame_size, .get_fmt = mt9m032_get_pad_format, .set_fmt = mt9m032_set_pad_format, .set_crop = mt9m032_set_pad_crop, .get_crop = mt9m032_get_pad_crop, }; static const struct v4l2_subdev_ops mt9m032_ops = { .core = &mt9m032_core_ops, .video = &mt9m032_video_ops, .pad = &mt9m032_pad_ops, }; /* ----------------------------------------------------------------------------- * Driver initialization and probing */ static int mt9m032_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct mt9m032_platform_data *pdata = client->dev.platform_data; struct i2c_adapter *adapter = client->adapter; struct mt9m032 *sensor; int chip_version; 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"); return -EIO; } if (!client->dev.platform_data) return -ENODEV; sensor = kzalloc(sizeof(*sensor), GFP_KERNEL); if (sensor == NULL) return -ENOMEM; mutex_init(&sensor->lock); sensor->pdata = pdata; v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops); sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION); if (chip_version != MT9M032_CHIP_VERSION_VALUE) { dev_err(&client->dev, "MT9M032 not detected, wrong version " "0x%04x\n", chip_version); ret = -ENODEV; goto error_sensor; } dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n", client->addr); sensor->frame_interval.numerator = 1; sensor->frame_interval.denominator = 30; sensor->crop.left = MT9M032_COLUMN_START_DEF; sensor->crop.top = MT9M032_ROW_START_DEF; sensor->crop.width = MT9M032_COLUMN_SIZE_DEF; sensor->crop.height = MT9M032_ROW_SIZE_DEF; sensor->format.width = sensor->crop.width; sensor->format.height = sensor->crop.height; sensor->format.code = V4L2_MBUS_FMT_Y8_1X8; sensor->format.field = V4L2_FIELD_NONE; sensor->format.colorspace = V4L2_COLORSPACE_SRGB; v4l2_ctrl_handler_init(&sensor->ctrls, 5); v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_GAIN, 0, 127, 1, 64); sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN, MT9M032_SHUTTER_WIDTH_MAX, 1, MT9M032_SHUTTER_WIDTH_DEF); v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops, V4L2_CID_PIXEL_RATE, pdata->pix_clock, pdata->pix_clock, 1, pdata->pix_clock); if (sensor->ctrls.error) { ret = sensor->ctrls.error; dev_err(&client->dev, "control initialization error %d\n", ret); goto error_ctrl; } v4l2_ctrl_cluster(2, &sensor->hflip); sensor->subdev.ctrl_handler = &sensor->ctrls; sensor->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0); if (ret < 0) goto error_ctrl; ret = mt9m032_write(client, MT9M032_RESET, 1); /* reset on */ if (ret < 0) goto error_entity; ret = mt9m032_write(client, MT9M032_RESET, 0); /* reset off */ if (ret < 0) goto error_entity; ret = mt9m032_setup_pll(sensor); if (ret < 0) goto error_entity; usleep_range(10000, 11000); ret = v4l2_ctrl_handler_setup(&sensor->ctrls); if (ret < 0) goto error_entity; /* SIZE */ ret = mt9m032_update_geom_timing(sensor); if (ret < 0) goto error_entity; ret = mt9m032_write(client, 0x41, 0x0000); /* reserved !!! */ if (ret < 0) goto error_entity; ret = mt9m032_write(client, 0x42, 0x0003); /* reserved !!! */ if (ret < 0) goto error_entity; ret = mt9m032_write(client, 0x43, 0x0003); /* reserved !!! */ if (ret < 0) goto error_entity; ret = mt9m032_write(client, 0x7f, 0x0000); /* reserved !!! */ if (ret < 0) goto error_entity; if (sensor->pdata->invert_pixclock) { ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL, MT9M032_PIX_CLK_CTRL_INV_PIXCLK); if (ret < 0) goto error_entity; } ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */ if (ret < 0) goto error_entity; msleep(100); ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */ if (ret < 0) goto error_entity; msleep(100); ret = update_formatter2(sensor, false); if (ret < 0) goto error_entity; return ret; error_entity: media_entity_cleanup(&sensor->subdev.entity); error_ctrl: v4l2_ctrl_handler_free(&sensor->ctrls); error_sensor: mutex_destroy(&sensor->lock); kfree(sensor); return ret; } static int mt9m032_remove(struct i2c_client *client) { struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct mt9m032 *sensor = to_mt9m032(subdev); v4l2_device_unregister_subdev(subdev); v4l2_ctrl_handler_free(&sensor->ctrls); media_entity_cleanup(&subdev->entity); mutex_destroy(&sensor->lock); kfree(sensor); return 0; } static const struct i2c_device_id mt9m032_id_table[] = { { MT9M032_NAME, 0 }, { } }; MODULE_DEVICE_TABLE(i2c, mt9m032_id_table); static struct i2c_driver mt9m032_i2c_driver = { .driver = { .name = MT9M032_NAME, }, .probe = mt9m032_probe, .remove = mt9m032_remove, .id_table = mt9m032_id_table, };
struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *wpf; unsigned int flags; int ret; wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); if (wpf == NULL) return ERR_PTR(-ENOMEM); wpf->max_width = WPF_MAX_WIDTH; wpf->max_height = WPF_MAX_HEIGHT; wpf->entity.type = VSP1_ENTITY_WPF; wpf->entity.index = index; ret = vsp1_entity_init(vsp1, &wpf->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &wpf->entity.subdev; v4l2_subdev_init(subdev, &wpf_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s wpf.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, wpf); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the video device. */ video = &wpf->video; video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; video->vsp1 = vsp1; video->ops = &wpf_vdev_ops; ret = vsp1_video_init(video, &wpf->entity); if (ret < 0) goto error_video; /* Connect the video device to the WPF. All connections are immutable * except for the WPF0 source link if a LIF is present. */ flags = MEDIA_LNK_FL_ENABLED; if (!(vsp1->pdata->features & VSP1_HAS_LIF) || index != 0) flags |= MEDIA_LNK_FL_IMMUTABLE; ret = media_entity_create_link(&wpf->entity.subdev.entity, RWPF_PAD_SOURCE, &wpf->video.video.entity, 0, flags); if (ret < 0) goto error_link; wpf->entity.sink = &wpf->video.video.entity; return wpf; error_link: vsp1_video_cleanup(video); error_video: media_entity_cleanup(&wpf->entity.subdev.entity); return ERR_PTR(ret); }
static int lm3554_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err; struct lm3554 *flash; #ifndef CONFIG_GMIN_INTEL_MID if (client->dev.platform_data == NULL) { dev_err(&client->dev, "no platform data\n"); return -ENODEV; } #endif flash = kzalloc(sizeof(*flash), GFP_KERNEL); if (!flash) { dev_err(&client->dev, "out of memory\n"); return -ENOMEM; } flash->pdata = client->dev.platform_data; #ifdef CONFIG_GMIN_INTEL_MID if (!flash->pdata || ACPI_COMPANION(&client->dev)) flash->pdata = lm3554_platform_data_func(client); #endif v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops; flash->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; flash->mode = ATOMISP_FLASH_MODE_OFF; flash->timeout = LM3554_MAX_TIMEOUT / LM3554_TIMEOUT_STEPSIZE - 1; err = media_entity_init(&flash->sd.entity, 0, NULL, 0); if (err) { dev_err(&client->dev, "error initialize a media entity.\n"); goto fail1; } flash->sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV_FLASH; mutex_init(&flash->power_lock); setup_timer(&flash->flash_off_delay, lm3554_flash_off_delay, (unsigned long)client); err = lm3554_gpio_init(client); if (err) { dev_err(&client->dev, "gpio request/direction_output fail"); goto fail2; } #ifdef CONFIG_GMIN_INTEL_MID if (ACPI_HANDLE(&client->dev)) err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); #endif return 0; fail2: media_entity_cleanup(&flash->sd.entity); fail1: v4l2_device_unregister_subdev(&flash->sd); kfree(flash); return err; }
static int __init msm_sensor_init_module(void) { struct msm_sensor_init_t *s_init = NULL; struct device *cam_dev_back; struct device *cam_dev_front; int rc = 0; camera_class = class_create(THIS_MODULE, "camera"); if (IS_ERR(camera_class)) pr_err("failed to create device cam_dev_rear!\n"); /* Allocate memory for msm_sensor_init control structure */ s_init = kzalloc(sizeof(struct msm_sensor_init_t), GFP_KERNEL); if (!s_init) { class_destroy(camera_class); pr_err("failed: no memory s_init %p", NULL); return -ENOMEM; } pr_err("MSM_SENSOR_INIT_MODULE %p", NULL); /* Initialize mutex */ mutex_init(&s_init->imutex); /* Create /dev/v4l-subdevX for msm_sensor_init */ v4l2_subdev_init(&s_init->msm_sd.sd, &msm_sensor_init_subdev_ops); snprintf(s_init->msm_sd.sd.name, sizeof(s_init->msm_sd.sd.name), "%s", "msm_sensor_init"); v4l2_set_subdevdata(&s_init->msm_sd.sd, s_init); s_init->msm_sd.sd.internal_ops = &msm_sensor_init_internal_ops; s_init->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; rc = media_entity_init(&s_init->msm_sd.sd.entity, 0, NULL, 0); if (rc < 0) goto entity_fail; s_init->msm_sd.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV; s_init->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR_INIT; s_init->msm_sd.sd.entity.name = s_init->msm_sd.sd.name; s_init->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6; rc = msm_sd_register(&s_init->msm_sd); if (rc < 0) goto msm_sd_register_fail; cam_dev_back = device_create(camera_class, NULL, 1, NULL, "rear"); if (IS_ERR(cam_dev_back)) { printk("Failed to create cam_dev_back device!\n"); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camtype) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camtype.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_user) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_checkfw_user.attr.name); rc = -ENODEV; goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_checkfw_factory) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_checkfw_factory.attr.name); rc = -ENODEV; goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_isp_core) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_isp_core.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_load) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_load.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_camfw_full) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_full.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_back, &dev_attr_rear_vendorid) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_vendorid.attr.name); goto device_create_fail; } cam_dev_front = device_create(camera_class, NULL, 2, NULL, "front"); if (IS_ERR(cam_dev_front)) { printk("Failed to create cam_dev_front device!"); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camtype) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_front_camtype.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_front_camfw.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw_load) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_load.attr.name); goto device_create_fail; } if (device_create_file(cam_dev_front, &dev_attr_front_camfw_full) < 0) { printk("Failed to create device file!(%s)!\n", dev_attr_rear_camfw_full.attr.name); goto device_create_fail; } init_waitqueue_head(&s_init->state_wait); return 0; device_create_fail: msm_sd_unregister(&s_init->msm_sd); msm_sd_register_fail: media_entity_cleanup(&s_init->msm_sd.sd.entity); entity_fail: mutex_destroy(&s_init->imutex); kfree(s_init); class_destroy(camera_class); return rc; }
static int ov13858_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct ov13858 *ov13858; int ret; u32 val = 0; device_property_read_u32(&client->dev, "clock-frequency", &val); if (val != 19200000) return -EINVAL; ov13858 = devm_kzalloc(&client->dev, sizeof(*ov13858), GFP_KERNEL); if (!ov13858) return -ENOMEM; /* Initialize subdev */ v4l2_i2c_subdev_init(&ov13858->sd, client, &ov13858_subdev_ops); /* Check module identity */ ret = ov13858_identify_module(ov13858); if (ret) { dev_err(&client->dev, "failed to find sensor: %d\n", ret); return ret; } /* Set default mode to max resolution */ ov13858->cur_mode = &supported_modes[0]; ret = ov13858_init_controls(ov13858); if (ret) return ret; /* Initialize subdev */ ov13858->sd.internal_ops = &ov13858_internal_ops; ov13858->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ov13858->sd.entity.ops = &ov13858_subdev_entity_ops; ov13858->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; /* Initialize source pad */ ov13858->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_pads_init(&ov13858->sd.entity, 1, &ov13858->pad); if (ret) { dev_err(&client->dev, "%s failed:%d\n", __func__, ret); goto error_handler_free; } ret = v4l2_async_register_subdev_sensor_common(&ov13858->sd); if (ret < 0) goto error_media_entity; /* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device. */ pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); return 0; error_media_entity: media_entity_cleanup(&ov13858->sd.entity); error_handler_free: ov13858_free_controls(ov13858); dev_err(&client->dev, "%s failed:%d\n", __func__, ret); return ret; }
int gsc_register_capture_device(struct gsc_dev *gsc) { struct video_device *vfd; struct gsc_capture_device *gsc_cap; struct gsc_ctx *ctx; struct vb2_queue *q; struct exynos_platform_gscaler *pdata = gsc->pdata; struct exynos_isp_info *isp_info; int ret = -ENOMEM; int i; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->gsc_dev = gsc; ctx->in_path = GSC_CAMERA; ctx->out_path = GSC_DMA; ctx->state = GSC_CTX_CAP; vfd = video_device_alloc(); if (!vfd) { printk("Failed to allocate video device\n"); goto err_ctx_alloc; } snprintf(vfd->name, sizeof(vfd->name), "%s.capture", dev_name(&gsc->pdev->dev)); vfd->fops = &gsc_capture_fops; vfd->ioctl_ops = &gsc_capture_ioctl_ops; vfd->v4l2_dev = &gsc->mdev[MDEV_CAPTURE]->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &gsc->lock; video_set_drvdata(vfd, gsc); gsc_cap = &gsc->cap; gsc_cap->vfd = vfd; gsc_cap->refcnt = 0; gsc_cap->active_buf_cnt = 0; gsc_cap->reqbufs_cnt = 0; spin_lock_init(&ctx->slock); gsc_cap->ctx = ctx; q = &gsc->cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = gsc->cap.ctx; q->ops = &gsc_capture_qops; q->mem_ops = gsc->vb2->ops; vb2_queue_init(q); /* Get mipi-csis and fimc-lite subdev ptr using mdev */ for (i = 0; i < FLITE_MAX_ENTITIES; i++) gsc->cap.sd_flite[i] = gsc->mdev[MDEV_CAPTURE]->flite_sd[i]; for (i = 0; i < CSIS_MAX_ENTITIES; i++) gsc->cap.sd_csis[i] = gsc->mdev[MDEV_CAPTURE]->csis_sd[i]; if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) { isp_info = pdata->isp_info[i]; ret = gsc_cap_config_camclk(gsc, isp_info, i); if (ret) { gsc_err("failed setup cam clk"); goto err_ctx_alloc; } } } ret = gsc_cap_register_sensor_entities(gsc); if (ret) { gsc_err("failed register sensor entities"); goto err_clk; } ret = video_register_device(vfd, VFL_TYPE_GRABBER, EXYNOS_VIDEONODE_GSC_CAP(gsc->id)); if (ret) { gsc_err("failed to register video device"); goto err_clk; } gsc->cap.vd_pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&vfd->entity, 1, &gsc->cap.vd_pad, 0); if (ret) { gsc_err("failed to initialize entity"); goto err_ent; } ret = gsc_capture_create_subdev(gsc); if (ret) { gsc_err("failed create subdev"); goto err_sd_reg; } ret = gsc_capture_create_link(gsc); if (ret) { gsc_err("failed create link"); goto err_sd_reg; } vfd->ctrl_handler = &ctx->ctrl_handler; gsc_dbg("gsc capture driver registered as /dev/video%d", vfd->num); return 0; err_sd_reg: media_entity_cleanup(&vfd->entity); err_ent: video_device_release(vfd); err_clk: if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) clk_put(gsc_cap->sensor[i].camclk); } err_ctx_alloc: kfree(ctx); return ret; }
void omap4iss_ipipe_unregister_entities(struct iss_ipipe_device *ipipe) { media_entity_cleanup(&ipipe->subdev.entity); v4l2_device_unregister_subdev(&ipipe->subdev); }
void omap4iss_video_cleanup(struct iss_video *video) { media_entity_cleanup(&video->video.entity); mutex_destroy(&video->stream_lock); mutex_destroy(&video->mutex); }
static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); struct vb2_queue *q = &fimc->vb_queue; struct video_device *vfd; int ret; fimc->fmt = &fimc_lite_formats[0]; fimc->out_path = FIMC_IO_DMA; vfd = video_device_alloc(); if (!vfd) { v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n"); return -ENOMEM; } snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture", fimc->index); vfd->fops = &fimc_lite_fops; vfd->ioctl_ops = &fimc_lite_ioctl_ops; vfd->v4l2_dev = sd->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &fimc->lock; fimc->vfd = vfd; fimc->ref_count = 0; fimc->reqbufs_count = 0; INIT_LIST_HEAD(&fimc->pending_buf_q); INIT_LIST_HEAD(&fimc->active_buf_q); memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR; q->ops = &fimc_lite_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; vb2_queue_init(q); fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); if (ret) goto err; video_set_drvdata(vfd, fimc); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) goto err_vd; v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n", vfd->name, video_device_node_name(vfd)); return 0; err_vd: media_entity_cleanup(&vfd->entity); err: video_device_release(vfd); return ret; }
void atomisp_mipi_csi2_unregister_entities(struct atomisp_mipi_csi2_device *csi2) { media_entity_cleanup(&csi2->subdev.entity); v4l2_device_unregister_subdev(&csi2->subdev); }
static int xdmsc_probe(struct platform_device *pdev) { struct xdmsc_dev *xdmsc; struct v4l2_subdev *subdev; struct v4l2_mbus_framefmt *def_fmt; int rval; xdmsc = devm_kzalloc(&pdev->dev, sizeof(*xdmsc), GFP_KERNEL); if (!xdmsc) return -ENOMEM; xdmsc->xvip.dev = &pdev->dev; rval = xdmsc_parse_of(xdmsc); if (rval < 0) return rval; rval = xvip_init_resources(&xdmsc->xvip); /* Reset Demosaic IP */ gpiod_set_value_cansleep(xdmsc->rst_gpio, XDEMOSAIC_RESET_DEASSERT); /* Init V4L2 subdev */ subdev = &xdmsc->xvip.subdev; v4l2_subdev_init(subdev, &xdmsc_ops); subdev->dev = &pdev->dev; subdev->internal_ops = &xdmsc_internal_ops; strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name)); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; /* Default Formats Initialization */ def_fmt = &xdmsc->default_formats[XVIP_PAD_SINK]; def_fmt->field = V4L2_FIELD_NONE; def_fmt->colorspace = V4L2_COLORSPACE_SRGB; def_fmt->width = XDEMOSAIC_DEF_WIDTH; def_fmt->height = XDEMOSAIC_DEF_HEIGHT; /* * Sink Pad can be any Bayer format. * Default Sink Pad format is RGGB. */ def_fmt->code = MEDIA_BUS_FMT_SRGGB8_1X8; xdmsc->formats[XVIP_PAD_SINK] = *def_fmt; def_fmt = &xdmsc->default_formats[XVIP_PAD_SOURCE]; *def_fmt = xdmsc->default_formats[XVIP_PAD_SINK]; /* Source Pad has a fixed media bus format of RGB */ def_fmt->code = MEDIA_BUS_FMT_RBG888_1X24; xdmsc->formats[XVIP_PAD_SOURCE] = *def_fmt; xdmsc->pads[XVIP_PAD_SINK].flags = MEDIA_PAD_FL_SINK; xdmsc->pads[XVIP_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; /* Init Media Entity */ subdev->entity.ops = &xdmsc_media_ops; rval = media_entity_pads_init(&subdev->entity, 2, xdmsc->pads); if (rval < 0) goto media_error; platform_set_drvdata(pdev, xdmsc); rval = v4l2_async_register_subdev(subdev); if (rval < 0) { dev_err(&pdev->dev, "failed to register subdev"); goto v4l2_subdev_error; } dev_info(&pdev->dev, "Xilinx Video Demosaic Probe Successful"); return 0; v4l2_subdev_error: media_entity_cleanup(&subdev->entity); media_error: xvip_cleanup_resources(&xdmsc->xvip); return rval; }
static int32_t cam_dummy_platform_probe(struct platform_device *pdev) { int32_t rc = 0; const struct of_device_id *match; struct msm_video_device *pvdev; /* init_waitqueue_head(&cam_dummy_queue.state_wait);*/ pr_err("%s:%d\n", __func__, __LINE__); match = of_match_device(cam_dummy_dt_match, &pdev->dev); msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev), GFP_KERNEL); if (WARN_ON(!msm_v4l2_dev)) { rc = -ENOMEM; goto probe_end; } pvdev = kzalloc(sizeof(struct msm_video_device), GFP_KERNEL); if (WARN_ON(!pvdev)) { rc = -ENOMEM; goto pvdev_fail; } pvdev->vdev = video_device_alloc(); if (WARN_ON(!pvdev->vdev)) { rc = -ENOMEM; goto video_fail; } #if defined(CONFIG_MEDIA_CONTROLLER) msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!msm_v4l2_dev->mdev) { rc = -ENOMEM; goto mdev_fail; } strlcpy(msm_v4l2_dev->mdev->model, MSM_CAMERA_DUMMY_NAME, sizeof(msm_v4l2_dev->mdev->model)); msm_v4l2_dev->mdev->dev = &(pdev->dev); rc = media_device_register(msm_v4l2_dev->mdev); if (WARN_ON(rc < 0)) goto media_fail; if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity, 0, NULL, 0)) < 0)) goto entity_fail; pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID; #endif pvdev->vdev->v4l2_dev = msm_v4l2_dev; rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev); if (WARN_ON(rc < 0)) goto register_fail; strlcpy(pvdev->vdev->name, "msm-camdummy", sizeof(pvdev->vdev->name)); pvdev->vdev->release = video_device_release; pvdev->vdev->fops = &msm_fops_config; pvdev->vdev->minor = -1; pvdev->vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(pvdev->vdev, VFL_TYPE_GRABBER, -1); if (WARN_ON(rc < 0)) goto v4l2_fail; #if defined(CONFIG_MEDIA_CONTROLLER) /* FIXME: How to get rid of this messy? */ pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev); #endif atomic_set(&pvdev->opened, 0); video_set_drvdata(pvdev->vdev, pvdev); goto probe_end; v4l2_fail: v4l2_device_unregister(pvdev->vdev->v4l2_dev); register_fail: #if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&pvdev->vdev->entity); entity_fail: media_device_unregister(msm_v4l2_dev->mdev); media_fail: kzfree(msm_v4l2_dev->mdev); mdev_fail: #endif video_device_release(pvdev->vdev); video_fail: kzfree(pvdev); pvdev_fail: kzfree(msm_v4l2_dev); probe_end: return rc; }
void ispstat_unregister_entities(struct ispstat *stat) { media_entity_cleanup(&stat->subdev.entity); v4l2_device_unregister_subdev(&stat->subdev); }
/* * omap4iss_ipipeif_cleanup - IPIPEIF module cleanup. * @iss: Device pointer specific to the OMAP4 ISS. */ void omap4iss_ipipeif_cleanup(struct iss_device *iss) { struct iss_ipipeif_device *ipipeif = &iss->ipipeif; media_entity_cleanup(&ipipeif->subdev.entity); }
void atomisp_tpg_unregister_entities(struct atomisp_tpg_device *tpg) { media_entity_cleanup(&tpg->sd.entity); v4l2_device_unregister_subdev(&tpg->sd); }
struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) { struct v4l2_subdev *subdev; struct vsp1_video *video; struct vsp1_rwpf *rpf; int ret; rpf = devm_kzalloc(vsp1->dev, sizeof(*rpf), GFP_KERNEL); if (rpf == NULL) return ERR_PTR(-ENOMEM); rpf->max_width = RPF_MAX_WIDTH; rpf->max_height = RPF_MAX_HEIGHT; rpf->entity.type = VSP1_ENTITY_RPF; rpf->entity.index = index; ret = vsp1_entity_init(vsp1, &rpf->entity, 2); if (ret < 0) return ERR_PTR(ret); /* Initialize the V4L2 subdev. */ subdev = &rpf->entity.subdev; v4l2_subdev_init(subdev, &rpf_ops); subdev->entity.ops = &vsp1_media_ops; subdev->internal_ops = &vsp1_subdev_internal_ops; snprintf(subdev->name, sizeof(subdev->name), "%s rpf.%u", dev_name(vsp1->dev), index); v4l2_set_subdevdata(subdev, rpf); subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; vsp1_entity_init_formats(subdev, NULL); /* Initialize the video device. */ video = &rpf->video; video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; video->vsp1 = vsp1; video->ops = &rpf_vdev_ops; ret = vsp1_video_init(video, &rpf->entity); if (ret < 0) goto error_video; /* Connect the video device to the RPF. */ ret = media_entity_create_link(&rpf->video.video.entity, 0, &rpf->entity.subdev.entity, RWPF_PAD_SINK, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) goto error_link; return rpf; error_link: vsp1_video_cleanup(video); error_video: media_entity_cleanup(&rpf->entity.subdev.entity); return ERR_PTR(ret); }
static int adv7180_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct adv7180_state *state; struct v4l2_subdev *sd; int ret; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; v4l_info(client, "chip found @ 0x%02x (%s)\n", client->addr, client->adapter->name); state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL); if (state == NULL) return -ENOMEM; state->client = client; state->field = V4L2_FIELD_INTERLACED; state->chip_info = (struct adv7180_chip_info *)id->driver_data; if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) { state->csi_client = i2c_new_dummy(client->adapter, ADV7180_DEFAULT_CSI_I2C_ADDR); if (!state->csi_client) return -ENOMEM; } if (state->chip_info->flags & ADV7180_FLAG_I2P) { state->vpp_client = i2c_new_dummy(client->adapter, ADV7180_DEFAULT_VPP_I2C_ADDR); if (!state->vpp_client) { ret = -ENOMEM; goto err_unregister_csi_client; } } state->irq = client->irq; mutex_init(&state->mutex); state->autodetect = true; if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED) state->powered = true; else state->powered = false; state->input = 0; sd = &state->sd; v4l2_i2c_subdev_init(sd, client, &adv7180_ops); sd->flags = V4L2_SUBDEV_FL_HAS_DEVNODE; ret = adv7180_init_controls(state); if (ret) goto err_unregister_vpp_client; state->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.flags |= MEDIA_ENT_F_ATV_DECODER; ret = media_entity_pads_init(&sd->entity, 1, &state->pad); if (ret) goto err_free_ctrl; ret = init_device(state); if (ret) goto err_media_entity_cleanup; if (state->irq) { ret = request_threaded_irq(client->irq, NULL, adv7180_irq, IRQF_ONESHOT | IRQF_TRIGGER_FALLING, KBUILD_MODNAME, state); if (ret) goto err_media_entity_cleanup; } ret = v4l2_async_register_subdev(sd); if (ret) goto err_free_irq; return 0; err_free_irq: if (state->irq > 0) free_irq(client->irq, state); err_media_entity_cleanup: media_entity_cleanup(&sd->entity); err_free_ctrl: adv7180_exit_controls(state); err_unregister_vpp_client: if (state->chip_info->flags & ADV7180_FLAG_I2P) i2c_unregister_device(state->vpp_client); err_unregister_csi_client: if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2) i2c_unregister_device(state->csi_client); mutex_destroy(&state->mutex); return ret; }
static int m5mols_probe(struct i2c_client *client, const struct i2c_device_id *id) { const struct m5mols_platform_data *pdata = client->dev.platform_data; struct m5mols_info *info; struct v4l2_subdev *sd; int ret; if (pdata == NULL) { dev_err(&client->dev, "No platform data\n"); return -EINVAL; } if (!gpio_is_valid(pdata->gpio_reset)) { dev_err(&client->dev, "No valid RESET GPIO specified\n"); return -EINVAL; } if (!client->irq) { dev_err(&client->dev, "Interrupt not assigned\n"); return -EINVAL; } info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL); if (!info) return -ENOMEM; info->pdata = pdata; info->set_power = pdata->set_power; ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST"); if (ret) { dev_err(&client->dev, "Failed to request gpio: %d\n", ret); goto out_free; } gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity); ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies); if (ret) { dev_err(&client->dev, "Failed to get regulators: %d\n", ret); goto out_gpio; } sd = &info->sd; v4l2_i2c_subdev_init(sd, client, &m5mols_ops); strlcpy(sd->name, MODULE_NAME, sizeof(sd->name)); sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; sd->internal_ops = &m5mols_subdev_internal_ops; info->pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&sd->entity, 1, &info->pad, 0); if (ret < 0) goto out_reg; sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR; init_waitqueue_head(&info->irq_waitq); mutex_init(&info->lock); ret = request_irq(client->irq, m5mols_irq_handler, IRQF_TRIGGER_RISING, MODULE_NAME, sd); if (ret) { dev_err(&client->dev, "Interrupt request failed: %d\n", ret); goto out_me; } info->res_type = M5MOLS_RESTYPE_MONITOR; info->ffmt[0] = m5mols_default_ffmt[0]; info->ffmt[1] = m5mols_default_ffmt[1]; ret = m5mols_sensor_power(info, true); if (ret) goto out_irq; ret = m5mols_fw_start(sd); if (!ret) ret = m5mols_init_controls(sd); ret = m5mols_sensor_power(info, false); if (!ret) return 0; out_irq: free_irq(client->irq, sd); out_me: media_entity_cleanup(&sd->entity); out_reg: regulator_bulk_free(ARRAY_SIZE(supplies), supplies); out_gpio: gpio_free(pdata->gpio_reset); out_free: kfree(info); return ret; }