diff options
Diffstat (limited to 'drivers/media/usb')
97 files changed, 1543 insertions, 2520 deletions
diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index b35231ffe503..751703db06f5 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -71,7 +71,6 @@ static const struct v4l2_frequency_band bands_rf[] = { /* stream formats */ struct airspy_format { - char *name; u32 pixelformat; u32 buffersize; }; @@ -79,7 +78,6 @@ struct airspy_format { /* format descriptions for capture and preview */ static struct airspy_format formats[] = { { - .name = "Real U12LE", .pixelformat = V4L2_SDR_FMT_RU12LE, .buffersize = BULK_BUFFER_SIZE, }, @@ -622,7 +620,6 @@ static int airspy_enum_fmt_sdr_cap(struct file *file, void *priv, if (f->index >= NUM_FORMATS) return -EINVAL; - strscpy(f->description, formats[f->index].name, sizeof(f->description)); f->pixelformat = formats[f->index].pixelformat; return 0; diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index 5e00019bce8a..d1895334cbbf 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1153,7 +1153,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd, format->fmt.pix.sizeimage = width * height * 2; format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; format->fmt.pix.field = V4L2_FIELD_INTERLACED; - format->fmt.pix.priv = 0; if (cmd == VIDIOC_TRY_FMT) return 0; @@ -1207,10 +1206,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, dprintk(1, "%s called\n", __func__); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strscpy(f->description, "Packed YUV2", sizeof(f->description)); - - f->flags = 0; f->pixelformat = V4L2_PIX_FMT_UYVY; return 0; @@ -1231,7 +1226,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.sizeimage = dev->frame_size; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */ f->fmt.pix.field = V4L2_FIELD_INTERLACED; - f->fmt.pix.priv = 0; return 0; } diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c index 1826ff825c2e..039963a7765b 100644 --- a/drivers/media/usb/b2c2/flexcop-usb.c +++ b/drivers/media/usb/b2c2/flexcop-usb.c @@ -295,7 +295,7 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, mutex_unlock(&fc_usb->data_mutex); - return 0; + return ret; } /* actual bus specific access functions, @@ -504,7 +504,13 @@ urb_error: static int flexcop_usb_init(struct flexcop_usb *fc_usb) { /* use the alternate setting with the larges buffer */ - usb_set_interface(fc_usb->udev,0,1); + int ret = usb_set_interface(fc_usb->udev, 0, 1); + + if (ret) { + err("set interface failed."); + return ret; + } + switch (fc_usb->udev->speed) { case USB_SPEED_LOW: err("cannot handle USB speed because it is too slow."); @@ -538,6 +544,9 @@ static int flexcop_usb_probe(struct usb_interface *intf, struct flexcop_device *fc = NULL; int ret; + if (intf->cur_altsetting->desc.bNumEndpoints < 1) + return -ENODEV; + if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) { err("out of memory\n"); return -ENOMEM; diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 17468f7d78ed..3ab80a7b4498 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -676,6 +676,10 @@ static int submit_urbs(struct camera_data *cam) if (!urb) { for (j = 0; j < i; j++) usb_free_urb(cam->sbuf[j].urb); + for (j = 0; j < NUM_SBUF; j++) { + kfree(cam->sbuf[j].data); + cam->sbuf[j].data = NULL; + } return -ENOMEM; } diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c index 0feae825cebb..9d3d05125d7b 100644 --- a/drivers/media/usb/cpia2/cpia2_v4l.c +++ b/drivers/media/usb/cpia2/cpia2_v4l.c @@ -292,28 +292,13 @@ static int cpia2_s_input(struct file *file, void *fh, unsigned int i) static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { - int index = f->index; - - if (index < 0 || index > 1) - return -EINVAL; + if (f->index > 1) + return -EINVAL; - memset(f, 0, sizeof(*f)); - f->index = index; - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - switch(index) { - case 0: - strscpy(f->description, "MJPEG", sizeof(f->description)); + if (f->index == 0) f->pixelformat = V4L2_PIX_FMT_MJPEG; - break; - case 1: - strscpy(f->description, "JPEG", sizeof(f->description)); + else f->pixelformat = V4L2_PIX_FMT_JPEG; - break; - default: - return -EINVAL; - } - return 0; } @@ -338,7 +323,6 @@ static int cpia2_try_fmt_vid_cap(struct file *file, void *fh, f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = cam->frame_size; f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; - f->fmt.pix.priv = 0; switch (cpia2_match_video_size(f->fmt.pix.width, f->fmt.pix.height)) { case VIDEOSIZE_VGA: @@ -449,7 +433,6 @@ static int cpia2_g_fmt_vid_cap(struct file *file, void *fh, f->fmt.pix.bytesperline = 0; f->fmt.pix.sizeimage = cam->frame_size; f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG; - f->fmt.pix.priv = 0; return 0; } @@ -817,7 +800,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) break; case FRAME_READY: buf->bytesused = cam->buffers[buf->index].length; - buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); buf->sequence = cam->buffers[buf->index].seq; buf->flags = V4L2_BUF_FLAG_DONE; break; @@ -924,7 +907,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) buf->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; buf->field = V4L2_FIELD_NONE; - buf->timestamp = ns_to_timeval(cam->buffers[buf->index].ts); + v4l2_buffer_set_timestamp(buf, cam->buffers[buf->index].ts); buf->sequence = cam->buffers[buf->index].seq; buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer; buf->length = cam->frame_size; diff --git a/drivers/media/usb/cx231xx/Kconfig b/drivers/media/usb/cx231xx/Kconfig index 74f3b29d9c60..2fe2b2d335ba 100644 --- a/drivers/media/usb/cx231xx/Kconfig +++ b/drivers/media/usb/cx231xx/Kconfig @@ -4,7 +4,7 @@ config VIDEO_CX231XX depends on VIDEO_DEV && I2C && I2C_MUX select VIDEO_TUNER select VIDEO_TVEEPROM - select VIDEOBUF_VMALLOC + select VIDEOBUF2_VMALLOC select VIDEO_CX25840 select VIDEO_CX2341X diff --git a/drivers/media/usb/cx231xx/cx231xx-417.c b/drivers/media/usb/cx231xx/cx231xx-417.c index 2475f69a2f1c..1aec4459f50a 100644 --- a/drivers/media/usb/cx231xx/cx231xx-417.c +++ b/drivers/media/usb/cx231xx/cx231xx-417.c @@ -60,10 +60,6 @@ #define MCI_MODE_MEMORY_READ 0x000 #define MCI_MODE_MEMORY_WRITE 0x4000 -static unsigned int mpegbufs = 8; -module_param(mpegbufs, int, 0644); -MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); - static unsigned int mpeglines = 128; module_param(mpeglines, int, 0644); MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); @@ -1051,6 +1047,7 @@ static int cx231xx_load_firmware(struct cx231xx *dev) p_current_fw = p_fw; vfree(p_current_fw); p_current_fw = NULL; + vfree(p_buffer); uninitGPIO(dev); release_firmware(firmware); dprintk(1, "Firmware upload successful.\n"); @@ -1079,16 +1076,6 @@ static int cx231xx_load_firmware(struct cx231xx *dev) return 0; } -static void cx231xx_417_check_encoder(struct cx231xx *dev) -{ - u32 status, seq; - - status = 0; - seq = 0; - cx231xx_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq); - dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq); -} - static void cx231xx_codec_settings(struct cx231xx *dev) { dprintk(1, "%s()\n", __func__); @@ -1226,40 +1213,25 @@ static int cx231xx_initialize_codec(struct cx231xx *dev) /* ------------------------------------------------------------------ */ -static int bb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) { - struct cx231xx_fh *fh = q->priv_data; + struct cx231xx *dev = vb2_get_drv_priv(vq); + unsigned int size = mpeglinesize * mpeglines; - fh->dev->ts1.ts_packet_size = mpeglinesize; - fh->dev->ts1.ts_packet_count = mpeglines; + dev->ts1.ts_packet_size = mpeglinesize; + dev->ts1.ts_packet_count = mpeglines; - *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; - *count = mpegbufs; + if (vq->num_buffers + *nbuffers < CX231XX_MIN_BUF) + *nbuffers = CX231XX_MIN_BUF - vq->num_buffers; - return 0; -} - -static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) -{ - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; - unsigned long flags = 0; + if (*nplanes) + return sizes[0] < size ? -EINVAL : 0; + *nplanes = 1; + sizes[0] = mpeglinesize * mpeglines; - BUG_ON(in_interrupt()); - - spin_lock_irqsave(&dev->video_mode.slock, flags); - if (dev->USE_ISO) { - if (dev->video_mode.isoc_ctl.buf == buf) - dev->video_mode.isoc_ctl.buf = NULL; - } else { - if (dev->video_mode.bulk_ctl.buf == buf) - dev->video_mode.bulk_ctl.buf = NULL; - } - spin_unlock_irqrestore(&dev->video_mode.slock, flags); - videobuf_waiton(vq, &buf->vb, 0, 0); - videobuf_vmalloc_free(&buf->vb); - buf->vb.state = VIDEOBUF_NEEDS_INIT; + return 0; } static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *urb, @@ -1275,13 +1247,13 @@ static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *ur return; buf = list_entry(dma_q->active.next, - struct cx231xx_buffer, vb.queue); + struct cx231xx_buffer, list); dev->video_mode.isoc_ctl.buf = buf; dma_q->mpeg_buffer_done = 1; } /* Fill buffer */ buf = dev->video_mode.isoc_ctl.buf; - vbuf = videobuf_to_vmalloc(&buf->vb); + vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); if ((dma_q->mpeg_buffer_completed+len) < mpeglines*mpeglinesize) { @@ -1305,11 +1277,10 @@ static void buffer_copy(struct cx231xx *dev, char *data, int len, struct urb *ur memcpy(vbuf+dma_q->mpeg_buffer_completed, data, tail_data); - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - buf->vb.ts = ktime_get_ns(); - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); + buf->vb.vb2_buf.timestamp = ktime_get_ns(); + buf->vb.sequence = dma_q->sequence++; + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); dma_q->mpeg_buffer_completed = 0; if (len - tail_data > 0) { @@ -1330,17 +1301,15 @@ static void buffer_filled(char *data, int len, struct urb *urb, if (list_empty(&dma_q->active)) return; - buf = list_entry(dma_q->active.next, - struct cx231xx_buffer, vb.queue); + buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list); /* Fill buffer */ - vbuf = videobuf_to_vmalloc(&buf->vb); + vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); memcpy(vbuf, data, len); - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - buf->vb.ts = ktime_get_ns(); - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); + buf->vb.sequence = dma_q->sequence++; + buf->vb.vb2_buf.timestamp = ktime_get_ns(); + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } static int cx231xx_isoc_copy(struct cx231xx *dev, struct urb *urb) @@ -1393,100 +1362,104 @@ static int cx231xx_bulk_copy(struct cx231xx *dev, struct urb *urb) return 0; } -static int bb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) +static void buffer_queue(struct vb2_buffer *vb) { - struct cx231xx_fh *fh = q->priv_data; struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx *dev = fh->dev; - int rc = 0, urb_init = 0; - int size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; + container_of(vb, struct cx231xx_buffer, vb.vb2_buf); + struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue); + struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + unsigned long flags; - if (0 != buf->vb.baddr && buf->vb.bsize < size) - return -EINVAL; - buf->vb.width = fh->dev->ts1.ts_packet_size; - buf->vb.height = fh->dev->ts1.ts_packet_count; - buf->vb.size = size; - buf->vb.field = field; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - rc = videobuf_iolock(q, &buf->vb, NULL); - if (rc < 0) - goto fail; - } + spin_lock_irqsave(&dev->video_mode.slock, flags); + list_add_tail(&buf->list, &vidq->active); + spin_unlock_irqrestore(&dev->video_mode.slock, flags); +} - if (dev->USE_ISO) { - if (!dev->video_mode.isoc_ctl.num_bufs) - urb_init = 1; - } else { - if (!dev->video_mode.bulk_ctl.num_bufs) - urb_init = 1; +static void return_all_buffers(struct cx231xx *dev, + enum vb2_buffer_state state) +{ + struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + struct cx231xx_buffer *buf, *node; + unsigned long flags; + + spin_lock_irqsave(&dev->video_mode.slock, flags); + list_for_each_entry_safe(buf, node, &vidq->active, list) { + vb2_buffer_done(&buf->vb.vb2_buf, state); + list_del(&buf->list); } - dev_dbg(dev->dev, - "urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size); + spin_unlock_irqrestore(&dev->video_mode.slock, flags); +} + +static int start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct cx231xx *dev = vb2_get_drv_priv(vq); + struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + int ret = 0; + + vidq->sequence = 0; dev->mode_tv = 1; - if (urb_init) { - rc = cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - rc = cx231xx_unmute_audio(dev); - if (dev->USE_ISO) { - cx231xx_set_alt_setting(dev, INDEX_TS1, 4); - rc = cx231xx_init_isoc(dev, mpeglines, - mpegbufs, - dev->ts1_mode.max_pkt_size, - cx231xx_isoc_copy); - } else { - cx231xx_set_alt_setting(dev, INDEX_TS1, 0); - rc = cx231xx_init_bulk(dev, mpeglines, - mpegbufs, - dev->ts1_mode.max_pkt_size, - cx231xx_bulk_copy); - } - if (rc < 0) - goto fail; - } + cx231xx_set_alt_setting(dev, INDEX_VANC, 1); + cx231xx_set_gpio_value(dev, 2, 0); - buf->vb.state = VIDEOBUF_PREPARED; - return 0; + cx231xx_initialize_codec(dev); + + cx231xx_start_TS1(dev); + + cx231xx_set_alt_setting(dev, INDEX_TS1, 0); + cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); + if (dev->USE_ISO) + ret = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, + CX231XX_NUM_BUFS, + dev->ts1_mode.max_pkt_size, + cx231xx_isoc_copy); + else + ret = cx231xx_init_bulk(dev, 320, 5, + dev->ts1_mode.max_pkt_size, + cx231xx_bulk_copy); + if (ret) + return_all_buffers(dev, VB2_BUF_STATE_QUEUED); -fail: - free_buffer(q, buf); - return rc; + call_all(dev, video, s_stream, 1); + return ret; } -static void bb_buf_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static void stop_streaming(struct vb2_queue *vq) { - struct cx231xx_fh *fh = q->priv_data; + struct cx231xx *dev = vb2_get_drv_priv(vq); + unsigned long flags; - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx *dev = fh->dev; - struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + call_all(dev, video, s_stream, 0); - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue, &vidq->active); + cx231xx_stop_TS1(dev); -} + /* do this before setting alternate! */ + if (dev->USE_ISO) + cx231xx_uninit_isoc(dev); + else + cx231xx_uninit_bulk(dev); + cx231xx_set_mode(dev, CX231XX_SUSPEND); -static void bb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - /*struct cx231xx_fh *fh = q->priv_data;*/ - /*struct cx231xx *dev = (struct cx231xx *)fh->dev;*/ + cx231xx_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, + CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, + CX231xx_RAW_BITS_NONE); - free_buffer(q, buf); + spin_lock_irqsave(&dev->video_mode.slock, flags); + if (dev->USE_ISO) + dev->video_mode.isoc_ctl.buf = NULL; + else + dev->video_mode.bulk_ctl.buf = NULL; + spin_unlock_irqrestore(&dev->video_mode.slock, flags); + return_all_buffers(dev, VB2_BUF_STATE_ERROR); } -static const struct videobuf_queue_ops cx231xx_qops = { - .buf_setup = bb_buf_setup, - .buf_prepare = bb_buf_prepare, - .buf_queue = bb_buf_queue, - .buf_release = bb_buf_release, +static struct vb2_ops cx231xx_video_qops = { + .queue_setup = queue_setup, + .buf_queue = buffer_queue, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* ------------------------------------------------------------------ */ @@ -1494,8 +1467,7 @@ static const struct videobuf_queue_ops cx231xx_qops = { static int vidioc_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); bool is_50hz = dev->encodernorm.id & V4L2_STD_625_50; if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -1510,8 +1482,7 @@ static int vidioc_g_pixelaspect(struct file *file, void *priv, static int vidioc_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1532,8 +1503,7 @@ static int vidioc_g_selection(struct file *file, void *priv, static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) { - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); *norm = dev->encodernorm.id; return 0; @@ -1541,8 +1511,7 @@ static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) { - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); unsigned int i; for (i = 0; i < ARRAY_SIZE(cx231xx_tvnorms); i++) @@ -1574,8 +1543,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctl) { - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); struct v4l2_subdev *sd; dprintk(3, "enter vidioc_s_ctrl()\n"); @@ -1592,7 +1560,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (f->index != 0) return -EINVAL; - strscpy(f->description, "MPEG", sizeof(f->description)); f->pixelformat = V4L2_PIX_FMT_MPEG; return 0; @@ -1601,8 +1568,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); dprintk(3, "enter vidioc_g_fmt_vid_cap()\n"); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; @@ -1621,8 +1587,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); dprintk(3, "enter vidioc_try_fmt_vid_cap()\n"); f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; @@ -1636,230 +1601,21 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct cx231xx_fh *fh = file->private_data; - - return videobuf_reqbufs(&fh->vidq, p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx231xx_fh *fh = file->private_data; - - return videobuf_querybuf(&fh->vidq, p); -} - -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx231xx_fh *fh = file->private_data; - - return videobuf_qbuf(&fh->vidq, p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx231xx_fh *fh = priv; - - return videobuf_dqbuf(&fh->vidq, b, file->f_flags & O_NONBLOCK); -} - - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - - dprintk(3, "enter vidioc_streamon()\n"); - cx231xx_set_alt_setting(dev, INDEX_TS1, 0); - cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); - if (dev->USE_ISO) - cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, - CX231XX_NUM_BUFS, - dev->video_mode.max_pkt_size, - cx231xx_isoc_copy); - else { - cx231xx_init_bulk(dev, 320, - 5, - dev->ts1_mode.max_pkt_size, - cx231xx_bulk_copy); - } - dprintk(3, "exit vidioc_streamon()\n"); - return videobuf_streamon(&fh->vidq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx231xx_fh *fh = file->private_data; - - return videobuf_streamoff(&fh->vidq); -} - static int vidioc_log_status(struct file *file, void *priv) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); call_all(dev, core, log_status); return v4l2_ctrl_log_status(file, priv); } -static int mpeg_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct cx231xx *dev = video_drvdata(file); - struct cx231xx_fh *fh; - - dprintk(2, "%s()\n", __func__); - - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - mutex_unlock(&dev->lock); - return -ENOMEM; - } - - file->private_data = fh; - v4l2_fh_init(&fh->fh, vdev); - fh->dev = dev; - - - videobuf_queue_vmalloc_init(&fh->vidq, &cx231xx_qops, - NULL, &dev->video_mode.slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, - sizeof(struct cx231xx_buffer), fh, &dev->lock); -/* - videobuf_queue_sg_init(&fh->vidq, &cx231xx_qops, - dev->dev, &dev->ts1.slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx231xx_buffer), - fh, &dev->lock); -*/ - - cx231xx_set_alt_setting(dev, INDEX_VANC, 1); - cx231xx_set_gpio_value(dev, 2, 0); - - cx231xx_initialize_codec(dev); - - mutex_unlock(&dev->lock); - v4l2_fh_add(&fh->fh); - cx231xx_start_TS1(dev); - - return 0; -} - -static int mpeg_release(struct file *file) -{ - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - - dprintk(3, "mpeg_release()! dev=0x%p\n", dev); - - mutex_lock(&dev->lock); - - cx231xx_stop_TS1(dev); - - /* do this before setting alternate! */ - if (dev->USE_ISO) - cx231xx_uninit_isoc(dev); - else - cx231xx_uninit_bulk(dev); - cx231xx_set_mode(dev, CX231XX_SUSPEND); - - cx231xx_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX231xx_END_NOW, CX231xx_MPEG_CAPTURE, - CX231xx_RAW_BITS_NONE); - - /* FIXME: Review this crap */ - /* Shut device down on last close */ - if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { - if (atomic_dec_return(&dev->v4l_reader_count) == 0) { - /* stop mpeg capture */ - - msleep(500); - cx231xx_417_check_encoder(dev); - - } - } - - if (fh->vidq.streaming) - videobuf_streamoff(&fh->vidq); - if (fh->vidq.reading) - videobuf_read_stop(&fh->vidq); - - videobuf_mmap_free(&fh->vidq); - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - kfree(fh); - mutex_unlock(&dev->lock); - return 0; -} - -static ssize_t mpeg_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - - /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ - /* Start mpeg encoder on first read. */ - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&dev->v4l_reader_count) == 1) { - if (cx231xx_initialize_codec(dev) < 0) - return -EINVAL; - } - } - - return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static __poll_t mpeg_poll(struct file *file, - struct poll_table_struct *wait) -{ - __poll_t req_events = poll_requested_events(wait); - struct cx231xx_fh *fh = file->private_data; - struct cx231xx *dev = fh->dev; - __poll_t res = 0; - - if (v4l2_event_pending(&fh->fh)) - res |= EPOLLPRI; - else - poll_wait(file, &fh->fh.wait, wait); - - if (!(req_events & (EPOLLIN | EPOLLRDNORM))) - return res; - - mutex_lock(&dev->lock); - res |= videobuf_poll_stream(file, &fh->vidq, wait); - mutex_unlock(&dev->lock); - return res; -} - -static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx231xx_fh *fh = file->private_data; - - dprintk(2, "%s()\n", __func__); - - return videobuf_mmap_mapper(&fh->vidq, vma); -} - static const struct v4l2_file_operations mpeg_fops = { .owner = THIS_MODULE, - .open = mpeg_open, - .release = mpeg_release, - .read = mpeg_read, - .poll = mpeg_poll, - .mmap = mpeg_mmap, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; @@ -1881,12 +1637,12 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_log_status = vidioc_log_status, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = cx231xx_g_register, @@ -1980,6 +1736,7 @@ int cx231xx_417_register(struct cx231xx *dev) /* FIXME: Port1 hardcoded here */ int err = -ENODEV; struct cx231xx_tsport *tsport = &dev->ts1; + struct vb2_queue *q; dprintk(1, "%s()\n", __func__); @@ -2017,6 +1774,21 @@ int cx231xx_417_register(struct cx231xx *dev) /* Allocate and initialize V4L video device */ cx231xx_video_dev_init(dev, dev->udev, &dev->v4l_device, &cx231xx_mpeg_template, "mpeg"); + q = &dev->mpegq; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx231xx_buffer); + q->ops = &cx231xx_video_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 1; + q->lock = &dev->lock; + err = vb2_queue_init(q); + if (err) + return err; + dev->v4l_device.queue = q; + err = video_register_device(&dev->v4l_device, VFL_TYPE_GRABBER, -1); if (err < 0) { diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 9ef362e221df..de42db6f6ad1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -13,8 +13,6 @@ #include <linux/spinlock.h> #include <linux/soundcard.h> #include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/proc_fs.h> #include <linux/module.h> #include <sound/core.h> #include <sound/pcm.h> @@ -373,28 +371,6 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) return errCode; } -static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, - size_t size) -{ - struct snd_pcm_runtime *runtime = subs->runtime; - struct cx231xx *dev = snd_pcm_substream_chip(subs); - - dev_dbg(dev->dev, "Allocating vbuffer\n"); - if (runtime->dma_area) { - if (runtime->dma_bytes > size) - return 0; - - vfree(runtime->dma_area); - } - runtime->dma_area = vmalloc(size); - if (!runtime->dma_area) - return -ENOMEM; - - runtime->dma_bytes = size; - - return 0; -} - static const struct snd_pcm_hardware snd_cx231xx_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -485,11 +461,6 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) } dev->adev.users--; - if (substream->runtime->dma_area) { - dev_dbg(dev->dev, "freeing\n"); - vfree(substream->runtime->dma_area); - substream->runtime->dma_area = NULL; - } mutex_unlock(&dev->lock); if (dev->adev.users == 0 && dev->adev.shutdown == 1) { @@ -505,44 +476,6 @@ static int snd_cx231xx_pcm_close(struct snd_pcm_substream *substream) return 0; } -static int snd_cx231xx_hw_capture_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct cx231xx *dev = snd_pcm_substream_chip(substream); - int ret; - - dev_dbg(dev->dev, "Setting capture parameters\n"); - - ret = snd_pcm_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); -#if 0 - /* TODO: set up cx231xx audio chip to deliver the correct audio format, - current default is 48000hz multiplexed => 96000hz mono - which shouldn't matter since analogue TV only supports mono */ - unsigned int channels, rate, format; - - format = params_format(hw_params); - rate = params_rate(hw_params); - channels = params_channels(hw_params); -#endif - - return ret; -} - -static int snd_cx231xx_hw_capture_free(struct snd_pcm_substream *substream) -{ - struct cx231xx *dev = snd_pcm_substream_chip(substream); - - dev_dbg(dev->dev, "Stop capture, if needed\n"); - - if (atomic_read(&dev->stream_started) > 0) { - atomic_set(&dev->stream_started, 0); - schedule_work(&dev->wq_trigger); - } - - return 0; -} - static int snd_cx231xx_prepare(struct snd_pcm_substream *substream) { struct cx231xx *dev = snd_pcm_substream_chip(substream); @@ -615,24 +548,12 @@ static snd_pcm_uframes_t snd_cx231xx_capture_pointer(struct snd_pcm_substream return hwptr_done; } -static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, - unsigned long offset) -{ - void *pageptr = subs->runtime->dma_area + offset; - - return vmalloc_to_page(pageptr); -} - static const struct snd_pcm_ops snd_cx231xx_pcm_capture = { .open = snd_cx231xx_capture_open, .close = snd_cx231xx_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cx231xx_hw_capture_params, - .hw_free = snd_cx231xx_hw_capture_free, .prepare = snd_cx231xx_prepare, .trigger = snd_cx231xx_capture_trigger, .pointer = snd_cx231xx_capture_pointer, - .page = snd_pcm_get_vmalloc_page, }; static int cx231xx_audio_init(struct cx231xx *dev) @@ -667,6 +588,7 @@ static int cx231xx_audio_init(struct cx231xx *dev) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx231xx_pcm_capture); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); pcm->info_flags = 0; pcm->private_data = dev; strscpy(pcm->name, "Conexant cx231xx Capture", sizeof(pcm->name)); diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index d417b5fe4093..0974965e848f 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -1240,7 +1240,7 @@ int cx231xx_init_ctrl_pin_status(struct cx231xx *dev) int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev, u8 analog_or_digital) { - int status = 0; + int status; /* first set the direction to output */ status = cx231xx_set_gpio_direction(dev, diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index e0d98ba8fdbf..92efe6c1f47b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1351,7 +1351,7 @@ static void cx231xx_unregister_media_device(struct cx231xx *dev) /* * cx231xx_realease_resources() * unregisters the v4l2,i2c and usb devices - * called when the device gets disconected or at module unload + * called when the device gets disconnected or at module unload */ void cx231xx_release_resources(struct cx231xx *dev) { @@ -1479,13 +1479,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, goto err_dev_init; } - /* init video dma queues */ + /* init video dma queue */ INIT_LIST_HEAD(&dev->video_mode.vidq.active); - INIT_LIST_HEAD(&dev->video_mode.vidq.queued); - /* init vbi dma queues */ + /* init vbi dma queue */ INIT_LIST_HEAD(&dev->vbi_mode.vidq.active); - INIT_LIST_HEAD(&dev->vbi_mode.vidq.queued); /* Reset other chips required if they are tied up with GPIO pins */ cx231xx_add_into_devlist(dev); @@ -1924,7 +1922,7 @@ err_if: /* * cx231xx_usb_disconnect() - * called when the device gets diconencted + * called when the device gets disconnected * video device will be unregistered on v4l2_close in case it is still open */ static void cx231xx_usb_disconnect(struct usb_interface *interface) diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index a749baadc1f1..982cb56e97e9 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -53,7 +53,7 @@ static DEFINE_MUTEX(cx231xx_devlist_mutex); /* * cx231xx_realease_resources() * unregisters the v4l2,i2c and usb devices - * called when the device gets disconected or at module unload + * called when the device gets disconnected or at module unload */ void cx231xx_remove_from_devlist(struct cx231xx *dev) { diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index f33b6a077d57..c6659253c6fb 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -515,7 +515,8 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus) { struct cx231xx *dev = bus->dev; - BUG_ON(!dev->cx231xx_send_usb_command); + if (!dev->cx231xx_send_usb_command) + return -EINVAL; bus->i2c_adap = cx231xx_adap_template; bus->i2c_adap.dev.parent = dev->dev; diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.c b/drivers/media/usb/cx231xx/cx231xx-vbi.c index fba7ccdf5a25..d2f143a096d1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.c +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.c @@ -153,131 +153,98 @@ static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb) Vbi buf operations ------------------------------------------------------------------*/ -static int -vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count, - unsigned int *size) +static int vbi_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) { - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = vb2_get_drv_priv(vq); u32 height = 0; height = ((dev->norm & V4L2_STD_625_50) ? PAL_VBI_LINES : NTSC_VBI_LINES); - *size = (dev->width * height * 2 * 2); - if (0 == *count) - *count = CX231XX_DEF_VBI_BUF; - - if (*count < CX231XX_MIN_BUF) - *count = CX231XX_MIN_BUF; - + *nplanes = 1; + sizes[0] = (dev->width * height * 2 * 2); return 0; } /* This is called *without* dev->slock held; please keep it that way */ -static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) -{ - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; - unsigned long flags = 0; - BUG_ON(in_interrupt()); - - /* We used to wait for the buffer to finish here, but this didn't work - because, as we were keeping the state as VIDEOBUF_QUEUED, - videobuf_queue_cancel marked it as finished for us. - (Also, it could wedge forever if the hardware was misconfigured.) - - This should be safe; by the time we get here, the buffer isn't - queued anymore. If we ever start marking the buffers as - VIDEOBUF_ACTIVE, it won't be, though. - */ - spin_lock_irqsave(&dev->vbi_mode.slock, flags); - if (dev->vbi_mode.bulk_ctl.buf == buf) - dev->vbi_mode.bulk_ctl.buf = NULL; - spin_unlock_irqrestore(&dev->vbi_mode.slock, flags); - - videobuf_vmalloc_free(&buf->vb); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -static int -vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, - enum v4l2_field field) +static int vbi_buf_prepare(struct vb2_buffer *vb) { - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx *dev = fh->dev; - int rc = 0, urb_init = 0; + struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue); u32 height = 0; + u32 size; height = ((dev->norm & V4L2_STD_625_50) ? PAL_VBI_LINES : NTSC_VBI_LINES); - buf->vb.size = ((dev->width << 1) * height * 2); + size = ((dev->width << 1) * height * 2); - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) + if (vb2_plane_size(vb, 0) < size) return -EINVAL; - - buf->vb.width = dev->width; - buf->vb.height = height; - buf->vb.field = field; - buf->vb.field = V4L2_FIELD_SEQ_TB; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - rc = videobuf_iolock(vq, &buf->vb, NULL); - if (rc < 0) - goto fail; - } - - if (!dev->vbi_mode.bulk_ctl.num_bufs) - urb_init = 1; - - if (urb_init) { - rc = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS, - CX231XX_NUM_VBI_BUFS, - dev->vbi_mode.alt_max_pkt_size[0], - cx231xx_isoc_vbi_copy); - if (rc < 0) - goto fail; - } - - buf->vb.state = VIDEOBUF_PREPARED; + vb2_set_plane_payload(vb, 0, size); return 0; - -fail: - free_buffer(vq, buf); - return rc; } -static void -vbi_buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +static void vbi_buf_queue(struct vb2_buffer *vb) { + struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue); struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; + container_of(vb, struct cx231xx_buffer, vb.vb2_buf); struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq; + unsigned long flags; - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue, &vidq->active); + spin_lock_irqsave(&dev->vbi_mode.slock, flags); + list_add_tail(&buf->list, &vidq->active); + spin_unlock_irqrestore(&dev->vbi_mode.slock, flags); +} + +static void return_all_buffers(struct cx231xx *dev, + enum vb2_buffer_state state) +{ + struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq; + struct cx231xx_buffer *buf, *node; + unsigned long flags; + spin_lock_irqsave(&dev->vbi_mode.slock, flags); + dev->vbi_mode.bulk_ctl.buf = NULL; + list_for_each_entry_safe(buf, node, &vidq->active, list) { + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, state); + } + spin_unlock_irqrestore(&dev->vbi_mode.slock, flags); } -static void vbi_buffer_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) +static int vbi_start_streaming(struct vb2_queue *vq, unsigned int count) { - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); + struct cx231xx *dev = vb2_get_drv_priv(vq); + struct cx231xx_dmaqueue *vidq = &dev->vbi_mode.vidq; + int ret; + + vidq->sequence = 0; + ret = cx231xx_init_vbi_isoc(dev, CX231XX_NUM_VBI_PACKETS, + CX231XX_NUM_VBI_BUFS, + dev->vbi_mode.alt_max_pkt_size[0], + cx231xx_isoc_vbi_copy); + if (ret) + return_all_buffers(dev, VB2_BUF_STATE_QUEUED); + return ret; +} +static void vbi_stop_streaming(struct vb2_queue *vq) +{ + struct cx231xx *dev = vb2_get_drv_priv(vq); - free_buffer(vq, buf); + return_all_buffers(dev, VB2_BUF_STATE_ERROR); } -const struct videobuf_queue_ops cx231xx_vbi_qops = { - .buf_setup = vbi_buffer_setup, - .buf_prepare = vbi_buffer_prepare, - .buf_queue = vbi_buffer_queue, - .buf_release = vbi_buffer_release, +struct vb2_ops cx231xx_vbi_qops = { + .queue_setup = vbi_queue_setup, + .buf_prepare = vbi_buf_prepare, + .buf_queue = vbi_buf_queue, + .start_streaming = vbi_start_streaming, + .stop_streaming = vbi_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* ------------------------------------------------------------------ @@ -512,16 +479,15 @@ static inline void vbi_buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - /* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.i); */ + /* dev_dbg(dev->dev, "[%p/%d] wakeup\n", buf, buf->vb.index); */ - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - buf->vb.ts = ktime_get_ns(); + buf->vb.sequence = dma_q->sequence++; + buf->vb.vb2_buf.timestamp = ktime_get_ns(); dev->vbi_mode.bulk_ctl.buf = NULL; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, @@ -611,11 +577,11 @@ static inline void get_next_vbi_buf(struct cx231xx_dmaqueue *dma_q, } /* Get the next buffer */ - *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue); + *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list); /* Cleans up buffer - Useful for testing for frame/URB loss */ - outp = videobuf_to_vmalloc(&(*buf)->vb); - memset(outp, 0, (*buf)->vb.size); + outp = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0); + memset(outp, 0, vb2_plane_size(&(*buf)->vb.vb2_buf, 0)); dev->vbi_mode.bulk_ctl.buf = *buf; @@ -656,7 +622,7 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, if (buf == NULL) return -EINVAL; - p_out_buffer = videobuf_to_vmalloc(&buf->vb); + p_out_buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); if (dma_q->bytes_left_in_line != _line_size) { current_line_bytes_copied = diff --git a/drivers/media/usb/cx231xx/cx231xx-vbi.h b/drivers/media/usb/cx231xx/cx231xx-vbi.h index 7cddd629fbfc..0b21bee5fa30 100644 --- a/drivers/media/usb/cx231xx/cx231xx-vbi.h +++ b/drivers/media/usb/cx231xx/cx231xx-vbi.h @@ -10,7 +10,7 @@ #ifndef _CX231XX_VBI_H #define _CX231XX_VBI_H -extern const struct videobuf_queue_ops cx231xx_vbi_qops; +extern struct vb2_ops cx231xx_vbi_qops; #define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ #define NTSC_VBI_END_LINE 21 diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index b651ac7713ea..69abafaebbf3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -58,10 +58,10 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_VERSION(CX231XX_VERSION); -static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; -static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; -static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = UNSET }; +static unsigned int card[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = -1U }; +static unsigned int video_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = -1U }; +static unsigned int vbi_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = -1U }; +static unsigned int radio_nr[] = {[0 ... (CX231XX_MAXBOARDS - 1)] = -1U }; module_param_array(card, int, NULL, 0444); module_param_array(video_nr, int, NULL, 0444); @@ -80,7 +80,6 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); /* supported video standards */ static struct cx231xx_fmt format[] = { { - .name = "16bpp YUY2, 4:2:2, packed", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .reg = 0, @@ -167,18 +166,19 @@ static inline void buffer_filled(struct cx231xx *dev, struct cx231xx_buffer *buf) { /* Advice that buffer was filled */ - cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - buf->vb.ts = ktime_get_ns(); + cx231xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.vb2_buf.index); + buf->vb.sequence = dma_q->sequence++; + buf->vb.field = V4L2_FIELD_INTERLACED; + buf->vb.vb2_buf.timestamp = ktime_get_ns(); + vb2_set_plane_payload(&buf->vb.vb2_buf, 0, dev->size); if (dev->USE_ISO) dev->video_mode.isoc_ctl.buf = NULL; else dev->video_mode.bulk_ctl.buf = NULL; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); } static inline void print_err_status(struct cx231xx *dev, int packet, int status) @@ -242,11 +242,11 @@ static inline void get_next_buf(struct cx231xx_dmaqueue *dma_q, } /* Get the next buffer */ - *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, vb.queue); + *buf = list_entry(dma_q->active.next, struct cx231xx_buffer, list); /* Cleans up buffer - Useful for testing for frame/URB loss */ - outp = videobuf_to_vmalloc(&(*buf)->vb); - memset(outp, 0, (*buf)->vb.size); + outp = vb2_plane_vaddr(&(*buf)->vb.vb2_buf, 0); + memset(outp, 0, dev->size); if (dev->USE_ISO) dev->video_mode.isoc_ctl.buf = *buf; @@ -654,7 +654,7 @@ int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, if (buf == NULL) return -1; - p_out_buffer = videobuf_to_vmalloc(&buf->vb); + p_out_buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); current_line_bytes_copied = _line_size - dma_q->bytes_left_in_line; @@ -673,7 +673,7 @@ int cx231xx_do_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q, lencopy = dma_q->bytes_left_in_line > bytes_to_copy ? bytes_to_copy : dma_q->bytes_left_in_line; - if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + buf->vb.size)) + if ((u8 *)(startwrite + lencopy) > (u8 *)(p_out_buffer + dev->size)) return 0; /* The below copies the UYVY data straight into video buffer */ @@ -709,149 +709,98 @@ u8 cx231xx_is_buffer_done(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q) Videobuf operations ------------------------------------------------------------------*/ -static int -buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) +static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) { - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = vb2_get_drv_priv(vq); - *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)>>3; - if (0 == *count) - *count = CX231XX_DEF_BUF; + dev->size = (dev->width * dev->height * dev->format->depth + 7) >> 3; - if (*count < CX231XX_MIN_BUF) - *count = CX231XX_MIN_BUF; + if (vq->num_buffers + *nbuffers < CX231XX_MIN_BUF) + *nbuffers = CX231XX_MIN_BUF - vq->num_buffers; - - cx231xx_enable_analog_tuner(dev); + if (*nplanes) + return sizes[0] < dev->size ? -EINVAL : 0; + *nplanes = 1; + sizes[0] = dev->size; return 0; } -/* This is called *without* dev->slock held; please keep it that way */ -static void free_buffer(struct videobuf_queue *vq, struct cx231xx_buffer *buf) +static void buffer_queue(struct vb2_buffer *vb) { - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; - unsigned long flags = 0; - - BUG_ON(in_interrupt()); - - /* We used to wait for the buffer to finish here, but this didn't work - because, as we were keeping the state as VIDEOBUF_QUEUED, - videobuf_queue_cancel marked it as finished for us. - (Also, it could wedge forever if the hardware was misconfigured.) + struct cx231xx_buffer *buf = + container_of(vb, struct cx231xx_buffer, vb.vb2_buf); + struct cx231xx *dev = vb2_get_drv_priv(vb->vb2_queue); + struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + unsigned long flags; - This should be safe; by the time we get here, the buffer isn't - queued anymore. If we ever start marking the buffers as - VIDEOBUF_ACTIVE, it won't be, though. - */ spin_lock_irqsave(&dev->video_mode.slock, flags); - if (dev->USE_ISO) { - if (dev->video_mode.isoc_ctl.buf == buf) - dev->video_mode.isoc_ctl.buf = NULL; - } else { - if (dev->video_mode.bulk_ctl.buf == buf) - dev->video_mode.bulk_ctl.buf = NULL; - } + list_add_tail(&buf->list, &vidq->active); spin_unlock_irqrestore(&dev->video_mode.slock, flags); - - videobuf_vmalloc_free(&buf->vb); - buf->vb.state = VIDEOBUF_NEEDS_INIT; } -static int -buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, - enum v4l2_field field) +static void return_all_buffers(struct cx231xx *dev, + enum vb2_buffer_state state) { - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx *dev = fh->dev; - int rc = 0, urb_init = 0; - - /* The only currently supported format is 16 bits/pixel */ - buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth - + 7) >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - buf->vb.width = dev->width; - buf->vb.height = dev->height; - buf->vb.field = field; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - rc = videobuf_iolock(vq, &buf->vb, NULL); - if (rc < 0) - goto fail; - } + struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + struct cx231xx_buffer *buf, *node; + unsigned long flags; - if (dev->USE_ISO) { - if (!dev->video_mode.isoc_ctl.num_bufs) - urb_init = 1; - } else { - if (!dev->video_mode.bulk_ctl.num_bufs) - urb_init = 1; - } - dev_dbg(dev->dev, - "urb_init=%d dev->video_mode.max_pkt_size=%d\n", - urb_init, dev->video_mode.max_pkt_size); - if (urb_init) { - dev->mode_tv = 0; - if (dev->USE_ISO) - rc = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, - CX231XX_NUM_BUFS, - dev->video_mode.max_pkt_size, - cx231xx_isoc_copy); - else - rc = cx231xx_init_bulk(dev, CX231XX_NUM_PACKETS, - CX231XX_NUM_BUFS, - dev->video_mode.max_pkt_size, - cx231xx_bulk_copy); - if (rc < 0) - goto fail; + spin_lock_irqsave(&dev->video_mode.slock, flags); + if (dev->USE_ISO) + dev->video_mode.isoc_ctl.buf = NULL; + else + dev->video_mode.bulk_ctl.buf = NULL; + list_for_each_entry_safe(buf, node, &vidq->active, list) { + list_del(&buf->list); + vb2_buffer_done(&buf->vb.vb2_buf, state); } - - buf->vb.state = VIDEOBUF_PREPARED; - - return 0; - -fail: - free_buffer(vq, buf); - return rc; + spin_unlock_irqrestore(&dev->video_mode.slock, flags); } -static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +static int start_streaming(struct vb2_queue *vq, unsigned int count) { - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = vb2_get_drv_priv(vq); struct cx231xx_dmaqueue *vidq = &dev->video_mode.vidq; + int ret = 0; - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue, &vidq->active); + vidq->sequence = 0; + dev->mode_tv = 0; + cx231xx_enable_analog_tuner(dev); + if (dev->USE_ISO) + ret = cx231xx_init_isoc(dev, CX231XX_NUM_PACKETS, + CX231XX_NUM_BUFS, + dev->video_mode.max_pkt_size, + cx231xx_isoc_copy); + else + ret = cx231xx_init_bulk(dev, CX231XX_NUM_PACKETS, + CX231XX_NUM_BUFS, + dev->video_mode.max_pkt_size, + cx231xx_bulk_copy); + if (ret) + return_all_buffers(dev, VB2_BUF_STATE_QUEUED); + call_all(dev, video, s_stream, 1); + return ret; } -static void buffer_release(struct videobuf_queue *vq, - struct videobuf_buffer *vb) +static void stop_streaming(struct vb2_queue *vq) { - struct cx231xx_buffer *buf = - container_of(vb, struct cx231xx_buffer, vb); - struct cx231xx_fh *fh = vq->priv_data; - struct cx231xx *dev = (struct cx231xx *)fh->dev; - - cx231xx_isocdbg("cx231xx: called buffer_release\n"); + struct cx231xx *dev = vb2_get_drv_priv(vq); - free_buffer(vq, buf); + call_all(dev, video, s_stream, 0); + return_all_buffers(dev, VB2_BUF_STATE_ERROR); } -static const struct videobuf_queue_ops cx231xx_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, +static struct vb2_ops cx231xx_video_qops = { + .queue_setup = queue_setup, + .buf_queue = buffer_queue, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /********************* v4l2 interface **************************************/ @@ -873,58 +822,6 @@ void video_mux(struct cx231xx *dev, int index) cx231xx_do_mode_ctrl_overrides(dev); } -/* Usage lock check functions */ -static int res_get(struct cx231xx_fh *fh) -{ - struct cx231xx *dev = fh->dev; - int rc = 0; - - /* This instance already has stream_on */ - if (fh->stream_on) - return rc; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - if (dev->stream_on) - return -EBUSY; - dev->stream_on = 1; - } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - if (dev->vbi_stream_on) - return -EBUSY; - dev->vbi_stream_on = 1; - } else - return -EINVAL; - - fh->stream_on = 1; - - return rc; -} - -static int res_check(struct cx231xx_fh *fh) -{ - return fh->stream_on; -} - -static void res_free(struct cx231xx_fh *fh) -{ - struct cx231xx *dev = fh->dev; - - fh->stream_on = 0; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - dev->stream_on = 0; - if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) - dev->vbi_stream_on = 0; -} - -static int check_dev(struct cx231xx *dev) -{ - if (dev->state & DEV_DISCONNECTED) { - dev_err(dev->dev, "v4l2 ioctl: device not present\n"); - return -ENODEV; - } - return 0; -} - /* ------------------------------------------------------------------ IOCTL vidioc handling ------------------------------------------------------------------*/ @@ -932,8 +829,7 @@ static int check_dev(struct cx231xx *dev) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); f->fmt.pix.width = dev->width; f->fmt.pix.height = dev->height; @@ -961,8 +857,7 @@ static struct cx231xx_fmt *format_by_fourcc(unsigned int fourcc) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); unsigned int width = f->fmt.pix.width; unsigned int height = f->fmt.pix.height; unsigned int maxw = norm_maxw(dev); @@ -994,39 +889,25 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - struct cx231xx_fmt *fmt; + struct cx231xx *dev = video_drvdata(file); struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; + int rc; - rc = check_dev(dev); - if (rc < 0) + rc = vidioc_try_fmt_vid_cap(file, priv, f); + if (rc) return rc; - vidioc_try_fmt_vid_cap(file, priv, f); - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (!fmt) - return -EINVAL; - - if (videobuf_queue_is_busy(&fh->vb_vidq)) { + if (vb2_is_busy(&dev->vidq)) { dev_err(dev->dev, "%s: queue busy\n", __func__); return -EBUSY; } - if (dev->stream_on && !fh->stream_on) { - dev_err(dev->dev, - "%s: device in use by another fh\n", __func__); - return -EBUSY; - } - /* set new image size */ dev->width = f->fmt.pix.width; dev->height = f->fmt.pix.height; - dev->format = fmt; + dev->format = format_by_fourcc(f->fmt.pix.pixelformat); v4l2_fill_mbus_format(&format.format, &f->fmt.pix, MEDIA_BUS_FMT_FIXED); call_all(dev, pad, set_fmt, NULL, &format); @@ -1037,8 +918,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); *id = dev->norm; return 0; @@ -1046,21 +926,15 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); struct v4l2_subdev_format format = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; if (dev->norm == norm) return 0; - if (videobuf_queue_is_busy(&fh->vb_vidq)) + if (vb2_is_busy(&dev->vidq)) return -EBUSY; dev->norm = norm; @@ -1142,8 +1016,7 @@ void cx231xx_v4l2_create_entities(struct cx231xx *dev) int cx231xx_enum_input(struct file *file, void *priv, struct v4l2_input *i) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); u32 gen_stat; unsigned int n; int ret; @@ -1182,8 +1055,7 @@ int cx231xx_enum_input(struct file *file, void *priv, int cx231xx_g_input(struct file *file, void *priv, unsigned int *i) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); *i = dev->video_input; @@ -1192,14 +1064,9 @@ int cx231xx_g_input(struct file *file, void *priv, unsigned int *i) int cx231xx_s_input(struct file *file, void *priv, unsigned int i) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; + struct cx231xx *dev = video_drvdata(file); dev->mode_tv = 0; - rc = check_dev(dev); - if (rc < 0) - return rc; if (i >= MAX_CX231XX_INPUT) return -EINVAL; @@ -1221,13 +1088,7 @@ int cx231xx_s_input(struct file *file, void *priv, unsigned int i) int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; + struct cx231xx *dev = video_drvdata(file); if (0 != t->index) return -EINVAL; @@ -1245,27 +1106,15 @@ int cx231xx_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) int cx231xx_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - if (0 != t->index) return -EINVAL; -#if 0 - call_all(dev, tuner, s_tuner, t); -#endif return 0; } int cx231xx_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); if (f->tuner) return -EINVAL; @@ -1278,8 +1127,7 @@ int cx231xx_g_frequency(struct file *file, void *priv, int cx231xx_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); struct v4l2_frequency new_freq = *f; int rc; u32 if_frequency = 5400000; @@ -1288,10 +1136,6 @@ int cx231xx_s_frequency(struct file *file, void *priv, "Enter vidioc_s_frequency()f->frequency=%d;f->type=%d\n", f->frequency, f->type); - rc = check_dev(dev); - if (rc < 0) - return rc; - if (0 != f->tuner) return -EINVAL; @@ -1366,8 +1210,7 @@ int cx231xx_g_chip_info(struct file *file, void *fh, int cx231xx_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); int ret; u8 value[4] = { 0, 0, 0, 0 }; u32 data = 0; @@ -1425,8 +1268,7 @@ int cx231xx_g_register(struct file *file, void *priv, int cx231xx_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *reg) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); int ret; u8 data[4] = { 0, 0, 0, 0 }; @@ -1473,8 +1315,7 @@ int cx231xx_s_register(struct file *file, void *priv, static int vidioc_g_pixelaspect(struct file *file, void *priv, int type, struct v4l2_fract *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); bool is_50hz = dev->norm & V4L2_STD_625_50; if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -1489,8 +1330,7 @@ static int vidioc_g_pixelaspect(struct file *file, void *priv, static int vidioc_g_selection(struct file *file, void *priv, struct v4l2_selection *s) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1509,54 +1349,10 @@ static int vidioc_g_selection(struct file *file, void *priv, return 0; } -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - rc = res_get(fh); - - if (likely(rc >= 0)) - rc = videobuf_streamon(&fh->vb_vidq); - - call_all(dev, video, s_stream, 1); - - return rc; -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - if (type != fh->type) - return -EINVAL; - - cx25840_call(dev, video, s_stream, 0); - - videobuf_streamoff(&fh->vb_vidq); - res_free(fh); - - return 0; -} - int cx231xx_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); strscpy(cap->driver, "cx231xx", sizeof(cap->driver)); strscpy(cap->card, cx231xx_boards[dev->model].name, sizeof(cap->card)); @@ -1578,7 +1374,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (unlikely(f->index >= ARRAY_SIZE(format))) return -EINVAL; - strscpy(f->description, format[f->index].name, sizeof(f->description)); f->pixelformat = format[f->index].fourcc; return 0; @@ -1589,8 +1384,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); f->fmt.vbi.sampling_rate = 6750000 * 4; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; @@ -1612,8 +1406,7 @@ static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(file); f->fmt.vbi.sampling_rate = 6750000 * 4; f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; @@ -1636,77 +1429,16 @@ static int vidioc_try_fmt_vbi_cap(struct file *file, void *priv, static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - - if (dev->vbi_stream_on && !fh->stream_on) { - dev_err(dev->dev, - "%s device in use by another fh\n", __func__); - return -EBUSY; - } return vidioc_try_fmt_vbi_cap(file, priv, f); } -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *rb) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_reqbufs(&fh->vb_vidq, rb); -} - -static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_querybuf(&fh->vb_vidq, b); -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_qbuf(&fh->vb_vidq, b); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx231xx_fh *fh = priv; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); -} - /* ----------------------------------------------------------- */ /* RADIO ESPECIFIC IOCTLS */ /* ----------------------------------------------------------- */ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { - struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; + struct cx231xx *dev = video_drvdata(file); if (t->index) return -EINVAL; @@ -1719,7 +1451,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) } static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { - struct cx231xx *dev = ((struct cx231xx_fh *)priv)->dev; + struct cx231xx *dev = video_drvdata(file); if (t->index) return -EINVAL; @@ -1735,52 +1467,20 @@ static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner */ static int cx231xx_v4l2_open(struct file *filp) { - int radio = 0; struct video_device *vdev = video_devdata(filp); struct cx231xx *dev = video_drvdata(filp); - struct cx231xx_fh *fh; - enum v4l2_buf_type fh_type = 0; - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - break; - case VFL_TYPE_VBI: - fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; - break; - case VFL_TYPE_RADIO: - radio = 1; - break; - default: - return -EINVAL; - } - - cx231xx_videodbg("open dev=%s type=%s users=%d\n", - video_device_node_name(vdev), v4l2_type_names[fh_type], - dev->users); - -#if 0 - errCode = cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); - if (errCode < 0) { - dev_err(dev->dev, - "Device locked on digital mode. Can't open analog\n"); - return -EBUSY; - } -#endif + int ret; - fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL); - if (!fh) - return -ENOMEM; - if (mutex_lock_interruptible(&dev->lock)) { - kfree(fh); + if (mutex_lock_interruptible(&dev->lock)) return -ERESTARTSYS; + + ret = v4l2_fh_open(filp); + if (ret) { + mutex_unlock(&dev->lock); + return ret; } - fh->dev = dev; - fh->type = fh_type; - filp->private_data = fh; - v4l2_fh_init(&fh->fh, vdev); - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { + if (dev->users++ == 0) { /* Power up in Analog TV mode */ if (dev->board.external_av) cx231xx_set_power_mode(dev, @@ -1788,10 +1488,6 @@ static int cx231xx_v4l2_open(struct file *filp) else cx231xx_set_power_mode(dev, POLARIS_AVMODE_ANALOGT_TV); -#if 0 - cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); -#endif - /* set video alternate setting */ cx231xx_set_video_alternate(dev); @@ -1801,45 +1497,28 @@ static int cx231xx_v4l2_open(struct file *filp) /* device needs to be initialized before isoc transfer */ dev->video_input = dev->video_input > 2 ? 2 : dev->video_input; - } - if (radio) { + + if (vdev->vfl_type == VFL_TYPE_RADIO) { cx231xx_videodbg("video_open: setting radio device\n"); /* cx231xx_start_radio(dev); */ call_all(dev, tuner, s_radio); } - - dev->users++; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_video_qops, - NULL, &dev->video_mode.slock, - fh->type, V4L2_FIELD_INTERLACED, - sizeof(struct cx231xx_buffer), - fh, &dev->lock); - if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + if (vdev->vfl_type == VFL_TYPE_VBI) { /* Set the required alternate setting VBI interface works in Bulk mode only */ cx231xx_set_alt_setting(dev, INDEX_VANC, 0); - - videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, - NULL, &dev->vbi_mode.slock, - fh->type, V4L2_FIELD_SEQ_TB, - sizeof(struct cx231xx_buffer), - fh, &dev->lock); } mutex_unlock(&dev->lock); - v4l2_fh_add(&fh->fh); - return 0; } /* * cx231xx_realease_resources() * unregisters the v4l2,i2c and usb devices - * called when the device gets disconected or at module unload + * called when the device gets disconnected or at module unload */ void cx231xx_release_analog_resources(struct cx231xx *dev) { @@ -1873,68 +1552,12 @@ void cx231xx_release_analog_resources(struct cx231xx *dev) */ static int cx231xx_close(struct file *filp) { - struct cx231xx_fh *fh = filp->private_data; - struct cx231xx *dev = fh->dev; - - cx231xx_videodbg("users=%d\n", dev->users); - - cx231xx_videodbg("users=%d\n", dev->users); - if (res_check(fh)) - res_free(fh); - - /* - * To workaround error number=-71 on EP0 for VideoGrabber, - * need exclude following. - * FIXME: It is probably safe to remove most of these, as we're - * now avoiding the alternate setting for INDEX_VANC - */ - if (!dev->board.no_alt_vanc) - if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - videobuf_stop(&fh->vb_vidq); - videobuf_mmap_free(&fh->vb_vidq); - - /* the device is already disconnect, - free the remaining resources */ - if (dev->state & DEV_DISCONNECTED) { - if (atomic_read(&dev->devlist_count) > 0) { - cx231xx_release_resources(dev); - fh->dev = NULL; - return 0; - } - return 0; - } - - /* do this before setting alternate! */ - cx231xx_uninit_vbi_isoc(dev); - - /* set alternate 0 */ - if (!dev->vbi_or_sliced_cc_mode) - cx231xx_set_alt_setting(dev, INDEX_VANC, 0); - else - cx231xx_set_alt_setting(dev, INDEX_HANC, 0); - - v4l2_fh_del(&fh->fh); - v4l2_fh_exit(&fh->fh); - kfree(fh); - dev->users--; - wake_up_interruptible(&dev->open); - return 0; - } + struct cx231xx *dev = video_drvdata(filp); + struct video_device *vdev = video_devdata(filp); - v4l2_fh_del(&fh->fh); - dev->users--; - if (!dev->users) { - videobuf_stop(&fh->vb_vidq); - videobuf_mmap_free(&fh->vb_vidq); - - /* the device is already disconnect, - free the remaining resources */ - if (dev->state & DEV_DISCONNECTED) { - cx231xx_release_resources(dev); - fh->dev = NULL; - return 0; - } + _vb2_fop_release(filp, NULL); + if (--dev->users == 0) { /* Save some power by putting tuner to sleep */ call_all(dev, tuner, standby); @@ -1944,20 +1567,40 @@ static int cx231xx_close(struct file *filp) else cx231xx_uninit_bulk(dev); cx231xx_set_mode(dev, CX231XX_SUSPEND); + } + + /* + * To workaround error number=-71 on EP0 for VideoGrabber, + * need exclude following. + * FIXME: It is probably safe to remove most of these, as we're + * now avoiding the alternate setting for INDEX_VANC + */ + if (!dev->board.no_alt_vanc && vdev->vfl_type == VFL_TYPE_VBI) { + /* do this before setting alternate! */ + cx231xx_uninit_vbi_isoc(dev); /* set alternate 0 */ + if (!dev->vbi_or_sliced_cc_mode) + cx231xx_set_alt_setting(dev, INDEX_VANC, 0); + else + cx231xx_set_alt_setting(dev, INDEX_HANC, 0); + + wake_up_interruptible_nr(&dev->open, 1); + return 0; + } + + if (dev->users == 0) { + /* set alternate 0 */ cx231xx_set_alt_setting(dev, INDEX_VIDEO, 0); } - v4l2_fh_exit(&fh->fh); - kfree(fh); + wake_up_interruptible(&dev->open); return 0; } static int cx231xx_v4l2_close(struct file *filp) { - struct cx231xx_fh *fh = filp->private_data; - struct cx231xx *dev = fh->dev; + struct cx231xx *dev = video_drvdata(filp); int rc; mutex_lock(&dev->lock); @@ -1966,116 +1609,13 @@ static int cx231xx_v4l2_close(struct file *filp) return rc; } -/* - * cx231xx_v4l2_read() - * will allocate buffers when called for the first time - */ -static ssize_t -cx231xx_v4l2_read(struct file *filp, char __user *buf, size_t count, - loff_t *pos) -{ - struct cx231xx_fh *fh = filp->private_data; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) || - (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) { - rc = res_get(fh); - - if (unlikely(rc < 0)) - return rc; - - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - rc = videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, - filp->f_flags & O_NONBLOCK); - mutex_unlock(&dev->lock); - return rc; - } - return 0; -} - -/* - * cx231xx_v4l2_poll() - * will allocate buffers when called for the first time - */ -static __poll_t cx231xx_v4l2_poll(struct file *filp, poll_table *wait) -{ - __poll_t req_events = poll_requested_events(wait); - struct cx231xx_fh *fh = filp->private_data; - struct cx231xx *dev = fh->dev; - __poll_t res = 0; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return EPOLLERR; - - rc = res_get(fh); - - if (unlikely(rc < 0)) - return EPOLLERR; - - if (v4l2_event_pending(&fh->fh)) - res |= EPOLLPRI; - else - poll_wait(filp, &fh->fh.wait, wait); - - if (!(req_events & (EPOLLIN | EPOLLRDNORM))) - return res; - - if ((V4L2_BUF_TYPE_VIDEO_CAPTURE == fh->type) || - (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)) { - mutex_lock(&dev->lock); - res |= videobuf_poll_stream(filp, &fh->vb_vidq, wait); - mutex_unlock(&dev->lock); - return res; - } - return res | EPOLLERR; -} - -/* - * cx231xx_v4l2_mmap() - */ -static int cx231xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct cx231xx_fh *fh = filp->private_data; - struct cx231xx *dev = fh->dev; - int rc; - - rc = check_dev(dev); - if (rc < 0) - return rc; - - rc = res_get(fh); - - if (unlikely(rc < 0)) - return rc; - - if (mutex_lock_interruptible(&dev->lock)) - return -ERESTARTSYS; - rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); - mutex_unlock(&dev->lock); - - cx231xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", - (unsigned long)vma->vm_start, - (unsigned long)vma->vm_end - - (unsigned long)vma->vm_start, rc); - - return rc; -} - static const struct v4l2_file_operations cx231xx_v4l_fops = { .owner = THIS_MODULE, .open = cx231xx_v4l2_open, .release = cx231xx_v4l2_close, - .read = cx231xx_v4l2_read, - .poll = cx231xx_v4l2_poll, - .mmap = cx231xx_v4l2_mmap, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, .unlocked_ioctl = video_ioctl2, }; @@ -2090,17 +1630,17 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, .vidioc_g_pixelaspect = vidioc_g_pixelaspect, .vidioc_g_selection = vidioc_g_selection, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, .vidioc_s_std = vidioc_s_std, .vidioc_g_std = vidioc_g_std, .vidioc_enum_input = cx231xx_enum_input, .vidioc_g_input = cx231xx_g_input, .vidioc_s_input = cx231xx_s_input, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, .vidioc_g_tuner = cx231xx_g_tuner, .vidioc_s_tuner = cx231xx_s_tuner, .vidioc_g_frequency = cx231xx_g_frequency, @@ -2177,6 +1717,7 @@ static void cx231xx_vdev_init(struct cx231xx *dev, int cx231xx_register_analog_devices(struct cx231xx *dev) { + struct vb2_queue *q; int ret; dev_info(dev->dev, "v4l2 driver version %s\n", CX231XX_VERSION); @@ -2223,6 +1764,21 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev_err(dev->dev, "failed to initialize video media entity!\n"); #endif dev->vdev.ctrl_handler = &dev->ctrl_handler; + + q = &dev->vidq; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx231xx_buffer); + q->ops = &cx231xx_video_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 1; + q->lock = &dev->lock; + ret = vb2_queue_init(q); + if (ret) + return ret; + dev->vdev.queue = q; dev->vdev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; if (dev->tuner_type != TUNER_ABSENT) @@ -2256,6 +1812,21 @@ int cx231xx_register_analog_devices(struct cx231xx *dev) dev_err(dev->dev, "failed to initialize vbi media entity!\n"); #endif dev->vbi_dev.ctrl_handler = &dev->ctrl_handler; + + q = &dev->vbiq; + q->type = V4L2_BUF_TYPE_VBI_CAPTURE; + q->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF | VB2_READ; + q->drv_priv = dev; + q->buf_struct_size = sizeof(struct cx231xx_buffer); + q->ops = &cx231xx_vbi_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 1; + q->lock = &dev->lock; + ret = vb2_queue_init(q); + if (ret) + return ret; + dev->vbi_dev.queue = q; dev->vbi_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_VBI_CAPTURE; if (dev->tuner_type != TUNER_ABSENT) diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h index 3efa8ff93c1c..b32eab641793 100644 --- a/drivers/media/usb/cx231xx/cx231xx.h +++ b/drivers/media/usb/cx231xx/cx231xx.h @@ -20,7 +20,7 @@ #include <media/drv-intf/cx2341x.h> -#include <media/videobuf-vmalloc.h> +#include <media/videobuf2-vmalloc.h> #include <media/v4l2-device.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-fh.h> @@ -121,7 +121,6 @@ #define CX23417_RESET 9 struct cx23417_fmt { - char *name; u32 fourcc; /* v4l2 format id */ int depth; int flags; @@ -224,8 +223,8 @@ struct cx231xx_fmt { /* buffer for one video frame */ struct cx231xx_buffer { /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - + struct vb2_v4l2_buffer vb; + struct list_head list; struct list_head frame; int top_field; int receiving; @@ -238,7 +237,6 @@ enum ps_package_head { struct cx231xx_dmaqueue { struct list_head active; - struct list_head queued; wait_queue_head_t wq; @@ -252,6 +250,7 @@ struct cx231xx_dmaqueue { u32 lines_completed; u8 field1_done; u32 lines_per_field; + u32 sequence; /*Mpeg2 control buffer*/ u8 *p_left_data; @@ -428,23 +427,6 @@ struct cx231xx_audio { struct cx231xx; -struct cx231xx_fh { - struct v4l2_fh fh; - struct cx231xx *dev; - unsigned int stream_on:1; /* Locks streams */ - enum v4l2_buf_type type; - - struct videobuf_queue vb_vidq; - - /* vbi capture */ - struct videobuf_queue vidq; - struct videobuf_queue vbiq; - - /* MPEG Encoder specifics ONLY */ - - atomic_t v4l_reading; -}; - /*****************************************************************/ /* set/get i2c */ /* 00--1Mb/s, 01-400kb/s, 10--100kb/s, 11--5Mb/s */ @@ -635,6 +617,7 @@ struct cx231xx { int width; /* current frame width */ int height; /* current frame height */ int interlaced; /* 1=interlace fields, 0=just top fields */ + unsigned int size; struct cx231xx_audio adev; @@ -658,6 +641,9 @@ struct cx231xx { struct media_pad input_pad[MAX_CX231XX_INPUT]; #endif + struct vb2_queue vidq; + struct vb2_queue vbiq; + unsigned char eedata[256]; struct cx231xx_video_mode video_mode; @@ -718,6 +704,7 @@ struct cx231xx { u8 USE_ISO; struct cx231xx_tvnorm encodernorm; struct cx231xx_tsport ts1, ts2; + struct vb2_queue mpegq; struct video_device v4l_device; atomic_t v4l_reader_count; u32 freq; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index 3afd18733614..b1f69c11c839 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -208,8 +208,8 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type, request_module("%s", board_info.type); /* register I2C device */ - client = i2c_new_device(adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(adapter, &board_info); + if (!i2c_client_has_driver(client)) { ret = -ENODEV; goto err; } @@ -1197,6 +1197,15 @@ err: return ret; } +/* + * The I2C speed register is calculated with: + * I2C speed register = (1000000000 / (24.4 * 16 * I2C_speed)) + * + * The default speed register for it930x is 7, with means a + * speed of ~366 kbps + */ +#define I2C_SPEED_366K 7 + static int it930x_frontend_attach(struct dvb_usb_adapter *adap) { struct state *state = adap_to_priv(adap); @@ -1208,13 +1217,13 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap) dev_dbg(&intf->dev, "adap->id=%d\n", adap->id); - /* I2C master bus 2 clock speed 300k */ - ret = af9035_wr_reg(d, 0x00f6a7, 0x07); + /* I2C master bus 2 clock speed 366k */ + ret = af9035_wr_reg(d, 0x00f6a7, I2C_SPEED_366K); if (ret < 0) goto err; - /* I2C master bus 1,3 clock speed 300k */ - ret = af9035_wr_reg(d, 0x00f103, 0x07); + /* I2C master bus 1,3 clock speed 366k */ + ret = af9035_wr_reg(d, 0x00f103, I2C_SPEED_366K); if (ret < 0) goto err; @@ -1610,6 +1619,27 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap) memset(&si2157_config, 0, sizeof(si2157_config)); si2157_config.fe = adap->fe[0]; + + /* + * HACK: The Logilink VG0022A and TerraTec TC2 Stick have + * a bug: when the si2157 firmware that came with the device + * is replaced by a new one, the I2C transfers to the tuner + * will return just 0xff. + * + * Probably, the vendor firmware has some patch specifically + * designed for this device. So, we can't replace by the + * generic firmware. The right solution would be to extract + * the si2157 firmware from the original driver and ask the + * driver to load the specifically designed firmware, but, + * while we don't have that, the next best solution is to just + * keep the original firmware at the device. + */ + if ((le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_DEXATEK && + le16_to_cpu(d->udev->descriptor.idProduct) == 0x0100) || + (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_TERRATEC && + le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_TERRATEC_CINERGY_TC2_STICK)) + si2157_config.dont_load_firmware = true; + si2157_config.if_port = it930x_addresses_table[state->it930x_addresses].tuner_if_port; ret = af9035_add_i2c_dev(d, "si2157", it930x_addresses_table[state->it930x_addresses].tuner_i2c_addr, @@ -2121,6 +2151,10 @@ static const struct usb_device_id af9035_id_table[] = { &it930x_props, "ITE 9303 Generic", NULL) }, { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD310, &it930x_props, "AVerMedia TD310 DVB-T2", NULL) }, + { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x0100, + &it930x_props, "Logilink VG0022A", NULL) }, + { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_TC2_STICK, + &it930x_props, "TerraTec Cinergy TC2 Stick", NULL) }, { } }; MODULE_DEVICE_TABLE(usb, af9035_id_table); diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index fb6d99dea31a..0514e87405b6 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -649,8 +649,8 @@ static int anysee_add_i2c_dev(struct dvb_usb_device *d, const char *type, request_module("%s", board_info.type); /* register I2C device */ - client = i2c_new_device(adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(adapter, &board_info); + if (!i2c_client_has_driver(client)) { ret = -ENODEV; goto err; } diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index b874a49ececf..52bcc2d2efe5 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -121,6 +121,7 @@ struct dvb_usb_driver_info { * @interval: time in ms between two queries * @driver_type: used to point if a device supports raw mode * @bulk_mode: device supports bulk mode for rc (disable polling mode) + * @timeout: set to length of last space before raw IR goes idle */ struct dvb_usb_rc { const char *map_name; @@ -130,6 +131,7 @@ struct dvb_usb_rc { unsigned int interval; enum rc_driver_type driver_type; bool bulk_mode; + int timeout; }; /** diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index e5e056bf9dfa..f1c79f351ec8 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -150,6 +150,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d) dev->map_name = d->rc.map_name; dev->allowed_protocols = d->rc.allowed_protos; dev->change_protocol = d->rc.change_protocol; + dev->timeout = d->rc.timeout; dev->priv = d; ret = rc_register_device(dev); diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c index 8610487f2d72..356fd8e66834 100644 --- a/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -22,7 +22,6 @@ MODULE_PARM_DESC(disable_rc, "Disable inbuilt IR receiver."); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct dvbsky_state { - struct mutex stream_mutex; u8 ibuf[DVBSKY_BUF_LEN]; u8 obuf[DVBSKY_BUF_LEN]; u8 last_lock; @@ -60,17 +59,19 @@ static int dvbsky_usb_generic_rw(struct dvb_usb_device *d, static int dvbsky_stream_ctrl(struct dvb_usb_device *d, u8 onoff) { struct dvbsky_state *state = d_to_priv(d); + static const u8 obuf_pre[3] = { 0x37, 0, 0 }; + static const u8 obuf_post[3] = { 0x36, 3, 0 }; int ret; - u8 obuf_pre[3] = { 0x37, 0, 0 }; - u8 obuf_post[3] = { 0x36, 3, 0 }; - mutex_lock(&state->stream_mutex); - ret = dvbsky_usb_generic_rw(d, obuf_pre, 3, NULL, 0); + mutex_lock(&d->usb_mutex); + memcpy(state->obuf, obuf_pre, 3); + ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3); if (!ret && onoff) { msleep(20); - ret = dvbsky_usb_generic_rw(d, obuf_post, 3, NULL, 0); + memcpy(state->obuf, obuf_post, 3); + ret = dvb_usbv2_generic_write_locked(d, state->obuf, 3); } - mutex_unlock(&state->stream_mutex); + mutex_unlock(&d->usb_mutex); return ret; } @@ -540,6 +541,8 @@ static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap) si2168_config.i2c_adapter = &i2c_adapter; si2168_config.fe = &adap->fe[0]; si2168_config.ts_mode = SI2168_TS_PARALLEL; + if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230C2) + si2168_config.ts_mode |= SI2168_TS_CLK_MANUAL; si2168_config.ts_clock_inv = 1; state->i2c_client_demod = dvb_module_probe("si2168", NULL, @@ -550,11 +553,19 @@ static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap) /* attach tuner */ si2157_config.fe = adap->fe[0]; - si2157_config.if_port = 0; - - state->i2c_client_tuner = dvb_module_probe("si2157", "si2141", - i2c_adapter, - 0x60, &si2157_config); + if (le16_to_cpu(d->udev->descriptor.idProduct) == USB_PID_MYGICA_T230) { + si2157_config.if_port = 1; + state->i2c_client_tuner = dvb_module_probe("si2157", NULL, + i2c_adapter, + 0x60, + &si2157_config); + } else { + si2157_config.if_port = 0; + state->i2c_client_tuner = dvb_module_probe("si2157", "si2141", + i2c_adapter, + 0x60, + &si2157_config); + } if (!state->i2c_client_tuner) { dvb_module_release(state->i2c_client_demod); return -ENODEV; @@ -581,17 +592,7 @@ static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name) static int dvbsky_init(struct dvb_usb_device *d) { struct dvbsky_state *state = d_to_priv(d); - - /* use default interface */ - /* - ret = usb_set_interface(d->udev, 0, 0); - if (ret) - return ret; - */ - mutex_init(&state->stream_mutex); - state->last_lock = 0; - return 0; } @@ -776,9 +777,18 @@ static const struct usb_device_id dvbsky_id_table[] = { { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4, &dvbsky_s960_props, "Terratec Cinergy S2 Rev.4", RC_MAP_DVBSKY) }, + { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230, + &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230", + RC_MAP_TOTAL_MEDIA_IN_HAND_02) }, { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C, &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C", RC_MAP_TOTAL_MEDIA_IN_HAND_02) }, + { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C_LITE, + &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C Lite", + NULL) }, + { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2, + &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C v2", + RC_MAP_TOTAL_MEDIA_IN_HAND_02) }, { } }; MODULE_DEVICE_TABLE(usb, dvbsky_id_table); diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c index 0c1fef118be4..e30305876840 100644 --- a/drivers/media/usb/dvb-usb-v2/ec168.c +++ b/drivers/media/usb/dvb-usb-v2/ec168.c @@ -309,7 +309,7 @@ static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff) /* DVB USB Driver stuff */ /* bInterfaceNumber 0 is HID * bInterfaceNumber 1 is DVB-T */ -static struct dvb_usb_device_properties ec168_props = { +static const struct dvb_usb_device_properties ec168_props = { .driver_name = KBUILD_MODNAME, .owner = THIS_MODULE, .adapter_nr = adapter_nr, diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c index b784d9da1a82..19217dcf20f1 100644 --- a/drivers/media/usb/dvb-usb-v2/gl861.c +++ b/drivers/media/usb/dvb-usb-v2/gl861.c @@ -5,7 +5,7 @@ */ #include <linux/string.h> -#include "gl861.h" +#include "dvb_usb.h" #include "zl10353.h" #include "qt1010.h" @@ -14,93 +14,157 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u16 index; - u16 value = addr << (8 + 1); - int wo = (rbuf == NULL || rlen == 0); /* write-only */ - u8 req, type; - u8 *buf; - int ret; +struct gl861 { + /* USB control message buffer */ + u8 buf[16]; - if (wo) { - req = GL861_REQ_I2C_WRITE; - type = GL861_WRITE; - buf = kmemdup(wbuf, wlen, GFP_KERNEL); - } else { /* rw */ - req = GL861_REQ_I2C_READ; - type = GL861_READ; - buf = kmalloc(rlen, GFP_KERNEL); - } - if (!buf) - return -ENOMEM; + struct i2c_adapter *demod_sub_i2c; + struct i2c_client *i2c_client_demod; + struct i2c_client *i2c_client_tuner; +}; - switch (wlen) { - case 1: - index = wbuf[0]; +#define CMD_WRITE_SHORT 0x01 +#define CMD_READ 0x02 +#define CMD_WRITE 0x03 + +static int gl861_ctrl_msg(struct dvb_usb_device *d, u8 request, u16 value, + u16 index, void *data, u16 size) +{ + struct gl861 *ctx = d_to_priv(d); + struct usb_interface *intf = d->intf; + int ret; + unsigned int pipe; + u8 requesttype; + + mutex_lock(&d->usb_mutex); + + switch (request) { + case CMD_WRITE: + memcpy(ctx->buf, data, size); + /* Fall through */ + case CMD_WRITE_SHORT: + pipe = usb_sndctrlpipe(d->udev, 0); + requesttype = USB_TYPE_VENDOR | USB_DIR_OUT; break; - case 2: - index = wbuf[0]; - value = value + wbuf[1]; + case CMD_READ: + pipe = usb_rcvctrlpipe(d->udev, 0); + requesttype = USB_TYPE_VENDOR | USB_DIR_IN; break; default: - dev_err(&d->udev->dev, "%s: wlen=%d, aborting\n", - KBUILD_MODNAME, wlen); - kfree(buf); - return -EINVAL; + ret = -EINVAL; + goto err_mutex_unlock; } - usleep_range(1000, 2000); /* avoid I2C errors */ + ret = usb_control_msg(d->udev, pipe, request, requesttype, value, + index, ctx->buf, size, 200); + dev_dbg(&intf->dev, "%d | %02x %02x %*ph %*ph %*ph %s %*ph\n", + ret, requesttype, request, 2, &value, 2, &index, 2, &size, + (requesttype & USB_DIR_IN) ? "<<<" : ">>>", size, ctx->buf); + if (ret < 0) + goto err_mutex_unlock; - ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, - value, index, buf, rlen, 2000); + if (request == CMD_READ) + memcpy(data, ctx->buf, size); - if (!wo && ret > 0) - memcpy(rbuf, buf, rlen); + usleep_range(1000, 2000); /* Avoid I2C errors */ - kfree(buf); + mutex_unlock(&d->usb_mutex); + + return 0; + +err_mutex_unlock: + mutex_unlock(&d->usb_mutex); + dev_dbg(&intf->dev, "failed %d\n", ret); return ret; } -/* I2C */ -static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) +static int gl861_short_write(struct dvb_usb_device *d, u8 addr, u8 reg, u8 val) +{ + return gl861_ctrl_msg(d, CMD_WRITE_SHORT, + (addr << 9) | val, reg, NULL, 0); +} + +static int gl861_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; + struct usb_interface *intf = d->intf; + struct gl861 *ctx = d_to_priv(d); + int ret; + u8 request, *data; + u16 value, index, size; + + /* XXX: I2C adapter maximum data lengths are not tested */ + if (num == 1 && !(msg[0].flags & I2C_M_RD)) { + /* I2C write */ + if (msg[0].len < 2 || msg[0].len > sizeof(ctx->buf)) { + ret = -EOPNOTSUPP; + goto err; + } + + value = (msg[0].addr << 1) << 8; + index = msg[0].buf[0]; + + if (msg[0].len == 2) { + request = CMD_WRITE_SHORT; + value |= msg[0].buf[1]; + size = 0; + data = NULL; + } else { + request = CMD_WRITE; + size = msg[0].len - 1; + data = &msg[0].buf[1]; + } + + ret = gl861_ctrl_msg(d, request, value, index, data, size); + } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && + (msg[1].flags & I2C_M_RD)) { + /* I2C write + read */ + if (msg[0].len > 1 || msg[1].len > sizeof(ctx->buf)) { + ret = -EOPNOTSUPP; + goto err; + } - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) - break; - i++; - } else - if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) - break; + value = (msg[0].addr << 1) << 8; + index = msg[0].buf[0]; + request = CMD_READ; + + ret = gl861_ctrl_msg(d, request, value, index, + msg[1].buf, msg[1].len); + } else if (num == 1 && (msg[0].flags & I2C_M_RD)) { + /* I2C read */ + if (msg[0].len > sizeof(ctx->buf)) { + ret = -EOPNOTSUPP; + goto err; + } + value = (msg[0].addr << 1) << 8; + index = 0x0100; + request = CMD_READ; + + ret = gl861_ctrl_msg(d, request, value, index, + msg[0].buf, msg[0].len); + } else { + /* Unsupported I2C message */ + dev_dbg(&intf->dev, "unknown i2c msg, num %u\n", num); + ret = -EOPNOTSUPP; } + if (ret) + goto err; - mutex_unlock(&d->i2c_mutex); - return i; + return num; +err: + dev_dbg(&intf->dev, "failed %d\n", ret); + return ret; } -static u32 gl861_i2c_func(struct i2c_adapter *adapter) +static u32 gl861_i2c_functionality(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; } static struct i2c_algorithm gl861_i2c_algo = { - .master_xfer = gl861_i2c_xfer, - .functionality = gl861_i2c_func, + .master_xfer = gl861_i2c_master_xfer, + .functionality = gl861_i2c_functionality, }; /* Callbacks for DVB USB */ @@ -149,6 +213,8 @@ static struct dvb_usb_device_properties gl861_props = { .owner = THIS_MODULE, .adapter_nr = adapter_nr, + .size_of_priv = sizeof(struct gl861), + .i2c_algo = &gl861_i2c_algo, .frontend_attach = gl861_frontend_attach, .tuner_attach = gl861_tuner_attach, @@ -166,14 +232,6 @@ static struct dvb_usb_device_properties gl861_props = { /* * For Friio */ - -struct friio_priv { - struct i2c_adapter *demod_sub_i2c; - struct i2c_client *i2c_client_demod; - struct i2c_client *i2c_client_tuner; - struct i2c_adapter tuner_adap; -}; - struct friio_config { struct i2c_board_info demod_info; struct tc90522_config demod_cfg; @@ -184,132 +242,10 @@ struct friio_config { static const struct friio_config friio_config = { .demod_info = { I2C_BOARD_INFO(TC90522_I2C_DEV_TER, 0x18), }, + .demod_cfg = { .split_tuner_read_i2c = true, }, .tuner_info = { I2C_BOARD_INFO("tua6034_friio", 0x60), }, }; -/* For another type of I2C: - * message sent by a USB control-read/write transaction with data stage. - * Used in init/config of Friio. - */ -static int -gl861_i2c_write_ex(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen) -{ - u8 *buf; - int ret; - - buf = kmemdup(wbuf, wlen, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), - GL861_REQ_I2C_RAW, GL861_WRITE, - addr << (8 + 1), 0x0100, buf, wlen, 2000); - kfree(buf); - return ret; -} - -static int -gl861_i2c_read_ex(struct dvb_usb_device *d, u8 addr, u8 *rbuf, u16 rlen) -{ - u8 *buf; - int ret; - - buf = kmalloc(rlen, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), - GL861_REQ_I2C_READ, GL861_READ, - addr << (8 + 1), 0x0100, buf, rlen, 2000); - if (ret > 0 && rlen > 0) - memcpy(buf, rbuf, rlen); - kfree(buf); - return ret; -} - -/* For I2C transactions to the tuner of Friio (dvb_pll). - * - * Friio uses irregular USB encapsulation for tuner i2c transactions: - * write transacions are encapsulated with a different USB 'request' value. - * - * Although all transactions are sent via the demod(tc90522) - * and the demod provides an i2c adapter for them, it cannot be used in Friio - * since it assumes using the same parent adapter with the demod, - * which does not use the request value and uses same one for both read/write. - * So we define a dedicated i2c adapter here. - */ - -static int -friio_i2c_tuner_read(struct dvb_usb_device *d, struct i2c_msg *msg) -{ - struct friio_priv *priv; - u8 addr; - - priv = d_to_priv(d); - addr = priv->i2c_client_demod->addr; - return gl861_i2c_read_ex(d, addr, msg->buf, msg->len); -} - -static int -friio_i2c_tuner_write(struct dvb_usb_device *d, struct i2c_msg *msg) -{ - u8 *buf; - int ret; - struct friio_priv *priv; - - priv = d_to_priv(d); - - if (msg->len < 1) - return -EINVAL; - - buf = kmalloc(msg->len + 1, GFP_KERNEL); - if (!buf) - return -ENOMEM; - buf[0] = msg->addr << 1; - memcpy(buf + 1, msg->buf, msg->len); - - ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), - GL861_REQ_I2C_RAW, GL861_WRITE, - priv->i2c_client_demod->addr << (8 + 1), - 0xFE, buf, msg->len + 1, 2000); - kfree(buf); - return ret; -} - -static int friio_tuner_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - int ret; - - if (msg[i].flags & I2C_M_RD) - ret = friio_i2c_tuner_read(d, &msg[i]); - else - ret = friio_i2c_tuner_write(d, &msg[i]); - - if (ret < 0) - break; - - usleep_range(1000, 2000); /* avoid I2C errors */ - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static struct i2c_algorithm friio_tuner_i2c_algo = { - .master_xfer = friio_tuner_i2c_xfer, - .functionality = gl861_i2c_func, -}; /* GPIO control in Friio */ @@ -353,7 +289,7 @@ static int friio_ext_ctl(struct dvb_usb_device *d, ret += i2c_transfer(&d->i2c_adap, &msg, 1); /* send 32bit(satur, R, G, B) data in serial */ - mask = 1 << 31; + mask = 1UL << 31; for (i = 0; i < 32; i++) { buf[1] = power | FRIIO_CTL_STROBE; if (sat_color & mask) @@ -377,9 +313,11 @@ static int friio_ext_ctl(struct dvb_usb_device *d, /* init/config of gl861 for Friio */ /* NOTE: * This function cannot be moved to friio_init()/dvb_usbv2_init(), - * because the init defined here must be done before any activities like I2C, + * because the init defined here includes a whole device reset, + * it must be run early before any activities like I2C, * but friio_init() is called by dvb-usbv2 after {_frontend, _tuner}_attach(), * where I2C communication is used. + * In addition, this reset is required in reset_resume() as well. * Thus this function is set to be called from _power_ctl(). * * Since it will be called on the early init stage @@ -389,7 +327,7 @@ static int friio_ext_ctl(struct dvb_usb_device *d, static int friio_reset(struct dvb_usb_device *d) { int i, ret; - u8 wbuf[2], rbuf[2]; + u8 wbuf[1], rbuf[2]; static const u8 friio_init_cmds[][2] = { {0x33, 0x08}, {0x37, 0x40}, {0x3a, 0x1f}, {0x3b, 0xff}, @@ -401,16 +339,12 @@ static int friio_reset(struct dvb_usb_device *d) if (ret < 0) return ret; - wbuf[0] = 0x11; - wbuf[1] = 0x02; - ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0); + ret = gl861_short_write(d, 0x00, 0x11, 0x02); if (ret < 0) return ret; usleep_range(2000, 3000); - wbuf[0] = 0x11; - wbuf[1] = 0x00; - ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0); + ret = gl861_short_write(d, 0x00, 0x11, 0x00); if (ret < 0) return ret; @@ -420,14 +354,13 @@ static int friio_reset(struct dvb_usb_device *d) */ usleep_range(1000, 2000); - wbuf[0] = 0x03; - wbuf[1] = 0x80; - ret = gl861_i2c_write_ex(d, 0x09, wbuf, 2); + wbuf[0] = 0x80; + ret = gl861_ctrl_msg(d, CMD_WRITE, 0x09 << 9, 0x03, wbuf, 1); if (ret < 0) return ret; usleep_range(2000, 3000); - ret = gl861_i2c_read_ex(d, 0x09, rbuf, 2); + ret = gl861_ctrl_msg(d, CMD_READ, 0x09 << 9, 0x0100, rbuf, 2); if (ret < 0) return ret; if (rbuf[0] != 0xff || rbuf[1] != 0xff) @@ -435,38 +368,33 @@ static int friio_reset(struct dvb_usb_device *d) usleep_range(1000, 2000); - ret = gl861_i2c_write_ex(d, 0x48, wbuf, 2); + wbuf[0] = 0x80; + ret = gl861_ctrl_msg(d, CMD_WRITE, 0x48 << 9, 0x03, wbuf, 1); if (ret < 0) return ret; usleep_range(2000, 3000); - ret = gl861_i2c_read_ex(d, 0x48, rbuf, 2); + ret = gl861_ctrl_msg(d, CMD_READ, 0x48 << 9, 0x0100, rbuf, 2); if (ret < 0) return ret; if (rbuf[0] != 0xff || rbuf[1] != 0xff) return -ENODEV; - wbuf[0] = 0x30; - wbuf[1] = 0x04; - ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0); + ret = gl861_short_write(d, 0x00, 0x30, 0x04); if (ret < 0) return ret; - wbuf[0] = 0x00; - wbuf[1] = 0x01; - ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0); + ret = gl861_short_write(d, 0x00, 0x00, 0x01); if (ret < 0) return ret; - wbuf[0] = 0x06; - wbuf[1] = 0x0f; - ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0); + ret = gl861_short_write(d, 0x00, 0x06, 0x0f); if (ret < 0) return ret; for (i = 0; i < ARRAY_SIZE(friio_init_cmds); i++) { - ret = gl861_i2c_msg(d, 0x00, (u8 *)friio_init_cmds[i], 2, - NULL, 0); + ret = gl861_short_write(d, 0x00, friio_init_cmds[i][0], + friio_init_cmds[i][1]); if (ret < 0) return ret; } @@ -488,9 +416,10 @@ static int friio_frontend_attach(struct dvb_usb_adapter *adap) struct dvb_usb_device *d; struct tc90522_config cfg; struct i2c_client *cl; - struct friio_priv *priv; + struct gl861 *priv; info = &friio_config.demod_info; + cfg = friio_config.demod_cfg; d = adap_to_d(adap); cl = dvb_module_probe("tc90522", info->type, &d->i2c_adap, info->addr, &cfg); @@ -498,25 +427,17 @@ static int friio_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; adap->fe[0] = cfg.fe; - /* ignore cfg.tuner_i2c and create new one */ priv = adap_to_priv(adap); priv->i2c_client_demod = cl; - priv->tuner_adap.algo = &friio_tuner_i2c_algo; - priv->tuner_adap.dev.parent = &d->udev->dev; - strscpy(priv->tuner_adap.name, d->name, sizeof(priv->tuner_adap.name)); - strlcat(priv->tuner_adap.name, "-tuner", sizeof(priv->tuner_adap.name)); - priv->demod_sub_i2c = &priv->tuner_adap; - i2c_set_adapdata(&priv->tuner_adap, d); - - return i2c_add_adapter(&priv->tuner_adap); + priv->demod_sub_i2c = cfg.tuner_i2c; + return 0; } static int friio_frontend_detach(struct dvb_usb_adapter *adap) { - struct friio_priv *priv; + struct gl861 *priv; priv = adap_to_priv(adap); - i2c_del_adapter(&priv->tuner_adap); dvb_module_release(priv->i2c_client_demod); return 0; } @@ -526,7 +447,7 @@ static int friio_tuner_attach(struct dvb_usb_adapter *adap) const struct i2c_board_info *info; struct dvb_pll_config cfg; struct i2c_client *cl; - struct friio_priv *priv; + struct gl861 *priv; priv = adap_to_priv(adap); info = &friio_config.tuner_info; @@ -543,7 +464,7 @@ static int friio_tuner_attach(struct dvb_usb_adapter *adap) static int friio_tuner_detach(struct dvb_usb_adapter *adap) { - struct friio_priv *priv; + struct gl861 *priv; priv = adap_to_priv(adap); dvb_module_release(priv->i2c_client_tuner); @@ -554,7 +475,7 @@ static int friio_init(struct dvb_usb_device *d) { int i; int ret; - struct friio_priv *priv; + struct gl861 *priv; static const u8 demod_init[][2] = { {0x01, 0x40}, {0x04, 0x38}, {0x05, 0x40}, {0x07, 0x40}, @@ -606,7 +527,7 @@ static struct dvb_usb_device_properties friio_props = { .owner = THIS_MODULE, .adapter_nr = adapter_nr, - .size_of_priv = sizeof(struct friio_priv), + .size_of_priv = sizeof(struct gl861), .i2c_algo = &gl861_i2c_algo, .power_ctrl = friio_power_ctrl, diff --git a/drivers/media/usb/dvb-usb-v2/gl861.h b/drivers/media/usb/dvb-usb-v2/gl861.h deleted file mode 100644 index 02c00e10748a..000000000000 --- a/drivers/media/usb/dvb-usb-v2/gl861.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _DVB_USB_GL861_H_ -#define _DVB_USB_GL861_H_ - -#include "dvb_usb.h" - -#define GL861_WRITE 0x40 -#define GL861_READ 0xc0 - -#define GL861_REQ_I2C_WRITE 0x01 -#define GL861_REQ_I2C_READ 0x02 -#define GL861_REQ_I2C_RAW 0x03 - -#endif diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 1a36bda28542..c6881a1b3232 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -697,8 +697,8 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x10; board_info.platform_data = pdata; request_module("%s", board_info.type); - client = i2c_new_device(&d->i2c_adap, &board_info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(&d->i2c_adap, &board_info); + if (!i2c_client_has_driver(client)) { ret = -ENODEV; goto err; } @@ -918,8 +918,8 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x10; board_info.platform_data = pdata; request_module("%s", board_info.type); - client = i2c_new_device(&d->i2c_adap, &board_info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(&d->i2c_adap, &board_info); + if (!i2c_client_has_driver(client)) { ret = -ENODEV; goto err; } @@ -960,8 +960,8 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) info.addr = 0x18; info.platform_data = &mn88472_config; request_module(info.type); - client = i2c_new_device(&d->i2c_adap, &info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(&d->i2c_adap, &info); + if (!i2c_client_has_driver(client)) { dev->slave_demod = SLAVE_DEMOD_NONE; goto err_slave_demod_failed; } @@ -982,8 +982,8 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) info.addr = 0x18; info.platform_data = &mn88473_config; request_module(info.type); - client = i2c_new_device(&d->i2c_adap, &info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(&d->i2c_adap, &info); + if (!i2c_client_has_driver(client)) { dev->slave_demod = SLAVE_DEMOD_NONE; goto err_slave_demod_failed; } @@ -1025,8 +1025,8 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) info.addr = 0x64; info.platform_data = &si2168_config; request_module(info.type); - client = i2c_new_device(&d->i2c_adap, &info); - if (client == NULL || client->dev.driver == NULL) { + client = i2c_new_client_device(&d->i2c_adap, &info); + if (!i2c_client_has_driver(client)) { dev->slave_demod = SLAVE_DEMOD_NONE; goto err_slave_demod_failed; } @@ -1217,8 +1217,9 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) info.platform_data = &e4000_config; request_module(info.type); - client = i2c_new_device(dev->demod_i2c_adapter, &info); - if (client == NULL || client->dev.driver == NULL) + client = i2c_new_client_device(dev->demod_i2c_adapter, + &info); + if (!i2c_client_has_driver(client)) break; if (!try_module_get(client->dev.driver->owner)) { @@ -1240,9 +1241,9 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x56; board_info.platform_data = &fc2580_pdata; request_module("fc2580"); - client = i2c_new_device(dev->demod_i2c_adapter, - &board_info); - if (client == NULL || client->dev.driver == NULL) + client = i2c_new_client_device(dev->demod_i2c_adapter, + &board_info); + if (!i2c_client_has_driver(client)) break; if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); @@ -1271,8 +1272,9 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x60; board_info.platform_data = &tua9001_pdata; request_module("tua9001"); - client = i2c_new_device(dev->demod_i2c_adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) + client = i2c_new_client_device(dev->demod_i2c_adapter, + &board_info); + if (!i2c_client_has_driver(client)) break; if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); @@ -1316,8 +1318,8 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap) info.addr = 0x60; info.platform_data = &si2157_config; request_module(info.type); - client = i2c_new_device(&d->i2c_adap, &info); - if (client == NULL || client->dev.driver == NULL) + client = i2c_new_client_device(&d->i2c_adap, &info); + if (!i2c_client_has_driver(client)) break; if (!try_module_get(client->dev.driver->owner)) { @@ -1781,7 +1783,6 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d) } /* 'flush'Â ir_raw_event_store_with_filter() */ - ir_raw_event_set_idle(d->rc_dev, true); ir_raw_event_handle(d->rc_dev); exit: return ret; @@ -1804,6 +1805,8 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d, rc->driver_type = RC_DRIVER_IR_RAW; rc->query = rtl2832u_rc_query; rc->interval = 200; + /* we program idle len to 0xc0, set timeout to one less */ + rc->timeout = 0xbf * 50800; return 0; } @@ -1954,10 +1957,13 @@ static const struct usb_device_id rtl28xxu_id_table[] = { &rtl28xxu_props, "Sveon STV27", NULL) }, { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TURBOX_DTT_2000, &rtl28xxu_props, "TURBO-X Pure TV Tuner DTT-2000", NULL) }, + { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_PROLECTRIX_DV107669, + &rtl28xxu_props, "PROlectrix DV107669", NULL) }, /* RTL2832P devices: */ { DVB_USB_DEVICE(USB_VID_HANFTEK, 0x0131, - &rtl28xxu_props, "Astrometa DVB-T2", NULL) }, + &rtl28xxu_props, "Astrometa DVB-T2", + RC_MAP_ASTROMETA_T2HYBRID) }, { DVB_USB_DEVICE(0x5654, 0xca42, &rtl28xxu_props, "GoTView MasterHD 3", NULL) }, { } diff --git a/drivers/media/usb/dvb-usb-v2/zd1301.c b/drivers/media/usb/dvb-usb-v2/zd1301.c index 63b66b207b64..ba2c1b0d3989 100644 --- a/drivers/media/usb/dvb-usb-v2/zd1301.c +++ b/drivers/media/usb/dvb-usb-v2/zd1301.c @@ -172,8 +172,8 @@ static int zd1301_frontend_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x60; board_info.platform_data = &dev->mt2060_pdata; request_module("%s", "mt2060"); - client = i2c_new_device(adapter, &board_info); - if (!client || !client->dev.driver) { + client = i2c_new_client_device(adapter, &board_info); + if (!i2c_client_has_driver(client)) { ret = -ENODEV; goto err_module_put_demod; } diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c index 02697d86e8c1..89b4b5d84cdf 100644 --- a/drivers/media/usb/dvb-usb/af9005.c +++ b/drivers/media/usb/dvb-usb/af9005.c @@ -554,7 +554,7 @@ static int af9005_boot_packet(struct usb_device *udev, int type, u8 *reply, u8 *buf, int size) { u16 checksum; - int act_len, i, ret; + int act_len = 0, i, ret; memset(buf, 0, size); buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); @@ -976,8 +976,9 @@ static int af9005_identify_state(struct usb_device *udev, else if (reply == 0x02) *cold = 0; else - return -EIO; - deb_info("Identify state cold = %d\n", *cold); + ret = -EIO; + if (!ret) + deb_info("Identify state cold = %d\n", *cold); err: kfree(buf); diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index bac0778f7def..c421b603be44 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -54,9 +54,6 @@ MODULE_PARM_DESC(debug, "set debugging level (see cxusb.h)." DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, CXUSB_DBG_MISC, args) -#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, CXUSB_DBG_I2C, args) - enum cxusb_table_index { MEDION_MD95700, DVICO_BLUEBIRD_LG064F_COLD, @@ -78,7 +75,6 @@ enum cxusb_table_index { DVICO_BLUEBIRD_DUAL_4_REV_2, CONEXANT_D680_DMB, MYGICA_D689, - MYGICA_T230, NR__cxusb_table_index }; @@ -126,7 +122,7 @@ static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); if (i != 0x01) - deb_info("gpio_write failed.\n"); + dev_info(&d->udev->dev, "gpio_write failed.\n"); st->gpio_write_state[GPIO_TUNER] = onoff; st->gpio_write_refresh[GPIO_TUNER] = false; @@ -143,7 +139,7 @@ static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask, rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1); if (rc < 0 || (gpio_state & changemask) != (newval & changemask)) - deb_info("bluebird_gpio_write failed.\n"); + dev_info(&d->udev->dev, "bluebird_gpio_write failed.\n"); return rc < 0 ? rc : gpio_state; } @@ -175,7 +171,7 @@ static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, if (i == 0x01) return 0; - deb_info("gpio_write failed.\n"); + dev_info(&d->udev->dev, "gpio_write failed.\n"); return -EIO; } @@ -249,7 +245,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], break; if (ibuf[0] != 0x08) - deb_i2c("i2c read may have failed\n"); + dev_info(&d->udev->dev, "i2c read may have failed\n"); memcpy(msg[i + 1].buf, &ibuf[1], msg[i + 1].len); @@ -272,7 +268,7 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], 2 + msg[i].len, &ibuf, 1) < 0) break; if (ibuf != 0x08) - deb_i2c("i2c write may have failed\n"); + dev_info(&d->udev->dev, "i2c write may have failed\n"); } } @@ -300,7 +296,7 @@ static int _cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 b = 0; - deb_info("setting power %s\n", onoff ? "ON" : "OFF"); + dev_info(&d->udev->dev, "setting power %s\n", onoff ? "ON" : "OFF"); if (onoff) return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); @@ -319,7 +315,7 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) mutex_lock(&cxdev->open_lock); if (cxdev->open_type == CXUSB_OPEN_ANALOG) { - deb_info("preventing DVB core from setting power OFF while we are in analog mode\n"); + dev_info(&d->udev->dev, "preventing DVB core from setting power OFF while we are in analog mode\n"); ret = -EBUSY; goto ret_unlock; } @@ -456,26 +452,6 @@ static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return 0; } -static int cxusb_read_status(struct dvb_frontend *fe, - enum fe_status *status) -{ - struct dvb_usb_adapter *adap = (struct dvb_usb_adapter *)fe->dvb->priv; - struct cxusb_state *state = (struct cxusb_state *)adap->dev->priv; - int ret; - - ret = state->fe_read_status(fe, status); - - /* it need resync slave fifo when signal change from unlock to lock.*/ - if ((*status & FE_HAS_LOCK) && (!state->last_lock)) { - mutex_lock(&state->stream_mutex); - cxusb_streaming_ctrl(adap, 1); - mutex_unlock(&state->stream_mutex); - } - - state->last_lock = (*status & FE_HAS_LOCK) ? 1 : 0; - return ret; -} - static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) { int ep = d->props.generic_bulk_ctrl_endpoint; @@ -542,7 +518,8 @@ static int cxusb_rc_query(struct dvb_usb_device *d) { u8 ircode[4]; - cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); + if (cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4) < 0) + return 0; if (ircode[2] || ircode[3]) rc_keydown(d->rc_dev, RC_PROTO_NEC, @@ -774,16 +751,16 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int component, switch (command) { case XC2028_TUNER_RESET: - deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg); + dev_info(&d->udev->dev, "XC2028_TUNER_RESET %d\n", arg); cxusb_bluebird_gpio_pulse(d, 0x01, 1); break; case XC2028_RESET_CLK: - deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); + dev_info(&d->udev->dev, "XC2028_RESET_CLK %d\n", arg); break; case XC2028_I2C_FLUSH: break; default: - deb_info("%s: unknown command %d, arg %d\n", __func__, + dev_info(&d->udev->dev, "unknown command %d, arg %d\n", command, arg); return -EINVAL; } @@ -1374,86 +1351,6 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) return 0; } -static int cxusb_mygica_t230_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_usb_device *d = adap->dev; - struct cxusb_state *st = d->priv; - struct i2c_adapter *adapter; - struct i2c_client *client_demod; - struct i2c_client *client_tuner; - struct i2c_board_info info; - struct si2168_config si2168_config; - struct si2157_config si2157_config; - - /* Select required USB configuration */ - if (usb_set_interface(d->udev, 0, 0) < 0) - err("set interface failed"); - - /* Unblock all USB pipes */ - usb_clear_halt(d->udev, - usb_sndbulkpipe(d->udev, - d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, - d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, - d->props.adapter[0].fe[0].stream.endpoint)); - - /* attach frontend */ - si2168_config.i2c_adapter = &adapter; - si2168_config.fe = &adap->fe_adap[0].fe; - si2168_config.ts_mode = SI2168_TS_PARALLEL; - si2168_config.ts_clock_inv = 1; - memset(&info, 0, sizeof(struct i2c_board_info)); - strscpy(info.type, "si2168", I2C_NAME_SIZE); - info.addr = 0x64; - info.platform_data = &si2168_config; - request_module(info.type); - client_demod = i2c_new_device(&d->i2c_adap, &info); - if (!client_demod || !client_demod->dev.driver) - return -ENODEV; - - if (!try_module_get(client_demod->dev.driver->owner)) { - i2c_unregister_device(client_demod); - return -ENODEV; - } - - st->i2c_client_demod = client_demod; - - /* attach tuner */ - memset(&si2157_config, 0, sizeof(si2157_config)); - si2157_config.fe = adap->fe_adap[0].fe; - si2157_config.if_port = 1; - memset(&info, 0, sizeof(struct i2c_board_info)); - strscpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = 0x60; - info.platform_data = &si2157_config; - request_module(info.type); - client_tuner = i2c_new_device(adapter, &info); - if (!client_tuner || !client_tuner->dev.driver) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - if (!try_module_get(client_tuner->dev.driver->owner)) { - i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - return -ENODEV; - } - - st->i2c_client_tuner = client_tuner; - - /* hook fe: need to resync the slave fifo when signal locks. */ - mutex_init(&st->stream_mutex); - st->last_lock = 0; - st->fe_read_status = adap->fe_adap[0].fe->ops.read_status; - adap->fe_adap[0].fe->ops.read_status = cxusb_read_status; - - return 0; -} - /* * DViCO has shipped two devices with the same USB ID, but only one of them * needs a firmware download. Check the device class details to see if they @@ -1544,7 +1441,7 @@ int cxusb_medion_get(struct dvb_usb_device *dvbdev, if (cxdev->open_ctr == 0) { if (cxdev->open_type != open_type) { - deb_info("will acquire and switch to %s\n", + dev_info(&dvbdev->udev->dev, "will acquire and switch to %s\n", open_type == CXUSB_OPEN_ANALOG ? "analog" : "digital"); @@ -1576,7 +1473,7 @@ int cxusb_medion_get(struct dvb_usb_device *dvbdev, cxdev->open_type = open_type; } else { - deb_info("reacquired idle %s\n", + dev_info(&dvbdev->udev->dev, "reacquired idle %s\n", open_type == CXUSB_OPEN_ANALOG ? "analog" : "digital"); } @@ -1584,8 +1481,8 @@ int cxusb_medion_get(struct dvb_usb_device *dvbdev, cxdev->open_ctr = 1; } else if (cxdev->open_type == open_type) { cxdev->open_ctr++; - deb_info("acquired %s\n", open_type == CXUSB_OPEN_ANALOG ? - "analog" : "digital"); + dev_info(&dvbdev->udev->dev, "acquired %s\n", + open_type == CXUSB_OPEN_ANALOG ? "analog" : "digital"); } else { ret = -EBUSY; } @@ -1611,7 +1508,7 @@ void cxusb_medion_put(struct dvb_usb_device *dvbdev) if (!WARN_ON(cxdev->open_ctr < 1)) { cxdev->open_ctr--; - deb_info("release %s\n", + dev_info(&dvbdev->udev->dev, "release %s\n", cxdev->open_type == CXUSB_OPEN_ANALOG ? "analog" : "digital"); } @@ -1633,7 +1530,6 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static struct dvb_usb_device_properties cxusb_d680_dmb_properties; static struct dvb_usb_device_properties cxusb_mygica_d689_properties; -static struct dvb_usb_device_properties cxusb_mygica_t230_properties; static int cxusb_medion_priv_init(struct dvb_usb_device *dvbdev) { @@ -1759,8 +1655,6 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || !dvb_usb_device_init(intf, &cxusb_mygica_d689_properties, THIS_MODULE, NULL, adapter_nr) || - !dvb_usb_device_init(intf, &cxusb_mygica_t230_properties, - THIS_MODULE, NULL, adapter_nr) || 0) return 0; @@ -1862,9 +1756,6 @@ static struct usb_device_id cxusb_table[NR__cxusb_table_index + 1] = { [MYGICA_D689] = { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) }, - [MYGICA_T230] = { - USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230) - }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, cxusb_table); @@ -2535,60 +2426,6 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { } }; -static struct dvb_usb_device_properties cxusb_mygica_t230_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .num_frontends = 1, - .fe = {{ - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_mygica_t230_frontend_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - } }, - }, - }, - - .power_ctrl = cxusb_d680_dmb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc.core = { - .rc_interval = 100, - .rc_codes = RC_MAP_D680_DMB, - .module_name = KBUILD_MODNAME, - .rc_query = cxusb_d680_dmb_rc_query, - .allowed_protos = RC_PROTO_BIT_UNKNOWN, - }, - - .num_device_descs = 1, - .devices = { - { - "Mygica T230 DVB-T/T2/C", - { NULL }, - { &cxusb_table[MYGICA_T230], NULL }, - }, - } -}; - static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 66d685065e06..4ef3fa98d20f 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -2439,9 +2439,13 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) 8, 0x0486, }; + if (!IS_ENABLED(CONFIG_DVB_DIB9000)) + return -ENODEV; if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL) return -ENODEV; i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + if (!i2c) + return -ENODEV; if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) return -ENODEV; dib0700_set_i2c_speed(adap->dev, 1500); @@ -2517,10 +2521,14 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) 0, 0x00ef, 8, 0x0406, }; + if (!IS_ENABLED(CONFIG_DVB_DIB9000)) + return -ENODEV; i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe); if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL) return -ENODEV; i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + if (!i2c) + return -ENODEV; if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) return -ENODEV; @@ -3764,8 +3772,8 @@ static int xbox_one_attach(struct dvb_usb_adapter *adap) info.addr = 0x18; info.platform_data = &mn88472_config; request_module(info.type); - client_demod = i2c_new_device(&d->i2c_adap, &info); - if (client_demod == NULL || client_demod->dev.driver == NULL) + client_demod = i2c_new_client_device(&d->i2c_adap, &info); + if (!i2c_client_has_driver(client_demod)) goto fail_demod_device; if (!try_module_get(client_demod->dev.driver->owner)) goto fail_demod_module; @@ -3792,8 +3800,8 @@ static int xbox_one_attach(struct dvb_usb_adapter *adap) info.platform_data = &tda18250_config; request_module(info.type); - client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info); - if (client_tuner == NULL || client_tuner->dev.driver == NULL) + client_tuner = i2c_new_client_device(&adap->dev->i2c_adap, &info); + if (!i2c_client_has_driver(client_tuner)) goto fail_tuner_device; if (!try_module_get(client_tuner->dev.driver->owner)) goto fail_tuner_module; diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c index dd5bb230cec1..99a39339d45d 100644 --- a/drivers/media/usb/dvb-usb/digitv.c +++ b/drivers/media/usb/dvb-usb/digitv.c @@ -230,18 +230,22 @@ static struct rc_map_table rc_map_digitv_table[] = { static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - int i; + int ret, i; u8 key[5]; u8 b[4] = { 0 }; *event = 0; *state = REMOTE_NO_KEY_PRESSED; - digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); + ret = digitv_ctrl_msg(d, USB_READ_REMOTE, 0, NULL, 0, &key[1], 4); + if (ret) + return ret; /* Tell the device we've read the remote. Not sure how necessary this is, but the Nebula SDK does it. */ - digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); + ret = digitv_ctrl_msg(d, USB_WRITE_REMOTE, 0, b, 4, NULL, 0); + if (ret) + return ret; /* if something is inside the buffer, simulate key press */ if (key[1] != 0) diff --git a/drivers/media/usb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c index c1b4e94a37f8..2aabf90d8697 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-urb.c @@ -12,7 +12,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen, int delay_ms) { - int actlen,ret = -ENOMEM; + int actlen = 0, ret = -ENOMEM; if (!d || wbuf == NULL || wlen == 0) return -EINVAL; diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c index b960abd00d48..8b584507dd59 100644 --- a/drivers/media/usb/dvb-usb/dw2102.c +++ b/drivers/media/usb/dvb-usb/dw2102.c @@ -1590,8 +1590,8 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x68; board_info.platform_data = &m88ds3103_pdata; request_module("m88ds3103"); - client = i2c_new_device(&d->i2c_adap, &board_info); - if (client == NULL || client->dev.driver == NULL) + client = i2c_new_client_device(&d->i2c_adap, &board_info); + if (!i2c_client_has_driver(client)) return -ENODEV; if (!try_module_get(client->dev.driver->owner)) { i2c_unregister_device(client); @@ -1609,9 +1609,9 @@ static int tt_s2_4600_frontend_attach(struct dvb_usb_adapter *adap) board_info.addr = 0x60; board_info.platform_data = &ts2020_config; request_module("ts2020"); - client = i2c_new_device(i2c_adapter, &board_info); + client = i2c_new_client_device(i2c_adapter, &board_info); - if (client == NULL || client->dev.driver == NULL) { + if (!i2c_client_has_driver(client)) { dvb_frontend_detach(adap->fe_adap[0].fe); return -ENODEV; } diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c index d6b36e4f33d2..441d878fc22c 100644 --- a/drivers/media/usb/dvb-usb/pctv452e.c +++ b/drivers/media/usb/dvb-usb/pctv452e.c @@ -909,14 +909,6 @@ static int pctv452e_frontend_attach(struct dvb_usb_adapter *a) &a->dev->i2c_adap); if (!a->fe_adap[0].fe) return -ENODEV; - - /* - * dvb_frontend will call dvb_detach for both stb0899_detach - * and stb0899_release but we only do dvb_attach(stb0899_attach). - * Increment the module refcount instead. - */ - symbol_get(stb0899_attach); - if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe, &a->dev->i2c_adap)) == NULL) err("Cannot attach lnbp22\n"); diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c index c659e18b358b..676d233d46d5 100644 --- a/drivers/media/usb/dvb-usb/technisat-usb2.c +++ b/drivers/media/usb/dvb-usb/technisat-usb2.c @@ -608,10 +608,9 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) static int technisat_usb2_get_ir(struct dvb_usb_device *d) { struct technisat_usb2_state *state = d->priv; - u8 *buf = state->buf; - u8 *b; - int ret; struct ir_raw_event ev; + u8 *buf = state->buf; + int i, ret; buf[0] = GET_IR_DATA_VENDOR_REQUEST; buf[1] = 0x08; @@ -647,26 +646,25 @@ unlock: return 0; /* no key pressed */ /* decoding */ - b = buf+1; #if 0 deb_rc("RC: %d ", ret); - debug_dump(b, ret, deb_rc); + debug_dump(buf + 1, ret, deb_rc); #endif ev.pulse = 0; - while (1) { - ev.pulse = !ev.pulse; - ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000; - ir_raw_event_store(d->rc_dev, &ev); - - b++; - if (*b == 0xff) { + for (i = 1; i < ARRAY_SIZE(state->buf); i++) { + if (buf[i] == 0xff) { ev.pulse = 0; ev.duration = 888888*2; ir_raw_event_store(d->rc_dev, &ev); break; } + + ev.pulse = !ev.pulse; + ev.duration = (buf[i] * FIRMWARE_CLOCK_DIVISOR * + FIRMWARE_CLOCK_TICK) / 1000; + ir_raw_event_store(d->rc_dev, &ev); } ir_raw_event_handle(d->rc_dev); diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c index 80c1cf05384b..2baf57216d19 100644 --- a/drivers/media/usb/dvb-usb/vp7045.c +++ b/drivers/media/usb/dvb-usb/vp7045.c @@ -96,10 +96,14 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) static int vp7045_rc_query(struct dvb_usb_device *d) { + int ret; u8 key; - vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); - deb_rc("remote query key: %x %d\n",key,key); + ret = vp7045_usb_op(d, RC_VAL_READ, NULL, 0, &key, 1, 20); + if (ret) + return ret; + + deb_rc("remote query key: %x\n", key); if (key != 0x44) { /* @@ -115,15 +119,18 @@ static int vp7045_rc_query(struct dvb_usb_device *d) static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset) { - int i = 0; - u8 v,br[2]; + int i, ret; + u8 v, br[2]; for (i=0; i < len; i++) { v = offset + i; - vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5); + ret = vp7045_usb_op(d, GET_EE_VALUE, &v, 1, br, 2, 5); + if (ret) + return ret; + buf[i] = br[1]; } - deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i); - debug_dump(buf,i,deb_info); + deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ", offset, i); + debug_dump(buf, i, deb_info); return 0; } diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 49c9b70b632b..6833b5bfe293 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -30,8 +30,6 @@ #include <linux/spinlock.h> #include <linux/soundcard.h> #include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/proc_fs.h> #include <linux/module.h> #include <sound/core.h> #include <sound/pcm.h> @@ -193,28 +191,6 @@ static int em28xx_init_audio_isoc(struct em28xx *dev) return 0; } -static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, - size_t size) -{ - struct em28xx *dev = snd_pcm_substream_chip(subs); - struct snd_pcm_runtime *runtime = subs->runtime; - - dprintk("Allocating vbuffer\n"); - if (runtime->dma_area) { - if (runtime->dma_bytes > size) - return 0; - - vfree(runtime->dma_area); - } - runtime->dma_area = vmalloc(size); - if (!runtime->dma_area) - return -ENOMEM; - - runtime->dma_bytes = size; - - return 0; -} - static const struct snd_pcm_hardware snd_em28xx_hw_capture = { .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -342,63 +318,12 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) } em28xx_audio_analog_set(dev); - if (substream->runtime->dma_area) { - dprintk("freeing\n"); - vfree(substream->runtime->dma_area); - substream->runtime->dma_area = NULL; - } mutex_unlock(&dev->lock); kref_put(&dev->ref, em28xx_free_device); return 0; } -static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - int ret; - struct em28xx *dev = snd_pcm_substream_chip(substream); - - if (dev->disconnected) - return -ENODEV; - - dprintk("Setting capture parameters\n"); - - ret = snd_pcm_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); - if (ret < 0) - return ret; -#if 0 - /* - * TODO: set up em28xx audio chip to deliver the correct audio format, - * current default is 48000hz multiplexed => 96000hz mono - * which shouldn't matter since analogue TV only supports mono - */ - unsigned int channels, rate, format; - - format = params_format(hw_params); - rate = params_rate(hw_params); - channels = params_channels(hw_params); -#endif - - return 0; -} - -static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) -{ - struct em28xx *dev = snd_pcm_substream_chip(substream); - struct em28xx_audio *adev = &dev->adev; - - dprintk("Stop capture, if needed\n"); - - if (atomic_read(&adev->stream_started) > 0) { - atomic_set(&adev->stream_started, 0); - schedule_work(&adev->wq_trigger); - } - - return 0; -} - static int snd_em28xx_prepare(struct snd_pcm_substream *substream) { struct em28xx *dev = snd_pcm_substream_chip(substream); @@ -472,14 +397,6 @@ static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream return hwptr_done; } -static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, - unsigned long offset) -{ - void *pageptr = subs->runtime->dma_area + offset; - - return vmalloc_to_page(pageptr); -} - /* * AC97 volume control support */ @@ -709,13 +626,9 @@ static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev, static const struct snd_pcm_ops snd_em28xx_pcm_capture = { .open = snd_em28xx_capture_open, .close = snd_em28xx_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_em28xx_hw_capture_params, - .hw_free = snd_em28xx_hw_capture_free, .prepare = snd_em28xx_prepare, .trigger = snd_em28xx_capture_trigger, .pointer = snd_em28xx_capture_pointer, - .page = snd_pcm_get_vmalloc_page, }; static void em28xx_audio_free_urb(struct em28xx *dev) @@ -937,6 +850,7 @@ static int em28xx_audio_init(struct em28xx *dev) goto card_free; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); pcm->info_flags = 0; pcm->private_data = dev; strscpy(pcm->name, "Empia 28xx Capture", sizeof(pcm->name)); diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index 1283c7ca9ad5..def9cdd931a9 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -2487,6 +2487,24 @@ const struct em28xx_board em28xx_boards[] = { .ir_codes = RC_MAP_HAUPPAUGE, .leds = hauppauge_dualhd_leds, }, + /* + * 1b80:e349 Magix USB Videowandler-2 + * (same chips as Honestech VIDBOX NW03) + * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner + */ + [EM2861_BOARD_MAGIX_VIDEOWANDLER2] = { + .name = "Magix USB Videowandler-2", + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA711X, + .input = { { + .type = EM28XX_VMUX_COMPOSITE, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, }; EXPORT_SYMBOL_GPL(em28xx_boards); @@ -2696,6 +2714,8 @@ struct usb_device_id em28xx_id_table[] = { .driver_info = EM28178_BOARD_PLEX_PX_BCUD }, { USB_DEVICE(0xeb1a, 0x5051), /* Ion Video 2 PC MKII / Startech svid2usb23 / Raygo R12-41373 */ .driver_info = EM2860_BOARD_TVP5150_REFERENCE_DESIGN }, + { USB_DEVICE(0x1b80, 0xe349), /* Magix USB Videowandler-2 */ + .driver_info = EM2861_BOARD_MAGIX_VIDEOWANDLER2 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -3566,13 +3586,12 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, static int em28xx_duplicate_dev(struct em28xx *dev) { int nr; - struct em28xx *sec_dev = kzalloc(sizeof(*sec_dev), GFP_KERNEL); + struct em28xx *sec_dev = kmemdup(dev, sizeof(*sec_dev), GFP_KERNEL); if (!sec_dev) { dev->dev_next = NULL; return -ENOMEM; } - memcpy(sec_dev, dev, sizeof(*sec_dev)); /* Check to see next free device and mark as used */ do { nr = find_first_zero_bit(em28xx_devused, EM28XX_MAXBOARDS); @@ -4020,7 +4039,6 @@ static void em28xx_usb_disconnect(struct usb_interface *intf) dev->dev_next->disconnected = 1; dev_info(&dev->intf->dev, "Disconnecting %s\n", dev->dev_next->name); - flush_request_modules(dev->dev_next); } dev->disconnected = 1; diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 2b8c84a5c9a8..e6088b5d1b80 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -931,7 +931,7 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->buf = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL); if (!usb_bufs->buf) { - kfree(usb_bufs->buf); + kfree(usb_bufs->urb); return -ENOMEM; } diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a73faf12f7e4..0ab6c493bc74 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -471,13 +471,13 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) { int i; - struct em28xx_reg_seq hauppauge_hvr930c_init[] = { + static const struct em28xx_reg_seq hauppauge_hvr930c_init[] = { {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0x65}, {EM2874_R80_GPIO_P0_CTRL, 0xfb, 0xff, 0x32}, {EM2874_R80_GPIO_P0_CTRL, 0xff, 0xff, 0xb8}, { -1, -1, -1, -1}, }; - struct em28xx_reg_seq hauppauge_hvr930c_end[] = { + static const struct em28xx_reg_seq hauppauge_hvr930c_end[] = { {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x01}, {EM2874_R80_GPIO_P0_CTRL, 0xaf, 0xff, 0x65}, {EM2874_R80_GPIO_P0_CTRL, 0xef, 0xff, 0x76}, @@ -493,7 +493,7 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) { -1, -1, -1, -1}, }; - struct { + static const struct { unsigned char r[4]; int len; } regs[] = { @@ -537,20 +537,20 @@ static void hauppauge_hvr930c_init(struct em28xx *dev) static void terratec_h5_init(struct em28xx *dev) { int i; - struct em28xx_reg_seq terratec_h5_init[] = { + static const struct em28xx_reg_seq terratec_h5_init[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xf2, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, { -1, -1, -1, -1}, }; - struct em28xx_reg_seq terratec_h5_end[] = { + static const struct em28xx_reg_seq terratec_h5_end[] = { {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, { -1, -1, -1, -1}, }; - struct { + static const struct { unsigned char r[4]; int len; } regs[] = { @@ -594,14 +594,14 @@ static void terratec_htc_stick_init(struct em28xx *dev) * 0xe6: unknown (does not affect DVB-T). * 0xb6: unknown (does not affect DVB-T). */ - struct em28xx_reg_seq terratec_htc_stick_init[] = { + static const struct em28xx_reg_seq terratec_htc_stick_init[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 100}, { -1, -1, -1, -1}, }; - struct em28xx_reg_seq terratec_htc_stick_end[] = { + static const struct em28xx_reg_seq terratec_htc_stick_end[] = { {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xf6, 0xff, 50}, { -1, -1, -1, -1}, @@ -611,7 +611,7 @@ static void terratec_htc_stick_init(struct em28xx *dev) * Init the analog decoder (not yet supported), but * it's probably still a good idea. */ - struct { + static const struct { unsigned char r[4]; int len; } regs[] = { @@ -642,14 +642,14 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) { int i; - struct em28xx_reg_seq terratec_htc_usb_xs_init[] = { + static const struct em28xx_reg_seq terratec_htc_usb_xs_init[] = { {EM2820_R08_GPIO_CTRL, 0xff, 0xff, 10}, {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xb2, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0xb6, 0xff, 100}, { -1, -1, -1, -1}, }; - struct em28xx_reg_seq terratec_htc_usb_xs_end[] = { + static const struct em28xx_reg_seq terratec_htc_usb_xs_end[] = { {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 100}, {EM2874_R80_GPIO_P0_CTRL, 0xa6, 0xff, 50}, {EM2874_R80_GPIO_P0_CTRL, 0xe6, 0xff, 100}, @@ -660,7 +660,7 @@ static void terratec_htc_usb_xs_init(struct em28xx *dev) * Init the analog decoder (not yet supported), but * it's probably still a good idea. */ - struct { + static const struct { unsigned char r[4]; int len; } regs[] = { @@ -704,7 +704,7 @@ static void pctv_520e_init(struct em28xx *dev) * digital demodulator and tuner are routed via AVF4910B. */ int i; - struct { + static const struct { unsigned char r[4]; int len; } regs[] = { @@ -800,7 +800,7 @@ static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) static void px_bcud_init(struct em28xx *dev) { int i; - struct { + static const struct { unsigned char r[4]; int len; } regs1[] = { @@ -818,7 +818,7 @@ static void px_bcud_init(struct em28xx *dev) {{ 0x85, 0x7a }, 2}, {{ 0x87, 0x04 }, 2}, }; - static struct em28xx_reg_seq gpio[] = { + static const struct em28xx_reg_seq gpio[] = { {EM28XX_R06_I2C_CLK, 0x40, 0xff, 300}, {EM2874_R80_GPIO_P0_CTRL, 0xfd, 0xff, 60}, {EM28XX_R15_RGAIN, 0x20, 0xff, 0}, diff --git a/drivers/media/usb/em28xx/em28xx-i2c.c b/drivers/media/usb/em28xx/em28xx-i2c.c index a3155ec196cc..592b98b3643a 100644 --- a/drivers/media/usb/em28xx/em28xx-i2c.c +++ b/drivers/media/usb/em28xx/em28xx-i2c.c @@ -949,7 +949,7 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus) unsigned char buf; int i, rc; - memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); + memset(i2c_devicelist, 0, sizeof(i2c_devicelist)); for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { dev->i2c_client[bus].addr = i; @@ -964,7 +964,7 @@ void em28xx_do_i2c_scan(struct em28xx *dev, unsigned int bus) if (bus == dev->def_i2c_bus) dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, - ARRAY_SIZE(i2c_devicelist), 32); + sizeof(i2c_devicelist), 32); } /* diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 0512e1959394..b0f7390e4b4f 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -102,37 +102,30 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); /* supported video standards */ static struct em28xx_fmt format[] = { { - .name = "16 bpp YUY2, 4:2:2, packed", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, }, { - .name = "16 bpp RGB 565, LE", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .reg = EM28XX_OUTFMT_RGB_16_656, }, { - .name = "8 bpp Bayer RGRG..GBGB", .fourcc = V4L2_PIX_FMT_SRGGB8, .depth = 8, .reg = EM28XX_OUTFMT_RGB_8_RGRG, }, { - .name = "8 bpp Bayer BGBG..GRGR", .fourcc = V4L2_PIX_FMT_SBGGR8, .depth = 8, .reg = EM28XX_OUTFMT_RGB_8_BGBG, }, { - .name = "8 bpp Bayer GRGR..BGBG", .fourcc = V4L2_PIX_FMT_SGRBG8, .depth = 8, .reg = EM28XX_OUTFMT_RGB_8_GRGR, }, { - .name = "8 bpp Bayer GBGB..RGRG", .fourcc = V4L2_PIX_FMT_SGBRG8, .depth = 8, .reg = EM28XX_OUTFMT_RGB_8_GBGB, }, { - .name = "12 bpp YUV411", .fourcc = V4L2_PIX_FMT_YUV411P, .depth = 12, .reg = EM28XX_OUTFMT_YUV411, @@ -1517,7 +1510,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, else f->fmt.pix.field = v4l2->interlaced_fieldmode ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; - f->fmt.pix.priv = 0; return 0; } @@ -2011,7 +2003,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (unlikely(f->index >= ARRAY_SIZE(format))) return -EINVAL; - strscpy(f->description, format[f->index].name, sizeof(f->description)); f->pixelformat = format[f->index].fourcc; return 0; @@ -2208,7 +2199,7 @@ static int em28xx_v4l2_open(struct file *filp) /* * em28xx_v4l2_fini() * unregisters the v4l2,i2c and usb devices - * called when the device gets disconected or at module unload + * called when the device gets disconnected or at module unload */ static int em28xx_v4l2_fini(struct em28xx *dev) { diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index a551072e62ed..4ecadd57dac7 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -149,6 +149,7 @@ #define EM28174_BOARD_HAUPPAUGE_WINTV_DUALHD_01595 100 #define EM2884_BOARD_TERRATEC_H6 101 #define EM2882_BOARD_ZOLID_HYBRID_TV_STICK 102 +#define EM2861_BOARD_MAGIX_VIDEOWANDLER2 103 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -251,13 +252,11 @@ struct em28xx_usb_ctl { /** * struct em28xx_fmt - Struct to enumberate video formats * - * @name: Name for the video standard * @fourcc: v4l2 format id * @depth: mean number of bits to represent a pixel * @reg: em28xx register value to set it */ struct em28xx_fmt { - char *name; u32 fourcc; int depth; int reg; @@ -657,7 +656,7 @@ struct em28xx { enum em28xx_chip_id chip_id; unsigned int is_em25xx:1; // em25xx/em276x/7x/8x family bridge - unsigned int disconnected:1; // device has been diconnected + unsigned int disconnected:1; // device has been disconnected unsigned int has_video:1; unsigned int is_audio_only:1; unsigned int is_webcam:1; diff --git a/drivers/media/usb/go7007/go7007-v4l2.c b/drivers/media/usb/go7007/go7007-v4l2.c index 88edfef80b40..0b3d185f3cb0 100644 --- a/drivers/media/usb/go7007/go7007-v4l2.c +++ b/drivers/media/usb/go7007/go7007-v4l2.c @@ -285,33 +285,22 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fmt) { - char *desc = NULL; - switch (fmt->index) { case 0: fmt->pixelformat = V4L2_PIX_FMT_MJPEG; - desc = "Motion JPEG"; break; case 1: fmt->pixelformat = V4L2_PIX_FMT_MPEG1; - desc = "MPEG-1 ES"; break; case 2: fmt->pixelformat = V4L2_PIX_FMT_MPEG2; - desc = "MPEG-2 ES"; break; case 3: fmt->pixelformat = V4L2_PIX_FMT_MPEG4; - desc = "MPEG-4 ES"; break; default: return -EINVAL; } - fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt->flags = V4L2_FMT_FLAG_COMPRESSED; - - strscpy(fmt->description, desc, sizeof(fmt->description)); - return 0; } diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index 179d4d642dae..b9e45124673b 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -505,9 +505,9 @@ static int s2250_probe(struct i2c_client *client, struct go7007 *go = i2c_get_adapdata(adapter); struct go7007_usb *usb = go->hpi_context; - audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1); - if (audio == NULL) - return -ENOMEM; + audio = i2c_new_dummy_device(adapter, TLV320_ADDRESS >> 1); + if (IS_ERR(audio)) + return PTR_ERR(audio); state = kzalloc(sizeof(struct s2250), GFP_KERNEL); if (state == NULL) { @@ -607,6 +607,7 @@ static int s2250_remove(struct i2c_client *client) { struct s2250 *state = to_state(i2c_get_clientdata(client)); + i2c_unregister_device(state->audio); v4l2_device_unregister_subdev(&state->sd); v4l2_ctrl_handler_free(&state->hdl); kfree(state); diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index 4a449c62fc32..2ce85ab38db5 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -9,7 +9,6 @@ #include <linux/spinlock.h> #include <linux/delay.h> #include <linux/sched.h> -#include <linux/vmalloc.h> #include <linux/time.h> #include <linux/mm.h> #include <linux/i2c.h> @@ -100,16 +99,7 @@ static int go7007_snd_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct go7007 *go = snd_pcm_substream_chip(substream); - unsigned int bytes; - - bytes = params_buffer_bytes(hw_params); - if (substream->runtime->dma_bytes > 0) - vfree(substream->runtime->dma_area); - substream->runtime->dma_bytes = 0; - substream->runtime->dma_area = vmalloc(bytes); - if (substream->runtime->dma_area == NULL) - return -ENOMEM; - substream->runtime->dma_bytes = bytes; + go->audio_deliver = parse_audio_stream_data; return 0; } @@ -119,9 +109,6 @@ static int go7007_snd_hw_free(struct snd_pcm_substream *substream) struct go7007 *go = snd_pcm_substream_chip(substream); go->audio_deliver = NULL; - if (substream->runtime->dma_bytes > 0) - vfree(substream->runtime->dma_area); - substream->runtime->dma_bytes = 0; return 0; } @@ -185,22 +172,14 @@ static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substr return gosnd->hw_ptr; } -static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream, - unsigned long offset) -{ - return vmalloc_to_page(substream->runtime->dma_area + offset); -} - static const struct snd_pcm_ops go7007_snd_capture_ops = { .open = go7007_snd_capture_open, .close = go7007_snd_capture_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = go7007_snd_hw_params, .hw_free = go7007_snd_hw_free, .prepare = go7007_snd_pcm_prepare, .trigger = go7007_snd_pcm_trigger, .pointer = go7007_snd_pcm_pointer, - .page = go7007_snd_pcm_page, }; static int go7007_snd_free(struct snd_device *device) @@ -236,37 +215,32 @@ int go7007_snd_init(struct go7007 *go) gosnd->capturing = 0; ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0, &gosnd->card); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_snd; + ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, &go7007_snd_device_ops); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + strscpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver)); - strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver)); + strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->shortname)); strscpy(gosnd->card->longname, gosnd->card->shortname, sizeof(gosnd->card->longname)); gosnd->pcm->private_data = go; snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &go7007_snd_capture_ops); + snd_pcm_set_managed_buffer_all(gosnd->pcm, SNDRV_DMA_TYPE_VMALLOC, + NULL, 0, 0); ret = snd_card_register(gosnd->card); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; gosnd->substream = NULL; go->snd_context = gosnd; @@ -274,6 +248,12 @@ int go7007_snd_init(struct go7007 *go) ++dev; return 0; + +free_card: + snd_card_free(gosnd->card); +free_snd: + kfree(gosnd); + return ret; } EXPORT_SYMBOL(go7007_snd_init); diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index be11f7830bca..c1b307bbe540 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1024,27 +1024,18 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; /* no more format */ fmtdesc->pixelformat = fmt_tb[index]; - if (gspca_dev->cam.cam_mode[i].sizeimage < - gspca_dev->cam.cam_mode[i].width * - gspca_dev->cam.cam_mode[i].height) - fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; - fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; - fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; - fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; - fmtdesc->description[3] = fmtdesc->pixelformat >> 24; - fmtdesc->description[4] = '\0'; return 0; } -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *fmt) +static int vidioc_g_fmt_vid_cap(struct file *file, void *_priv, + struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = video_drvdata(file); + u32 priv = fmt->fmt.pix.priv; fmt->fmt.pix = gspca_dev->pixfmt; - /* some drivers use priv internally, zero it before giving it back to - the core */ - fmt->fmt.pix.priv = 0; + /* some drivers use priv internally, so keep the original value */ + fmt->fmt.pix.priv = priv; return 0; } @@ -1079,27 +1070,27 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, fmt->fmt.pix.height = h; gspca_dev->sd_desc->try_fmt(gspca_dev, fmt); } - /* some drivers use priv internally, zero it before giving it back to - the core */ - fmt->fmt.pix.priv = 0; return mode; /* used when s_fmt */ } -static int vidioc_try_fmt_vid_cap(struct file *file, - void *priv, - struct v4l2_format *fmt) +static int vidioc_try_fmt_vid_cap(struct file *file, void *_priv, + struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = video_drvdata(file); + u32 priv = fmt->fmt.pix.priv; if (try_fmt_vid_cap(gspca_dev, fmt) < 0) return -EINVAL; + /* some drivers use priv internally, so keep the original value */ + fmt->fmt.pix.priv = priv; return 0; } -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *fmt) +static int vidioc_s_fmt_vid_cap(struct file *file, void *_priv, + struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = video_drvdata(file); + u32 priv = fmt->fmt.pix.priv; int mode; if (vb2_is_busy(&gspca_dev->queue)) @@ -1115,6 +1106,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, gspca_dev->pixfmt = fmt->fmt.pix; else gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode]; + /* some drivers use priv internally, so keep the original value */ + fmt->fmt.pix.priv = priv; return 0; } @@ -1468,7 +1461,7 @@ int gspca_dev_probe2(struct usb_interface *intf, pr_err("couldn't kzalloc gspca struct\n"); return -ENOMEM; } - gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); + gspca_dev->usb_buf = kzalloc(USB_BUF_SZ, GFP_KERNEL); if (!gspca_dev->usb_buf) { pr_err("out of memory\n"); ret = -ENOMEM; diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c index d8e40137a204..53db9a2895ea 100644 --- a/drivers/media/usb/gspca/konica.c +++ b/drivers/media/usb/gspca/konica.c @@ -114,6 +114,11 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index) if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, 2); } } diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c index 59649704beba..880f569bda30 100644 --- a/drivers/media/usb/gspca/nw80x.c +++ b/drivers/media/usb/gspca/nw80x.c @@ -1572,6 +1572,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); return; } if (len == 1) diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c index cfb1f53bc17e..f417dfc0b872 100644 --- a/drivers/media/usb/gspca/ov519.c +++ b/drivers/media/usb/gspca/ov519.c @@ -2073,6 +2073,11 @@ static int reg_r(struct sd *sd, u16 index) } else { gspca_err(gspca_dev, "reg_r %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; + /* + * Make sure the result is zeroed to avoid uninitialized + * values. + */ + gspca_dev->usb_buf[0] = 0; } return ret; @@ -2101,6 +2106,11 @@ static int reg_r8(struct sd *sd, } else { gspca_err(gspca_dev, "reg_r8 %02x failed %d\n", index, ret); sd->gspca_dev.usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, 8); } return ret; diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c index 56521c991db4..185c1f10fb30 100644 --- a/drivers/media/usb/gspca/ov534.c +++ b/drivers/media/usb/gspca/ov534.c @@ -693,6 +693,11 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) if (ret < 0) { pr_err("read failed %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the result is zeroed to avoid uninitialized + * values. + */ + gspca_dev->usb_buf[0] = 0; } return gspca_dev->usb_buf[0]; } diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c index 867f860a9650..91efc650cf76 100644 --- a/drivers/media/usb/gspca/ov534_9.c +++ b/drivers/media/usb/gspca/ov534_9.c @@ -1145,6 +1145,7 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg) if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + return 0; } return gspca_dev->usb_buf[0]; } diff --git a/drivers/media/usb/gspca/se401.c b/drivers/media/usb/gspca/se401.c index 061deee138c3..e087cfb5980b 100644 --- a/drivers/media/usb/gspca/se401.c +++ b/drivers/media/usb/gspca/se401.c @@ -101,6 +101,11 @@ static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent) pr_err("read req failed req %#04x error %d\n", req, err); gspca_dev->usb_err = err; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, READ_REQ_SIZE); } } diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c index b43f89fee6c1..2a6d0a1265a7 100644 --- a/drivers/media/usb/gspca/sn9c20x.c +++ b/drivers/media/usb/gspca/sn9c20x.c @@ -124,6 +124,13 @@ static const struct dmi_system_id flip_dmi_table[] = { } }, { + .ident = "MSI MS-1039", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"), + } + }, + { .ident = "MSI MS-1632", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), @@ -909,6 +916,11 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) if (unlikely(result < 0 || result != length)) { pr_err("Read register %02x failed %d\n", reg, result); gspca_dev->usb_err = result; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c index 046fc2c2a135..4d655e2da9cb 100644 --- a/drivers/media/usb/gspca/sonixb.c +++ b/drivers/media/usb/gspca/sonixb.c @@ -453,6 +453,11 @@ static void reg_r(struct gspca_dev *gspca_dev, dev_err(gspca_dev->v4l2_dev.dev, "Error reading register %02x: %d\n", value, res); gspca_dev->usb_err = res; + /* + * Make sure the result is zeroed to avoid uninitialized + * values. + */ + gspca_dev->usb_buf[0] = 0; } } diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c index 50a6c8425827..2e1bd2df8304 100644 --- a/drivers/media/usb/gspca/sonixj.c +++ b/drivers/media/usb/gspca/sonixj.c @@ -1162,6 +1162,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c index 2ae03b60163f..ccc477944ef8 100644 --- a/drivers/media/usb/gspca/spca1528.c +++ b/drivers/media/usb/gspca/spca1528.c @@ -71,6 +71,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 863c485f4275..97799cfb832e 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -378,6 +378,9 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Start the workqueue function to do the streaming */ dev->work_thread = create_singlethread_workqueue(MODULE_NAME); + if (!dev->work_thread) + return -ENOMEM; + queue_work(dev->work_thread, &dev->work_struct); return 0; diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c index 3d7f6dcdd7a8..6ca947aef298 100644 --- a/drivers/media/usb/gspca/sq905c.c +++ b/drivers/media/usb/gspca/sq905c.c @@ -276,6 +276,9 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Start the workqueue function to do the streaming */ dev->work_thread = create_singlethread_workqueue(MODULE_NAME); + if (!dev->work_thread) + return -ENOMEM; + queue_work(dev->work_thread, &dev->work_struct); return 0; diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c index d1ba0888d798..c3610247a90e 100644 --- a/drivers/media/usb/gspca/sq930x.c +++ b/drivers/media/usb/gspca/sq930x.c @@ -425,6 +425,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r %04x failed %d\n", value, ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } diff --git a/drivers/media/usb/gspca/stv0680.c b/drivers/media/usb/gspca/stv0680.c index f869eb6065ce..b23988d8c7bc 100644 --- a/drivers/media/usb/gspca/stv0680.c +++ b/drivers/media/usb/gspca/stv0680.c @@ -35,7 +35,7 @@ struct sd { static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val, int size) { - int ret = -1; + int ret; u8 req_type = 0; unsigned int pipe = 0; diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c index 7104a88b1e43..aac19d449be2 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c @@ -117,7 +117,7 @@ static int st6422_init(struct sd *sd) { int err = 0, i; - const u16 st6422_bridge_init[][2] = { + static const u16 st6422_bridge_init[][2] = { { STV_ISO_ENABLE, 0x00 }, /* disable capture */ { 0x1436, 0x00 }, { 0x1432, 0x03 }, /* 0x00-0x1F brightness */ diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index d0ddfa957ca9..f4a4222f0d2e 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -255,6 +255,11 @@ static void reg_r(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c index 588a847ea483..4cb7c92ea132 100644 --- a/drivers/media/usb/gspca/vc032x.c +++ b/drivers/media/usb/gspca/vc032x.c @@ -2906,6 +2906,11 @@ static void reg_r_i(struct gspca_dev *gspca_dev, if (ret < 0) { pr_err("reg_r err %d\n", ret); gspca_dev->usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); } } static void reg_r(struct gspca_dev *gspca_dev, diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c index 16b679c2de21..a8350ee9712f 100644 --- a/drivers/media/usb/gspca/w996Xcf.c +++ b/drivers/media/usb/gspca/w996Xcf.c @@ -133,6 +133,11 @@ static int w9968cf_read_sb(struct sd *sd) } else { pr_err("Read SB reg [01] failed\n"); sd->gspca_dev.usb_err = ret; + /* + * Make sure the buffer is zeroed to avoid uninitialized + * values. + */ + memset(sd->gspca_dev.usb_buf, 0, 2); } udelay(W9968CF_I2C_BUS_DELAY); diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 9b9d894d29bc..b75c18a012a7 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -137,6 +137,7 @@ static int device_authorization(struct hdpvr_device *dev) dev->fw_ver = dev->usbc_buf[1]; + dev->usbc_buf[46] = '\0'; v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n", dev->fw_ver, &dev->usbc_buf[2]); @@ -271,6 +272,7 @@ static int hdpvr_probe(struct usb_interface *interface, #endif size_t buffer_size; int i; + int dev_num; int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ @@ -368,8 +370,17 @@ static int hdpvr_probe(struct usb_interface *interface, } #endif + dev_num = atomic_inc_return(&dev_nr); + if (dev_num >= HDPVR_MAX) { + v4l2_err(&dev->v4l2_dev, + "max device number reached, device register failed\n"); + atomic_dec(&dev_nr); + retval = -ENODEV; + goto reg_fail; + } + retval = hdpvr_register_videodev(dev, &interface->dev, - video_nr[atomic_inc_return(&dev_nr)]); + video_nr[dev_num]); if (retval < 0) { v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); goto reg_fail; diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c index bc5975b17c0c..785c8508a46e 100644 --- a/drivers/media/usb/hdpvr/hdpvr-i2c.c +++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c @@ -193,8 +193,6 @@ static int hdpvr_activate_ir(struct hdpvr_device *dev) int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) { - int retval = -ENOMEM; - hdpvr_activate_ir(dev); dev->i2c_adapter = hdpvr_i2c_adapter_template; @@ -202,9 +200,7 @@ int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) i2c_set_adapdata(&dev->i2c_adapter, dev); - retval = i2c_add_adapter(&dev->i2c_adapter); - - return retval; + return i2c_add_adapter(&dev->i2c_adapter); } #endif diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 5b3e67b80627..bad71d863d39 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -987,9 +987,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data, if (f->index != 0) return -EINVAL; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strscpy(f->description, "MPEG2-TS with AVC/AAC streams", - sizeof(f->description)); f->pixelformat = V4L2_PIX_FMT_MPEG; return 0; diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index 4c9b2a12acfb..65be6f140fe8 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -66,7 +66,6 @@ static const struct v4l2_frequency_band bands[] = { /* stream formats */ struct msi2500_format { - char *name; u32 pixelformat; u32 buffersize; }; @@ -74,27 +73,21 @@ struct msi2500_format { /* format descriptions for capture and preview */ static struct msi2500_format formats[] = { { - .name = "Complex S8", .pixelformat = V4L2_SDR_FMT_CS8, .buffersize = 3 * 1008, #if 0 }, { - .name = "10+2-bit signed", .pixelformat = MSI2500_PIX_FMT_SDR_MSI2500_384, }, { - .name = "12-bit signed", .pixelformat = MSI2500_PIX_FMT_SDR_S12, #endif }, { - .name = "Complex S14LE", .pixelformat = V4L2_SDR_FMT_CS14LE, .buffersize = 3 * 1008, }, { - .name = "Complex U8 (emulated)", .pixelformat = V4L2_SDR_FMT_CU8, .buffersize = 3 * 1008, }, { - .name = "Complex U16LE (emulated)", .pixelformat = V4L2_SDR_FMT_CU16LE, .buffersize = 3 * 1008, }, @@ -904,7 +897,6 @@ static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv, if (f->index >= dev->num_formats) return -EINVAL; - strscpy(f->description, formats[f->index].name, sizeof(f->description)); f->pixelformat = formats[f->index].pixelformat; return 0; diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c index ac88ade94cda..afda438d4e0a 100644 --- a/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -49,7 +49,7 @@ static int debug; static int persistent_config; module_param(debug, int, 0644); module_param(persistent_config, int, 0644); -MODULE_PARM_DESC(debug, "debug level (0-1)"); +MODULE_PARM_DESC(debug, "debug level (0-2)"); MODULE_PARM_DESC(persistent_config, "read config from persistent memory (0-1)"); enum pulse8_msgcodes { @@ -100,6 +100,61 @@ enum pulse8_msgcodes { MSGCODE_FRAME_ACK = 0x40, }; +static const char * const pulse8_msgnames[] = { + "NOTHING", + "PING", + "TIMEOUT_ERROR", + "HIGH_ERROR", + "LOW_ERROR", + "FRAME_START", + "FRAME_DATA", + "RECEIVE_FAILED", + "COMMAND_ACCEPTED", + "COMMAND_REJECTED", + "SET_ACK_MASK", + "TRANSMIT", + "TRANSMIT_EOM", + "TRANSMIT_IDLETIME", + "TRANSMIT_ACK_POLARITY", + "TRANSMIT_LINE_TIMEOUT", + "TRANSMIT_SUCCEEDED", + "TRANSMIT_FAILED_LINE", + "TRANSMIT_FAILED_ACK", + "TRANSMIT_FAILED_TIMEOUT_DATA", + "TRANSMIT_FAILED_TIMEOUT_LINE", + "FIRMWARE_VERSION", + "START_BOOTLOADER", + "GET_BUILDDATE", + "SET_CONTROLLED", + "GET_AUTO_ENABLED", + "SET_AUTO_ENABLED", + "GET_DEFAULT_LOGICAL_ADDRESS", + "SET_DEFAULT_LOGICAL_ADDRESS", + "GET_LOGICAL_ADDRESS_MASK", + "SET_LOGICAL_ADDRESS_MASK", + "GET_PHYSICAL_ADDRESS", + "SET_PHYSICAL_ADDRESS", + "GET_DEVICE_TYPE", + "SET_DEVICE_TYPE", + "GET_HDMI_VERSION", + "SET_HDMI_VERSION", + "GET_OSD_NAME", + "SET_OSD_NAME", + "WRITE_EEPROM", + "GET_ADAPTER_TYPE", + "SET_ACTIVE_SOURCE", +}; + +static const char *pulse8_msgname(u8 cmd) +{ + static char unknown_msg[5]; + + if ((cmd & 0x3f) < ARRAY_SIZE(pulse8_msgnames)) + return pulse8_msgnames[cmd & 0x3f]; + snprintf(unknown_msg, sizeof(unknown_msg), "0x%02x", cmd); + return unknown_msg; +} + #define MSGSTART 0xff #define MSGEND 0xfe #define MSGESC 0xfd @@ -109,57 +164,203 @@ enum pulse8_msgcodes { #define PING_PERIOD (15 * HZ) +#define NUM_MSGS 8 + struct pulse8 { struct device *dev; struct serio *serio; struct cec_adapter *adap; unsigned int vers; - struct completion cmd_done; - struct work_struct work; + struct delayed_work ping_eeprom_work; - struct cec_msg rx_msg; + + struct work_struct irq_work; + struct cec_msg rx_msg[NUM_MSGS]; + unsigned int rx_msg_cur_idx, rx_msg_num; + /* protect rx_msg_cur_idx and rx_msg_num */ + spinlock_t msg_lock; + u8 new_rx_msg[CEC_MAX_MSG_SIZE]; + u8 new_rx_msg_len; + + struct work_struct tx_work; + u32 tx_done_status; + u32 tx_signal_free_time; + struct cec_msg tx_msg; + bool tx_msg_is_bcast; + + struct completion cmd_done; u8 data[DATA_SIZE]; unsigned int len; u8 buf[DATA_SIZE]; unsigned int idx; bool escape; bool started; - struct mutex config_lock; - struct mutex write_lock; + + /* locks access to the adapter */ + struct mutex lock; bool config_pending; bool restoring_config; bool autonomous; }; -static void pulse8_ping_eeprom_work_handler(struct work_struct *work); +static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) +{ + int err = 0; + + err = serio_write(serio, MSGSTART); + if (err) + return err; + for (; !err && cmd_len; command++, cmd_len--) { + if (*command >= MSGESC) { + err = serio_write(serio, MSGESC); + if (!err) + err = serio_write(serio, *command - MSGOFFSET); + } else { + err = serio_write(serio, *command); + } + } + if (!err) + err = serio_write(serio, MSGEND); + + return err; +} + +static int pulse8_send_and_wait_once(struct pulse8 *pulse8, + const u8 *cmd, u8 cmd_len, + u8 response, u8 size) +{ + int err; + + if (debug > 1) + dev_info(pulse8->dev, "transmit %s: %*ph\n", + pulse8_msgname(cmd[0]), cmd_len, cmd); + init_completion(&pulse8->cmd_done); + + err = pulse8_send(pulse8->serio, cmd, cmd_len); + if (err) + return err; + + if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) + return -ETIMEDOUT; + if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && + cmd[0] != MSGCODE_SET_CONTROLLED && + cmd[0] != MSGCODE_SET_AUTO_ENABLED && + cmd[0] != MSGCODE_GET_BUILDDATE) + return -ENOTTY; + if (response && + ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { + dev_info(pulse8->dev, "transmit %s failed with %s\n", + pulse8_msgname(cmd[0]), + pulse8_msgname(pulse8->data[0])); + return -EIO; + } + return 0; +} + +static int pulse8_send_and_wait(struct pulse8 *pulse8, + const u8 *cmd, u8 cmd_len, u8 response, u8 size) +{ + u8 cmd_sc[2]; + int err; + + err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); + if (err != -ENOTTY) + return err; + + cmd_sc[0] = MSGCODE_SET_CONTROLLED; + cmd_sc[1] = 1; + err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + if (!err) + err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, + response, size); + return err == -ENOTTY ? -EIO : err; +} + +static void pulse8_tx_work_handler(struct work_struct *work) +{ + struct pulse8 *pulse8 = container_of(work, struct pulse8, tx_work); + struct cec_msg *msg = &pulse8->tx_msg; + unsigned int i; + u8 cmd[2]; + int err; + + if (msg->len == 0) + return; + + mutex_lock(&pulse8->lock); + cmd[0] = MSGCODE_TRANSMIT_IDLETIME; + cmd[1] = pulse8->tx_signal_free_time; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; + cmd[1] = cec_msg_is_broadcast(msg); + pulse8->tx_msg_is_bcast = cec_msg_is_broadcast(msg); + if (!err) + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; + cmd[1] = msg->msg[0]; + if (!err) + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + if (!err && msg->len > 1) { + for (i = 1; !err && i < msg->len; i++) { + cmd[0] = ((i == msg->len - 1)) ? + MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; + cmd[1] = msg->msg[i]; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + } + } + if (err && debug) + dev_info(pulse8->dev, "%s(0x%02x) failed with error %d for msg %*ph\n", + pulse8_msgname(cmd[0]), cmd[1], + err, msg->len, msg->msg); + msg->len = 0; + mutex_unlock(&pulse8->lock); + if (err) + cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR); +} static void pulse8_irq_work_handler(struct work_struct *work) { struct pulse8 *pulse8 = - container_of(work, struct pulse8, work); + container_of(work, struct pulse8, irq_work); + unsigned long flags; + u32 status; - switch (pulse8->data[0] & 0x3f) { - case MSGCODE_FRAME_DATA: - cec_received_msg(pulse8->adap, &pulse8->rx_msg); - break; - case MSGCODE_TRANSMIT_SUCCEEDED: - cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_OK); - break; - case MSGCODE_TRANSMIT_FAILED_ACK: - cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_NACK); - break; - case MSGCODE_TRANSMIT_FAILED_LINE: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: - case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: - cec_transmit_attempt_done(pulse8->adap, CEC_TX_STATUS_ERROR); - break; + spin_lock_irqsave(&pulse8->msg_lock, flags); + while (pulse8->rx_msg_num) { + spin_unlock_irqrestore(&pulse8->msg_lock, flags); + if (debug) + dev_info(pulse8->dev, "adap received %*ph\n", + pulse8->rx_msg[pulse8->rx_msg_cur_idx].len, + pulse8->rx_msg[pulse8->rx_msg_cur_idx].msg); + cec_received_msg(pulse8->adap, + &pulse8->rx_msg[pulse8->rx_msg_cur_idx]); + spin_lock_irqsave(&pulse8->msg_lock, flags); + if (pulse8->rx_msg_num) + pulse8->rx_msg_num--; + pulse8->rx_msg_cur_idx = + (pulse8->rx_msg_cur_idx + 1) % NUM_MSGS; } + spin_unlock_irqrestore(&pulse8->msg_lock, flags); + + mutex_lock(&pulse8->lock); + status = pulse8->tx_done_status; + pulse8->tx_done_status = 0; + mutex_unlock(&pulse8->lock); + if (status) + cec_transmit_attempt_done(pulse8->adap, status); } static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { struct pulse8 *pulse8 = serio_get_drvdata(serio); + unsigned long irq_flags; + unsigned int idx; if (!pulse8->started && data != MSGSTART) return IRQ_HANDLED; @@ -171,35 +372,80 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, data += MSGOFFSET; pulse8->escape = false; } else if (data == MSGEND) { - struct cec_msg *msg = &pulse8->rx_msg; + u8 msgcode = pulse8->buf[0]; - if (debug) - dev_info(pulse8->dev, "received: %*ph\n", + if (debug > 1) + dev_info(pulse8->dev, "received %s: %*ph\n", + pulse8_msgname(msgcode), pulse8->idx, pulse8->buf); - pulse8->data[0] = pulse8->buf[0]; - switch (pulse8->buf[0] & 0x3f) { + switch (msgcode & 0x3f) { case MSGCODE_FRAME_START: - msg->len = 1; - msg->msg[0] = pulse8->buf[1]; - break; + /* + * Test if we are receiving a new msg when a previous + * message is still pending. + */ + if (!(msgcode & MSGCODE_FRAME_EOM)) { + pulse8->new_rx_msg_len = 1; + pulse8->new_rx_msg[0] = pulse8->buf[1]; + break; + } + /* fall through */ case MSGCODE_FRAME_DATA: - if (msg->len == CEC_MAX_MSG_SIZE) + if (pulse8->new_rx_msg_len < CEC_MAX_MSG_SIZE) + pulse8->new_rx_msg[pulse8->new_rx_msg_len++] = + pulse8->buf[1]; + if (!(msgcode & MSGCODE_FRAME_EOM)) + break; + + spin_lock_irqsave(&pulse8->msg_lock, irq_flags); + idx = (pulse8->rx_msg_cur_idx + pulse8->rx_msg_num) % + NUM_MSGS; + if (pulse8->rx_msg_num == NUM_MSGS) { + dev_warn(pulse8->dev, + "message queue is full, dropping %*ph\n", + pulse8->new_rx_msg_len, + pulse8->new_rx_msg); + spin_unlock_irqrestore(&pulse8->msg_lock, + irq_flags); + pulse8->new_rx_msg_len = 0; break; - msg->msg[msg->len++] = pulse8->buf[1]; - if (pulse8->buf[0] & MSGCODE_FRAME_EOM) - schedule_work(&pulse8->work); + } + pulse8->rx_msg_num++; + memcpy(pulse8->rx_msg[idx].msg, pulse8->new_rx_msg, + pulse8->new_rx_msg_len); + pulse8->rx_msg[idx].len = pulse8->new_rx_msg_len; + spin_unlock_irqrestore(&pulse8->msg_lock, irq_flags); + schedule_work(&pulse8->irq_work); + pulse8->new_rx_msg_len = 0; break; case MSGCODE_TRANSMIT_SUCCEEDED: - case MSGCODE_TRANSMIT_FAILED_LINE: + WARN_ON(pulse8->tx_done_status); + pulse8->tx_done_status = CEC_TX_STATUS_OK; + schedule_work(&pulse8->irq_work); + break; case MSGCODE_TRANSMIT_FAILED_ACK: + /* + * A NACK for a broadcast message makes no sense, these + * seem to be spurious messages and are skipped. + */ + if (pulse8->tx_msg_is_bcast) + break; + WARN_ON(pulse8->tx_done_status); + pulse8->tx_done_status = CEC_TX_STATUS_NACK; + schedule_work(&pulse8->irq_work); + break; + case MSGCODE_TRANSMIT_FAILED_LINE: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: - schedule_work(&pulse8->work); + WARN_ON(pulse8->tx_done_status); + pulse8->tx_done_status = CEC_TX_STATUS_ERROR; + schedule_work(&pulse8->irq_work); break; case MSGCODE_HIGH_ERROR: case MSGCODE_LOW_ERROR: case MSGCODE_RECEIVE_FAILED: case MSGCODE_TIMEOUT_ERROR: + pulse8->new_rx_msg_len = 0; break; case MSGCODE_COMMAND_ACCEPTED: case MSGCODE_COMMAND_REJECTED: @@ -229,92 +475,183 @@ static irqreturn_t pulse8_interrupt(struct serio *serio, unsigned char data, return IRQ_HANDLED; } -static void pulse8_disconnect(struct serio *serio) +static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) { - struct pulse8 *pulse8 = serio_get_drvdata(serio); + struct pulse8 *pulse8 = cec_get_drvdata(adap); + u8 cmd[16]; + int err; - cec_unregister_adapter(pulse8->adap); - cancel_delayed_work_sync(&pulse8->ping_eeprom_work); - dev_info(&serio->dev, "disconnected\n"); - serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(pulse8); + mutex_lock(&pulse8->lock); + cmd[0] = MSGCODE_SET_CONTROLLED; + cmd[1] = enable; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 1); + if (!enable) { + pulse8->rx_msg_num = 0; + pulse8->tx_done_status = 0; + } + mutex_unlock(&pulse8->lock); + return enable ? err : 0; } -static int pulse8_send(struct serio *serio, const u8 *command, u8 cmd_len) +static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) { + struct pulse8 *pulse8 = cec_get_drvdata(adap); + u16 mask = 0; + u16 pa = adap->phys_addr; + u8 cmd[16]; int err = 0; - err = serio_write(serio, MSGSTART); + mutex_lock(&pulse8->lock); + if (log_addr != CEC_LOG_ADDR_INVALID) + mask = 1 << log_addr; + cmd[0] = MSGCODE_SET_ACK_MASK; + cmd[1] = mask >> 8; + cmd[2] = mask & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); + if ((err && mask != 0) || pulse8->restoring_config) + goto unlock; + + cmd[0] = MSGCODE_SET_AUTO_ENABLED; + cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); if (err) - return err; - for (; !err && cmd_len; command++, cmd_len--) { - if (*command >= MSGESC) { - err = serio_write(serio, MSGESC); - if (!err) - err = serio_write(serio, *command - MSGOFFSET); - } else { - err = serio_write(serio, *command); - } - } - if (!err) - err = serio_write(serio, MSGEND); + goto unlock; + pulse8->autonomous = cmd[1]; + if (log_addr == CEC_LOG_ADDR_INVALID) + goto unlock; - return err; -} + cmd[0] = MSGCODE_SET_DEVICE_TYPE; + cmd[1] = adap->log_addrs.primary_device_type[0]; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; -static int pulse8_send_and_wait_once(struct pulse8 *pulse8, - const u8 *cmd, u8 cmd_len, - u8 response, u8 size) -{ - int err; + switch (adap->log_addrs.primary_device_type[0]) { + case CEC_OP_PRIM_DEVTYPE_TV: + mask = CEC_LOG_ADDR_MASK_TV; + break; + case CEC_OP_PRIM_DEVTYPE_RECORD: + mask = CEC_LOG_ADDR_MASK_RECORD; + break; + case CEC_OP_PRIM_DEVTYPE_TUNER: + mask = CEC_LOG_ADDR_MASK_TUNER; + break; + case CEC_OP_PRIM_DEVTYPE_PLAYBACK: + mask = CEC_LOG_ADDR_MASK_PLAYBACK; + break; + case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: + mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; + break; + case CEC_OP_PRIM_DEVTYPE_SWITCH: + mask = CEC_LOG_ADDR_MASK_UNREGISTERED; + break; + case CEC_OP_PRIM_DEVTYPE_PROCESSOR: + mask = CEC_LOG_ADDR_MASK_SPECIFIC; + break; + default: + mask = 0; + break; + } + cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; + cmd[1] = mask >> 8; + cmd[2] = mask & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; - /*dev_info(pulse8->dev, "transmit: %*ph\n", cmd_len, cmd);*/ - init_completion(&pulse8->cmd_done); + cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; + cmd[1] = log_addr; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; - err = pulse8_send(pulse8->serio, cmd, cmd_len); + cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; + cmd[1] = pa >> 8; + cmd[2] = pa & 0xff; + err = pulse8_send_and_wait(pulse8, cmd, 3, + MSGCODE_COMMAND_ACCEPTED, 0); if (err) - return err; + goto unlock; - if (!wait_for_completion_timeout(&pulse8->cmd_done, HZ)) - return -ETIMEDOUT; - if ((pulse8->data[0] & 0x3f) == MSGCODE_COMMAND_REJECTED && - cmd[0] != MSGCODE_SET_CONTROLLED && - cmd[0] != MSGCODE_SET_AUTO_ENABLED && - cmd[0] != MSGCODE_GET_BUILDDATE) - return -ENOTTY; - if (response && - ((pulse8->data[0] & 0x3f) != response || pulse8->len < size + 1)) { - dev_info(pulse8->dev, "transmit: failed %02x\n", - pulse8->data[0] & 0x3f); - return -EIO; + cmd[0] = MSGCODE_SET_HDMI_VERSION; + cmd[1] = adap->log_addrs.cec_version; + err = pulse8_send_and_wait(pulse8, cmd, 2, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; + + if (adap->log_addrs.osd_name[0]) { + size_t osd_len = strlen(adap->log_addrs.osd_name); + char *osd_str = cmd + 1; + + cmd[0] = MSGCODE_SET_OSD_NAME; + strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1); + if (osd_len < 4) { + memset(osd_str + osd_len, ' ', 4 - osd_len); + osd_len = 4; + osd_str[osd_len] = '\0'; + strscpy(adap->log_addrs.osd_name, osd_str, + sizeof(adap->log_addrs.osd_name)); + } + err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, + MSGCODE_COMMAND_ACCEPTED, 0); + if (err) + goto unlock; } + +unlock: + if (pulse8->restoring_config) + pulse8->restoring_config = false; + else + pulse8->config_pending = true; + mutex_unlock(&pulse8->lock); + return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err; +} + +static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, + u32 signal_free_time, struct cec_msg *msg) +{ + struct pulse8 *pulse8 = cec_get_drvdata(adap); + + pulse8->tx_msg = *msg; + if (debug) + dev_info(pulse8->dev, "adap transmit %*ph\n", + msg->len, msg->msg); + pulse8->tx_signal_free_time = signal_free_time; + schedule_work(&pulse8->tx_work); return 0; } -static int pulse8_send_and_wait(struct pulse8 *pulse8, - const u8 *cmd, u8 cmd_len, u8 response, u8 size) +static void pulse8_cec_adap_free(struct cec_adapter *adap) { - u8 cmd_sc[2]; - int err; + struct pulse8 *pulse8 = cec_get_drvdata(adap); - mutex_lock(&pulse8->write_lock); - err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, response, size); + cancel_delayed_work_sync(&pulse8->ping_eeprom_work); + cancel_work_sync(&pulse8->irq_work); + cancel_work_sync(&pulse8->tx_work); + serio_close(pulse8->serio); + serio_set_drvdata(pulse8->serio, NULL); + kfree(pulse8); +} - if (err == -ENOTTY) { - cmd_sc[0] = MSGCODE_SET_CONTROLLED; - cmd_sc[1] = 1; - err = pulse8_send_and_wait_once(pulse8, cmd_sc, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - if (err) - goto unlock; - err = pulse8_send_and_wait_once(pulse8, cmd, cmd_len, - response, size); - } +static const struct cec_adap_ops pulse8_cec_adap_ops = { + .adap_enable = pulse8_cec_adap_enable, + .adap_log_addr = pulse8_cec_adap_log_addr, + .adap_transmit = pulse8_cec_adap_transmit, + .adap_free = pulse8_cec_adap_free, +}; -unlock: - mutex_unlock(&pulse8->write_lock); - return err == -ENOTTY ? -EIO : err; +static void pulse8_disconnect(struct serio *serio) +{ + struct pulse8 *pulse8 = serio_get_drvdata(serio); + + cec_unregister_adapter(pulse8->adap); } static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, @@ -451,191 +788,34 @@ static int pulse8_apply_persistent_config(struct pulse8 *pulse8, return 0; } -static int pulse8_cec_adap_enable(struct cec_adapter *adap, bool enable) -{ - struct pulse8 *pulse8 = cec_get_drvdata(adap); - u8 cmd[16]; - int err; - - cmd[0] = MSGCODE_SET_CONTROLLED; - cmd[1] = enable; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - return enable ? err : 0; -} - -static int pulse8_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) +static void pulse8_ping_eeprom_work_handler(struct work_struct *work) { - struct pulse8 *pulse8 = cec_get_drvdata(adap); - u16 mask = 0; - u16 pa = adap->phys_addr; - u8 cmd[16]; - int err = 0; - - mutex_lock(&pulse8->config_lock); - if (log_addr != CEC_LOG_ADDR_INVALID) - mask = 1 << log_addr; - cmd[0] = MSGCODE_SET_ACK_MASK; - cmd[1] = mask >> 8; - cmd[2] = mask & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if ((err && mask != 0) || pulse8->restoring_config) - goto unlock; - - cmd[0] = MSGCODE_SET_AUTO_ENABLED; - cmd[1] = log_addr == CEC_LOG_ADDR_INVALID ? 0 : 1; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - pulse8->autonomous = cmd[1]; - if (log_addr == CEC_LOG_ADDR_INVALID) - goto unlock; - - cmd[0] = MSGCODE_SET_DEVICE_TYPE; - cmd[1] = adap->log_addrs.primary_device_type[0]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - switch (adap->log_addrs.primary_device_type[0]) { - case CEC_OP_PRIM_DEVTYPE_TV: - mask = CEC_LOG_ADDR_MASK_TV; - break; - case CEC_OP_PRIM_DEVTYPE_RECORD: - mask = CEC_LOG_ADDR_MASK_RECORD; - break; - case CEC_OP_PRIM_DEVTYPE_TUNER: - mask = CEC_LOG_ADDR_MASK_TUNER; - break; - case CEC_OP_PRIM_DEVTYPE_PLAYBACK: - mask = CEC_LOG_ADDR_MASK_PLAYBACK; - break; - case CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM: - mask = CEC_LOG_ADDR_MASK_AUDIOSYSTEM; - break; - case CEC_OP_PRIM_DEVTYPE_SWITCH: - mask = CEC_LOG_ADDR_MASK_UNREGISTERED; - break; - case CEC_OP_PRIM_DEVTYPE_PROCESSOR: - mask = CEC_LOG_ADDR_MASK_SPECIFIC; - break; - default: - mask = 0; - break; - } - cmd[0] = MSGCODE_SET_LOGICAL_ADDRESS_MASK; - cmd[1] = mask >> 8; - cmd[2] = mask & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; - - cmd[0] = MSGCODE_SET_DEFAULT_LOGICAL_ADDRESS; - cmd[1] = log_addr; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; + struct pulse8 *pulse8 = + container_of(work, struct pulse8, ping_eeprom_work.work); + u8 cmd; - cmd[0] = MSGCODE_SET_PHYSICAL_ADDRESS; - cmd[1] = pa >> 8; - cmd[2] = pa & 0xff; - err = pulse8_send_and_wait(pulse8, cmd, 3, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; + mutex_lock(&pulse8->lock); + cmd = MSGCODE_PING; + pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0); - cmd[0] = MSGCODE_SET_HDMI_VERSION; - cmd[1] = adap->log_addrs.cec_version; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) + if (pulse8->vers < 2) goto unlock; - if (adap->log_addrs.osd_name[0]) { - size_t osd_len = strlen(adap->log_addrs.osd_name); - char *osd_str = cmd + 1; - - cmd[0] = MSGCODE_SET_OSD_NAME; - strscpy(cmd + 1, adap->log_addrs.osd_name, sizeof(cmd) - 1); - if (osd_len < 4) { - memset(osd_str + osd_len, ' ', 4 - osd_len); - osd_len = 4; - osd_str[osd_len] = '\0'; - strscpy(adap->log_addrs.osd_name, osd_str, - sizeof(adap->log_addrs.osd_name)); - } - err = pulse8_send_and_wait(pulse8, cmd, 1 + osd_len, - MSGCODE_COMMAND_ACCEPTED, 0); - if (err) - goto unlock; + if (pulse8->config_pending && persistent_config) { + dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); + cmd = MSGCODE_WRITE_EEPROM; + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) + dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); + else + pulse8->config_pending = false; } - unlock: - if (pulse8->restoring_config) - pulse8->restoring_config = false; - else - pulse8->config_pending = true; - mutex_unlock(&pulse8->config_lock); - return log_addr == CEC_LOG_ADDR_INVALID ? 0 : err; -} - -static int pulse8_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg) -{ - struct pulse8 *pulse8 = cec_get_drvdata(adap); - u8 cmd[2]; - unsigned int i; - int err; - - cmd[0] = MSGCODE_TRANSMIT_IDLETIME; - cmd[1] = signal_free_time; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - cmd[0] = MSGCODE_TRANSMIT_ACK_POLARITY; - cmd[1] = cec_msg_is_broadcast(msg); - if (!err) - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - cmd[0] = msg->len == 1 ? MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; - cmd[1] = msg->msg[0]; - if (!err) - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - if (!err && msg->len > 1) { - cmd[0] = msg->len == 2 ? MSGCODE_TRANSMIT_EOM : - MSGCODE_TRANSMIT; - cmd[1] = msg->msg[1]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - for (i = 0; !err && i + 2 < msg->len; i++) { - cmd[0] = (i + 2 == msg->len - 1) ? - MSGCODE_TRANSMIT_EOM : MSGCODE_TRANSMIT; - cmd[1] = msg->msg[i + 2]; - err = pulse8_send_and_wait(pulse8, cmd, 2, - MSGCODE_COMMAND_ACCEPTED, 1); - } - } - - return err; -} - -static int pulse8_received(struct cec_adapter *adap, struct cec_msg *msg) -{ - return -ENOMSG; + schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); + mutex_unlock(&pulse8->lock); } -static const struct cec_adap_ops pulse8_cec_adap_ops = { - .adap_enable = pulse8_cec_adap_enable, - .adap_log_addr = pulse8_cec_adap_log_addr, - .adap_transmit = pulse8_cec_adap_transmit, - .received = pulse8_received, -}; - static int pulse8_connect(struct serio *serio, struct serio_driver *drv) { u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_CAP_MONITOR_ALL; @@ -658,9 +838,10 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) pulse8->dev = &serio->dev; serio_set_drvdata(serio, pulse8); - INIT_WORK(&pulse8->work, pulse8_irq_work_handler); - mutex_init(&pulse8->write_lock); - mutex_init(&pulse8->config_lock); + INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler); + INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler); + mutex_init(&pulse8->lock); + spin_lock_init(&pulse8->msg_lock); pulse8->config_pending = false; err = serio_open(serio, drv); @@ -700,33 +881,6 @@ free_device: return err; } -static void pulse8_ping_eeprom_work_handler(struct work_struct *work) -{ - struct pulse8 *pulse8 = - container_of(work, struct pulse8, ping_eeprom_work.work); - u8 cmd; - - schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); - cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); - - if (pulse8->vers < 2) - return; - - mutex_lock(&pulse8->config_lock); - if (pulse8->config_pending && persistent_config) { - dev_dbg(pulse8->dev, "writing pending config to EEPROM\n"); - cmd = MSGCODE_WRITE_EEPROM; - if (pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0)) - dev_info(pulse8->dev, "failed to write pending config to EEPROM\n"); - else - pulse8->config_pending = false; - } - mutex_unlock(&pulse8->config_lock); -} - static const struct serio_device_id pulse8_serio_ids[] = { { .type = SERIO_RS232, diff --git a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c index 79f0e0c6df37..8e81af537901 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-eeprom.c @@ -39,7 +39,7 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) int ret; int mode16 = 0; unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); + eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL); if (!eeprom) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to allocate memory required to read eeprom"); @@ -74,7 +74,6 @@ static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) (1) we're only fetching part of the eeprom, and (2) if we were getting the whole thing our I2C driver can't grab it in one pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { pcnt = 16; if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c index fb3178d909ce..f6005d1296ef 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-encoder.c @@ -284,8 +284,8 @@ rdData[0]); wrData[0] = 0x0; ret = pvr2_encoder_write_words(hdw,MBOX_BASE,wrData,1); break; - - }; LOCK_GIVE(hdw->ctl_lock); + } + LOCK_GIVE(hdw->ctl_lock); return ret; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 6fe8b9af858a..1cfb7cf64131 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -660,7 +660,7 @@ static int ctrl_check_input(struct pvr2_ctrl *cptr,int v) { if (v < 0 || v > PVR2_CVAL_INPUT_MAX) return 0; - return ((1 << v) & cptr->hdw->input_allowed_mask) != 0; + return ((1UL << v) & cptr->hdw->input_allowed_mask) != 0; } static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v) @@ -784,7 +784,7 @@ static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) { - struct v4l2_queryctrl qctrl; + struct v4l2_queryctrl qctrl = {}; struct pvr2_ctl_info *info; qctrl.id = cptr->info->v4l_id; cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); @@ -2445,7 +2445,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, /* Ensure that default input choice is a valid one. */ m = hdw->input_avail_mask; if (m) for (idx = 0; idx < (sizeof(m) << 3); idx++) { - if (!((1 << idx) & m)) continue; + if (!((1UL << idx) & m)) continue; hdw->input_val = idx; break; } @@ -2501,11 +2501,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, // Initialize control data regarding video standard masks valid_std_mask = pvr2_std_get_usable(); for (idx = 0; idx < 32; idx++) { - if (!(valid_std_mask & (1 << idx))) continue; + if (!(valid_std_mask & (1UL << idx))) continue; cnt1 = pvr2_std_id_to_str( hdw->std_mask_names[idx], sizeof(hdw->std_mask_names[idx])-1, - 1 << idx); + 1UL << idx); hdw->std_mask_names[idx][cnt1] = 0; } cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); @@ -3329,7 +3329,7 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) int ret; int mode16 = 0; unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); + eeprom = kzalloc(EEPROM_SIZE, GFP_KERNEL); if (!eeprom) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "Failed to allocate memory required to read eeprom"); @@ -3364,7 +3364,6 @@ static u8 *pvr2_full_eeprom_fetch(struct pvr2_hdw *hdw) (1) we're only fetching part of the eeprom, and (2) if we were getting the whole thing our I2C driver can't grab it in one pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { pcnt = 16; if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; @@ -4673,7 +4672,7 @@ static unsigned int print_input_mask(unsigned int msk, unsigned int idx,ccnt; unsigned int tcnt = 0; for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) { - if (!((1 << idx) & msk)) continue; + if (!((1UL << idx) & msk)) continue; ccnt = scnprintf(buf+tcnt, acnt-tcnt, "%s%s", @@ -5100,7 +5099,7 @@ int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw, break; } hdw->input_allowed_mask = nv; - if ((1 << hdw->input_val) & hdw->input_allowed_mask) { + if ((1UL << hdw->input_val) & hdw->input_allowed_mask) { /* Current mode is still in the allowed mask, so we're done. */ break; @@ -5113,7 +5112,7 @@ int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw, } m = hdw->input_allowed_mask; for (idx = 0; idx < (sizeof(m) << 3); idx++) { - if (!((1 << idx) & m)) continue; + if (!((1UL << idx) & m)) continue; pvr2_hdw_set_input(hdw,idx); break; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index 0aff2f396392..eaa08c7999d4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -898,8 +898,12 @@ static void pvr2_v4l2_internal_check(struct pvr2_channel *chp) pvr2_v4l2_dev_disassociate_parent(vp->dev_video); pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); if (!list_empty(&vp->dev_video->devbase.fh_list) || - !list_empty(&vp->dev_radio->devbase.fh_list)) + (vp->dev_radio && + !list_empty(&vp->dev_radio->devbase.fh_list))) { + pvr2_trace(PVR2_TRACE_STRUCT, + "pvr2_v4l2 internal_check exit-empty id=%p", vp); return; + } pvr2_v4l2_destroy_no_lock(vp); } @@ -935,7 +939,8 @@ static int pvr2_v4l2_release(struct file *file) kfree(fhp); if (vp->channel.mc_head->disconnect_flag && list_empty(&vp->dev_video->devbase.fh_list) && - list_empty(&vp->dev_radio->devbase.fh_list)) { + (!vp->dev_radio || + list_empty(&vp->dev_radio->devbase.fh_list))) { pvr2_v4l2_destroy_no_lock(vp); } return 0; @@ -1003,7 +1008,7 @@ static int pvr2_v4l2_open(struct file *file) input_mask &= pvr2_hdw_get_input_available(hdw); input_cnt = 0; for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { - if (input_mask & (1 << idx)) input_cnt++; + if (input_mask & (1UL << idx)) input_cnt++; } fhp->input_cnt = input_cnt; fhp->input_map = kzalloc(input_cnt,GFP_KERNEL); @@ -1018,7 +1023,7 @@ static int pvr2_v4l2_open(struct file *file) } input_cnt = 0; for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) { - if (!(input_mask & (1 << idx))) continue; + if (!(input_mask & (1UL << idx))) continue; fhp->input_map[input_cnt++] = idx; } diff --git a/drivers/media/usb/pwc/pwc-v4l.c b/drivers/media/usb/pwc/pwc-v4l.c index 76c498cccc49..2f135d533af6 100644 --- a/drivers/media/usb/pwc/pwc-v4l.c +++ b/drivers/media/usb/pwc/pwc-v4l.c @@ -873,14 +873,9 @@ static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc case 0: /* RAW format */ f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strscpy(f->description, "Raw Philips Webcam", - sizeof(f->description)); break; case 1: f->pixelformat = V4L2_PIX_FMT_YUV420; - strscpy(f->description, "4:2:0, planar, Y-Cb-Cr", - sizeof(f->description)); break; default: return -EINVAL; diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index aa90558479f7..329ec8089592 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -273,7 +273,6 @@ static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev) } struct s2255_fmt { - char *name; u32 fourcc; int depth; }; @@ -385,29 +384,23 @@ MODULE_DEVICE_TABLE(usb, s2255_table); /* JPEG formats must be defined last to support jpeg_enable parameter */ static const struct s2255_fmt formats[] = { { - .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16 }, { - .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16 }, { - .name = "4:2:2, planar, YUV422P", .fourcc = V4L2_PIX_FMT_YUV422P, .depth = 16 }, { - .name = "8bpp GREY", .fourcc = V4L2_PIX_FMT_GREY, .depth = 8 }, { - .name = "JPG", .fourcc = V4L2_PIX_FMT_JPEG, .depth = 24 }, { - .name = "MJPG", .fourcc = V4L2_PIX_FMT_MJPEG, .depth = 24 } @@ -737,7 +730,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) || (formats[index].fourcc == V4L2_PIX_FMT_MJPEG))) return -EINVAL; - strscpy(f->description, formats[index].name, sizeof(f->description)); f->pixelformat = formats[index].fourcc; return 0; } @@ -759,7 +751,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - f->fmt.pix.priv = 0; return 0; } @@ -811,7 +802,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - f->fmt.pix.priv = 0; dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); return 0; diff --git a/drivers/media/usb/stk1160/stk1160-v4l.c b/drivers/media/usb/stk1160/stk1160-v4l.c index b71a0f4b40b5..bcd14c66e8df 100644 --- a/drivers/media/usb/stk1160/stk1160-v4l.c +++ b/drivers/media/usb/stk1160/stk1160-v4l.c @@ -46,7 +46,6 @@ struct stk1160_decimate_ctrl { /* supported video standards */ static struct stk1160_fmt format[] = { { - .name = "16 bpp YUY2, 4:2:2, packed", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16, } @@ -346,7 +345,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (f->index != 0) return -EINVAL; - strscpy(f->description, format[f->index].name, sizeof(f->description)); f->pixelformat = format[f->index].fourcc; return 0; } diff --git a/drivers/media/usb/stk1160/stk1160.h b/drivers/media/usb/stk1160/stk1160.h index 099ce2a2f021..a31ea1c80f25 100644 --- a/drivers/media/usb/stk1160/stk1160.h +++ b/drivers/media/usb/stk1160/stk1160.h @@ -102,7 +102,6 @@ struct stk1160_isoc_ctl { }; struct stk1160_fmt { - char *name; u32 fourcc; /* v4l2 format id */ int depth; }; diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index be8041e3e6b8..b22501f76b78 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -643,8 +643,7 @@ static int v4l_stk_release(struct file *fp) dev->owner = NULL; } - if (is_present(dev)) - usb_autopm_put_interface(dev->interface); + usb_autopm_put_interface(dev->interface); mutex_unlock(&dev->lock); return v4l2_fh_release(fp); } @@ -857,23 +856,18 @@ static int stk_vidioc_enum_fmt_vid_cap(struct file *filp, switch (fmtd->index) { case 0: fmtd->pixelformat = V4L2_PIX_FMT_RGB565; - strscpy(fmtd->description, "r5g6b5", sizeof(fmtd->description)); break; case 1: fmtd->pixelformat = V4L2_PIX_FMT_RGB565X; - strscpy(fmtd->description, "r5g6b5BE", sizeof(fmtd->description)); break; case 2: fmtd->pixelformat = V4L2_PIX_FMT_UYVY; - strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description)); break; case 3: fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8; - strscpy(fmtd->description, "Raw bayer", sizeof(fmtd->description)); break; case 4: fmtd->pixelformat = V4L2_PIX_FMT_YUYV; - strscpy(fmtd->description, "yuv4:2:2", sizeof(fmtd->description)); break; default: return -EINVAL; @@ -1131,7 +1125,7 @@ static int stk_vidioc_dqbuf(struct file *filp, sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED; sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE; sbuf->v4lbuf.sequence = ++dev->sequence; - sbuf->v4lbuf.timestamp = ns_to_timeval(ktime_get_ns()); + v4l2_buffer_set_timestamp(&sbuf->v4lbuf, ktime_get_ns()); *buf = sbuf->v4lbuf; return 0; diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c index d6c79c13b332..c26a0ff60a64 100644 --- a/drivers/media/usb/tm6000/tm6000-alsa.c +++ b/drivers/media/usb/tm6000/tm6000-alsa.c @@ -10,7 +10,6 @@ #include <linux/interrupt.h> #include <linux/usb.h> #include <linux/slab.h> -#include <linux/vmalloc.h> #include <linux/delay.h> #include <sound/core.h> @@ -94,40 +93,6 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip) return 0; } -static void dsp_buffer_free(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - dprintk(2, "Freeing buffer\n"); - - vfree(substream->runtime->dma_area); - substream->runtime->dma_area = NULL; - substream->runtime->dma_bytes = 0; -} - -static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - dprintk(2, "Allocating buffer\n"); - - if (substream->runtime->dma_area) { - if (substream->runtime->dma_bytes > size) - return 0; - - dsp_buffer_free(substream); - } - - substream->runtime->dma_area = vmalloc(size); - if (!substream->runtime->dma_area) - return -ENOMEM; - - substream->runtime->dma_bytes = size; - - return 0; -} - - /**************************************************************************** ALSA PCM Interface ****************************************************************************/ @@ -269,40 +234,6 @@ static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) } /* - * hw_params callback - */ -static int snd_tm6000_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - int size, rc; - - size = params_period_bytes(hw_params) * params_periods(hw_params); - - rc = dsp_buffer_alloc(substream, size); - if (rc < 0) - return rc; - - return 0; -} - -/* - * hw free callback - */ -static int snd_tm6000_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - struct tm6000_core *core = chip->core; - - if (atomic_read(&core->stream_started) > 0) { - atomic_set(&core->stream_started, 0); - schedule_work(&core->wq_trigger); - } - - dsp_buffer_free(substream); - return 0; -} - -/* * prepare callback */ static int snd_tm6000_prepare(struct snd_pcm_substream *substream) @@ -369,27 +300,15 @@ static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream) return chip->buf_pos; } -static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, - unsigned long offset) -{ - void *pageptr = subs->runtime->dma_area + offset; - - return vmalloc_to_page(pageptr); -} - /* * operators */ static const struct snd_pcm_ops snd_tm6000_pcm_ops = { .open = snd_tm6000_pcm_open, .close = snd_tm6000_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_tm6000_hw_params, - .hw_free = snd_tm6000_hw_free, .prepare = snd_tm6000_prepare, .trigger = snd_tm6000_card_trigger, .pointer = snd_tm6000_pointer, - .page = snd_pcm_get_vmalloc_page, }; /* @@ -459,6 +378,7 @@ static int tm6000_audio_init(struct tm6000_core *dev) strscpy(pcm->name, "Trident TM5600/60x0", sizeof(pcm->name)); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_VMALLOC, NULL, 0, 0); INIT_WORK(&dev->wq_trigger, audio_trigger); rc = snd_card_register(card); diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c index 23df50aa0a4a..5358cd8c4603 100644 --- a/drivers/media/usb/tm6000/tm6000-cards.c +++ b/drivers/media/usb/tm6000/tm6000-cards.c @@ -1328,7 +1328,7 @@ put_device: /* * tm6000_usb_disconnect() - * called when the device gets diconencted + * called when the device gets disconnected * video device will be unregistered on v4l2_close in case it is still open */ static void tm6000_usb_disconnect(struct usb_interface *interface) diff --git a/drivers/media/usb/tm6000/tm6000-dvb.c b/drivers/media/usb/tm6000/tm6000-dvb.c index e4d2dcd5cc0f..19c90fa9e443 100644 --- a/drivers/media/usb/tm6000/tm6000-dvb.c +++ b/drivers/media/usb/tm6000/tm6000-dvb.c @@ -97,6 +97,7 @@ static void tm6000_urb_received(struct urb *urb) printk(KERN_ERR "tm6000: error %s\n", __func__); kfree(urb->transfer_buffer); usb_free_urb(urb); + dev->dvb->bulk_urb = NULL; } } } @@ -127,6 +128,7 @@ static int tm6000_start_stream(struct tm6000_core *dev) dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); if (!dvb->bulk_urb->transfer_buffer) { usb_free_urb(dvb->bulk_urb); + dvb->bulk_urb = NULL; return -ENOMEM; } @@ -153,6 +155,7 @@ static int tm6000_start_stream(struct tm6000_core *dev) kfree(dvb->bulk_urb->transfer_buffer); usb_free_urb(dvb->bulk_urb); + dvb->bulk_urb = NULL; return ret; } diff --git a/drivers/media/usb/tm6000/tm6000-regs.h b/drivers/media/usb/tm6000/tm6000-regs.h index d10424673db9..6a181f2e7ef2 100644 --- a/drivers/media/usb/tm6000/tm6000-regs.h +++ b/drivers/media/usb/tm6000/tm6000-regs.h @@ -1,5 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * SPDX-License-Identifier: GPL-2.0 * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices * * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h b/drivers/media/usb/tm6000/tm6000-usb-isoc.h index b275dbce3a1b..e3c6933f854d 100644 --- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h +++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h @@ -1,5 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * SPDX-License-Identifier: GPL-2.0 * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices * * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c index 85fcddfb0202..c07a81a6cbe2 100644 --- a/drivers/media/usb/tm6000/tm6000-video.c +++ b/drivers/media/usb/tm6000/tm6000-video.c @@ -52,15 +52,12 @@ EXPORT_SYMBOL_GPL(tm6000_debug); static struct tm6000_fmt format[] = { { - .name = "4:2:2, packed, YVY2", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, }, { - .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16, }, { - .name = "A/V + VBI mux packet", .fourcc = V4L2_PIX_FMT_TM6000, .depth = 16, } @@ -875,7 +872,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, if (f->index >= ARRAY_SIZE(format)) return -EINVAL; - strscpy(f->description, format[f->index].name, sizeof(f->description)); f->pixelformat = format[f->index].fourcc; return 0; } diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h index 0864ed7314eb..c08c95312739 100644 --- a/drivers/media/usb/tm6000/tm6000.h +++ b/drivers/media/usb/tm6000/tm6000.h @@ -1,5 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * SPDX-License-Identifier: GPL-2.0 * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices * * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@kernel.org> @@ -64,7 +64,6 @@ struct tm6000_input { */ struct tm6000_fmt { - char *name; u32 fourcc; /* v4l2 format id */ int depth; }; diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index 1d0afa340f47..3198f9624b7c 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -319,7 +319,7 @@ static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, dprintk("%s\n", __func__); - b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); + b = kzalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); if (!b) return -ENOMEM; diff --git a/drivers/media/usb/usbtv/usbtv-audio.c b/drivers/media/usb/usbtv/usbtv-audio.c index 6f108996142d..b57e94fb1977 100644 --- a/drivers/media/usb/usbtv/usbtv-audio.c +++ b/drivers/media/usb/usbtv/usbtv-audio.c @@ -85,30 +85,6 @@ static int snd_usbtv_pcm_close(struct snd_pcm_substream *substream) return 0; } -static int snd_usbtv_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - int rv; - struct usbtv *chip = snd_pcm_substream_chip(substream); - - rv = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - - if (rv < 0) { - dev_warn(chip->dev, "pcm audio buffer allocation failure %i\n", - rv); - return rv; - } - - return 0; -} - -static int snd_usbtv_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_lib_free_pages(substream); - return 0; -} - static int snd_usbtv_prepare(struct snd_pcm_substream *substream) { struct usbtv *chip = snd_pcm_substream_chip(substream); @@ -336,9 +312,6 @@ static snd_pcm_uframes_t snd_usbtv_pointer(struct snd_pcm_substream *substream) static const struct snd_pcm_ops snd_usbtv_pcm_ops = { .open = snd_usbtv_pcm_open, .close = snd_usbtv_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_usbtv_hw_params, - .hw_free = snd_usbtv_hw_free, .prepare = snd_usbtv_prepare, .trigger = snd_usbtv_card_trigger, .pointer = snd_usbtv_pointer, @@ -377,9 +350,8 @@ int usbtv_audio_init(struct usbtv *usbtv) pcm->private_data = usbtv; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usbtv_pcm_ops); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), USBTV_AUDIO_BUFFER, - USBTV_AUDIO_BUFFER); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + NULL, USBTV_AUDIO_BUFFER, USBTV_AUDIO_BUFFER); rv = snd_card_register(card); if (rv) diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index 51f784479e91..3d9284a09ee5 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -633,8 +633,6 @@ static int usbtv_enum_fmt_vid_cap(struct file *file, void *priv, if (f->index > 0) return -EINVAL; - strscpy(f->description, "16 bpp YUY2, 4:2:2, packed", - sizeof(f->description)); f->pixelformat = V4L2_PIX_FMT_YUYV; return 0; } diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index 93750af82d98..5ca2c2f35fe2 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -87,14 +87,14 @@ static int usbvision_nr; static struct usbvision_v4l2_format_st usbvision_v4l2_format[] = { - { 1, 1, 8, V4L2_PIX_FMT_GREY , "GREY" }, - { 1, 2, 16, V4L2_PIX_FMT_RGB565 , "RGB565" }, - { 1, 3, 24, V4L2_PIX_FMT_RGB24 , "RGB24" }, - { 1, 4, 32, V4L2_PIX_FMT_RGB32 , "RGB32" }, - { 1, 2, 16, V4L2_PIX_FMT_RGB555 , "RGB555" }, - { 1, 2, 16, V4L2_PIX_FMT_YUYV , "YUV422" }, - { 1, 2, 12, V4L2_PIX_FMT_YVU420 , "YUV420P" }, /* 1.5 ! */ - { 1, 2, 16, V4L2_PIX_FMT_YUV422P , "YUV422P" } + { 1, 1, 8, V4L2_PIX_FMT_GREY }, + { 1, 2, 16, V4L2_PIX_FMT_RGB565 }, + { 1, 3, 24, V4L2_PIX_FMT_RGB24 }, + { 1, 4, 32, V4L2_PIX_FMT_RGB32 }, + { 1, 2, 16, V4L2_PIX_FMT_RGB555 }, + { 1, 2, 16, V4L2_PIX_FMT_YUYV }, + { 1, 2, 12, V4L2_PIX_FMT_YVU420 }, /* 1.5 ! */ + { 1, 2, 16, V4L2_PIX_FMT_YUV422P } }; /* Function prototypes */ @@ -314,6 +314,10 @@ static int usbvision_v4l2_open(struct file *file) if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto unlock; + } if (usbvision->user) { err_code = -EBUSY; } else { @@ -377,6 +381,7 @@ unlock: static int usbvision_v4l2_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, "close"); @@ -391,9 +396,10 @@ static int usbvision_v4l2_close(struct file *file) usbvision_scratch_free(usbvision); usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); return 0; @@ -453,6 +459,9 @@ static int vidioc_querycap(struct file *file, void *priv, { struct usb_usbvision *usbvision = video_drvdata(file); + if (!usbvision->dev) + return -ENODEV; + strscpy(vc->driver, "USBVision", sizeof(vc->driver)); strscpy(vc->card, usbvision_device_data[usbvision->dev_model].model_string, @@ -687,7 +696,7 @@ static int vidioc_querybuf(struct file *file, vb->length = usbvision->curwidth * usbvision->curheight * usbvision->palette.bytes_per_pixel; - vb->timestamp = ns_to_timeval(usbvision->frame[vb->index].ts); + v4l2_buffer_set_timestamp(vb, usbvision->frame[vb->index].ts); vb->sequence = usbvision->frame[vb->index].sequence; return 0; } @@ -756,7 +765,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *vb) V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; vb->index = f->index; vb->sequence = f->sequence; - vb->timestamp = ns_to_timeval(f->ts); + v4l2_buffer_set_timestamp(vb, f->ts); vb->field = V4L2_FIELD_NONE; vb->bytesused = f->scanlength; @@ -796,8 +805,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, { if (vfd->index >= USBVISION_SUPPORTED_PALETTES - 1) return -EINVAL; - strscpy(vfd->description, usbvision_v4l2_format[vfd->index].desc, - sizeof(vfd->description)); vfd->pixelformat = usbvision_v4l2_format[vfd->index].format; return 0; } @@ -967,7 +974,6 @@ static ssize_t usbvision_read(struct file *file, char __user *buf, __func__, (unsigned long)count, frame->bytes_read); -#if 1 /* * FIXME: * For now, forget the frame if it has not been read in one shot. @@ -976,15 +982,6 @@ static ssize_t usbvision_read(struct file *file, char __user *buf, /* Mark it as available to be used again. */ frame->grabstate = frame_state_unused; -#else - if (frame->bytes_read >= frame->scanlength) { - /* All data has been read */ - frame->bytes_read = 0; - - /* Mark it as available to be used again. */ - frame->grabstate = frame_state_unused; - } -#endif return count; } @@ -1073,6 +1070,11 @@ static int usbvision_radio_open(struct file *file) if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto out; + } err_code = v4l2_fh_open(file); if (err_code) goto out; @@ -1105,21 +1107,24 @@ out: static int usbvision_radio_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, ""); mutex_lock(&usbvision->v4l2_lock); /* Set packet size to 0 */ usbvision->iface_alt = 0; - usb_set_interface(usbvision->dev, usbvision->iface, - usbvision->iface_alt); + if (usbvision->dev) + usb_set_interface(usbvision->dev, usbvision->iface, + usbvision->iface_alt); usbvision_audio_off(usbvision); usbvision->radio = 0; usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); v4l2_fh_release(file); usbvision_release(usbvision); @@ -1551,6 +1556,7 @@ err_usb: static void usbvision_disconnect(struct usb_interface *intf) { struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf)); + int u; PDEBUG(DBG_PROBE, ""); @@ -1567,13 +1573,14 @@ static void usbvision_disconnect(struct usb_interface *intf) v4l2_device_disconnect(&usbvision->v4l2_dev); usbvision_i2c_unregister(usbvision); usbvision->remove_pending = 1; /* Now all ISO data will be ignored */ + u = usbvision->user; usb_put_dev(usbvision->dev); usbvision->dev = NULL; /* USB device is no more */ mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->user) { + if (u) { printk(KERN_INFO "%s: In use, disconnect pending\n", __func__); wake_up_interruptible(&usbvision->wait_frame); diff --git a/drivers/media/usb/usbvision/usbvision.h b/drivers/media/usb/usbvision/usbvision.h index 4198f972a47b..11539578e8d2 100644 --- a/drivers/media/usb/usbvision/usbvision.h +++ b/drivers/media/usb/usbvision/usbvision.h @@ -264,7 +264,6 @@ struct usbvision_v4l2_format_st { int bytes_per_pixel; int depth; int format; - char *desc; }; #define USBVISION_SUPPORTED_PALETTES ARRAY_SIZE(usbvision_v4l2_format) diff --git a/drivers/media/usb/uvc/uvc_debugfs.c b/drivers/media/usb/uvc/uvc_debugfs.c index d2b109959d82..2b8af4b54117 100644 --- a/drivers/media/usb/uvc/uvc_debugfs.c +++ b/drivers/media/usb/uvc/uvc_debugfs.c @@ -108,15 +108,7 @@ void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream) void uvc_debugfs_init(void) { - struct dentry *dir; - - dir = debugfs_create_dir("uvcvideo", usb_debug_root); - if (IS_ERR_OR_NULL(dir)) { - uvc_printk(KERN_INFO, "Unable to create debugfs directory\n"); - return; - } - - uvc_debugfs_root_dir = dir; + uvc_debugfs_root_dir = debugfs_create_dir("uvcvideo", usb_debug_root); } void uvc_debugfs_cleanup(void) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 66ee168ddc7e..99883550375e 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -497,6 +497,22 @@ static int uvc_parse_format(struct uvc_device *dev, } } + /* Some devices report bpp that doesn't match the format. */ + if (dev->quirks & UVC_QUIRK_FORCE_BPP) { + const struct v4l2_format_info *info = + v4l2_format_info(format->fcc); + + if (info) { + unsigned int div = info->hdiv * info->vdiv; + + n = info->bpp[0] * div; + for (i = 1; i < info->comp_planes; i++) + n += info->bpp[i]; + + format->bpp = DIV_ROUND_UP(8 * n, div); + } + } + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { @@ -1493,6 +1509,11 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, break; if (forward == prev) continue; + if (forward->chain.next || forward->chain.prev) { + uvc_trace(UVC_TRACE_DESCR, "Found reference to " + "entity %d already in chain.\n", forward->id); + return -EINVAL; + } switch (UVC_ENTITY_TYPE(forward)) { case UVC_VC_EXTENSION_UNIT: @@ -1574,6 +1595,13 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain, return -1; } + if (term->chain.next || term->chain.prev) { + uvc_trace(UVC_TRACE_DESCR, "Found reference to " + "entity %d already in chain.\n", + term->id); + return -EINVAL; + } + if (uvc_trace_param & UVC_TRACE_PROBE) printk(KERN_CONT " %d", term->id); @@ -2151,6 +2179,20 @@ static int uvc_probe(struct usb_interface *intf, sizeof(dev->name) - len); } + /* Initialize the media device. */ +#ifdef CONFIG_MEDIA_CONTROLLER + dev->mdev.dev = &intf->dev; + strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); + if (udev->serial) + strscpy(dev->mdev.serial, udev->serial, + sizeof(dev->mdev.serial)); + usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); + dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); + media_device_init(&dev->mdev); + + dev->vdev.mdev = &dev->mdev; +#endif + /* Parse the Video Class control descriptor. */ if (uvc_parse_control(dev) < 0) { uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC " @@ -2171,19 +2213,7 @@ static int uvc_probe(struct usb_interface *intf, "linux-uvc-devel mailing list.\n"); } - /* Initialize the media device and register the V4L2 device. */ -#ifdef CONFIG_MEDIA_CONTROLLER - dev->mdev.dev = &intf->dev; - strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); - if (udev->serial) - strscpy(dev->mdev.serial, udev->serial, - sizeof(dev->mdev.serial)); - usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); - dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); - media_device_init(&dev->mdev); - - dev->vdev.mdev = &dev->mdev; -#endif + /* Register the V4L2 device. */ if (v4l2_device_register(&intf->dev, &dev->vdev) < 0) goto error; @@ -2860,6 +2890,15 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 }, + /* GEO Semiconductor GC6500 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x29fe, + .idProduct = 0x4d53, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) }, /* Intel RealSense D4M */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c index 99bb71b47117..b6279ad7ac84 100644 --- a/drivers/media/usb/uvc/uvc_metadata.c +++ b/drivers/media/usb/uvc/uvc_metadata.c @@ -51,7 +51,7 @@ static int uvc_meta_v4l2_get_format(struct file *file, void *fh, memset(fmt, 0, sizeof(*fmt)); fmt->dataformat = stream->meta.format; - fmt->buffersize = UVC_METATADA_BUF_SIZE; + fmt->buffersize = UVC_METADATA_BUF_SIZE; return 0; } @@ -72,7 +72,7 @@ static int uvc_meta_v4l2_try_format(struct file *file, void *fh, fmt->dataformat = fmeta == dev->info->meta_format ? fmeta : V4L2_META_FMT_UVC; - fmt->buffersize = UVC_METATADA_BUF_SIZE; + fmt->buffersize = UVC_METADATA_BUF_SIZE; return 0; } diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index da72577c2998..cd60c6c1749e 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -79,7 +79,7 @@ static int uvc_queue_setup(struct vb2_queue *vq, switch (vq->type) { case V4L2_BUF_TYPE_META_CAPTURE: - size = UVC_METATADA_BUF_SIZE; + size = UVC_METADATA_BUF_SIZE; break; default: diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 203329cadbc4..0335e69b70ab 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -253,7 +253,6 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame); fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize; fmt->fmt.pix.colorspace = format->colorspace; - fmt->fmt.pix.priv = 0; if (uvc_format != NULL) *uvc_format = format; @@ -290,7 +289,6 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream, fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame); fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize; fmt->fmt.pix.colorspace = format->colorspace; - fmt->fmt.pix.priv = 0; done: mutex_unlock(&stream->mutex); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index c7c1baa90dea..6ab972c643e3 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -198,6 +198,7 @@ #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 #define UVC_QUIRK_FORCE_Y8 0x00000800 +#define UVC_QUIRK_FORCE_BPP 0x00001000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -491,7 +492,7 @@ struct uvc_stats_stream { unsigned int max_sof; /* Maximum STC.SOF value */ }; -#define UVC_METATADA_BUF_SIZE 1024 +#define UVC_METADATA_BUF_SIZE 1024 /** * struct uvc_copy_op: Context structure to schedule asynchronous memcpy diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index a9bcba4fa9c6..57dbcc8083bf 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -20,7 +20,6 @@ #include <linux/usb.h> #include <linux/vmalloc.h> #include <linux/slab.h> -#include <linux/proc_fs.h> #include <linux/highmem.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> @@ -141,7 +140,6 @@ struct zr364xx_pipeinfo { }; struct zr364xx_fmt { - char *name; u32 fourcc; int depth; }; @@ -149,7 +147,6 @@ struct zr364xx_fmt { /* image formats. */ static const struct zr364xx_fmt formats[] = { { - .name = "JPG", .fourcc = V4L2_PIX_FMT_JPEG, .depth = 24 } @@ -199,12 +196,10 @@ static int send_control_msg(struct usb_device *udev, u8 request, u16 value, { int status; - unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL); + unsigned char *transfer_buffer = kmemdup(cp, size, GFP_KERNEL); if (!transfer_buffer) return -ENOMEM; - memcpy(transfer_buffer, cp, size); - status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, @@ -376,8 +371,7 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, vb); int rc; - DBG("%s, field=%d, fmt name = %s\n", __func__, field, - cam->fmt ? cam->fmt->name : ""); + DBG("%s, field=%d\n", __func__, field); if (!cam->fmt) return -EINVAL; @@ -561,14 +555,12 @@ static int zr364xx_read_video_callback(struct zr364xx_camera *cam, { unsigned char *pdest; unsigned char *psrc; - s32 idx = -1; - struct zr364xx_framei *frm; + s32 idx = cam->cur_frame; + struct zr364xx_framei *frm = &cam->buffer.frame[idx]; int i = 0; unsigned char *ptr = NULL; _DBG("buffer to user\n"); - idx = cam->cur_frame; - frm = &cam->buffer.frame[idx]; /* swap bytes if camera needs it */ if (cam->method == METHOD0) { @@ -751,8 +743,6 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file, { if (f->index > 0) return -EINVAL; - f->flags = V4L2_FMT_FLAG_COMPRESSED; - strscpy(f->description, formats[0].name, sizeof(f->description)); f->pixelformat = formats[0].fourcc; return 0; } |