1 /* 2 * Sonix sn9c201 sn9c202 library 3 * 4 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr> 5 * Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com> 6 * Copyright (C) 2009 Brian Johnson <brijohn@gmail.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 24 25 #include <linux/input.h> 26 27 #include "gspca.h" 28 #include "jpeg.h" 29 30 #include <linux/dmi.h> 31 32 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, " 33 "microdia project <microdia@googlegroups.com>"); 34 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver"); 35 MODULE_LICENSE("GPL"); 36 37 /* 38 * Pixel format private data 39 */ 40 #define SCALE_MASK 0x0f 41 #define SCALE_160x120 0 42 #define SCALE_320x240 1 43 #define SCALE_640x480 2 44 #define SCALE_1280x1024 3 45 #define MODE_RAW 0x10 46 #define MODE_JPEG 0x20 47 #define MODE_SXGA 0x80 48 49 #define SENSOR_OV9650 0 50 #define SENSOR_OV9655 1 51 #define SENSOR_SOI968 2 52 #define SENSOR_OV7660 3 53 #define SENSOR_OV7670 4 54 #define SENSOR_MT9V011 5 55 #define SENSOR_MT9V111 6 56 #define SENSOR_MT9V112 7 57 #define SENSOR_MT9M001 8 58 #define SENSOR_MT9M111 9 59 #define SENSOR_MT9M112 10 60 #define SENSOR_HV7131R 11 61 #define SENSOR_MT9VPRB 12 62 63 /* camera flags */ 64 #define HAS_NO_BUTTON 0x1 65 #define LED_REVERSE 0x2 /* some cameras unset gpio to turn on leds */ 66 #define FLIP_DETECT 0x4 67 68 /* specific webcam descriptor */ 69 struct sd { 70 struct gspca_dev gspca_dev; 71 72 struct { /* color control cluster */ 73 struct v4l2_ctrl *brightness; 74 struct v4l2_ctrl *contrast; 75 struct v4l2_ctrl *saturation; 76 struct v4l2_ctrl *hue; 77 }; 78 struct { /* blue/red balance control cluster */ 79 struct v4l2_ctrl *blue; 80 struct v4l2_ctrl *red; 81 }; 82 struct { /* h/vflip control cluster */ 83 struct v4l2_ctrl *hflip; 84 struct v4l2_ctrl *vflip; 85 }; 86 struct v4l2_ctrl *gamma; 87 struct { /* autogain and exposure or gain control cluster */ 88 struct v4l2_ctrl *autogain; 89 struct v4l2_ctrl *exposure; 90 struct v4l2_ctrl *gain; 91 }; 92 struct v4l2_ctrl *jpegqual; 93 94 struct work_struct work; 95 struct workqueue_struct *work_thread; 96 97 u32 pktsz; /* (used by pkt_scan) */ 98 u16 npkt; 99 s8 nchg; 100 u8 fmt; /* (used for JPEG QTAB update */ 101 102 #define MIN_AVG_LUM 80 103 #define MAX_AVG_LUM 130 104 atomic_t avg_lum; 105 u8 old_step; 106 u8 older_step; 107 u8 exposure_step; 108 109 u8 i2c_addr; 110 u8 i2c_intf; 111 u8 sensor; 112 u8 hstart; 113 u8 vstart; 114 115 u8 jpeg_hdr[JPEG_HDR_SZ]; 116 117 u8 flags; 118 }; 119 120 static void qual_upd(struct work_struct *work); 121 122 struct i2c_reg_u8 { 123 u8 reg; 124 u8 val; 125 }; 126 127 struct i2c_reg_u16 { 128 u8 reg; 129 u16 val; 130 }; 131 132 static const struct dmi_system_id flip_dmi_table[] = { 133 { 134 .ident = "MSI MS-1034", 135 .matches = { 136 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."), 137 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"), 138 DMI_MATCH(DMI_PRODUCT_VERSION, "0341") 139 } 140 }, 141 { 142 .ident = "MSI MS-1632", 143 .matches = { 144 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 145 DMI_MATCH(DMI_BOARD_NAME, "MS-1632") 146 } 147 }, 148 { 149 .ident = "MSI MS-1633X", 150 .matches = { 151 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 152 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X") 153 } 154 }, 155 { 156 .ident = "MSI MS-1635X", 157 .matches = { 158 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 159 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X") 160 } 161 }, 162 { 163 .ident = "ASUSTeK W7J", 164 .matches = { 165 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), 166 DMI_MATCH(DMI_BOARD_NAME, "W7J ") 167 } 168 }, 169 {} 170 }; 171 172 static const struct v4l2_pix_format vga_mode[] = { 173 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 174 .bytesperline = 160, 175 .sizeimage = 160 * 120 * 4 / 8 + 590, 176 .colorspace = V4L2_COLORSPACE_JPEG, 177 .priv = SCALE_160x120 | MODE_JPEG}, 178 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 179 .bytesperline = 160, 180 .sizeimage = 160 * 120, 181 .colorspace = V4L2_COLORSPACE_SRGB, 182 .priv = SCALE_160x120 | MODE_RAW}, 183 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 184 .bytesperline = 160, 185 .sizeimage = 240 * 120, 186 .colorspace = V4L2_COLORSPACE_SRGB, 187 .priv = SCALE_160x120}, 188 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 189 .bytesperline = 320, 190 .sizeimage = 320 * 240 * 4 / 8 + 590, 191 .colorspace = V4L2_COLORSPACE_JPEG, 192 .priv = SCALE_320x240 | MODE_JPEG}, 193 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 194 .bytesperline = 320, 195 .sizeimage = 320 * 240 , 196 .colorspace = V4L2_COLORSPACE_SRGB, 197 .priv = SCALE_320x240 | MODE_RAW}, 198 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 199 .bytesperline = 320, 200 .sizeimage = 480 * 240 , 201 .colorspace = V4L2_COLORSPACE_SRGB, 202 .priv = SCALE_320x240}, 203 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 204 .bytesperline = 640, 205 .sizeimage = 640 * 480 * 4 / 8 + 590, 206 .colorspace = V4L2_COLORSPACE_JPEG, 207 .priv = SCALE_640x480 | MODE_JPEG}, 208 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 209 .bytesperline = 640, 210 .sizeimage = 640 * 480, 211 .colorspace = V4L2_COLORSPACE_SRGB, 212 .priv = SCALE_640x480 | MODE_RAW}, 213 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 214 .bytesperline = 640, 215 .sizeimage = 960 * 480, 216 .colorspace = V4L2_COLORSPACE_SRGB, 217 .priv = SCALE_640x480}, 218 }; 219 220 static const struct v4l2_pix_format sxga_mode[] = { 221 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 222 .bytesperline = 160, 223 .sizeimage = 160 * 120 * 4 / 8 + 590, 224 .colorspace = V4L2_COLORSPACE_JPEG, 225 .priv = SCALE_160x120 | MODE_JPEG}, 226 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 227 .bytesperline = 160, 228 .sizeimage = 160 * 120, 229 .colorspace = V4L2_COLORSPACE_SRGB, 230 .priv = SCALE_160x120 | MODE_RAW}, 231 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 232 .bytesperline = 160, 233 .sizeimage = 240 * 120, 234 .colorspace = V4L2_COLORSPACE_SRGB, 235 .priv = SCALE_160x120}, 236 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 237 .bytesperline = 320, 238 .sizeimage = 320 * 240 * 4 / 8 + 590, 239 .colorspace = V4L2_COLORSPACE_JPEG, 240 .priv = SCALE_320x240 | MODE_JPEG}, 241 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 242 .bytesperline = 320, 243 .sizeimage = 320 * 240 , 244 .colorspace = V4L2_COLORSPACE_SRGB, 245 .priv = SCALE_320x240 | MODE_RAW}, 246 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 247 .bytesperline = 320, 248 .sizeimage = 480 * 240 , 249 .colorspace = V4L2_COLORSPACE_SRGB, 250 .priv = SCALE_320x240}, 251 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 252 .bytesperline = 640, 253 .sizeimage = 640 * 480 * 4 / 8 + 590, 254 .colorspace = V4L2_COLORSPACE_JPEG, 255 .priv = SCALE_640x480 | MODE_JPEG}, 256 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 257 .bytesperline = 640, 258 .sizeimage = 640 * 480, 259 .colorspace = V4L2_COLORSPACE_SRGB, 260 .priv = SCALE_640x480 | MODE_RAW}, 261 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE, 262 .bytesperline = 640, 263 .sizeimage = 960 * 480, 264 .colorspace = V4L2_COLORSPACE_SRGB, 265 .priv = SCALE_640x480}, 266 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 267 .bytesperline = 1280, 268 .sizeimage = 1280 * 1024, 269 .colorspace = V4L2_COLORSPACE_SRGB, 270 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, 271 }; 272 273 static const struct v4l2_pix_format mono_mode[] = { 274 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 275 .bytesperline = 160, 276 .sizeimage = 160 * 120, 277 .colorspace = V4L2_COLORSPACE_SRGB, 278 .priv = SCALE_160x120 | MODE_RAW}, 279 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 280 .bytesperline = 320, 281 .sizeimage = 320 * 240 , 282 .colorspace = V4L2_COLORSPACE_SRGB, 283 .priv = SCALE_320x240 | MODE_RAW}, 284 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 285 .bytesperline = 640, 286 .sizeimage = 640 * 480, 287 .colorspace = V4L2_COLORSPACE_SRGB, 288 .priv = SCALE_640x480 | MODE_RAW}, 289 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE, 290 .bytesperline = 1280, 291 .sizeimage = 1280 * 1024, 292 .colorspace = V4L2_COLORSPACE_SRGB, 293 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA}, 294 }; 295 296 static const s16 hsv_red_x[] = { 297 41, 44, 46, 48, 50, 52, 54, 56, 298 58, 60, 62, 64, 66, 68, 70, 72, 299 74, 76, 78, 80, 81, 83, 85, 87, 300 88, 90, 92, 93, 95, 97, 98, 100, 301 101, 102, 104, 105, 107, 108, 109, 110, 302 112, 113, 114, 115, 116, 117, 118, 119, 303 120, 121, 122, 123, 123, 124, 125, 125, 304 126, 127, 127, 128, 128, 129, 129, 129, 305 130, 130, 130, 130, 131, 131, 131, 131, 306 131, 131, 131, 131, 130, 130, 130, 130, 307 129, 129, 129, 128, 128, 127, 127, 126, 308 125, 125, 124, 123, 122, 122, 121, 120, 309 119, 118, 117, 116, 115, 114, 112, 111, 310 110, 109, 107, 106, 105, 103, 102, 101, 311 99, 98, 96, 94, 93, 91, 90, 88, 312 86, 84, 83, 81, 79, 77, 75, 74, 313 72, 70, 68, 66, 64, 62, 60, 58, 314 56, 54, 52, 49, 47, 45, 43, 41, 315 39, 36, 34, 32, 30, 28, 25, 23, 316 21, 19, 16, 14, 12, 9, 7, 5, 317 3, 0, -1, -3, -6, -8, -10, -12, 318 -15, -17, -19, -22, -24, -26, -28, -30, 319 -33, -35, -37, -39, -41, -44, -46, -48, 320 -50, -52, -54, -56, -58, -60, -62, -64, 321 -66, -68, -70, -72, -74, -76, -78, -80, 322 -81, -83, -85, -87, -88, -90, -92, -93, 323 -95, -97, -98, -100, -101, -102, -104, -105, 324 -107, -108, -109, -110, -112, -113, -114, -115, 325 -116, -117, -118, -119, -120, -121, -122, -123, 326 -123, -124, -125, -125, -126, -127, -127, -128, 327 -128, -128, -128, -128, -128, -128, -128, -128, 328 -128, -128, -128, -128, -128, -128, -128, -128, 329 -128, -128, -128, -128, -128, -128, -128, -128, 330 -128, -127, -127, -126, -125, -125, -124, -123, 331 -122, -122, -121, -120, -119, -118, -117, -116, 332 -115, -114, -112, -111, -110, -109, -107, -106, 333 -105, -103, -102, -101, -99, -98, -96, -94, 334 -93, -91, -90, -88, -86, -84, -83, -81, 335 -79, -77, -75, -74, -72, -70, -68, -66, 336 -64, -62, -60, -58, -56, -54, -52, -49, 337 -47, -45, -43, -41, -39, -36, -34, -32, 338 -30, -28, -25, -23, -21, -19, -16, -14, 339 -12, -9, -7, -5, -3, 0, 1, 3, 340 6, 8, 10, 12, 15, 17, 19, 22, 341 24, 26, 28, 30, 33, 35, 37, 39, 41 342 }; 343 344 static const s16 hsv_red_y[] = { 345 82, 80, 78, 76, 74, 73, 71, 69, 346 67, 65, 63, 61, 58, 56, 54, 52, 347 50, 48, 46, 44, 41, 39, 37, 35, 348 32, 30, 28, 26, 23, 21, 19, 16, 349 14, 12, 10, 7, 5, 3, 0, -1, 350 -3, -6, -8, -10, -13, -15, -17, -19, 351 -22, -24, -26, -29, -31, -33, -35, -38, 352 -40, -42, -44, -46, -48, -51, -53, -55, 353 -57, -59, -61, -63, -65, -67, -69, -71, 354 -73, -75, -77, -79, -81, -82, -84, -86, 355 -88, -89, -91, -93, -94, -96, -98, -99, 356 -101, -102, -104, -105, -106, -108, -109, -110, 357 -112, -113, -114, -115, -116, -117, -119, -120, 358 -120, -121, -122, -123, -124, -125, -126, -126, 359 -127, -128, -128, -128, -128, -128, -128, -128, 360 -128, -128, -128, -128, -128, -128, -128, -128, 361 -128, -128, -128, -128, -128, -128, -128, -128, 362 -128, -128, -128, -128, -128, -128, -128, -128, 363 -127, -127, -126, -125, -125, -124, -123, -122, 364 -121, -120, -119, -118, -117, -116, -115, -114, 365 -113, -111, -110, -109, -107, -106, -105, -103, 366 -102, -100, -99, -97, -96, -94, -92, -91, 367 -89, -87, -85, -84, -82, -80, -78, -76, 368 -74, -73, -71, -69, -67, -65, -63, -61, 369 -58, -56, -54, -52, -50, -48, -46, -44, 370 -41, -39, -37, -35, -32, -30, -28, -26, 371 -23, -21, -19, -16, -14, -12, -10, -7, 372 -5, -3, 0, 1, 3, 6, 8, 10, 373 13, 15, 17, 19, 22, 24, 26, 29, 374 31, 33, 35, 38, 40, 42, 44, 46, 375 48, 51, 53, 55, 57, 59, 61, 63, 376 65, 67, 69, 71, 73, 75, 77, 79, 377 81, 82, 84, 86, 88, 89, 91, 93, 378 94, 96, 98, 99, 101, 102, 104, 105, 379 106, 108, 109, 110, 112, 113, 114, 115, 380 116, 117, 119, 120, 120, 121, 122, 123, 381 124, 125, 126, 126, 127, 128, 128, 129, 382 129, 130, 130, 131, 131, 131, 131, 132, 383 132, 132, 132, 132, 132, 132, 132, 132, 384 132, 132, 132, 131, 131, 131, 130, 130, 385 130, 129, 129, 128, 127, 127, 126, 125, 386 125, 124, 123, 122, 121, 120, 119, 118, 387 117, 116, 115, 114, 113, 111, 110, 109, 388 107, 106, 105, 103, 102, 100, 99, 97, 389 96, 94, 92, 91, 89, 87, 85, 84, 82 390 }; 391 392 static const s16 hsv_green_x[] = { 393 -124, -124, -125, -125, -125, -125, -125, -125, 394 -125, -126, -126, -125, -125, -125, -125, -125, 395 -125, -124, -124, -124, -123, -123, -122, -122, 396 -121, -121, -120, -120, -119, -118, -117, -117, 397 -116, -115, -114, -113, -112, -111, -110, -109, 398 -108, -107, -105, -104, -103, -102, -100, -99, 399 -98, -96, -95, -93, -92, -91, -89, -87, 400 -86, -84, -83, -81, -79, -77, -76, -74, 401 -72, -70, -69, -67, -65, -63, -61, -59, 402 -57, -55, -53, -51, -49, -47, -45, -43, 403 -41, -39, -37, -35, -33, -30, -28, -26, 404 -24, -22, -20, -18, -15, -13, -11, -9, 405 -7, -4, -2, 0, 1, 3, 6, 8, 406 10, 12, 14, 17, 19, 21, 23, 25, 407 27, 29, 32, 34, 36, 38, 40, 42, 408 44, 46, 48, 50, 52, 54, 56, 58, 409 60, 62, 64, 66, 68, 70, 71, 73, 410 75, 77, 78, 80, 82, 83, 85, 87, 411 88, 90, 91, 93, 94, 96, 97, 98, 412 100, 101, 102, 104, 105, 106, 107, 108, 413 109, 111, 112, 113, 113, 114, 115, 116, 414 117, 118, 118, 119, 120, 120, 121, 122, 415 122, 123, 123, 124, 124, 124, 125, 125, 416 125, 125, 125, 125, 125, 126, 126, 125, 417 125, 125, 125, 125, 125, 124, 124, 124, 418 123, 123, 122, 122, 121, 121, 120, 120, 419 119, 118, 117, 117, 116, 115, 114, 113, 420 112, 111, 110, 109, 108, 107, 105, 104, 421 103, 102, 100, 99, 98, 96, 95, 93, 422 92, 91, 89, 87, 86, 84, 83, 81, 423 79, 77, 76, 74, 72, 70, 69, 67, 424 65, 63, 61, 59, 57, 55, 53, 51, 425 49, 47, 45, 43, 41, 39, 37, 35, 426 33, 30, 28, 26, 24, 22, 20, 18, 427 15, 13, 11, 9, 7, 4, 2, 0, 428 -1, -3, -6, -8, -10, -12, -14, -17, 429 -19, -21, -23, -25, -27, -29, -32, -34, 430 -36, -38, -40, -42, -44, -46, -48, -50, 431 -52, -54, -56, -58, -60, -62, -64, -66, 432 -68, -70, -71, -73, -75, -77, -78, -80, 433 -82, -83, -85, -87, -88, -90, -91, -93, 434 -94, -96, -97, -98, -100, -101, -102, -104, 435 -105, -106, -107, -108, -109, -111, -112, -113, 436 -113, -114, -115, -116, -117, -118, -118, -119, 437 -120, -120, -121, -122, -122, -123, -123, -124, -124 438 }; 439 440 static const s16 hsv_green_y[] = { 441 -100, -99, -98, -97, -95, -94, -93, -91, 442 -90, -89, -87, -86, -84, -83, -81, -80, 443 -78, -76, -75, -73, -71, -70, -68, -66, 444 -64, -63, -61, -59, -57, -55, -53, -51, 445 -49, -48, -46, -44, -42, -40, -38, -36, 446 -34, -32, -30, -27, -25, -23, -21, -19, 447 -17, -15, -13, -11, -9, -7, -4, -2, 448 0, 1, 3, 5, 7, 9, 11, 14, 449 16, 18, 20, 22, 24, 26, 28, 30, 450 32, 34, 36, 38, 40, 42, 44, 46, 451 48, 50, 52, 54, 56, 58, 59, 61, 452 63, 65, 67, 68, 70, 72, 74, 75, 453 77, 78, 80, 82, 83, 85, 86, 88, 454 89, 90, 92, 93, 95, 96, 97, 98, 455 100, 101, 102, 103, 104, 105, 106, 107, 456 108, 109, 110, 111, 112, 112, 113, 114, 457 115, 115, 116, 116, 117, 117, 118, 118, 458 119, 119, 119, 120, 120, 120, 120, 120, 459 121, 121, 121, 121, 121, 121, 120, 120, 460 120, 120, 120, 119, 119, 119, 118, 118, 461 117, 117, 116, 116, 115, 114, 114, 113, 462 112, 111, 111, 110, 109, 108, 107, 106, 463 105, 104, 103, 102, 100, 99, 98, 97, 464 95, 94, 93, 91, 90, 89, 87, 86, 465 84, 83, 81, 80, 78, 76, 75, 73, 466 71, 70, 68, 66, 64, 63, 61, 59, 467 57, 55, 53, 51, 49, 48, 46, 44, 468 42, 40, 38, 36, 34, 32, 30, 27, 469 25, 23, 21, 19, 17, 15, 13, 11, 470 9, 7, 4, 2, 0, -1, -3, -5, 471 -7, -9, -11, -14, -16, -18, -20, -22, 472 -24, -26, -28, -30, -32, -34, -36, -38, 473 -40, -42, -44, -46, -48, -50, -52, -54, 474 -56, -58, -59, -61, -63, -65, -67, -68, 475 -70, -72, -74, -75, -77, -78, -80, -82, 476 -83, -85, -86, -88, -89, -90, -92, -93, 477 -95, -96, -97, -98, -100, -101, -102, -103, 478 -104, -105, -106, -107, -108, -109, -110, -111, 479 -112, -112, -113, -114, -115, -115, -116, -116, 480 -117, -117, -118, -118, -119, -119, -119, -120, 481 -120, -120, -120, -120, -121, -121, -121, -121, 482 -121, -121, -120, -120, -120, -120, -120, -119, 483 -119, -119, -118, -118, -117, -117, -116, -116, 484 -115, -114, -114, -113, -112, -111, -111, -110, 485 -109, -108, -107, -106, -105, -104, -103, -102, -100 486 }; 487 488 static const s16 hsv_blue_x[] = { 489 112, 113, 114, 114, 115, 116, 117, 117, 490 118, 118, 119, 119, 120, 120, 120, 121, 491 121, 121, 122, 122, 122, 122, 122, 122, 492 122, 122, 122, 122, 122, 122, 121, 121, 493 121, 120, 120, 120, 119, 119, 118, 118, 494 117, 116, 116, 115, 114, 113, 113, 112, 495 111, 110, 109, 108, 107, 106, 105, 104, 496 103, 102, 100, 99, 98, 97, 95, 94, 497 93, 91, 90, 88, 87, 85, 84, 82, 498 80, 79, 77, 76, 74, 72, 70, 69, 499 67, 65, 63, 61, 60, 58, 56, 54, 500 52, 50, 48, 46, 44, 42, 40, 38, 501 36, 34, 32, 30, 28, 26, 24, 22, 502 19, 17, 15, 13, 11, 9, 7, 5, 503 2, 0, -1, -3, -5, -7, -9, -12, 504 -14, -16, -18, -20, -22, -24, -26, -28, 505 -31, -33, -35, -37, -39, -41, -43, -45, 506 -47, -49, -51, -53, -54, -56, -58, -60, 507 -62, -64, -66, -67, -69, -71, -73, -74, 508 -76, -78, -79, -81, -83, -84, -86, -87, 509 -89, -90, -92, -93, -94, -96, -97, -98, 510 -99, -101, -102, -103, -104, -105, -106, -107, 511 -108, -109, -110, -111, -112, -113, -114, -114, 512 -115, -116, -117, -117, -118, -118, -119, -119, 513 -120, -120, -120, -121, -121, -121, -122, -122, 514 -122, -122, -122, -122, -122, -122, -122, -122, 515 -122, -122, -121, -121, -121, -120, -120, -120, 516 -119, -119, -118, -118, -117, -116, -116, -115, 517 -114, -113, -113, -112, -111, -110, -109, -108, 518 -107, -106, -105, -104, -103, -102, -100, -99, 519 -98, -97, -95, -94, -93, -91, -90, -88, 520 -87, -85, -84, -82, -80, -79, -77, -76, 521 -74, -72, -70, -69, -67, -65, -63, -61, 522 -60, -58, -56, -54, -52, -50, -48, -46, 523 -44, -42, -40, -38, -36, -34, -32, -30, 524 -28, -26, -24, -22, -19, -17, -15, -13, 525 -11, -9, -7, -5, -2, 0, 1, 3, 526 5, 7, 9, 12, 14, 16, 18, 20, 527 22, 24, 26, 28, 31, 33, 35, 37, 528 39, 41, 43, 45, 47, 49, 51, 53, 529 54, 56, 58, 60, 62, 64, 66, 67, 530 69, 71, 73, 74, 76, 78, 79, 81, 531 83, 84, 86, 87, 89, 90, 92, 93, 532 94, 96, 97, 98, 99, 101, 102, 103, 533 104, 105, 106, 107, 108, 109, 110, 111, 112 534 }; 535 536 static const s16 hsv_blue_y[] = { 537 -11, -13, -15, -17, -19, -21, -23, -25, 538 -27, -29, -31, -33, -35, -37, -39, -41, 539 -43, -45, -46, -48, -50, -52, -54, -55, 540 -57, -59, -61, -62, -64, -66, -67, -69, 541 -71, -72, -74, -75, -77, -78, -80, -81, 542 -83, -84, -86, -87, -88, -90, -91, -92, 543 -93, -95, -96, -97, -98, -99, -100, -101, 544 -102, -103, -104, -105, -106, -106, -107, -108, 545 -109, -109, -110, -111, -111, -112, -112, -113, 546 -113, -114, -114, -114, -115, -115, -115, -115, 547 -116, -116, -116, -116, -116, -116, -116, -116, 548 -116, -115, -115, -115, -115, -114, -114, -114, 549 -113, -113, -112, -112, -111, -111, -110, -110, 550 -109, -108, -108, -107, -106, -105, -104, -103, 551 -102, -101, -100, -99, -98, -97, -96, -95, 552 -94, -93, -91, -90, -89, -88, -86, -85, 553 -84, -82, -81, -79, -78, -76, -75, -73, 554 -71, -70, -68, -67, -65, -63, -62, -60, 555 -58, -56, -55, -53, -51, -49, -47, -45, 556 -44, -42, -40, -38, -36, -34, -32, -30, 557 -28, -26, -24, -22, -20, -18, -16, -14, 558 -12, -10, -8, -6, -4, -2, 0, 1, 559 3, 5, 7, 9, 11, 13, 15, 17, 560 19, 21, 23, 25, 27, 29, 31, 33, 561 35, 37, 39, 41, 43, 45, 46, 48, 562 50, 52, 54, 55, 57, 59, 61, 62, 563 64, 66, 67, 69, 71, 72, 74, 75, 564 77, 78, 80, 81, 83, 84, 86, 87, 565 88, 90, 91, 92, 93, 95, 96, 97, 566 98, 99, 100, 101, 102, 103, 104, 105, 567 106, 106, 107, 108, 109, 109, 110, 111, 568 111, 112, 112, 113, 113, 114, 114, 114, 569 115, 115, 115, 115, 116, 116, 116, 116, 570 116, 116, 116, 116, 116, 115, 115, 115, 571 115, 114, 114, 114, 113, 113, 112, 112, 572 111, 111, 110, 110, 109, 108, 108, 107, 573 106, 105, 104, 103, 102, 101, 100, 99, 574 98, 97, 96, 95, 94, 93, 91, 90, 575 89, 88, 86, 85, 84, 82, 81, 79, 576 78, 76, 75, 73, 71, 70, 68, 67, 577 65, 63, 62, 60, 58, 56, 55, 53, 578 51, 49, 47, 45, 44, 42, 40, 38, 579 36, 34, 32, 30, 28, 26, 24, 22, 580 20, 18, 16, 14, 12, 10, 8, 6, 581 4, 2, 0, -1, -3, -5, -7, -9, -11 582 }; 583 584 static const u16 bridge_init[][2] = { 585 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c}, 586 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40}, 587 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10}, 588 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00}, 589 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50}, 590 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50}, 591 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04}, 592 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05}, 593 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00}, 594 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d}, 595 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04}, 596 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8}, 597 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32}, 598 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd}, 599 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01}, 600 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f}, 601 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f}, 602 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01}, 603 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80}, 604 {0x1007, 0x00} 605 }; 606 607 /* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */ 608 static const u8 ov_gain[] = { 609 0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */, 610 0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */, 611 0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */, 612 0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */, 613 0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */, 614 0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */, 615 0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */, 616 0x70 /* 8x */ 617 }; 618 619 /* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */ 620 static const u16 micron1_gain[] = { 621 /* 1x 1.25x 1.5x 1.75x */ 622 0x0020, 0x0028, 0x0030, 0x0038, 623 /* 2x 2.25x 2.5x 2.75x */ 624 0x00a0, 0x00a4, 0x00a8, 0x00ac, 625 /* 3x 3.25x 3.5x 3.75x */ 626 0x00b0, 0x00b4, 0x00b8, 0x00bc, 627 /* 4x 4.25x 4.5x 4.75x */ 628 0x00c0, 0x00c4, 0x00c8, 0x00cc, 629 /* 5x 5.25x 5.5x 5.75x */ 630 0x00d0, 0x00d4, 0x00d8, 0x00dc, 631 /* 6x 6.25x 6.5x 6.75x */ 632 0x00e0, 0x00e4, 0x00e8, 0x00ec, 633 /* 7x 7.25x 7.5x 7.75x */ 634 0x00f0, 0x00f4, 0x00f8, 0x00fc, 635 /* 8x */ 636 0x01c0 637 }; 638 639 /* mt9m001 sensor uses a different gain formula then other micron sensors */ 640 /* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */ 641 static const u16 micron2_gain[] = { 642 /* 1x 1.25x 1.5x 1.75x */ 643 0x0008, 0x000a, 0x000c, 0x000e, 644 /* 2x 2.25x 2.5x 2.75x */ 645 0x0010, 0x0012, 0x0014, 0x0016, 646 /* 3x 3.25x 3.5x 3.75x */ 647 0x0018, 0x001a, 0x001c, 0x001e, 648 /* 4x 4.25x 4.5x 4.75x */ 649 0x0020, 0x0051, 0x0052, 0x0053, 650 /* 5x 5.25x 5.5x 5.75x */ 651 0x0054, 0x0055, 0x0056, 0x0057, 652 /* 6x 6.25x 6.5x 6.75x */ 653 0x0058, 0x0059, 0x005a, 0x005b, 654 /* 7x 7.25x 7.5x 7.75x */ 655 0x005c, 0x005d, 0x005e, 0x005f, 656 /* 8x */ 657 0x0060 658 }; 659 660 /* Gain = .5 + bit[7:0] / 16 */ 661 static const u8 hv7131r_gain[] = { 662 0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */, 663 0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */, 664 0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */, 665 0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */, 666 0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */, 667 0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */, 668 0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */, 669 0x78 /* 8x */ 670 }; 671 672 static const struct i2c_reg_u8 soi968_init[] = { 673 {0x0c, 0x00}, {0x0f, 0x1f}, 674 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00}, 675 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c}, 676 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff}, 677 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20}, 678 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e}, 679 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13}, 680 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79}, 681 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40}, 682 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32}, 683 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80}, 684 }; 685 686 static const struct i2c_reg_u8 ov7660_init[] = { 687 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 688 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 689 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 690 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using 691 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */ 692 {0x17, 0x10}, {0x18, 0x61}, 693 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 694 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00}, 695 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50}, 696 }; 697 698 static const struct i2c_reg_u8 ov7670_init[] = { 699 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01}, 700 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00}, 701 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0}, 702 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00}, 703 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07}, 704 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75}, 705 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8}, 706 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5}, 707 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27}, 708 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b}, 709 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a}, 710 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00}, 711 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00}, 712 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80}, 713 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82}, 714 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20}, 715 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c}, 716 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66}, 717 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11}, 718 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40}, 719 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02}, 720 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a}, 721 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08}, 722 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04}, 723 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30}, 724 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88}, 725 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30}, 726 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99}, 727 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0}, 728 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e}, 729 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01}, 730 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20}, 731 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0}, 732 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30}, 733 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06}, 734 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a}, 735 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a}, 736 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84}, 737 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d}, 738 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d}, 739 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00}, 740 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, 741 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60}, 742 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, 743 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e}, 744 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56}, 745 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03}, 746 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47}, 747 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74}, 748 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2}, 749 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00}, 750 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a}, 751 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00}, 752 {0x93, 0x00}, 753 }; 754 755 static const struct i2c_reg_u8 ov9650_init[] = { 756 {0x00, 0x00}, {0x01, 0x78}, 757 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03}, 758 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00}, 759 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00}, 760 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c}, 761 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2}, 762 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07}, 763 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00}, 764 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04}, 765 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68}, 766 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80}, 767 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00}, 768 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00}, 769 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30}, 770 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf}, 771 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00}, 772 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01}, 773 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19}, 774 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1}, 775 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80}, 776 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00}, 777 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20}, 778 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf}, 779 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88}, 780 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00}, 781 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8}, 782 {0xaa, 0x92}, {0xab, 0x0a}, 783 }; 784 785 static const struct i2c_reg_u8 ov9655_init[] = { 786 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba}, 787 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08}, 788 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d}, 789 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57}, 790 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19}, 791 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80}, 792 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c}, 793 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc}, 794 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05}, 795 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e}, 796 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68}, 797 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92}, 798 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80}, 799 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00}, 800 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44}, 801 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01}, 802 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0}, 803 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00}, 804 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61}, 805 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a}, 806 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01}, 807 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a}, 808 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c}, 809 {0x04, 0x03}, {0x00, 0x13}, 810 }; 811 812 static const struct i2c_reg_u16 mt9v112_init[] = { 813 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020}, 814 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b}, 815 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001}, 816 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a}, 817 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58}, 818 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001}, 819 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020}, 820 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020}, 821 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020}, 822 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 823 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2}, 824 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 825 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020}, 826 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c}, 827 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae}, 828 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae}, 829 }; 830 831 static const struct i2c_reg_u16 mt9v111_init[] = { 832 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000}, 833 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0}, 834 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e}, 835 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016}, 836 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004}, 837 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008}, 838 {0x0e, 0x0008}, {0x20, 0x0000} 839 }; 840 841 static const struct i2c_reg_u16 mt9v011_init[] = { 842 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000}, 843 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1}, 844 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006}, 845 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000}, 846 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000}, 847 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000}, 848 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000}, 849 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000}, 850 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000}, 851 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000}, 852 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000}, 853 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000}, 854 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024}, 855 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000}, 856 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100}, 857 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1}, 858 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000}, 859 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000}, 860 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000}, 861 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101}, 862 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003}, 863 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0}, 864 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000}, 865 {0x06, 0x0029}, {0x05, 0x0009}, 866 }; 867 868 static const struct i2c_reg_u16 mt9m001_init[] = { 869 {0x0d, 0x0001}, 870 {0x0d, 0x0000}, 871 {0x04, 0x0500}, /* hres = 1280 */ 872 {0x03, 0x0400}, /* vres = 1024 */ 873 {0x20, 0x1100}, 874 {0x06, 0x0010}, 875 {0x2b, 0x0024}, 876 {0x2e, 0x0024}, 877 {0x35, 0x0024}, 878 {0x2d, 0x0020}, 879 {0x2c, 0x0020}, 880 {0x09, 0x0ad4}, 881 {0x35, 0x0057}, 882 }; 883 884 static const struct i2c_reg_u16 mt9m111_init[] = { 885 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 886 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 887 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 888 {0xf0, 0x0000}, 889 }; 890 891 static const struct i2c_reg_u16 mt9m112_init[] = { 892 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008}, 893 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300}, 894 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e}, 895 {0xf0, 0x0000}, 896 }; 897 898 static const struct i2c_reg_u8 hv7131r_init[] = { 899 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08}, 900 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0}, 901 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08}, 902 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07}, 903 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62}, 904 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10}, 905 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00}, 906 {0x23, 0x09}, {0x01, 0x08}, 907 }; 908 909 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) 910 { 911 struct usb_device *dev = gspca_dev->dev; 912 int result; 913 914 if (gspca_dev->usb_err < 0) 915 return; 916 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 917 0x00, 918 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 919 reg, 920 0x00, 921 gspca_dev->usb_buf, 922 length, 923 500); 924 if (unlikely(result < 0 || result != length)) { 925 pr_err("Read register %02x failed %d\n", reg, result); 926 gspca_dev->usb_err = result; 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_quality(struct gspca_dev *gspca_dev, s32 val) 1540 { 1541 struct sd *sd = (struct sd *) gspca_dev; 1542 1543 jpeg_set_qual(sd->jpeg_hdr, val); 1544 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */ 1545 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */ 1546 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 1547 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); 1548 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */ 1549 reg_w1(gspca_dev, 0x10e0, sd->fmt); 1550 sd->fmt ^= 0x0c; /* invert QTAB use + write */ 1551 reg_w1(gspca_dev, 0x10e0, sd->fmt); 1552 } 1553 1554 #ifdef CONFIG_VIDEO_ADV_DEBUG 1555 static int sd_dbg_g_register(struct gspca_dev *gspca_dev, 1556 struct v4l2_dbg_register *reg) 1557 { 1558 struct sd *sd = (struct sd *) gspca_dev; 1559 1560 reg->size = 1; 1561 switch (reg->match.addr) { 1562 case 0: 1563 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1564 return -EINVAL; 1565 reg_r(gspca_dev, reg->reg, 1); 1566 reg->val = gspca_dev->usb_buf[0]; 1567 return gspca_dev->usb_err; 1568 case 1: 1569 if (sd->sensor >= SENSOR_MT9V011 && 1570 sd->sensor <= SENSOR_MT9M112) { 1571 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val); 1572 reg->size = 2; 1573 } else { 1574 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val); 1575 } 1576 return gspca_dev->usb_err; 1577 } 1578 return -EINVAL; 1579 } 1580 1581 static int sd_dbg_s_register(struct gspca_dev *gspca_dev, 1582 const struct v4l2_dbg_register *reg) 1583 { 1584 struct sd *sd = (struct sd *) gspca_dev; 1585 1586 switch (reg->match.addr) { 1587 case 0: 1588 if (reg->reg < 0x1000 || reg->reg > 0x11ff) 1589 return -EINVAL; 1590 reg_w1(gspca_dev, reg->reg, reg->val); 1591 return gspca_dev->usb_err; 1592 case 1: 1593 if (sd->sensor >= SENSOR_MT9V011 && 1594 sd->sensor <= SENSOR_MT9M112) { 1595 i2c_w2(gspca_dev, reg->reg, reg->val); 1596 } else { 1597 i2c_w1(gspca_dev, reg->reg, reg->val); 1598 } 1599 return gspca_dev->usb_err; 1600 } 1601 return -EINVAL; 1602 } 1603 1604 static int sd_chip_info(struct gspca_dev *gspca_dev, 1605 struct v4l2_dbg_chip_info *chip) 1606 { 1607 if (chip->match.addr > 1) 1608 return -EINVAL; 1609 if (chip->match.addr == 1) 1610 strlcpy(chip->name, "sensor", sizeof(chip->name)); 1611 return 0; 1612 } 1613 #endif 1614 1615 static int sd_config(struct gspca_dev *gspca_dev, 1616 const struct usb_device_id *id) 1617 { 1618 struct sd *sd = (struct sd *) gspca_dev; 1619 struct cam *cam; 1620 1621 cam = &gspca_dev->cam; 1622 cam->needs_full_bandwidth = 1; 1623 1624 sd->sensor = id->driver_info >> 8; 1625 sd->i2c_addr = id->driver_info; 1626 sd->flags = id->driver_info >> 16; 1627 sd->i2c_intf = 0x80; /* i2c 100 Kb/s */ 1628 1629 switch (sd->sensor) { 1630 case SENSOR_MT9M112: 1631 case SENSOR_MT9M111: 1632 case SENSOR_OV9650: 1633 case SENSOR_SOI968: 1634 cam->cam_mode = sxga_mode; 1635 cam->nmodes = ARRAY_SIZE(sxga_mode); 1636 break; 1637 case SENSOR_MT9M001: 1638 cam->cam_mode = mono_mode; 1639 cam->nmodes = ARRAY_SIZE(mono_mode); 1640 break; 1641 case SENSOR_HV7131R: 1642 sd->i2c_intf = 0x81; /* i2c 400 Kb/s */ 1643 /* fall thru */ 1644 default: 1645 cam->cam_mode = vga_mode; 1646 cam->nmodes = ARRAY_SIZE(vga_mode); 1647 break; 1648 } 1649 1650 sd->old_step = 0; 1651 sd->older_step = 0; 1652 sd->exposure_step = 16; 1653 1654 INIT_WORK(&sd->work, qual_upd); 1655 1656 return 0; 1657 } 1658 1659 static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 1660 { 1661 struct gspca_dev *gspca_dev = 1662 container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 1663 struct sd *sd = (struct sd *)gspca_dev; 1664 1665 gspca_dev->usb_err = 0; 1666 1667 if (!gspca_dev->streaming) 1668 return 0; 1669 1670 switch (ctrl->id) { 1671 /* color control cluster */ 1672 case V4L2_CID_BRIGHTNESS: 1673 set_cmatrix(gspca_dev, sd->brightness->val, 1674 sd->contrast->val, sd->saturation->val, sd->hue->val); 1675 break; 1676 case V4L2_CID_GAMMA: 1677 set_gamma(gspca_dev, ctrl->val); 1678 break; 1679 /* blue/red balance cluster */ 1680 case V4L2_CID_BLUE_BALANCE: 1681 set_redblue(gspca_dev, sd->blue->val, sd->red->val); 1682 break; 1683 /* h/vflip cluster */ 1684 case V4L2_CID_HFLIP: 1685 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val); 1686 break; 1687 /* standalone exposure control */ 1688 case V4L2_CID_EXPOSURE: 1689 set_exposure(gspca_dev, ctrl->val); 1690 break; 1691 /* standalone gain control */ 1692 case V4L2_CID_GAIN: 1693 set_gain(gspca_dev, ctrl->val); 1694 break; 1695 /* autogain + exposure or gain control cluster */ 1696 case V4L2_CID_AUTOGAIN: 1697 if (sd->sensor == SENSOR_SOI968) 1698 set_gain(gspca_dev, sd->gain->val); 1699 else 1700 set_exposure(gspca_dev, sd->exposure->val); 1701 break; 1702 case V4L2_CID_JPEG_COMPRESSION_QUALITY: 1703 set_quality(gspca_dev, ctrl->val); 1704 break; 1705 } 1706 return gspca_dev->usb_err; 1707 } 1708 1709 static const struct v4l2_ctrl_ops sd_ctrl_ops = { 1710 .s_ctrl = sd_s_ctrl, 1711 }; 1712 1713 static int sd_init_controls(struct gspca_dev *gspca_dev) 1714 { 1715 struct sd *sd = (struct sd *) gspca_dev; 1716 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 1717 1718 gspca_dev->vdev.ctrl_handler = hdl; 1719 v4l2_ctrl_handler_init(hdl, 13); 1720 1721 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1722 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); 1723 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1724 V4L2_CID_CONTRAST, 0, 255, 1, 127); 1725 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1726 V4L2_CID_SATURATION, 0, 255, 1, 127); 1727 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1728 V4L2_CID_HUE, -180, 180, 1, 0); 1729 1730 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1731 V4L2_CID_GAMMA, 0, 255, 1, 0x10); 1732 1733 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1734 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); 1735 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1736 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); 1737 1738 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && 1739 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && 1740 sd->sensor != SENSOR_MT9VPRB) { 1741 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1742 V4L2_CID_HFLIP, 0, 1, 1, 0); 1743 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1744 V4L2_CID_VFLIP, 0, 1, 1, 0); 1745 } 1746 1747 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && 1748 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 && 1749 sd->sensor != SENSOR_MT9V111) 1750 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1751 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33); 1752 1753 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 && 1754 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) { 1755 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1756 V4L2_CID_GAIN, 0, 28, 1, 0); 1757 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1758 V4L2_CID_AUTOGAIN, 0, 1, 1, 1); 1759 } 1760 1761 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 1762 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); 1763 if (hdl->error) { 1764 pr_err("Could not initialize controls\n"); 1765 return hdl->error; 1766 } 1767 1768 v4l2_ctrl_cluster(4, &sd->brightness); 1769 v4l2_ctrl_cluster(2, &sd->blue); 1770 if (sd->hflip) 1771 v4l2_ctrl_cluster(2, &sd->hflip); 1772 if (sd->autogain) { 1773 if (sd->sensor == SENSOR_SOI968) 1774 /* this sensor doesn't have the exposure control and 1775 autogain is clustered with gain instead. This works 1776 because sd->exposure == NULL. */ 1777 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false); 1778 else 1779 /* Otherwise autogain is clustered with exposure. */ 1780 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); 1781 } 1782 return 0; 1783 } 1784 1785 static int sd_init(struct gspca_dev *gspca_dev) 1786 { 1787 struct sd *sd = (struct sd *) gspca_dev; 1788 int i; 1789 u8 value; 1790 u8 i2c_init[9] = { 1791 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 1792 }; 1793 1794 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) { 1795 value = bridge_init[i][1]; 1796 reg_w(gspca_dev, bridge_init[i][0], &value, 1); 1797 if (gspca_dev->usb_err < 0) { 1798 pr_err("Device initialization failed\n"); 1799 return gspca_dev->usb_err; 1800 } 1801 } 1802 1803 if (sd->flags & LED_REVERSE) 1804 reg_w1(gspca_dev, 0x1006, 0x00); 1805 else 1806 reg_w1(gspca_dev, 0x1006, 0x20); 1807 1808 reg_w(gspca_dev, 0x10c0, i2c_init, 9); 1809 if (gspca_dev->usb_err < 0) { 1810 pr_err("Device initialization failed\n"); 1811 return gspca_dev->usb_err; 1812 } 1813 1814 switch (sd->sensor) { 1815 case SENSOR_OV9650: 1816 ov9650_init_sensor(gspca_dev); 1817 if (gspca_dev->usb_err < 0) 1818 break; 1819 pr_info("OV9650 sensor detected\n"); 1820 break; 1821 case SENSOR_OV9655: 1822 ov9655_init_sensor(gspca_dev); 1823 if (gspca_dev->usb_err < 0) 1824 break; 1825 pr_info("OV9655 sensor detected\n"); 1826 break; 1827 case SENSOR_SOI968: 1828 soi968_init_sensor(gspca_dev); 1829 if (gspca_dev->usb_err < 0) 1830 break; 1831 pr_info("SOI968 sensor detected\n"); 1832 break; 1833 case SENSOR_OV7660: 1834 ov7660_init_sensor(gspca_dev); 1835 if (gspca_dev->usb_err < 0) 1836 break; 1837 pr_info("OV7660 sensor detected\n"); 1838 break; 1839 case SENSOR_OV7670: 1840 ov7670_init_sensor(gspca_dev); 1841 if (gspca_dev->usb_err < 0) 1842 break; 1843 pr_info("OV7670 sensor detected\n"); 1844 break; 1845 case SENSOR_MT9VPRB: 1846 mt9v_init_sensor(gspca_dev); 1847 if (gspca_dev->usb_err < 0) 1848 break; 1849 pr_info("MT9VPRB sensor detected\n"); 1850 break; 1851 case SENSOR_MT9M111: 1852 mt9m111_init_sensor(gspca_dev); 1853 if (gspca_dev->usb_err < 0) 1854 break; 1855 pr_info("MT9M111 sensor detected\n"); 1856 break; 1857 case SENSOR_MT9M112: 1858 mt9m112_init_sensor(gspca_dev); 1859 if (gspca_dev->usb_err < 0) 1860 break; 1861 pr_info("MT9M112 sensor detected\n"); 1862 break; 1863 case SENSOR_MT9M001: 1864 mt9m001_init_sensor(gspca_dev); 1865 if (gspca_dev->usb_err < 0) 1866 break; 1867 break; 1868 case SENSOR_HV7131R: 1869 hv7131r_init_sensor(gspca_dev); 1870 if (gspca_dev->usb_err < 0) 1871 break; 1872 pr_info("HV7131R sensor detected\n"); 1873 break; 1874 default: 1875 pr_err("Unsupported sensor\n"); 1876 gspca_dev->usb_err = -ENODEV; 1877 } 1878 return gspca_dev->usb_err; 1879 } 1880 1881 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode) 1882 { 1883 struct sd *sd = (struct sd *) gspca_dev; 1884 u8 value; 1885 1886 switch (sd->sensor) { 1887 case SENSOR_SOI968: 1888 if (mode & MODE_SXGA) { 1889 i2c_w1(gspca_dev, 0x17, 0x1d); 1890 i2c_w1(gspca_dev, 0x18, 0xbd); 1891 i2c_w1(gspca_dev, 0x19, 0x01); 1892 i2c_w1(gspca_dev, 0x1a, 0x81); 1893 i2c_w1(gspca_dev, 0x12, 0x00); 1894 sd->hstart = 140; 1895 sd->vstart = 19; 1896 } else { 1897 i2c_w1(gspca_dev, 0x17, 0x13); 1898 i2c_w1(gspca_dev, 0x18, 0x63); 1899 i2c_w1(gspca_dev, 0x19, 0x01); 1900 i2c_w1(gspca_dev, 0x1a, 0x79); 1901 i2c_w1(gspca_dev, 0x12, 0x40); 1902 sd->hstart = 60; 1903 sd->vstart = 11; 1904 } 1905 break; 1906 case SENSOR_OV9650: 1907 if (mode & MODE_SXGA) { 1908 i2c_w1(gspca_dev, 0x17, 0x1b); 1909 i2c_w1(gspca_dev, 0x18, 0xbc); 1910 i2c_w1(gspca_dev, 0x19, 0x01); 1911 i2c_w1(gspca_dev, 0x1a, 0x82); 1912 i2c_r1(gspca_dev, 0x12, &value); 1913 i2c_w1(gspca_dev, 0x12, value & 0x07); 1914 } else { 1915 i2c_w1(gspca_dev, 0x17, 0x24); 1916 i2c_w1(gspca_dev, 0x18, 0xc5); 1917 i2c_w1(gspca_dev, 0x19, 0x00); 1918 i2c_w1(gspca_dev, 0x1a, 0x3c); 1919 i2c_r1(gspca_dev, 0x12, &value); 1920 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40); 1921 } 1922 break; 1923 case SENSOR_MT9M112: 1924 case SENSOR_MT9M111: 1925 if (mode & MODE_SXGA) { 1926 i2c_w2(gspca_dev, 0xf0, 0x0002); 1927 i2c_w2(gspca_dev, 0xc8, 0x970b); 1928 i2c_w2(gspca_dev, 0xf0, 0x0000); 1929 } else { 1930 i2c_w2(gspca_dev, 0xf0, 0x0002); 1931 i2c_w2(gspca_dev, 0xc8, 0x8000); 1932 i2c_w2(gspca_dev, 0xf0, 0x0000); 1933 } 1934 break; 1935 } 1936 } 1937 1938 static int sd_isoc_init(struct gspca_dev *gspca_dev) 1939 { 1940 struct usb_interface *intf; 1941 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv; 1942 1943 /* 1944 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth 1945 * than our regular bandwidth calculations reserve, so we force the 1946 * use of a specific altsetting when using the SN9C20X_I420 fmt. 1947 */ 1948 if (!(flags & (MODE_RAW | MODE_JPEG))) { 1949 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); 1950 1951 if (intf->num_altsetting != 9) { 1952 pr_warn("sn9c20x camera with unknown number of alt " 1953 "settings (%d), please report!\n", 1954 intf->num_altsetting); 1955 gspca_dev->alt = intf->num_altsetting; 1956 return 0; 1957 } 1958 1959 switch (gspca_dev->pixfmt.width) { 1960 case 160: /* 160x120 */ 1961 gspca_dev->alt = 2; 1962 break; 1963 case 320: /* 320x240 */ 1964 gspca_dev->alt = 6; 1965 break; 1966 default: /* >= 640x480 */ 1967 gspca_dev->alt = 9; 1968 break; 1969 } 1970 } 1971 1972 return 0; 1973 } 1974 1975 #define HW_WIN(mode, hstart, vstart) \ 1976 ((const u8 []){hstart, 0, vstart, 0, \ 1977 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \ 1978 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)}) 1979 1980 #define CLR_WIN(width, height) \ 1981 ((const u8 [])\ 1982 {0, width >> 2, 0, height >> 1,\ 1983 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)}) 1984 1985 static int sd_start(struct gspca_dev *gspca_dev) 1986 { 1987 struct sd *sd = (struct sd *) gspca_dev; 1988 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; 1989 int width = gspca_dev->pixfmt.width; 1990 int height = gspca_dev->pixfmt.height; 1991 u8 fmt, scale = 0; 1992 1993 jpeg_define(sd->jpeg_hdr, height, width, 1994 0x21); 1995 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); 1996 1997 if (mode & MODE_RAW) 1998 fmt = 0x2d; 1999 else if (mode & MODE_JPEG) 2000 fmt = 0x24; 2001 else 2002 fmt = 0x2f; /* YUV 420 */ 2003 sd->fmt = fmt; 2004 2005 switch (mode & SCALE_MASK) { 2006 case SCALE_1280x1024: 2007 scale = 0xc0; 2008 pr_info("Set 1280x1024\n"); 2009 break; 2010 case SCALE_640x480: 2011 scale = 0x80; 2012 pr_info("Set 640x480\n"); 2013 break; 2014 case SCALE_320x240: 2015 scale = 0x90; 2016 pr_info("Set 320x240\n"); 2017 break; 2018 case SCALE_160x120: 2019 scale = 0xa0; 2020 pr_info("Set 160x120\n"); 2021 break; 2022 } 2023 2024 configure_sensor_output(gspca_dev, mode); 2025 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64); 2026 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64); 2027 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5); 2028 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6); 2029 reg_w1(gspca_dev, 0x1189, scale); 2030 reg_w1(gspca_dev, 0x10e0, fmt); 2031 2032 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness), 2033 v4l2_ctrl_g_ctrl(sd->contrast), 2034 v4l2_ctrl_g_ctrl(sd->saturation), 2035 v4l2_ctrl_g_ctrl(sd->hue)); 2036 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); 2037 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue), 2038 v4l2_ctrl_g_ctrl(sd->red)); 2039 if (sd->gain) 2040 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); 2041 if (sd->exposure) 2042 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); 2043 if (sd->hflip) 2044 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 2045 v4l2_ctrl_g_ctrl(sd->vflip)); 2046 2047 reg_w1(gspca_dev, 0x1007, 0x20); 2048 reg_w1(gspca_dev, 0x1061, 0x03); 2049 2050 /* if JPEG, prepare the compression quality update */ 2051 if (mode & MODE_JPEG) { 2052 sd->pktsz = sd->npkt = 0; 2053 sd->nchg = 0; 2054 sd->work_thread = 2055 create_singlethread_workqueue(KBUILD_MODNAME); 2056 } 2057 2058 return gspca_dev->usb_err; 2059 } 2060 2061 static void sd_stopN(struct gspca_dev *gspca_dev) 2062 { 2063 reg_w1(gspca_dev, 0x1007, 0x00); 2064 reg_w1(gspca_dev, 0x1061, 0x01); 2065 } 2066 2067 /* called on streamoff with alt==0 and on disconnect */ 2068 /* the usb_lock is held at entry - restore on exit */ 2069 static void sd_stop0(struct gspca_dev *gspca_dev) 2070 { 2071 struct sd *sd = (struct sd *) gspca_dev; 2072 2073 if (sd->work_thread != NULL) { 2074 mutex_unlock(&gspca_dev->usb_lock); 2075 destroy_workqueue(sd->work_thread); 2076 mutex_lock(&gspca_dev->usb_lock); 2077 sd->work_thread = NULL; 2078 } 2079 } 2080 2081 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum) 2082 { 2083 struct sd *sd = (struct sd *) gspca_dev; 2084 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure); 2085 s32 max = sd->exposure->maximum - sd->exposure_step; 2086 s32 min = sd->exposure->minimum + sd->exposure_step; 2087 s16 new_exp; 2088 2089 /* 2090 * some hardcoded values are present 2091 * like those for maximal/minimal exposure 2092 * and exposure steps 2093 */ 2094 if (avg_lum < MIN_AVG_LUM) { 2095 if (cur_exp > max) 2096 return; 2097 2098 new_exp = cur_exp + sd->exposure_step; 2099 if (new_exp > max) 2100 new_exp = max; 2101 if (new_exp < min) 2102 new_exp = min; 2103 v4l2_ctrl_s_ctrl(sd->exposure, new_exp); 2104 2105 sd->older_step = sd->old_step; 2106 sd->old_step = 1; 2107 2108 if (sd->old_step ^ sd->older_step) 2109 sd->exposure_step /= 2; 2110 else 2111 sd->exposure_step += 2; 2112 } 2113 if (avg_lum > MAX_AVG_LUM) { 2114 if (cur_exp < min) 2115 return; 2116 new_exp = cur_exp - sd->exposure_step; 2117 if (new_exp > max) 2118 new_exp = max; 2119 if (new_exp < min) 2120 new_exp = min; 2121 v4l2_ctrl_s_ctrl(sd->exposure, new_exp); 2122 sd->older_step = sd->old_step; 2123 sd->old_step = 0; 2124 2125 if (sd->old_step ^ sd->older_step) 2126 sd->exposure_step /= 2; 2127 else 2128 sd->exposure_step += 2; 2129 } 2130 } 2131 2132 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum) 2133 { 2134 struct sd *sd = (struct sd *) gspca_dev; 2135 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain); 2136 2137 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum) 2138 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1); 2139 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum) 2140 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1); 2141 } 2142 2143 static void sd_dqcallback(struct gspca_dev *gspca_dev) 2144 { 2145 struct sd *sd = (struct sd *) gspca_dev; 2146 int avg_lum; 2147 2148 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) 2149 return; 2150 2151 avg_lum = atomic_read(&sd->avg_lum); 2152 if (sd->sensor == SENSOR_SOI968) 2153 do_autogain(gspca_dev, avg_lum); 2154 else 2155 do_autoexposure(gspca_dev, avg_lum); 2156 } 2157 2158 /* JPEG quality update */ 2159 /* This function is executed from a work queue. */ 2160 static void qual_upd(struct work_struct *work) 2161 { 2162 struct sd *sd = container_of(work, struct sd, work); 2163 struct gspca_dev *gspca_dev = &sd->gspca_dev; 2164 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual); 2165 2166 /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */ 2167 mutex_lock(&gspca_dev->usb_lock); 2168 PDEBUG(D_STREAM, "qual_upd %d%%", qual); 2169 gspca_dev->usb_err = 0; 2170 set_quality(gspca_dev, qual); 2171 mutex_unlock(&gspca_dev->usb_lock); 2172 } 2173 2174 #if IS_ENABLED(CONFIG_INPUT) 2175 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev, 2176 u8 *data, /* interrupt packet */ 2177 int len) /* interrupt packet length */ 2178 { 2179 struct sd *sd = (struct sd *) gspca_dev; 2180 2181 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) { 2182 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1); 2183 input_sync(gspca_dev->input_dev); 2184 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0); 2185 input_sync(gspca_dev->input_dev); 2186 return 0; 2187 } 2188 return -EINVAL; 2189 } 2190 #endif 2191 2192 /* check the JPEG compression */ 2193 static void transfer_check(struct gspca_dev *gspca_dev, 2194 u8 *data) 2195 { 2196 struct sd *sd = (struct sd *) gspca_dev; 2197 int new_qual, r; 2198 2199 new_qual = 0; 2200 2201 /* if USB error, discard the frame and decrease the quality */ 2202 if (data[6] & 0x08) { /* USB FIFO full */ 2203 gspca_dev->last_packet_type = DISCARD_PACKET; 2204 new_qual = -5; 2205 } else { 2206 2207 /* else, compute the filling rate and a new JPEG quality */ 2208 r = (sd->pktsz * 100) / 2209 (sd->npkt * 2210 gspca_dev->urb[0]->iso_frame_desc[0].length); 2211 if (r >= 85) 2212 new_qual = -3; 2213 else if (r < 75) 2214 new_qual = 2; 2215 } 2216 if (new_qual != 0) { 2217 sd->nchg += new_qual; 2218 if (sd->nchg < -6 || sd->nchg >= 12) { 2219 /* Note: we are in interrupt context, so we can't 2220 use v4l2_ctrl_g/s_ctrl here. Access the value 2221 directly instead. */ 2222 s32 curqual = sd->jpegqual->cur.val; 2223 sd->nchg = 0; 2224 new_qual += curqual; 2225 if (new_qual < sd->jpegqual->minimum) 2226 new_qual = sd->jpegqual->minimum; 2227 else if (new_qual > sd->jpegqual->maximum) 2228 new_qual = sd->jpegqual->maximum; 2229 if (new_qual != curqual) { 2230 sd->jpegqual->cur.val = new_qual; 2231 queue_work(sd->work_thread, &sd->work); 2232 } 2233 } 2234 } else { 2235 sd->nchg = 0; 2236 } 2237 sd->pktsz = sd->npkt = 0; 2238 } 2239 2240 static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2241 u8 *data, /* isoc packet */ 2242 int len) /* iso packet length */ 2243 { 2244 struct sd *sd = (struct sd *) gspca_dev; 2245 int avg_lum, is_jpeg; 2246 static const u8 frame_header[] = { 2247 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96 2248 }; 2249 2250 is_jpeg = (sd->fmt & 0x03) == 0; 2251 if (len >= 64 && memcmp(data, frame_header, 6) == 0) { 2252 avg_lum = ((data[35] >> 2) & 3) | 2253 (data[20] << 2) | 2254 (data[19] << 10); 2255 avg_lum += ((data[35] >> 4) & 3) | 2256 (data[22] << 2) | 2257 (data[21] << 10); 2258 avg_lum += ((data[35] >> 6) & 3) | 2259 (data[24] << 2) | 2260 (data[23] << 10); 2261 avg_lum += (data[36] & 3) | 2262 (data[26] << 2) | 2263 (data[25] << 10); 2264 avg_lum += ((data[36] >> 2) & 3) | 2265 (data[28] << 2) | 2266 (data[27] << 10); 2267 avg_lum += ((data[36] >> 4) & 3) | 2268 (data[30] << 2) | 2269 (data[29] << 10); 2270 avg_lum += ((data[36] >> 6) & 3) | 2271 (data[32] << 2) | 2272 (data[31] << 10); 2273 avg_lum += ((data[44] >> 4) & 3) | 2274 (data[34] << 2) | 2275 (data[33] << 10); 2276 avg_lum >>= 9; 2277 atomic_set(&sd->avg_lum, avg_lum); 2278 2279 if (is_jpeg) 2280 transfer_check(gspca_dev, data); 2281 2282 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2283 len -= 64; 2284 if (len == 0) 2285 return; 2286 data += 64; 2287 } 2288 if (gspca_dev->last_packet_type == LAST_PACKET) { 2289 if (is_jpeg) { 2290 gspca_frame_add(gspca_dev, FIRST_PACKET, 2291 sd->jpeg_hdr, JPEG_HDR_SZ); 2292 gspca_frame_add(gspca_dev, INTER_PACKET, 2293 data, len); 2294 } else { 2295 gspca_frame_add(gspca_dev, FIRST_PACKET, 2296 data, len); 2297 } 2298 } else { 2299 /* if JPEG, count the packets and their size */ 2300 if (is_jpeg) { 2301 sd->npkt++; 2302 sd->pktsz += len; 2303 } 2304 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2305 } 2306 } 2307 2308 /* sub-driver description */ 2309 static const struct sd_desc sd_desc = { 2310 .name = KBUILD_MODNAME, 2311 .config = sd_config, 2312 .init = sd_init, 2313 .init_controls = sd_init_controls, 2314 .isoc_init = sd_isoc_init, 2315 .start = sd_start, 2316 .stopN = sd_stopN, 2317 .stop0 = sd_stop0, 2318 .pkt_scan = sd_pkt_scan, 2319 #if IS_ENABLED(CONFIG_INPUT) 2320 .int_pkt_scan = sd_int_pkt_scan, 2321 #endif 2322 .dq_callback = sd_dqcallback, 2323 #ifdef CONFIG_VIDEO_ADV_DEBUG 2324 .set_register = sd_dbg_s_register, 2325 .get_register = sd_dbg_g_register, 2326 .get_chip_info = sd_chip_info, 2327 #endif 2328 }; 2329 2330 #define SN9C20X(sensor, i2c_addr, flags) \ 2331 .driver_info = ((flags & 0xff) << 16) \ 2332 | (SENSOR_ ## sensor << 8) \ 2333 | (i2c_addr) 2334 2335 static const struct usb_device_id device_table[] = { 2336 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, 2337 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, 2338 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, 2339 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)}, 2340 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)}, 2341 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30, 2342 (FLIP_DETECT | HAS_NO_BUTTON))}, 2343 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)}, 2344 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2345 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2346 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, 2347 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)}, 2348 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, 2349 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2350 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2351 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)}, 2352 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)}, 2353 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)}, 2354 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)}, 2355 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)}, 2356 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2357 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2358 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)}, 2359 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)}, 2360 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2361 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2362 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2363 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)}, 2364 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)}, 2365 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)}, 2366 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)}, 2367 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)}, 2368 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)}, 2369 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)}, 2370 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)}, 2371 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)}, 2372 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)}, 2373 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)}, 2374 {} 2375 }; 2376 MODULE_DEVICE_TABLE(usb, device_table); 2377 2378 /* -- device connect -- */ 2379 static int sd_probe(struct usb_interface *intf, 2380 const struct usb_device_id *id) 2381 { 2382 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 2383 THIS_MODULE); 2384 } 2385 2386 static struct usb_driver sd_driver = { 2387 .name = KBUILD_MODNAME, 2388 .id_table = device_table, 2389 .probe = sd_probe, 2390 .disconnect = gspca_disconnect, 2391 #ifdef CONFIG_PM 2392 .suspend = gspca_suspend, 2393 .resume = gspca_resume, 2394 .reset_resume = gspca_resume, 2395 #endif 2396 }; 2397 2398 module_usb_driver(sd_driver); 2399