]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
[media] gspca-stv06xx: support bandwidth changing
[karo-tx-linux.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         packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
221
222         /* If we don't have enough bandwidth use a lower framerate */
223         max_packet_size = sd->sensor->max_packet_size[sd->gspca_dev.curr_mode];
224         if (packet_size < max_packet_size)
225                 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
226         else
227                 stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(5)|BIT(3)|BIT(1));
228
229         /* Setup sensor window */
230         if (mode & PB0100_CROP_TO_VGA) {
231                 stv06xx_write_sensor(sd, PB_RSTART, 30);
232                 stv06xx_write_sensor(sd, PB_CSTART, 20);
233                 stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
234                 stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
235         } else {
236                 stv06xx_write_sensor(sd, PB_RSTART, 8);
237                 stv06xx_write_sensor(sd, PB_CSTART, 4);
238                 stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
239                 stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
240         }
241
242         if (mode & PB0100_SUBSAMPLE) {
243                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
244                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
245
246                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
247         } else {
248                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
249                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
250                 /* larger -> slower */
251                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
252         }
253
254         /* set_gain also sets red and blue balance */
255         pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
256         pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
257         pb0100_set_autogain_target(&sd->gspca_dev,
258                                    sensor_settings[AUTOGAIN_TARGET_IDX]);
259         pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
260
261         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
262         PDEBUG(D_STREAM, "Started stream, status: %d", err);
263
264         return (err < 0) ? err : 0;
265 }
266
267 static int pb0100_stop(struct sd *sd)
268 {
269         int err;
270
271         err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
272
273         if (err < 0)
274                 goto out;
275
276         /* Set bit 1 to zero */
277         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
278
279         PDEBUG(D_STREAM, "Halting stream");
280 out:
281         return (err < 0) ? err : 0;
282 }
283
284 static void pb0100_disconnect(struct sd *sd)
285 {
286         sd->sensor = NULL;
287         kfree(sd->sensor_priv);
288 }
289
290 /* FIXME: Sort the init commands out and put them into tables,
291           this is only for getting the camera to work */
292 /* FIXME: No error handling for now,
293           add this once the init has been converted to proper tables */
294 static int pb0100_init(struct sd *sd)
295 {
296         stv06xx_write_bridge(sd, STV_REG00, 1);
297         stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
298
299         /* Reset sensor */
300         stv06xx_write_sensor(sd, PB_RESET, 1);
301         stv06xx_write_sensor(sd, PB_RESET, 0);
302
303         /* Disable chip */
304         stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
305
306         /* Gain stuff...*/
307         stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
308         stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
309
310         /* Set up auto-exposure */
311         /* ADC VREF_HI new setting for a transition
312           from the Expose1 to the Expose2 setting */
313         stv06xx_write_sensor(sd, PB_R28, 12);
314         /* gain max for autoexposure */
315         stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
316         /* gain min for autoexposure  */
317         stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
318         /* Maximum frame integration time (programmed into R8)
319            allowed for auto-exposure routine */
320         stv06xx_write_sensor(sd, PB_R54, 3);
321         /* Minimum frame integration time (programmed into R8)
322            allowed for auto-exposure routine */
323         stv06xx_write_sensor(sd, PB_R55, 0);
324         stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
325         /* R15  Expose0 (maximum that auto-exposure may use) */
326         stv06xx_write_sensor(sd, PB_R15, 800);
327         /* R17  Expose2 (minimum that auto-exposure may use) */
328         stv06xx_write_sensor(sd, PB_R17, 10);
329
330         stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
331
332         /* 0x14 */
333         stv06xx_write_sensor(sd, PB_VOFFSET, 0);
334         /* 0x0D */
335         stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
336         /* Set black level (important!) */
337         stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
338
339         /* ??? */
340         stv06xx_write_bridge(sd, STV_REG00, 0x11);
341         stv06xx_write_bridge(sd, STV_REG03, 0x45);
342         stv06xx_write_bridge(sd, STV_REG04, 0x07);
343
344         /* Scan/timing for the sensor */
345         stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
346         stv06xx_write_sensor(sd, PB_CFILLIN, 14);
347         stv06xx_write_sensor(sd, PB_VBL, 0);
348         stv06xx_write_sensor(sd, PB_FINTTIME, 0);
349         stv06xx_write_sensor(sd, PB_RINTTIME, 123);
350
351         stv06xx_write_bridge(sd, STV_REG01, 0xc2);
352         stv06xx_write_bridge(sd, STV_REG02, 0xb0);
353         return 0;
354 }
355
356 static int pb0100_dump(struct sd *sd)
357 {
358         return 0;
359 }
360
361 static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
362 {
363         struct sd *sd = (struct sd *) gspca_dev;
364         s32 *sensor_settings = sd->sensor_priv;
365
366         *val = sensor_settings[GAIN_IDX];
367
368         return 0;
369 }
370
371 static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
372 {
373         int err;
374         struct sd *sd = (struct sd *) gspca_dev;
375         s32 *sensor_settings = sd->sensor_priv;
376
377         if (sensor_settings[AUTOGAIN_IDX])
378                 return -EBUSY;
379
380         sensor_settings[GAIN_IDX] = val;
381         err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
382         if (!err)
383                 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
384         PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
385
386         if (!err)
387                 err = pb0100_set_red_balance(gspca_dev,
388                                              sensor_settings[RED_BALANCE_IDX]);
389         if (!err)
390                 err = pb0100_set_blue_balance(gspca_dev,
391                                             sensor_settings[BLUE_BALANCE_IDX]);
392
393         return err;
394 }
395
396 static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
397 {
398         struct sd *sd = (struct sd *) gspca_dev;
399         s32 *sensor_settings = sd->sensor_priv;
400
401         *val = sensor_settings[RED_BALANCE_IDX];
402
403         return 0;
404 }
405
406 static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
407 {
408         int err;
409         struct sd *sd = (struct sd *) gspca_dev;
410         s32 *sensor_settings = sd->sensor_priv;
411
412         if (sensor_settings[AUTOGAIN_IDX])
413                 return -EBUSY;
414
415         sensor_settings[RED_BALANCE_IDX] = val;
416         val += sensor_settings[GAIN_IDX];
417         if (val < 0)
418                 val = 0;
419         else if (val > 255)
420                 val = 255;
421
422         err = stv06xx_write_sensor(sd, PB_RGAIN, val);
423         PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
424
425         return err;
426 }
427
428 static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
429 {
430         struct sd *sd = (struct sd *) gspca_dev;
431         s32 *sensor_settings = sd->sensor_priv;
432
433         *val = sensor_settings[BLUE_BALANCE_IDX];
434
435         return 0;
436 }
437
438 static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
439 {
440         int err;
441         struct sd *sd = (struct sd *) gspca_dev;
442         s32 *sensor_settings = sd->sensor_priv;
443
444         if (sensor_settings[AUTOGAIN_IDX])
445                 return -EBUSY;
446
447         sensor_settings[BLUE_BALANCE_IDX] = val;
448         val += sensor_settings[GAIN_IDX];
449         if (val < 0)
450                 val = 0;
451         else if (val > 255)
452                 val = 255;
453
454         err = stv06xx_write_sensor(sd, PB_BGAIN, val);
455         PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
456
457         return err;
458 }
459
460 static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
461 {
462         struct sd *sd = (struct sd *) gspca_dev;
463         s32 *sensor_settings = sd->sensor_priv;
464
465         *val = sensor_settings[EXPOSURE_IDX];
466
467         return 0;
468 }
469
470 static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
471 {
472         int err;
473         struct sd *sd = (struct sd *) gspca_dev;
474         s32 *sensor_settings = sd->sensor_priv;
475
476         if (sensor_settings[AUTOGAIN_IDX])
477                 return -EBUSY;
478
479         sensor_settings[EXPOSURE_IDX] = val;
480         err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
481         PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
482
483         return err;
484 }
485
486 static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
487 {
488         struct sd *sd = (struct sd *) gspca_dev;
489         s32 *sensor_settings = sd->sensor_priv;
490
491         *val = sensor_settings[AUTOGAIN_IDX];
492
493         return 0;
494 }
495
496 static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
497 {
498         int err;
499         struct sd *sd = (struct sd *) gspca_dev;
500         s32 *sensor_settings = sd->sensor_priv;
501
502         sensor_settings[AUTOGAIN_IDX] = val;
503         if (sensor_settings[AUTOGAIN_IDX]) {
504                 if (sensor_settings[NATURAL_IDX])
505                         val = BIT(6)|BIT(4)|BIT(0);
506                 else
507                         val = BIT(4)|BIT(0);
508         } else
509                 val = 0;
510
511         err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
512         PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
513                sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
514                err);
515
516         return err;
517 }
518
519 static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
520 {
521         struct sd *sd = (struct sd *) gspca_dev;
522         s32 *sensor_settings = sd->sensor_priv;
523
524         *val = sensor_settings[AUTOGAIN_TARGET_IDX];
525
526         return 0;
527 }
528
529 static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
530 {
531         int err, totalpixels, brightpixels, darkpixels;
532         struct sd *sd = (struct sd *) gspca_dev;
533         s32 *sensor_settings = sd->sensor_priv;
534
535         sensor_settings[AUTOGAIN_TARGET_IDX] = val;
536
537         /* Number of pixels counted by the sensor when subsampling the pixels.
538          * Slightly larger than the real value to avoid oscillation */
539         totalpixels = gspca_dev->width * gspca_dev->height;
540         totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
541
542         brightpixels = (totalpixels * val) >> 8;
543         darkpixels   = totalpixels - brightpixels;
544         err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
545         if (!err)
546                 err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
547
548         PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
549
550         return err;
551 }
552
553 static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
554 {
555         struct sd *sd = (struct sd *) gspca_dev;
556         s32 *sensor_settings = sd->sensor_priv;
557
558         *val = sensor_settings[NATURAL_IDX];
559
560         return 0;
561 }
562
563 static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
564 {
565         struct sd *sd = (struct sd *) gspca_dev;
566         s32 *sensor_settings = sd->sensor_priv;
567
568         sensor_settings[NATURAL_IDX] = val;
569
570         return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
571 }