1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Subdriver for the GL860 chip with the MI1320 sensor 3 * Author Olivier LORIN from own logs 4 */ 5 6 /* Sensor : MI1320 */ 7 8 #include "gl860.h" 9 10 static struct validx tbl_common[] = { 11 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1}, 12 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, 13 {0xffff, 0xffff}, 14 {0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1}, 15 {0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1}, 16 {0xba70, 0x0006}, {0xba0e, 0x00f1}, 17 {0xffff, 0xffff}, 18 {0xba74, 0x0006}, {0xba0e, 0x00f1}, 19 {0xffff, 0xffff}, 20 {0x0061, 0x0000}, {0x0068, 0x000d}, 21 }; 22 23 static struct validx tbl_init_at_startup[] = { 24 {0x0000, 0x0000}, {0x0010, 0x0010}, 25 {35, 0xffff}, 26 {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006}, 27 {0x006a, 0x000d}, 28 }; 29 30 static struct validx tbl_sensor_settings_common[] = { 31 {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000}, 32 {0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006}, 33 }; 34 static struct validx tbl_sensor_settings_1280[] = { 35 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1}, 36 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1}, 37 }; 38 static struct validx tbl_sensor_settings_800[] = { 39 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1}, 40 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1}, 41 }; 42 static struct validx tbl_sensor_settings_640[] = { 43 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, 44 {0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1}, 45 {0xba20, 0x0065}, {0xba00, 0x00f1}, 46 }; 47 static struct validx tbl_post_unset_alt[] = { 48 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1}, 49 {0x0061, 0x0000}, {0x0068, 0x000d}, 50 }; 51 52 static u8 *tbl_1280[] = { 53 (u8[]){ 54 0x0d, 0x80, 0xf1, 0x08, 0x03, 0x04, 0xf1, 0x00, 55 0x04, 0x05, 0xf1, 0x02, 0x05, 0x00, 0xf1, 0xf1, 56 0x06, 0x00, 0xf1, 0x0d, 0x20, 0x01, 0xf1, 0x00, 57 0x21, 0x84, 0xf1, 0x00, 0x0d, 0x00, 0xf1, 0x08, 58 0xf0, 0x00, 0xf1, 0x01, 0x34, 0x00, 0xf1, 0x00, 59 0x9b, 0x43, 0xf1, 0x00, 0xa6, 0x05, 0xf1, 0x00, 60 0xa9, 0x04, 0xf1, 0x00, 0xa1, 0x05, 0xf1, 0x00, 61 0xa4, 0x04, 0xf1, 0x00, 0xae, 0x0a, 0xf1, 0x08 62 }, (u8[]){ 63 0xf0, 0x00, 0xf1, 0x02, 0x3a, 0x05, 0xf1, 0xf1, 64 0x3c, 0x05, 0xf1, 0xf1, 0x59, 0x01, 0xf1, 0x47, 65 0x5a, 0x01, 0xf1, 0x88, 0x5c, 0x0a, 0xf1, 0x06, 66 0x5d, 0x0e, 0xf1, 0x0a, 0x64, 0x5e, 0xf1, 0x1c, 67 0xd2, 0x00, 0xf1, 0xcf, 0xcb, 0x00, 0xf1, 0x01 68 }, (u8[]){ 69 0xd3, 0x02, 0xd4, 0x28, 0xd5, 0x01, 0xd0, 0x02, 70 0xd1, 0x18, 0xd2, 0xc1 71 } 72 }; 73 74 static u8 *tbl_800[] = { 75 (u8[]){ 76 0x0d, 0x80, 0xf1, 0x08, 0x03, 0x03, 0xf1, 0xc0, 77 0x04, 0x05, 0xf1, 0x02, 0x05, 0x00, 0xf1, 0xf1, 78 0x06, 0x00, 0xf1, 0x0d, 0x20, 0x01, 0xf1, 0x00, 79 0x21, 0x84, 0xf1, 0x00, 0x0d, 0x00, 0xf1, 0x08, 80 0xf0, 0x00, 0xf1, 0x01, 0x34, 0x00, 0xf1, 0x00, 81 0x9b, 0x43, 0xf1, 0x00, 0xa6, 0x05, 0xf1, 0x00, 82 0xa9, 0x03, 0xf1, 0xc0, 0xa1, 0x03, 0xf1, 0x20, 83 0xa4, 0x02, 0xf1, 0x5a, 0xae, 0x0a, 0xf1, 0x08 84 }, (u8[]){ 85 0xf0, 0x00, 0xf1, 0x02, 0x3a, 0x05, 0xf1, 0xf1, 86 0x3c, 0x05, 0xf1, 0xf1, 0x59, 0x01, 0xf1, 0x47, 87 0x5a, 0x01, 0xf1, 0x88, 0x5c, 0x0a, 0xf1, 0x06, 88 0x5d, 0x0e, 0xf1, 0x0a, 0x64, 0x5e, 0xf1, 0x1c, 89 0xd2, 0x00, 0xf1, 0xcf, 0xcb, 0x00, 0xf1, 0x01 90 }, (u8[]){ 91 0xd3, 0x02, 0xd4, 0x18, 0xd5, 0x21, 0xd0, 0x02, 92 0xd1, 0x10, 0xd2, 0x59 93 } 94 }; 95 96 static u8 *tbl_640[] = { 97 (u8[]){ 98 0x0d, 0x80, 0xf1, 0x08, 0x03, 0x04, 0xf1, 0x04, 99 0x04, 0x05, 0xf1, 0x02, 0x07, 0x01, 0xf1, 0x7c, 100 0x08, 0x00, 0xf1, 0x0e, 0x21, 0x80, 0xf1, 0x00, 101 0x0d, 0x00, 0xf1, 0x08, 0xf0, 0x00, 0xf1, 0x01, 102 0x34, 0x10, 0xf1, 0x10, 0x3a, 0x43, 0xf1, 0x00, 103 0xa6, 0x05, 0xf1, 0x02, 0xa9, 0x04, 0xf1, 0x04, 104 0xa7, 0x02, 0xf1, 0x81, 0xaa, 0x01, 0xf1, 0xe2, 105 0xae, 0x0c, 0xf1, 0x09 106 }, (u8[]){ 107 0xf0, 0x00, 0xf1, 0x02, 0x39, 0x03, 0xf1, 0xfc, 108 0x3b, 0x04, 0xf1, 0x04, 0x57, 0x01, 0xf1, 0xb6, 109 0x58, 0x02, 0xf1, 0x0d, 0x5c, 0x1f, 0xf1, 0x19, 110 0x5d, 0x24, 0xf1, 0x1e, 0x64, 0x5e, 0xf1, 0x1c, 111 0xd2, 0x00, 0xf1, 0x00, 0xcb, 0x00, 0xf1, 0x01 112 }, (u8[]){ 113 0xd3, 0x02, 0xd4, 0x10, 0xd5, 0x81, 0xd0, 0x02, 114 0xd1, 0x08, 0xd2, 0xe1 115 } 116 }; 117 118 static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d}; 119 static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70}; 120 static s32 tbl_backlight[] = {0x0e, 0x06, 0x02}; 121 122 static s32 tbl_cntr1[] = { 123 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0}; 124 static s32 tbl_cntr2[] = { 125 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10}; 126 127 static u8 dat_wbalNL[] = 128 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10" 129 "\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20" 130 "\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00"; 131 132 static u8 dat_wbalLL[] = 133 "\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40" 134 "\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00" 135 "\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00"; 136 137 static u8 dat_wbalBL[] = 138 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae" 139 "\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20" 140 "\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00"; 141 142 static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00}; 143 144 static u8 dat_common00[] = 145 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42" 146 "\xd8\x04\x58\x00\x04\x02"; 147 static u8 dat_common01[] = 148 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d" 149 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0"; 150 static u8 dat_common02[] = 151 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e" 152 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00" 153 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff"; 154 static u8 dat_common03[] = 155 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda" 156 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c" 157 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c"; 158 static u8 dat_common04[] = 159 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43"; 160 static u8 dat_common05[] = 161 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68" 162 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82" 163 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b"; 164 static u8 dat_common06[] = 165 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06" 166 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4" 167 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f"; 168 static u8 dat_common07[] = 169 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72" 170 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03" 171 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea" 172 "\xe1\xff\xf1\x00"; 173 static u8 dat_common08[] = 174 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7" 175 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06" 176 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a"; 177 static u8 dat_common09[] = 178 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03" 179 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa" 180 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14"; 181 static u8 dat_common10[] = 182 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00" 183 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f" 184 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01" 185 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10"; 186 static u8 dat_common11[] = 187 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10" 188 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00" 189 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81"; 190 191 static int mi1320_init_at_startup(struct gspca_dev *gspca_dev); 192 static int mi1320_configure_alt(struct gspca_dev *gspca_dev); 193 static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev); 194 static int mi1320_init_post_alt(struct gspca_dev *gspca_dev); 195 static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev); 196 static int mi1320_sensor_settings(struct gspca_dev *gspca_dev); 197 static int mi1320_camera_settings(struct gspca_dev *gspca_dev); 198 /*==========================================================================*/ 199 200 void mi1320_init_settings(struct gspca_dev *gspca_dev) 201 { 202 struct sd *sd = (struct sd *) gspca_dev; 203 204 sd->vcur.backlight = 0; 205 sd->vcur.brightness = 0; 206 sd->vcur.sharpness = 6; 207 sd->vcur.contrast = 10; 208 sd->vcur.gamma = 20; 209 sd->vcur.hue = 0; 210 sd->vcur.saturation = 6; 211 sd->vcur.whitebal = 0; 212 sd->vcur.mirror = 0; 213 sd->vcur.flip = 0; 214 sd->vcur.AC50Hz = 1; 215 216 sd->vmax.backlight = 2; 217 sd->vmax.brightness = 8; 218 sd->vmax.sharpness = 7; 219 sd->vmax.contrast = 0; /* 10 but not working with this driver */ 220 sd->vmax.gamma = 40; 221 sd->vmax.hue = 5 + 1; 222 sd->vmax.saturation = 8; 223 sd->vmax.whitebal = 2; 224 sd->vmax.mirror = 1; 225 sd->vmax.flip = 1; 226 sd->vmax.AC50Hz = 1; 227 228 sd->dev_camera_settings = mi1320_camera_settings; 229 sd->dev_init_at_startup = mi1320_init_at_startup; 230 sd->dev_configure_alt = mi1320_configure_alt; 231 sd->dev_init_pre_alt = mi1320_init_pre_alt; 232 sd->dev_post_unset_alt = mi1320_post_unset_alt; 233 } 234 235 /*==========================================================================*/ 236 237 static void common(struct gspca_dev *gspca_dev) 238 { 239 s32 n; /* reserved for FETCH functions */ 240 241 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, dat_common00); 242 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL); 243 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, dat_common01); 244 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common)); 245 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common02); 246 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common03); 247 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, dat_common04); 248 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common05); 249 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, dat_common06); 250 keep_on_fetching_validx(gspca_dev, tbl_common, 251 ARRAY_SIZE(tbl_common), n); 252 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, dat_common07); 253 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common08); 254 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, dat_common09); 255 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, dat_common10); 256 keep_on_fetching_validx(gspca_dev, tbl_common, 257 ARRAY_SIZE(tbl_common), n); 258 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, dat_common11); 259 keep_on_fetching_validx(gspca_dev, tbl_common, 260 ARRAY_SIZE(tbl_common), n); 261 } 262 263 static int mi1320_init_at_startup(struct gspca_dev *gspca_dev) 264 { 265 fetch_validx(gspca_dev, tbl_init_at_startup, 266 ARRAY_SIZE(tbl_init_at_startup)); 267 268 common(gspca_dev); 269 270 /* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */ 271 272 return 0; 273 } 274 275 static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev) 276 { 277 struct sd *sd = (struct sd *) gspca_dev; 278 279 sd->mirrorMask = 0; 280 281 sd->vold.backlight = -1; 282 sd->vold.brightness = -1; 283 sd->vold.sharpness = -1; 284 sd->vold.contrast = -1; 285 sd->vold.saturation = -1; 286 sd->vold.gamma = -1; 287 sd->vold.hue = -1; 288 sd->vold.whitebal = -1; 289 sd->vold.mirror = -1; 290 sd->vold.flip = -1; 291 sd->vold.AC50Hz = -1; 292 293 common(gspca_dev); 294 295 mi1320_sensor_settings(gspca_dev); 296 297 mi1320_init_post_alt(gspca_dev); 298 299 return 0; 300 } 301 302 static int mi1320_init_post_alt(struct gspca_dev *gspca_dev) 303 { 304 mi1320_camera_settings(gspca_dev); 305 306 return 0; 307 } 308 309 static int mi1320_sensor_settings(struct gspca_dev *gspca_dev) 310 { 311 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 312 313 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL); 314 315 fetch_validx(gspca_dev, tbl_sensor_settings_common, 316 ARRAY_SIZE(tbl_sensor_settings_common)); 317 318 switch (reso) { 319 case IMAGE_1280: 320 fetch_validx(gspca_dev, tbl_sensor_settings_1280, 321 ARRAY_SIZE(tbl_sensor_settings_1280)); 322 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]); 323 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]); 324 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]); 325 break; 326 327 case IMAGE_800: 328 fetch_validx(gspca_dev, tbl_sensor_settings_800, 329 ARRAY_SIZE(tbl_sensor_settings_800)); 330 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]); 331 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]); 332 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]); 333 break; 334 335 default: 336 fetch_validx(gspca_dev, tbl_sensor_settings_640, 337 ARRAY_SIZE(tbl_sensor_settings_640)); 338 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]); 339 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]); 340 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]); 341 break; 342 } 343 return 0; 344 } 345 346 static int mi1320_configure_alt(struct gspca_dev *gspca_dev) 347 { 348 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv; 349 350 switch (reso) { 351 case IMAGE_640: 352 gspca_dev->alt = 3 + 1; 353 break; 354 355 case IMAGE_800: 356 case IMAGE_1280: 357 gspca_dev->alt = 1 + 1; 358 break; 359 } 360 return 0; 361 } 362 363 static int mi1320_camera_settings(struct gspca_dev *gspca_dev) 364 { 365 struct sd *sd = (struct sd *) gspca_dev; 366 367 s32 backlight = sd->vcur.backlight; 368 s32 bright = sd->vcur.brightness; 369 s32 sharp = sd->vcur.sharpness; 370 s32 cntr = sd->vcur.contrast; 371 s32 gam = sd->vcur.gamma; 372 s32 hue = sd->vcur.hue; 373 s32 sat = sd->vcur.saturation; 374 s32 wbal = sd->vcur.whitebal; 375 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0); 376 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0); 377 s32 freq = (sd->vcur.AC50Hz > 0); 378 s32 i; 379 380 if (freq != sd->vold.AC50Hz) { 381 sd->vold.AC50Hz = freq; 382 383 freq = 2 * (freq == 0); 384 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 385 ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL); 386 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x005b, 0, NULL); 387 ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL); 388 } 389 390 if (wbal != sd->vold.whitebal) { 391 sd->vold.whitebal = wbal; 392 if (wbal < 0 || wbal > sd->vmax.whitebal) 393 wbal = 0; 394 395 for (i = 0; i < 2; i++) { 396 if (wbal == 0) { /* Normal light */ 397 ctrl_out(gspca_dev, 0x40, 1, 398 0x0010, 0x0010, 0, NULL); 399 ctrl_out(gspca_dev, 0x40, 1, 400 0x0003, 0x00c1, 0, NULL); 401 ctrl_out(gspca_dev, 0x40, 1, 402 0x0042, 0x00c2, 0, NULL); 403 ctrl_out(gspca_dev, 0x40, 3, 404 0xba00, 0x0200, 48, dat_wbalNL); 405 } 406 407 if (wbal == 1) { /* Low light */ 408 ctrl_out(gspca_dev, 0x40, 1, 409 0x0010, 0x0010, 0, NULL); 410 ctrl_out(gspca_dev, 0x40, 1, 411 0x0004, 0x00c1, 0, NULL); 412 ctrl_out(gspca_dev, 0x40, 1, 413 0x0043, 0x00c2, 0, NULL); 414 ctrl_out(gspca_dev, 0x40, 3, 415 0xba00, 0x0200, 48, dat_wbalLL); 416 } 417 418 if (wbal == 2) { /* Back light */ 419 ctrl_out(gspca_dev, 0x40, 1, 420 0x0010, 0x0010, 0, NULL); 421 ctrl_out(gspca_dev, 0x40, 1, 422 0x0003, 0x00c1, 0, NULL); 423 ctrl_out(gspca_dev, 0x40, 1, 424 0x0042, 0x00c2, 0, NULL); 425 ctrl_out(gspca_dev, 0x40, 3, 426 0xba00, 0x0200, 44, dat_wbalBL); 427 } 428 } 429 } 430 431 if (bright != sd->vold.brightness) { 432 sd->vold.brightness = bright; 433 if (bright < 0 || bright > sd->vmax.brightness) 434 bright = 0; 435 436 bright = tbl_bright[bright]; 437 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 438 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 439 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL); 440 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL); 441 } 442 443 if (sat != sd->vold.saturation) { 444 sd->vold.saturation = sat; 445 if (sat < 0 || sat > sd->vmax.saturation) 446 sat = 0; 447 448 sat = tbl_sat[sat]; 449 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 450 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 451 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0025, 0, NULL); 452 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL); 453 } 454 455 if (sharp != sd->vold.sharpness) { 456 sd->vold.sharpness = sharp; 457 if (sharp < 0 || sharp > sd->vmax.sharpness) 458 sharp = 0; 459 460 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 461 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 462 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0005, 0, NULL); 463 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL); 464 } 465 466 if (hue != sd->vold.hue) { 467 /* 0=normal 1=NB 2="sepia" 3=negative 4=other 5=other2 */ 468 if (hue < 0 || hue > sd->vmax.hue) 469 hue = 0; 470 if (hue == sd->vmax.hue) 471 sd->swapRB = 1; 472 else 473 sd->swapRB = 0; 474 475 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 476 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 477 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL); 478 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1, 479 0, NULL); 480 } 481 482 if (backlight != sd->vold.backlight) { 483 sd->vold.backlight = backlight; 484 if (backlight < 0 || backlight > sd->vmax.backlight) 485 backlight = 0; 486 487 backlight = tbl_backlight[backlight]; 488 for (i = 0; i < 2; i++) { 489 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 490 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 491 ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL); 492 ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1, 493 0, NULL); 494 } 495 } 496 497 if (hue != sd->vold.hue) { 498 sd->vold.hue = hue; 499 500 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 501 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 502 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL); 503 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1, 504 0, NULL); 505 } 506 507 if (mirror != sd->vold.mirror || flip != sd->vold.flip) { 508 u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00}; 509 sd->vold.mirror = mirror; 510 sd->vold.flip = flip; 511 512 dat_hvflip2[3] = flip + 2 * mirror; 513 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1); 514 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2); 515 } 516 517 if (gam != sd->vold.gamma) { 518 sd->vold.gamma = gam; 519 if (gam < 0 || gam > sd->vmax.gamma) 520 gam = 0; 521 522 gam = 2 * gam; 523 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 524 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 525 ctrl_out(gspca_dev, 0x40, 1, 0xba04 , 0x003b, 0, NULL); 526 ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL); 527 } 528 529 if (cntr != sd->vold.contrast) { 530 sd->vold.contrast = cntr; 531 if (cntr < 0 || cntr > sd->vmax.contrast) 532 cntr = 0; 533 534 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL); 535 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL); 536 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035, 537 0, NULL); 538 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1, 539 0, NULL); 540 } 541 542 return 0; 543 } 544 545 static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev) 546 { 547 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL); 548 549 fetch_validx(gspca_dev, tbl_post_unset_alt, 550 ARRAY_SIZE(tbl_post_unset_alt)); 551 } 552