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
mi1320_init_settings(struct gspca_dev * gspca_dev)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
common(struct gspca_dev * gspca_dev)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
mi1320_init_at_startup(struct gspca_dev * gspca_dev)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
mi1320_init_pre_alt(struct gspca_dev * gspca_dev)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
mi1320_init_post_alt(struct gspca_dev * gspca_dev)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
mi1320_sensor_settings(struct gspca_dev * gspca_dev)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
mi1320_configure_alt(struct gspca_dev * gspca_dev)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
mi1320_camera_settings(struct gspca_dev * gspca_dev)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
mi1320_post_unset_alt(struct gspca_dev * gspca_dev)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