Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[pandora-kernel.git] / drivers / media / video / gspca / stv06xx / stv06xx_pb0100.c
1 /*
2  * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
3  *                    Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
4  * Copyright (c) 2002, 2003 Tuukka Toivonen
5  * Copyright (c) 2008 Erik AndrĂ©n
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * P/N 861037:      Sensor HDCS1000        ASIC STV0600
22  * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
23  * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
24  * P/N 861055:      Sensor ST VV6410       ASIC STV0610   - LEGO cam
25  * P/N 861075-0040: Sensor HDCS1000        ASIC
26  * P/N 961179-0700: Sensor ST VV6410       ASIC STV0602   - Dexxa WebCam USB
27  * P/N 861040-0000: Sensor ST VV6410       ASIC STV0610   - QuickCam Web
28  */
29
30 /*
31  * The spec file for the PB-0100 suggests the following for best quality
32  * images after the sensor has been reset :
33  *
34  * PB_ADCGAINL      = R60 = 0x03 (3 dec)      : sets low reference of ADC
35                                                 to produce good black level
36  * PB_PREADCTRL     = R32 = 0x1400 (5120 dec) : Enables global gain changes
37                                                 through R53
38  * PB_ADCMINGAIN    = R52 = 0x10 (16 dec)     : Sets the minimum gain for
39                                                 auto-exposure
40  * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec)     : Sets the global gain
41  * PB_EXPGAIN       = R14 = 0x11 (17 dec)     : Sets the auto-exposure value
42  * PB_UPDATEINT     = R23 = 0x02 (2 dec)      : Sets the speed on
43                                                 auto-exposure routine
44  * PB_CFILLIN       = R5  = 0x0E (14 dec)     : Sets the frame rate
45  */
46
47 #include "stv06xx_pb0100.h"
48
49 static const struct ctrl pb0100_ctrl[] = {
50 #define GAIN_IDX 0
51         {
52                 {
53                         .id             = V4L2_CID_GAIN,
54                         .type           = V4L2_CTRL_TYPE_INTEGER,
55                         .name           = "Gain",
56                         .minimum        = 0,
57                         .maximum        = 255,
58                         .step           = 1,
59                         .default_value  = 128
60                 },
61                 .set = pb0100_set_gain,
62                 .get = pb0100_get_gain
63         },
64 #define RED_BALANCE_IDX 1
65         {
66                 {
67                         .id             = V4L2_CID_RED_BALANCE,
68                         .type           = V4L2_CTRL_TYPE_INTEGER,
69                         .name           = "Red Balance",
70                         .minimum        = -255,
71                         .maximum        = 255,
72                         .step           = 1,
73                         .default_value  = 0
74                 },
75                 .set = pb0100_set_red_balance,
76                 .get = pb0100_get_red_balance
77         },
78 #define BLUE_BALANCE_IDX 2
79         {
80                 {
81                         .id             = V4L2_CID_BLUE_BALANCE,
82                         .type           = V4L2_CTRL_TYPE_INTEGER,
83                         .name           = "Blue Balance",
84                         .minimum        = -255,
85                         .maximum        = 255,
86                         .step           = 1,
87                         .default_value  = 0
88                 },
89                 .set = pb0100_set_blue_balance,
90                 .get = pb0100_get_blue_balance
91         },
92 #define EXPOSURE_IDX 3
93         {
94                 {
95                         .id             = V4L2_CID_EXPOSURE,
96                         .type           = V4L2_CTRL_TYPE_INTEGER,
97                         .name           = "Exposure",
98                         .minimum        = 0,
99                         .maximum        = 511,
100                         .step           = 1,
101                         .default_value  = 12
102                 },
103                 .set = pb0100_set_exposure,
104                 .get = pb0100_get_exposure
105         },
106 #define AUTOGAIN_IDX 4
107         {
108                 {
109                         .id             = V4L2_CID_AUTOGAIN,
110                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
111                         .name           = "Automatic Gain and Exposure",
112                         .minimum        = 0,
113                         .maximum        = 1,
114                         .step           = 1,
115                         .default_value  = 1
116                 },
117                 .set = pb0100_set_autogain,
118                 .get = pb0100_get_autogain
119         },
120 #define AUTOGAIN_TARGET_IDX 5
121         {
122                 {
123                         .id             = V4L2_CTRL_CLASS_USER + 0x1000,
124                         .type           = V4L2_CTRL_TYPE_INTEGER,
125                         .name           = "Automatic Gain Target",
126                         .minimum        = 0,
127                         .maximum        = 255,
128                         .step           = 1,
129                         .default_value  = 128
130                 },
131                 .set = pb0100_set_autogain_target,
132                 .get = pb0100_get_autogain_target
133         },
134 #define NATURAL_IDX 6
135         {
136                 {
137                         .id             = V4L2_CTRL_CLASS_USER + 0x1001,
138                         .type           = V4L2_CTRL_TYPE_BOOLEAN,
139                         .name           = "Natural Light Source",
140                         .minimum        = 0,
141                         .maximum        = 1,
142                         .step           = 1,
143                         .default_value  = 1
144                 },
145                 .set = pb0100_set_natural,
146                 .get = pb0100_get_natural
147         }
148 };
149
150 static struct v4l2_pix_format pb0100_mode[] = {
151 /* low res / subsample modes disabled as they are only half res horizontal,
152    halving the vertical resolution does not seem to work */
153         {
154                 320,
155                 240,
156                 V4L2_PIX_FMT_SGRBG8,
157                 V4L2_FIELD_NONE,
158                 .sizeimage = 320 * 240,
159                 .bytesperline = 320,
160                 .colorspace = V4L2_COLORSPACE_SRGB,
161                 .priv = PB0100_CROP_TO_VGA
162         },
163         {
164                 352,
165                 288,
166                 V4L2_PIX_FMT_SGRBG8,
167                 V4L2_FIELD_NONE,
168                 .sizeimage = 352 * 288,
169                 .bytesperline = 352,
170                 .colorspace = V4L2_COLORSPACE_SRGB,
171                 .priv = 0
172         }
173 };
174
175 static int pb0100_probe(struct sd *sd)
176 {
177         u16 sensor;
178         int i, err;
179         s32 *sensor_settings;
180
181         err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
182
183         if (err < 0)
184                 return -ENODEV;
185
186         if ((sensor >> 8) == 0x64) {
187                 sensor_settings = kmalloc(
188                                 ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
189                                 GFP_KERNEL);
190                 if (!sensor_settings)
191                         return -ENOMEM;
192
193                 info("Photobit pb0100 sensor detected");
194
195                 sd->gspca_dev.cam.cam_mode = pb0100_mode;
196                 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
197                 sd->desc.ctrls = pb0100_ctrl;
198                 sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
199                 for (i = 0; i < sd->desc.nctrls; i++)
200                         sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
201                 sd->sensor_priv = sensor_settings;
202
203                 return 0;
204         }
205
206         return -ENODEV;
207 }
208
209 static int pb0100_start(struct sd *sd)
210 {
211         int err, packet_size, max_packet_size;
212         struct usb_host_interface *alt;
213         struct usb_interface *intf;
214         struct cam *cam = &sd->gspca_dev.cam;
215         s32 *sensor_settings = sd->sensor_priv;
216         u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
217
218         intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
219         alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
220         if (!alt)
221                 return -ENODEV;
222         packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
223
224         /* If we don't have enough bandwidth use a lower framerate */
225         max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
226         if (packet_size < max_packet_size)
227                 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
228         else
229                 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
230
231         /* Setup sensor window */
232         if (mode & PB0100_CROP_TO_VGA) {
233                 stv06xx_write_sensor(sd, PB_RSTART, 30);
234                 stv06xx_write_sensor(sd, PB_CSTART, 20);
235                 stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
236                 stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
237         } else {
238                 stv06xx_write_sensor(sd, PB_RSTART, 8);
239                 stv06xx_write_sensor(sd, PB_CSTART, 4);
240                 stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
241                 stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
242         }
243
244         if (mode & PB0100_SUBSAMPLE) {
245                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
246                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
247
248                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
249         } else {
250                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
251                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
252                 /* larger -> slower */
253                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
254         }
255
256         /* set_gain also sets red and blue balance */
257         pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
258         pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
259         pb0100_set_autogain_target(&sd->gspca_dev,
260                                    sensor_settings[AUTOGAIN_TARGET_IDX]);
261         pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
262
263         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
264         PDEBUG(D_STREAM, "Started stream, status: %d", err);
265
266         return (err < 0) ? err : 0;
267 }
268
269 static int pb0100_stop(struct sd *sd)
270 {
271         int err;
272
273         err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
274
275         if (err < 0)
276                 goto out;
277
278         /* Set bit 1 to zero */
279         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
280
281         PDEBUG(D_STREAM, "Halting stream");
282 out:
283         return (err < 0) ? err : 0;
284 }
285
286 static void pb0100_disconnect(struct sd *sd)
287 {
288         sd->sensor = NULL;
289         kfree(sd->sensor_priv);
290 }
291
292 /* FIXME: Sort the init commands out and put them into tables,
293           this is only for getting the camera to work */
294 /* FIXME: No error handling for now,
295           add this once the init has been converted to proper tables */
296 static int pb0100_init(struct sd *sd)
297 {
298         stv06xx_write_bridge(sd, STV_REG00, 1);
299         stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
300
301         /* Reset sensor */
302         stv06xx_write_sensor(sd, PB_RESET, 1);
303         stv06xx_write_sensor(sd, PB_RESET, 0);
304
305         /* Disable chip */
306         stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
307
308         /* Gain stuff...*/
309         stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
310         stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
311
312         /* Set up auto-exposure */
313         /* ADC VREF_HI new setting for a transition
314           from the Expose1 to the Expose2 setting */
315         stv06xx_write_sensor(sd, PB_R28, 12);
316         /* gain max for autoexposure */
317         stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
318         /* gain min for autoexposure  */
319         stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
320         /* Maximum frame integration time (programmed into R8)
321            allowed for auto-exposure routine */
322         stv06xx_write_sensor(sd, PB_R54, 3);
323         /* Minimum frame integration time (programmed into R8)
324            allowed for auto-exposure routine */
325         stv06xx_write_sensor(sd, PB_R55, 0);
326         stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
327         /* R15  Expose0 (maximum that auto-exposure may use) */
328         stv06xx_write_sensor(sd, PB_R15, 800);
329         /* R17  Expose2 (minimum that auto-exposure may use) */
330         stv06xx_write_sensor(sd, PB_R17, 10);
331
332         stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
333
334         /* 0x14 */
335         stv06xx_write_sensor(sd, PB_VOFFSET, 0);
336         /* 0x0D */
337         stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
338         /* Set black level (important!) */
339         stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
340
341         /* ??? */
342         stv06xx_write_bridge(sd, STV_REG00, 0x11);
343         stv06xx_write_bridge(sd, STV_REG03, 0x45);
344         stv06xx_write_bridge(sd, STV_REG04, 0x07);
345
346         /* Scan/timing for the sensor */
347         stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
348         stv06xx_write_sensor(sd, PB_CFILLIN, 14);
349         stv06xx_write_sensor(sd, PB_VBL, 0);
350         stv06xx_write_sensor(sd, PB_FINTTIME, 0);
351         stv06xx_write_sensor(sd, PB_RINTTIME, 123);
352
353         stv06xx_write_bridge(sd, STV_REG01, 0xc2);
354         stv06xx_write_bridge(sd, STV_REG02, 0xb0);
355         return 0;
356 }
357
358 static int pb0100_dump(struct sd *sd)
359 {
360         return 0;
361 }
362
363 static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
364 {
365         struct sd *sd = (struct sd *) gspca_dev;
366         s32 *sensor_settings = sd->sensor_priv;
367
368         *val = sensor_settings[GAIN_IDX];
369
370         return 0;
371 }
372
373 static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
374 {
375         int err;
376         struct sd *sd = (struct sd *) gspca_dev;
377         s32 *sensor_settings = sd->sensor_priv;
378
379         if (sensor_settings[AUTOGAIN_IDX])
380                 return -EBUSY;
381
382         sensor_settings[GAIN_IDX] = val;
383         err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
384         if (!err)
385                 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
386         PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
387
388         if (!err)
389                 err = pb0100_set_red_balance(gspca_dev,
390                                              sensor_settings[RED_BALANCE_IDX]);
391         if (!err)
392                 err = pb0100_set_blue_balance(gspca_dev,
393                                             sensor_settings[BLUE_BALANCE_IDX]);
394
395         return err;
396 }
397
398 static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
399 {
400         struct sd *sd = (struct sd *) gspca_dev;
401         s32 *sensor_settings = sd->sensor_priv;
402
403         *val = sensor_settings[RED_BALANCE_IDX];
404
405         return 0;
406 }
407
408 static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
409 {
410         int err;
411         struct sd *sd = (struct sd *) gspca_dev;
412         s32 *sensor_settings = sd->sensor_priv;
413
414         if (sensor_settings[AUTOGAIN_IDX])
415                 return -EBUSY;
416
417         sensor_settings[RED_BALANCE_IDX] = val;
418         val += sensor_settings[GAIN_IDX];
419         if (val < 0)
420                 val = 0;
421         else if (val > 255)
422                 val = 255;
423
424         err = stv06xx_write_sensor(sd, PB_RGAIN, val);
425         PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
426
427         return err;
428 }
429
430 static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
431 {
432         struct sd *sd = (struct sd *) gspca_dev;
433         s32 *sensor_settings = sd->sensor_priv;
434
435         *val = sensor_settings[BLUE_BALANCE_IDX];
436
437         return 0;
438 }
439
440 static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
441 {
442         int err;
443         struct sd *sd = (struct sd *) gspca_dev;
444         s32 *sensor_settings = sd->sensor_priv;
445
446         if (sensor_settings[AUTOGAIN_IDX])
447                 return -EBUSY;
448
449         sensor_settings[BLUE_BALANCE_IDX] = val;
450         val += sensor_settings[GAIN_IDX];
451         if (val < 0)
452                 val = 0;
453         else if (val > 255)
454                 val = 255;
455
456         err = stv06xx_write_sensor(sd, PB_BGAIN, val);
457         PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
458
459         return err;
460 }
461
462 static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
463 {
464         struct sd *sd = (struct sd *) gspca_dev;
465         s32 *sensor_settings = sd->sensor_priv;
466
467         *val = sensor_settings[EXPOSURE_IDX];
468
469         return 0;
470 }
471
472 static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
473 {
474         int err;
475         struct sd *sd = (struct sd *) gspca_dev;
476         s32 *sensor_settings = sd->sensor_priv;
477
478         if (sensor_settings[AUTOGAIN_IDX])
479                 return -EBUSY;
480
481         sensor_settings[EXPOSURE_IDX] = val;
482         err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
483         PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
484
485         return err;
486 }
487
488 static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
489 {
490         struct sd *sd = (struct sd *) gspca_dev;
491         s32 *sensor_settings = sd->sensor_priv;
492
493         *val = sensor_settings[AUTOGAIN_IDX];
494
495         return 0;
496 }
497
498 static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
499 {
500         int err;
501         struct sd *sd = (struct sd *) gspca_dev;
502         s32 *sensor_settings = sd->sensor_priv;
503
504         sensor_settings[AUTOGAIN_IDX] = val;
505         if (sensor_settings[AUTOGAIN_IDX]) {
506                 if (sensor_settings[NATURAL_IDX])
507                         val = BIT(6)|BIT(4)|BIT(0);
508                 else
509                         val = BIT(4)|BIT(0);
510         } else
511                 val = 0;
512
513         err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
514         PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
515                sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
516                err);
517
518         return err;
519 }
520
521 static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
522 {
523         struct sd *sd = (struct sd *) gspca_dev;
524         s32 *sensor_settings = sd->sensor_priv;
525
526         *val = sensor_settings[AUTOGAIN_TARGET_IDX];
527
528         return 0;
529 }
530
531 static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
532 {
533         int err, totalpixels, brightpixels, darkpixels;
534         struct sd *sd = (struct sd *) gspca_dev;
535         s32 *sensor_settings = sd->sensor_priv;
536
537         sensor_settings[AUTOGAIN_TARGET_IDX] = val;
538
539         /* Number of pixels counted by the sensor when subsampling the pixels.
540          * Slightly larger than the real value to avoid oscillation */
541         totalpixels = gspca_dev->width * gspca_dev->height;
542         totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
543
544         brightpixels = (totalpixels * val) >> 8;
545         darkpixels   = totalpixels - brightpixels;
546         err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
547         if (!err)
548                 err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
549
550         PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
551
552         return err;
553 }
554
555 static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
556 {
557         struct sd *sd = (struct sd *) gspca_dev;
558         s32 *sensor_settings = sd->sensor_priv;
559
560         *val = sensor_settings[NATURAL_IDX];
561
562         return 0;
563 }
564
565 static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
566 {
567         struct sd *sd = (struct sd *) gspca_dev;
568         s32 *sensor_settings = sd->sensor_priv;
569
570         sensor_settings[NATURAL_IDX] = val;
571
572         return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
573 }