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)  * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define MODULE_NAME "etoms"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "gspca.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) MODULE_DESCRIPTION("Etoms USB Camera Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* specific webcam descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) struct sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	struct gspca_dev gspca_dev;	/* !! must be the first item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	unsigned char autogain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	char sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define SENSOR_PAS106 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define SENSOR_TAS5130CXX 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	signed char ag_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define AG_CNT_START 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static const struct v4l2_pix_format vga_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		.bytesperline = 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		.sizeimage = 320 * 240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		.colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		.priv = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		.bytesperline = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		.sizeimage = 640 * 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		.colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		.priv = 0}, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static const struct v4l2_pix_format sif_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		.bytesperline = 176,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		.sizeimage = 176 * 144,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		.priv = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	{352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		.bytesperline = 352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		.sizeimage = 352 * 288,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		.colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		.priv = 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define ETOMS_ALT_SIZE_1000   12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define ET_GPIO_DIR_CTRL 0x04	/* Control IO bit[0..5] (0 in  1 out) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define ET_GPIO_OUT 0x05	/* Only IO data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define ET_GPIO_IN 0x06		/* Read Only IO data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define ET_RESET_ALL 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define ET_ClCK 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define ET_CTRL 0x02		/* enable i2c OutClck Powerdown mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define ET_COMP 0x12		/* Compression register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define ET_MAXQt 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define ET_MINQt 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define ET_COMP_VAL0 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define ET_COMP_VAL1 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define ET_REG1d 0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define ET_REG1e 0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define ET_REG1f 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define ET_REG20 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define ET_REG21 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define ET_REG22 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define ET_REG23 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define ET_REG24 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define ET_REG25 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) /* base registers for luma calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define ET_LUMA_CENTER 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define ET_G_RED 0x4d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define ET_G_GREEN1 0x4e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define ET_G_BLUE 0x4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define ET_G_GREEN2 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define ET_G_GR_H 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define ET_G_GB_H 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define ET_O_RED 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define ET_O_GREEN1 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define ET_O_BLUE 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define ET_O_GREEN2 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define ET_SYNCHRO 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define ET_STARTX 0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define ET_STARTY 0x6a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define ET_WIDTH_LOW 0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ET_HEIGTH_LOW 0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ET_W_H_HEIGTH 0x6d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ET_REG6e 0x6e		/* OBW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ET_REG6f 0x6f		/* OBW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ET_REG70 0x70		/* OBW_AWB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define ET_REG71 0x71		/* OBW_AWB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define ET_REG72 0x72		/* OBW_AWB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define ET_REG73 0x73		/* Clkdelay ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define ET_REG74 0x74		/* test pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define ET_REG75 0x75		/* test pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define ET_I2C_CLK 0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define ET_PXL_CLK 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define ET_I2C_BASE 0x89
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define ET_I2C_COUNT 0x8a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define ET_I2C_PREFETCH 0x8b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define ET_I2C_REG 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define ET_I2C_DATA7 0x87
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define ET_I2C_DATA6 0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define ET_I2C_DATA5 0x85
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define ET_I2C_DATA4 0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ET_I2C_DATA3 0x83
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define ET_I2C_DATA2 0x82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define ET_I2C_DATA1 0x81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define ET_I2C_DATA0 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define PAS106_REG2 0x02	/* pxlClk = systemClk/(reg2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define PAS106_REG3 0x03	/* line/frame H [11..4] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define PAS106_REG4 0x04	/* line/frame L [3..0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define PAS106_REG5 0x05	/* exposure time line offset(default 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define PAS106_REG6 0x06	/* exposure time pixel offset(default 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define PAS106_REG7 0x07	/* signbit Dac (default 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define PAS106_REG9 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define PAS106_REG0e 0x0e	/* global gain [4..0](default 0x0e) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define PAS106_REG13 0x13	/* end i2c write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static const __u8 I2c3[] = { 0x12, 0x05 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const __u8 I2c4[] = { 0x41, 0x08 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* read 'len' bytes to gspca_dev->usb_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static void reg_r(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		  __u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		  __u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct usb_device *dev = gspca_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (len > USB_BUF_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		gspca_err(gspca_dev, "reg_r: buffer overflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		return;
^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) 	usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			usb_rcvctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			index, gspca_dev->usb_buf, len, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		  index, gspca_dev->usb_buf[0]);
^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) static void reg_w_val(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			__u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			__u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct usb_device *dev = gspca_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	gspca_dev->usb_buf[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			index, gspca_dev->usb_buf, 1, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void reg_w(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		  __u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		  const __u8 *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		  __u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	struct usb_device *dev = gspca_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (len > USB_BUF_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		pr_err("reg_w: buffer overflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		  index, *buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	memcpy(gspca_dev->usb_buf, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	usb_control_msg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			usb_sndctrlpipe(dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			0, index, gspca_dev->usb_buf, len, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int i2c_w(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		 __u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		 const __u8 *buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		 int len, __u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* buffer should be [D0..D7] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	__u8 ptchcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* set the base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 					 /* sensor base for the pas106 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	/* set count and prefetch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	ptchcount = ((len & 0x07) << 4) | (mode & 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* set the register base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	reg_w_val(gspca_dev, ET_I2C_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	while (--len >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int i2c_r(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			__u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	/* set the base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	reg_w_val(gspca_dev, ET_I2C_BASE, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 					/* sensor base for the pas106 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	/* set count and prefetch (cnd: 4 bits - mode: 4 bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	reg_w_val(gspca_dev, ET_I2C_REG, reg);	/* set the register base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02);	/* prefetch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	reg_r(gspca_dev, ET_I2C_DATA0, 1);	/* read one byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	return 0;
^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) static int Et_WaitStatus(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	int retry = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	while (retry--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		reg_r(gspca_dev, ET_ClCK, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		if (gspca_dev->usb_buf[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int et_video(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		    int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	reg_w_val(gspca_dev, ET_GPIO_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		  on ? 0x10		/* startvideo - set Bit5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		     : 0);		/* stopvideo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	ret = Et_WaitStatus(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		gspca_err(gspca_dev, "timeout video on/off\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void Et_init2(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	__u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	gspca_dbg(gspca_dev, D_STREAM, "Open Init2 ET\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	reg_r(gspca_dev, ET_GPIO_IN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	reg_w_val(gspca_dev, ET_CTRL, 0x1b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	/*  compression et subsampling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		value = ET_COMP_VAL1;	/* 320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		value = ET_COMP_VAL0;	/* 640 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	reg_w_val(gspca_dev, ET_COMP, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	reg_w_val(gspca_dev, ET_MAXQt, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	reg_w_val(gspca_dev, ET_MINQt, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	/* undocumented registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	reg_w_val(gspca_dev, ET_REG1d, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	reg_w_val(gspca_dev, ET_REG1e, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	reg_w_val(gspca_dev, ET_REG1f, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	reg_w_val(gspca_dev, ET_REG20, 0x35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	reg_w_val(gspca_dev, ET_REG21, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	reg_w_val(gspca_dev, ET_REG22, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	reg_w_val(gspca_dev, ET_REG23, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	reg_w_val(gspca_dev, ET_REG24, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	reg_w_val(gspca_dev, ET_REG25, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	/* colors setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	reg_w_val(gspca_dev, 0x30, 0x11);		/* 0x30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	reg_w_val(gspca_dev, 0x31, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	reg_w_val(gspca_dev, 0x32, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	reg_w_val(gspca_dev, ET_O_RED, 0x00);		/* 0x34 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	reg_w_val(gspca_dev, ET_O_GREEN1, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	reg_w_val(gspca_dev, ET_O_BLUE, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	reg_w_val(gspca_dev, ET_O_GREEN2, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	/*************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	reg_w_val(gspca_dev, ET_G_RED, 0x80);		/* 0x4d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	reg_w_val(gspca_dev, ET_G_GB_H, 0x00);		/* 0x52 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	/* Window control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	reg_w_val(gspca_dev, 0x61, 0x80);		/* use cmc_out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	reg_w_val(gspca_dev, 0x62, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	reg_w_val(gspca_dev, 0x63, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	reg_w_val(gspca_dev, 0x64, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	reg_w_val(gspca_dev, 0x65, 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	reg_w_val(gspca_dev, 0x66, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	reg_w_val(gspca_dev, 0x67, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	/**************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f);		/* 0x68 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	reg_w_val(gspca_dev, ET_STARTX, 0x69);		/* 0x6a //0x69 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	reg_w_val(gspca_dev, ET_STARTY, 0x0d);		/* 0x0d //0x0c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60);	/* 6d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	reg_w_val(gspca_dev, ET_REG6e, 0x86);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	reg_w_val(gspca_dev, ET_REG6f, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	reg_w_val(gspca_dev, ET_REG70, 0x26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	reg_w_val(gspca_dev, ET_REG71, 0x7a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	reg_w_val(gspca_dev, ET_REG72, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	/* Clock Pattern registers ***************** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	reg_w_val(gspca_dev, ET_REG73, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	reg_w_val(gspca_dev, ET_REG74, 0x18);		/* 0x28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	reg_w_val(gspca_dev, ET_REG75, 0x0f);		/* 0x01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	/**********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	reg_w_val(gspca_dev, 0x8a, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	reg_w_val(gspca_dev, 0x8d, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	reg_w_val(gspca_dev, 0x8e, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	/**************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	reg_w_val(gspca_dev, 0x03, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	reg_w_val(gspca_dev, ET_PXL_CLK, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	reg_w_val(gspca_dev, 0x81, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	reg_w_val(gspca_dev, 0x80, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	reg_w_val(gspca_dev, 0x81, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	reg_w_val(gspca_dev, 0x80, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	reg_w_val(gspca_dev, 0x03, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	reg_w_val(gspca_dev, 0x03, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	reg_w_val(gspca_dev, 0x03, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	/********************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /*	reg_r(gspca_dev, ET_I2C_BASE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 					 always 0x40 as the pas106 ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	/* set the sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		value = 0x04;		/* 320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	else				/* 640 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		value = 0x1e;	/* 0x17	 * setting PixelClock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 					 * 0x03 mean 24/(3+1) = 6 Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					 * 0x05 -> 24/(5+1) = 4 Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 					 * 0x0b -> 24/(11+1) = 2 Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 					 * 0x17 -> 24/(23+1) = 1 Mhz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	reg_w_val(gspca_dev, ET_PXL_CLK, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	/* now set by fifo the FormatLine setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	reg_w(gspca_dev, 0x62, FormLine, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	/* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	reg_w_val(gspca_dev, 0x81, 0x47);	/* 0x47; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	reg_w_val(gspca_dev, 0x80, 0x40);	/* 0x40; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* Pedro change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	/* Brightness change Brith+ decrease value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	/* Brigth- increase value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	/* original value = 0x70; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	reg_w_val(gspca_dev, 0x81, 0x30);	/* 0x20; - set brightness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	reg_w_val(gspca_dev, 0x80, 0x20);	/* 0x20; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		reg_w_val(gspca_dev, ET_O_RED + i, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	__u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	memset(RGBG, val, sizeof(RGBG) - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	reg_w(gspca_dev, ET_G_RED, RGBG, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static void setcolors(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	__u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	__u8 i2cflags = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	/* __u8 green = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	I2cc[3] = val;	/* red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	I2cc[0] = 15 - val;	/* blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	/* I2cc[1] = I2cc[2] = green; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (sd->sensor == SENSOR_PAS106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static s32 getcolors(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	if (sd->sensor == SENSOR_PAS106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /*		i2c_r(gspca_dev, PAS106_REG9);		 * blue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		i2c_r(gspca_dev, PAS106_REG9 + 3);	/* red */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		return gspca_dev->usb_buf[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static void setautogain(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (sd->autogain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		sd->ag_cnt = AG_CNT_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		sd->ag_cnt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static void Et_init1(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	__u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*	__u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	__u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 						/* try 1/120 0x6d 0xcd 0x40 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /*	__u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 						 * 1/60000 hmm ?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	gspca_dbg(gspca_dev, D_STREAM, "Open Init1 ET\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	reg_r(gspca_dev, ET_GPIO_IN, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	reg_w_val(gspca_dev, ET_RESET_ALL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	reg_w_val(gspca_dev, ET_RESET_ALL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	reg_w_val(gspca_dev, ET_ClCK, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	reg_w_val(gspca_dev, ET_CTRL, 0x19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	/*   compression et subsampling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		value = ET_COMP_VAL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		value = ET_COMP_VAL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	gspca_dbg(gspca_dev, D_STREAM, "Open mode %d Compression %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		  gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		  value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	reg_w_val(gspca_dev, ET_COMP, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	reg_w_val(gspca_dev, ET_MINQt, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	/* undocumented registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	reg_w_val(gspca_dev, ET_REG1d, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	reg_w_val(gspca_dev, ET_REG1e, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	reg_w_val(gspca_dev, ET_REG1f, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	reg_w_val(gspca_dev, ET_REG20, 0x35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	reg_w_val(gspca_dev, ET_REG21, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	reg_w_val(gspca_dev, ET_REG22, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	reg_w_val(gspca_dev, ET_REG23, 0xf7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	reg_w_val(gspca_dev, ET_REG24, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	reg_w_val(gspca_dev, ET_REG25, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	/* colors setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	reg_w_val(gspca_dev, ET_G_RED, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	reg_w_val(gspca_dev, ET_G_GREEN1, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	reg_w_val(gspca_dev, ET_G_BLUE, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	reg_w_val(gspca_dev, ET_G_GREEN2, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	reg_w_val(gspca_dev, ET_G_GR_H, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	reg_w_val(gspca_dev, ET_G_GB_H, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	/* Window control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	reg_w_val(gspca_dev, ET_STARTX, 0x56);		/* 0x56 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	reg_w_val(gspca_dev, ET_STARTY, 0x05);		/* 0x04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	reg_w_val(gspca_dev, ET_REG6e, 0x86);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	reg_w_val(gspca_dev, ET_REG6f, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	reg_w_val(gspca_dev, ET_REG70, 0x86);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	reg_w_val(gspca_dev, ET_REG71, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	reg_w_val(gspca_dev, ET_REG72, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	/* Clock Pattern registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	reg_w_val(gspca_dev, ET_REG73, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	reg_w_val(gspca_dev, ET_REG74, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	reg_w_val(gspca_dev, ET_REG75, 0x0a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	reg_w_val(gspca_dev, ET_I2C_CLK, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	reg_w_val(gspca_dev, ET_PXL_CLK, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	/* set the sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		I2c0[0] = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		value = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		/* value = 0x1f; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		value = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		I2c0[0] = 0x0a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		value = 0x0a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		value = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		/* value = 0x10; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		/* bit 2 enable bit 1:2 select 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		   value = 0x07;                                * curve 0 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		   i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /*	value = 0x01; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /*	value = 0x22; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*	i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	/* magnetude and sign bit for DAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	/* now set by fifo the whole colors setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	reg_w(gspca_dev, ET_G_RED, GainRGBG, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	setcolors(gspca_dev, getcolors(gspca_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* this function is called at probe time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int sd_config(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		     const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	struct cam *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	cam = &gspca_dev->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	sd->sensor = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	if (sd->sensor == SENSOR_PAS106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		cam->cam_mode = sif_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		cam->nmodes = ARRAY_SIZE(sif_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		cam->cam_mode = vga_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		cam->nmodes = ARRAY_SIZE(vga_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	sd->ag_cnt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* this function is called at probe and resume time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static int sd_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (sd->sensor == SENSOR_PAS106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		Et_init1(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		Et_init2(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	et_video(gspca_dev, 0);		/* video off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* -- start the camera -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static int sd_start(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if (sd->sensor == SENSOR_PAS106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		Et_init1(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		Et_init2(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	setautogain(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	reg_w_val(gspca_dev, ET_RESET_ALL, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	et_video(gspca_dev, 1);		/* video on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static void sd_stopN(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	et_video(gspca_dev, 0);		/* video off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	if (sd->sensor == SENSOR_PAS106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		i2c_r(gspca_dev, PAS106_REG0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		gspca_dbg(gspca_dev, D_CONF, "Etoms gain G %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			  gspca_dev->usb_buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		return gspca_dev->usb_buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	return 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	if (sd->sensor == SENSOR_PAS106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 		__u8 i2cflags = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) #define BLIMIT(bright) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	(u8)((bright > 0x1f) ? 0x1f : ((bright < 4) ? 3 : bright))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) #define LIMIT(color) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	(u8)((color > 0xff) ? 0xff : ((color < 0) ? 0 : color))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static void do_autogain(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	__u8 luma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	__u8 luma_mean = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	__u8 luma_delta = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	__u8 spring = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	int Gbright;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	__u8 r, g, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	if (sd->ag_cnt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	if (--sd->ag_cnt >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	sd->ag_cnt = AG_CNT_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	Gbright = Et_getgainG(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	reg_r(gspca_dev, ET_LUMA_CENTER, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	r = gspca_dev->usb_buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	b = gspca_dev->usb_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	r = ((r << 8) - (r << 4) - (r << 3)) >> 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	b = ((b << 7) >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	luma = LIMIT(r + g + b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	gspca_dbg(gspca_dev, D_FRAM, "Etoms luma G %d\n", luma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		Gbright += (luma_mean - luma) >> spring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		Gbright = BLIMIT(Gbright);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		gspca_dbg(gspca_dev, D_FRAM, "Etoms Gbright %d\n", Gbright);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		Et_setgainG(gspca_dev, (__u8) Gbright);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) #undef BLIMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #undef LIMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static void sd_pkt_scan(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			u8 *data,			/* isoc packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			int len)			/* iso packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	int seqframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	seqframe = data[0] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	len = (int) (((data[0] & 0xc0) << 2) | data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	if (seqframe == 0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		gspca_dbg(gspca_dev, D_FRAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			  "header packet found datalength %d !!\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		gspca_dbg(gspca_dev, D_FRAM, "G %d R %d G %d B %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 			  data[2], data[3], data[4], data[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		data += 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		/* don't change datalength as the chips provided it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		data += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	} else {			/* Drop Packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		gspca_dev->last_packet_type = DISCARD_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	struct gspca_dev *gspca_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	struct sd *sd = (struct sd *)gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	gspca_dev->usb_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (!gspca_dev->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		setbrightness(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	case V4L2_CID_CONTRAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		setcontrast(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	case V4L2_CID_SATURATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		setcolors(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	case V4L2_CID_AUTOGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		sd->autogain = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		setautogain(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	return gspca_dev->usb_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static const struct v4l2_ctrl_ops sd_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	.s_ctrl = sd_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int sd_init_controls(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	struct sd *sd = (struct sd *)gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	gspca_dev->vdev.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	v4l2_ctrl_handler_init(hdl, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 			V4L2_CID_BRIGHTNESS, 1, 127, 1, 63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			V4L2_CID_CONTRAST, 0, 255, 1, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	if (sd->sensor == SENSOR_PAS106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 			V4L2_CID_SATURATION, 0, 15, 1, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 			V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		pr_err("Could not initialize controls\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		return hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* sub-driver description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static const struct sd_desc sd_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	.name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	.config = sd_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	.init = sd_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	.init_controls = sd_init_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	.start = sd_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	.stopN = sd_stopN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	.pkt_scan = sd_pkt_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	.dq_callback = do_autogain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* -- module initialisation -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct usb_device_id device_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	{USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	{USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) MODULE_DEVICE_TABLE(usb, device_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* -- device connect -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static int sd_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		    const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 			       THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static struct usb_driver sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	.name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	.id_table = device_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	.probe = sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	.disconnect = gspca_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	.suspend = gspca_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	.resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	.reset_resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) module_usb_driver(sd_driver);