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