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 int dvb_create_media_entity(struct dvb_device *dvbdev, int type, int demux_sink_pads) { int i, ret, npads; switch (type) { case DVB_DEVICE_FRONTEND: npads = 2; break; case DVB_DEVICE_DVR: ret = dvb_create_tsout_entity(dvbdev, DVR_TSOUT, demux_sink_pads); return ret; case DVB_DEVICE_DEMUX: npads = 1 + demux_sink_pads; ret = dvb_create_tsout_entity(dvbdev, DEMUX_TSOUT, demux_sink_pads); if (ret < 0) return ret; break; case DVB_DEVICE_CA: npads = 2; break; case DVB_DEVICE_NET: /* * We should be creating entities for the MPE/ULE * decapsulation hardware (or software implementation). * * However, the number of for the MPE/ULE decaps may not be * fixed. As we don't have yet dynamic support for PADs at * the Media Controller, let's not create the decap * entities yet. */ return 0; default: return 0; } dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); if (!dvbdev->entity) return -ENOMEM; dvbdev->entity->name = dvbdev->name; if (npads) { dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), GFP_KERNEL); if (!dvbdev->pads) return -ENOMEM; } switch (type) { case DVB_DEVICE_FRONTEND: dvbdev->entity->function = MEDIA_ENT_F_DTV_DEMOD; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_DEMUX: dvbdev->entity->function = MEDIA_ENT_F_TS_DEMUX; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; for (i = 1; i < npads; i++) dvbdev->pads[i].flags = MEDIA_PAD_FL_SOURCE; break; case DVB_DEVICE_CA: dvbdev->entity->function = MEDIA_ENT_F_DTV_CA; dvbdev->pads[0].flags = MEDIA_PAD_FL_SINK; dvbdev->pads[1].flags = MEDIA_PAD_FL_SOURCE; break; default: /* Should never happen, as the first switch prevents it */ kfree(dvbdev->entity); kfree(dvbdev->pads); dvbdev->entity = NULL; dvbdev->pads = NULL; return 0; } if (npads) { ret = media_entity_pads_init(dvbdev->entity, npads, dvbdev->pads); if (ret) return ret; } ret = media_device_register_entity(dvbdev->adapter->mdev, dvbdev->entity); if (ret) return ret; printk(KERN_DEBUG "%s: media entity '%s' registered.\n", __func__, dvbdev->entity->name); return 0; }
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; }
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->curr_norm = V4L2_STD_NTSC; 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 | V4L2_SUBDEV_FL_HAS_EVENTS; 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 lm3554_probe(struct i2c_client *client) { int err = 0; struct lm3554 *flash; unsigned int i; int ret; flash = kzalloc(sizeof(*flash), GFP_KERNEL); if (!flash) return -ENOMEM; flash->pdata = lm3554_platform_data_func(client); 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; ret = v4l2_ctrl_handler_init(&flash->ctrl_handler, ARRAY_SIZE(lm3554_controls)); if (ret) { dev_err(&client->dev, "error initialize a ctrl_handler.\n"); goto fail2; } for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++) v4l2_ctrl_new_custom(&flash->ctrl_handler, &lm3554_controls[i], NULL); if (flash->ctrl_handler.error) { dev_err(&client->dev, "ctrl_handler error.\n"); goto fail2; } flash->sd.ctrl_handler = &flash->ctrl_handler; err = media_entity_pads_init(&flash->sd.entity, 0, NULL); if (err) { dev_err(&client->dev, "error initialize a media entity.\n"); goto fail1; } flash->sd.entity.function = MEDIA_ENT_F_FLASH; mutex_init(&flash->power_lock); timer_setup(&flash->flash_off_delay, lm3554_flash_off_delay, 0); err = lm3554_gpio_init(client); if (err) { dev_err(&client->dev, "gpio request/direction_output fail"); goto fail2; } return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); fail2: media_entity_cleanup(&flash->sd.entity); v4l2_ctrl_handler_free(&flash->ctrl_handler); fail1: v4l2_device_unregister_subdev(&flash->sd); kfree(flash); return err; }
int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev, const char *name, int is_pix) { struct media_pad *pad = &video->pad; struct video_device *vdev; struct vb2_queue *q; int ret; vdev = &video->vdev; mutex_init(&video->q_lock); q = &video->vb2_q; q->drv_priv = video; q->mem_ops = &vb2_dma_sg_memops; q->ops = &msm_video_vb2_q_ops; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_DMABUF | VB2_MMAP | VB2_READ; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->buf_struct_size = sizeof(struct camss_buffer); q->dev = video->camss->dev; q->lock = &video->q_lock; ret = vb2_queue_init(q); if (ret < 0) { dev_err(v4l2_dev->dev, "Failed to init vb2 queue: %d\n", ret); goto error_vb2_init; } pad->flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&vdev->entity, 1, pad); if (ret < 0) { dev_err(v4l2_dev->dev, "Failed to init video entity: %d\n", ret); goto error_media_init; } mutex_init(&video->lock); video->formats = formats_rdi; video->nformats = ARRAY_SIZE(formats_rdi); if (is_pix) { video->formats = formats_pix; video->nformats = ARRAY_SIZE(formats_pix); } ret = msm_video_init_format(video); if (ret < 0) { dev_err(v4l2_dev->dev, "Failed to init format: %d\n", ret); goto error_video_register; } vdev->fops = &msm_vid_fops; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; vdev->ioctl_ops = &msm_vid_ioctl_ops; vdev->release = msm_video_release; vdev->v4l2_dev = v4l2_dev; vdev->vfl_dir = VFL_DIR_RX; vdev->queue = &video->vb2_q; vdev->lock = &video->lock; strlcpy(vdev->name, name, sizeof(vdev->name)); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { dev_err(v4l2_dev->dev, "Failed to register video device: %d\n", ret); goto error_video_register; } video_set_drvdata(vdev, video); atomic_inc(&video->camss->ref_count); return 0; error_video_register: media_entity_cleanup(&vdev->entity); mutex_destroy(&video->lock); error_media_init: vb2_queue_release(&video->vb2_q); error_vb2_init: mutex_destroy(&video->q_lock); return ret; }