1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Sonix sn9c201 sn9c202 library 4 * 5 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr> 6 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> 7 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> 8 */ 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <linux/input.h> 13 14 #include "gspca.h" 15 #include "jpeg.h" 16 17 #include <linux/dmi.h> 18 19 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>"); 20 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); 21 MODULE_LICENSE("GPL"); 22 23 /* 24 * Pixel format private data 25 */ 26 #define SCALE_MASK 0x0f 27 #define SCALE_160x120 0 28 #define SCALE_320x240 1 29 #define SCALE_640x480 2 30 #define SCALE_1280x1024 3 31 #define MODE_RAW 0x10 32 #define MODE_JPEG 0x20 33 #define MODE_SXGA 0x80 34 35 #define SENSOR_OV9650 0 36 #define SENSOR_OV9655 1 37 #define SENSOR_SOI968 2 38 #define SENSOR_OV7660 3 39 #define SENSOR_OV7670 4 40 #define SENSOR_MT9V011 5 41 #define SENSOR_MT9V111 6 42 #define SENSOR_MT9V112 7 43 #define SENSOR_MT9M001 8 44 #define SENSOR_MT9M111 9 45 #define SENSOR_MT9M112 10 46 #define SENSOR_HV7131R 11 47 #define SENSOR_MT9VPRB 12 48 49 /* camera flags */ 50 #define HAS_NO_BUTTON 0x1 51 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 52 #define FLIP_DETECT 0x4 53 #define HAS_LED_TORCH 0x8 54 55 /* specific webcam descriptor */ 56 struct sd { 57 struct gspca_dev gspca_dev; 58 59 struct { /* color control cluster */ 60 struct v4l2_ctrl *brightness; 61 struct v4l2_ctrl *contrast; 62 struct v4l2_ctrl *saturation; 63 struct v4l2_ctrl *hue; 64 }; 65 struct { /* blue/red balance control cluster */ 66 struct v4l2_ctrl *blue; 67 struct v4l2_ctrl *red; 68 }; 69 struct { /* h/vflip control cluster */ 70 struct v4l2_ctrl *hflip; 71 struct v4l2_ctrl *vflip; 72 }; 73 struct v4l2_ctrl *gamma; 74 struct { /* autogain and exposure or gain control cluster */ 75 struct v4l2_ctrl *autogain; 76 struct v4l2_ctrl *exposure; 77 struct v4l2_ctrl *gain; 78 }; 79 struct v4l2_ctrl *jpegqual; 80 81 struct v4l2_ctrl *led_mode; 82 83 struct work_struct work; 84 85 u32 pktsz; /* (used by pkt_scan) */ 86 u16 npkt; 87 s8 nchg; 88 u8 fmt; /* (used for JPEG QTAB update */ 89 90 #define MIN_AVG_LUM 80 91 #define MAX_AVG_LUM 130 92 atomic_t avg_lum; 93 u8 old_step; 94 u8 older_step; 95 u8 exposure_step; 96 97 u8 i2c_addr; 98 u8 i2c_intf; 99 u8 sensor; 100 u8 hstart; 101 u8 vstart; 102 103 u8 jpeg_hdr[JPEG_HDR_SZ]; 104 105 u8 flags; 106 }; 107 108 static void qual_upd(struct work_struct *work); 109 110 struct i2c_reg_u8 { 111 u8 reg; 112 u8 val; 113 }; 114 115 struct i2c_reg_u16 { 116 u8 reg; 117 u16 val; 118 }; 119 120 static const struct dmi_system_id flip_dmi_table[] = { 121 { 122 .ident = "MSI MS-1034", 123 .matches = { 124 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."), 125 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"), 126 DMI_MATCH(DMI_PRODUCT_VERSION, "0341") 127 } 128 }, 129 { 130 .ident = "MSI MS-1039", 131 .matches = { 132 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."), 133 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"), 134 } 135 }, 136 { 137 .ident = "MSI MS-1632", 138 .matches = { 139 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 140 DMI_MATCH(DMI_BOARD_NAME, "MS-1632") 141 } 142 }, 143 { 144 .ident = "MSI MS-1633X", 145 .matches = { 146 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 147 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X") 148 } 149 }, 150 { 151 .ident = "MSI MS-1635X", 152 .matches = { 153 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 154 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X") 155 } 156 }, 157 { 158 .ident = "ASUSTeK W7J", 159 .matches = { 160 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), 161 DMI_MATCH(DMI_BOARD_NAME, "W7J ") 162 } 163 }, 164 {} 165 }; 166 167 static const struct v4l2_pix_format vga_mode[] = { 168 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 169 .bytesperline = 160, 170 .sizeimage = 160 * 120 * 4 / 8 + 590, 171 .colorspace = V4L2_COLORSPACE_JPEG, 172 .priv = SCALE_160x120 | MODE_JPEG}, 173 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 174 .bytesperline = 160, 175 .sizeimage = 160 * 120, 176 .colorspace = V4L2_COLORSPACE_SRGB, 177 .priv = SCALE_160x120 | MODE_RAW}, 178 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 179 .bytesperline = 160, 180 .sizeimage = 240 * 120, 181 .colorspace = V4L2_COLORSPACE_SRGB, 182 .priv = SCALE_160x120}, 183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 184 .bytesperline = 320, 185 .sizeimage = 320 * 240 * 4 / 8 + 590, 186 .colorspace = V4L2_COLORSPACE_JPEG, 187 .priv = SCALE_320x240 | MODE_JPEG}, 188 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 189 .bytesperline = 320, 190 .sizeimage = 320 * 240 , 191 .colorspace = V4L2_COLORSPACE_SRGB, 192 .priv = SCALE_320x240 | MODE_RAW}, 193 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 194 .bytesperline = 320, 195 .sizeimage = 480 * 240 , 196 .colorspace = V4L2_COLORSPACE_SRGB, 197 .priv = SCALE_320x240}, 198 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 199 .bytesperline = 640, 200 .sizeimage = 640 * 480 * 4 / 8 + 590, 201 .colorspace = V4L2_COLORSPACE_JPEG, 202 .priv = SCALE_640x480 | MODE_JPEG}, 203 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 204 .bytesperline = 640, 205 .sizeimage = 640 * 480, 206 .colorspace = V4L2_COLORSPACE_SRGB, 207 .priv = SCALE_640x480 | MODE_RAW}, 208 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 209 .bytesperline = 640, 210 .sizeimage = 960 * 480, 211 .colorspace = V4L2_COLORSPACE_SRGB, 212 .priv = SCALE_640x480}, 213 }; 214 215 static const struct v4l2_pix_format sxga_mode[] = { 216 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 217 .bytesperline = 160, 218 .sizeimage = 160 * 120 * 4 / 8 + 590, 219 .colorspace = V4L2_COLORSPACE_JPEG, 220 .priv = SCALE_160x120 | MODE_JPEG}, 221 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 222 .bytesperline = 160, 223 .sizeimage = 160 * 120, 224 .colorspace = V4L2_COLORSPACE_SRGB, 225 .priv = SCALE_160x120 | MODE_RAW}, 226 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 227 .bytesperline = 160, 228 .sizeimage = 240 * 120, 229 .colorspace = V4L2_COLORSPACE_SRGB, 230 .priv = SCALE_160x120}, 231 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 232 .bytesperline = 320, 233 .sizeimage = 320 * 240 * 4 / 8 + 590, 234 .colorspace = V4L2_COLORSPACE_JPEG, 235 .priv = SCALE_320x240 | MODE_JPEG}, 236 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 237 .bytesperline = 320, 238 .sizeimage = 320 * 240 , 239 .colorspace = V4L2_COLORSPACE_SRGB, 240 .priv = SCALE_320x240 | MODE_RAW}, 241 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 242 .bytesperline = 320, 243 .sizeimage = 480 * 240 , 244 .colorspace = V4L2_COLORSPACE_SRGB, 245 .priv = SCALE_320x240}, 246 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 247 .bytesperline = 640, 248 .sizeimage = 640 * 480 * 4 / 8 + 590, 249 .colorspace = V4L2_COLORSPACE_JPEG, 250 .priv = SCALE_640x480 | MODE_JPEG}, 251 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 252 .bytesperline = 640, 253 .sizeimage = 640 * 480, 254 .colorspace = V4L2_COLORSPACE_SRGB, 255 .priv = SCALE_640x480 | MODE_RAW}, 256 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 257 .bytesperline = 640, 258 .sizeimage = 960 * 480, 259 .colorspace = V4L2_COLORSPACE_SRGB, 260 .priv = SCALE_640x480}, 261 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 262 .bytesperline = 1280, 263 .sizeimage = 1280 * 1024, 264 .colorspace = V4L2_COLORSPACE_SRGB, 265 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, 266 }; 267 268 static const struct v4l2_pix_format mono_mode[] = { 269 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 270 .bytesperline = 160, 271 .sizeimage = 160 * 120, 272 .colorspace = V4L2_COLORSPACE_SRGB, 273 .priv = SCALE_160x120 | MODE_RAW}, 274 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 275 .bytesperline = 320, 276 .sizeimage = 320 * 240 , 277 .colorspace = V4L2_COLORSPACE_SRGB, 278 .priv = SCALE_320x240 | MODE_RAW}, 279 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 280 .bytesperline = 640, 281 .sizeimage = 640 * 480, 282 .colorspace = V4L2_COLORSPACE_SRGB, 283 .priv = SCALE_640x480 | MODE_RAW}, 284 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 285 .bytesperline = 1280, 286 .sizeimage = 1280 * 1024, 287 .colorspace = V4L2_COLORSPACE_SRGB, 288 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, 289 }; 290 291 static const s16 hsv_red_x[] = { 292 41, 44, 46, 48, 50, 52, 54, 56, 293 58, 60, 62, 64, 66, 68, 70, 72, 294 74, 76, 78, 80, 81, 83, 85, 87, 295 88, 90, 92, 93, 95, 97, 98, 100, 296 101, 102, 104, 105, 107, 108, 109, 110, 297 112, 113, 114, 115, 116, 117, 118, 119, 298 120, 121, 122, 123, 123, 124, 125, 125, 299 126, 127, 127, 128, 128, 129, 129, 129, 300 130, 130, 130, 130, 131, 131, 131, 131, 301 131, 131, 131, 131, 130, 130, 130, 130, 302 129, 129, 129, 128, 128, 127, 127, 126, 303 125, 125, 124, 123, 122, 122, 121, 120, 304 119, 118, 117, 116, 115, 114, 112, 111, 305 110, 109, 107, 106, 105, 103, 102, 101, 306 99, 98, 96, 94, 93, 91, 90, 88, 307 86, 84, 83, 81, 79, 77, 75, 74, 308 72, 70, 68, 66, 64, 62, 60, 58, 309 56, 54, 52, 49, 47, 45, 43, 41, 310 39, 36, 34, 32, 30, 28, 25, 23, 311 21, 19, 16, 14, 12, 9, 7, 5, 312 3, 0, -1, -3, -6, -8, -10, -12, 313 -15, -17, -19, -22, -24, -26, -28, -30, 314 -33, -35, -37, -39, -41, -44, -46, -48, 315 -50, -52, -54, -56, -58, -60, -62, -64, 316 -66, -68, -70, -72, -74, -76, -78, -80, 317 -81, -83, -85, -87, -88, -90, -92, -93, 318 -95, -97, -98, -100, -101, -102, -104, -105, 319 -107, -108, -109, -110, -112, -113, -114, -115, 320 -116, -117, -118, -119, -120, -121, -122, -123, 321 -123, -124, -125, -125, -126, -127, -127, -128, 322 -128, -128, -128, -128, -128, -128, -128, -128, 323 -128, -128, -128, -128, -128, -128, -128, -128, 324 -128, -128, -128, -128, -128, -128, -128, -128, 325 -128, -127, -127, -126, -125, -125, -124, -123, 326 -122, -122, -121, -120, -119, -118, -117, -116, 327 -115, -114, -112, -111, -110, -109, -107, -106, 328 -105, -103, -102, -101, -99, -98, -96, -94, 329 -93, -91, -90, -88, -86, -84, -83, -81, 330 -79, -77, -75, -74, -72, -70, -68, -66, 331 -64, -62, -60, -58, -56, -54, -52, -49, 332 -47, -45, -43, -41, -39, -36, -34, -32, 333 -30, -28, -25, -23, -21, -19, -16, -14, 334 -12, -9, -7, -5, -3, 0, 1, 3, 335 6, 8, 10, 12, 15, 17, 19, 22, 336 24, 26, 28, 30, 33, 35, 37, 39, 41 337 }; 338 339 static const s16 hsv_red_y[] = { 340 82, 80, 78, 76, 74, 73, 71, 69, 341 67, 65, 63, 61, 58, 56, 54, 52, 342 50, 48, 46, 44, 41, 39, 37, 35, 343 32, 30, 28, 26, 23, 21, 19, 16, 344 14, 12, 10, 7, 5, 3, 0, -1, 345 -3, -6, -8, -10, -13, -15, -17, -19, 346 -22, -24, -26, -29, -31, -33, -35, -38, 347 -40, -42, -44, -46, -48, -51, -53, -55, 348 -57, -59, -61, -63, -65, -67, -69, -71, 349 -73, -75, -77, -79, -81, -82, -84, -86, 350 -88, -89, -91, -93, -94, -96, -98, -99, 351 -101, -102, -104, -105, -106, -108, -109, -110, 352 -112, -113, -114, -115, -116, -117, -119, -120, 353 -120, -121, -122, -123, -124, -125, -126, -126, 354 -127, -128, -128, -128, -128, -128, -128, -128, 355 -128, -128, -128, -128, -128, -128, -128, -128, 356 -128, -128, -128, -128, -128, -128, -128, -128, 357 -128, -128, -128, -128, -128, -128, -128, -128, 358 -127, -127, -126, -125, -125, -124, -123, -122, 359 -121, -120, -119, -118, -117, -116, -115, -114, 360 -113, -111, -110, -109, -107, -106, -105, -103, 361 -102, -100, -99, -97, -96, -94, -92, -91, 362 -89, -87, -85, -84, -82, -80, -78, -76, 363 -74, -73, -71, -69, -67, -65, -63, -61, 364 -58, -56, -54, -52, -50, -48, -46, -44, 365 -41, -39, -37, -35, -32, -30, -28, -26, 366 -23, -21, -19, -16, -14, -12, -10, -7, 367 -5, -3, 0, 1, 3, 6, 8, 10, 368 13, 15, 17, 19, 22, 24, 26, 29, 369 31, 33, 35, 38, 40, 42, 44, 46, 370 48, 51, 53, 55, 57, 59, 61, 63, 371 65, 67, 69, 71, 73, 75, 77, 79, 372 81, 82, 84, 86, 88, 89, 91, 93, 373 94, 96, 98, 99, 101, 102, 104, 105, 374 106, 108, 109, 110, 112, 113, 114, 115, 375 116, 117, 119, 120, 120, 121, 122, 123, 376 124, 125, 126, 126, 127, 128, 128, 129, 377 129, 130, 130, 131, 131, 131, 131, 132, 378 132, 132, 132, 132, 132, 132, 132, 132, 379 132, 132, 132, 131, 131, 131, 130, 130, 380 130, 129, 129, 128, 127, 127, 126, 125, 381 125, 124, 123, 122, 121, 120, 119, 118, 382 117, 116, 115, 114, 113, 111, 110, 109, 383 107, 106, 105, 103, 102, 100, 99, 97, 384 96, 94, 92, 91, 89, 87, 85, 84, 82 385 }; 386 387 static const s16 hsv_green_x[] = { 388 -124, -124, -125, -125, -125, -125, -125, -125, 389 -125, -126, -126, -125, -125, -125, -125, -125, 390 -125, -124, -124, -124, -123, -123, -122, -122, 391 -121, -121, -120, -120, -119, -118, -117, -117, 392 -116, -115, -114, -113, -112, -111, -110, -109, 393 -108, -107, -105, -104, -103, -102, -100, -99, 394 -98, -96, -95, -93, -92, -91, -89, -87, 395 -86, -84, -83, -81, -79, -77, -76, -74, 396 -72, -70, -69, -67, -65, -63, -61, -59, 397 -57, -55, -53, -51, -49, -47, -45, -43, 398 -41, -39, -37, -35, -33, -30, -28, -26, 399 -24, -22, -20, -18, -15, -13, -11, -9, 400 -7, -4, -2, 0, 1, 3, 6, 8, 401 10, 12, 14, 17, 19, 21, 23, 25, 402 27, 29, 32, 34, 36, 38, 40, 42, 403 44, 46, 48, 50, 52, 54, 56, 58, 404 60, 62, 64, 66, 68, 70, 71, 73, 405 75, 77, 78, 80, 82, 83, 85, 87, 406 88, 90, 91, 93, 94, 96, 97, 98, 407 100, 101, 102, 104, 105, 106, 107, 108, 408 109, 111, 112, 113, 113, 114, 115, 116, 409 117, 118, 118, 119, 120, 120, 121, 122, 410 122, 123, 123, 124, 124, 124, 125, 125, 411 125, 125, 125, 125, 125, 126, 126, 125, 412 125, 125, 125, 125, 125, 124, 124, 124, 413 123, 123, 122, 122, 121, 121, 120, 120, 414 119, 118, 117, 117, 116, 115, 114, 113, 415 112, 111, 110, 109, 108, 107, 105, 104, 416 103, 102, 100, 99, 98, 96, 95, 93, 417 92, 91, 89, 87, 86, 84, 83, 81, 418 79, 77, 76, 74, 72, 70, 69, 67, 419 65, 63, 61, 59, 57, 55, 53, 51, 420 49, 47, 45, 43, 41, 39, 37, 35, 421 33, 30, 28, 26, 24, 22, 20, 18, 422 15, 13, 11, 9, 7, 4, 2, 0, 423 -1, -3, -6, -8, -10, -12, -14, -17, 424 -19, -21, -23, -25, -27, -29, -32, -34, 425 -36, -38, -40, -42, -44, -46, -48, -50, 426 -52, -54, -56, -58, -60, -62, -64, -66, 427 -68, -70, -71, -73, -75, -77, -78, -80, 428 -82, -83, -85, -87, -88, -90, -91, -93, 429 -94, -96, -97, -98, -100, -101, -102, -104, 430 -105, -106, -107, -108, -109, -111, -112, -113, 431 -113, -114, -115, -116, -117, -118, -118, -119, 432 -120, -120, -121, -122, -122, -123, -123, -124, -124 433 }; 434 435 static const s16 hsv_green_y[] = { 436 -100, -99, -98, -97, -95, -94, -93, -91, 437 -90, -89, -87, -86, -84, -83, -81, -80, 438 -78, -76, -75, -73, -71, -70, -68, -66, 439 -64, -63, -61, -59, -57, -55, -53, -51, 440 -49, -48, -46, -44, -42, -40, -38, -36, 441 -34, -32, -30, -27, -25, -23, -21, -19, 442 -17, -15, -13, -11, -9, -7, -4, -2, 443 0, 1, 3, 5, 7, 9, 11, 14, 444 16, 18, 20, 22, 24, 26, 28, 30, 445 32, 34, 36, 38, 40, 42, 44, 46, 446 48, 50, 52, 54, 56, 58, 59, 61, 447 63, 65, 67, 68, 70, 72, 74, 75, 448 77, 78, 80, 82, 83, 85, 86, 88, 449 89, 90, 92, 93, 95, 96, 97, 98, 450 100, 101, 102, 103, 104, 105, 106, 107, 451 108, 109, 110, 111, 112, 112, 113, 114, 452 115, 115, 116, 116, 117, 117, 118, 118, 453 119, 119, 119, 120, 120, 120, 120, 120, 454 121, 121, 121, 121, 121, 121, 120, 120, 455 120, 120, 120, 119, 119, 119, 118, 118, 456 117, 117, 116, 116, 115, 114, 114, 113, 457 112, 111, 111, 110, 109, 108, 107, 106, 458 105, 104, 103, 102, 100, 99, 98, 97, 459 95, 94, 93, 91, 90, 89, 87, 86, 460 84, 83, 81, 80, 78, 76, 75, 73, 461 71, 70, 68, 66, 64, 63, 61, 59, 462 57, 55, 53, 51, 49, 48, 46, 44, 463 42, 40, 38, 36, 34, 32, 30, 27, 464 25, 23, 21, 19, 17, 15, 13, 11, 465 9, 7, 4, 2, 0, -1, -3, -5, 466 -7, -9, -11, -14, -16, -18, -20, -22, 467 -24, -26, -28, -30, -32, -34, -36, -38, 468 -40, -42, -44, -46, -48, -50, -52, -54, 469 -56, -58, -59, -61, -63, -65, -67, -68, 470 -70, -72, -74, -75, -77, -78, -80, -82, 471 -83, -85, -86, -88, -89, -90, -92, -93, 472 -95, -96, -97, -98, -100, -101, -102, -103, 473 -104, -105, -106, -107, -108, -109, -110, -111, 474 -112, -112, -113, -114, -115, -115, -116, -116, 475 -117, -117, -118, -118, -119, -119, -119, -120, 476 -120, -120, -120, -120, -121, -121, -121, -121, 477 -121, -121, -120, -120, -120, -120, -120, -119, 478 -119, -119, -118, -118, -117, -117, -116, -116, 479 -115, -114, -114, -113, -112, -111, -111, -110, 480 -109, -108, -107, -106, -105, -104, -103, -102, -100 481 }; 482 483 static const s16 hsv_blue_x[] = { 484 112, 113, 114, 114, 115, 116, 117, 117, 485 118, 118, 119, 119, 120, 120, 120, 121, 486 121, 121, 122, 122, 122, 122, 122, 122, 487 122, 122, 122, 122, 122, 122, 121, 121, 488 121, 120, 120, 120, 119, 119, 118, 118, 489 117, 116, 116, 115, 114, 113, 113, 112, 490 111, 110, 109, 108, 107, 106, 105, 104, 491 103, 102, 100, 99, 98, 97, 95, 94, 492 93, 91, 90, 88, 87, 85, 84, 82, 493 80, 79, 77, 76, 74, 72, 70, 69, 494 67, 65, 63, 61, 60, 58, 56, 54, 495 52, 50, 48, 46, 44, 42, 40, 38, 496 36, 34, 32, 30, 28, 26, 24, 22, 497 19, 17, 15, 13, 11, 9, 7, 5, 498 2, 0, -1, -3, -5, -7, -9, -12, 499 -14, -16, -18, -20, -22, -24, -26, -28, 500 -31, -33, -35, -37, -39, -41, -43, -45, 501 -47, -49, -51, -53, -54, -56, -58, -60, 502 -62, -64, -66, -67, -69, -71, -73, -74, 503 -76, -78, -79, -81, -83, -84, -86, -87, 504 -89, -90, -92, -93, -94, -96, -97, -98, 505 -99, -101, -102, -103, -104, -105, -106, -107, 506 -108, -109, -110, -111, -112, -113, -114, -114, 507 -115, -116, -117, -117, -118, -118, -119, -119, 508 -120, -120, -120, -121, -121, -121, -122, -122, 509 -122, -122, -122, -122, -122, -122, -122, -122, 510 -122, -122, -121, -121, -121, -120, -120, -120, 511 -119, -119, -118, -118, -117, -116, -116, -115, 512 -114, -113, -113, -112, -111, -110, -109, -108, 513 -107, -106, -105, -104, -103, -102, -100, -99, 514 -98, -97, -95, -94, -93, -91, -90, -88, 515 -87, -85, -84, -82, -80, -79, -77, -76, 516 -74, -72, -70, -69, -67, -65, -63, -61, 517 -60, -58, -56, -54, -52, -50, -48, -46, 518 -44, -42, -40, -38, -36, -34, -32, -30, 519 -28, -26, -24, -22, -19, -17, -15, -13, 520 -11, -9, -7, -5, -2, 0, 1, 3, 521 5, 7, 9, 12, 14, 16, 18, 20, 522 22, 24, 26, 28, 31, 33, 35, 37, 523 39, 41, 43, 45, 47, 49, 51, 53, 524 54, 56, 58, 60, 62, 64, 66, 67, 525 69, 71, 73, 74, 76, 78, 79, 81, 526 83, 84, 86, 87, 89, 90, 92, 93, 527 94, 96, 97, 98, 99, 101, 102, 103, 528 104, 105, 106, 107, 108, 109, 110, 111, 112 529 }; 530 531 static const s16 hsv_blue_y[] = { 532 -11, -13, -15, -17, -19, -21, -23, -25, 533 -27, -29, -31, -33, -35, -37, -39, -41, 534 -43, -45, -46, -48, -50, -52, -54, -55, 535 -57, -59, -61, -62, -64, -66, -67, -69, 536 -71, -72, -74, -75, -77, -78, -80, -81, 537 -83, -84, -86, -87, -88, -90, -91, -92, 538 -93, -95, -96, -97, -98, -99, -100, -101, 539 -102, -103, -104, -105, -106, -106, -107, -108, 540 -109, -109, -110, -111, -111, -112, -112, -113, 541 -113, -114, -114, -114, -115, -115, -115, -115, 542 -116, -116, -116, -116, -116, -116, -116, -116, 543 -116, -115, -115, -115, -115, -114, -114, -114, 544 -113, -113, -112, -112, -111, -111, -110, -110, 545 -109, -108, -108, -107, -106, -105, -104, -103, 546 -102, -101, -100, -99, -98, -97, -96, -95, 547 -94, -93, -91, -90, -89, -88, -86, -85, 548 -84, -82, -81, -79, -78, -76, -75, -73, 549 -71, -70, -68, -67, -65, -63, -62, -60, 550 -58, -56, -55, -53, -51, -49, -47, -45, 551 -44, -42, -40, -38, -36, -34, -32, -30, 552 -28, -26, -24, -22, -20, -18, -16, -14, 553 -12, -10, -8, -6, -4, -2, 0, 1, 554 3, 5, 7, 9, 11, 13, 15, 17, 555 19, 21, 23, 25, 27, 29, 31, 33, 556 35, 37, 39, 41, 43, 45, 46, 48, 557 50, 52, 54, 55, 57, 59, 61, 62, 558 64, 66, 67, 69, 71, 72, 74, 75, 559 77, 78, 80, 81, 83, 84, 86, 87, 560 88, 90, 91, 92, 93, 95, 96, 97, 561 98, 99, 100, 101, 102, 103, 104, 105, 562 106, 106, 107, 108, 109, 109, 110, 111, 563 111, 112, 112, 113, 113, 114, 114, 114, 564 115, 115, 115, 115, 116, 116, 116, 116, 565 116, 116, 116, 116, 116, 115, 115, 115, 566 115, 114, 114, 114, 113, 113, 112, 112, 567 111, 111, 110, 110, 109, 108, 108, 107, 568 106, 105, 104, 103, 102, 101, 100, 99, 569 98, 97, 96, 95, 94, 93, 91, 90, 570 89, 88, 86, 85, 84, 82, 81, 79, 571 78, 76, 75, 73, 71, 70, 68, 67, 572 65, 63, 62, 60, 58, 56, 55, 53, 573 51, 49, 47, 45, 44, 42, 40, 38, 574 36, 34, 32, 30, 28, 26, 24, 22, 575 20, 18, 16, 14, 12, 10, 8, 6, 576 4, 2, 0, -1, -3, -5, -7, -9, -11 577 }; 578 579 static const u16 bridge_init[][2] = { 580 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, 581 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, 582 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, 583 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00}, 584 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50}, 585 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50}, 586 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04}, 587 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05}, 588 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00}, 589 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d}, 590 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04}, 591 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8}, 592 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32}, 593 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd}, 594 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01}, 595 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, 596 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, 597 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, 598 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}, 599 {0x1007, 0x00} 600 }; 601 602 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ 603 static const u8 ov_gain[] = { 604 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, 605 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, 606 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, 607 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */, 608 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */, 609 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */, 610 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */, 611 0x70 /* 8x */ 612 }; 613 614 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ 615 static const u16 micron1_gain[] = { 616 /* 1x 1.25x 1.5x 1.75x */ 617 0x0020, 0x0028, 0x0030, 0x0038, 618 /* 2x 2.25x 2.5x 2.75x */ 619 0x00a0, 0x00a4, 0x00a8, 0x00ac, 620 /* 3x 3.25x 3.5x 3.75x */ 621 0x00b0, 0x00b4, 0x00b8, 0x00bc, 622 /* 4x 4.25x 4.5x 4.75x */ 623 0x00c0, 0x00c4, 0x00c8, 0x00cc, 624 /* 5x 5.25x 5.5x 5.75x */ 625 0x00d0, 0x00d4, 0x00d8, 0x00dc, 626 /* 6x 6.25x 6.5x 6.75x */ 627 0x00e0, 0x00e4, 0x00e8, 0x00ec, 628 /* 7x 7.25x 7.5x 7.75x */ 629 0x00f0, 0x00f4, 0x00f8, 0x00fc, 630 /* 8x */ 631 0x01c0 632 }; 633 634 /* mt9m001 sensor uses a different gain formula then other micron sensors */ 635 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ 636 static const u16 micron2_gain[] = { 637 /* 1x 1.25x 1.5x 1.75x */ 638 0x0008, 0x000a, 0x000c, 0x000e, 639 /* 2x 2.25x 2.5x 2.75x */ 640 0x0010, 0x0012, 0x0014, 0x0016, 641 /* 3x 3.25x 3.5x 3.75x */ 642 0x0018, 0x001a, 0x001c, 0x001e, 643 /* 4x 4.25x 4.5x 4.75x */ 644 0x0020, 0x0051, 0x0052, 0x0053, 645 /* 5x 5.25x 5.5x 5.75x */ 646 0x0054, 0x0055, 0x0056, 0x0057, 647 /* 6x 6.25x 6.5x 6.75x */ 648 0x0058, 0x0059, 0x005a, 0x005b, 649 /* 7x 7.25x 7.5x 7.75x */ 650 0x005c, 0x005d, 0x005e, 0x005f, 651 /* 8x */ 652 0x0060 653 }; 654 655 /* Gain = .5 + bit[7:0] / 16 */ 656 static const u8 hv7131r_gain[] = { 657 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, 658 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, 659 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, 660 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */, 661 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */, 662 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */, 663 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */, 664 0x78 /* 8x */ 665 }; 666 667 static const struct i2c_reg_u8 soi968_init[] = { 668 {0x0c, 0x00}, {0x0f, 0x1f}, 669 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 670 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 671 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, 672 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, 673 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, 674 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13}, 675 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, 676 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, 677 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, 678 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, 679 }; 680 681 static const struct i2c_reg_u8 ov7660_init[] = { 682 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 683 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 684 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 685 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using 686 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */ 687 {0x17, 0x10}, {0x18, 0x61}, 688 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 689 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00}, 690 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50}, 691 }; 692 693 static const struct i2c_reg_u8 ov7670_init[] = { 694 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 695 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 696 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 697 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, 698 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07}, 699 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75}, 700 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8}, 701 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, 702 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27}, 703 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, 704 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a}, 705 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00}, 706 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, 707 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80}, 708 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, 709 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20}, 710 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c}, 711 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66}, 712 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, 713 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40}, 714 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02}, 715 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a}, 716 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, 717 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04}, 718 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30}, 719 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88}, 720 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, 721 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99}, 722 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, 723 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, 724 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, 725 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, 726 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, 727 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, 728 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06}, 729 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a}, 730 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a}, 731 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84}, 732 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d}, 733 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d}, 734 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00}, 735 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, 736 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60}, 737 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, 738 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e}, 739 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56}, 740 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03}, 741 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47}, 742 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74}, 743 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2}, 744 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00}, 745 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a}, 746 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00}, 747 {0x93, 0x00}, 748 }; 749 750 static const struct i2c_reg_u8 ov9650_init[] = { 751 {0x00, 0x00}, {0x01, 0x78}, 752 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 753 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 754 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, 755 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c}, 756 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2}, 757 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07}, 758 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00}, 759 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04}, 760 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68}, 761 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80}, 762 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00}, 763 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00}, 764 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30}, 765 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf}, 766 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00}, 767 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01}, 768 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19}, 769 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1}, 770 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80}, 771 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00}, 772 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20}, 773 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf}, 774 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88}, 775 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00}, 776 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8}, 777 {0xaa, 0x92}, {0xab, 0x0a}, 778 }; 779 780 static const struct i2c_reg_u8 ov9655_init[] = { 781 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 782 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, 783 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, 784 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, 785 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19}, 786 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80}, 787 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c}, 788 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc}, 789 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05}, 790 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e}, 791 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, 792 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, 793 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, 794 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, 795 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, 796 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01}, 797 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, 798 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00}, 799 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61}, 800 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, 801 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01}, 802 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a}, 803 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c}, 804 {0x04, 0x03}, {0x00, 0x13}, 805 }; 806 807 static const struct i2c_reg_u16 mt9v112_init[] = { 808 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, 809 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, 810 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, 811 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a}, 812 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58}, 813 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001}, 814 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020}, 815 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020}, 816 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020}, 817 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 818 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2}, 819 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 820 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020}, 821 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 822 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae}, 823 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, 824 }; 825 826 static const struct i2c_reg_u16 mt9v111_init[] = { 827 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 828 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0}, 829 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e}, 830 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016}, 831 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004}, 832 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008}, 833 {0x0e, 0x0008}, {0x20, 0x0000} 834 }; 835 836 static const struct i2c_reg_u16 mt9v011_init[] = { 837 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, 838 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, 839 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, 840 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000}, 841 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000}, 842 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000}, 843 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000}, 844 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000}, 845 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000}, 846 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000}, 847 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000}, 848 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000}, 849 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024}, 850 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000}, 851 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100}, 852 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1}, 853 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000}, 854 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000}, 855 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000}, 856 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101}, 857 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003}, 858 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 859 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000}, 860 {0x06, 0x0029}, {0x05, 0x0009}, 861 }; 862 863 static const struct i2c_reg_u16 mt9m001_init[] = { 864 {0x0d, 0x0001}, 865 {0x0d, 0x0000}, 866 {0x04, 0x0500}, /* hres = 1280 */ 867 {0x03, 0x0400}, /* vres = 1024 */ 868 {0x20, 0x1100}, 869 {0x06, 0x0010}, 870 {0x2b, 0x0024}, 871 {0x2e, 0x0024}, 872 {0x35, 0x0024}, 873 {0x2d, 0x0020}, 874 {0x2c, 0x0020}, 875 {0x09, 0x0ad4}, 876 {0x35, 0x0057}, 877 }; 878 879 static const struct i2c_reg_u16 mt9m111_init[] = { 880 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 881 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 882 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 883 {0xf0, 0x0000}, 884 }; 885 886 static const struct i2c_reg_u16 mt9m112_init[] = { 887 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 888 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 889 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 890 {0xf0, 0x0000}, 891 }; 892 893 static const struct i2c_reg_u8 hv7131r_init[] = { 894 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 895 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 896 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, 897 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07}, 898 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62}, 899 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10}, 900 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00}, 901 {0x23, 0x09}, {0x01, 0x08}, 902 }; 903 904 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 905 { 906 struct usb_device *dev = gspca_dev->dev; 907 int result; 908 909 if (gspca_dev->usb_err < 0) 910 return; 911 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 912 0x00, 913 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 914 reg, 915 0x00, 916 gspca_dev->usb_buf, 917 length, 918 500); 919 if (unlikely(result < 0 || result != length)) { 920 pr_err("Read register %02x failed %d\n", reg, result); 921 gspca_dev->usb_err = result; 922 /* 923 * Make sure the buffer is zeroed to avoid uninitialized 924 * values. 925 */ 926 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); 927 } 928 } 929 930 static void reg_w(struct gspca_dev *gspca_dev, u16 reg, 931 const u8 *buffer, int length) 932 { 933 struct usb_device *dev = gspca_dev->dev; 934 int result; 935 936 if (gspca_dev->usb_err < 0) 937 return; 938 memcpy(gspca_dev->usb_buf, buffer, length); 939 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 940 0x08, 941 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 942 reg, 943 0x00, 944 gspca_dev->usb_buf, 945 length, 946 500); 947 if (unlikely(result < 0 || result != length)) { 948 pr_err("Write register %02x failed %d\n", reg, result); 949 gspca_dev->usb_err = result; 950 } 951 } 952 953 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value) 954 { 955 reg_w(gspca_dev, reg, &value, 1); 956 } 957 958 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer) 959 { 960 int i; 961 962 reg_w(gspca_dev, 0x10c0, buffer, 8); 963 for (i = 0; i < 5; i++) { 964 reg_r(gspca_dev, 0x10c0, 1); 965 if (gspca_dev->usb_err < 0) 966 return; 967 if (gspca_dev->usb_buf[0] & 0x04) { 968 if (gspca_dev->usb_buf[0] & 0x08) { 969 pr_err("i2c_w error\n"); 970 gspca_dev->usb_err = -EIO; 971 } 972 return; 973 } 974 msleep(10); 975 } 976 pr_err("i2c_w reg %02x no response\n", buffer[2]); 977 /* gspca_dev->usb_err = -EIO; fixme: may occur */ 978 } 979 980 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val) 981 { 982 struct sd *sd = (struct sd *) gspca_dev; 983 u8 row[8]; 984 985 /* 986 * from the point of view of the bridge, the length 987 * includes the address 988 */ 989 row[0] = sd->i2c_intf | (2 << 4); 990 row[1] = sd->i2c_addr; 991 row[2] = reg; 992 row[3] = val; 993 row[4] = 0x00; 994 row[5] = 0x00; 995 row[6] = 0x00; 996 row[7] = 0x10; 997 998 i2c_w(gspca_dev, row); 999 } 1000 1001 static void i2c_w1_buf(struct gspca_dev *gspca_dev, 1002 const struct i2c_reg_u8 *buf, int sz) 1003 { 1004 while (--sz >= 0) { 1005 i2c_w1(gspca_dev, buf->reg, buf->val); 1006 buf++; 1007 } 1008 } 1009 1010 static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val) 1011 { 1012 struct sd *sd = (struct sd *) gspca_dev; 1013 u8 row[8]; 1014 1015 /* 1016 * from the point of view of the bridge, the length 1017 * includes the address 1018 */ 1019 row[0] = sd->i2c_intf | (3 << 4); 1020 row[1] = sd->i2c_addr; 1021 row[2] = reg; 1022 row[3] = val >> 8; 1023 row[4] = val; 1024 row[5] = 0x00; 1025 row[6] = 0x00; 1026 row[7] = 0x10; 1027 1028 i2c_w(gspca_dev, row); 1029 } 1030 1031 static void i2c_w2_buf(struct gspca_dev *gspca_dev, 1032 const struct i2c_reg_u16 *buf, int sz) 1033 { 1034 while (--sz >= 0) { 1035 i2c_w2(gspca_dev, buf->reg, buf->val); 1036 buf++; 1037 } 1038 } 1039 1040 static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val) 1041 { 1042 struct sd *sd = (struct sd *) gspca_dev; 1043 u8 row[8]; 1044 1045 row[0] = sd->i2c_intf | (1 << 4); 1046 row[1] = sd->i2c_addr; 1047 row[2] = reg; 1048 row[3] = 0; 1049 row[4] = 0; 1050 row[5] = 0; 1051 row[6] = 0; 1052 row[7] = 0x10; 1053 i2c_w(gspca_dev, row); 1054 row[0] = sd->i2c_intf | (1 << 4) | 0x02; 1055 row[2] = 0; 1056 i2c_w(gspca_dev, row); 1057 reg_r(gspca_dev, 0x10c2, 5); 1058 *val = gspca_dev->usb_buf[4]; 1059 } 1060 1061 static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val) 1062 { 1063 struct sd *sd = (struct sd *) gspca_dev; 1064 u8 row[8]; 1065 1066 row[0] = sd->i2c_intf | (1 << 4); 1067 row[1] = sd->i2c_addr; 1068 row[2] = reg; 1069 row[3] = 0; 1070 row[4] = 0; 1071 row[5] = 0; 1072 row[6] = 0; 1073 row[7] = 0x10; 1074 i2c_w(gspca_dev, row); 1075 row[0] = sd->i2c_intf | (2 << 4) | 0x02; 1076 row[2] = 0; 1077 i2c_w(gspca_dev, row); 1078 reg_r(gspca_dev, 0x10c2, 5); 1079 *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4]; 1080 } 1081 1082 static void ov9650_init_sensor(struct gspca_dev *gspca_dev) 1083 { 1084 u16 id; 1085 struct sd *sd = (struct sd *) gspca_dev; 1086 1087 i2c_r2(gspca_dev, 0x1c, &id); 1088 if (gspca_dev->usb_err < 0) 1089 return; 1090 1091 if (id != 0x7fa2) { 1092 pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id); 1093 gspca_dev->usb_err = -ENODEV; 1094 return; 1095 } 1096 1097 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1098 msleep(200); 1099 i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init)); 1100 if (gspca_dev->usb_err < 0) 1101 pr_err("OV9650 sensor initialization failed\n"); 1102 sd->hstart = 1; 1103 sd->vstart = 7; 1104 } 1105 1106 static void ov9655_init_sensor(struct gspca_dev *gspca_dev) 1107 { 1108 struct sd *sd = (struct sd *) gspca_dev; 1109 1110 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1111 msleep(200); 1112 i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init)); 1113 if (gspca_dev->usb_err < 0) 1114 pr_err("OV9655 sensor initialization failed\n"); 1115 1116 sd->hstart = 1; 1117 sd->vstart = 2; 1118 } 1119 1120 static void soi968_init_sensor(struct gspca_dev *gspca_dev) 1121 { 1122 struct sd *sd = (struct sd *) gspca_dev; 1123 1124 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1125 msleep(200); 1126 i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init)); 1127 if (gspca_dev->usb_err < 0) 1128 pr_err("SOI968 sensor initialization failed\n"); 1129 1130 sd->hstart = 60; 1131 sd->vstart = 11; 1132 } 1133 1134 static void ov7660_init_sensor(struct gspca_dev *gspca_dev) 1135 { 1136 struct sd *sd = (struct sd *) gspca_dev; 1137 1138 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1139 msleep(200); 1140 i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init)); 1141 if (gspca_dev->usb_err < 0) 1142 pr_err("OV7660 sensor initialization failed\n"); 1143 sd->hstart = 3; 1144 sd->vstart = 3; 1145 } 1146 1147 static void ov7670_init_sensor(struct gspca_dev *gspca_dev) 1148 { 1149 struct sd *sd = (struct sd *) gspca_dev; 1150 1151 i2c_w1(gspca_dev, 0x12, 0x80); /* sensor reset */ 1152 msleep(200); 1153 i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init)); 1154 if (gspca_dev->usb_err < 0) 1155 pr_err("OV7670 sensor initialization failed\n"); 1156 1157 sd->hstart = 0; 1158 sd->vstart = 1; 1159 } 1160 1161 static void mt9v_init_sensor(struct gspca_dev *gspca_dev) 1162 { 1163 struct sd *sd = (struct sd *) gspca_dev; 1164 u16 value; 1165 1166 sd->i2c_addr = 0x5d; 1167 i2c_r2(gspca_dev, 0xff, &value); 1168 if (gspca_dev->usb_err >= 0 1169 && value == 0x8243) { 1170 i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init)); 1171 if (gspca_dev->usb_err < 0) { 1172 pr_err("MT9V011 sensor initialization failed\n"); 1173 return; 1174 } 1175 sd->hstart = 2; 1176 sd->vstart = 2; 1177 sd->sensor = SENSOR_MT9V011; 1178 pr_info("MT9V011 sensor detected\n"); 1179 return; 1180 } 1181 1182 gspca_dev->usb_err = 0; 1183 sd->i2c_addr = 0x5c; 1184 i2c_w2(gspca_dev, 0x01, 0x0004); 1185 i2c_r2(gspca_dev, 0xff, &value); 1186 if (gspca_dev->usb_err >= 0 1187 && value == 0x823a) { 1188 i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init)); 1189 if (gspca_dev->usb_err < 0) { 1190 pr_err("MT9V111 sensor initialization failed\n"); 1191 return; 1192 } 1193 sd->hstart = 2; 1194 sd->vstart = 2; 1195 sd->sensor = SENSOR_MT9V111; 1196 pr_info("MT9V111 sensor detected\n"); 1197 return; 1198 } 1199 1200 gspca_dev->usb_err = 0; 1201 sd->i2c_addr = 0x5d; 1202 i2c_w2(gspca_dev, 0xf0, 0x0000); 1203 if (gspca_dev->usb_err < 0) { 1204 gspca_dev->usb_err = 0; 1205 sd->i2c_addr = 0x48; 1206 i2c_w2(gspca_dev, 0xf0, 0x0000); 1207 } 1208 i2c_r2(gspca_dev, 0x00, &value); 1209 if (gspca_dev->usb_err >= 0 1210 && value == 0x1229) { 1211 i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init)); 1212 if (gspca_dev->usb_err < 0) { 1213 pr_err("MT9V112 sensor initialization failed\n"); 1214 return; 1215 } 1216 sd->hstart = 6; 1217 sd->vstart = 2; 1218 sd->sensor = SENSOR_MT9V112; 1219 pr_info("MT9V112 sensor detected\n"); 1220 return; 1221 } 1222 1223 gspca_dev->usb_err = -ENODEV; 1224 } 1225 1226 static void mt9m112_init_sensor(struct gspca_dev *gspca_dev) 1227 { 1228 struct sd *sd = (struct sd *) gspca_dev; 1229 1230 i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init)); 1231 if (gspca_dev->usb_err < 0) 1232 pr_err("MT9M112 sensor initialization failed\n"); 1233 1234 sd->hstart = 0; 1235 sd->vstart = 2; 1236 } 1237 1238 static void mt9m111_init_sensor(struct gspca_dev *gspca_dev) 1239 { 1240 struct sd *sd = (struct sd *) gspca_dev; 1241 1242 i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init)); 1243 if (gspca_dev->usb_err < 0) 1244 pr_err("MT9M111 sensor initialization failed\n"); 1245 1246 sd->hstart = 0; 1247 sd->vstart = 2; 1248 } 1249 1250 static void mt9m001_init_sensor(struct gspca_dev *gspca_dev) 1251 { 1252 struct sd *sd = (struct sd *) gspca_dev; 1253 u16 id; 1254 1255 i2c_r2(gspca_dev, 0x00, &id); 1256 if (gspca_dev->usb_err < 0) 1257 return; 1258 1259 /* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */ 1260 switch (id) { 1261 case 0x8411: 1262 case 0x8421: 1263 pr_info("MT9M001 color sensor detected\n"); 1264 break; 1265 case 0x8431: 1266 pr_info("MT9M001 mono sensor detected\n"); 1267 break; 1268 default: 1269 pr_err("No MT9M001 chip detected, ID = %x\n\n", id); 1270 gspca_dev->usb_err = -ENODEV; 1271 return; 1272 } 1273 1274 i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init)); 1275 if (gspca_dev->usb_err < 0) 1276 pr_err("MT9M001 sensor initialization failed\n"); 1277 1278 sd->hstart = 1; 1279 sd->vstart = 1; 1280 } 1281 1282 static void hv7131r_init_sensor(struct gspca_dev *gspca_dev) 1283 { 1284 struct sd *sd = (struct sd *) gspca_dev; 1285 1286 i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init)); 1287 if (gspca_dev->usb_err < 0) 1288 pr_err("HV7131R Sensor initialization failed\n"); 1289 1290 sd->hstart = 0; 1291 sd->vstart = 1; 1292 } 1293 1294 static void set_cmatrix(struct gspca_dev *gspca_dev, 1295 s32 brightness, s32 contrast, s32 satur, s32 hue) 1296 { 1297 s32 hue_coord, hue_index = 180 + hue; 1298 u8 cmatrix[21]; 1299 1300 memset(cmatrix, 0, sizeof(cmatrix)); 1301 cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26; 1302 cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25; 1303 cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25; 1304 cmatrix[18] = brightness - 0x80; 1305 1306 hue_coord = (hsv_red_x[hue_index] * satur) >> 8; 1307 cmatrix[6] = hue_coord; 1308 cmatrix[7] = (hue_coord >> 8) & 0x0f; 1309 1310 hue_coord = (hsv_red_y[hue_index] * satur) >> 8; 1311 cmatrix[8] = hue_coord; 1312 cmatrix[9] = (hue_coord >> 8) & 0x0f; 1313 1314 hue_coord = (hsv_green_x[hue_index] * satur) >> 8; 1315 cmatrix[10] = hue_coord; 1316 cmatrix[11] = (hue_coord >> 8) & 0x0f; 1317 1318 hue_coord = (hsv_green_y[hue_index] * satur) >> 8; 1319 cmatrix[12] = hue_coord; 1320 cmatrix[13] = (hue_coord >> 8) & 0x0f; 1321 1322 hue_coord = (hsv_blue_x[hue_index] * satur) >> 8; 1323 cmatrix[14] = hue_coord; 1324 cmatrix[15] = (hue_coord >> 8) & 0x0f; 1325 1326 hue_coord = (hsv_blue_y[hue_index] * satur) >> 8; 1327 cmatrix[16] = hue_coord; 1328 cmatrix[17] = (hue_coord >> 8) & 0x0f; 1329 1330 reg_w(gspca_dev, 0x10e1, cmatrix, 21); 1331 } 1332 1333 static void set_gamma(struct gspca_dev *gspca_dev, s32 val) 1334 { 1335 u8 gamma[17]; 1336 u8 gval = val * 0xb8 / 0x100; 1337 1338 gamma[0] = 0x0a; 1339 gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8); 1340 gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8); 1341 gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8); 1342 gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8); 1343 gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8); 1344 gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8); 1345 gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8); 1346 gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8); 1347 gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8); 1348 gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8); 1349 gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8); 1350 gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8); 1351 gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8); 1352 gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8); 1353 gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8); 1354 gamma[16] = 0xf5; 1355 1356 reg_w(gspca_dev, 0x1190, gamma, 17); 1357 } 1358 1359 static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red) 1360 { 1361 reg_w1(gspca_dev, 0x118c, red); 1362 reg_w1(gspca_dev, 0x118f, blue); 1363 } 1364 1365 static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) 1366 { 1367 u8 value, tslb; 1368 u16 value2; 1369 struct sd *sd = (struct sd *) gspca_dev; 1370 1371 if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) { 1372 hflip = !hflip; 1373 vflip = !vflip; 1374 } 1375 1376 switch (sd->sensor) { 1377 case SENSOR_OV7660: 1378 value = 0x01; 1379 if (hflip) 1380 value |= 0x20; 1381 if (vflip) { 1382 value |= 0x10; 1383 sd->vstart = 2; 1384 } else { 1385 sd->vstart = 3; 1386 } 1387 reg_w1(gspca_dev, 0x1182, sd->vstart); 1388 i2c_w1(gspca_dev, 0x1e, value); 1389 break; 1390 case SENSOR_OV9650: 1391 i2c_r1(gspca_dev, 0x1e, &value); 1392 value &= ~0x30; 1393 tslb = 0x01; 1394 if (hflip) 1395 value |= 0x20; 1396 if (vflip) { 1397 value |= 0x10; 1398 tslb = 0x49; 1399 } 1400 i2c_w1(gspca_dev, 0x1e, value); 1401 i2c_w1(gspca_dev, 0x3a, tslb); 1402 break; 1403 case SENSOR_MT9V111: 1404 case SENSOR_MT9V011: 1405 i2c_r2(gspca_dev, 0x20, &value2); 1406 value2 &= ~0xc0a0; 1407 if (hflip) 1408 value2 |= 0x8080; 1409 if (vflip) 1410 value2 |= 0x4020; 1411 i2c_w2(gspca_dev, 0x20, value2); 1412 break; 1413 case SENSOR_MT9M112: 1414 case SENSOR_MT9M111: 1415 case SENSOR_MT9V112: 1416 i2c_r2(gspca_dev, 0x20, &value2); 1417 value2 &= ~0x0003; 1418 if (hflip) 1419 value2 |= 0x0002; 1420 if (vflip) 1421 value2 |= 0x0001; 1422 i2c_w2(gspca_dev, 0x20, value2); 1423 break; 1424 case SENSOR_HV7131R: 1425 i2c_r1(gspca_dev, 0x01, &value); 1426 value &= ~0x03; 1427 if (vflip) 1428 value |= 0x01; 1429 if (hflip) 1430 value |= 0x02; 1431 i2c_w1(gspca_dev, 0x01, value); 1432 break; 1433 } 1434 } 1435 1436 static void set_exposure(struct gspca_dev *gspca_dev, s32 expo) 1437 { 1438 struct sd *sd = (struct sd *) gspca_dev; 1439 u8 exp[8] = {sd->i2c_intf, sd->i2c_addr, 1440 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 1441 int expo2; 1442 1443 if (gspca_dev->streaming) 1444 exp[7] = 0x1e; 1445 1446 switch (sd->sensor) { 1447 case SENSOR_OV7660: 1448 case SENSOR_OV7670: 1449 case SENSOR_OV9655: 1450 case SENSOR_OV9650: 1451 if (expo > 547) 1452 expo2 = 547; 1453 else 1454 expo2 = expo; 1455 exp[0] |= (2 << 4); 1456 exp[2] = 0x10; /* AECH */ 1457 exp[3] = expo2 >> 2; 1458 exp[7] = 0x10; 1459 i2c_w(gspca_dev, exp); 1460 exp[2] = 0x04; /* COM1 */ 1461 exp[3] = expo2 & 0x0003; 1462 exp[7] = 0x10; 1463 i2c_w(gspca_dev, exp); 1464 expo -= expo2; 1465 exp[7] = 0x1e; 1466 exp[0] |= (3 << 4); 1467 exp[2] = 0x2d; /* ADVFL & ADVFH */ 1468 exp[3] = expo; 1469 exp[4] = expo >> 8; 1470 break; 1471 case SENSOR_MT9M001: 1472 case SENSOR_MT9V112: 1473 case SENSOR_MT9V011: 1474 exp[0] |= (3 << 4); 1475 exp[2] = 0x09; 1476 exp[3] = expo >> 8; 1477 exp[4] = expo; 1478 break; 1479 case SENSOR_HV7131R: 1480 exp[0] |= (4 << 4); 1481 exp[2] = 0x25; 1482 exp[3] = expo >> 5; 1483 exp[4] = expo << 3; 1484 exp[5] = 0; 1485 break; 1486 default: 1487 return; 1488 } 1489 i2c_w(gspca_dev, exp); 1490 } 1491 1492 static void set_gain(struct gspca_dev *gspca_dev, s32 g) 1493 { 1494 struct sd *sd = (struct sd *) gspca_dev; 1495 u8 gain[8] = {sd->i2c_intf, sd->i2c_addr, 1496 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; 1497 1498 if (gspca_dev->streaming) 1499 gain[7] = 0x15; /* or 1d ? */ 1500 1501 switch (sd->sensor) { 1502 case SENSOR_OV7660: 1503 case SENSOR_OV7670: 1504 case SENSOR_SOI968: 1505 case SENSOR_OV9655: 1506 case SENSOR_OV9650: 1507 gain[0] |= (2 << 4); 1508 gain[3] = ov_gain[g]; 1509 break; 1510 case SENSOR_MT9V011: 1511 gain[0] |= (3 << 4); 1512 gain[2] = 0x35; 1513 gain[3] = micron1_gain[g] >> 8; 1514 gain[4] = micron1_gain[g]; 1515 break; 1516 case SENSOR_MT9V112: 1517 gain[0] |= (3 << 4); 1518 gain[2] = 0x2f; 1519 gain[3] = micron1_gain[g] >> 8; 1520 gain[4] = micron1_gain[g]; 1521 break; 1522 case SENSOR_MT9M001: 1523 gain[0] |= (3 << 4); 1524 gain[2] = 0x2f; 1525 gain[3] = micron2_gain[g] >> 8; 1526 gain[4] = micron2_gain[g]; 1527 break; 1528 case SENSOR_HV7131R: 1529 gain[0] |= (2 << 4); 1530 gain[2] = 0x30; 1531 gain[3] = hv7131r_gain[g]; 1532 break; 1533 default: 1534 return; 1535 } 1536 i2c_w(gspca_dev, gain); 1537 } 1538 1539 static void set_led_mode(struct gspca_dev *gspca_dev, s32 val) 1540 { 1541 reg_w1(gspca_dev, 0x1007, 0x60); 1542 reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00); 1543 } 1544 1545 static void set_quality(struct gspca_dev *gspca_dev, s32 val) 1546 { 1547 struct sd *sd = (struct sd *) gspca_dev; 1548 1549 jpeg_set_qual(sd->jpeg_hdr, val); 1550 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ 1551 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ 1552 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 1553 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); 1554 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */ 1555 reg_w1(gspca_dev, 0x10e0, sd->fmt); 1556 sd->fmt ^= 0x0c; /* invert QTAB use + write */ 1557 reg_w1(gspca_dev, 0x10e0, sd->fmt); 1558 } 1559 1560 #ifdef CONFIG_VIDEO_ADV_DEBUG 1561 static int sd_dbg_g_register(struct gspca_dev *gspca_dev, 1562 struct v4l2_dbg_register *reg) 1563 { 1564 struct sd *sd = (struct sd *) gspca_dev; 1565 1566 reg->size = 1; 1567 switch (reg->match.addr) { 1568 case 0: 1569 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1570 return -EINVAL; 1571 reg_r(gspca_dev, reg->reg, 1); 1572 reg->val = gspca_dev->usb_buf[0]; 1573 return gspca_dev->usb_err; 1574 case 1: 1575 if (sd->sensor >= SENSOR_MT9V011 && 1576 sd->sensor <= SENSOR_MT9M112) { 1577 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val); 1578 reg->size = 2; 1579 } else { 1580 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val); 1581 } 1582 return gspca_dev->usb_err; 1583 } 1584 return -EINVAL; 1585 } 1586 1587 static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1588 const struct v4l2_dbg_register *reg) 1589 { 1590 struct sd *sd = (struct sd *) gspca_dev; 1591 1592 switch (reg->match.addr) { 1593 case 0: 1594 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1595 return -EINVAL; 1596 reg_w1(gspca_dev, reg->reg, reg->val); 1597 return gspca_dev->usb_err; 1598 case 1: 1599 if (sd->sensor >= SENSOR_MT9V011 && 1600 sd->sensor <= SENSOR_MT9M112) { 1601 i2c_w2(gspca_dev, reg->reg, reg->val); 1602 } else { 1603 i2c_w1(gspca_dev, reg->reg, reg->val); 1604 } 1605 return gspca_dev->usb_err; 1606 } 1607 return -EINVAL; 1608 } 1609 1610 static int sd_chip_info(struct gspca_dev *gspca_dev, 1611 struct v4l2_dbg_chip_info *chip) 1612 { 1613 if (chip->match.addr > 1) 1614 return -EINVAL; 1615 if (chip->match.addr == 1) 1616 strscpy(chip->name, "sensor", sizeof(chip->name)); 1617 return 0; 1618 } 1619 #endif 1620 1621 static int sd_config(struct gspca_dev *gspca_dev, 1622 const struct usb_device_id *id) 1623 { 1624 struct sd *sd = (struct sd *) gspca_dev; 1625 struct cam *cam; 1626 1627 cam = &gspca_dev->cam; 1628 cam->needs_full_bandwidth = 1; 1629 1630 sd->sensor = id->driver_info >> 8; 1631 sd->i2c_addr = id->driver_info; 1632 sd->flags = id->driver_info >> 16; 1633 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */ 1634 1635 switch (sd->sensor) { 1636 case SENSOR_MT9M112: 1637 case SENSOR_MT9M111: 1638 case SENSOR_OV9650: 1639 case SENSOR_SOI968: 1640 cam->cam_mode = sxga_mode; 1641 cam->nmodes = ARRAY_SIZE(sxga_mode); 1642 break; 1643 case SENSOR_MT9M001: 1644 cam->cam_mode = mono_mode; 1645 cam->nmodes = ARRAY_SIZE(mono_mode); 1646 break; 1647 case SENSOR_HV7131R: 1648 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */ 1649 fallthrough; 1650 default: 1651 cam->cam_mode = vga_mode; 1652 cam->nmodes = ARRAY_SIZE(vga_mode); 1653 break; 1654 } 1655 1656 sd->old_step = 0; 1657 sd->older_step = 0; 1658 sd->exposure_step = 16; 1659 1660 INIT_WORK(&sd->work, qual_upd); 1661 1662 return 0; 1663 } 1664 1665 static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 1666 { 1667 struct gspca_dev *gspca_dev = 1668 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 1669 struct sd *sd = (struct sd *)gspca_dev; 1670 1671 gspca_dev->usb_err = 0; 1672 1673 if (!gspca_dev->streaming) 1674 return 0; 1675 1676 switch (ctrl->id) { 1677 /* color control cluster */ 1678 case V4L2_CID_BRIGHTNESS: 1679 set_cmatrix(gspca_dev, sd->brightness->val, 1680 sd->contrast->val, sd->saturation->val, sd->hue->val); 1681 break; 1682 case V4L2_CID_GAMMA: 1683 set_gamma(gspca_dev, ctrl->val); 1684 break; 1685 /* blue/red balance cluster */ 1686 case V4L2_CID_BLUE_BALANCE: 1687 set_redblue(gspca_dev, sd->blue->val, sd->red->val); 1688 break; 1689 /* h/vflip cluster */ 1690 case V4L2_CID_HFLIP: 1691 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val); 1692 break; 1693 /* standalone exposure control */ 1694 case V4L2_CID_EXPOSURE: 1695 set_exposure(gspca_dev, ctrl->val); 1696 break; 1697 /* standalone gain control */ 1698 case V4L2_CID_GAIN: 1699 set_gain(gspca_dev, ctrl->val); 1700 break; 1701 /* autogain + exposure or gain control cluster */ 1702 case V4L2_CID_AUTOGAIN: 1703 if (sd->sensor == SENSOR_SOI968) 1704 set_gain(gspca_dev, sd->gain->val); 1705 else 1706 set_exposure(gspca_dev, sd->exposure->val); 1707 break; 1708 case V4L2_CID_JPEG_COMPRESSION_QUALITY: 1709 set_quality(gspca_dev, ctrl->val); 1710 break; 1711 case V4L2_CID_FLASH_LED_MODE: 1712 set_led_mode(gspca_dev, ctrl->val); 1713 break; 1714 } 1715 return gspca_dev->usb_err; 1716 } 1717 1718 static const struct v4l2_ctrl_ops sd_ctrl_ops = { 1719 .s_ctrl = sd_s_ctrl, 1720 }; 1721 1722 static int sd_init_controls(struct gspca_dev *gspca_dev) 1723 { 1724 struct sd *sd = (struct sd *) gspca_dev; 1725 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 1726 1727 gspca_dev->vdev.ctrl_handler = hdl; 1728 v4l2_ctrl_handler_init(hdl, 13); 1729 1730 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1731 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); 1732 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1733 V4L2_CID_CONTRAST, 0, 255, 1, 127); 1734 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1735 V4L2_CID_SATURATION, 0, 255, 1, 127); 1736 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1737 V4L2_CID_HUE, -180, 180, 1, 0); 1738 1739 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1740 V4L2_CID_GAMMA, 0, 255, 1, 0x10); 1741 1742 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1743 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); 1744 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1745 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); 1746 1747 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && 1748 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && 1749 sd->sensor != SENSOR_MT9VPRB) { 1750 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1751 V4L2_CID_HFLIP, 0, 1, 1, 0); 1752 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1753 V4L2_CID_VFLIP, 0, 1, 1, 0); 1754 } 1755 1756 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && 1757 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 && 1758 sd->sensor != SENSOR_MT9V111) 1759 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1760 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33); 1761 1762 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 && 1763 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) { 1764 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1765 V4L2_CID_GAIN, 0, 28, 1, 0); 1766 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1767 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1768 } 1769 1770 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1771 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); 1772 1773 if (sd->flags & HAS_LED_TORCH) 1774 sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, 1775 V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH, 1776 ~0x5, V4L2_FLASH_LED_MODE_NONE); 1777 1778 if (hdl->error) { 1779 pr_err("Could not initialize controls\n"); 1780 return hdl->error; 1781 } 1782 1783 v4l2_ctrl_cluster(4, &sd->brightness); 1784 v4l2_ctrl_cluster(2, &sd->blue); 1785 if (sd->hflip) 1786 v4l2_ctrl_cluster(2, &sd->hflip); 1787 if (sd->autogain) { 1788 if (sd->sensor == SENSOR_SOI968) 1789 /* this sensor doesn't have the exposure control and 1790 autogain is clustered with gain instead. This works 1791 because sd->exposure == NULL. */ 1792 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false); 1793 else 1794 /* Otherwise autogain is clustered with exposure. */ 1795 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); 1796 } 1797 return 0; 1798 } 1799 1800 static int sd_init(struct gspca_dev *gspca_dev) 1801 { 1802 struct sd *sd = (struct sd *) gspca_dev; 1803 int i; 1804 u8 value; 1805 u8 i2c_init[9] = { 1806 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 1807 }; 1808 1809 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { 1810 value = bridge_init[i][1]; 1811 reg_w(gspca_dev, bridge_init[i][0], &value, 1); 1812 if (gspca_dev->usb_err < 0) { 1813 pr_err("Device initialization failed\n"); 1814 return gspca_dev->usb_err; 1815 } 1816 } 1817 1818 if (sd->flags & LED_REVERSE) 1819 reg_w1(gspca_dev, 0x1006, 0x00); 1820 else 1821 reg_w1(gspca_dev, 0x1006, 0x20); 1822 1823 reg_w(gspca_dev, 0x10c0, i2c_init, 9); 1824 if (gspca_dev->usb_err < 0) { 1825 pr_err("Device initialization failed\n"); 1826 return gspca_dev->usb_err; 1827 } 1828 1829 switch (sd->sensor) { 1830 case SENSOR_OV9650: 1831 ov9650_init_sensor(gspca_dev); 1832 if (gspca_dev->usb_err < 0) 1833 break; 1834 pr_info("OV9650 sensor detected\n"); 1835 break; 1836 case SENSOR_OV9655: 1837 ov9655_init_sensor(gspca_dev); 1838 if (gspca_dev->usb_err < 0) 1839 break; 1840 pr_info("OV9655 sensor detected\n"); 1841 break; 1842 case SENSOR_SOI968: 1843 soi968_init_sensor(gspca_dev); 1844 if (gspca_dev->usb_err < 0) 1845 break; 1846 pr_info("SOI968 sensor detected\n"); 1847 break; 1848 case SENSOR_OV7660: 1849 ov7660_init_sensor(gspca_dev); 1850 if (gspca_dev->usb_err < 0) 1851 break; 1852 pr_info("OV7660 sensor detected\n"); 1853 break; 1854 case SENSOR_OV7670: 1855 ov7670_init_sensor(gspca_dev); 1856 if (gspca_dev->usb_err < 0) 1857 break; 1858 pr_info("OV7670 sensor detected\n"); 1859 break; 1860 case SENSOR_MT9VPRB: 1861 mt9v_init_sensor(gspca_dev); 1862 if (gspca_dev->usb_err < 0) 1863 break; 1864 pr_info("MT9VPRB sensor detected\n"); 1865 break; 1866 case SENSOR_MT9M111: 1867 mt9m111_init_sensor(gspca_dev); 1868 if (gspca_dev->usb_err < 0) 1869 break; 1870 pr_info("MT9M111 sensor detected\n"); 1871 break; 1872 case SENSOR_MT9M112: 1873 mt9m112_init_sensor(gspca_dev); 1874 if (gspca_dev->usb_err < 0) 1875 break; 1876 pr_info("MT9M112 sensor detected\n"); 1877 break; 1878 case SENSOR_MT9M001: 1879 mt9m001_init_sensor(gspca_dev); 1880 if (gspca_dev->usb_err < 0) 1881 break; 1882 break; 1883 case SENSOR_HV7131R: 1884 hv7131r_init_sensor(gspca_dev); 1885 if (gspca_dev->usb_err < 0) 1886 break; 1887 pr_info("HV7131R sensor detected\n"); 1888 break; 1889 default: 1890 pr_err("Unsupported sensor\n"); 1891 gspca_dev->usb_err = -ENODEV; 1892 } 1893 return gspca_dev->usb_err; 1894 } 1895 1896 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) 1897 { 1898 struct sd *sd = (struct sd *) gspca_dev; 1899 u8 value; 1900 1901 switch (sd->sensor) { 1902 case SENSOR_SOI968: 1903 if (mode & MODE_SXGA) { 1904 i2c_w1(gspca_dev, 0x17, 0x1d); 1905 i2c_w1(gspca_dev, 0x18, 0xbd); 1906 i2c_w1(gspca_dev, 0x19, 0x01); 1907 i2c_w1(gspca_dev, 0x1a, 0x81); 1908 i2c_w1(gspca_dev, 0x12, 0x00); 1909 sd->hstart = 140; 1910 sd->vstart = 19; 1911 } else { 1912 i2c_w1(gspca_dev, 0x17, 0x13); 1913 i2c_w1(gspca_dev, 0x18, 0x63); 1914 i2c_w1(gspca_dev, 0x19, 0x01); 1915 i2c_w1(gspca_dev, 0x1a, 0x79); 1916 i2c_w1(gspca_dev, 0x12, 0x40); 1917 sd->hstart = 60; 1918 sd->vstart = 11; 1919 } 1920 break; 1921 case SENSOR_OV9650: 1922 if (mode & MODE_SXGA) { 1923 i2c_w1(gspca_dev, 0x17, 0x1b); 1924 i2c_w1(gspca_dev, 0x18, 0xbc); 1925 i2c_w1(gspca_dev, 0x19, 0x01); 1926 i2c_w1(gspca_dev, 0x1a, 0x82); 1927 i2c_r1(gspca_dev, 0x12, &value); 1928 i2c_w1(gspca_dev, 0x12, value & 0x07); 1929 } else { 1930 i2c_w1(gspca_dev, 0x17, 0x24); 1931 i2c_w1(gspca_dev, 0x18, 0xc5); 1932 i2c_w1(gspca_dev, 0x19, 0x00); 1933 i2c_w1(gspca_dev, 0x1a, 0x3c); 1934 i2c_r1(gspca_dev, 0x12, &value); 1935 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); 1936 } 1937 break; 1938 case SENSOR_MT9M112: 1939 case SENSOR_MT9M111: 1940 if (mode & MODE_SXGA) { 1941 i2c_w2(gspca_dev, 0xf0, 0x0002); 1942 i2c_w2(gspca_dev, 0xc8, 0x970b); 1943 i2c_w2(gspca_dev, 0xf0, 0x0000); 1944 } else { 1945 i2c_w2(gspca_dev, 0xf0, 0x0002); 1946 i2c_w2(gspca_dev, 0xc8, 0x8000); 1947 i2c_w2(gspca_dev, 0xf0, 0x0000); 1948 } 1949 break; 1950 } 1951 } 1952 1953 static int sd_isoc_init(struct gspca_dev *gspca_dev) 1954 { 1955 struct usb_interface *intf; 1956 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv; 1957 1958 /* 1959 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth 1960 * than our regular bandwidth calculations reserve, so we force the 1961 * use of a specific altsetting when using the SN9C20X_I420 fmt. 1962 */ 1963 if (!(flags & (MODE_RAW | MODE_JPEG))) { 1964 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 1965 1966 if (intf->num_altsetting != 9) { 1967 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n", 1968 intf->num_altsetting); 1969 gspca_dev->alt = intf->num_altsetting; 1970 return 0; 1971 } 1972 1973 switch (gspca_dev->pixfmt.width) { 1974 case 160: /* 160x120 */ 1975 gspca_dev->alt = 2; 1976 break; 1977 case 320: /* 320x240 */ 1978 gspca_dev->alt = 6; 1979 break; 1980 default: /* >= 640x480 */ 1981 gspca_dev->alt = 9; 1982 break; 1983 } 1984 } 1985 1986 return 0; 1987 } 1988 1989 #define HW_WIN(mode, hstart, vstart) \ 1990 ((const u8 []){hstart, 0, vstart, 0, \ 1991 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ 1992 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) 1993 1994 #define CLR_WIN(width, height) \ 1995 ((const u8 [])\ 1996 {0, width >> 2, 0, height >> 1,\ 1997 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)}) 1998 1999 static int sd_start(struct gspca_dev *gspca_dev) 2000 { 2001 struct sd *sd = (struct sd *) gspca_dev; 2002 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 2003 int width = gspca_dev->pixfmt.width; 2004 int height = gspca_dev->pixfmt.height; 2005 u8 fmt, scale = 0; 2006 2007 jpeg_define(sd->jpeg_hdr, height, width, 2008 0x21); 2009 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); 2010 2011 if (mode & MODE_RAW) 2012 fmt = 0x2d; 2013 else if (mode & MODE_JPEG) 2014 fmt = 0x24; 2015 else 2016 fmt = 0x2f; /* YUV 420 */ 2017 sd->fmt = fmt; 2018 2019 switch (mode & SCALE_MASK) { 2020 case SCALE_1280x1024: 2021 scale = 0xc0; 2022 pr_info("Set 1280x1024\n"); 2023 break; 2024 case SCALE_640x480: 2025 scale = 0x80; 2026 pr_info("Set 640x480\n"); 2027 break; 2028 case SCALE_320x240: 2029 scale = 0x90; 2030 pr_info("Set 320x240\n"); 2031 break; 2032 case SCALE_160x120: 2033 scale = 0xa0; 2034 pr_info("Set 160x120\n"); 2035 break; 2036 } 2037 2038 configure_sensor_output(gspca_dev, mode); 2039 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 2040 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); 2041 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5); 2042 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6); 2043 reg_w1(gspca_dev, 0x1189, scale); 2044 reg_w1(gspca_dev, 0x10e0, fmt); 2045 2046 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness), 2047 v4l2_ctrl_g_ctrl(sd->contrast), 2048 v4l2_ctrl_g_ctrl(sd->saturation), 2049 v4l2_ctrl_g_ctrl(sd->hue)); 2050 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); 2051 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue), 2052 v4l2_ctrl_g_ctrl(sd->red)); 2053 if (sd->gain) 2054 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); 2055 if (sd->exposure) 2056 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); 2057 if (sd->hflip) 2058 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 2059 v4l2_ctrl_g_ctrl(sd->vflip)); 2060 2061 reg_w1(gspca_dev, 0x1007, 0x20); 2062 reg_w1(gspca_dev, 0x1061, 0x03); 2063 2064 /* if JPEG, prepare the compression quality update */ 2065 if (mode & MODE_JPEG) { 2066 sd->pktsz = sd->npkt = 0; 2067 sd->nchg = 0; 2068 } 2069 if (sd->led_mode) 2070 v4l2_ctrl_s_ctrl(sd->led_mode, 0); 2071 2072 return gspca_dev->usb_err; 2073 } 2074 2075 static void sd_stopN(struct gspca_dev *gspca_dev) 2076 { 2077 reg_w1(gspca_dev, 0x1007, 0x00); 2078 reg_w1(gspca_dev, 0x1061, 0x01); 2079 } 2080 2081 /* called on streamoff with alt==0 and on disconnect */ 2082 /* the usb_lock is held at entry - restore on exit */ 2083 static void sd_stop0(struct gspca_dev *gspca_dev) 2084 { 2085 struct sd *sd = (struct sd *) gspca_dev; 2086 2087 mutex_unlock(&gspca_dev->usb_lock); 2088 flush_work(&sd->work); 2089 mutex_lock(&gspca_dev->usb_lock); 2090 } 2091 2092 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) 2093 { 2094 struct sd *sd = (struct sd *) gspca_dev; 2095 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure); 2096 s32 max = sd->exposure->maximum - sd->exposure_step; 2097 s32 min = sd->exposure->minimum + sd->exposure_step; 2098 s16 new_exp; 2099 2100 /* 2101 * some hardcoded values are present 2102 * like those for maximal/minimal exposure 2103 * and exposure steps 2104 */ 2105 if (avg_lum < MIN_AVG_LUM) { 2106 if (cur_exp > max) 2107 return; 2108 2109 new_exp = cur_exp + sd->exposure_step; 2110 if (new_exp > max) 2111 new_exp = max; 2112 if (new_exp < min) 2113 new_exp = min; 2114 v4l2_ctrl_s_ctrl(sd->exposure, new_exp); 2115 2116 sd->older_step = sd->old_step; 2117 sd->old_step = 1; 2118 2119 if (sd->old_step ^ sd->older_step) 2120 sd->exposure_step /= 2; 2121 else 2122 sd->exposure_step += 2; 2123 } 2124 if (avg_lum > MAX_AVG_LUM) { 2125 if (cur_exp < min) 2126 return; 2127 new_exp = cur_exp - sd->exposure_step; 2128 if (new_exp > max) 2129 new_exp = max; 2130 if (new_exp < min) 2131 new_exp = min; 2132 v4l2_ctrl_s_ctrl(sd->exposure, new_exp); 2133 sd->older_step = sd->old_step; 2134 sd->old_step = 0; 2135 2136 if (sd->old_step ^ sd->older_step) 2137 sd->exposure_step /= 2; 2138 else 2139 sd->exposure_step += 2; 2140 } 2141 } 2142 2143 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) 2144 { 2145 struct sd *sd = (struct sd *) gspca_dev; 2146 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain); 2147 2148 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum) 2149 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1); 2150 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum) 2151 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1); 2152 } 2153 2154 static void sd_dqcallback(struct gspca_dev *gspca_dev) 2155 { 2156 struct sd *sd = (struct sd *) gspca_dev; 2157 int avg_lum; 2158 2159 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) 2160 return; 2161 2162 avg_lum = atomic_read(&sd->avg_lum); 2163 if (sd->sensor == SENSOR_SOI968) 2164 do_autogain(gspca_dev, avg_lum); 2165 else 2166 do_autoexposure(gspca_dev, avg_lum); 2167 } 2168 2169 /* JPEG quality update */ 2170 /* This function is executed from a work queue. */ 2171 static void qual_upd(struct work_struct *work) 2172 { 2173 struct sd *sd = container_of(work, struct sd, work); 2174 struct gspca_dev *gspca_dev = &sd->gspca_dev; 2175 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual); 2176 2177 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */ 2178 mutex_lock(&gspca_dev->usb_lock); 2179 gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual); 2180 gspca_dev->usb_err = 0; 2181 set_quality(gspca_dev, qual); 2182 mutex_unlock(&gspca_dev->usb_lock); 2183 } 2184 2185 #if IS_ENABLED(CONFIG_INPUT) 2186 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 2187 u8 *data, /* interrupt packet */ 2188 int len) /* interrupt packet length */ 2189 { 2190 struct sd *sd = (struct sd *) gspca_dev; 2191 2192 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { 2193 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 2194 input_sync(gspca_dev->input_dev); 2195 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 2196 input_sync(gspca_dev->input_dev); 2197 return 0; 2198 } 2199 return -EINVAL; 2200 } 2201 #endif 2202 2203 /* check the JPEG compression */ 2204 static void transfer_check(struct gspca_dev *gspca_dev, 2205 u8 *data) 2206 { 2207 struct sd *sd = (struct sd *) gspca_dev; 2208 int new_qual, r; 2209 2210 new_qual = 0; 2211 2212 /* if USB error, discard the frame and decrease the quality */ 2213 if (data[6] & 0x08) { /* USB FIFO full */ 2214 gspca_dev->last_packet_type = DISCARD_PACKET; 2215 new_qual = -5; 2216 } else { 2217 2218 /* else, compute the filling rate and a new JPEG quality */ 2219 r = (sd->pktsz * 100) / 2220 (sd->npkt * 2221 gspca_dev->urb[0]->iso_frame_desc[0].length); 2222 if (r >= 85) 2223 new_qual = -3; 2224 else if (r < 75) 2225 new_qual = 2; 2226 } 2227 if (new_qual != 0) { 2228 sd->nchg += new_qual; 2229 if (sd->nchg < -6 || sd->nchg >= 12) { 2230 /* Note: we are in interrupt context, so we can't 2231 use v4l2_ctrl_g/s_ctrl here. Access the value 2232 directly instead. */ 2233 s32 curqual = sd->jpegqual->cur.val; 2234 sd->nchg = 0; 2235 new_qual += curqual; 2236 if (new_qual < sd->jpegqual->minimum) 2237 new_qual = sd->jpegqual->minimum; 2238 else if (new_qual > sd->jpegqual->maximum) 2239 new_qual = sd->jpegqual->maximum; 2240 if (new_qual != curqual) { 2241 sd->jpegqual->cur.val = new_qual; 2242 schedule_work(&sd->work); 2243 } 2244 } 2245 } else { 2246 sd->nchg = 0; 2247 } 2248 sd->pktsz = sd->npkt = 0; 2249 } 2250 2251 static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2252 u8 *data, /* isoc packet */ 2253 int len) /* iso packet length */ 2254 { 2255 struct sd *sd = (struct sd *) gspca_dev; 2256 int avg_lum, is_jpeg; 2257 static const u8 frame_header[] = { 2258 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96 2259 }; 2260 2261 is_jpeg = (sd->fmt & 0x03) == 0; 2262 if (len >= 64 && memcmp(data, frame_header, 6) == 0) { 2263 avg_lum = ((data[35] >> 2) & 3) | 2264 (data[20] << 2) | 2265 (data[19] << 10); 2266 avg_lum += ((data[35] >> 4) & 3) | 2267 (data[22] << 2) | 2268 (data[21] << 10); 2269 avg_lum += ((data[35] >> 6) & 3) | 2270 (data[24] << 2) | 2271 (data[23] << 10); 2272 avg_lum += (data[36] & 3) | 2273 (data[26] << 2) | 2274 (data[25] << 10); 2275 avg_lum += ((data[36] >> 2) & 3) | 2276 (data[28] << 2) | 2277 (data[27] << 10); 2278 avg_lum += ((data[36] >> 4) & 3) | 2279 (data[30] << 2) | 2280 (data[29] << 10); 2281 avg_lum += ((data[36] >> 6) & 3) | 2282 (data[32] << 2) | 2283 (data[31] << 10); 2284 avg_lum += ((data[44] >> 4) & 3) | 2285 (data[34] << 2) | 2286 (data[33] << 10); 2287 avg_lum >>= 9; 2288 atomic_set(&sd->avg_lum, avg_lum); 2289 2290 if (is_jpeg) 2291 transfer_check(gspca_dev, data); 2292 2293 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2294 len -= 64; 2295 if (len == 0) 2296 return; 2297 data += 64; 2298 } 2299 if (gspca_dev->last_packet_type == LAST_PACKET) { 2300 if (is_jpeg) { 2301 gspca_frame_add(gspca_dev, FIRST_PACKET, 2302 sd->jpeg_hdr, JPEG_HDR_SZ); 2303 gspca_frame_add(gspca_dev, INTER_PACKET, 2304 data, len); 2305 } else { 2306 gspca_frame_add(gspca_dev, FIRST_PACKET, 2307 data, len); 2308 } 2309 } else { 2310 /* if JPEG, count the packets and their size */ 2311 if (is_jpeg) { 2312 sd->npkt++; 2313 sd->pktsz += len; 2314 } 2315 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2316 } 2317 } 2318 2319 /* sub-driver description */ 2320 static const struct sd_desc sd_desc = { 2321 .name = KBUILD_MODNAME, 2322 .config = sd_config, 2323 .init = sd_init, 2324 .init_controls = sd_init_controls, 2325 .isoc_init = sd_isoc_init, 2326 .start = sd_start, 2327 .stopN = sd_stopN, 2328 .stop0 = sd_stop0, 2329 .pkt_scan = sd_pkt_scan, 2330 #if IS_ENABLED(CONFIG_INPUT) 2331 .int_pkt_scan = sd_int_pkt_scan, 2332 #endif 2333 .dq_callback = sd_dqcallback, 2334 #ifdef CONFIG_VIDEO_ADV_DEBUG 2335 .set_register = sd_dbg_s_register, 2336 .get_register = sd_dbg_g_register, 2337 .get_chip_info = sd_chip_info, 2338 #endif 2339 }; 2340 2341 #define SN9C20X(sensor, i2c_addr, flags) \ 2342 .driver_info = ((flags & 0xff) << 16) \ 2343 | (SENSOR_ ## sensor << 8) \ 2344 | (i2c_addr) 2345 2346 static const struct usb_device_id device_table[] = { 2347 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, 2348 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)}, 2349 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2350 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)}, 2351 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)}, 2352 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 2353 (FLIP_DETECT | HAS_NO_BUTTON))}, 2354 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2355 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2356 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2357 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, 2358 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)}, 2359 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, 2360 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2361 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2362 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, 2363 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, 2364 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)}, 2365 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, 2366 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, 2367 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2368 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2369 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)}, 2370 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)}, 2371 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2372 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2373 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2374 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, 2375 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)}, 2376 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)}, 2377 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)}, 2378 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, 2379 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, 2380 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, 2381 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, 2382 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, 2383 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, 2384 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, 2385 {} 2386 }; 2387 MODULE_DEVICE_TABLE(usb, device_table); 2388 2389 /* -- device connect -- */ 2390 static int sd_probe(struct usb_interface *intf, 2391 const struct usb_device_id *id) 2392 { 2393 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2394 THIS_MODULE); 2395 } 2396 2397 static struct usb_driver sd_driver = { 2398 .name = KBUILD_MODNAME, 2399 .id_table = device_table, 2400 .probe = sd_probe, 2401 .disconnect = gspca_disconnect, 2402 #ifdef CONFIG_PM 2403 .suspend = gspca_suspend, 2404 .resume = gspca_resume, 2405 .reset_resume = gspca_resume, 2406 #endif 2407 }; 2408 2409 module_usb_driver(sd_driver); 2410