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)  * T613 subdriver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2010 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)  *Notes: * t613  + tas5130A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *	* Focus to light do not balance well as in win.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *	  Quality in win is not good, but its kinda better.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *	 * Fix some "extraneous bytes", most of apps will show the image anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *	 * Gamma table, is there, but its really doing something?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *	 * 7~8 Fps, its ok, max on win its 10.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *			Costantino Leandro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #define MODULE_NAME "t613"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "gspca.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) struct sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	struct gspca_dev gspca_dev;	/* !! must be the first item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	struct v4l2_ctrl *freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	struct { /* awb / color gains control cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 		struct v4l2_ctrl *awb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 		struct v4l2_ctrl *gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 		struct v4l2_ctrl *red_balance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 		struct v4l2_ctrl *blue_balance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	u8 sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	u8 button_pressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) enum sensors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	SENSOR_OM6802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	SENSOR_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	SENSOR_TAS5130A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	SENSOR_LT168G,		/* must verify if this is the actual model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) static const struct v4l2_pix_format vga_mode_t16[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 		.bytesperline = 160,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 		.sizeimage = 160 * 120 * 4 / 8 + 590,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 		.colorspace = V4L2_COLORSPACE_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 		.priv = 4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #if 0 /* HDG: broken with my test cam, so lets disable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 		.bytesperline = 176,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 		.sizeimage = 176 * 144 * 3 / 8 + 590,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		.colorspace = V4L2_COLORSPACE_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 		.priv = 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		.bytesperline = 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 		.sizeimage = 320 * 240 * 3 / 8 + 590,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		.colorspace = V4L2_COLORSPACE_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 		.priv = 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #if 0 /* HDG: broken with my test cam, so lets disable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 		.bytesperline = 352,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 		.sizeimage = 352 * 288 * 3 / 8 + 590,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 		.colorspace = V4L2_COLORSPACE_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		.priv = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		.bytesperline = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 		.sizeimage = 640 * 480 * 3 / 8 + 590,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 		.colorspace = V4L2_COLORSPACE_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		.priv = 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /* sensor specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) struct additional_sensor_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	const u8 n3[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	const u8 *n4, n4sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	const u8 reg80, reg8e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	const u8 nset8[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	const u8 data1[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	const u8 data2[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	const u8 data3[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	const u8 data5[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	const u8 stream[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) static const u8 n4_om6802[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) static const u8 n4_other[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) static const u8 n4_tas5130a[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	0xc6, 0xda
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static const u8 n4_lt168g[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) static const struct additional_sensor_data sensor_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) [SENSOR_OM6802] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	.n3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	.n4 = n4_om6802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	.n4sz = sizeof n4_om6802,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	.reg80 = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	.reg8e = 0x33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	.nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	.data1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		 0xb3, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	.data2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	.data3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	.data5 =	/* this could be removed later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	.stream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		{0x0b, 0x04, 0x0a, 0x78},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) [SENSOR_OTHER] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	.n3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	.n4 = n4_other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	.n4sz = sizeof n4_other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	.reg80 = 0xac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	.reg8e = 0xb8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	.nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	.data1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		 0xe8, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.data2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		 0xd9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	.data3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		 0xd9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	.data5 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		{0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	.stream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		{0x0b, 0x04, 0x0a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) [SENSOR_TAS5130A] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	.n3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		{0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	.n4 = n4_tas5130a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	.n4sz = sizeof n4_tas5130a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	.reg80 = 0x3c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	.reg8e = 0xb4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	.nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	.data1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		 0xc8, 0xfc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	.data2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	.data3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		 0xe0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	.data5 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	.stream =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		{0x0b, 0x04, 0x0a, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) [SENSOR_LT168G] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	.n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	.n4 = n4_lt168g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	.n4sz = sizeof n4_lt168g,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	.reg80 = 0x7c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	.reg8e = 0xb3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	.nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	.data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		 0xb0, 0xf4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	.data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	.data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	.data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	.stream = {0x0b, 0x04, 0x0a, 0x28},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)     },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) #define MAX_EFFECTS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static const u8 effects_table[MAX_EFFECTS][6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},	/* Normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},	/* Repujar */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},	/* Monochrome */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},	/* Sepia */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},	/* Croquis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},	/* Sun Effect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},	/* Negative */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) #define GAMMA_MAX (15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) static const u8 gamma_table[GAMMA_MAX+1][17] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) /* gamma table from cam1690.ini */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	{0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21,	/* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	{0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d,	/* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	{0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35,	/* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	{0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f,	/* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	{0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a,	/* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	{0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58,	/* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	{0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67,	/* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,	/* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	{0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79,	/* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	{0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84,	/* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	{0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e,	/* 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	{0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b,	/* 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,	/* 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	{0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,	/* 13 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	{0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,	/* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	{0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,	/* 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	 0xff}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static const u8 tas5130a_sensor_init[][8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) /* read 1 byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) static u8 reg_r(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		   u16 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 			usb_rcvctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			0,		/* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			0,		/* value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 			index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 			gspca_dev->usb_buf, 1, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	return gspca_dev->usb_buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) static void reg_w(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		  u16 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			0, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 			NULL, 0, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) static void reg_w_buf(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		  const u8 *buffer, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	if (len <= USB_BUF_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		memcpy(gspca_dev->usb_buf, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 				usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 				0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 				0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 				gspca_dev->usb_buf, len, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		u8 *tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (!tmpbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			pr_err("Out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 				usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 				0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 				0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 				tmpbuf, len, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		kfree(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) /* write values to consecutive registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			const u8 *buffer, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	u8 *p, *tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	if (len * 2 <= USB_BUF_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		p = tmpbuf = gspca_dev->usb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		p = tmpbuf = kmalloc_array(len, 2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		if (!tmpbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 			pr_err("Out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	i = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		*p++ = reg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		*p++ = *buffer++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			0x01, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			tmpbuf, len * 2, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (len * 2 > USB_BUF_SZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		kfree(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) static void om6802_sensor_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	const u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	u8 byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	static const u8 sensor_init[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		0xdf, 0x6d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		0xdd, 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		0x5a, 0xe0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		0x5c, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		0x5d, 0xb0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		0x5e, 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		0x60, 0x71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		0xef, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		0xe9, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		0xea, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		0x90, 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		0x91, 0xb2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		0x82, 0x32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		0xfd, 0x41,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		0x00			/* table end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	i = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	while (--i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		byte = reg_r(gspca_dev, 0x0060);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		if (!(byte & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	byte = reg_r(gspca_dev, 0x0063);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (byte != 0x17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		pr_err("Bad sensor reset %02x\n", byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		/* continue? */
^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) 	p = sensor_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	while (*p != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		val[1] = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		val[3] = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		if (*p == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			reg_w(gspca_dev, 0x3c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		reg_w_buf(gspca_dev, val, sizeof val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		i = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			msleep(15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			byte = reg_r(gspca_dev, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			if (!(byte & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	msleep(15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	reg_w(gspca_dev, 0x3c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) /* this function is called at probe time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) static int sd_config(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		     const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	struct cam *cam  = &gspca_dev->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	cam->cam_mode = vga_mode_t16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	cam->nmodes = ARRAY_SIZE(vga_mode_t16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) static void setbrightness(struct gspca_dev *gspca_dev, s32 brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (brightness < 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		set6[1] = 0x26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		set6[3] = 0x70 - brightness * 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		set6[3] = 0x00 + ((brightness - 7) * 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	reg_w_buf(gspca_dev, set6, sizeof set6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) static void setcontrast(struct gspca_dev *gspca_dev, s32 contrast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	u16 reg_to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	if (contrast < 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		reg_to_write = 0x8ea9 - contrast * 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	reg_w(gspca_dev, reg_to_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) static void setcolors(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	u16 reg_to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	reg_to_write = 0x80bb + val * 0x100;	/* was 0xc0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	reg_w(gspca_dev, reg_to_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static void setgamma(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	gspca_dbg(gspca_dev, D_CONF, "Gamma: %d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	reg_w_ixbuf(gspca_dev, 0x90,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		gamma_table[val], sizeof gamma_table[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) static void setawb_n_RGB(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	u8 all_gain_reg[8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	s32 red_gain, blue_gain, green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	green_gain = sd->gain->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	red_gain = green_gain + sd->red_balance->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	if (red_gain > 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		red_gain = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	else if (red_gain < 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		red_gain = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	blue_gain = green_gain + sd->blue_balance->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	if (blue_gain > 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		blue_gain = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	else if (blue_gain < 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		blue_gain = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	all_gain_reg[1] = red_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	all_gain_reg[3] = blue_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	all_gain_reg[5] = green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	all_gain_reg[7] = sensor_data[sd->sensor].reg80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	if (!sd->awb->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		all_gain_reg[7] &= ~0x04; /* AWB off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	u16 reg_to_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	reg_to_write = 0x0aa6 + 0x1000 * val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	reg_w(gspca_dev, reg_to_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static void setfreq(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	u8 reg66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	case SENSOR_LT168G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		if (val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 			freq[3] = 0xa8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		reg66 = 0x41;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	case SENSOR_OM6802:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		reg66 = 0xca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		reg66 = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	case 0:				/* no flicker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		freq[3] = 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	case 2:				/* 60Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		reg66 &= ~0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	freq[1] = reg66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	reg_w_buf(gspca_dev, freq, sizeof freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) /* this function is called at probe and resume time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static int sd_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	/* some of this registers are not really needed, because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	 * they are overridden by setbrigthness, setcontrast, etc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	 * but won't hurt anyway, and can help someone with similar webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	 * to see the initial parameters.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	const struct additional_sensor_data *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	u16 sensor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	u8 test_byte = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	static const u8 read_indexs[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	static const u8 n1[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	static const u8 n2[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 			{0x08, 0x00};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	sensor_id = (reg_r(gspca_dev, 0x06) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 			| reg_r(gspca_dev, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	switch (sensor_id & 0xff0f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	case 0x0801:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		gspca_dbg(gspca_dev, D_PROBE, "sensor tas5130a\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		sd->sensor = SENSOR_TAS5130A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	case 0x0802:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		gspca_dbg(gspca_dev, D_PROBE, "sensor lt168g\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		sd->sensor = SENSOR_LT168G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	case 0x0803:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		gspca_dbg(gspca_dev, D_PROBE, "sensor 'other'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		sd->sensor = SENSOR_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	case 0x0807:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		gspca_dbg(gspca_dev, D_PROBE, "sensor om6802\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		sd->sensor = SENSOR_OM6802;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		pr_err("unknown sensor %04x\n", sensor_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	if (sd->sensor == SENSOR_OM6802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		reg_w_buf(gspca_dev, n1, sizeof n1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		i = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			test_byte = reg_r(gspca_dev, 0x0063);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			if (test_byte == 0x17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 				break;		/* OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			pr_err("Bad sensor reset %02x\n", test_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		reg_w_buf(gspca_dev, n2, sizeof n2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	while (read_indexs[i] != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		test_byte = reg_r(gspca_dev, read_indexs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			  read_indexs[i], test_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	sensor = &sensor_data[sd->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	if (sd->sensor == SENSOR_LT168G) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		test_byte = reg_r(gspca_dev, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			  test_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		reg_w(gspca_dev, 0x6c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	reg_w(gspca_dev, (0x20 << 8) + 0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	reg_w(gspca_dev, (0x20 << 8) + 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	reg_w(gspca_dev, (0x20 << 8) + 0x89);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	if (sd->sensor == SENSOR_LT168G) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		test_byte = reg_r(gspca_dev, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 			  test_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		reg_w(gspca_dev, 0x6c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) static void setmirror(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	u8 hflipcmd[8] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		hflipcmd[3] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static void seteffect(struct gspca_dev *gspca_dev, s32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	case V4L2_COLORFX_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	case V4L2_COLORFX_BW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		idx = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	case V4L2_COLORFX_SEPIA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		idx = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	case V4L2_COLORFX_SKETCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		idx = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	case V4L2_COLORFX_NEGATIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		idx = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	reg_w_buf(gspca_dev, effects_table[idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 				sizeof effects_table[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (val == V4L2_COLORFX_SKETCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		reg_w(gspca_dev, 0x4aa6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		reg_w(gspca_dev, 0xfaa6);
^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) /* Is this really needed?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)  * i added some module parameters for test with some users */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static void poll_sensor(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	static const u8 poll1[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		 0x60, 0x14};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	static const u8 poll2[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	static const u8 noise03[] =	/* (some differences / ms-drv) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		 0xc2, 0x80, 0xc3, 0x10};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	gspca_dbg(gspca_dev, D_STREAM, "[Sensor requires polling]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	reg_w_buf(gspca_dev, poll1, sizeof poll1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	reg_w_buf(gspca_dev, poll2, sizeof poll2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	reg_w_buf(gspca_dev, noise03, sizeof noise03);
^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 int sd_start(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	const struct additional_sensor_data *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	int i, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	static const u8 t3[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		{ 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	case 0:		/* 640x480 (0x00) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	case 1:		/* 352x288 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		t2[1] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	case 2:		/* 320x240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		t2[1] = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	case 3:		/* 176x144 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		t2[1] = 0x50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) /*	case 4:		 * 160x120 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		t2[1] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	case SENSOR_OM6802:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		om6802_sensor_init(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	case SENSOR_TAS5130A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 					 sizeof tas5130a_sensor_init[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		reg_w(gspca_dev, 0x3c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		/* just in case and to keep sync with logs (for mine) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 				 sizeof tas5130a_sensor_init[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		reg_w(gspca_dev, 0x3c80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	sensor = &sensor_data[sd->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	reg_r(gspca_dev, 0x0012);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	reg_w_buf(gspca_dev, t2, sizeof t2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	reg_w(gspca_dev, 0x0013);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	msleep(15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	if (sd->sensor == SENSOR_OM6802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		poll_sensor(gspca_dev);
^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) static void sd_stopN(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			sizeof sensor_data[sd->sensor].stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			sizeof sensor_data[sd->sensor].stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	if (sd->sensor == SENSOR_OM6802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		reg_w(gspca_dev, 0x0309);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) #if IS_ENABLED(CONFIG_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	/* If the last button state is pressed, release it now! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (sd->button_pressed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		input_sync(gspca_dev->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		sd->button_pressed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) static void sd_pkt_scan(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			u8 *data,			/* isoc packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			int len)			/* iso packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	int pkt_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	if (data[0] == 0x5a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) #if IS_ENABLED(CONFIG_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		if (len > 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			u8 state = (data[20] & 0x80) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			if (sd->button_pressed != state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				input_report_key(gspca_dev->input_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 						 KEY_CAMERA, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 				input_sync(gspca_dev->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				sd->button_pressed = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		/* Control Packet, after this came the header again,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		 * but extra bytes came in the packet before this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		 * sometimes an EOF arrives, sometimes not... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	data += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	if (data[0] == 0xff && data[1] == 0xd8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		pkt_type = FIRST_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		pkt_type = LAST_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		pkt_type = INTER_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	gspca_frame_add(gspca_dev, pkt_type, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	struct gspca_dev *gspca_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	struct sd *sd = (struct sd *)gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	s32 red_gain, blue_gain, green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	gspca_dev->usb_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	case V4L2_CID_AUTO_WHITE_BALANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		red_gain = reg_r(gspca_dev, 0x0087);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		if (red_gain > 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			red_gain = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		else if (red_gain < 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			red_gain = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		blue_gain = reg_r(gspca_dev, 0x0088);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		if (blue_gain > 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			blue_gain = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		else if (blue_gain < 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			blue_gain = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		green_gain = reg_r(gspca_dev, 0x0089);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		if (green_gain > 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			green_gain = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		else if (green_gain < 0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			green_gain = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		sd->gain->val = green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		sd->red_balance->val = red_gain - green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		sd->blue_balance->val = blue_gain - green_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	struct gspca_dev *gspca_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	gspca_dev->usb_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	if (!gspca_dev->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		setbrightness(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	case V4L2_CID_CONTRAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		setcontrast(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	case V4L2_CID_SATURATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		setcolors(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	case V4L2_CID_GAMMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		setgamma(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		setmirror(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	case V4L2_CID_SHARPNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		setsharpness(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	case V4L2_CID_POWER_LINE_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		setfreq(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	case V4L2_CID_BACKLIGHT_COMPENSATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		reg_w(gspca_dev, ctrl->val ? 0xf48e : 0xb48e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	case V4L2_CID_AUTO_WHITE_BALANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		setawb_n_RGB(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	case V4L2_CID_COLORFX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		seteffect(gspca_dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	return gspca_dev->usb_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) static const struct v4l2_ctrl_ops sd_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	.g_volatile_ctrl = sd_g_volatile_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	.s_ctrl = sd_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) static int sd_init_controls(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct sd *sd = (struct sd *)gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	gspca_dev->vdev.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	v4l2_ctrl_handler_init(hdl, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			V4L2_CID_BRIGHTNESS, 0, 14, 1, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			V4L2_CID_CONTRAST, 0, 0x0d, 1, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			V4L2_CID_SATURATION, 0, 0xf, 1, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 			V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	/* Activate lowlight, some apps don't bring up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	   backlight_compensation control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			V4L2_CID_BACKLIGHT_COMPENSATION, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (sd->sensor == SENSOR_TAS5130A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 				V4L2_CID_HFLIP, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	sd->awb = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			V4L2_CID_GAIN, 0x10, 0x40, 1, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	sd->blue_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			V4L2_CID_BLUE_BALANCE, -0x30, 0x30, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	sd->red_balance = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 			V4L2_CID_RED_BALANCE, -0x30, 0x30, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			V4L2_CID_SHARPNESS, 0, 15, 1, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 			V4L2_CID_COLORFX, V4L2_COLORFX_SKETCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			~((1 << V4L2_COLORFX_NONE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			  (1 << V4L2_COLORFX_BW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 			  (1 << V4L2_COLORFX_SEPIA) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			  (1 << V4L2_COLORFX_SKETCH) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 			  (1 << V4L2_COLORFX_NEGATIVE)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			V4L2_COLORFX_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 			V4L2_CID_POWER_LINE_FREQUENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 			V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		pr_err("Could not initialize controls\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		return hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	v4l2_ctrl_auto_cluster(4, &sd->awb, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) /* sub-driver description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static const struct sd_desc sd_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	.name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	.config = sd_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	.init = sd_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	.init_controls = sd_init_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	.start = sd_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	.stopN = sd_stopN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	.pkt_scan = sd_pkt_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) #if IS_ENABLED(CONFIG_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	.other_input = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* -- module initialisation -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static const struct usb_device_id device_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	{USB_DEVICE(0x17a1, 0x0128)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) MODULE_DEVICE_TABLE(usb, device_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* -- device connect -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static int sd_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		    const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 			       THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static struct usb_driver sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	.name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.id_table = device_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	.probe = sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	.disconnect = gspca_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	.suspend = gspca_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	.resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	.reset_resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) module_usb_driver(sd_driver);