/* * si470x_fops_open - file open */ static int si470x_fops_open(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; radio->users++; retval = usb_autopm_get_interface(radio->intf); if (retval < 0) { radio->users--; return -EIO; } if (radio->users == 1) { retval = si470x_start(radio); if (retval < 0) usb_autopm_put_interface(radio->intf); return retval; } return 0; }
ssize_t vb2_fop_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct video_device *vdev = video_devdata(file); struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; int err = -EBUSY; if (!(vdev->queue->io_modes & VB2_WRITE)) return -EINVAL; if (lock && mutex_lock_interruptible(lock)) return -ERESTARTSYS; if (vb2_queue_is_busy(vdev, file)) goto exit; err = vb2_write(vdev->queue, buf, count, ppos, file->f_flags & O_NONBLOCK); if (vdev->queue->fileio) vdev->queue->owner = file->private_data; exit: if (lock) mutex_unlock(lock); return err; }
static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct video_device *dev = video_devdata(file); struct zol_device *zol = dev->priv; if (v->index > 0) return -EINVAL; strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; v->rangelow = (88*16000); v->rangehigh = (108*16000); v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; v->capability = V4L2_TUNER_CAP_LOW; if (zol_is_stereo(zol)) v->audmode = V4L2_TUNER_MODE_STEREO; else v->audmode = V4L2_TUNER_MODE_MONO; v->signal = 0xFFFF*zol_getsigstr(zol); return 0; }
static int s3c2410camif_vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *c) { struct video_device *dev = video_devdata(file); s3c2440camif_dev *pcam = video_get_drvdata(dev); switch (c->id) { case V4L2_CID_AUTOGAIN: return pcam->sensor_op->set_auto_gain(c->value); case V4L2_CID_GAIN: return pcam->sensor_op->set_gain(c->value); case V4L2_CID_EXPOSURE_AUTO: return pcam->sensor_op->set_auto_exposure(c->value); case V4L2_CID_EXPOSURE: return pcam->sensor_op->set_exposure(c->value); case V4L2_CID_AUTO_WHITE_BALANCE: return pcam->sensor_op->set_auto_wb(c->value); default: return -EINVAL; } return 0; }
static int video_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct camss_video *video = video_drvdata(file); struct v4l2_fh *vfh; int ret; mutex_lock(&video->lock); vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); if (vfh == NULL) { ret = -ENOMEM; goto error_alloc; } v4l2_fh_init(vfh, vdev); v4l2_fh_add(vfh); file->private_data = vfh; ret = v4l2_pipeline_pm_use(&vdev->entity, 1); if (ret < 0) { dev_err(video->camss->dev, "Failed to power up pipeline: %d\n", ret); goto error_pm_use; } mutex_unlock(&video->lock); return 0; error_pm_use: v4l2_fh_release(file); error_alloc: mutex_unlock(&video->lock); return ret; }
int vidioc_g_edid(struct file *file, void *_fh, struct v4l2_edid *edid) { struct vivid_dev *dev = video_drvdata(file); struct video_device *vdev = video_devdata(file); struct cec_adapter *adap; memset(edid->reserved, 0, sizeof(edid->reserved)); if (vdev->vfl_dir == VFL_DIR_RX) { if (edid->pad >= dev->num_inputs) return -EINVAL; if (dev->input_type[edid->pad] != HDMI) return -EINVAL; adap = dev->cec_rx_adap; } else { unsigned int bus_idx; if (edid->pad >= dev->num_outputs) return -EINVAL; if (dev->output_type[edid->pad] != HDMI) return -EINVAL; bus_idx = dev->cec_output2bus_map[edid->pad]; adap = dev->cec_tx_adap[bus_idx]; } if (edid->start_block == 0 && edid->blocks == 0) { edid->blocks = dev->edid_blocks; return 0; } if (dev->edid_blocks == 0) return -ENODATA; if (edid->start_block >= dev->edid_blocks) return -EINVAL; if (edid->blocks > dev->edid_blocks - edid->start_block) edid->blocks = dev->edid_blocks - edid->start_block; if (adap) v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr); memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128); return 0; }
/* release the camera */ static int zr364xx_release(struct inode *inode, struct file *file) { struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam; struct usb_device *udev; int i, err; DBG("zr364xx_release"); if (vdev == NULL) return -ENODEV; cam = video_get_drvdata(vdev); udev = cam->udev; mutex_lock(&cam->lock); for (i = 0; i < 2; i++) { err = send_control_msg(udev, 1, init[cam->method][i].value, 0, init[i][cam->method].bytes, init[cam->method][i].size); if (err < 0) { info("error during release sequence"); mutex_unlock(&cam->lock); return err; } } file->private_data = NULL; video_exclusive_release(inode, file); /* Added some delay here, since opening/closing the camera quickly, * like Ekiga does during its startup, can crash the webcam */ mdelay(100); mutex_unlock(&cam->lock); return 0; }
/* * si470x_vidioc_s_tuner - set tuner attributes */ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; if (radio->disconnected) return -EIO; if (tuner->index > 0) return -EINVAL; if (tuner->audmode == V4L2_TUNER_MODE_MONO) radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ else radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ retval = si470x_set_register(radio, POWERCFG); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": set tuner failed with %d\n", retval); return retval; }
/* * si470x_fops_release - file release */ static int si470x_fops_release(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; if (!radio) return -ENODEV; radio->users--; if (radio->users == 0) { /* stop rds reception */ cancel_delayed_work_sync(&radio->work); /* cancel read processes */ wake_up_interruptible(&radio->read_queue); retval = si470x_stop(radio); usb_autopm_put_interface(radio->intf); return retval; } 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 int si4703_close(struct inode *inode, struct file *file) { struct si4703_device *chip = video_get_drvdata(video_devdata(file)); unset_radio_dvfm_constraint(); if (!chip) { disable_oscc_tout_s0(); return -ENODEV; } if (si4703_power_down(chip)) printk(KERN_ERR "Radio did not shutdown properly"); chip->users = 0; if (chip->removed) kfree(chip); /* disable clock */ disable_oscc_tout_s0(); return 0; }
/****************************************************************************** * * cpia2_close * *****************************************************************************/ static int cpia2_close(struct file *file) { struct video_device *dev = video_devdata(file); struct camera_data *cam = video_get_drvdata(dev); mutex_lock(&cam->v4l2_lock); if (video_is_registered(&cam->vdev) && v4l2_fh_is_singular_file(file)) { cpia2_usb_stream_stop(cam); /* save camera state for later open */ cpia2_save_camera_state(cam); cpia2_set_low_power(cam); cpia2_free_buffers(cam); } if (cam->stream_fh == file->private_data) { cam->stream_fh = NULL; cam->mmapped = 0; } mutex_unlock(&cam->v4l2_lock); return v4l2_fh_release(file); }
static int uvc_v4l2_release(struct file *file) { struct video_device *vdev = video_devdata(file); struct uvc_device *uvc = video_get_drvdata(vdev); struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data); struct uvc_video *video = handle->device; uvc_function_disconnect(uvc); uvc_video_enable(video, 0); mutex_lock(&video->queue.mutex); if (uvc_free_buffers(&video->queue) < 0) printk(KERN_ERR "uvc_v4l2_release: Unable to free " "buffers.\n"); mutex_unlock(&video->queue.mutex); file->private_data = NULL; v4l2_fh_del(&handle->vfh); v4l2_fh_exit(&handle->vfh); kfree(handle); return 0; }
static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; strcpy((char *)cap->driver, "saa7146 v4l2"); strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->device_caps |= dev->ext_vv_data->capabilities; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; if (vdev->vfl_type == VFL_TYPE_GRABBER) cap->device_caps &= ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT); else cap->device_caps &= ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO); return 0; }
static int videoin_open(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); videoin_priv_t *priv = (videoin_priv_t *)dev->priv; volatile int loop; int ret = 0, buf_num; DBG_PRINTF("%s\n",__FUNCTION__); for(buf_num=0; buf_num<=2; buf_num=buf_num+1) {//Clear packet buffer, Black in YUV422 is Y=0x0, U=V=0x80 unsigned int* pu32Addr = videoIn_buf[buf_num].u32VirtAddr; unsigned int i; for(i=0; i<LCDWIDTH*LCDHEIGHT*LCDBPP/8;i=i+4) { *pu32Addr++=0x80008000; //2 Pixel } } w55fa93_VIN_PAC_BUFFER = videoIn_buf[0].u32PhysAddr; bIsVideoInEnable = 1; /* Important !!! to enable VPOST show video buffer */ //Critical section spin_lock(&spin_vin_opc); if(i32OpenCount==0) { i32OpenCount = 1; spin_unlock(&spin_vin_opc); DrvVideoIn_EnableInt(eDRVVIDEOIN_VINT); return 0; } else { spin_unlock(&spin_vin_opc); return -1; } }
static int vivid_fop_release(struct file *file) { struct vivid_dev *dev = video_drvdata(file); struct video_device *vdev = video_devdata(file); mutex_lock(&dev->mutex); if (!no_error_inj && v4l2_fh_is_singular_file(file) && !video_is_registered(vdev) && vivid_is_last_user(dev)) { /* * I am the last user of this driver, and a disconnect * was forced (since this video_device is unregistered), * so re-register all video_device's again. */ v4l2_info(&dev->v4l2_dev, "reconnect\n"); set_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags); set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags); } mutex_unlock(&dev->mutex); if (file->private_data == dev->overlay_cap_owner) dev->overlay_cap_owner = NULL; if (file->private_data == dev->radio_rx_rds_owner) { dev->radio_rx_rds_last_block = 0; dev->radio_rx_rds_owner = NULL; } if (file->private_data == dev->radio_tx_rds_owner) { dev->radio_tx_rds_last_block = 0; dev->radio_tx_rds_owner = NULL; } if (vdev->queue) return vb2_fop_release(file); return v4l2_fh_release(file); }
static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct si4703_device *chip = video_get_drvdata(video_devdata(file)); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { if (si4703_mute(chip)) printk(KERN_ERR "si4703: no reponse"); } else { if (si4703_unmute(chip)) printk(KERN_ERR "si4703: no reponse"); } break; case V4L2_CID_AUDIO_VOLUME: si4703_setvol(chip, ctrl->value); break; default: return -EINVAL; } return 0; }
int vb2_ioctl_create_bufs(struct file *file, void *priv, struct v4l2_create_buffers *p) { struct video_device *vdev = video_devdata(file); int res = vb2_verify_memory_type(vdev->queue, p->memory, p->format.type); p->index = vdev->queue->num_buffers; /* * If count == 0, then just check if memory and type are valid. * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. */ if (p->count == 0) return res != -EBUSY ? res : 0; if (res) return res; if (vb2_queue_is_busy(vdev, file)) return -EBUSY; res = vb2_create_bufs(vdev->queue, p); if (res == 0) vdev->queue->owner = file->private_data; return res; }
static int uvc_v4l2_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct uvc_device *uvc = video_get_drvdata(vdev); struct uvc_file_handle *handle; int ret; handle = kzalloc(sizeof(*handle), GFP_KERNEL); if (handle == NULL) return -ENOMEM; ret = v4l2_fh_init(&handle->vfh, vdev); if (ret < 0) goto error; ret = v4l2_event_init(&handle->vfh); if (ret < 0) goto error; ret = v4l2_event_alloc(&handle->vfh, 8); if (ret < 0) goto error; v4l2_fh_add(&handle->vfh); handle->device = &uvc->video; file->private_data = &handle->vfh; uvc_function_connect(uvc); return 0; error: v4l2_fh_exit(&handle->vfh); return ret; }
static int videoin_close(struct inode *inode, struct file *file) { struct video_device *dev = video_devdata(file); videoin_priv_t *priv = (videoin_priv_t *)dev->priv; DBG_PRINTF("%s\n",__FUNCTION__); if((inp32(REG_VPECTL)&(PKEN|VPEEN))==(PKEN|VPEEN)) {// DrvVideoIn_SetOperationMode(TRUE); //One shutter mode while(DrvVideoIn_GetOperationMode()==TRUE); } DrvVideoIn_SetPipeEnable(TRUE, eDRVVIDEOIN_BOTH_PIPE_DISABLE); DrvVideoIn_DisableInt(eDRVVIDEOIN_VINT); DrvVideoIn_SetPipeEnable(FALSE, eDRVVIDEOIN_BOTH_PIPE_DISABLE); DrvVideoIn_DisableInt(eDRVVIDEOIN_VINT); spin_lock(&spin_vin_opc); if(i32OpenCount==1) i32OpenCount = 0; spin_unlock(&spin_vin_opc); #ifndef CONFIG_FSC bIsVideoInEnable = 0; outp32(REG_LCM_FSADDR, g_u32FbPhyAddr); #endif }
static int atomisp_g_fmt_file(struct file *file, void *fh, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); struct atomisp_device *isp = video_get_drvdata(vdev); struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); int ret; if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { v4l2_err(&atomisp_dev, "unsupported v4l2 buf type\n"); return -EINVAL; } memset(f, 0, sizeof(struct v4l2_format)); f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; switch (isp->sw_contex.output_mode) { case OUTPUT_MODE_FILE: f->fmt.pix.width = pipe->out_fmt->width; f->fmt.pix.height = pipe->out_fmt->height; f->fmt.pix.pixelformat = pipe->out_fmt->pixelformat; f->fmt.pix.bytesperline = pipe->out_fmt->bytesperline; f->fmt.pix.sizeimage = pipe->out_fmt->imagesize; break; case OUTPUT_MODE_TEXT: f->fmt.pix.sizeimage = pipe->out_fmt->framesize; break; default: v4l2_err(&atomisp_dev, "Unspported output mode\n"); ret = -EINVAL; break; } return ret; }
static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam; if (vdev == NULL) return -ENODEV; cam = video_get_drvdata(vdev); if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.width = cam->width; f->fmt.pix.height = cam->height; f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.colorspace = 0; f->fmt.pix.priv = 0; return 0; }
static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); struct zr364xx_camera *cam; if (vdev == NULL) return -ENODEV; cam = video_get_drvdata(vdev); if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) return -EINVAL; if (f->fmt.pix.field != V4L2_FIELD_ANY && f->fmt.pix.field != V4L2_FIELD_NONE) return -EINVAL; f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.width = cam->width; f->fmt.pix.height = cam->height; f->fmt.pix.bytesperline = f->fmt.pix.width * 2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.colorspace = 0; f->fmt.pix.priv = 0; return 0; }
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; }
/** * v4l2_m2m_poll() - poll replacement, for destination buffers only * * Call from the driver's poll() function. Will poll both queues. If a buffer * is available to dequeue (with dqbuf) from the source queue, this will * indicate that a non-blocking write can be performed, while read will be * returned in case of the destination queue. */ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct poll_table_struct *wait) { struct video_device *vfd = video_devdata(file); unsigned long req_events = poll_requested_events(wait); struct vb2_queue *src_q, *dst_q; struct vb2_buffer *src_vb = NULL, *dst_vb = NULL; unsigned int rc = 0; unsigned long flags; if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { struct v4l2_fh *fh = file->private_data; if (v4l2_event_pending(fh)) rc = POLLPRI; else if (req_events & POLLPRI) poll_wait(file, &fh->wait, wait); if (!(req_events & (POLLOUT | POLLWRNORM | POLLIN | POLLRDNORM))) return rc; } src_q = v4l2_m2m_get_src_vq(m2m_ctx); dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); /* * There has to be at least one buffer queued on each queued_list, which * means either in driver already or waiting for driver to claim it * and start processing. */ if ((!src_q->streaming || list_empty(&src_q->queued_list)) && (!dst_q->streaming || list_empty(&dst_q->queued_list))) { rc |= POLLERR; goto end; } if (m2m_ctx->m2m_dev->m2m_ops->unlock) m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv); poll_wait(file, &src_q->done_wq, wait); poll_wait(file, &dst_q->done_wq, wait); if (m2m_ctx->m2m_dev->m2m_ops->lock) m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv); spin_lock_irqsave(&src_q->done_lock, flags); if (!list_empty(&src_q->done_list)) src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer, done_entry); if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE || src_vb->state == VB2_BUF_STATE_ERROR)) rc |= POLLOUT | POLLWRNORM; spin_unlock_irqrestore(&src_q->done_lock, flags); spin_lock_irqsave(&dst_q->done_lock, flags); if (!list_empty(&dst_q->done_list)) dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer, done_entry); if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE || dst_vb->state == VB2_BUF_STATE_ERROR)) rc |= POLLIN | POLLRDNORM; spin_unlock_irqrestore(&dst_q->done_lock, flags); end: return rc; }
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; }
static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *vdev = video_devdata(file); struct w9966_dev *cam = vdev->priv; switch(cmd) { case VIDIOCGCAP: { static struct video_capability vcap = { .name = W9966_DRIVERNAME, .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, .channels = 1, .maxwidth = W9966_WND_MAX_W, .maxheight = W9966_WND_MAX_H, .minwidth = 2, .minheight = 1, }; struct video_capability *cap = arg; *cap = vcap; return 0; } case VIDIOCGCHAN: { struct video_channel *vch = arg; if(vch->channel != 0) // We only support one channel (#0) return -EINVAL; memset(vch,0,sizeof(*vch)); strcpy(vch->name, "CCD-input"); vch->type = VIDEO_TYPE_CAMERA; return 0; } case VIDIOCSCHAN: { struct video_channel *vch = arg; if(vch->channel != 0) return -EINVAL; return 0; } case VIDIOCGTUNER: { struct video_tuner *vtune = arg; if(vtune->tuner != 0) return -EINVAL; strcpy(vtune->name, "no tuner"); vtune->rangelow = 0; vtune->rangehigh = 0; vtune->flags = VIDEO_TUNER_NORM; vtune->mode = VIDEO_MODE_AUTO; vtune->signal = 0xffff; return 0; } case VIDIOCSTUNER: { struct video_tuner *vtune = arg; if (vtune->tuner != 0) return -EINVAL; if (vtune->mode != VIDEO_MODE_AUTO) return -EINVAL; return 0; } case VIDIOCGPICT: { struct video_picture vpic = { cam->brightness << 8, // brightness (cam->hue + 128) << 8, // hue cam->color << 9, // color cam->contrast << 9, // contrast 0x8000, // whiteness 16, VIDEO_PALETTE_YUV422// bpp, palette format }; struct video_picture *pic = arg; *pic = vpic; return 0; } case VIDIOCSPICT: { struct video_picture *vpic = arg; if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV)) return -EINVAL; cam->brightness = vpic->brightness >> 8; cam->hue = (vpic->hue >> 8) - 128; cam->color = vpic->colour >> 9; cam->contrast = vpic->contrast >> 9; w9966_pdev_claim(cam); if ( w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 || w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 || w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 || w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1 ) { w9966_pdev_release(cam); return -EIO; } w9966_pdev_release(cam); return 0; } case VIDIOCSWIN: { int ret; struct video_window *vwin = arg; if (vwin->flags != 0) return -EINVAL; if (vwin->clipcount != 0) return -EINVAL; if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W) return -EINVAL; if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H) return -EINVAL; // Update camera regs w9966_pdev_claim(cam); ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height); w9966_pdev_release(cam); if (ret != 0) { DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n"); return -EIO; } return 0; } case VIDIOCGWIN: { struct video_window *vwin = arg; memset(vwin, 0, sizeof(*vwin)); vwin->width = cam->width; vwin->height = cam->height; return 0; } // Unimplemented case VIDIOCCAPTURE: case VIDIOCGFBUF: case VIDIOCSFBUF: case VIDIOCKEY: case VIDIOCGFREQ: case VIDIOCSFREQ: case VIDIOCGAUDIO: case VIDIOCSAUDIO: return -EINVAL; default: return -ENOIOCTLCMD; } return 0; } static int w9966_v4l_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl); } // Capture data static ssize_t w9966_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct video_device *vdev = video_devdata(file); struct w9966_dev *cam = vdev->priv; unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000 unsigned char __user *dest = (unsigned char __user *)buf; unsigned long dleft = count; unsigned char *tbuf; // Why would anyone want more than this?? if (count > cam->width * cam->height * 2) return -EINVAL; w9966_pdev_claim(cam); w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer w9966_wReg(cam, 0x00, 0x00); // Return to normal operation w9966_wReg(cam, 0x01, 0x98); // Enable capture // write special capture-addr and negotiate into data transfer if ( (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )|| (parport_write(cam->pport, &addr, 1) != 1 )|| (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0 ) ) { w9966_pdev_release(cam); return -EFAULT; } tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL); if (tbuf == NULL) { count = -ENOMEM; goto out; } while(dleft > 0) { unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft; if (parport_read(cam->pport, tbuf, tsize) < tsize) { count = -EFAULT; goto out; } if (copy_to_user(dest, tbuf, tsize) != 0) { count = -EFAULT; goto out; } dest += tsize; dleft -= tsize; } w9966_wReg(cam, 0x01, 0x18); // Disable capture out: kfree(tbuf); w9966_pdev_release(cam); return count; } // Called once for every parport on init static void w9966_attach(struct parport *port) { int i; for (i = 0; i < W9966_MAXCAMS; i++) { if (w9966_cams[i].dev_state != 0) // Cam is already assigned continue; if ( strcmp(pardev[i], "aggressive") == 0 || strcmp(pardev[i], port->name) == 0 ) { if (w9966_init(&w9966_cams[i], port) != 0) w9966_term(&w9966_cams[i]); break; // return } } }
/** * vpif_open : vpif open handler * @filep: file ptr * * It creates object of file handle structure and stores it in private_data * member of filepointer */ static int vpif_open(struct file *filep) { struct vpif_capture_config *config = vpif_dev->platform_data; struct video_device *vdev = video_devdata(filep); struct common_obj *common; struct video_obj *vid_ch; struct channel_obj *ch; struct vpif_fh *fh; int i, ret = 0; vpif_dbg(2, debug, "vpif_open\n"); ch = video_get_drvdata(vdev); vid_ch = &ch->video; common = &ch->common[VPIF_VIDEO_INDEX]; if (mutex_lock_interruptible(&common->lock)) return -ERESTARTSYS; if (NULL == ch->curr_subdev_info) { /** * search through the sub device to see a registered * sub device and make it as current sub device */ for (i = 0; i < config->subdev_count; i++) { if (vpif_obj.sd[i]) { /* the sub device is registered */ ch->curr_subdev_info = &config->subdev_info[i]; /* make first input as the current input */ vid_ch->input_idx = 0; break; } } if (i == config->subdev_count) { vpif_err("No sub device registered\n"); ret = -ENOENT; goto exit; } } /* Allocate memory for the file handle object */ fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL); if (NULL == fh) { vpif_err("unable to allocate memory for file handle object\n"); ret = -ENOMEM; goto exit; } /* store pointer to fh in private_data member of filep */ filep->private_data = fh; fh->channel = ch; fh->initialized = 0; /* If decoder is not initialized. initialize it */ if (!ch->initialized) { fh->initialized = 1; ch->initialized = 1; memset(&(ch->vpifparams), 0, sizeof(struct vpif_params)); } /* Increment channel usrs counter */ ch->usrs++; /* Set io_allowed member to false */ fh->io_allowed[VPIF_VIDEO_INDEX] = 0; /* Initialize priority of this instance to default priority */ fh->prio = V4L2_PRIORITY_UNSET; v4l2_prio_open(&ch->prio, &fh->prio); exit: mutex_unlock(&common->lock); return ret; }
static int pcm20_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct pcm20_device *pcm20 = dev->priv; int i; switch(cmd) { case VIDIOCGCAP: { struct video_capability *v = arg; memset(v,0,sizeof(*v)); v->type=VID_TYPE_TUNER; strcpy(v->name, "Miro PCM20"); v->channels=1; v->audios=1; return 0; } case VIDIOCGTUNER: { struct video_tuner *v = arg; if(v->tuner) /* Only 1 tuner */ return -EINVAL; v->rangelow=87*16000; v->rangehigh=108*16000; pcm20_getflags(pcm20, &v->flags, &v->signal); v->flags|=VIDEO_TUNER_LOW; v->mode=VIDEO_MODE_AUTO; strcpy(v->name, "FM"); return 0; } case VIDIOCSTUNER: { struct video_tuner *v = arg; if(v->tuner!=0) return -EINVAL; /* Only 1 tuner so no setting needed ! */ return 0; } case VIDIOCGFREQ: { unsigned long *freq = arg; *freq = pcm20->freq; return 0; } case VIDIOCSFREQ: { unsigned long *freq = arg; pcm20->freq = *freq; i=pcm20_setfreq(pcm20, pcm20->freq); pr_debug("First view (setfreq): 0x%x\n", i); return i; } case VIDIOCGAUDIO: { struct video_audio *v = arg; memset(v,0, sizeof(*v)); v->flags=VIDEO_AUDIO_MUTABLE; if (pcm20->muted) v->flags|=VIDEO_AUDIO_MUTE; v->mode=VIDEO_SOUND_STEREO; if (pcm20->stereo) v->mode|=VIDEO_SOUND_MONO; /* v->step=2048; */ strcpy(v->name, "Radio"); return 0; } case VIDIOCSAUDIO: { struct video_audio *v = arg; if(v->audio) return -EINVAL; pcm20_mute(pcm20, !!(v->flags&VIDEO_AUDIO_MUTE)); if(v->flags&VIDEO_SOUND_MONO) pcm20_stereo(pcm20, 0); if(v->flags&VIDEO_SOUND_STEREO) pcm20_stereo(pcm20, 1); return 0; } default: return -ENOIOCTLCMD; } }