]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
Merge branch 'simplify_PRT' into release
[linux-2.6-omap-h63xx.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 int pb0100_probe(struct sd *sd)
50 {
51         u16 sensor;
52         int i, err;
53         s32 *sensor_settings;
54
55         err = stv06xx_read_sensor(sd, PB_IDENT, &sensor);
56
57         if (err < 0)
58                 return -ENODEV;
59
60         if ((sensor >> 8) == 0x64) {
61                 sensor_settings = kmalloc(
62                                 stv06xx_sensor_pb0100.nctrls * sizeof(s32),
63                                 GFP_KERNEL);
64                 if (!sensor_settings)
65                         return -ENOMEM;
66
67                 info("Photobit pb0100 sensor detected");
68
69                 sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
70                 sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
71                 sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
72                 sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
73                 for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
74                         sensor_settings[i] = stv06xx_sensor_pb0100.
75                                              ctrls[i].qctrl.default_value;
76                 sd->sensor_priv = sensor_settings;
77
78                 return 0;
79         }
80
81         return -ENODEV;
82 }
83
84 static int pb0100_start(struct sd *sd)
85 {
86         int err;
87         struct cam *cam = &sd->gspca_dev.cam;
88         s32 *sensor_settings = sd->sensor_priv;
89         u32 mode = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
90
91         /* Setup sensor window */
92         if (mode & PB0100_CROP_TO_VGA) {
93                 stv06xx_write_sensor(sd, PB_RSTART, 30);
94                 stv06xx_write_sensor(sd, PB_CSTART, 20);
95                 stv06xx_write_sensor(sd, PB_RWSIZE, 240 - 1);
96                 stv06xx_write_sensor(sd, PB_CWSIZE, 320 - 1);
97         } else {
98                 stv06xx_write_sensor(sd, PB_RSTART, 8);
99                 stv06xx_write_sensor(sd, PB_CSTART, 4);
100                 stv06xx_write_sensor(sd, PB_RWSIZE, 288 - 1);
101                 stv06xx_write_sensor(sd, PB_CWSIZE, 352 - 1);
102         }
103
104         if (mode & PB0100_SUBSAMPLE) {
105                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02); /* Wrong, FIXME */
106                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
107
108                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x10);
109         } else {
110                 stv06xx_write_bridge(sd, STV_Y_CTRL, 0x01);
111                 stv06xx_write_bridge(sd, STV_X_CTRL, 0x0a);
112                 /* larger -> slower */
113                 stv06xx_write_bridge(sd, STV_SCAN_RATE, 0x20);
114         }
115
116         /* set_gain also sets red and blue balance */
117         pb0100_set_gain(&sd->gspca_dev, sensor_settings[GAIN_IDX]);
118         pb0100_set_exposure(&sd->gspca_dev, sensor_settings[EXPOSURE_IDX]);
119         pb0100_set_autogain_target(&sd->gspca_dev,
120                                    sensor_settings[AUTOGAIN_TARGET_IDX]);
121         pb0100_set_autogain(&sd->gspca_dev, sensor_settings[AUTOGAIN_IDX]);
122
123         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
124         PDEBUG(D_STREAM, "Started stream, status: %d", err);
125
126         return (err < 0) ? err : 0;
127 }
128
129 static int pb0100_stop(struct sd *sd)
130 {
131         int err;
132
133         err = stv06xx_write_sensor(sd, PB_ABORTFRAME, 1);
134
135         if (err < 0)
136                 goto out;
137
138         /* Set bit 1 to zero */
139         err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
140
141         PDEBUG(D_STREAM, "Halting stream");
142 out:
143         return (err < 0) ? err : 0;
144 }
145
146 /* FIXME: Sort the init commands out and put them into tables,
147           this is only for getting the camera to work */
148 /* FIXME: No error handling for now,
149           add this once the init has been converted to proper tables */
150 static int pb0100_init(struct sd *sd)
151 {
152         stv06xx_write_bridge(sd, STV_REG00, 1);
153         stv06xx_write_bridge(sd, STV_SCAN_RATE, 0);
154
155         /* Reset sensor */
156         stv06xx_write_sensor(sd, PB_RESET, 1);
157         stv06xx_write_sensor(sd, PB_RESET, 0);
158
159         /* Disable chip */
160         stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
161
162         /* Gain stuff...*/
163         stv06xx_write_sensor(sd, PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6));
164         stv06xx_write_sensor(sd, PB_ADCGLOBALGAIN, 12);
165
166         /* Set up auto-exposure */
167         /* ADC VREF_HI new setting for a transition
168           from the Expose1 to the Expose2 setting */
169         stv06xx_write_sensor(sd, PB_R28, 12);
170         /* gain max for autoexposure */
171         stv06xx_write_sensor(sd, PB_ADCMAXGAIN, 180);
172         /* gain min for autoexposure  */
173         stv06xx_write_sensor(sd, PB_ADCMINGAIN, 12);
174         /* Maximum frame integration time (programmed into R8)
175            allowed for auto-exposure routine */
176         stv06xx_write_sensor(sd, PB_R54, 3);
177         /* Minimum frame integration time (programmed into R8)
178            allowed for auto-exposure routine */
179         stv06xx_write_sensor(sd, PB_R55, 0);
180         stv06xx_write_sensor(sd, PB_UPDATEINT, 1);
181         /* R15  Expose0 (maximum that auto-exposure may use) */
182         stv06xx_write_sensor(sd, PB_R15, 800);
183         /* R17  Expose2 (minimum that auto-exposure may use) */
184         stv06xx_write_sensor(sd, PB_R17, 10);
185
186         stv06xx_write_sensor(sd, PB_EXPGAIN, 0);
187
188         /* 0x14 */
189         stv06xx_write_sensor(sd, PB_VOFFSET, 0);
190         /* 0x0D */
191         stv06xx_write_sensor(sd, PB_ADCGAINH, 11);
192         /* Set black level (important!) */
193         stv06xx_write_sensor(sd, PB_ADCGAINL, 0);
194
195         /* ??? */
196         stv06xx_write_bridge(sd, STV_REG00, 0x11);
197         stv06xx_write_bridge(sd, STV_REG03, 0x45);
198         stv06xx_write_bridge(sd, STV_REG04, 0x07);
199
200         /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */
201         stv06xx_write_bridge(sd, STV_ISO_SIZE_L, 847);
202
203         /* Scan/timing for the sensor */
204         stv06xx_write_sensor(sd, PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1));
205         stv06xx_write_sensor(sd, PB_CFILLIN, 14);
206         stv06xx_write_sensor(sd, PB_VBL, 0);
207         stv06xx_write_sensor(sd, PB_FINTTIME, 0);
208         stv06xx_write_sensor(sd, PB_RINTTIME, 123);
209
210         stv06xx_write_bridge(sd, STV_REG01, 0xc2);
211         stv06xx_write_bridge(sd, STV_REG02, 0xb0);
212         return 0;
213 }
214
215 static int pb0100_dump(struct sd *sd)
216 {
217         return 0;
218 }
219
220 static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
221 {
222         struct sd *sd = (struct sd *) gspca_dev;
223         s32 *sensor_settings = sd->sensor_priv;
224
225         *val = sensor_settings[GAIN_IDX];
226
227         return 0;
228 }
229
230 static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
231 {
232         int err;
233         struct sd *sd = (struct sd *) gspca_dev;
234         s32 *sensor_settings = sd->sensor_priv;
235
236         if (sensor_settings[AUTOGAIN_IDX])
237                 return -EBUSY;
238
239         sensor_settings[GAIN_IDX] = val;
240         err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
241         if (!err)
242                 err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
243         PDEBUG(D_V4L2, "Set green gain to %d, status: %d", val, err);
244
245         if (!err)
246                 err = pb0100_set_red_balance(gspca_dev,
247                                              sensor_settings[RED_BALANCE_IDX]);
248         if (!err)
249                 err = pb0100_set_blue_balance(gspca_dev,
250                                             sensor_settings[BLUE_BALANCE_IDX]);
251
252         return err;
253 }
254
255 static int pb0100_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
256 {
257         struct sd *sd = (struct sd *) gspca_dev;
258         s32 *sensor_settings = sd->sensor_priv;
259
260         *val = sensor_settings[RED_BALANCE_IDX];
261
262         return 0;
263 }
264
265 static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
266 {
267         int err;
268         struct sd *sd = (struct sd *) gspca_dev;
269         s32 *sensor_settings = sd->sensor_priv;
270
271         if (sensor_settings[AUTOGAIN_IDX])
272                 return -EBUSY;
273
274         sensor_settings[RED_BALANCE_IDX] = val;
275         val += sensor_settings[GAIN_IDX];
276         if (val < 0)
277                 val = 0;
278         else if (val > 255)
279                 val = 255;
280
281         err = stv06xx_write_sensor(sd, PB_RGAIN, val);
282         PDEBUG(D_V4L2, "Set red gain to %d, status: %d", val, err);
283
284         return err;
285 }
286
287 static int pb0100_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
288 {
289         struct sd *sd = (struct sd *) gspca_dev;
290         s32 *sensor_settings = sd->sensor_priv;
291
292         *val = sensor_settings[BLUE_BALANCE_IDX];
293
294         return 0;
295 }
296
297 static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
298 {
299         int err;
300         struct sd *sd = (struct sd *) gspca_dev;
301         s32 *sensor_settings = sd->sensor_priv;
302
303         if (sensor_settings[AUTOGAIN_IDX])
304                 return -EBUSY;
305
306         sensor_settings[BLUE_BALANCE_IDX] = val;
307         val += sensor_settings[GAIN_IDX];
308         if (val < 0)
309                 val = 0;
310         else if (val > 255)
311                 val = 255;
312
313         err = stv06xx_write_sensor(sd, PB_BGAIN, val);
314         PDEBUG(D_V4L2, "Set blue gain to %d, status: %d", val, err);
315
316         return err;
317 }
318
319 static int pb0100_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
320 {
321         struct sd *sd = (struct sd *) gspca_dev;
322         s32 *sensor_settings = sd->sensor_priv;
323
324         *val = sensor_settings[EXPOSURE_IDX];
325
326         return 0;
327 }
328
329 static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
330 {
331         int err;
332         struct sd *sd = (struct sd *) gspca_dev;
333         s32 *sensor_settings = sd->sensor_priv;
334
335         if (sensor_settings[AUTOGAIN_IDX])
336                 return -EBUSY;
337
338         sensor_settings[EXPOSURE_IDX] = val;
339         err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
340         PDEBUG(D_V4L2, "Set exposure to %d, status: %d", val, err);
341
342         return err;
343 }
344
345 static int pb0100_get_autogain(struct gspca_dev *gspca_dev, __s32 *val)
346 {
347         struct sd *sd = (struct sd *) gspca_dev;
348         s32 *sensor_settings = sd->sensor_priv;
349
350         *val = sensor_settings[AUTOGAIN_IDX];
351
352         return 0;
353 }
354
355 static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
356 {
357         int err;
358         struct sd *sd = (struct sd *) gspca_dev;
359         s32 *sensor_settings = sd->sensor_priv;
360
361         sensor_settings[AUTOGAIN_IDX] = val;
362         if (sensor_settings[AUTOGAIN_IDX]) {
363                 if (sensor_settings[NATURAL_IDX])
364                         val = BIT(6)|BIT(4)|BIT(0);
365                 else
366                         val = BIT(4)|BIT(0);
367         } else
368                 val = 0;
369
370         err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
371         PDEBUG(D_V4L2, "Set autogain to %d (natural: %d), status: %d",
372                sensor_settings[AUTOGAIN_IDX], sensor_settings[NATURAL_IDX],
373                err);
374
375         return err;
376 }
377
378 static int pb0100_get_autogain_target(struct gspca_dev *gspca_dev, __s32 *val)
379 {
380         struct sd *sd = (struct sd *) gspca_dev;
381         s32 *sensor_settings = sd->sensor_priv;
382
383         *val = sensor_settings[AUTOGAIN_TARGET_IDX];
384
385         return 0;
386 }
387
388 static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
389 {
390         int err, totalpixels, brightpixels, darkpixels;
391         struct sd *sd = (struct sd *) gspca_dev;
392         s32 *sensor_settings = sd->sensor_priv;
393
394         sensor_settings[AUTOGAIN_TARGET_IDX] = val;
395
396         /* Number of pixels counted by the sensor when subsampling the pixels.
397          * Slightly larger than the real value to avoid oscillation */
398         totalpixels = gspca_dev->width * gspca_dev->height;
399         totalpixels = totalpixels/(8*8) + totalpixels/(64*64);
400
401         brightpixels = (totalpixels * val) >> 8;
402         darkpixels   = totalpixels - brightpixels;
403         err = stv06xx_write_sensor(sd, PB_R21, brightpixels);
404         if (!err)
405                 err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
406
407         PDEBUG(D_V4L2, "Set autogain target to %d, status: %d", val, err);
408
409         return err;
410 }
411
412 static int pb0100_get_natural(struct gspca_dev *gspca_dev, __s32 *val)
413 {
414         struct sd *sd = (struct sd *) gspca_dev;
415         s32 *sensor_settings = sd->sensor_priv;
416
417         *val = sensor_settings[NATURAL_IDX];
418
419         return 0;
420 }
421
422 static int pb0100_set_natural(struct gspca_dev *gspca_dev, __s32 val)
423 {
424         struct sd *sd = (struct sd *) gspca_dev;
425         s32 *sensor_settings = sd->sensor_priv;
426
427         sensor_settings[NATURAL_IDX] = val;
428
429         return pb0100_set_autogain(gspca_dev, sensor_settings[AUTOGAIN_IDX]);
430 }