Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }