^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) * SQ930x 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-François Moine <http://moinejf.free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006 -2008 Gerard Klaver <gerard at gkall dot hobby dot nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2007 Sam Revitch <samr7@cs.washington.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define MODULE_NAME "sq930x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "gspca.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) "Gerard Klaver <gerard at gkall dot hobby dot nl\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) "Sam Revitch <samr7@cs.washington.edu>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Structure to hold all of our device specific stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct sd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct gspca_dev gspca_dev; /* !! must be the first item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct { /* exposure/gain control cluster */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct v4l2_ctrl *exposure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct v4l2_ctrl *gain;
^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) u8 do_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u8 gpio[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u8 sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define Generic 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define Creative_live_motion 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) enum sensors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SENSOR_ICX098BQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) SENSOR_LZ24BP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) SENSOR_MI0360,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) SENSOR_MT9V111, /* = MI360SOC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) SENSOR_OV7660,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) SENSOR_OV9630,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static struct v4l2_pix_format vga_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {320, 240, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .bytesperline = 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .sizeimage = 320 * 240,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .priv = 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {640, 480, V4L2_PIX_FMT_SRGGB8, V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .bytesperline = 640,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .sizeimage = 640 * 480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .colorspace = V4L2_COLORSPACE_SRGB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .priv = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* sq930x registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define SQ930_CTRL_UCBUS_IO 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define SQ930_CTRL_I2C_IO 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define SQ930_CTRL_GPIO 0x0005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define SQ930_CTRL_CAP_START 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define SQ930_CTRL_CAP_STOP 0x0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define SQ930_CTRL_SET_EXPOSURE 0x001d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define SQ930_CTRL_RESET 0x001e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SQ930_CTRL_GET_DEV_INFO 0x001f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* gpio 1 (8..15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define SQ930_GPIO_DFL_I2C_SDA 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SQ930_GPIO_DFL_I2C_SCL 0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define SQ930_GPIO_RSTBAR 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define SQ930_GPIO_EXTRA1 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define SQ930_GPIO_EXTRA2 0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* gpio 3 (24..31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SQ930_GPIO_POWER 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SQ930_GPIO_DFL_LED 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct ucbus_write_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u16 bw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u8 bw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct i2c_write_cmd {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const struct ucbus_write_cmd icx098bq_start_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xce},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {0xf802, 0xc1}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {0xf80a, 0x01}, {0xf80b, 0xee}, {0xf807, 0x60}, {0xf80c, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {0xf80d, 0xf0}, {0xf80e, 0x03}, {0xf80f, 0x0a}, {0xf81c, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {0xf81d, 0xf0}, {0xf81e, 0x03}, {0xf81f, 0x0a}, {0xf83a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {0xf83b, 0x10}, {0xf83c, 0x00}, {0xf83d, 0x4e}, {0xf810, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {0xf811, 0x00}, {0xf812, 0x02}, {0xf813, 0x10}, {0xf803, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {0xf814, 0x01}, {0xf815, 0x18}, {0xf816, 0x00}, {0xf817, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {0xf823, 0x07}, {0xf824, 0xff}, {0xf825, 0x03}, {0xf826, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {0xf827, 0x06}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {0xf82b, 0x0c}, {0xf82c, 0xfd}, {0xf82d, 0x01}, {0xf82e, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {0xf854, 0x00}, {0xf855, 0x18}, {0xf856, 0x00}, {0xf857, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {0xf858, 0x00}, {0xf859, 0x0c}, {0xf85a, 0x00}, {0xf85b, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {0xf85c, 0x00}, {0xf85d, 0x0c}, {0xf85e, 0x00}, {0xf85f, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {0xf860, 0x00}, {0xf861, 0x48}, {0xf862, 0x01}, {0xf863, 0xdc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {0xf868, 0xff}, {0xf869, 0x70}, {0xf86c, 0xff}, {0xf86d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {0xf86a, 0xff}, {0xf86b, 0x48}, {0xf86e, 0xff}, {0xf86f, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {0xf870, 0x01}, {0xf871, 0xdb}, {0xf872, 0x01}, {0xf873, 0xfa},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {0xf874, 0x01}, {0xf875, 0xdb}, {0xf876, 0x01}, {0xf877, 0xfa},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {0xf800, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const struct ucbus_write_cmd icx098bq_start_1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {0xf5f0, 0x00}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {0xf5f4, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {0xf5f0, 0x49}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {0xf5f4, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {0xf5f9, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static const struct ucbus_write_cmd icx098bq_start_2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x82}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x40}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xcf}, {0xf806, 0xd0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {0xf807, 0x7f}, {0xf800, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static const struct ucbus_write_cmd lz24bp_start_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xbe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {0xf802, 0xc6}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {0xf80a, 0x01}, {0xf80b, 0xfe}, {0xf807, 0x84}, {0xf80c, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {0xf80d, 0xf7}, {0xf80e, 0x03}, {0xf80f, 0x0b}, {0xf81c, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {0xf81d, 0x49}, {0xf81e, 0x03}, {0xf81f, 0x0b}, {0xf83a, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {0xf83b, 0x01}, {0xf83c, 0x00}, {0xf83d, 0x6b}, {0xf810, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {0xf811, 0x10}, {0xf812, 0x02}, {0xf813, 0x6f}, {0xf803, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {0xf814, 0x00}, {0xf815, 0x44}, {0xf816, 0x00}, {0xf817, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {0xf823, 0x07}, {0xf824, 0xfd}, {0xf825, 0x07}, {0xf826, 0xf0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {0xf827, 0x0c}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {0xf82b, 0x0c}, {0xf82c, 0xfc}, {0xf82d, 0x01}, {0xf82e, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {0xf854, 0x00}, {0xf855, 0x0c}, {0xf856, 0x00}, {0xf857, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {0xf858, 0x00}, {0xf859, 0x18}, {0xf85a, 0x00}, {0xf85b, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {0xf85c, 0x00}, {0xf85d, 0x18}, {0xf85e, 0x00}, {0xf85f, 0x3c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {0xf860, 0xff}, {0xf861, 0x37}, {0xf862, 0xff}, {0xf863, 0x1d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0xf868, 0x00}, {0xf869, 0x37}, {0xf86c, 0x02}, {0xf86d, 0x1d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {0xf86a, 0x00}, {0xf86b, 0x37}, {0xf86e, 0x02}, {0xf86f, 0x1d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {0xf870, 0x01}, {0xf871, 0xc6}, {0xf872, 0x02}, {0xf873, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {0xf874, 0x01}, {0xf875, 0xc6}, {0xf876, 0x02}, {0xf877, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {0xf800, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static const struct ucbus_write_cmd lz24bp_start_1_gen[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {0xf5f4, 0xb3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {0xf5f4, 0xb3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {0xf5f9, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static const struct ucbus_write_cmd lz24bp_start_1_clm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {0xf5f4, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {0xf5f4, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {0xf5f9, 0x00}
^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 const struct ucbus_write_cmd lz24bp_start_2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x80}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x4e}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xc0}, {0xf806, 0x48},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {0xf807, 0x7f}, {0xf800, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {0xf807, 0x7f}, {0xf800, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static const struct ucbus_write_cmd mi0360_start_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0xcc}, {0xf333, 0xcc},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {0xf334, 0xcc}, {0xf335, 0xcc}, {0xf33f, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static const struct i2c_write_cmd mi0360_init_23[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {0x30, 0x0040}, /* reserved - def 0x0005 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {0x31, 0x0000}, /* reserved - def 0x002a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {0x34, 0x0100}, /* reserved - def 0x0100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {0x3d, 0x068f}, /* reserved - def 0x068f */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static const struct i2c_write_cmd mi0360_init_24[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {0x03, 0x01e5}, /* window height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {0x04, 0x0285}, /* window width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static const struct i2c_write_cmd mi0360_init_25[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {0x35, 0x0020}, /* global gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {0x2b, 0x0020}, /* green1 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {0x2c, 0x002a}, /* blue gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {0x2d, 0x0028}, /* red gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {0x2e, 0x0020}, /* green2 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static const struct ucbus_write_cmd mi0360_start_1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {0xf5f0, 0x11}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {0xf5f4, 0xa6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {0xf5f0, 0x51}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {0xf5f4, 0xa6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {0xf5f9, 0x00}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static const struct i2c_write_cmd mi0360_start_2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {0x62, 0x041d}, /* reserved - def 0x0418 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static const struct i2c_write_cmd mi0360_start_3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {0x05, 0x007b}, /* horiz blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static const struct i2c_write_cmd mi0360_start_4[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {0x05, 0x03f5}, /* horiz blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static const struct i2c_write_cmd mt9v111_init_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {0x01, 0x0001}, /* select IFP/SOC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {0x06, 0x300c}, /* operating mode control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {0x08, 0xcc00}, /* output format control (RGB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {0x01, 0x0004}, /* select sensor core registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static const struct i2c_write_cmd mt9v111_init_1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {0x03, 0x01e5}, /* window height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {0x04, 0x0285}, /* window width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static const struct i2c_write_cmd mt9v111_init_2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {0x30, 0x7800},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {0x31, 0x0000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {0x07, 0x3002}, /* output control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {0x35, 0x0020}, /* global gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0x2b, 0x0020}, /* green1 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x2c, 0x0020}, /* blue gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x2d, 0x0020}, /* red gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x2e, 0x0020}, /* green2 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static const struct ucbus_write_cmd mt9v111_start_1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0xf5f4, 0xaa},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0xf5f4, 0xaa},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0xf5f9, 0x0a}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static const struct i2c_write_cmd mt9v111_init_3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x62, 0x0405},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static const struct i2c_write_cmd mt9v111_init_4[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /* {0x05, 0x00ce}, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x05, 0x005d}, /* horizontal blanking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct ucbus_write_cmd ov7660_start_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static const struct ucbus_write_cmd ov9630_start_0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* start parameters indexed by [sensor][mode] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static const struct cap_s {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) u8 cc_sizeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u8 cc_bytes[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) } capconfig[4][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) [SENSOR_ICX098BQ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {2, /* Bayer 320x240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {0x05, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {4, /* Bayer 640x480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) [SENSOR_LZ24BP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {2, /* Bayer 320x240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {0x05, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {4, /* Bayer 640x480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) [SENSOR_MI0360] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {2, /* Bayer 320x240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {4, /* Bayer 640x480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) [SENSOR_MT9V111] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {2, /* Bayer 320x240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {0x05, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 0x01, 0x01, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {4, /* Bayer 640x480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct sensor_s {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u8 i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u8 i2c_dum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u8 gpio[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u8 cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) const struct ucbus_write_cmd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static const struct sensor_s sensor_tb[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) [SENSOR_ICX098BQ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) "icx098bp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) SQ930_GPIO_RSTBAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 8, icx098bq_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) [SENSOR_LZ24BP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) "lz24bp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) SQ930_GPIO_RSTBAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 8, lz24bp_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) [SENSOR_MI0360] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) "mi0360",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 0x5d, 0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {SQ930_GPIO_RSTBAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 7, mi0360_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) [SENSOR_MT9V111] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) "mt9v111",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 0x5c, 0x7f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {SQ930_GPIO_RSTBAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 7, mi0360_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) [SENSOR_OV7660] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) "ov7660",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 0x21, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SQ930_GPIO_RSTBAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 7, ov7660_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) [SENSOR_OV9630] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) "ov9630",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 0x30, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SQ930_GPIO_DFL_I2C_SDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) SQ930_GPIO_RSTBAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 7, ov9630_start_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) },
^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) static void reg_r(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) u16 value, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret = usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) usb_rcvctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) value, 0, gspca_dev->usb_buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) pr_err("reg_r %04x failed %d\n", value, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) gspca_dev->usb_err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * Make sure the buffer is zeroed to avoid uninitialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) gspca_dbg(gspca_dev, D_USBO, "reg_w v: %04x i: %04x\n", value, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ret = usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 0x0c, /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) value, index, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) msleep(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pr_err("reg_w %04x %04x failed %d\n", value, index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) gspca_dev->usb_err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) const u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) gspca_dbg(gspca_dev, D_USBO, "reg_wb v: %04x i: %04x %02x...%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) value, index, *data, data[len - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) memcpy(gspca_dev->usb_buf, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 0x0c, /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) value, index, gspca_dev->usb_buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) msleep(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pr_err("reg_wb %04x %04x failed %d\n", value, index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) gspca_dev->usb_err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void i2c_write(struct sd *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) const struct i2c_write_cmd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int ncmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct gspca_dev *gspca_dev = &sd->gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) const struct sensor_s *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) u16 val, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) sensor = &sensor_tb[sd->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) idx = (cmd->val & 0xff00) | cmd->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) buf = gspca_dev->usb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) *buf++ = sensor->i2c_dum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) *buf++ = cmd->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) while (--ncmds > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) cmd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) *buf++ = cmd->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *buf++ = cmd->val >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) *buf++ = sensor->i2c_dum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) *buf++ = cmd->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) gspca_dbg(gspca_dev, D_USBO, "i2c_w v: %04x i: %04x %02x...%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) val, idx, gspca_dev->usb_buf[0], buf[-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 0x0c, /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) val, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) pr_err("i2c_write failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) gspca_dev->usb_err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^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) static void ucbus_write(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) const struct ucbus_write_cmd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int ncmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int batchsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) u16 val, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int len, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if ((batchsize - 1) * 3 > USB_BUF_SZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) gspca_err(gspca_dev, "Bug: usb_buf overflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) gspca_dev->usb_err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) len = ncmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (len > batchsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) len = batchsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ncmds -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) buf = gspca_dev->usb_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) while (--len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) cmd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) *buf++ = cmd->bw_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) *buf++ = cmd->bw_addr >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) *buf++ = cmd->bw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (buf != gspca_dev->usb_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x %02x...%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) val, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) gspca_dev->usb_buf[0], buf[-1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) val, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ret = usb_control_msg(gspca_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) usb_sndctrlpipe(gspca_dev->dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 0x0c, /* request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) val, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) pr_err("ucbus_write failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) gspca_dev->usb_err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) msleep(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (ncmds <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cmd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static void gpio_set(struct sd *sd, u16 val, u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct gspca_dev *gspca_dev = &sd->gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (mask & 0x00ff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) sd->gpio[0] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) sd->gpio[0] |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ~sd->gpio[0] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) mask >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) val >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) sd->gpio[1] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) sd->gpio[1] |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ~sd->gpio[1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static void gpio_init(struct sd *sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) const u8 *gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) gpio_set(sd, *gpio++, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) gpio_set(sd, *gpio++, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) gpio_set(sd, *gpio++, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) gpio_set(sd, *gpio++, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) gpio_set(sd, *gpio, 0x000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static void bridge_init(struct sd *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static const struct ucbus_write_cmd clkfreq_cmd = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static void cmos_probe(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) const struct sensor_s *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static const u8 probe_order[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* SENSOR_LZ24BP, (tested as ccd) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) SENSOR_OV9630,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) SENSOR_MI0360,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) SENSOR_OV7660,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) SENSOR_MT9V111,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) sensor = &sensor_tb[probe_order[i]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) gpio_init(sd, sensor->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (gspca_dev->usb_buf[0] != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (i >= ARRAY_SIZE(probe_order)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pr_err("Unknown sensor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) gspca_dev->usb_err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) sd->sensor = probe_order[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case SENSOR_OV7660:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) case SENSOR_OV9630:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) pr_err("Sensor %s not yet treated\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sensor_tb[sd->sensor].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) gspca_dev->usb_err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^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) static void mt9v111_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int i, nwait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static const u8 cmd_001b[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 0x00, 0x00, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static const u8 cmd_011b[][7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ARRAY_SIZE(cmd_011b[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) msleep(400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) nwait = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) reg_r(gspca_dev, 0x031b, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (gspca_dev->usb_buf[0] == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) || gspca_dev->usb_err != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (--nwait < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) gspca_dbg(gspca_dev, D_PROBE, "mt9v111_init timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) gspca_dev->usb_err = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void global_init(struct sd *sd, int first_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case SENSOR_ICX098BQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (first_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) ucbus_write(&sd->gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) icx098bq_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) gpio_init(sd, sensor_tb[sd->sensor].gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case SENSOR_LZ24BP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (sd->type != Creative_live_motion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) gpio_set(sd, 0, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (first_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ucbus_write(&sd->gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) lz24bp_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) gpio_init(sd, sensor_tb[sd->sensor].gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case SENSOR_MI0360:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (first_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ucbus_write(&sd->gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) mi0360_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ARRAY_SIZE(mi0360_start_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) gpio_init(sd, sensor_tb[sd->sensor].gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* case SENSOR_MT9V111: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (first_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) mt9v111_init(&sd->gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) gpio_init(sd, sensor_tb[sd->sensor].gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void lz24bp_ppl(struct sd *sd, u16 ppl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct ucbus_write_cmd cmds[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {0xf810, ppl >> 8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {0xf811, ppl}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 gain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int i, integclks, intstartclk, frameclks, min_frclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) const struct sensor_s *sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u16 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u8 buf[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) integclks = expo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) cmd = SQ930_CTRL_SET_EXPOSURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case SENSOR_ICX098BQ: /* ccd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case SENSOR_LZ24BP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (integclks >= min_frclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) intstartclk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) frameclks = integclks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) intstartclk = min_frclk - integclks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) frameclks = min_frclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) buf[i++] = intstartclk >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) buf[i++] = intstartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) buf[i++] = frameclks >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) buf[i++] = frameclks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) buf[i++] = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) default: /* cmos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* case SENSOR_MI0360: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* case SENSOR_MT9V111: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) cmd |= 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) sensor = &sensor_tb[sd->sensor];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) buf[i++] = sensor->i2c_addr; /* i2c_slave_addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) buf[i++] = 0x08; /* 2 * ni2c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) buf[i++] = 0x09; /* reg = shutter width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) buf[i++] = integclks >> 8; /* val H */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) buf[i++] = sensor->i2c_dum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) buf[i++] = integclks; /* val L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) buf[i++] = 0x35; /* reg = global gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) buf[i++] = 0x00; /* val H */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) buf[i++] = sensor->i2c_dum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) buf[i++] = 0x80 + gain / 2; /* val L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) buf[i++] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) buf[i++] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) buf[i++] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) buf[i++] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) buf[i++] = 0x83;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) reg_wb(gspca_dev, cmd, 0, buf, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /* This function is called at probe time just before sd_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int sd_config(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct cam *cam = &gspca_dev->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) sd->sensor = id->driver_info >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) sd->type = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) cam->cam_mode = vga_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) cam->nmodes = ARRAY_SIZE(vga_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) cam->bulk = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* this function is called at probe and resume time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int sd_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /*fixme: is this needed for icx098bp and mi0360?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (sd->sensor != SENSOR_LZ24BP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (gspca_dev->usb_err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) return gspca_dev->usb_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) /* it returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * 03 00 12 93 0b f6 c9 00 live! ultra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * 03 00 07 93 0b f6 ca 00 live! ultra for notebook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * 03 00 12 93 0b fe c8 00 Trust WB-3500T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * 02 00 06 93 0b fe c8 00 Joy-IT 318S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * 03 00 12 93 0b f6 cf 00 icam tracer - sensor icx098bq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * 02 00 12 93 0b fe cf 00 ProQ Motion Webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * 1: 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * 2: 06 / 07 / 12 = mode webcam? firmware??
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * 3: 93 chip = 930b (930b or 930c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * 4: 0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * 7: 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) gspca_dbg(gspca_dev, D_PROBE, "info: %*ph\n", 8, gspca_dev->usb_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) bridge_init(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (sd->sensor == SENSOR_MI0360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* no sensor probe for icam tracer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (gspca_dev->usb_buf[5] == 0xf6) /* if ccd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) sd->sensor = SENSOR_ICX098BQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) cmos_probe(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (gspca_dev->usb_err >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) gspca_dbg(gspca_dev, D_PROBE, "Sensor %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) sensor_tb[sd->sensor].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) global_init(sd, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return gspca_dev->usb_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* send the start/stop commands to the webcam */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) static void send_start(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) const struct cap_s *cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) cap = &capconfig[sd->sensor][mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) reg_wb(gspca_dev, 0x0900 | SQ930_CTRL_CAP_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 0x0a00 | cap->cc_sizeid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) cap->cc_bytes, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static void send_stop(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 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) /* function called at start time before URB creation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int sd_isoc_init(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) sd->do_ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) gspca_dev->cam.bulk_size = gspca_dev->pixfmt.width *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) gspca_dev->pixfmt.height + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* start the capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static int sd_start(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) bridge_init(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) global_init(sd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) switch (sd->sensor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case SENSOR_ICX098BQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ucbus_write(gspca_dev, icx098bq_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) ARRAY_SIZE(icx098bq_start_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ucbus_write(gspca_dev, icx098bq_start_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) ARRAY_SIZE(icx098bq_start_1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ucbus_write(gspca_dev, icx098bq_start_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ARRAY_SIZE(icx098bq_start_2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* 1st start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) send_start(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) msleep(70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) gpio_set(sd, 0x7f, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) /* 2nd start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) send_start(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case SENSOR_LZ24BP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) ucbus_write(gspca_dev, lz24bp_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) ARRAY_SIZE(lz24bp_start_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (sd->type != Creative_live_motion)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ucbus_write(gspca_dev, lz24bp_start_1_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ARRAY_SIZE(lz24bp_start_1_gen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ucbus_write(gspca_dev, lz24bp_start_1_clm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ARRAY_SIZE(lz24bp_start_1_clm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ucbus_write(gspca_dev, lz24bp_start_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ARRAY_SIZE(lz24bp_start_2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) lz24bp_ppl(sd, mode == 1 ? 0x0564 : 0x0310);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case SENSOR_MI0360:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ucbus_write(gspca_dev, mi0360_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ARRAY_SIZE(mi0360_start_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) i2c_write(sd, mi0360_init_23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ARRAY_SIZE(mi0360_init_23));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) i2c_write(sd, mi0360_init_24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ARRAY_SIZE(mi0360_init_24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) i2c_write(sd, mi0360_init_25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ARRAY_SIZE(mi0360_init_25));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ucbus_write(gspca_dev, mi0360_start_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ARRAY_SIZE(mi0360_start_1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) i2c_write(sd, mi0360_start_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ARRAY_SIZE(mi0360_start_2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) i2c_write(sd, mi0360_start_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) ARRAY_SIZE(mi0360_start_3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* 1st start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) send_start(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) send_stop(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) i2c_write(sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* case SENSOR_MT9V111: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ucbus_write(gspca_dev, mi0360_start_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ARRAY_SIZE(mi0360_start_0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) i2c_write(sd, mt9v111_init_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ARRAY_SIZE(mt9v111_init_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) i2c_write(sd, mt9v111_init_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) ARRAY_SIZE(mt9v111_init_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) i2c_write(sd, mt9v111_init_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ARRAY_SIZE(mt9v111_init_2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ucbus_write(gspca_dev, mt9v111_start_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) ARRAY_SIZE(mt9v111_start_1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) i2c_write(sd, mt9v111_init_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ARRAY_SIZE(mt9v111_init_3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) i2c_write(sd, mt9v111_init_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ARRAY_SIZE(mt9v111_init_4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) send_start(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (sd->sensor == SENSOR_MT9V111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) sd->do_ctrl = 1; /* set the exposure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return gspca_dev->usb_err;
^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) static void sd_stopN(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (sd->sensor == SENSOR_MT9V111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) gpio_set(sd, 0, SQ930_GPIO_DFL_LED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) send_stop(gspca_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /* function called when the application gets a new frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* It sets the exposure if required and restart the bulk transfer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static void sd_dq_callback(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) sd->do_ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) v4l2_ctrl_g_ctrl(sd->gain));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) gspca_dev->cam.bulk_nurbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ret = usb_submit_urb(gspca_dev->urb[0], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) pr_err("sd_dq_callback() err %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* wait a little time, otherwise the webcam crashes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static void sd_pkt_scan(struct gspca_dev *gspca_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) u8 *data, /* isoc packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int len) /* iso packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (sd->do_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) gspca_dev->cam.bulk_nurbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) gspca_frame_add(gspca_dev, INTER_PACKET, data, len - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct gspca_dev *gspca_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) gspca_dev->usb_err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!gspca_dev->streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) case V4L2_CID_EXPOSURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) setexposure(gspca_dev, ctrl->val, sd->gain->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return gspca_dev->usb_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static const struct v4l2_ctrl_ops sd_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .s_ctrl = sd_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int sd_init_controls(struct gspca_dev *gspca_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct sd *sd = (struct sd *) gspca_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) gspca_dev->vdev.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) v4l2_ctrl_handler_init(hdl, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) V4L2_CID_EXPOSURE, 1, 0xfff, 1, 0x356);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) V4L2_CID_GAIN, 1, 255, 1, 0x8d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) pr_err("Could not initialize controls\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) v4l2_ctrl_cluster(2, &sd->exposure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* sub-driver description */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static const struct sd_desc sd_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .config = sd_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .init = sd_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .init_controls = sd_init_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .isoc_init = sd_isoc_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .start = sd_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .stopN = sd_stopN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .pkt_scan = sd_pkt_scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .dq_callback = sd_dq_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) /* Table of supported USB devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) #define ST(sensor, type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .driver_info = (SENSOR_ ## sensor << 8) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) | (type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static const struct usb_device_id device_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) MODULE_DEVICE_TABLE(usb, device_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /* -- device connect -- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int sd_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static struct usb_driver sd_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .name = MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .id_table = device_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .probe = sd_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) .disconnect = gspca_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .suspend = gspca_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) .resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) .reset_resume = gspca_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) module_usb_driver(sd_driver);