Lines Matching +full:device +full:- +full:width

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()
129 * Since the format is UYVY, the device must skip or send in stk1160_set_fmt()
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()
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()
209 /* Check device presence */ in stk1160_start_streaming()
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 struct stk1160_urb *stk_urb = &dev->isoc_ctl.urb_ctl[i]; in stk1160_start_streaming()
237 dma_sync_sgtable_for_device(stk1160_get_dmadev(dev), stk_urb->sgt, in stk1160_start_streaming()
239 rc = usb_submit_urb(dev->isoc_ctl.urb_ctl[i].urb, GFP_KERNEL); in stk1160_start_streaming()
247 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); in stk1160_start_streaming()
249 dev->sequence = 0; in stk1160_start_streaming()
257 mutex_unlock(&dev->v4l_lock); in stk1160_start_streaming()
264 usb_set_interface(dev->udev, 0, 0); in stk1160_start_streaming()
267 mutex_unlock(&dev->v4l_lock); in stk1160_start_streaming()
275 /* If the device is not physically present, there is nothing to do */ in stk1160_stop_hw()
276 if (!dev->udev) in stk1160_stop_hw()
280 dev->alt = 0; in stk1160_stop_hw()
281 stk1160_dbg("setting alternate %d\n", dev->alt); in stk1160_stop_hw()
282 usb_set_interface(dev->udev, 0, 0); in stk1160_stop_hw()
289 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); in stk1160_stop_hw()
294 if (mutex_lock_interruptible(&dev->v4l_lock)) in stk1160_stop_streaming()
295 return -ERESTARTSYS; in stk1160_stop_streaming()
300 * current buffer (dev->isoc_ctl.buf). in stk1160_stop_streaming()
317 mutex_unlock(&dev->v4l_lock); in stk1160_stop_streaming()
340 strscpy(cap->driver, "stk1160", sizeof(cap->driver)); in vidioc_querycap()
341 strscpy(cap->card, "stk1160", sizeof(cap->card)); in vidioc_querycap()
342 usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); in vidioc_querycap()
349 if (f->index != 0) in vidioc_enum_fmt_vid_cap()
350 return -EINVAL; in vidioc_enum_fmt_vid_cap()
352 f->pixelformat = format[f->index].fourcc; in vidioc_enum_fmt_vid_cap()
361 f->fmt.pix.width = dev->width; in vidioc_g_fmt_vid_cap()
362 f->fmt.pix.height = dev->height; in vidioc_g_fmt_vid_cap()
363 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in vidioc_g_fmt_vid_cap()
364 f->fmt.pix.pixelformat = dev->fmt->fourcc; in vidioc_g_fmt_vid_cap()
365 f->fmt.pix.bytesperline = dev->width * 2; in vidioc_g_fmt_vid_cap()
366 f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline; in vidioc_g_fmt_vid_cap()
367 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in vidioc_g_fmt_vid_cap()
375 unsigned int width, height; in stk1160_try_fmt() local
382 base_height = (dev->norm & V4L2_STD_525_60) ? 480 : 576; in stk1160_try_fmt()
384 /* Minimum width and height is 5% the frame size */ in stk1160_try_fmt()
385 width = clamp_t(unsigned int, f->fmt.pix.width, in stk1160_try_fmt()
387 height = clamp_t(unsigned int, f->fmt.pix.height, in stk1160_try_fmt()
395 f->fmt.pix.width = base_width; in stk1160_try_fmt()
396 f->fmt.pix.height = base_height; in stk1160_try_fmt()
400 if (width < base_width && width > base_width / 2) { in stk1160_try_fmt()
402 * The device will send count units for each in stk1160_try_fmt()
405 * n = width / (frame width - width) in stk1160_try_fmt()
407 * And the width is: in stk1160_try_fmt()
409 * width = (n / n + 1) * frame width in stk1160_try_fmt()
411 col_n = div_round_integer(width, base_width - width); in stk1160_try_fmt()
415 f->fmt.pix.width = (base_width * col_n) / (col_n + 1); in stk1160_try_fmt()
418 } else if (width <= base_width / 2) { in stk1160_try_fmt()
421 * The device will skip count units for each in stk1160_try_fmt()
424 * n = (frame width / width) - 1 in stk1160_try_fmt()
426 * And the width is: in stk1160_try_fmt()
428 * width = frame width / (n + 1) in stk1160_try_fmt()
430 col_n = div_round_integer(base_width, width) - 1; in stk1160_try_fmt()
434 f->fmt.pix.width = base_width / (col_n + 1); in stk1160_try_fmt()
439 row_n = div_round_integer(height, base_height - height); in stk1160_try_fmt()
443 f->fmt.pix.height = (base_height * row_n) / (row_n + 1); in stk1160_try_fmt()
447 row_n = div_round_integer(base_height, height) - 1; in stk1160_try_fmt()
451 f->fmt.pix.height = base_height / (row_n + 1); in stk1160_try_fmt()
455 f->fmt.pix.pixelformat = dev->fmt->fourcc; in stk1160_try_fmt()
456 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in stk1160_try_fmt()
457 f->fmt.pix.bytesperline = f->fmt.pix.width * 2; in stk1160_try_fmt()
458 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; in stk1160_try_fmt()
459 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in stk1160_try_fmt()
462 ctrl->col_en = col_en; in stk1160_try_fmt()
463 ctrl->col_n = col_n; in stk1160_try_fmt()
464 ctrl->col_mode = col_mode; in stk1160_try_fmt()
465 ctrl->row_en = row_en; in stk1160_try_fmt()
466 ctrl->row_n = row_n; in stk1160_try_fmt()
467 ctrl->row_mode = row_mode; in stk1160_try_fmt()
470 stk1160_dbg("width %d, height %d\n", in stk1160_try_fmt()
471 f->fmt.pix.width, f->fmt.pix.height); in stk1160_try_fmt()
487 struct vb2_queue *q = &dev->vb_vidq; in vidioc_s_fmt_vid_cap()
492 return -EBUSY; in vidioc_s_fmt_vid_cap()
497 dev->width = f->fmt.pix.width; in vidioc_s_fmt_vid_cap()
498 dev->height = f->fmt.pix.height; in vidioc_s_fmt_vid_cap()
507 v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm); in vidioc_querystd()
515 *norm = dev->norm; in vidioc_g_std()
522 struct vb2_queue *q = &dev->vb_vidq; in vidioc_s_std()
524 if (dev->norm == norm) in vidioc_s_std()
528 return -EBUSY; in vidioc_s_std()
530 /* Check device presence */ in vidioc_s_std()
531 if (!dev->udev) in vidioc_s_std()
532 return -ENODEV; in vidioc_s_std()
535 dev->width = 720; in vidioc_s_std()
536 dev->height = (norm & V4L2_STD_525_60) ? 480 : 576; in vidioc_s_std()
537 dev->norm = norm; in vidioc_s_std()
544 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, in vidioc_s_std()
545 dev->norm); in vidioc_s_std()
556 if (i->index > STK1160_MAX_INPUT) in vidioc_enum_input()
557 return -EINVAL; in vidioc_enum_input()
559 /* S-Video special handling */ in vidioc_enum_input()
560 if (i->index == STK1160_SVIDEO_INPUT) in vidioc_enum_input()
561 sprintf(i->name, "S-Video"); in vidioc_enum_input()
563 sprintf(i->name, "Composite%d", i->index); in vidioc_enum_input()
565 i->type = V4L2_INPUT_TYPE_CAMERA; in vidioc_enum_input()
566 i->std = dev->vdev.tvnorms; in vidioc_enum_input()
573 *i = dev->ctl_input; in vidioc_g_input()
582 return -EINVAL; in vidioc_s_input()
584 dev->ctl_input = i; in vidioc_s_input()
600 rc = stk1160_read_reg(dev, reg->reg, &val); in vidioc_g_register()
601 reg->val = val; in vidioc_g_register()
602 reg->size = 1; in vidioc_g_register()
613 return stk1160_write_reg(dev, reg->reg, reg->val); in vidioc_s_register()
656 unsigned int sizes[], struct device *alloc_devs[]) in queue_setup()
661 size = dev->width * dev->height * 2; in queue_setup()
671 return sizes[0] < size ? -EINVAL : 0; in queue_setup()
687 struct stk1160 *dev = vb2_get_drv_priv(vb->vb2_queue); in buffer_queue()
692 spin_lock_irqsave(&dev->buf_lock, flags); in buffer_queue()
693 if (!dev->udev) { in buffer_queue()
695 * If the device is disconnected return the buffer to userspace in buffer_queue()
696 * directly. The next QBUF call will fail with -ENODEV. in buffer_queue()
698 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in buffer_queue()
701 buf->mem = vb2_plane_vaddr(vb, 0); in buffer_queue()
702 buf->length = vb2_plane_size(vb, 0); in buffer_queue()
703 buf->bytesused = 0; in buffer_queue()
704 buf->pos = 0; in buffer_queue()
710 if (buf->length < dev->width * dev->height * 2) in buffer_queue()
711 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in buffer_queue()
713 list_add_tail(&buf->list, &dev->avail_bufs); in buffer_queue()
716 spin_unlock_irqrestore(&dev->buf_lock, flags); in buffer_queue()
758 spin_lock_irqsave(&dev->buf_lock, flags); in stk1160_clear_queue()
759 while (!list_empty(&dev->avail_bufs)) { in stk1160_clear_queue()
760 buf = list_first_entry(&dev->avail_bufs, in stk1160_clear_queue()
762 list_del(&buf->list); in stk1160_clear_queue()
763 vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); in stk1160_clear_queue()
765 buf, buf->vb.vb2_buf.index); in stk1160_clear_queue()
769 if (dev->isoc_ctl.buf) { in stk1160_clear_queue()
770 buf = dev->isoc_ctl.buf; in stk1160_clear_queue()
771 dev->isoc_ctl.buf = NULL; in stk1160_clear_queue()
773 vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); in stk1160_clear_queue()
775 buf, buf->vb.vb2_buf.index); in stk1160_clear_queue()
777 spin_unlock_irqrestore(&dev->buf_lock, flags); in stk1160_clear_queue()
785 q = &dev->vb_vidq; in stk1160_vb2_setup()
786 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in stk1160_vb2_setup()
787 q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in stk1160_vb2_setup()
788 q->drv_priv = dev; in stk1160_vb2_setup()
789 q->buf_struct_size = sizeof(struct stk1160_buffer); in stk1160_vb2_setup()
790 q->ops = &stk1160_video_qops; in stk1160_vb2_setup()
791 q->mem_ops = &vb2_vmalloc_memops; in stk1160_vb2_setup()
792 q->lock = &dev->vb_queue_lock; in stk1160_vb2_setup()
793 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in stk1160_vb2_setup()
800 INIT_LIST_HEAD(&dev->avail_bufs); in stk1160_vb2_setup()
810 dev->vdev = v4l_template; in stk1160_video_register()
811 dev->vdev.queue = &dev->vb_vidq; in stk1160_video_register()
817 dev->vdev.lock = &dev->v4l_lock; in stk1160_video_register()
820 dev->vdev.v4l2_dev = &dev->v4l2_dev; in stk1160_video_register()
821 dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | in stk1160_video_register()
825 dev->norm = V4L2_STD_NTSC_M; in stk1160_video_register()
826 dev->width = 720; in stk1160_video_register()
827 dev->height = 480; in stk1160_video_register()
830 dev->fmt = &format[0]; in stk1160_video_register()
833 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, in stk1160_video_register()
834 dev->norm); in stk1160_video_register()
836 video_set_drvdata(&dev->vdev, dev); in stk1160_video_register()
837 rc = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1); in stk1160_video_register()
843 v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", in stk1160_video_register()
844 video_device_node_name(&dev->vdev)); in stk1160_video_register()