^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * STK1160 driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012 Ezequiel Garcia
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * <elezegarcia--a.t--gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based on Easycap driver by R.M. Thomas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2010 R.M. Thomas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * <rmthomas--a.t--sciolus.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <media/v4l2-fh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <media/videobuf2-vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/i2c/saa7115.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "stk1160.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "stk1160-reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static bool keep_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) module_param(keep_buffers, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_PARM_DESC(keep_buffers, "don't release buffers upon stop streaming");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) enum stk1160_decimate_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) STK1160_DECIMATE_MORE_THAN_HALF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) STK1160_DECIMATE_LESS_THAN_HALF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct stk1160_decimate_ctrl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) bool col_en, row_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) enum stk1160_decimate_mode col_mode, row_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned int col_n, row_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* supported video standards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static struct stk1160_fmt format[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .fourcc = V4L2_PIX_FMT_UYVY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .depth = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Helper to find the next divisor that results in modulo being zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * This is required to guarantee valid decimation unit counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) div_round_integer(unsigned int x, unsigned int y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) for (;; y++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (x % y == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return x / y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void stk1160_set_std(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct regval std525[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* 720x480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Frame start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {STK116_CFSPO_STX_L, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {STK116_CFSPO_STX_H, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {STK116_CFSPO_STY_L, 0x0003},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {STK116_CFSPO_STY_H, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Frame end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {STK116_CFEPO_ENX_L, 0x05a0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {STK116_CFEPO_ENX_H, 0x0005},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {STK116_CFEPO_ENY_L, 0x00f3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {STK116_CFEPO_ENY_H, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {0xffff, 0xffff}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static struct regval std625[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* 720x576 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* TODO: Each line of frame has some junk at the end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Frame start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {STK116_CFSPO, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {STK116_CFSPO+1, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {STK116_CFSPO+2, 0x0001},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {STK116_CFSPO+3, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Frame end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {STK116_CFEPO, 0x05a0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {STK116_CFEPO+1, 0x0005},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {STK116_CFEPO+2, 0x0121},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {STK116_CFEPO+3, 0x0001},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {0xffff, 0xffff}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (dev->norm & V4L2_STD_525_60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) stk1160_dbg("registers to NTSC like standard\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) for (i = 0; std525[i].reg != 0xffff; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) stk1160_write_reg(dev, std525[i].reg, std525[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) stk1160_dbg("registers to PAL like standard\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) for (i = 0; std625[i].reg != 0xffff; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) stk1160_write_reg(dev, std625[i].reg, std625[i].val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void stk1160_set_fmt(struct stk1160 *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct stk1160_decimate_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Since the format is UYVY, the device must skip or send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * a number of rows/columns multiple of four. This way, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * colour format is preserved. The STK1160_DEC_UNIT_SIZE bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * does exactly this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) val |= STK1160_DEC_UNIT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) val |= ctrl->col_en ? STK1160_H_DEC_EN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) val |= ctrl->row_en ? STK1160_V_DEC_EN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) val |= ctrl->col_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) STK1160_DECIMATE_MORE_THAN_HALF ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) STK1160_H_DEC_MODE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) val |= ctrl->row_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) STK1160_DECIMATE_MORE_THAN_HALF ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) STK1160_V_DEC_MODE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Horizontal count units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) stk1160_write_reg(dev, STK1160_DMCTRL_H_UNITS, ctrl->col_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Vertical count units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) stk1160_write_reg(dev, STK1160_DMCTRL_V_UNITS, ctrl->row_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) stk1160_dbg("decimate 0x%x, column units %d, row units %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) val, ctrl->col_n, ctrl->row_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Decimation control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) stk1160_write_reg(dev, STK1160_DMCTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * Set a new alternate setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Returns true is dev->max_pkt_size has changed, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static bool stk1160_set_alternate(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int i, prev_alt = dev->alt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int min_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) bool new_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * If we don't set right alternate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * then we will get a green screen with junk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) min_pkt_size = STK1160_MIN_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) for (i = 0; i < dev->num_alt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* stop when the selected alt setting offers enough bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (dev->alt_max_pkt_size[i] >= min_pkt_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev->alt = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * otherwise make sure that we end up with the maximum bandwidth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * because the min_pkt_size equation might be wrong...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) } else if (dev->alt_max_pkt_size[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) dev->alt_max_pkt_size[dev->alt])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dev->alt = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) stk1160_dbg("setting alternate %d\n", dev->alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (dev->alt != prev_alt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) stk1160_dbg("minimum isoc packet size: %u (alt=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) min_pkt_size, dev->alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) stk1160_dbg("setting alt %d with wMaxPacketSize=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev->alt, dev->alt_max_pkt_size[dev->alt]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) usb_set_interface(dev->udev, 0, dev->alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) new_pkt_size = dev->max_pkt_size != dev->alt_max_pkt_size[dev->alt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return new_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int stk1160_start_streaming(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bool new_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* Check device presence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!dev->udev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (mutex_lock_interruptible(&dev->v4l_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * For some reason it is mandatory to set alternate *first*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * and only *then* initialize isoc urbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * Someone please explain me why ;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) new_pkt_size = stk1160_set_alternate(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * We (re)allocate isoc urbs if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * there is no allocated isoc urbs, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * a new dev->max_pkt_size is detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!dev->isoc_ctl.num_bufs || new_pkt_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rc = stk1160_alloc_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto out_stop_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* submit urbs and enables IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) stk1160_err("cannot submit urb[%d] (%d)\n", i, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto out_uninit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* Start saa711x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev->sequence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Start stk1160 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) stk1160_write_reg(dev, STK1160_DCTRL, 0xb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) stk1160_dbg("streaming started\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mutex_unlock(&dev->v4l_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) out_uninit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) stk1160_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) out_stop_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) usb_set_interface(dev->udev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) stk1160_clear_queue(dev, VB2_BUF_STATE_QUEUED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mutex_unlock(&dev->v4l_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Must be called with v4l_lock hold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void stk1160_stop_hw(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* If the device is not physically present, there is nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (!dev->udev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* set alternate 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev->alt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) stk1160_dbg("setting alternate %d\n", dev->alt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) usb_set_interface(dev->udev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Stop stk1160 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) stk1160_write_reg(dev, STK1160_DCTRL, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Stop saa711x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int stk1160_stop_streaming(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (mutex_lock_interruptible(&dev->v4l_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Once URBs are cancelled, the URB complete handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * won't be running. This is required to safely release the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * current buffer (dev->isoc_ctl.buf).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) stk1160_cancel_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * It is possible to keep buffers around using a module parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * This is intended to avoid memory fragmentation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!keep_buffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) stk1160_free_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) stk1160_stop_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) stk1160_clear_queue(dev, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) stk1160_dbg("streaming stopped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) mutex_unlock(&dev->v4l_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static const struct v4l2_file_operations stk1160_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .open = v4l2_fh_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .release = vb2_fop_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * vidioc ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int vidioc_querycap(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) void *priv, struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) strscpy(cap->driver, "stk1160", sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) strscpy(cap->card, "stk1160", sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (f->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) f->pixelformat = format[f->index].fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) f->fmt.pix.width = dev->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) f->fmt.pix.height = dev->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) f->fmt.pix.pixelformat = dev->fmt->fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) f->fmt.pix.bytesperline = dev->width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) f->fmt.pix.sizeimage = dev->height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static int stk1160_try_fmt(struct stk1160 *dev, struct v4l2_format *f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct stk1160_decimate_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned int base_width, base_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) unsigned int col_n, row_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) enum stk1160_decimate_mode col_mode, row_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) bool col_en, row_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) base_width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) base_height = (dev->norm & V4L2_STD_525_60) ? 480 : 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Minimum width and height is 5% the frame size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) width = clamp_t(unsigned int, f->fmt.pix.width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) base_width / 20, base_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) height = clamp_t(unsigned int, f->fmt.pix.height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) base_height / 20, base_height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* Let's set default no decimation values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) col_n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) row_n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) col_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) row_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) f->fmt.pix.width = base_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) f->fmt.pix.height = base_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) row_mode = STK1160_DECIMATE_LESS_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) col_mode = STK1160_DECIMATE_LESS_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (width < base_width && width > base_width / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * The device will send count units for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * unit skipped. This means count unit is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * n = width / (frame width - width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * And the width is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * width = (n / n + 1) * frame width
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) col_n = div_round_integer(width, base_width - width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (col_n > 0 && col_n <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) col_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) col_mode = STK1160_DECIMATE_LESS_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) f->fmt.pix.width = (base_width * col_n) / (col_n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) } else if (width <= base_width / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * The device will skip count units for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * unit sent. This means count is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * n = (frame width / width) - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * And the width is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * width = frame width / (n + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) col_n = div_round_integer(base_width, width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (col_n > 0 && col_n <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) col_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) col_mode = STK1160_DECIMATE_MORE_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) f->fmt.pix.width = base_width / (col_n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (height < base_height && height > base_height / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) row_n = div_round_integer(height, base_height - height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (row_n > 0 && row_n <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) row_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) row_mode = STK1160_DECIMATE_LESS_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) f->fmt.pix.height = (base_height * row_n) / (row_n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) } else if (height <= base_height / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) row_n = div_round_integer(base_height, height) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (row_n > 0 && row_n <= 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) row_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) row_mode = STK1160_DECIMATE_MORE_THAN_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) f->fmt.pix.height = base_height / (row_n + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) f->fmt.pix.pixelformat = dev->fmt->fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ctrl->col_en = col_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ctrl->col_n = col_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ctrl->col_mode = col_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ctrl->row_en = row_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ctrl->row_n = row_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ctrl->row_mode = row_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) stk1160_dbg("width %d, height %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) f->fmt.pix.width, f->fmt.pix.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return stk1160_try_fmt(dev, f, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct vb2_queue *q = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct stk1160_decimate_ctrl ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (vb2_is_busy(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rc = stk1160_try_fmt(dev, f, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dev->width = f->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dev->height = f->fmt.pix.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) stk1160_set_fmt(dev, &ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *norm = dev->norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct vb2_queue *q = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (dev->norm == norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (vb2_is_busy(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* Check device presence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!dev->udev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* We need to set this now, before we call stk1160_set_std */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev->width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dev->height = (norm & V4L2_STD_525_60) ? 480 : 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dev->norm = norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) stk1160_set_std(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* Calling with NULL disables frame decimation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) stk1160_set_fmt(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dev->norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct v4l2_input *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (i->index > STK1160_MAX_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* S-Video special handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (i->index == STK1160_SVIDEO_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) sprintf(i->name, "S-Video");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) sprintf(i->name, "Composite%d", i->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) i->type = V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) i->std = dev->vdev.tvnorms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) *i = dev->ctl_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (i > STK1160_MAX_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dev->ctl_input = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) stk1160_select_input(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int vidioc_g_register(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Match host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) rc = stk1160_read_reg(dev, reg->reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) reg->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) reg->size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int vidioc_s_register(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) const struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct stk1160 *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* Match host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return stk1160_write_reg(dev, reg->reg, reg->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static const struct v4l2_ioctl_ops stk1160_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .vidioc_querycap = vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .vidioc_querystd = vidioc_querystd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .vidioc_enum_input = vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .vidioc_g_input = vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .vidioc_s_input = vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* vb2 takes care of these */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .vidioc_expbuf = vb2_ioctl_expbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .vidioc_log_status = v4l2_ctrl_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .vidioc_g_register = vidioc_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .vidioc_s_register = vidioc_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * Videobuf2 operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static int queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned int *nbuffers, unsigned int *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct stk1160 *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) size = dev->width * dev->height * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * Here we can change the number of buffers being requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * So, we set a minimum and a maximum like this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *nbuffers = clamp_t(unsigned int, *nbuffers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) STK1160_MIN_VIDEO_BUFFERS, STK1160_MAX_VIDEO_BUFFERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (*nplanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return sizes[0] < size ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) /* This means a packed colorformat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) stk1160_dbg("%s: buffer count %d, each %ld bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) __func__, *nbuffers, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static void buffer_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct stk1160 *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) struct stk1160_buffer *buf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) container_of(vbuf, struct stk1160_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) spin_lock_irqsave(&dev->buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!dev->udev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * If the device is disconnected return the buffer to userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * directly. The next QBUF call will fail with -ENODEV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) buf->mem = vb2_plane_vaddr(vb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) buf->length = vb2_plane_size(vb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) buf->bytesused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) buf->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * If buffer length is less from expected then we return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * the buffer to userspace directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (buf->length < dev->width * dev->height * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) list_add_tail(&buf->list, &dev->avail_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) spin_unlock_irqrestore(&dev->buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static int start_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct stk1160 *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return stk1160_start_streaming(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static void stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct stk1160 *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) stk1160_stop_streaming(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static const struct vb2_ops stk1160_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) .queue_setup = queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) .start_streaming = start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) .stop_streaming = stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static const struct video_device v4l_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) .name = "stk1160",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) .tvnorms = V4L2_STD_525_60 | V4L2_STD_625_50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .fops = &stk1160_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .ioctl_ops = &stk1160_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) .release = video_device_release_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /********************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* Must be called with both v4l_lock and vb_queue_lock hold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) void stk1160_clear_queue(struct stk1160 *dev, enum vb2_buffer_state vb2_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct stk1160_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* Release all active buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) spin_lock_irqsave(&dev->buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) while (!list_empty(&dev->avail_bufs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) buf = list_first_entry(&dev->avail_bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct stk1160_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) vb2_buffer_done(&buf->vb.vb2_buf, vb2_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) stk1160_dbg("buffer [%p/%d] aborted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) buf, buf->vb.vb2_buf.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* It's important to release the current buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (dev->isoc_ctl.buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) buf = dev->isoc_ctl.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dev->isoc_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) vb2_buffer_done(&buf->vb.vb2_buf, vb2_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) stk1160_dbg("buffer [%p/%d] aborted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) buf, buf->vb.vb2_buf.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) spin_unlock_irqrestore(&dev->buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) int stk1160_vb2_setup(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct vb2_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) q = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) q->drv_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) q->buf_struct_size = sizeof(struct stk1160_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) q->ops = &stk1160_video_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) q->mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) q->lock = &dev->vb_queue_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) rc = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* initialize video dma queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) INIT_LIST_HEAD(&dev->avail_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int stk1160_video_register(struct stk1160 *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* Initialize video_device with a template structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dev->vdev = v4l_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dev->vdev.queue = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * Provide mutexes for v4l2 core and for videobuf2 queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * It will be used to protect *only* v4l2 ioctls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev->vdev.lock = &dev->v4l_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /* This will be used to set video_device parent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev->vdev.v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) V4L2_CAP_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /* NTSC is default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev->norm = V4L2_STD_NTSC_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev->width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev->height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /* set default format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dev->fmt = &format[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) stk1160_set_std(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dev->norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) video_set_drvdata(&dev->vdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) rc = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) stk1160_err("video_register_device failed (%d)\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) video_device_node_name(&dev->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }