]> Pileus Git - ~andy/linux/blob - drivers/media/usb/gspca/m5602/m5602_po1030.c
[media] gscpa_m5602: Convert to the control framework
[~andy/linux] / drivers / media / usb / gspca / m5602 / m5602_po1030.c
1 /*
2  * Driver for the po1030 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_po1030.h"
22
23 static int po1030_s_ctrl(struct v4l2_ctrl *ctrl);
24 static void po1030_dump_registers(struct sd *sd);
25
26 static struct v4l2_pix_format po1030_modes[] = {
27         {
28                 640,
29                 480,
30                 V4L2_PIX_FMT_SBGGR8,
31                 V4L2_FIELD_NONE,
32                 .sizeimage = 640 * 480,
33                 .bytesperline = 640,
34                 .colorspace = V4L2_COLORSPACE_SRGB,
35                 .priv = 2
36         }
37 };
38
39 static const struct v4l2_ctrl_ops po1030_ctrl_ops = {
40         .s_ctrl = po1030_s_ctrl,
41 };
42
43 static const struct v4l2_ctrl_config po1030_greenbal_cfg = {
44         .ops    = &po1030_ctrl_ops,
45         .id     = M5602_V4L2_CID_GREEN_BALANCE,
46         .name   = "Green Balance",
47         .type   = V4L2_CTRL_TYPE_INTEGER,
48         .min    = 0,
49         .max    = 255,
50         .step   = 1,
51         .def    = PO1030_GREEN_GAIN_DEFAULT,
52         .flags  = V4L2_CTRL_FLAG_SLIDER,
53 };
54
55 int po1030_probe(struct sd *sd)
56 {
57         u8 dev_id_h = 0, i;
58
59         if (force_sensor) {
60                 if (force_sensor == PO1030_SENSOR) {
61                         pr_info("Forcing a %s sensor\n", po1030.name);
62                         goto sensor_found;
63                 }
64                 /* If we want to force another sensor, don't try to probe this
65                  * one */
66                 return -ENODEV;
67         }
68
69         PDEBUG(D_PROBE, "Probing for a po1030 sensor");
70
71         /* Run the pre-init to actually probe the unit */
72         for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
73                 u8 data = preinit_po1030[i][2];
74                 if (preinit_po1030[i][0] == SENSOR)
75                         m5602_write_sensor(sd,
76                                 preinit_po1030[i][1], &data, 1);
77                 else
78                         m5602_write_bridge(sd, preinit_po1030[i][1], data);
79         }
80
81         if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1))
82                 return -ENODEV;
83
84         if (dev_id_h == 0x30) {
85                 pr_info("Detected a po1030 sensor\n");
86                 goto sensor_found;
87         }
88         return -ENODEV;
89
90 sensor_found:
91         sd->gspca_dev.cam.cam_mode = po1030_modes;
92         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(po1030_modes);
93
94         return 0;
95 }
96
97 int po1030_init(struct sd *sd)
98 {
99         int i, err = 0;
100
101         /* Init the sensor */
102         for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
103                 u8 data[2] = {0x00, 0x00};
104
105                 switch (init_po1030[i][0]) {
106                 case BRIDGE:
107                         err = m5602_write_bridge(sd,
108                                 init_po1030[i][1],
109                                 init_po1030[i][2]);
110                         break;
111
112                 case SENSOR:
113                         data[0] = init_po1030[i][2];
114                         err = m5602_write_sensor(sd,
115                                 init_po1030[i][1], data, 1);
116                         break;
117
118                 default:
119                         pr_info("Invalid stream command, exiting init\n");
120                         return -EINVAL;
121                 }
122         }
123         if (err < 0)
124                 return err;
125
126         if (dump_sensor)
127                 po1030_dump_registers(sd);
128
129         return 0;
130 }
131
132 int po1030_init_controls(struct sd *sd)
133 {
134         struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
135
136         sd->gspca_dev.vdev.ctrl_handler = hdl;
137         v4l2_ctrl_handler_init(hdl, 9);
138
139         sd->auto_white_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
140                                                V4L2_CID_AUTO_WHITE_BALANCE,
141                                                0, 1, 1, 0);
142         sd->green_bal = v4l2_ctrl_new_custom(hdl, &po1030_greenbal_cfg, NULL);
143         sd->red_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
144                                         V4L2_CID_RED_BALANCE, 0, 255, 1,
145                                         PO1030_RED_GAIN_DEFAULT);
146         sd->blue_bal = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops,
147                                         V4L2_CID_BLUE_BALANCE, 0, 255, 1,
148                                         PO1030_BLUE_GAIN_DEFAULT);
149
150         sd->autoexpo = v4l2_ctrl_new_std_menu(hdl, &po1030_ctrl_ops,
151                           V4L2_CID_EXPOSURE_AUTO, 1, 0, V4L2_EXPOSURE_MANUAL);
152         sd->expo = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_EXPOSURE,
153                           0, 0x2ff, 1, PO1030_EXPOSURE_DEFAULT);
154
155         sd->gain = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_GAIN, 0,
156                                      0x4f, 1, PO1030_GLOBAL_GAIN_DEFAULT);
157
158         sd->hflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_HFLIP,
159                                       0, 1, 1, 0);
160         sd->vflip = v4l2_ctrl_new_std(hdl, &po1030_ctrl_ops, V4L2_CID_VFLIP,
161                                       0, 1, 1, 0);
162
163         if (hdl->error) {
164                 pr_err("Could not initialize controls\n");
165                 return hdl->error;
166         }
167
168         v4l2_ctrl_auto_cluster(4, &sd->auto_white_bal, 0, false);
169         v4l2_ctrl_auto_cluster(2, &sd->autoexpo, 0, false);
170         v4l2_ctrl_cluster(2, &sd->hflip);
171
172         return 0;
173 }
174
175 int po1030_start(struct sd *sd)
176 {
177         struct cam *cam = &sd->gspca_dev.cam;
178         int i, err = 0;
179         int width = cam->cam_mode[sd->gspca_dev.curr_mode].width;
180         int height = cam->cam_mode[sd->gspca_dev.curr_mode].height;
181         int ver_offs = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
182         u8 data;
183
184         switch (width) {
185         case 320:
186                 data = PO1030_SUBSAMPLING;
187                 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
188                 if (err < 0)
189                         return err;
190
191                 data = ((width + 3) >> 8) & 0xff;
192                 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
193                 if (err < 0)
194                         return err;
195
196                 data = (width + 3) & 0xff;
197                 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
198                 if (err < 0)
199                         return err;
200
201                 data = ((height + 1) >> 8) & 0xff;
202                 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
203                 if (err < 0)
204                         return err;
205
206                 data = (height + 1) & 0xff;
207                 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
208
209                 height += 6;
210                 width -= 1;
211                 break;
212
213         case 640:
214                 data = 0;
215                 err = m5602_write_sensor(sd, PO1030_CONTROL3, &data, 1);
216                 if (err < 0)
217                         return err;
218
219                 data = ((width + 7) >> 8) & 0xff;
220                 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_H, &data, 1);
221                 if (err < 0)
222                         return err;
223
224                 data = (width + 7) & 0xff;
225                 err = m5602_write_sensor(sd, PO1030_WINDOWWIDTH_L, &data, 1);
226                 if (err < 0)
227                         return err;
228
229                 data = ((height + 3) >> 8) & 0xff;
230                 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_H, &data, 1);
231                 if (err < 0)
232                         return err;
233
234                 data = (height + 3) & 0xff;
235                 err = m5602_write_sensor(sd, PO1030_WINDOWHEIGHT_L, &data, 1);
236
237                 height += 12;
238                 width -= 2;
239                 break;
240         }
241         err = m5602_write_bridge(sd, M5602_XB_SENSOR_TYPE, 0x0c);
242         if (err < 0)
243                 return err;
244
245         err = m5602_write_bridge(sd, M5602_XB_LINE_OF_FRAME_H, 0x81);
246         if (err < 0)
247                 return err;
248
249         err = m5602_write_bridge(sd, M5602_XB_PIX_OF_LINE_H, 0x82);
250         if (err < 0)
251                 return err;
252
253         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0x01);
254         if (err < 0)
255                 return err;
256
257         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA,
258                                  ((ver_offs >> 8) & 0xff));
259         if (err < 0)
260                 return err;
261
262         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (ver_offs & 0xff));
263         if (err < 0)
264                 return err;
265
266         for (i = 0; i < 2 && !err; i++)
267                 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
268         if (err < 0)
269                 return err;
270
271         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height >> 8) & 0xff);
272         if (err < 0)
273                 return err;
274
275         err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, (height & 0xff));
276         if (err < 0)
277                 return err;
278
279         for (i = 0; i < 2 && !err; i++)
280                 err = m5602_write_bridge(sd, M5602_XB_VSYNC_PARA, 0);
281
282         for (i = 0; i < 2 && !err; i++)
283                 err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
284
285         for (i = 0; i < 2 && !err; i++)
286                 err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, 0);
287         if (err < 0)
288                 return err;
289
290         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width >> 8) & 0xff);
291         if (err < 0)
292                 return err;
293
294         err = m5602_write_bridge(sd, M5602_XB_HSYNC_PARA, (width & 0xff));
295         if (err < 0)
296                 return err;
297
298         err = m5602_write_bridge(sd, M5602_XB_SIG_INI, 0);
299         return err;
300 }
301
302 static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
303 {
304         struct sd *sd = (struct sd *) gspca_dev;
305         u8 i2c_data;
306         int err;
307
308         PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
309
310         i2c_data = ((val & 0xff00) >> 8);
311         PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
312                i2c_data);
313
314         err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
315                                   &i2c_data, 1);
316         if (err < 0)
317                 return err;
318
319         i2c_data = (val & 0xff);
320         PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
321                i2c_data);
322         err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
323                                   &i2c_data, 1);
324
325         return err;
326 }
327
328 static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
329 {
330         struct sd *sd = (struct sd *) gspca_dev;
331         u8 i2c_data;
332         int err;
333
334         i2c_data = val & 0xff;
335         PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
336         err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
337                                  &i2c_data, 1);
338         return err;
339 }
340
341 static int po1030_set_hvflip(struct gspca_dev *gspca_dev)
342 {
343         struct sd *sd = (struct sd *) gspca_dev;
344         u8 i2c_data;
345         int err;
346
347         PDEBUG(D_V4L2, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val);
348         err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
349         if (err < 0)
350                 return err;
351
352         i2c_data = (0x3f & i2c_data) | (sd->hflip->val << 7) |
353                    (sd->vflip->val << 6);
354
355         err = m5602_write_sensor(sd, PO1030_CONTROL2,
356                                  &i2c_data, 1);
357
358         return err;
359 }
360
361 static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
362 {
363         struct sd *sd = (struct sd *) gspca_dev;
364         u8 i2c_data;
365         int err;
366
367         i2c_data = val & 0xff;
368         PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
369         err = m5602_write_sensor(sd, PO1030_RED_GAIN,
370                                   &i2c_data, 1);
371         return err;
372 }
373
374 static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
375 {
376         struct sd *sd = (struct sd *) gspca_dev;
377         u8 i2c_data;
378         int err;
379
380         i2c_data = val & 0xff;
381         PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
382         err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
383                                   &i2c_data, 1);
384
385         return err;
386 }
387
388 static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
389 {
390         struct sd *sd = (struct sd *) gspca_dev;
391         u8 i2c_data;
392         int err;
393
394         i2c_data = val & 0xff;
395         PDEBUG(D_V4L2, "Set green gain to %d", i2c_data);
396
397         err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
398                            &i2c_data, 1);
399         if (err < 0)
400                 return err;
401
402         return m5602_write_sensor(sd, PO1030_GREEN_2_GAIN,
403                                  &i2c_data, 1);
404 }
405
406 static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
407                                          __s32 val)
408 {
409         struct sd *sd = (struct sd *) gspca_dev;
410         u8 i2c_data;
411         int err;
412
413         err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
414         if (err < 0)
415                 return err;
416
417         PDEBUG(D_V4L2, "Set auto white balance to %d", val);
418         i2c_data = (i2c_data & 0xfe) | (val & 0x01);
419         err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
420         return err;
421 }
422
423 static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
424                                     __s32 val)
425 {
426         struct sd *sd = (struct sd *) gspca_dev;
427         u8 i2c_data;
428         int err;
429
430         err = m5602_read_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
431         if (err < 0)
432                 return err;
433
434         PDEBUG(D_V4L2, "Set auto exposure to %d", val);
435         val = (val == V4L2_EXPOSURE_AUTO);
436         i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
437         return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
438 }
439
440 void po1030_disconnect(struct sd *sd)
441 {
442         sd->sensor = NULL;
443 }
444
445 static int po1030_s_ctrl(struct v4l2_ctrl *ctrl)
446 {
447         struct gspca_dev *gspca_dev =
448                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
449         struct sd *sd = (struct sd *) gspca_dev;
450         int err;
451
452         if (!gspca_dev->streaming)
453                 return 0;
454
455         switch (ctrl->id) {
456         case V4L2_CID_AUTO_WHITE_BALANCE:
457                 err = po1030_set_auto_white_balance(gspca_dev, ctrl->val);
458                 if (err || ctrl->val)
459                         return err;
460                 err = po1030_set_green_balance(gspca_dev, sd->green_bal->val);
461                 if (err)
462                         return err;
463                 err = po1030_set_red_balance(gspca_dev, sd->red_bal->val);
464                 if (err)
465                         return err;
466                 err = po1030_set_blue_balance(gspca_dev, sd->blue_bal->val);
467                 break;
468         case V4L2_CID_EXPOSURE_AUTO:
469                 err = po1030_set_auto_exposure(gspca_dev, ctrl->val);
470                 if (err || ctrl->val == V4L2_EXPOSURE_AUTO)
471                         return err;
472                 err = po1030_set_exposure(gspca_dev, sd->expo->val);
473                 break;
474         case V4L2_CID_GAIN:
475                 err = po1030_set_gain(gspca_dev, ctrl->val);
476                 break;
477         case V4L2_CID_HFLIP:
478                 err = po1030_set_hvflip(gspca_dev);
479                 break;
480         default:
481                 return -EINVAL;
482         }
483
484         return err;
485 }
486
487 static void po1030_dump_registers(struct sd *sd)
488 {
489         int address;
490         u8 value = 0;
491
492         pr_info("Dumping the po1030 sensor core registers\n");
493         for (address = 0; address < 0x7f; address++) {
494                 m5602_read_sensor(sd, address, &value, 1);
495                 pr_info("register 0x%x contains 0x%x\n", address, value);
496         }
497
498         pr_info("po1030 register state dump complete\n");
499
500         pr_info("Probing for which registers that are read/write\n");
501         for (address = 0; address < 0xff; address++) {
502                 u8 old_value, ctrl_value;
503                 u8 test_value[2] = {0xff, 0xff};
504
505                 m5602_read_sensor(sd, address, &old_value, 1);
506                 m5602_write_sensor(sd, address, test_value, 1);
507                 m5602_read_sensor(sd, address, &ctrl_value, 1);
508
509                 if (ctrl_value == test_value[0])
510                         pr_info("register 0x%x is writeable\n", address);
511                 else
512                         pr_info("register 0x%x is read only\n", address);
513
514                 /* Restore original value */
515                 m5602_write_sensor(sd, address, &old_value, 1);
516         }
517 }