^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);