0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011
0012 #include <linux/input.h>
0013
0014 #include "gspca.h"
0015 #include "jpeg.h"
0016
0017 #include <linux/dmi.h>
0018
0019 MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
0020 MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
0021 MODULE_LICENSE("GPL");
0022
0023
0024
0025
0026 #define SCALE_MASK 0x0f
0027 #define SCALE_160x120 0
0028 #define SCALE_320x240 1
0029 #define SCALE_640x480 2
0030 #define SCALE_1280x1024 3
0031 #define MODE_RAW 0x10
0032 #define MODE_JPEG 0x20
0033 #define MODE_SXGA 0x80
0034
0035 #define SENSOR_OV9650 0
0036 #define SENSOR_OV9655 1
0037 #define SENSOR_SOI968 2
0038 #define SENSOR_OV7660 3
0039 #define SENSOR_OV7670 4
0040 #define SENSOR_MT9V011 5
0041 #define SENSOR_MT9V111 6
0042 #define SENSOR_MT9V112 7
0043 #define SENSOR_MT9M001 8
0044 #define SENSOR_MT9M111 9
0045 #define SENSOR_MT9M112 10
0046 #define SENSOR_HV7131R 11
0047 #define SENSOR_MT9VPRB 12
0048
0049
0050 #define HAS_NO_BUTTON 0x1
0051 #define LED_REVERSE 0x2
0052 #define FLIP_DETECT 0x4
0053 #define HAS_LED_TORCH 0x8
0054
0055
0056 struct sd {
0057 struct gspca_dev gspca_dev;
0058
0059 struct {
0060 struct v4l2_ctrl *brightness;
0061 struct v4l2_ctrl *contrast;
0062 struct v4l2_ctrl *saturation;
0063 struct v4l2_ctrl *hue;
0064 };
0065 struct {
0066 struct v4l2_ctrl *blue;
0067 struct v4l2_ctrl *red;
0068 };
0069 struct {
0070 struct v4l2_ctrl *hflip;
0071 struct v4l2_ctrl *vflip;
0072 };
0073 struct v4l2_ctrl *gamma;
0074 struct {
0075 struct v4l2_ctrl *autogain;
0076 struct v4l2_ctrl *exposure;
0077 struct v4l2_ctrl *gain;
0078 };
0079 struct v4l2_ctrl *jpegqual;
0080
0081 struct v4l2_ctrl *led_mode;
0082
0083 struct work_struct work;
0084
0085 u32 pktsz;
0086 u16 npkt;
0087 s8 nchg;
0088 u8 fmt;
0089
0090 #define MIN_AVG_LUM 80
0091 #define MAX_AVG_LUM 130
0092 atomic_t avg_lum;
0093 u8 old_step;
0094 u8 older_step;
0095 u8 exposure_step;
0096
0097 u8 i2c_addr;
0098 u8 i2c_intf;
0099 u8 sensor;
0100 u8 hstart;
0101 u8 vstart;
0102
0103 u8 jpeg_hdr[JPEG_HDR_SZ];
0104
0105 u8 flags;
0106 };
0107
0108 static void qual_upd(struct work_struct *work);
0109
0110 struct i2c_reg_u8 {
0111 u8 reg;
0112 u8 val;
0113 };
0114
0115 struct i2c_reg_u16 {
0116 u8 reg;
0117 u16 val;
0118 };
0119
0120 static const struct dmi_system_id flip_dmi_table[] = {
0121 {
0122 .ident = "MSI MS-1034",
0123 .matches = {
0124 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
0125 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
0126 DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
0127 }
0128 },
0129 {
0130 .ident = "MSI MS-1039",
0131 .matches = {
0132 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
0133 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
0134 }
0135 },
0136 {
0137 .ident = "MSI MS-1632",
0138 .matches = {
0139 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0140 DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
0141 }
0142 },
0143 {
0144 .ident = "MSI MS-1633X",
0145 .matches = {
0146 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0147 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
0148 }
0149 },
0150 {
0151 .ident = "MSI MS-1635X",
0152 .matches = {
0153 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
0154 DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
0155 }
0156 },
0157 {
0158 .ident = "ASUSTeK W7J",
0159 .matches = {
0160 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
0161 DMI_MATCH(DMI_BOARD_NAME, "W7J ")
0162 }
0163 },
0164 {}
0165 };
0166
0167 static const struct v4l2_pix_format vga_mode[] = {
0168 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0169 .bytesperline = 160,
0170 .sizeimage = 160 * 120 * 4 / 8 + 590,
0171 .colorspace = V4L2_COLORSPACE_JPEG,
0172 .priv = SCALE_160x120 | MODE_JPEG},
0173 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0174 .bytesperline = 160,
0175 .sizeimage = 160 * 120,
0176 .colorspace = V4L2_COLORSPACE_SRGB,
0177 .priv = SCALE_160x120 | MODE_RAW},
0178 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0179 .bytesperline = 160,
0180 .sizeimage = 240 * 120,
0181 .colorspace = V4L2_COLORSPACE_SRGB,
0182 .priv = SCALE_160x120},
0183 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0184 .bytesperline = 320,
0185 .sizeimage = 320 * 240 * 4 / 8 + 590,
0186 .colorspace = V4L2_COLORSPACE_JPEG,
0187 .priv = SCALE_320x240 | MODE_JPEG},
0188 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0189 .bytesperline = 320,
0190 .sizeimage = 320 * 240 ,
0191 .colorspace = V4L2_COLORSPACE_SRGB,
0192 .priv = SCALE_320x240 | MODE_RAW},
0193 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0194 .bytesperline = 320,
0195 .sizeimage = 480 * 240 ,
0196 .colorspace = V4L2_COLORSPACE_SRGB,
0197 .priv = SCALE_320x240},
0198 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0199 .bytesperline = 640,
0200 .sizeimage = 640 * 480 * 4 / 8 + 590,
0201 .colorspace = V4L2_COLORSPACE_JPEG,
0202 .priv = SCALE_640x480 | MODE_JPEG},
0203 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0204 .bytesperline = 640,
0205 .sizeimage = 640 * 480,
0206 .colorspace = V4L2_COLORSPACE_SRGB,
0207 .priv = SCALE_640x480 | MODE_RAW},
0208 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0209 .bytesperline = 640,
0210 .sizeimage = 960 * 480,
0211 .colorspace = V4L2_COLORSPACE_SRGB,
0212 .priv = SCALE_640x480},
0213 };
0214
0215 static const struct v4l2_pix_format sxga_mode[] = {
0216 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0217 .bytesperline = 160,
0218 .sizeimage = 160 * 120 * 4 / 8 + 590,
0219 .colorspace = V4L2_COLORSPACE_JPEG,
0220 .priv = SCALE_160x120 | MODE_JPEG},
0221 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0222 .bytesperline = 160,
0223 .sizeimage = 160 * 120,
0224 .colorspace = V4L2_COLORSPACE_SRGB,
0225 .priv = SCALE_160x120 | MODE_RAW},
0226 {160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0227 .bytesperline = 160,
0228 .sizeimage = 240 * 120,
0229 .colorspace = V4L2_COLORSPACE_SRGB,
0230 .priv = SCALE_160x120},
0231 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0232 .bytesperline = 320,
0233 .sizeimage = 320 * 240 * 4 / 8 + 590,
0234 .colorspace = V4L2_COLORSPACE_JPEG,
0235 .priv = SCALE_320x240 | MODE_JPEG},
0236 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0237 .bytesperline = 320,
0238 .sizeimage = 320 * 240 ,
0239 .colorspace = V4L2_COLORSPACE_SRGB,
0240 .priv = SCALE_320x240 | MODE_RAW},
0241 {320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0242 .bytesperline = 320,
0243 .sizeimage = 480 * 240 ,
0244 .colorspace = V4L2_COLORSPACE_SRGB,
0245 .priv = SCALE_320x240},
0246 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
0247 .bytesperline = 640,
0248 .sizeimage = 640 * 480 * 4 / 8 + 590,
0249 .colorspace = V4L2_COLORSPACE_JPEG,
0250 .priv = SCALE_640x480 | MODE_JPEG},
0251 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0252 .bytesperline = 640,
0253 .sizeimage = 640 * 480,
0254 .colorspace = V4L2_COLORSPACE_SRGB,
0255 .priv = SCALE_640x480 | MODE_RAW},
0256 {640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
0257 .bytesperline = 640,
0258 .sizeimage = 960 * 480,
0259 .colorspace = V4L2_COLORSPACE_SRGB,
0260 .priv = SCALE_640x480},
0261 {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
0262 .bytesperline = 1280,
0263 .sizeimage = 1280 * 1024,
0264 .colorspace = V4L2_COLORSPACE_SRGB,
0265 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
0266 };
0267
0268 static const struct v4l2_pix_format mono_mode[] = {
0269 {160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0270 .bytesperline = 160,
0271 .sizeimage = 160 * 120,
0272 .colorspace = V4L2_COLORSPACE_SRGB,
0273 .priv = SCALE_160x120 | MODE_RAW},
0274 {320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0275 .bytesperline = 320,
0276 .sizeimage = 320 * 240 ,
0277 .colorspace = V4L2_COLORSPACE_SRGB,
0278 .priv = SCALE_320x240 | MODE_RAW},
0279 {640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0280 .bytesperline = 640,
0281 .sizeimage = 640 * 480,
0282 .colorspace = V4L2_COLORSPACE_SRGB,
0283 .priv = SCALE_640x480 | MODE_RAW},
0284 {1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
0285 .bytesperline = 1280,
0286 .sizeimage = 1280 * 1024,
0287 .colorspace = V4L2_COLORSPACE_SRGB,
0288 .priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
0289 };
0290
0291 static const s16 hsv_red_x[] = {
0292 41, 44, 46, 48, 50, 52, 54, 56,
0293 58, 60, 62, 64, 66, 68, 70, 72,
0294 74, 76, 78, 80, 81, 83, 85, 87,
0295 88, 90, 92, 93, 95, 97, 98, 100,
0296 101, 102, 104, 105, 107, 108, 109, 110,
0297 112, 113, 114, 115, 116, 117, 118, 119,
0298 120, 121, 122, 123, 123, 124, 125, 125,
0299 126, 127, 127, 128, 128, 129, 129, 129,
0300 130, 130, 130, 130, 131, 131, 131, 131,
0301 131, 131, 131, 131, 130, 130, 130, 130,
0302 129, 129, 129, 128, 128, 127, 127, 126,
0303 125, 125, 124, 123, 122, 122, 121, 120,
0304 119, 118, 117, 116, 115, 114, 112, 111,
0305 110, 109, 107, 106, 105, 103, 102, 101,
0306 99, 98, 96, 94, 93, 91, 90, 88,
0307 86, 84, 83, 81, 79, 77, 75, 74,
0308 72, 70, 68, 66, 64, 62, 60, 58,
0309 56, 54, 52, 49, 47, 45, 43, 41,
0310 39, 36, 34, 32, 30, 28, 25, 23,
0311 21, 19, 16, 14, 12, 9, 7, 5,
0312 3, 0, -1, -3, -6, -8, -10, -12,
0313 -15, -17, -19, -22, -24, -26, -28, -30,
0314 -33, -35, -37, -39, -41, -44, -46, -48,
0315 -50, -52, -54, -56, -58, -60, -62, -64,
0316 -66, -68, -70, -72, -74, -76, -78, -80,
0317 -81, -83, -85, -87, -88, -90, -92, -93,
0318 -95, -97, -98, -100, -101, -102, -104, -105,
0319 -107, -108, -109, -110, -112, -113, -114, -115,
0320 -116, -117, -118, -119, -120, -121, -122, -123,
0321 -123, -124, -125, -125, -126, -127, -127, -128,
0322 -128, -128, -128, -128, -128, -128, -128, -128,
0323 -128, -128, -128, -128, -128, -128, -128, -128,
0324 -128, -128, -128, -128, -128, -128, -128, -128,
0325 -128, -127, -127, -126, -125, -125, -124, -123,
0326 -122, -122, -121, -120, -119, -118, -117, -116,
0327 -115, -114, -112, -111, -110, -109, -107, -106,
0328 -105, -103, -102, -101, -99, -98, -96, -94,
0329 -93, -91, -90, -88, -86, -84, -83, -81,
0330 -79, -77, -75, -74, -72, -70, -68, -66,
0331 -64, -62, -60, -58, -56, -54, -52, -49,
0332 -47, -45, -43, -41, -39, -36, -34, -32,
0333 -30, -28, -25, -23, -21, -19, -16, -14,
0334 -12, -9, -7, -5, -3, 0, 1, 3,
0335 6, 8, 10, 12, 15, 17, 19, 22,
0336 24, 26, 28, 30, 33, 35, 37, 39, 41
0337 };
0338
0339 static const s16 hsv_red_y[] = {
0340 82, 80, 78, 76, 74, 73, 71, 69,
0341 67, 65, 63, 61, 58, 56, 54, 52,
0342 50, 48, 46, 44, 41, 39, 37, 35,
0343 32, 30, 28, 26, 23, 21, 19, 16,
0344 14, 12, 10, 7, 5, 3, 0, -1,
0345 -3, -6, -8, -10, -13, -15, -17, -19,
0346 -22, -24, -26, -29, -31, -33, -35, -38,
0347 -40, -42, -44, -46, -48, -51, -53, -55,
0348 -57, -59, -61, -63, -65, -67, -69, -71,
0349 -73, -75, -77, -79, -81, -82, -84, -86,
0350 -88, -89, -91, -93, -94, -96, -98, -99,
0351 -101, -102, -104, -105, -106, -108, -109, -110,
0352 -112, -113, -114, -115, -116, -117, -119, -120,
0353 -120, -121, -122, -123, -124, -125, -126, -126,
0354 -127, -128, -128, -128, -128, -128, -128, -128,
0355 -128, -128, -128, -128, -128, -128, -128, -128,
0356 -128, -128, -128, -128, -128, -128, -128, -128,
0357 -128, -128, -128, -128, -128, -128, -128, -128,
0358 -127, -127, -126, -125, -125, -124, -123, -122,
0359 -121, -120, -119, -118, -117, -116, -115, -114,
0360 -113, -111, -110, -109, -107, -106, -105, -103,
0361 -102, -100, -99, -97, -96, -94, -92, -91,
0362 -89, -87, -85, -84, -82, -80, -78, -76,
0363 -74, -73, -71, -69, -67, -65, -63, -61,
0364 -58, -56, -54, -52, -50, -48, -46, -44,
0365 -41, -39, -37, -35, -32, -30, -28, -26,
0366 -23, -21, -19, -16, -14, -12, -10, -7,
0367 -5, -3, 0, 1, 3, 6, 8, 10,
0368 13, 15, 17, 19, 22, 24, 26, 29,
0369 31, 33, 35, 38, 40, 42, 44, 46,
0370 48, 51, 53, 55, 57, 59, 61, 63,
0371 65, 67, 69, 71, 73, 75, 77, 79,
0372 81, 82, 84, 86, 88, 89, 91, 93,
0373 94, 96, 98, 99, 101, 102, 104, 105,
0374 106, 108, 109, 110, 112, 113, 114, 115,
0375 116, 117, 119, 120, 120, 121, 122, 123,
0376 124, 125, 126, 126, 127, 128, 128, 129,
0377 129, 130, 130, 131, 131, 131, 131, 132,
0378 132, 132, 132, 132, 132, 132, 132, 132,
0379 132, 132, 132, 131, 131, 131, 130, 130,
0380 130, 129, 129, 128, 127, 127, 126, 125,
0381 125, 124, 123, 122, 121, 120, 119, 118,
0382 117, 116, 115, 114, 113, 111, 110, 109,
0383 107, 106, 105, 103, 102, 100, 99, 97,
0384 96, 94, 92, 91, 89, 87, 85, 84, 82
0385 };
0386
0387 static const s16 hsv_green_x[] = {
0388 -124, -124, -125, -125, -125, -125, -125, -125,
0389 -125, -126, -126, -125, -125, -125, -125, -125,
0390 -125, -124, -124, -124, -123, -123, -122, -122,
0391 -121, -121, -120, -120, -119, -118, -117, -117,
0392 -116, -115, -114, -113, -112, -111, -110, -109,
0393 -108, -107, -105, -104, -103, -102, -100, -99,
0394 -98, -96, -95, -93, -92, -91, -89, -87,
0395 -86, -84, -83, -81, -79, -77, -76, -74,
0396 -72, -70, -69, -67, -65, -63, -61, -59,
0397 -57, -55, -53, -51, -49, -47, -45, -43,
0398 -41, -39, -37, -35, -33, -30, -28, -26,
0399 -24, -22, -20, -18, -15, -13, -11, -9,
0400 -7, -4, -2, 0, 1, 3, 6, 8,
0401 10, 12, 14, 17, 19, 21, 23, 25,
0402 27, 29, 32, 34, 36, 38, 40, 42,
0403 44, 46, 48, 50, 52, 54, 56, 58,
0404 60, 62, 64, 66, 68, 70, 71, 73,
0405 75, 77, 78, 80, 82, 83, 85, 87,
0406 88, 90, 91, 93, 94, 96, 97, 98,
0407 100, 101, 102, 104, 105, 106, 107, 108,
0408 109, 111, 112, 113, 113, 114, 115, 116,
0409 117, 118, 118, 119, 120, 120, 121, 122,
0410 122, 123, 123, 124, 124, 124, 125, 125,
0411 125, 125, 125, 125, 125, 126, 126, 125,
0412 125, 125, 125, 125, 125, 124, 124, 124,
0413 123, 123, 122, 122, 121, 121, 120, 120,
0414 119, 118, 117, 117, 116, 115, 114, 113,
0415 112, 111, 110, 109, 108, 107, 105, 104,
0416 103, 102, 100, 99, 98, 96, 95, 93,
0417 92, 91, 89, 87, 86, 84, 83, 81,
0418 79, 77, 76, 74, 72, 70, 69, 67,
0419 65, 63, 61, 59, 57, 55, 53, 51,
0420 49, 47, 45, 43, 41, 39, 37, 35,
0421 33, 30, 28, 26, 24, 22, 20, 18,
0422 15, 13, 11, 9, 7, 4, 2, 0,
0423 -1, -3, -6, -8, -10, -12, -14, -17,
0424 -19, -21, -23, -25, -27, -29, -32, -34,
0425 -36, -38, -40, -42, -44, -46, -48, -50,
0426 -52, -54, -56, -58, -60, -62, -64, -66,
0427 -68, -70, -71, -73, -75, -77, -78, -80,
0428 -82, -83, -85, -87, -88, -90, -91, -93,
0429 -94, -96, -97, -98, -100, -101, -102, -104,
0430 -105, -106, -107, -108, -109, -111, -112, -113,
0431 -113, -114, -115, -116, -117, -118, -118, -119,
0432 -120, -120, -121, -122, -122, -123, -123, -124, -124
0433 };
0434
0435 static const s16 hsv_green_y[] = {
0436 -100, -99, -98, -97, -95, -94, -93, -91,
0437 -90, -89, -87, -86, -84, -83, -81, -80,
0438 -78, -76, -75, -73, -71, -70, -68, -66,
0439 -64, -63, -61, -59, -57, -55, -53, -51,
0440 -49, -48, -46, -44, -42, -40, -38, -36,
0441 -34, -32, -30, -27, -25, -23, -21, -19,
0442 -17, -15, -13, -11, -9, -7, -4, -2,
0443 0, 1, 3, 5, 7, 9, 11, 14,
0444 16, 18, 20, 22, 24, 26, 28, 30,
0445 32, 34, 36, 38, 40, 42, 44, 46,
0446 48, 50, 52, 54, 56, 58, 59, 61,
0447 63, 65, 67, 68, 70, 72, 74, 75,
0448 77, 78, 80, 82, 83, 85, 86, 88,
0449 89, 90, 92, 93, 95, 96, 97, 98,
0450 100, 101, 102, 103, 104, 105, 106, 107,
0451 108, 109, 110, 111, 112, 112, 113, 114,
0452 115, 115, 116, 116, 117, 117, 118, 118,
0453 119, 119, 119, 120, 120, 120, 120, 120,
0454 121, 121, 121, 121, 121, 121, 120, 120,
0455 120, 120, 120, 119, 119, 119, 118, 118,
0456 117, 117, 116, 116, 115, 114, 114, 113,
0457 112, 111, 111, 110, 109, 108, 107, 106,
0458 105, 104, 103, 102, 100, 99, 98, 97,
0459 95, 94, 93, 91, 90, 89, 87, 86,
0460 84, 83, 81, 80, 78, 76, 75, 73,
0461 71, 70, 68, 66, 64, 63, 61, 59,
0462 57, 55, 53, 51, 49, 48, 46, 44,
0463 42, 40, 38, 36, 34, 32, 30, 27,
0464 25, 23, 21, 19, 17, 15, 13, 11,
0465 9, 7, 4, 2, 0, -1, -3, -5,
0466 -7, -9, -11, -14, -16, -18, -20, -22,
0467 -24, -26, -28, -30, -32, -34, -36, -38,
0468 -40, -42, -44, -46, -48, -50, -52, -54,
0469 -56, -58, -59, -61, -63, -65, -67, -68,
0470 -70, -72, -74, -75, -77, -78, -80, -82,
0471 -83, -85, -86, -88, -89, -90, -92, -93,
0472 -95, -96, -97, -98, -100, -101, -102, -103,
0473 -104, -105, -106, -107, -108, -109, -110, -111,
0474 -112, -112, -113, -114, -115, -115, -116, -116,
0475 -117, -117, -118, -118, -119, -119, -119, -120,
0476 -120, -120, -120, -120, -121, -121, -121, -121,
0477 -121, -121, -120, -120, -120, -120, -120, -119,
0478 -119, -119, -118, -118, -117, -117, -116, -116,
0479 -115, -114, -114, -113, -112, -111, -111, -110,
0480 -109, -108, -107, -106, -105, -104, -103, -102, -100
0481 };
0482
0483 static const s16 hsv_blue_x[] = {
0484 112, 113, 114, 114, 115, 116, 117, 117,
0485 118, 118, 119, 119, 120, 120, 120, 121,
0486 121, 121, 122, 122, 122, 122, 122, 122,
0487 122, 122, 122, 122, 122, 122, 121, 121,
0488 121, 120, 120, 120, 119, 119, 118, 118,
0489 117, 116, 116, 115, 114, 113, 113, 112,
0490 111, 110, 109, 108, 107, 106, 105, 104,
0491 103, 102, 100, 99, 98, 97, 95, 94,
0492 93, 91, 90, 88, 87, 85, 84, 82,
0493 80, 79, 77, 76, 74, 72, 70, 69,
0494 67, 65, 63, 61, 60, 58, 56, 54,
0495 52, 50, 48, 46, 44, 42, 40, 38,
0496 36, 34, 32, 30, 28, 26, 24, 22,
0497 19, 17, 15, 13, 11, 9, 7, 5,
0498 2, 0, -1, -3, -5, -7, -9, -12,
0499 -14, -16, -18, -20, -22, -24, -26, -28,
0500 -31, -33, -35, -37, -39, -41, -43, -45,
0501 -47, -49, -51, -53, -54, -56, -58, -60,
0502 -62, -64, -66, -67, -69, -71, -73, -74,
0503 -76, -78, -79, -81, -83, -84, -86, -87,
0504 -89, -90, -92, -93, -94, -96, -97, -98,
0505 -99, -101, -102, -103, -104, -105, -106, -107,
0506 -108, -109, -110, -111, -112, -113, -114, -114,
0507 -115, -116, -117, -117, -118, -118, -119, -119,
0508 -120, -120, -120, -121, -121, -121, -122, -122,
0509 -122, -122, -122, -122, -122, -122, -122, -122,
0510 -122, -122, -121, -121, -121, -120, -120, -120,
0511 -119, -119, -118, -118, -117, -116, -116, -115,
0512 -114, -113, -113, -112, -111, -110, -109, -108,
0513 -107, -106, -105, -104, -103, -102, -100, -99,
0514 -98, -97, -95, -94, -93, -91, -90, -88,
0515 -87, -85, -84, -82, -80, -79, -77, -76,
0516 -74, -72, -70, -69, -67, -65, -63, -61,
0517 -60, -58, -56, -54, -52, -50, -48, -46,
0518 -44, -42, -40, -38, -36, -34, -32, -30,
0519 -28, -26, -24, -22, -19, -17, -15, -13,
0520 -11, -9, -7, -5, -2, 0, 1, 3,
0521 5, 7, 9, 12, 14, 16, 18, 20,
0522 22, 24, 26, 28, 31, 33, 35, 37,
0523 39, 41, 43, 45, 47, 49, 51, 53,
0524 54, 56, 58, 60, 62, 64, 66, 67,
0525 69, 71, 73, 74, 76, 78, 79, 81,
0526 83, 84, 86, 87, 89, 90, 92, 93,
0527 94, 96, 97, 98, 99, 101, 102, 103,
0528 104, 105, 106, 107, 108, 109, 110, 111, 112
0529 };
0530
0531 static const s16 hsv_blue_y[] = {
0532 -11, -13, -15, -17, -19, -21, -23, -25,
0533 -27, -29, -31, -33, -35, -37, -39, -41,
0534 -43, -45, -46, -48, -50, -52, -54, -55,
0535 -57, -59, -61, -62, -64, -66, -67, -69,
0536 -71, -72, -74, -75, -77, -78, -80, -81,
0537 -83, -84, -86, -87, -88, -90, -91, -92,
0538 -93, -95, -96, -97, -98, -99, -100, -101,
0539 -102, -103, -104, -105, -106, -106, -107, -108,
0540 -109, -109, -110, -111, -111, -112, -112, -113,
0541 -113, -114, -114, -114, -115, -115, -115, -115,
0542 -116, -116, -116, -116, -116, -116, -116, -116,
0543 -116, -115, -115, -115, -115, -114, -114, -114,
0544 -113, -113, -112, -112, -111, -111, -110, -110,
0545 -109, -108, -108, -107, -106, -105, -104, -103,
0546 -102, -101, -100, -99, -98, -97, -96, -95,
0547 -94, -93, -91, -90, -89, -88, -86, -85,
0548 -84, -82, -81, -79, -78, -76, -75, -73,
0549 -71, -70, -68, -67, -65, -63, -62, -60,
0550 -58, -56, -55, -53, -51, -49, -47, -45,
0551 -44, -42, -40, -38, -36, -34, -32, -30,
0552 -28, -26, -24, -22, -20, -18, -16, -14,
0553 -12, -10, -8, -6, -4, -2, 0, 1,
0554 3, 5, 7, 9, 11, 13, 15, 17,
0555 19, 21, 23, 25, 27, 29, 31, 33,
0556 35, 37, 39, 41, 43, 45, 46, 48,
0557 50, 52, 54, 55, 57, 59, 61, 62,
0558 64, 66, 67, 69, 71, 72, 74, 75,
0559 77, 78, 80, 81, 83, 84, 86, 87,
0560 88, 90, 91, 92, 93, 95, 96, 97,
0561 98, 99, 100, 101, 102, 103, 104, 105,
0562 106, 106, 107, 108, 109, 109, 110, 111,
0563 111, 112, 112, 113, 113, 114, 114, 114,
0564 115, 115, 115, 115, 116, 116, 116, 116,
0565 116, 116, 116, 116, 116, 115, 115, 115,
0566 115, 114, 114, 114, 113, 113, 112, 112,
0567 111, 111, 110, 110, 109, 108, 108, 107,
0568 106, 105, 104, 103, 102, 101, 100, 99,
0569 98, 97, 96, 95, 94, 93, 91, 90,
0570 89, 88, 86, 85, 84, 82, 81, 79,
0571 78, 76, 75, 73, 71, 70, 68, 67,
0572 65, 63, 62, 60, 58, 56, 55, 53,
0573 51, 49, 47, 45, 44, 42, 40, 38,
0574 36, 34, 32, 30, 28, 26, 24, 22,
0575 20, 18, 16, 14, 12, 10, 8, 6,
0576 4, 2, 0, -1, -3, -5, -7, -9, -11
0577 };
0578
0579 static const u16 bridge_init[][2] = {
0580 {0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
0581 {0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
0582 {0x1068, 0x30}, {0x1069, 0x20}, {0x106a, 0x10},
0583 {0x106b, 0x08}, {0x1188, 0x87}, {0x11a1, 0x00},
0584 {0x11a2, 0x00}, {0x11a3, 0x6a}, {0x11a4, 0x50},
0585 {0x11ab, 0x00}, {0x11ac, 0x00}, {0x11ad, 0x50},
0586 {0x11ae, 0x3c}, {0x118a, 0x04}, {0x0395, 0x04},
0587 {0x11b8, 0x3a}, {0x118b, 0x0e}, {0x10f7, 0x05},
0588 {0x10f8, 0x14}, {0x10fa, 0xff}, {0x10f9, 0x00},
0589 {0x11ba, 0x0a}, {0x11a5, 0x2d}, {0x11a6, 0x2d},
0590 {0x11a7, 0x3a}, {0x11a8, 0x05}, {0x11a9, 0x04},
0591 {0x11aa, 0x3f}, {0x11af, 0x28}, {0x11b0, 0xd8},
0592 {0x11b1, 0x14}, {0x11b2, 0xec}, {0x11b3, 0x32},
0593 {0x11b4, 0xdd}, {0x11b5, 0x32}, {0x11b6, 0xdd},
0594 {0x10e0, 0x2c}, {0x11bc, 0x40}, {0x11bd, 0x01},
0595 {0x11be, 0xf0}, {0x11bf, 0x00}, {0x118c, 0x1f},
0596 {0x118d, 0x1f}, {0x118e, 0x1f}, {0x118f, 0x1f},
0597 {0x1180, 0x01}, {0x1181, 0x00}, {0x1182, 0x01},
0598 {0x1183, 0x00}, {0x1184, 0x50}, {0x1185, 0x80},
0599 {0x1007, 0x00}
0600 };
0601
0602
0603 static const u8 ov_gain[] = {
0604 0x00 , 0x04 , 0x08 , 0x0c ,
0605 0x10 , 0x12 , 0x14 , 0x16 ,
0606 0x18 , 0x1a , 0x1c , 0x1e ,
0607 0x30 , 0x31 , 0x32 , 0x33 ,
0608 0x34 , 0x35 , 0x36 , 0x37 ,
0609 0x38 , 0x39 , 0x3a , 0x3b ,
0610 0x3c , 0x3d , 0x3e , 0x3f ,
0611 0x70
0612 };
0613
0614
0615 static const u16 micron1_gain[] = {
0616
0617 0x0020, 0x0028, 0x0030, 0x0038,
0618
0619 0x00a0, 0x00a4, 0x00a8, 0x00ac,
0620
0621 0x00b0, 0x00b4, 0x00b8, 0x00bc,
0622
0623 0x00c0, 0x00c4, 0x00c8, 0x00cc,
0624
0625 0x00d0, 0x00d4, 0x00d8, 0x00dc,
0626
0627 0x00e0, 0x00e4, 0x00e8, 0x00ec,
0628
0629 0x00f0, 0x00f4, 0x00f8, 0x00fc,
0630
0631 0x01c0
0632 };
0633
0634
0635
0636 static const u16 micron2_gain[] = {
0637
0638 0x0008, 0x000a, 0x000c, 0x000e,
0639
0640 0x0010, 0x0012, 0x0014, 0x0016,
0641
0642 0x0018, 0x001a, 0x001c, 0x001e,
0643
0644 0x0020, 0x0051, 0x0052, 0x0053,
0645
0646 0x0054, 0x0055, 0x0056, 0x0057,
0647
0648 0x0058, 0x0059, 0x005a, 0x005b,
0649
0650 0x005c, 0x005d, 0x005e, 0x005f,
0651
0652 0x0060
0653 };
0654
0655
0656 static const u8 hv7131r_gain[] = {
0657 0x08 , 0x0c , 0x10 , 0x14 ,
0658 0x18 , 0x1c , 0x20 , 0x24 ,
0659 0x28 , 0x2c , 0x30 , 0x34 ,
0660 0x38 , 0x3c , 0x40 , 0x44 ,
0661 0x48 , 0x4c , 0x50 , 0x54 ,
0662 0x58 , 0x5c , 0x60 , 0x64 ,
0663 0x68 , 0x6c , 0x70 , 0x74 ,
0664 0x78
0665 };
0666
0667 static const struct i2c_reg_u8 soi968_init[] = {
0668 {0x0c, 0x00}, {0x0f, 0x1f},
0669 {0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
0670 {0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
0671 {0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
0672 {0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
0673 {0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
0674 {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
0675 {0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
0676 {0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
0677 {0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
0678 {0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
0679 };
0680
0681 static const struct i2c_reg_u8 ov7660_init[] = {
0682 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
0683 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
0684 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
0685
0686
0687 {0x17, 0x10}, {0x18, 0x61},
0688 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
0689 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
0690 {0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
0691 };
0692
0693 static const struct i2c_reg_u8 ov7670_init[] = {
0694 {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
0695 {0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
0696 {0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
0697 {0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
0698 {0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
0699 {0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
0700 {0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
0701 {0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
0702 {0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
0703 {0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
0704 {0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
0705 {0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
0706 {0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
0707 {0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
0708 {0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
0709 {0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
0710 {0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
0711 {0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
0712 {0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
0713 {0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
0714 {0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
0715 {0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
0716 {0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
0717 {0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
0718 {0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
0719 {0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
0720 {0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
0721 {0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
0722 {0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
0723 {0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
0724 {0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
0725 {0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
0726 {0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
0727 {0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
0728 {0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
0729 {0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
0730 {0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
0731 {0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
0732 {0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
0733 {0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
0734 {0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
0735 {0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
0736 {0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
0737 {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
0738 {0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
0739 {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
0740 {0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
0741 {0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
0742 {0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
0743 {0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
0744 {0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
0745 {0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
0746 {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
0747 {0x93, 0x00},
0748 };
0749
0750 static const struct i2c_reg_u8 ov9650_init[] = {
0751 {0x00, 0x00}, {0x01, 0x78},
0752 {0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
0753 {0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
0754 {0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
0755 {0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
0756 {0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
0757 {0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
0758 {0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
0759 {0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
0760 {0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
0761 {0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
0762 {0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
0763 {0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
0764 {0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
0765 {0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
0766 {0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
0767 {0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
0768 {0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
0769 {0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
0770 {0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
0771 {0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
0772 {0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
0773 {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
0774 {0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
0775 {0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
0776 {0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
0777 {0xaa, 0x92}, {0xab, 0x0a},
0778 };
0779
0780 static const struct i2c_reg_u8 ov9655_init[] = {
0781 {0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
0782 {0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
0783 {0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
0784 {0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
0785 {0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
0786 {0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
0787 {0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
0788 {0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
0789 {0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
0790 {0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
0791 {0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
0792 {0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
0793 {0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
0794 {0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
0795 {0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
0796 {0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
0797 {0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
0798 {0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
0799 {0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
0800 {0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
0801 {0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
0802 {0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
0803 {0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
0804 {0x04, 0x03}, {0x00, 0x13},
0805 };
0806
0807 static const struct i2c_reg_u16 mt9v112_init[] = {
0808 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
0809 {0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
0810 {0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
0811 {0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
0812 {0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
0813 {0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
0814 {0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
0815 {0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
0816 {0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
0817 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
0818 {0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
0819 {0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
0820 {0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
0821 {0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
0822 {0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
0823 {0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
0824 };
0825
0826 static const struct i2c_reg_u16 mt9v111_init[] = {
0827 {0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
0828 {0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
0829 {0x2e, 0x0c64}, {0x2f, 0x0064}, {0x06, 0x600e},
0830 {0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
0831 {0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
0832 {0x06, 0x002d}, {0x07, 0x3002}, {0x08, 0x0008},
0833 {0x0e, 0x0008}, {0x20, 0x0000}
0834 };
0835
0836 static const struct i2c_reg_u16 mt9v011_init[] = {
0837 {0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
0838 {0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
0839 {0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
0840 {0x0d, 0x0002}, {0x0a, 0x0000}, {0x0b, 0x0000},
0841 {0x0c, 0x0000}, {0x0d, 0x0000}, {0x0e, 0x0000},
0842 {0x0f, 0x0000}, {0x10, 0x0000}, {0x11, 0x0000},
0843 {0x12, 0x0000}, {0x13, 0x0000}, {0x14, 0x0000},
0844 {0x15, 0x0000}, {0x16, 0x0000}, {0x17, 0x0000},
0845 {0x18, 0x0000}, {0x19, 0x0000}, {0x1a, 0x0000},
0846 {0x1b, 0x0000}, {0x1c, 0x0000}, {0x1d, 0x0000},
0847 {0x32, 0x0000}, {0x20, 0x1101}, {0x21, 0x0000},
0848 {0x22, 0x0000}, {0x23, 0x0000}, {0x24, 0x0000},
0849 {0x25, 0x0000}, {0x26, 0x0000}, {0x27, 0x0024},
0850 {0x2f, 0xf7b0}, {0x30, 0x0005}, {0x31, 0x0000},
0851 {0x32, 0x0000}, {0x33, 0x0000}, {0x34, 0x0100},
0852 {0x3d, 0x068f}, {0x40, 0x01e0}, {0x41, 0x00d1},
0853 {0x44, 0x0082}, {0x5a, 0x0000}, {0x5b, 0x0000},
0854 {0x5c, 0x0000}, {0x5d, 0x0000}, {0x5e, 0x0000},
0855 {0x5f, 0xa31d}, {0x62, 0x0611}, {0x0a, 0x0000},
0856 {0x06, 0x0029}, {0x05, 0x0009}, {0x20, 0x1101},
0857 {0x20, 0x1101}, {0x09, 0x0064}, {0x07, 0x0003},
0858 {0x2b, 0x0033}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
0859 {0x2e, 0x0033}, {0x07, 0x0002}, {0x06, 0x0000},
0860 {0x06, 0x0029}, {0x05, 0x0009},
0861 };
0862
0863 static const struct i2c_reg_u16 mt9m001_init[] = {
0864 {0x0d, 0x0001},
0865 {0x0d, 0x0000},
0866 {0x04, 0x0500},
0867 {0x03, 0x0400},
0868 {0x20, 0x1100},
0869 {0x06, 0x0010},
0870 {0x2b, 0x0024},
0871 {0x2e, 0x0024},
0872 {0x35, 0x0024},
0873 {0x2d, 0x0020},
0874 {0x2c, 0x0020},
0875 {0x09, 0x0ad4},
0876 {0x35, 0x0057},
0877 };
0878
0879 static const struct i2c_reg_u16 mt9m111_init[] = {
0880 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
0881 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
0882 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
0883 {0xf0, 0x0000},
0884 };
0885
0886 static const struct i2c_reg_u16 mt9m112_init[] = {
0887 {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
0888 {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
0889 {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
0890 {0xf0, 0x0000},
0891 };
0892
0893 static const struct i2c_reg_u8 hv7131r_init[] = {
0894 {0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
0895 {0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
0896 {0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
0897 {0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
0898 {0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
0899 {0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
0900 {0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
0901 {0x23, 0x09}, {0x01, 0x08},
0902 };
0903
0904 static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
0905 {
0906 struct usb_device *dev = gspca_dev->dev;
0907 int result;
0908
0909 if (gspca_dev->usb_err < 0)
0910 return;
0911 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
0912 0x00,
0913 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0914 reg,
0915 0x00,
0916 gspca_dev->usb_buf,
0917 length,
0918 500);
0919 if (unlikely(result < 0 || result != length)) {
0920 pr_err("Read register %02x failed %d\n", reg, result);
0921 gspca_dev->usb_err = result;
0922
0923
0924
0925
0926 memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
0927 }
0928 }
0929
0930 static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
0931 const u8 *buffer, int length)
0932 {
0933 struct usb_device *dev = gspca_dev->dev;
0934 int result;
0935
0936 if (gspca_dev->usb_err < 0)
0937 return;
0938 memcpy(gspca_dev->usb_buf, buffer, length);
0939 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0940 0x08,
0941 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0942 reg,
0943 0x00,
0944 gspca_dev->usb_buf,
0945 length,
0946 500);
0947 if (unlikely(result < 0 || result != length)) {
0948 pr_err("Write register %02x failed %d\n", reg, result);
0949 gspca_dev->usb_err = result;
0950 }
0951 }
0952
0953 static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
0954 {
0955 reg_w(gspca_dev, reg, &value, 1);
0956 }
0957
0958 static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
0959 {
0960 int i;
0961
0962 reg_w(gspca_dev, 0x10c0, buffer, 8);
0963 for (i = 0; i < 5; i++) {
0964 reg_r(gspca_dev, 0x10c0, 1);
0965 if (gspca_dev->usb_err < 0)
0966 return;
0967 if (gspca_dev->usb_buf[0] & 0x04) {
0968 if (gspca_dev->usb_buf[0] & 0x08) {
0969 pr_err("i2c_w error\n");
0970 gspca_dev->usb_err = -EIO;
0971 }
0972 return;
0973 }
0974 msleep(10);
0975 }
0976 pr_err("i2c_w reg %02x no response\n", buffer[2]);
0977
0978 }
0979
0980 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
0981 {
0982 struct sd *sd = (struct sd *) gspca_dev;
0983 u8 row[8];
0984
0985
0986
0987
0988
0989 row[0] = sd->i2c_intf | (2 << 4);
0990 row[1] = sd->i2c_addr;
0991 row[2] = reg;
0992 row[3] = val;
0993 row[4] = 0x00;
0994 row[5] = 0x00;
0995 row[6] = 0x00;
0996 row[7] = 0x10;
0997
0998 i2c_w(gspca_dev, row);
0999 }
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
1017
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);
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);
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);
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);
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);
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
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;
1457 exp[3] = expo2 >> 2;
1458 exp[7] = 0x10;
1459 i2c_w(gspca_dev, exp);
1460 exp[2] = 0x04;
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;
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;
1500
1501 switch (sd->sensor) {
1502 case SENSOR_OV7660:
1503 case SENSOR_OV7670:
1504 case SENSOR_SOI968:
1505 case SENSOR_OV9655:
1506 case SENSOR_OV9650:
1507 gain[0] |= (2 << 4);
1508 gain[3] = ov_gain[g];
1509 break;
1510 case SENSOR_MT9V011:
1511 gain[0] |= (3 << 4);
1512 gain[2] = 0x35;
1513 gain[3] = micron1_gain[g] >> 8;
1514 gain[4] = micron1_gain[g];
1515 break;
1516 case SENSOR_MT9V112:
1517 gain[0] |= (3 << 4);
1518 gain[2] = 0x2f;
1519 gain[3] = micron1_gain[g] >> 8;
1520 gain[4] = micron1_gain[g];
1521 break;
1522 case SENSOR_MT9M001:
1523 gain[0] |= (3 << 4);
1524 gain[2] = 0x2f;
1525 gain[3] = micron2_gain[g] >> 8;
1526 gain[4] = micron2_gain[g];
1527 break;
1528 case SENSOR_HV7131R:
1529 gain[0] |= (2 << 4);
1530 gain[2] = 0x30;
1531 gain[3] = hv7131r_gain[g];
1532 break;
1533 default:
1534 return;
1535 }
1536 i2c_w(gspca_dev, gain);
1537 }
1538
1539 static void set_led_mode(struct gspca_dev *gspca_dev, s32 val)
1540 {
1541 reg_w1(gspca_dev, 0x1007, 0x60);
1542 reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00);
1543 }
1544
1545 static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1546 {
1547 struct sd *sd = (struct sd *) gspca_dev;
1548
1549 jpeg_set_qual(sd->jpeg_hdr, val);
1550 reg_w1(gspca_dev, 0x1061, 0x01);
1551 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20);
1552 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1553 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1554 reg_w1(gspca_dev, 0x1061, 0x03);
1555 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1556 sd->fmt ^= 0x0c;
1557 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1558 }
1559
1560 #ifdef CONFIG_VIDEO_ADV_DEBUG
1561 static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1562 struct v4l2_dbg_register *reg)
1563 {
1564 struct sd *sd = (struct sd *) gspca_dev;
1565
1566 reg->size = 1;
1567 switch (reg->match.addr) {
1568 case 0:
1569 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1570 return -EINVAL;
1571 reg_r(gspca_dev, reg->reg, 1);
1572 reg->val = gspca_dev->usb_buf[0];
1573 return gspca_dev->usb_err;
1574 case 1:
1575 if (sd->sensor >= SENSOR_MT9V011 &&
1576 sd->sensor <= SENSOR_MT9M112) {
1577 i2c_r2(gspca_dev, reg->reg, (u16 *) ®->val);
1578 reg->size = 2;
1579 } else {
1580 i2c_r1(gspca_dev, reg->reg, (u8 *) ®->val);
1581 }
1582 return gspca_dev->usb_err;
1583 }
1584 return -EINVAL;
1585 }
1586
1587 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1588 const struct v4l2_dbg_register *reg)
1589 {
1590 struct sd *sd = (struct sd *) gspca_dev;
1591
1592 switch (reg->match.addr) {
1593 case 0:
1594 if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1595 return -EINVAL;
1596 reg_w1(gspca_dev, reg->reg, reg->val);
1597 return gspca_dev->usb_err;
1598 case 1:
1599 if (sd->sensor >= SENSOR_MT9V011 &&
1600 sd->sensor <= SENSOR_MT9M112) {
1601 i2c_w2(gspca_dev, reg->reg, reg->val);
1602 } else {
1603 i2c_w1(gspca_dev, reg->reg, reg->val);
1604 }
1605 return gspca_dev->usb_err;
1606 }
1607 return -EINVAL;
1608 }
1609
1610 static int sd_chip_info(struct gspca_dev *gspca_dev,
1611 struct v4l2_dbg_chip_info *chip)
1612 {
1613 if (chip->match.addr > 1)
1614 return -EINVAL;
1615 if (chip->match.addr == 1)
1616 strscpy(chip->name, "sensor", sizeof(chip->name));
1617 return 0;
1618 }
1619 #endif
1620
1621 static int sd_config(struct gspca_dev *gspca_dev,
1622 const struct usb_device_id *id)
1623 {
1624 struct sd *sd = (struct sd *) gspca_dev;
1625 struct cam *cam;
1626
1627 cam = &gspca_dev->cam;
1628 cam->needs_full_bandwidth = 1;
1629
1630 sd->sensor = id->driver_info >> 8;
1631 sd->i2c_addr = id->driver_info;
1632 sd->flags = id->driver_info >> 16;
1633 sd->i2c_intf = 0x80;
1634
1635 switch (sd->sensor) {
1636 case SENSOR_MT9M112:
1637 case SENSOR_MT9M111:
1638 case SENSOR_OV9650:
1639 case SENSOR_SOI968:
1640 cam->cam_mode = sxga_mode;
1641 cam->nmodes = ARRAY_SIZE(sxga_mode);
1642 break;
1643 case SENSOR_MT9M001:
1644 cam->cam_mode = mono_mode;
1645 cam->nmodes = ARRAY_SIZE(mono_mode);
1646 break;
1647 case SENSOR_HV7131R:
1648 sd->i2c_intf = 0x81;
1649 fallthrough;
1650 default:
1651 cam->cam_mode = vga_mode;
1652 cam->nmodes = ARRAY_SIZE(vga_mode);
1653 break;
1654 }
1655
1656 sd->old_step = 0;
1657 sd->older_step = 0;
1658 sd->exposure_step = 16;
1659
1660 INIT_WORK(&sd->work, qual_upd);
1661
1662 return 0;
1663 }
1664
1665 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1666 {
1667 struct gspca_dev *gspca_dev =
1668 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1669 struct sd *sd = (struct sd *)gspca_dev;
1670
1671 gspca_dev->usb_err = 0;
1672
1673 if (!gspca_dev->streaming)
1674 return 0;
1675
1676 switch (ctrl->id) {
1677
1678 case V4L2_CID_BRIGHTNESS:
1679 set_cmatrix(gspca_dev, sd->brightness->val,
1680 sd->contrast->val, sd->saturation->val, sd->hue->val);
1681 break;
1682 case V4L2_CID_GAMMA:
1683 set_gamma(gspca_dev, ctrl->val);
1684 break;
1685
1686 case V4L2_CID_BLUE_BALANCE:
1687 set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1688 break;
1689
1690 case V4L2_CID_HFLIP:
1691 set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1692 break;
1693
1694 case V4L2_CID_EXPOSURE:
1695 set_exposure(gspca_dev, ctrl->val);
1696 break;
1697
1698 case V4L2_CID_GAIN:
1699 set_gain(gspca_dev, ctrl->val);
1700 break;
1701
1702 case V4L2_CID_AUTOGAIN:
1703 if (sd->sensor == SENSOR_SOI968)
1704 set_gain(gspca_dev, sd->gain->val);
1705 else
1706 set_exposure(gspca_dev, sd->exposure->val);
1707 break;
1708 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1709 set_quality(gspca_dev, ctrl->val);
1710 break;
1711 case V4L2_CID_FLASH_LED_MODE:
1712 set_led_mode(gspca_dev, ctrl->val);
1713 break;
1714 }
1715 return gspca_dev->usb_err;
1716 }
1717
1718 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1719 .s_ctrl = sd_s_ctrl,
1720 };
1721
1722 static int sd_init_controls(struct gspca_dev *gspca_dev)
1723 {
1724 struct sd *sd = (struct sd *) gspca_dev;
1725 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1726
1727 gspca_dev->vdev.ctrl_handler = hdl;
1728 v4l2_ctrl_handler_init(hdl, 13);
1729
1730 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1731 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1732 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733 V4L2_CID_CONTRAST, 0, 255, 1, 127);
1734 sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735 V4L2_CID_SATURATION, 0, 255, 1, 127);
1736 sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737 V4L2_CID_HUE, -180, 180, 1, 0);
1738
1739 sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740 V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1741
1742 sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1744 sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745 V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1746
1747 if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1748 sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1749 sd->sensor != SENSOR_MT9VPRB) {
1750 sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1751 V4L2_CID_HFLIP, 0, 1, 1, 0);
1752 sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753 V4L2_CID_VFLIP, 0, 1, 1, 0);
1754 }
1755
1756 if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1757 sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1758 sd->sensor != SENSOR_MT9V111)
1759 sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1760 V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1761
1762 if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1763 sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1764 sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1765 V4L2_CID_GAIN, 0, 28, 1, 0);
1766 sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1768 }
1769
1770 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1771 V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1772
1773 if (sd->flags & HAS_LED_TORCH)
1774 sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1775 V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH,
1776 ~0x5, V4L2_FLASH_LED_MODE_NONE);
1777
1778 if (hdl->error) {
1779 pr_err("Could not initialize controls\n");
1780 return hdl->error;
1781 }
1782
1783 v4l2_ctrl_cluster(4, &sd->brightness);
1784 v4l2_ctrl_cluster(2, &sd->blue);
1785 if (sd->hflip)
1786 v4l2_ctrl_cluster(2, &sd->hflip);
1787 if (sd->autogain) {
1788 if (sd->sensor == SENSOR_SOI968)
1789
1790
1791
1792 v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1793 else
1794
1795 v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1796 }
1797 return 0;
1798 }
1799
1800 static int sd_init(struct gspca_dev *gspca_dev)
1801 {
1802 struct sd *sd = (struct sd *) gspca_dev;
1803 int i;
1804 u8 value;
1805 u8 i2c_init[9] = {
1806 0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1807 };
1808
1809 for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1810 value = bridge_init[i][1];
1811 reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1812 if (gspca_dev->usb_err < 0) {
1813 pr_err("Device initialization failed\n");
1814 return gspca_dev->usb_err;
1815 }
1816 }
1817
1818 if (sd->flags & LED_REVERSE)
1819 reg_w1(gspca_dev, 0x1006, 0x00);
1820 else
1821 reg_w1(gspca_dev, 0x1006, 0x20);
1822
1823 reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1824 if (gspca_dev->usb_err < 0) {
1825 pr_err("Device initialization failed\n");
1826 return gspca_dev->usb_err;
1827 }
1828
1829 switch (sd->sensor) {
1830 case SENSOR_OV9650:
1831 ov9650_init_sensor(gspca_dev);
1832 if (gspca_dev->usb_err < 0)
1833 break;
1834 pr_info("OV9650 sensor detected\n");
1835 break;
1836 case SENSOR_OV9655:
1837 ov9655_init_sensor(gspca_dev);
1838 if (gspca_dev->usb_err < 0)
1839 break;
1840 pr_info("OV9655 sensor detected\n");
1841 break;
1842 case SENSOR_SOI968:
1843 soi968_init_sensor(gspca_dev);
1844 if (gspca_dev->usb_err < 0)
1845 break;
1846 pr_info("SOI968 sensor detected\n");
1847 break;
1848 case SENSOR_OV7660:
1849 ov7660_init_sensor(gspca_dev);
1850 if (gspca_dev->usb_err < 0)
1851 break;
1852 pr_info("OV7660 sensor detected\n");
1853 break;
1854 case SENSOR_OV7670:
1855 ov7670_init_sensor(gspca_dev);
1856 if (gspca_dev->usb_err < 0)
1857 break;
1858 pr_info("OV7670 sensor detected\n");
1859 break;
1860 case SENSOR_MT9VPRB:
1861 mt9v_init_sensor(gspca_dev);
1862 if (gspca_dev->usb_err < 0)
1863 break;
1864 pr_info("MT9VPRB sensor detected\n");
1865 break;
1866 case SENSOR_MT9M111:
1867 mt9m111_init_sensor(gspca_dev);
1868 if (gspca_dev->usb_err < 0)
1869 break;
1870 pr_info("MT9M111 sensor detected\n");
1871 break;
1872 case SENSOR_MT9M112:
1873 mt9m112_init_sensor(gspca_dev);
1874 if (gspca_dev->usb_err < 0)
1875 break;
1876 pr_info("MT9M112 sensor detected\n");
1877 break;
1878 case SENSOR_MT9M001:
1879 mt9m001_init_sensor(gspca_dev);
1880 if (gspca_dev->usb_err < 0)
1881 break;
1882 break;
1883 case SENSOR_HV7131R:
1884 hv7131r_init_sensor(gspca_dev);
1885 if (gspca_dev->usb_err < 0)
1886 break;
1887 pr_info("HV7131R sensor detected\n");
1888 break;
1889 default:
1890 pr_err("Unsupported sensor\n");
1891 gspca_dev->usb_err = -ENODEV;
1892 }
1893 return gspca_dev->usb_err;
1894 }
1895
1896 static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1897 {
1898 struct sd *sd = (struct sd *) gspca_dev;
1899 u8 value;
1900
1901 switch (sd->sensor) {
1902 case SENSOR_SOI968:
1903 if (mode & MODE_SXGA) {
1904 i2c_w1(gspca_dev, 0x17, 0x1d);
1905 i2c_w1(gspca_dev, 0x18, 0xbd);
1906 i2c_w1(gspca_dev, 0x19, 0x01);
1907 i2c_w1(gspca_dev, 0x1a, 0x81);
1908 i2c_w1(gspca_dev, 0x12, 0x00);
1909 sd->hstart = 140;
1910 sd->vstart = 19;
1911 } else {
1912 i2c_w1(gspca_dev, 0x17, 0x13);
1913 i2c_w1(gspca_dev, 0x18, 0x63);
1914 i2c_w1(gspca_dev, 0x19, 0x01);
1915 i2c_w1(gspca_dev, 0x1a, 0x79);
1916 i2c_w1(gspca_dev, 0x12, 0x40);
1917 sd->hstart = 60;
1918 sd->vstart = 11;
1919 }
1920 break;
1921 case SENSOR_OV9650:
1922 if (mode & MODE_SXGA) {
1923 i2c_w1(gspca_dev, 0x17, 0x1b);
1924 i2c_w1(gspca_dev, 0x18, 0xbc);
1925 i2c_w1(gspca_dev, 0x19, 0x01);
1926 i2c_w1(gspca_dev, 0x1a, 0x82);
1927 i2c_r1(gspca_dev, 0x12, &value);
1928 i2c_w1(gspca_dev, 0x12, value & 0x07);
1929 } else {
1930 i2c_w1(gspca_dev, 0x17, 0x24);
1931 i2c_w1(gspca_dev, 0x18, 0xc5);
1932 i2c_w1(gspca_dev, 0x19, 0x00);
1933 i2c_w1(gspca_dev, 0x1a, 0x3c);
1934 i2c_r1(gspca_dev, 0x12, &value);
1935 i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1936 }
1937 break;
1938 case SENSOR_MT9M112:
1939 case SENSOR_MT9M111:
1940 if (mode & MODE_SXGA) {
1941 i2c_w2(gspca_dev, 0xf0, 0x0002);
1942 i2c_w2(gspca_dev, 0xc8, 0x970b);
1943 i2c_w2(gspca_dev, 0xf0, 0x0000);
1944 } else {
1945 i2c_w2(gspca_dev, 0xf0, 0x0002);
1946 i2c_w2(gspca_dev, 0xc8, 0x8000);
1947 i2c_w2(gspca_dev, 0xf0, 0x0000);
1948 }
1949 break;
1950 }
1951 }
1952
1953 static int sd_isoc_init(struct gspca_dev *gspca_dev)
1954 {
1955 struct usb_interface *intf;
1956 u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1957
1958
1959
1960
1961
1962
1963 if (!(flags & (MODE_RAW | MODE_JPEG))) {
1964 intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1965
1966 if (intf->num_altsetting != 9) {
1967 pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1968 intf->num_altsetting);
1969 gspca_dev->alt = intf->num_altsetting;
1970 return 0;
1971 }
1972
1973 switch (gspca_dev->pixfmt.width) {
1974 case 160:
1975 gspca_dev->alt = 2;
1976 break;
1977 case 320:
1978 gspca_dev->alt = 6;
1979 break;
1980 default:
1981 gspca_dev->alt = 9;
1982 break;
1983 }
1984 }
1985
1986 return 0;
1987 }
1988
1989 #define HW_WIN(mode, hstart, vstart) \
1990 ((const u8 []){hstart, 0, vstart, 0, \
1991 (mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1992 (mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1993
1994 #define CLR_WIN(width, height) \
1995 ((const u8 [])\
1996 {0, width >> 2, 0, height >> 1,\
1997 ((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1998
1999 static int sd_start(struct gspca_dev *gspca_dev)
2000 {
2001 struct sd *sd = (struct sd *) gspca_dev;
2002 int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2003 int width = gspca_dev->pixfmt.width;
2004 int height = gspca_dev->pixfmt.height;
2005 u8 fmt, scale = 0;
2006
2007 jpeg_define(sd->jpeg_hdr, height, width,
2008 0x21);
2009 jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2010
2011 if (mode & MODE_RAW)
2012 fmt = 0x2d;
2013 else if (mode & MODE_JPEG)
2014 fmt = 0x24;
2015 else
2016 fmt = 0x2f;
2017 sd->fmt = fmt;
2018
2019 switch (mode & SCALE_MASK) {
2020 case SCALE_1280x1024:
2021 scale = 0xc0;
2022 pr_info("Set 1280x1024\n");
2023 break;
2024 case SCALE_640x480:
2025 scale = 0x80;
2026 pr_info("Set 640x480\n");
2027 break;
2028 case SCALE_320x240:
2029 scale = 0x90;
2030 pr_info("Set 320x240\n");
2031 break;
2032 case SCALE_160x120:
2033 scale = 0xa0;
2034 pr_info("Set 160x120\n");
2035 break;
2036 }
2037
2038 configure_sensor_output(gspca_dev, mode);
2039 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2040 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2041 reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2042 reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2043 reg_w1(gspca_dev, 0x1189, scale);
2044 reg_w1(gspca_dev, 0x10e0, fmt);
2045
2046 set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2047 v4l2_ctrl_g_ctrl(sd->contrast),
2048 v4l2_ctrl_g_ctrl(sd->saturation),
2049 v4l2_ctrl_g_ctrl(sd->hue));
2050 set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2051 set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2052 v4l2_ctrl_g_ctrl(sd->red));
2053 if (sd->gain)
2054 set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2055 if (sd->exposure)
2056 set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2057 if (sd->hflip)
2058 set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2059 v4l2_ctrl_g_ctrl(sd->vflip));
2060
2061 reg_w1(gspca_dev, 0x1007, 0x20);
2062 reg_w1(gspca_dev, 0x1061, 0x03);
2063
2064
2065 if (mode & MODE_JPEG) {
2066 sd->pktsz = sd->npkt = 0;
2067 sd->nchg = 0;
2068 }
2069 if (sd->led_mode)
2070 v4l2_ctrl_s_ctrl(sd->led_mode, 0);
2071
2072 return gspca_dev->usb_err;
2073 }
2074
2075 static void sd_stopN(struct gspca_dev *gspca_dev)
2076 {
2077 reg_w1(gspca_dev, 0x1007, 0x00);
2078 reg_w1(gspca_dev, 0x1061, 0x01);
2079 }
2080
2081
2082
2083 static void sd_stop0(struct gspca_dev *gspca_dev)
2084 {
2085 struct sd *sd = (struct sd *) gspca_dev;
2086
2087 mutex_unlock(&gspca_dev->usb_lock);
2088 flush_work(&sd->work);
2089 mutex_lock(&gspca_dev->usb_lock);
2090 }
2091
2092 static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2093 {
2094 struct sd *sd = (struct sd *) gspca_dev;
2095 s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2096 s32 max = sd->exposure->maximum - sd->exposure_step;
2097 s32 min = sd->exposure->minimum + sd->exposure_step;
2098 s16 new_exp;
2099
2100
2101
2102
2103
2104
2105 if (avg_lum < MIN_AVG_LUM) {
2106 if (cur_exp > max)
2107 return;
2108
2109 new_exp = cur_exp + sd->exposure_step;
2110 if (new_exp > max)
2111 new_exp = max;
2112 if (new_exp < min)
2113 new_exp = min;
2114 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2115
2116 sd->older_step = sd->old_step;
2117 sd->old_step = 1;
2118
2119 if (sd->old_step ^ sd->older_step)
2120 sd->exposure_step /= 2;
2121 else
2122 sd->exposure_step += 2;
2123 }
2124 if (avg_lum > MAX_AVG_LUM) {
2125 if (cur_exp < min)
2126 return;
2127 new_exp = cur_exp - sd->exposure_step;
2128 if (new_exp > max)
2129 new_exp = max;
2130 if (new_exp < min)
2131 new_exp = min;
2132 v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2133 sd->older_step = sd->old_step;
2134 sd->old_step = 0;
2135
2136 if (sd->old_step ^ sd->older_step)
2137 sd->exposure_step /= 2;
2138 else
2139 sd->exposure_step += 2;
2140 }
2141 }
2142
2143 static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2144 {
2145 struct sd *sd = (struct sd *) gspca_dev;
2146 s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2147
2148 if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2149 v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2150 if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2151 v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2152 }
2153
2154 static void sd_dqcallback(struct gspca_dev *gspca_dev)
2155 {
2156 struct sd *sd = (struct sd *) gspca_dev;
2157 int avg_lum;
2158
2159 if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2160 return;
2161
2162 avg_lum = atomic_read(&sd->avg_lum);
2163 if (sd->sensor == SENSOR_SOI968)
2164 do_autogain(gspca_dev, avg_lum);
2165 else
2166 do_autoexposure(gspca_dev, avg_lum);
2167 }
2168
2169
2170
2171 static void qual_upd(struct work_struct *work)
2172 {
2173 struct sd *sd = container_of(work, struct sd, work);
2174 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2175 s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2176
2177
2178 mutex_lock(&gspca_dev->usb_lock);
2179 gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2180 gspca_dev->usb_err = 0;
2181 set_quality(gspca_dev, qual);
2182 mutex_unlock(&gspca_dev->usb_lock);
2183 }
2184
2185 #if IS_ENABLED(CONFIG_INPUT)
2186 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2187 u8 *data,
2188 int len)
2189 {
2190 struct sd *sd = (struct sd *) gspca_dev;
2191
2192 if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2193 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2194 input_sync(gspca_dev->input_dev);
2195 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2196 input_sync(gspca_dev->input_dev);
2197 return 0;
2198 }
2199 return -EINVAL;
2200 }
2201 #endif
2202
2203
2204 static void transfer_check(struct gspca_dev *gspca_dev,
2205 u8 *data)
2206 {
2207 struct sd *sd = (struct sd *) gspca_dev;
2208 int new_qual, r;
2209
2210 new_qual = 0;
2211
2212
2213 if (data[6] & 0x08) {
2214 gspca_dev->last_packet_type = DISCARD_PACKET;
2215 new_qual = -5;
2216 } else {
2217
2218
2219 r = (sd->pktsz * 100) /
2220 (sd->npkt *
2221 gspca_dev->urb[0]->iso_frame_desc[0].length);
2222 if (r >= 85)
2223 new_qual = -3;
2224 else if (r < 75)
2225 new_qual = 2;
2226 }
2227 if (new_qual != 0) {
2228 sd->nchg += new_qual;
2229 if (sd->nchg < -6 || sd->nchg >= 12) {
2230
2231
2232
2233 s32 curqual = sd->jpegqual->cur.val;
2234 sd->nchg = 0;
2235 new_qual += curqual;
2236 if (new_qual < sd->jpegqual->minimum)
2237 new_qual = sd->jpegqual->minimum;
2238 else if (new_qual > sd->jpegqual->maximum)
2239 new_qual = sd->jpegqual->maximum;
2240 if (new_qual != curqual) {
2241 sd->jpegqual->cur.val = new_qual;
2242 schedule_work(&sd->work);
2243 }
2244 }
2245 } else {
2246 sd->nchg = 0;
2247 }
2248 sd->pktsz = sd->npkt = 0;
2249 }
2250
2251 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2252 u8 *data,
2253 int len)
2254 {
2255 struct sd *sd = (struct sd *) gspca_dev;
2256 int avg_lum, is_jpeg;
2257 static const u8 frame_header[] = {
2258 0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2259 };
2260
2261 is_jpeg = (sd->fmt & 0x03) == 0;
2262 if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2263 avg_lum = ((data[35] >> 2) & 3) |
2264 (data[20] << 2) |
2265 (data[19] << 10);
2266 avg_lum += ((data[35] >> 4) & 3) |
2267 (data[22] << 2) |
2268 (data[21] << 10);
2269 avg_lum += ((data[35] >> 6) & 3) |
2270 (data[24] << 2) |
2271 (data[23] << 10);
2272 avg_lum += (data[36] & 3) |
2273 (data[26] << 2) |
2274 (data[25] << 10);
2275 avg_lum += ((data[36] >> 2) & 3) |
2276 (data[28] << 2) |
2277 (data[27] << 10);
2278 avg_lum += ((data[36] >> 4) & 3) |
2279 (data[30] << 2) |
2280 (data[29] << 10);
2281 avg_lum += ((data[36] >> 6) & 3) |
2282 (data[32] << 2) |
2283 (data[31] << 10);
2284 avg_lum += ((data[44] >> 4) & 3) |
2285 (data[34] << 2) |
2286 (data[33] << 10);
2287 avg_lum >>= 9;
2288 atomic_set(&sd->avg_lum, avg_lum);
2289
2290 if (is_jpeg)
2291 transfer_check(gspca_dev, data);
2292
2293 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2294 len -= 64;
2295 if (len == 0)
2296 return;
2297 data += 64;
2298 }
2299 if (gspca_dev->last_packet_type == LAST_PACKET) {
2300 if (is_jpeg) {
2301 gspca_frame_add(gspca_dev, FIRST_PACKET,
2302 sd->jpeg_hdr, JPEG_HDR_SZ);
2303 gspca_frame_add(gspca_dev, INTER_PACKET,
2304 data, len);
2305 } else {
2306 gspca_frame_add(gspca_dev, FIRST_PACKET,
2307 data, len);
2308 }
2309 } else {
2310
2311 if (is_jpeg) {
2312 sd->npkt++;
2313 sd->pktsz += len;
2314 }
2315 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2316 }
2317 }
2318
2319
2320 static const struct sd_desc sd_desc = {
2321 .name = KBUILD_MODNAME,
2322 .config = sd_config,
2323 .init = sd_init,
2324 .init_controls = sd_init_controls,
2325 .isoc_init = sd_isoc_init,
2326 .start = sd_start,
2327 .stopN = sd_stopN,
2328 .stop0 = sd_stop0,
2329 .pkt_scan = sd_pkt_scan,
2330 #if IS_ENABLED(CONFIG_INPUT)
2331 .int_pkt_scan = sd_int_pkt_scan,
2332 #endif
2333 .dq_callback = sd_dqcallback,
2334 #ifdef CONFIG_VIDEO_ADV_DEBUG
2335 .set_register = sd_dbg_s_register,
2336 .get_register = sd_dbg_g_register,
2337 .get_chip_info = sd_chip_info,
2338 #endif
2339 };
2340
2341 #define SN9C20X(sensor, i2c_addr, flags) \
2342 .driver_info = ((flags & 0xff) << 16) \
2343 | (SENSOR_ ## sensor << 8) \
2344 | (i2c_addr)
2345
2346 static const struct usb_device_id device_table[] = {
2347 {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2348 {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)},
2349 {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2350 {USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2351 {USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2352 {USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2353 (FLIP_DETECT | HAS_NO_BUTTON))},
2354 {USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2359 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362 {USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363 {USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364 {USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2365 {USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366 {USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2370 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2371 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374 {USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375 {USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2376 {USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2377 {USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2378 {USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2379 {USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2380 {USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2381 {USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2382 {USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2383 {USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2384 {USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2385 {}
2386 };
2387 MODULE_DEVICE_TABLE(usb, device_table);
2388
2389
2390 static int sd_probe(struct usb_interface *intf,
2391 const struct usb_device_id *id)
2392 {
2393 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2394 THIS_MODULE);
2395 }
2396
2397 static struct usb_driver sd_driver = {
2398 .name = KBUILD_MODNAME,
2399 .id_table = device_table,
2400 .probe = sd_probe,
2401 .disconnect = gspca_disconnect,
2402 #ifdef CONFIG_PM
2403 .suspend = gspca_suspend,
2404 .resume = gspca_resume,
2405 .reset_resume = gspca_resume,
2406 #endif
2407 };
2408
2409 module_usb_driver(sd_driver);