Lines Matching +full:row +full:- +full:hold
1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * <elezegarcia--a.t--gmail.com>
10 * <rmthomas--a.t--sciolus.org>
19 #include <media/v4l2-device.h>
20 #include <media/v4l2-common.h>
21 #include <media/v4l2-ioctl.h>
22 #include <media/v4l2-fh.h>
23 #include <media/v4l2-event.h>
24 #include <media/videobuf2-vmalloc.h>
29 #include "stk1160-reg.h"
110 if (dev->norm & V4L2_STD_525_60) { in stk1160_set_std()
135 val |= ctrl->col_en ? STK1160_H_DEC_EN : 0; in stk1160_set_fmt()
136 val |= ctrl->row_en ? STK1160_V_DEC_EN : 0; in stk1160_set_fmt()
137 val |= ctrl->col_mode == in stk1160_set_fmt()
140 val |= ctrl->row_mode == in stk1160_set_fmt()
145 stk1160_write_reg(dev, STK1160_DMCTRL_H_UNITS, ctrl->col_n); in stk1160_set_fmt()
147 stk1160_write_reg(dev, STK1160_DMCTRL_V_UNITS, ctrl->row_n); in stk1160_set_fmt()
149 stk1160_dbg("decimate 0x%x, column units %d, row units %d\n", in stk1160_set_fmt()
150 val, ctrl->col_n, ctrl->row_n); in stk1160_set_fmt()
159 * Returns true is dev->max_pkt_size has changed, false otherwise.
163 int i, prev_alt = dev->alt; in stk1160_set_alternate()
173 for (i = 0; i < dev->num_alt; i++) { in stk1160_set_alternate()
175 if (dev->alt_max_pkt_size[i] >= min_pkt_size) { in stk1160_set_alternate()
176 dev->alt = i; in stk1160_set_alternate()
182 } else if (dev->alt_max_pkt_size[i] > in stk1160_set_alternate()
183 dev->alt_max_pkt_size[dev->alt]) in stk1160_set_alternate()
184 dev->alt = i; in stk1160_set_alternate()
187 stk1160_dbg("setting alternate %d\n", dev->alt); in stk1160_set_alternate()
189 if (dev->alt != prev_alt) { in stk1160_set_alternate()
191 min_pkt_size, dev->alt); in stk1160_set_alternate()
193 dev->alt, dev->alt_max_pkt_size[dev->alt]); in stk1160_set_alternate()
194 usb_set_interface(dev->udev, 0, dev->alt); in stk1160_set_alternate()
197 new_pkt_size = dev->max_pkt_size != dev->alt_max_pkt_size[dev->alt]; in stk1160_set_alternate()
198 dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; in stk1160_set_alternate()
210 if (!dev->udev) in stk1160_start_streaming()
211 return -ENODEV; in stk1160_start_streaming()
213 if (mutex_lock_interruptible(&dev->v4l_lock)) in stk1160_start_streaming()
214 return -ERESTARTSYS; in stk1160_start_streaming()
225 * a new dev->max_pkt_size is detected in stk1160_start_streaming()
227 if (!dev->isoc_ctl.num_bufs || new_pkt_size) { in stk1160_start_streaming()
234 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { in stk1160_start_streaming()
235 rc = usb_submit_urb(dev->isoc_ctl.urb_ctl[i].urb, GFP_KERNEL); in stk1160_start_streaming()
243 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); in stk1160_start_streaming()
245 dev->sequence = 0; in stk1160_start_streaming()
253 mutex_unlock(&dev->v4l_lock); in stk1160_start_streaming()
260 usb_set_interface(dev->udev, 0, 0); in stk1160_start_streaming()
263 mutex_unlock(&dev->v4l_lock); in stk1160_start_streaming()
268 /* Must be called with v4l_lock hold */
272 if (!dev->udev) in stk1160_stop_hw()
276 dev->alt = 0; in stk1160_stop_hw()
277 stk1160_dbg("setting alternate %d\n", dev->alt); in stk1160_stop_hw()
278 usb_set_interface(dev->udev, 0, 0); in stk1160_stop_hw()
285 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); in stk1160_stop_hw()
290 if (mutex_lock_interruptible(&dev->v4l_lock)) in stk1160_stop_streaming()
291 return -ERESTARTSYS; in stk1160_stop_streaming()
296 * current buffer (dev->isoc_ctl.buf). in stk1160_stop_streaming()
313 mutex_unlock(&dev->v4l_lock); in stk1160_stop_streaming()
336 strscpy(cap->driver, "stk1160", sizeof(cap->driver)); in vidioc_querycap()
337 strscpy(cap->card, "stk1160", sizeof(cap->card)); in vidioc_querycap()
338 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); in vidioc_querycap()
345 if (f->index != 0) in vidioc_enum_fmt_vid_cap()
346 return -EINVAL; in vidioc_enum_fmt_vid_cap()
348 f->pixelformat = format[f->index].fourcc; in vidioc_enum_fmt_vid_cap()
357 f->fmt.pix.width = dev->width; in vidioc_g_fmt_vid_cap()
358 f->fmt.pix.height = dev->height; in vidioc_g_fmt_vid_cap()
359 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in vidioc_g_fmt_vid_cap()
360 f->fmt.pix.pixelformat = dev->fmt->fourcc; in vidioc_g_fmt_vid_cap()
361 f->fmt.pix.bytesperline = dev->width * 2; in vidioc_g_fmt_vid_cap()
362 f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; in vidioc_g_fmt_vid_cap()
363 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in vidioc_g_fmt_vid_cap()
378 base_height = (dev->norm & V4L2_STD_525_60) ? 480 : 576; in stk1160_try_fmt()
381 width = clamp_t(unsigned int, f->fmt.pix.width, in stk1160_try_fmt()
383 height = clamp_t(unsigned int, f->fmt.pix.height, in stk1160_try_fmt()
391 f->fmt.pix.width = base_width; in stk1160_try_fmt()
392 f->fmt.pix.height = base_height; in stk1160_try_fmt()
401 * n = width / (frame width - width) in stk1160_try_fmt()
407 col_n = div_round_integer(width, base_width - width); in stk1160_try_fmt()
411 f->fmt.pix.width = (base_width * col_n) / (col_n + 1); in stk1160_try_fmt()
420 * n = (frame width / width) - 1 in stk1160_try_fmt()
426 col_n = div_round_integer(base_width, width) - 1; in stk1160_try_fmt()
430 f->fmt.pix.width = base_width / (col_n + 1); in stk1160_try_fmt()
435 row_n = div_round_integer(height, base_height - height); in stk1160_try_fmt()
439 f->fmt.pix.height = (base_height * row_n) / (row_n + 1); in stk1160_try_fmt()
443 row_n = div_round_integer(base_height, height) - 1; in stk1160_try_fmt()
447 f->fmt.pix.height = base_height / (row_n + 1); in stk1160_try_fmt()
451 f->fmt.pix.pixelformat = dev->fmt->fourcc; in stk1160_try_fmt()
452 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in stk1160_try_fmt()
453 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; in stk1160_try_fmt()
454 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; in stk1160_try_fmt()
455 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in stk1160_try_fmt()
458 ctrl->col_en = col_en; in stk1160_try_fmt()
459 ctrl->col_n = col_n; in stk1160_try_fmt()
460 ctrl->col_mode = col_mode; in stk1160_try_fmt()
461 ctrl->row_en = row_en; in stk1160_try_fmt()
462 ctrl->row_n = row_n; in stk1160_try_fmt()
463 ctrl->row_mode = row_mode; in stk1160_try_fmt()
467 f->fmt.pix.width, f->fmt.pix.height); in stk1160_try_fmt()
483 struct vb2_queue *q = &dev->vb_vidq; in vidioc_s_fmt_vid_cap()
488 return -EBUSY; in vidioc_s_fmt_vid_cap()
493 dev->width = f->fmt.pix.width; in vidioc_s_fmt_vid_cap()
494 dev->height = f->fmt.pix.height; in vidioc_s_fmt_vid_cap()
503 v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm); in vidioc_querystd()
511 *norm = dev->norm; in vidioc_g_std()
518 struct vb2_queue *q = &dev->vb_vidq; in vidioc_s_std()
520 if (dev->norm == norm) in vidioc_s_std()
524 return -EBUSY; in vidioc_s_std()
527 if (!dev->udev) in vidioc_s_std()
528 return -ENODEV; in vidioc_s_std()
531 dev->width = 720; in vidioc_s_std()
532 dev->height = (norm & V4L2_STD_525_60) ? 480 : 576; in vidioc_s_std()
533 dev->norm = norm; in vidioc_s_std()
540 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, in vidioc_s_std()
541 dev->norm); in vidioc_s_std()
552 if (i->index > STK1160_MAX_INPUT) in vidioc_enum_input()
553 return -EINVAL; in vidioc_enum_input()
555 /* S-Video special handling */ in vidioc_enum_input()
556 if (i->index == STK1160_SVIDEO_INPUT) in vidioc_enum_input()
557 sprintf(i->name, "S-Video"); in vidioc_enum_input()
559 sprintf(i->name, "Composite%d", i->index); in vidioc_enum_input()
561 i->type = V4L2_INPUT_TYPE_CAMERA; in vidioc_enum_input()
562 i->std = dev->vdev.tvnorms; in vidioc_enum_input()
569 *i = dev->ctl_input; in vidioc_g_input()
578 return -EINVAL; in vidioc_s_input()
580 dev->ctl_input = i; in vidioc_s_input()
596 rc = stk1160_read_reg(dev, reg->reg, &val); in vidioc_g_register()
597 reg->val = val; in vidioc_g_register()
598 reg->size = 1; in vidioc_g_register()
609 return stk1160_write_reg(dev, reg->reg, reg->val); in vidioc_s_register()
657 size = dev->width * dev->height * 2; in queue_setup()
667 return sizes[0] < size ? -EINVAL : 0; in queue_setup()
683 struct stk1160 *dev = vb2_get_drv_priv(vb->vb2_queue); in buffer_queue()
688 spin_lock_irqsave(&dev->buf_lock, flags); in buffer_queue()
689 if (!dev->udev) { in buffer_queue()
692 * directly. The next QBUF call will fail with -ENODEV. in buffer_queue()
694 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in buffer_queue()
697 buf->mem = vb2_plane_vaddr(vb, 0); in buffer_queue()
698 buf->length = vb2_plane_size(vb, 0); in buffer_queue()
699 buf->bytesused = 0; in buffer_queue()
700 buf->pos = 0; in buffer_queue()
706 if (buf->length < dev->width * dev->height * 2) in buffer_queue()
707 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in buffer_queue()
709 list_add_tail(&buf->list, &dev->avail_bufs); in buffer_queue()
712 spin_unlock_irqrestore(&dev->buf_lock, flags); in buffer_queue()
745 /* Must be called with both v4l_lock and vb_queue_lock hold */
752 spin_lock_irqsave(&dev->buf_lock, flags); in stk1160_clear_queue()
753 while (!list_empty(&dev->avail_bufs)) { in stk1160_clear_queue()
754 buf = list_first_entry(&dev->avail_bufs, in stk1160_clear_queue()
756 list_del(&buf->list); in stk1160_clear_queue()
757 vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); in stk1160_clear_queue()
759 buf, buf->vb.vb2_buf.index); in stk1160_clear_queue()
763 if (dev->isoc_ctl.buf) { in stk1160_clear_queue()
764 buf = dev->isoc_ctl.buf; in stk1160_clear_queue()
765 dev->isoc_ctl.buf = NULL; in stk1160_clear_queue()
767 vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); in stk1160_clear_queue()
769 buf, buf->vb.vb2_buf.index); in stk1160_clear_queue()
771 spin_unlock_irqrestore(&dev->buf_lock, flags); in stk1160_clear_queue()
779 q = &dev->vb_vidq; in stk1160_vb2_setup()
780 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in stk1160_vb2_setup()
781 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in stk1160_vb2_setup()
782 q->drv_priv = dev; in stk1160_vb2_setup()
783 q->buf_struct_size = sizeof(struct stk1160_buffer); in stk1160_vb2_setup()
784 q->ops = &stk1160_video_qops; in stk1160_vb2_setup()
785 q->mem_ops = &vb2_vmalloc_memops; in stk1160_vb2_setup()
786 q->lock = &dev->vb_queue_lock; in stk1160_vb2_setup()
787 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in stk1160_vb2_setup()
794 INIT_LIST_HEAD(&dev->avail_bufs); in stk1160_vb2_setup()
804 dev->vdev = v4l_template; in stk1160_video_register()
805 dev->vdev.queue = &dev->vb_vidq; in stk1160_video_register()
811 dev->vdev.lock = &dev->v4l_lock; in stk1160_video_register()
814 dev->vdev.v4l2_dev = &dev->v4l2_dev; in stk1160_video_register()
815 dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | in stk1160_video_register()
819 dev->norm = V4L2_STD_NTSC_M; in stk1160_video_register()
820 dev->width = 720; in stk1160_video_register()
821 dev->height = 480; in stk1160_video_register()
824 dev->fmt = &format[0]; in stk1160_video_register()
827 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, in stk1160_video_register()
828 dev->norm); in stk1160_video_register()
830 video_set_drvdata(&dev->vdev, dev); in stk1160_video_register()
831 rc = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1); in stk1160_video_register()
837 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", in stk1160_video_register()
838 video_device_node_name(&dev->vdev)); in stk1160_video_register()