~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/media/video/gspca/m5602/m5602_mt9m111.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Driver for the mt9m111 sensor
 
3
 *
 
4
 * Copyright (C) 2008 Erik AndrĆ©n
 
5
 * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
 
6
 * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
 
7
 *
 
8
 * Portions of code to USB interface and ALi driver software,
 
9
 * Copyright (c) 2006 Willem Duinker
 
10
 * v4l2 interface modeled after the V4L2 driver
 
11
 * for SN9C10x PC Camera Controllers
 
12
 *
 
13
 * This program is free software; you can redistribute it and/or
 
14
 * modify it under the terms of the GNU General Public License as
 
15
 * published by the Free Software Foundation, version 2.
 
16
 *
 
17
 */
 
18
 
 
19
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
20
 
 
21
#include "m5602_mt9m111.h"
 
22
 
 
23
static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 
24
static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
 
25
static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
 
26
static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
 
27
static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 
28
static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val);
 
29
static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
 
30
                                         __s32 val);
 
31
static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
 
32
                                          __s32 *val);
 
33
static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val);
 
34
static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val);
 
35
static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
 
36
static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
 
37
static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
 
38
static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
 
39
 
 
40
static struct v4l2_pix_format mt9m111_modes[] = {
 
41
        {
 
42
                640,
 
43
                480,
 
44
                V4L2_PIX_FMT_SBGGR8,
 
45
                V4L2_FIELD_NONE,
 
46
                .sizeimage = 640 * 480,
 
47
                .bytesperline = 640,
 
48
                .colorspace = V4L2_COLORSPACE_SRGB,
 
49
                .priv = 0
 
50
        }
 
51
};
 
52
 
 
53
static const struct ctrl mt9m111_ctrls[] = {
 
54
#define VFLIP_IDX 0
 
55
        {
 
56
                {
 
57
                        .id             = V4L2_CID_VFLIP,
 
58
                        .type           = V4L2_CTRL_TYPE_BOOLEAN,
 
59
                        .name           = "vertical flip",
 
60
                        .minimum        = 0,
 
61
                        .maximum        = 1,
 
62
                        .step           = 1,
 
63
                        .default_value  = 0
 
64
                },
 
65
                .set = mt9m111_set_vflip,
 
66
                .get = mt9m111_get_vflip
 
67
        },
 
68
#define HFLIP_IDX 1
 
69
        {
 
70
                {
 
71
                        .id             = V4L2_CID_HFLIP,
 
72
                        .type           = V4L2_CTRL_TYPE_BOOLEAN,
 
73
                        .name           = "horizontal flip",
 
74
                        .minimum        = 0,
 
75
                        .maximum        = 1,
 
76
                        .step           = 1,
 
77
                        .default_value  = 0
 
78
                },
 
79
                .set = mt9m111_set_hflip,
 
80
                .get = mt9m111_get_hflip
 
81
        },
 
82
#define GAIN_IDX 2
 
83
        {
 
84
                {
 
85
                        .id             = V4L2_CID_GAIN,
 
86
                        .type           = V4L2_CTRL_TYPE_INTEGER,
 
87
                        .name           = "gain",
 
88
                        .minimum        = 0,
 
89
                        .maximum        = (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2,
 
90
                        .step           = 1,
 
91
                        .default_value  = MT9M111_DEFAULT_GAIN,
 
92
                        .flags          = V4L2_CTRL_FLAG_SLIDER
 
93
                },
 
94
                .set = mt9m111_set_gain,
 
95
                .get = mt9m111_get_gain
 
96
        },
 
97
#define AUTO_WHITE_BALANCE_IDX 3
 
98
        {
 
99
                {
 
100
                        .id             = V4L2_CID_AUTO_WHITE_BALANCE,
 
101
                        .type           = V4L2_CTRL_TYPE_BOOLEAN,
 
102
                        .name           = "auto white balance",
 
103
                        .minimum        = 0,
 
104
                        .maximum        = 1,
 
105
                        .step           = 1,
 
106
                        .default_value  = 0,
 
107
                },
 
108
                .set = mt9m111_set_auto_white_balance,
 
109
                .get = mt9m111_get_auto_white_balance
 
110
        },
 
111
#define GREEN_BALANCE_IDX 4
 
112
        {
 
113
                {
 
114
                        .id             = M5602_V4L2_CID_GREEN_BALANCE,
 
115
                        .type           = V4L2_CTRL_TYPE_INTEGER,
 
116
                        .name           = "green balance",
 
117
                        .minimum        = 0x00,
 
118
                        .maximum        = 0x7ff,
 
119
                        .step           = 0x1,
 
120
                        .default_value  = MT9M111_GREEN_GAIN_DEFAULT,
 
121
                        .flags          = V4L2_CTRL_FLAG_SLIDER
 
122
                },
 
123
                .set = mt9m111_set_green_balance,
 
124
                .get = mt9m111_get_green_balance
 
125
        },
 
126
#define BLUE_BALANCE_IDX 5
 
127
        {
 
128
                {
 
129
                        .id             = V4L2_CID_BLUE_BALANCE,
 
130
                        .type           = V4L2_CTRL_TYPE_INTEGER,
 
131
                        .name           = "blue balance",
 
132
                        .minimum        = 0x00,
 
133
                        .maximum        = 0x7ff,
 
134
                        .step           = 0x1,
 
135
                        .default_value  = MT9M111_BLUE_GAIN_DEFAULT,
 
136
                        .flags          = V4L2_CTRL_FLAG_SLIDER
 
137
                },
 
138
                .set = mt9m111_set_blue_balance,
 
139
                .get = mt9m111_get_blue_balance
 
140
        },
 
141
#define RED_BALANCE_IDX 5
 
142
        {
 
143
                {
 
144
                        .id             = V4L2_CID_RED_BALANCE,
 
145
                        .type           = V4L2_CTRL_TYPE_INTEGER,
 
146
                        .name           = "red balance",
 
147
                        .minimum        = 0x00,
 
148
                        .maximum        = 0x7ff,
 
149
                        .step           = 0x1,
 
150
                        .default_value  = MT9M111_RED_GAIN_DEFAULT,
 
151
                        .flags          = V4L2_CTRL_FLAG_SLIDER
 
152
                },
 
153
                .set = mt9m111_set_red_balance,
 
154
                .get = mt9m111_get_red_balance
 
155
        },
 
156
};
 
157
 
 
158
static void mt9m111_dump_registers(struct sd *sd);
 
159
 
 
160
int mt9m111_probe(struct sd *sd)
 
161
{
 
162
        u8 data[2] = {0x00, 0x00};
 
163
        int i;
 
164
        s32 *sensor_settings;
 
165
 
 
166
        if (force_sensor) {
 
167
                if (force_sensor == MT9M111_SENSOR) {
 
168
                        pr_info("Forcing a %s sensor\n", mt9m111.name);
 
169
                        goto sensor_found;
 
170
                }
 
171
                /* If we want to force another sensor, don't try to probe this
 
172
                 * one */
 
173
                return -ENODEV;
 
174
        }
 
175
 
 
176
        PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
 
177
 
 
178
        /* Do the preinit */
 
179
        for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
 
180
                if (preinit_mt9m111[i][0] == BRIDGE) {
 
181
                        m5602_write_bridge(sd,
 
182
                                preinit_mt9m111[i][1],
 
183
                                preinit_mt9m111[i][2]);
 
184
                } else {
 
185
                        data[0] = preinit_mt9m111[i][2];
 
186
                        data[1] = preinit_mt9m111[i][3];
 
187
                        m5602_write_sensor(sd,
 
188
                                preinit_mt9m111[i][1], data, 2);
 
189
                }
 
190
        }
 
191
 
 
192
        if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
 
193
                return -ENODEV;
 
194
 
 
195
        if ((data[0] == 0x14) && (data[1] == 0x3a)) {
 
196
                pr_info("Detected a mt9m111 sensor\n");
 
197
                goto sensor_found;
 
198
        }
 
199
 
 
200
        return -ENODEV;
 
201
 
 
202
sensor_found:
 
203
        sensor_settings = kmalloc(ARRAY_SIZE(mt9m111_ctrls) * sizeof(s32),
 
204
                                  GFP_KERNEL);
 
205
        if (!sensor_settings)
 
206
                return -ENOMEM;
 
207
 
 
208
        sd->gspca_dev.cam.cam_mode = mt9m111_modes;
 
209
        sd->gspca_dev.cam.nmodes = ARRAY_SIZE(mt9m111_modes);
 
210
        sd->desc->ctrls = mt9m111_ctrls;
 
211
        sd->desc->nctrls = ARRAY_SIZE(mt9m111_ctrls);
 
212
 
 
213
        for (i = 0; i < ARRAY_SIZE(mt9m111_ctrls); i++)
 
214
                sensor_settings[i] = mt9m111_ctrls[i].qctrl.default_value;
 
215
        sd->sensor_priv = sensor_settings;
 
216
 
 
217
        return 0;
 
218
}
 
219
 
 
220
int mt9m111_init(struct sd *sd)
 
221
{
 
222
        int i, err = 0;
 
223
        s32 *sensor_settings = sd->sensor_priv;
 
224
 
 
225
        /* Init the sensor */
 
226
        for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
 
227
                u8 data[2];
 
228
 
 
229
                if (init_mt9m111[i][0] == BRIDGE) {
 
230
                        err = m5602_write_bridge(sd,
 
231
                                init_mt9m111[i][1],
 
232
                                init_mt9m111[i][2]);
 
233
                } else {
 
234
                        data[0] = init_mt9m111[i][2];
 
235
                        data[1] = init_mt9m111[i][3];
 
236
                        err = m5602_write_sensor(sd,
 
237
                                init_mt9m111[i][1], data, 2);
 
238
                }
 
239
        }
 
240
 
 
241
        if (dump_sensor)
 
242
                mt9m111_dump_registers(sd);
 
243
 
 
244
        err = mt9m111_set_vflip(&sd->gspca_dev, sensor_settings[VFLIP_IDX]);
 
245
        if (err < 0)
 
246
                return err;
 
247
 
 
248
        err = mt9m111_set_hflip(&sd->gspca_dev, sensor_settings[HFLIP_IDX]);
 
249
        if (err < 0)
 
250
                return err;
 
251
 
 
252
        err = mt9m111_set_green_balance(&sd->gspca_dev,
 
253
                                         sensor_settings[GREEN_BALANCE_IDX]);
 
254
        if (err < 0)
 
255
                return err;
 
256
 
 
257
        err = mt9m111_set_blue_balance(&sd->gspca_dev,
 
258
                                         sensor_settings[BLUE_BALANCE_IDX]);
 
259
        if (err < 0)
 
260
                return err;
 
261
 
 
262
        err = mt9m111_set_red_balance(&sd->gspca_dev,
 
263
                                        sensor_settings[RED_BALANCE_IDX]);
 
264
        if (err < 0)
 
265
                return err;
 
266
 
 
267
        return mt9m111_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
 
268
}
 
269
 
 
270
int mt9m111_start(struct sd *sd)
 
271
{
 
272
        int i, err = 0;
 
273
        u8 data[2];
 
274
        struct cam *cam = &sd->gspca_dev.cam;
 
275
        s32 *sensor_settings = sd->sensor_priv;
 
276
 
 
277
        int width = cam->cam_mode[sd->gspca_dev.curr_mode].width - 1;
 
278
        int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
 
279
 
 
280
        for (i = 0; i < ARRAY_SIZE(start_mt9m111) && !err; i++) {
 
281
                if (start_mt9m111[i][0] == BRIDGE) {
 
282
                        err = m5602_write_bridge(sd,
 
283
                                start_mt9m111[i][1],
 
284
                                start_mt9m111[i][2]);
 
285
                } else {
 
286
                        data[0] = start_mt9m111[i][2];
 
287
                        data[1] = start_mt9m111[i][3];
 
288
                        err = m5602_write_sensor(sd,
 
289
                                start_mt9m111[i][1], data, 2);
 
290
                }
 
291
        }
 
292
        if (err < 0)
 
293
                return err;
 
294
 
 
295
        err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
 
296
        if (err < 0)
 
297
                return err;
 
298
 
 
299
        err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
 
300
        if (err < 0)
 
301
                return err;
 
302
 
 
303
        for (i = 0; i < 2 && !err; i++)
 
304
                err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
 
305
        if (err < 0)
 
306
                return err;
 
307
 
 
308
        err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
 
309
        if (err < 0)
 
310
                return err;
 
311
 
 
312
        err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 2);
 
313
        if (err < 0)
 
314
                return err;
 
315
 
 
316
        for (i = 0; i < 2 && !err; i++)
 
317
                err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
 
318
        if (err < 0)
 
319
                return err;
 
320
 
 
321
        err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA,
 
322
                                 (width >> 8) & 0xff);
 
323
        if (err < 0)
 
324
                return err;
 
325
 
 
326
        err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, width & 0xff);
 
327
        if (err < 0)
 
328
                return err;
 
329
 
 
330
        err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
 
331
        if (err < 0)
 
332
                return err;
 
333
 
 
334
        switch (width) {
 
335
        case 640:
 
336
                PDEBUG(D_V4L2, "Configuring camera for VGA mode");
 
337
                data[0] = MT9M111_RMB_OVER_SIZED;
 
338
                data[1] = MT9M111_RMB_ROW_SKIP_2X |
 
339
                          MT9M111_RMB_COLUMN_SKIP_2X |
 
340
                          (sensor_settings[VFLIP_IDX] << 0) |
 
341
                          (sensor_settings[HFLIP_IDX] << 1);
 
342
 
 
343
                err = m5602_write_sensor(sd,
 
344
                                         MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 
345
                break;
 
346
 
 
347
        case 320:
 
348
                PDEBUG(D_V4L2, "Configuring camera for QVGA mode");
 
349
                data[0] = MT9M111_RMB_OVER_SIZED;
 
350
                data[1] = MT9M111_RMB_ROW_SKIP_4X |
 
351
                                MT9M111_RMB_COLUMN_SKIP_4X |
 
352
                                (sensor_settings[VFLIP_IDX] << 0) |
 
353
                                (sensor_settings[HFLIP_IDX] << 1);
 
354
                err = m5602_write_sensor(sd,
 
355
                                         MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 
356
                break;
 
357
        }
 
358
        return err;
 
359
}
 
360
 
 
361
void mt9m111_disconnect(struct sd *sd)
 
362
{
 
363
        sd->sensor = NULL;
 
364
        kfree(sd->sensor_priv);
 
365
}
 
366
 
 
367
static int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
 
368
{
 
369
        struct sd *sd = (struct sd *) gspca_dev;
 
370
        s32 *sensor_settings = sd->sensor_priv;
 
371
 
 
372
        *val = sensor_settings[VFLIP_IDX];
 
373
        PDEBUG(D_V4L2, "Read vertical flip %d", *val);
 
374
 
 
375
        return 0;
 
376
}
 
377
 
 
378
static int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
 
379
{
 
380
        int err;
 
381
        u8 data[2] = {0x00, 0x00};
 
382
        struct sd *sd = (struct sd *) gspca_dev;
 
383
        s32 *sensor_settings = sd->sensor_priv;
 
384
 
 
385
        PDEBUG(D_V4L2, "Set vertical flip to %d", val);
 
386
 
 
387
        sensor_settings[VFLIP_IDX] = val;
 
388
 
 
389
        /* The mt9m111 is flipped by default */
 
390
        val = !val;
 
391
 
 
392
        /* Set the correct page map */
 
393
        err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 
394
        if (err < 0)
 
395
                return err;
 
396
 
 
397
        err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 
398
        if (err < 0)
 
399
                return err;
 
400
 
 
401
        data[1] = (data[1] & 0xfe) | val;
 
402
        err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 
403
                                   data, 2);
 
404
        return err;
 
405
}
 
406
 
 
407
static int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
 
408
{
 
409
        struct sd *sd = (struct sd *) gspca_dev;
 
410
        s32 *sensor_settings = sd->sensor_priv;
 
411
 
 
412
        *val = sensor_settings[HFLIP_IDX];
 
413
        PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
 
414
 
 
415
        return 0;
 
416
}
 
417
 
 
418
static int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
 
419
{
 
420
        int err;
 
421
        u8 data[2] = {0x00, 0x00};
 
422
        struct sd *sd = (struct sd *) gspca_dev;
 
423
        s32 *sensor_settings = sd->sensor_priv;
 
424
 
 
425
        PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
 
426
 
 
427
        sensor_settings[HFLIP_IDX] = val;
 
428
 
 
429
        /* The mt9m111 is flipped by default */
 
430
        val = !val;
 
431
 
 
432
        /* Set the correct page map */
 
433
        err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 
434
        if (err < 0)
 
435
                return err;
 
436
 
 
437
        err = m5602_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
 
438
        if (err < 0)
 
439
                return err;
 
440
 
 
441
        data[1] = (data[1] & 0xfd) | ((val << 1) & 0x02);
 
442
        err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
 
443
                                        data, 2);
 
444
        return err;
 
445
}
 
446
 
 
447
static int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 
448
{
 
449
        struct sd *sd = (struct sd *) gspca_dev;
 
450
        s32 *sensor_settings = sd->sensor_priv;
 
451
 
 
452
        *val = sensor_settings[GAIN_IDX];
 
453
        PDEBUG(D_V4L2, "Read gain %d", *val);
 
454
 
 
455
        return 0;
 
456
}
 
457
 
 
458
static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
 
459
                                          __s32 val)
 
460
{
 
461
        struct sd *sd = (struct sd *) gspca_dev;
 
462
        s32 *sensor_settings = sd->sensor_priv;
 
463
        int err;
 
464
        u8 data[2];
 
465
 
 
466
        err = m5602_read_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
 
467
        if (err < 0)
 
468
                return err;
 
469
 
 
470
        sensor_settings[AUTO_WHITE_BALANCE_IDX] = val & 0x01;
 
471
        data[1] = ((data[1] & 0xfd) | ((val & 0x01) << 1));
 
472
 
 
473
        err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
 
474
 
 
475
        PDEBUG(D_V4L2, "Set auto white balance %d", val);
 
476
        return err;
 
477
}
 
478
 
 
479
static int mt9m111_get_auto_white_balance(struct gspca_dev *gspca_dev,
 
480
                                          __s32 *val) {
 
481
        struct sd *sd = (struct sd *) gspca_dev;
 
482
        s32 *sensor_settings = sd->sensor_priv;
 
483
 
 
484
        *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
 
485
        PDEBUG(D_V4L2, "Read auto white balance %d", *val);
 
486
        return 0;
 
487
}
 
488
 
 
489
static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 
490
{
 
491
        int err, tmp;
 
492
        u8 data[2] = {0x00, 0x00};
 
493
        struct sd *sd = (struct sd *) gspca_dev;
 
494
        s32 *sensor_settings = sd->sensor_priv;
 
495
 
 
496
        sensor_settings[GAIN_IDX] = val;
 
497
 
 
498
        /* Set the correct page map */
 
499
        err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
 
500
        if (err < 0)
 
501
                return err;
 
502
 
 
503
        if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
 
504
                return -EINVAL;
 
505
 
 
506
        if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
 
507
            (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
 
508
                tmp = (1 << 10) | (val << 9) |
 
509
                                (val << 8) | (val / 8);
 
510
        else if ((val >= INITIAL_MAX_GAIN * 2) &&
 
511
                 (val <  INITIAL_MAX_GAIN * 2 * 2))
 
512
                tmp = (1 << 9) | (1 << 8) | (val / 4);
 
513
        else if ((val >= INITIAL_MAX_GAIN) &&
 
514
                 (val < INITIAL_MAX_GAIN * 2))
 
515
                tmp = (1 << 8) | (val / 2);
 
516
        else
 
517
                tmp = val;
 
518
 
 
519
        data[1] = (tmp & 0xff);
 
520
        data[0] = (tmp & 0xff00) >> 8;
 
521
        PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
 
522
               data[1], data[0]);
 
523
 
 
524
        err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
 
525
                                   data, 2);
 
526
 
 
527
        return err;
 
528
}
 
529
 
 
530
static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
 
531
{
 
532
        int err;
 
533
        u8 data[2];
 
534
        struct sd *sd = (struct sd *) gspca_dev;
 
535
        s32 *sensor_settings = sd->sensor_priv;
 
536
 
 
537
        sensor_settings[GREEN_BALANCE_IDX] = val;
 
538
        data[1] = (val & 0xff);
 
539
        data[0] = (val & 0xff00) >> 8;
 
540
 
 
541
        PDEBUG(D_V4L2, "Set green balance %d", val);
 
542
        err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
 
543
                                 data, 2);
 
544
        if (err < 0)
 
545
                return err;
 
546
 
 
547
        return m5602_write_sensor(sd, MT9M111_SC_GREEN_2_GAIN,
 
548
                                  data, 2);
 
549
}
 
550
 
 
551
static int mt9m111_get_green_balance(struct gspca_dev *gspca_dev, __s32 *val)
 
552
{
 
553
        struct sd *sd = (struct sd *) gspca_dev;
 
554
        s32 *sensor_settings = sd->sensor_priv;
 
555
 
 
556
        *val = sensor_settings[GREEN_BALANCE_IDX];
 
557
        PDEBUG(D_V4L2, "Read green balance %d", *val);
 
558
        return 0;
 
559
}
 
560
 
 
561
static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
 
562
{
 
563
        u8 data[2];
 
564
        struct sd *sd = (struct sd *) gspca_dev;
 
565
        s32 *sensor_settings = sd->sensor_priv;
 
566
 
 
567
        sensor_settings[BLUE_BALANCE_IDX] = val;
 
568
        data[1] = (val & 0xff);
 
569
        data[0] = (val & 0xff00) >> 8;
 
570
 
 
571
        PDEBUG(D_V4L2, "Set blue balance %d", val);
 
572
 
 
573
        return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
 
574
                                  data, 2);
 
575
}
 
576
 
 
577
static int mt9m111_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
 
578
{
 
579
        struct sd *sd = (struct sd *) gspca_dev;
 
580
        s32 *sensor_settings = sd->sensor_priv;
 
581
 
 
582
        *val = sensor_settings[BLUE_BALANCE_IDX];
 
583
        PDEBUG(D_V4L2, "Read blue balance %d", *val);
 
584
        return 0;
 
585
}
 
586
 
 
587
static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
 
588
{
 
589
        u8 data[2];
 
590
        struct sd *sd = (struct sd *) gspca_dev;
 
591
        s32 *sensor_settings = sd->sensor_priv;
 
592
 
 
593
        sensor_settings[RED_BALANCE_IDX] = val;
 
594
        data[1] = (val & 0xff);
 
595
        data[0] = (val & 0xff00) >> 8;
 
596
 
 
597
        PDEBUG(D_V4L2, "Set red balance %d", val);
 
598
 
 
599
        return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
 
600
                                  data, 2);
 
601
}
 
602
 
 
603
static int mt9m111_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
 
604
{
 
605
        struct sd *sd = (struct sd *) gspca_dev;
 
606
        s32 *sensor_settings = sd->sensor_priv;
 
607
 
 
608
        *val = sensor_settings[RED_BALANCE_IDX];
 
609
        PDEBUG(D_V4L2, "Read red balance %d", *val);
 
610
        return 0;
 
611
}
 
612
 
 
613
static void mt9m111_dump_registers(struct sd *sd)
 
614
{
 
615
        u8 address, value[2] = {0x00, 0x00};
 
616
 
 
617
        pr_info("Dumping the mt9m111 register state\n");
 
618
 
 
619
        pr_info("Dumping the mt9m111 sensor core registers\n");
 
620
        value[1] = MT9M111_SENSOR_CORE;
 
621
        m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
 
622
        for (address = 0; address < 0xff; address++) {
 
623
                m5602_read_sensor(sd, address, value, 2);
 
624
                pr_info("register 0x%x contains 0x%x%x\n",
 
625
                        address, value[0], value[1]);
 
626
        }
 
627
 
 
628
        pr_info("Dumping the mt9m111 color pipeline registers\n");
 
629
        value[1] = MT9M111_COLORPIPE;
 
630
        m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
 
631
        for (address = 0; address < 0xff; address++) {
 
632
                m5602_read_sensor(sd, address, value, 2);
 
633
                pr_info("register 0x%x contains 0x%x%x\n",
 
634
                        address, value[0], value[1]);
 
635
        }
 
636
 
 
637
        pr_info("Dumping the mt9m111 camera control registers\n");
 
638
        value[1] = MT9M111_CAMERA_CONTROL;
 
639
        m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
 
640
        for (address = 0; address < 0xff; address++) {
 
641
                m5602_read_sensor(sd, address, value, 2);
 
642
                pr_info("register 0x%x contains 0x%x%x\n",
 
643
                        address, value[0], value[1]);
 
644
        }
 
645
 
 
646
        pr_info("mt9m111 register state dump complete\n");
 
647
}