aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/m5602/m5602_mt9m111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/m5602/m5602_mt9m111.c')
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c400
1 files changed, 361 insertions, 39 deletions
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 7d3f9e348ef4..8d071dff6944 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -18,6 +18,23 @@
18 18
19#include "m5602_mt9m111.h" 19#include "m5602_mt9m111.h"
20 20
21static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
22static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
23static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
24static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
25static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
26static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
27static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
28 __s32 val);
29static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
30 __s32 *val);
31static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
32static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
33static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
34static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
35static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
36static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
37
21static struct v4l2_pix_format mt9m111_modes[] = { 38static struct v4l2_pix_format mt9m111_modes[] = {
22 { 39 {
23 640, 40 640,
@@ -32,6 +49,7 @@ static struct v4l2_pix_format mt9m111_modes[] = {
32}; 49};
33 50
34const static struct ctrl mt9m111_ctrls[] = { 51const static struct ctrl mt9m111_ctrls[] = {
52#define VFLIP_IDX 0
35 { 53 {
36 { 54 {
37 .id = V4L2_CID_VFLIP, 55 .id = V4L2_CID_VFLIP,
@@ -44,7 +62,9 @@ const static struct ctrl mt9m111_ctrls[] = {
44 }, 62 },
45 .set = mt9m111_set_vflip, 63 .set = mt9m111_set_vflip,
46 .get = mt9m111_get_vflip 64 .get = mt9m111_get_vflip
47 }, { 65 },
66#define HFLIP_IDX 1
67 {
48 { 68 {
49 .id = V4L2_CID_HFLIP, 69 .id = V4L2_CID_HFLIP,
50 .type = V4L2_CTRL_TYPE_BOOLEAN, 70 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -56,7 +76,9 @@ const static struct ctrl mt9m111_ctrls[] = {
56 }, 76 },
57 .set = mt9m111_set_hflip, 77 .set = mt9m111_set_hflip,
58 .get = mt9m111_get_hflip 78 .get = mt9m111_get_hflip
59 }, { 79 },
80#define GAIN_IDX 2
81 {
60 { 82 {
61 .id = V4L2_CID_GAIN, 83 .id = V4L2_CID_GAIN,
62 .type = V4L2_CTRL_TYPE_INTEGER, 84 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -64,21 +86,80 @@ const static struct ctrl mt9m111_ctrls[] = {
64 .minimum = 0, 86 .minimum = 0,
65 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2, 87 .maximum = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
66 .step = 1, 88 .step = 1,
67 .default_value = DEFAULT_GAIN, 89 .default_value = MT9M111_DEFAULT_GAIN,
68 .flags = V4L2_CTRL_FLAG_SLIDER 90 .flags = V4L2_CTRL_FLAG_SLIDER
69 }, 91 },
70 .set = mt9m111_set_gain, 92 .set = mt9m111_set_gain,
71 .get = mt9m111_get_gain 93 .get = mt9m111_get_gain
72 } 94 },
95#define AUTO_WHITE_BALANCE_IDX 3
96 {
97 {
98 .id = V4L2_CID_AUTO_WHITE_BALANCE,
99 .type = V4L2_CTRL_TYPE_BOOLEAN,
100 .name = "auto white balance",
101 .minimum = 0,
102 .maximum = 1,
103 .step = 1,
104 .default_value = 0,
105 },
106 .set = mt9m111_set_auto_white_balance,
107 .get = mt9m111_get_auto_white_balance
108 },
109#define GREEN_BALANCE_IDX 4
110 {
111 {
112 .id = M5602_V4L2_CID_GREEN_BALANCE,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "green balance",
115 .minimum = 0x00,
116 .maximum = 0x7ff,
117 .step = 0x1,
118 .default_value = MT9M111_GREEN_GAIN_DEFAULT,
119 .flags = V4L2_CTRL_FLAG_SLIDER
120 },
121 .set = mt9m111_set_green_balance,
122 .get = mt9m111_get_green_balance
123 },
124#define BLUE_BALANCE_IDX 5
125 {
126 {
127 .id = V4L2_CID_BLUE_BALANCE,
128 .type = V4L2_CTRL_TYPE_INTEGER,
129 .name = "blue balance",
130 .minimum = 0x00,
131 .maximum = 0x7ff,
132 .step = 0x1,
133 .default_value = MT9M111_BLUE_GAIN_DEFAULT,
134 .flags = V4L2_CTRL_FLAG_SLIDER
135 },
136 .set = mt9m111_set_blue_balance,
137 .get = mt9m111_get_blue_balance
138 },
139#define RED_BALANCE_IDX 5
140 {
141 {
142 .id = V4L2_CID_RED_BALANCE,
143 .type = V4L2_CTRL_TYPE_INTEGER,
144 .name = "red balance",
145 .minimum = 0x00,
146 .maximum = 0x7ff,
147 .step = 0x1,
148 .default_value = MT9M111_RED_GAIN_DEFAULT,
149 .flags = V4L2_CTRL_FLAG_SLIDER
150 },
151 .set = mt9m111_set_red_balance,
152 .get = mt9m111_get_red_balance
153 },
73}; 154};
74 155
75
76static void mt9m111_dump_registers(struct sd *sd); 156static void mt9m111_dump_registers(struct sd *sd);
77 157
78int mt9m111_probe(struct sd *sd) 158int mt9m111_probe(struct sd *sd)
79{ 159{
80 u8 data[2] = {0x00, 0x00}; 160 u8 data[2] = {0x00, 0x00};
81 int i; 161 int i;
162 s32 *sensor_settings;
82 163
83 if (force_sensor) { 164 if (force_sensor) {
84 if (force_sensor == MT9M111_SENSOR) { 165 if (force_sensor == MT9M111_SENSOR) {
@@ -117,16 +198,27 @@ int mt9m111_probe(struct sd *sd)
117 return -ENODEV; 198 return -ENODEV;
118 199
119sensor_found: 200sensor_found:
201 sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
202 GFP_KERNEL);
203 if (!sensor_settings)
204 return -ENOMEM;
205
120 sd->gspca_dev.cam.cam_mode = mt9m111_modes; 206 sd->gspca_dev.cam.cam_mode = mt9m111_modes;
121 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes); 207 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
122 sd->desc->ctrls = mt9m111_ctrls; 208 sd->desc->ctrls = mt9m111_ctrls;
123 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls); 209 sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
210
211 for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
212 sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
213 sd->sensor_priv = sensor_settings;
214
124 return 0; 215 return 0;
125} 216}
126 217
127int mt9m111_init(struct sd *sd) 218int mt9m111_init(struct sd *sd)
128{ 219{
129 int i, err = 0; 220 int i, err = 0;
221 s32 *sensor_settings = sd->sensor_priv;
130 222
131 /* Init the sensor */ 223 /* Init the sensor */
132 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) { 224 for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
@@ -147,36 +239,154 @@ int mt9m111_init(struct sd *sd)
147 if (dump_sensor) 239 if (dump_sensor)
148 mt9m111_dump_registers(sd); 240 mt9m111_dump_registers(sd);
149 241
150 return (err < 0) ? err : 0; 242 err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
243 if (err < 0)
244 return err;
245
246 err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
247 if (err < 0)
248 return err;
249
250 err = mt9m111_set_green_balance(&sd->gspca_dev,
251 sensor_settings[GREEN_BALANCE_IDX]);
252 if (err < 0)
253 return err;
254
255 err = mt9m111_set_blue_balance(&sd->gspca_dev,
256 sensor_settings[BLUE_BALANCE_IDX]);
257 if (err < 0)
258 return err;
259
260 err = mt9m111_set_red_balance(&sd->gspca_dev,
261 sensor_settings[RED_BALANCE_IDX]);
262 if (err < 0)
263 return err;
264
265 return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
151} 266}
152 267
153int mt9m111_power_down(struct sd *sd) 268int mt9m111_start(struct sd *sd)
154{ 269{
155 return 0; 270 int i, err = 0;
271 u8 data[2];
272 struct cam *cam = &sd->gspca_dev.cam;
273 s32 *sensor_settings = sd->sensor_priv;
274
275 int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
276 int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
277
278 for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
279 if (start_mt9m111[i][0] == BRIDGE) {
280 err = m5602_write_bridge(sd,
281 start_mt9m111[i][1],
282 start_mt9m111[i][2]);
283 } else {
284 data[0] = start_mt9m111[i][2];
285 data[1] = start_mt9m111[i][3];
286 err = m5602_write_sensor(sd,
287 start_mt9m111[i][1], data, 2);
288 }
289 }
290 if (err < 0)
291 return err;
292
293 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
294 if (err < 0)
295 return err;
296
297 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
298 if (err < 0)
299 return err;
300
301 for (i = 0; i < 2 && !err; i++)
302 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
303 if (err < 0)
304 return err;
305
306 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
307 if (err < 0)
308 return err;
309
310 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
311 if (err < 0)
312 return err;
313
314 for (i = 0; i < 2 && !err; i++)
315 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
316 if (err < 0)
317 return err;
318
319 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
320 (width >> 8) & 0xff);
321 if (err < 0)
322 return err;
323
324 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
325 if (err < 0)
326 return err;
327
328 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
329 if (err < 0)
330 return err;
331
332 switch (width) {
333 case 640:
334 PDEBUG(D_V4L2, "Configuring camera for VGA mode");
335 data[0] = MT9M111_RMB_OVER_SIZED;
336 data[1] = MT9M111_RMB_ROW_SKIP_2X |
337 MT9M111_RMB_COLUMN_SKIP_2X |
338 (sensor_settings[VFLIP_IDX] << 0) |
339 (sensor_settings[HFLIP_IDX] << 1);
340
341 err = m5602_write_sensor(sd,
342 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
343 break;
344
345 case 320:
346 PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
347 data[0] = MT9M111_RMB_OVER_SIZED;
348 data[1] = MT9M111_RMB_ROW_SKIP_4X |
349 MT9M111_RMB_COLUMN_SKIP_4X |
350 (sensor_settings[VFLIP_IDX] << 0) |
351 (sensor_settings[HFLIP_IDX] << 1);
352 err = m5602_write_sensor(sd,
353 MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
354 break;
355 }
356 return err;
156} 357}
157 358
158int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val) 359void mt9m111_disconnect(struct sd *sd)
360{
361 sd->sensor = NULL;
362 kfree(sd->sensor_priv);
363}
364
365static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
159{ 366{
160 int err;
161 u8 data[2] = {0x00, 0x00};
162 struct sd *sd = (struct sd *) gspca_dev; 367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
163 369
164 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 370 *val = sensor_settings[VFLIP_IDX];
165 data, 2);
166 *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
167 PDEBUG(D_V4L2, "Read vertical flip %d", *val); 371 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
168 372
169 return err; 373 return 0;
170} 374}
171 375
172int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val) 376static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
173{ 377{
174 int err; 378 int err;
175 u8 data[2] = {0x00, 0x00}; 379 u8 data[2] = {0x00, 0x00};
176 struct sd *sd = (struct sd *) gspca_dev; 380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
177 382
178 PDEBUG(D_V4L2, "Set vertical flip to %d", val); 383 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
179 384
385 sensor_settings[VFLIP_IDX] = val;
386
387 /* The mt9m111 is flipped by default */
388 val = !val;
389
180 /* Set the correct page map */ 390 /* Set the correct page map */
181 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 391 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
182 if (err < 0) 392 if (err < 0)
@@ -186,34 +396,37 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
186 if (err < 0) 396 if (err < 0)
187 return err; 397 return err;
188 398
189 data[0] = (data[0] & 0xfe) | val; 399 data[1] = (data[1] & 0xfe) | val;
190 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 400 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
191 data, 2); 401 data, 2);
192 return err; 402 return err;
193} 403}
194 404
195int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val) 405static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
196{ 406{
197 int err;
198 u8 data[2] = {0x00, 0x00};
199 struct sd *sd = (struct sd *) gspca_dev; 407 struct sd *sd = (struct sd *) gspca_dev;
408 s32 *sensor_settings = sd->sensor_priv;
200 409
201 err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 410 *val = sensor_settings[HFLIP_IDX];
202 data, 2);
203 *val = data[0] & MT9M111_RMB_MIRROR_COLS;
204 PDEBUG(D_V4L2, "Read horizontal flip %d", *val); 411 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
205 412
206 return err; 413 return 0;
207} 414}
208 415
209int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val) 416static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
210{ 417{
211 int err; 418 int err;
212 u8 data[2] = {0x00, 0x00}; 419 u8 data[2] = {0x00, 0x00};
213 struct sd *sd = (struct sd *) gspca_dev; 420 struct sd *sd = (struct sd *) gspca_dev;
421 s32 *sensor_settings = sd->sensor_priv;
214 422
215 PDEBUG(D_V4L2, "Set horizontal flip to %d", val); 423 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
216 424
425 sensor_settings[HFLIP_IDX] = val;
426
427 /* The mt9m111 is flipped by default */
428 val = !val;
429
217 /* Set the correct page map */ 430 /* Set the correct page map */
218 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 431 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
219 if (err < 0) 432 if (err < 0)
@@ -223,36 +436,62 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
223 if (err < 0) 436 if (err < 0)
224 return err; 437 return err;
225 438
226 data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02); 439 data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
227 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, 440 err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
228 data, 2); 441 data, 2);
229 return err; 442 return err;
230} 443}
231 444
232int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 445static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
233{ 446{
234 int err, tmp;
235 u8 data[2] = {0x00, 0x00};
236 struct sd *sd = (struct sd *) gspca_dev; 447 struct sd *sd = (struct sd *) gspca_dev;
448 s32 *sensor_settings = sd->sensor_priv;
237 449
238 err = m5602_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2); 450 *val = sensor_settings[GAIN_IDX];
239 tmp = ((data[1] << 8) | data[0]); 451 PDEBUG(D_V4L2, "Read gain %d", *val);
240 452
241 *val = ((tmp & (1 << 10)) * 2) | 453 return 0;
242 ((tmp & (1 << 9)) * 2) | 454}
243 ((tmp & (1 << 8)) * 2) |
244 (tmp & 0x7f);
245 455
246 PDEBUG(D_V4L2, "Read gain %d", *val); 456static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
457 __s32 val)
458{
459 struct sd *sd = (struct sd *) gspca_dev;
460 s32 *sensor_settings = sd->sensor_priv;
461 int err;
462 u8 data[2];
463
464 err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
465 if (err < 0)
466 return err;
467
468 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
469 data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
247 470
471 err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
472
473 PDEBUG(D_V4L2, "Set auto white balance %d", val);
248 return err; 474 return err;
249} 475}
250 476
251int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val) 477static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
478 __s32 *val) {
479 struct sd *sd = (struct sd *) gspca_dev;
480 s32 *sensor_settings = sd->sensor_priv;
481
482 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
483 PDEBUG(D_V4L2, "Read auto white balance %d", *val);
484 return 0;
485}
486
487static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
252{ 488{
253 int err, tmp; 489 int err, tmp;
254 u8 data[2] = {0x00, 0x00}; 490 u8 data[2] = {0x00, 0x00};
255 struct sd *sd = (struct sd *) gspca_dev; 491 struct sd *sd = (struct sd *) gspca_dev;
492 s32 *sensor_settings = sd->sensor_priv;
493
494 sensor_settings[GAIN_IDX] = val;
256 495
257 /* Set the correct page map */ 496 /* Set the correct page map */
258 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2); 497 err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -275,8 +514,8 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
275 else 514 else
276 tmp = val; 515 tmp = val;
277 516
278 data[1] = (tmp & 0xff00) >> 8; 517 data[1] = (tmp & 0xff);
279 data[0] = (tmp & 0xff); 518 data[0] = (tmp & 0xff00) >> 8;
280 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp, 519 PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
281 data[1], data[0]); 520 data[1], data[0]);
282 521
@@ -286,6 +525,89 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
286 return err; 525 return err;
287} 526}
288 527
528static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
529{
530 int err;
531 u8 data[2];
532 struct sd *sd = (struct sd *) gspca_dev;
533 s32 *sensor_settings = sd->sensor_priv;
534
535 sensor_settings[GREEN_BALANCE_IDX] = val;
536 data[1] = (val & 0xff);
537 data[0] = (val & 0xff00) >> 8;
538
539 PDEBUG(D_V4L2, "Set green balance %d", val);
540 err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
541 data, 2);
542 if (err < 0)
543 return err;
544
545 return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
546 data, 2);
547}
548
549static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
550{
551 struct sd *sd = (struct sd *) gspca_dev;
552 s32 *sensor_settings = sd->sensor_priv;
553
554 *val = sensor_settings[GREEN_BALANCE_IDX];
555 PDEBUG(D_V4L2, "Read green balance %d", *val);
556 return 0;
557}
558
559static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
560{
561 u8 data[2];
562 struct sd *sd = (struct sd *) gspca_dev;
563 s32 *sensor_settings = sd->sensor_priv;
564
565 sensor_settings[BLUE_BALANCE_IDX] = val;
566 data[1] = (val & 0xff);
567 data[0] = (val & 0xff00) >> 8;
568
569 PDEBUG(D_V4L2, "Set blue balance %d", val);
570
571 return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
572 data, 2);
573}
574
575static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
576{
577 struct sd *sd = (struct sd *) gspca_dev;
578 s32 *sensor_settings = sd->sensor_priv;
579
580 *val = sensor_settings[BLUE_BALANCE_IDX];
581 PDEBUG(D_V4L2, "Read blue balance %d", *val);
582 return 0;
583}
584
585static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
586{
587 u8 data[2];
588 struct sd *sd = (struct sd *) gspca_dev;
589 s32 *sensor_settings = sd->sensor_priv;
590
591 sensor_settings[RED_BALANCE_IDX] = val;
592 data[1] = (val & 0xff);
593 data[0] = (val & 0xff00) >> 8;
594
595 PDEBUG(D_V4L2, "Set red balance %d", val);
596
597 return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
598 data, 2);
599}
600
601static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
602{
603 struct sd *sd = (struct sd *) gspca_dev;
604 s32 *sensor_settings = sd->sensor_priv;
605
606 *val = sensor_settings[RED_BALANCE_IDX];
607 PDEBUG(D_V4L2, "Read red balance %d", *val);
608 return 0;
609}
610
289static void mt9m111_dump_registers(struct sd *sd) 611static void mt9m111_dump_registers(struct sd *sd)
290{ 612{
291 u8 address, value[2] = {0x00, 0x00}; 613 u8 address, value[2] = {0x00, 0x00};