]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/usb/media/zc0301_pas202bcb.c
[PATCH] USB: ZC0301 driver updates
[net-next-2.6.git] / drivers / usb / media / zc0301_pas202bcb.c
1 /***************************************************************************
2  * Plug-in for PAS202BCB image sensor connected to the ZC030! Image        *
3  * Processor and Control Chip                                              *
4  *                                                                         *
5  * Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it>       *
6  *                                                                         *
7  * Initialization values of the ZC0301 have been taken from the SPCA5XX    *
8  * driver maintained by Michel Xhaard <mxhaard@magic.fr>                   *
9  *                                                                         *
10  * This program is free software; you can redistribute it and/or modify    *
11  * it under the terms of the GNU General Public License as published by    *
12  * the Free Software Foundation; either version 2 of the License, or       *
13  * (at your option) any later version.                                     *
14  *                                                                         *
15  * This program is distributed in the hope that it will be useful,         *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
18  * GNU General Public License for more details.                            *
19  *                                                                         *
20  * You should have received a copy of the GNU General Public License       *
21  * along with this program; if not, write to the Free Software             *
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               *
23  ***************************************************************************/
24
25 #include <linux/delay.h>
26 #include "zc0301_sensor.h"
27
28
29 static struct zc0301_sensor pas202bcb;
30
31
32 static int pas202bcb_init(struct zc0301_device* cam)
33 {
34         int err = 0;
35
36         err += zc0301_write_reg(cam, 0x0002, 0x00);
37         err += zc0301_write_reg(cam, 0x0003, 0x02);
38         err += zc0301_write_reg(cam, 0x0004, 0x80);
39         err += zc0301_write_reg(cam, 0x0005, 0x01);
40         err += zc0301_write_reg(cam, 0x0006, 0xE0);
41         err += zc0301_write_reg(cam, 0x0098, 0x00);
42         err += zc0301_write_reg(cam, 0x009A, 0x03);
43         err += zc0301_write_reg(cam, 0x011A, 0x00);
44         err += zc0301_write_reg(cam, 0x011C, 0x03);
45         err += zc0301_write_reg(cam, 0x009B, 0x01);
46         err += zc0301_write_reg(cam, 0x009C, 0xE6);
47         err += zc0301_write_reg(cam, 0x009D, 0x02);
48         err += zc0301_write_reg(cam, 0x009E, 0x86);
49
50         err += zc0301_i2c_write(cam, 0x02, 0x02);
51         err += zc0301_i2c_write(cam, 0x0A, 0x01);
52         err += zc0301_i2c_write(cam, 0x0B, 0x01);
53         err += zc0301_i2c_write(cam, 0x0D, 0x00);
54         err += zc0301_i2c_write(cam, 0x12, 0x05);
55         err += zc0301_i2c_write(cam, 0x13, 0x63);
56         err += zc0301_i2c_write(cam, 0x15, 0x70);
57
58         err += zc0301_write_reg(cam, 0x0101, 0xB7);
59         err += zc0301_write_reg(cam, 0x0100, 0x0D);
60         err += zc0301_write_reg(cam, 0x0189, 0x06);
61         err += zc0301_write_reg(cam, 0x01AD, 0x00);
62         err += zc0301_write_reg(cam, 0x01C5, 0x03);
63         err += zc0301_write_reg(cam, 0x01CB, 0x13);
64         err += zc0301_write_reg(cam, 0x0250, 0x08);
65         err += zc0301_write_reg(cam, 0x0301, 0x08);
66         err += zc0301_write_reg(cam, 0x018D, 0x70);
67         err += zc0301_write_reg(cam, 0x0008, 0x03);
68         err += zc0301_write_reg(cam, 0x01C6, 0x04);
69         err += zc0301_write_reg(cam, 0x01CB, 0x07);
70         err += zc0301_write_reg(cam, 0x0120, 0x11);
71         err += zc0301_write_reg(cam, 0x0121, 0x37);
72         err += zc0301_write_reg(cam, 0x0122, 0x58);
73         err += zc0301_write_reg(cam, 0x0123, 0x79);
74         err += zc0301_write_reg(cam, 0x0124, 0x91);
75         err += zc0301_write_reg(cam, 0x0125, 0xA6);
76         err += zc0301_write_reg(cam, 0x0126, 0xB8);
77         err += zc0301_write_reg(cam, 0x0127, 0xC7);
78         err += zc0301_write_reg(cam, 0x0128, 0xD3);
79         err += zc0301_write_reg(cam, 0x0129, 0xDE);
80         err += zc0301_write_reg(cam, 0x012A, 0xE6);
81         err += zc0301_write_reg(cam, 0x012B, 0xED);
82         err += zc0301_write_reg(cam, 0x012C, 0xF3);
83         err += zc0301_write_reg(cam, 0x012D, 0xF8);
84         err += zc0301_write_reg(cam, 0x012E, 0xFB);
85         err += zc0301_write_reg(cam, 0x012F, 0xFF);
86         err += zc0301_write_reg(cam, 0x0130, 0x26);
87         err += zc0301_write_reg(cam, 0x0131, 0x23);
88         err += zc0301_write_reg(cam, 0x0132, 0x20);
89         err += zc0301_write_reg(cam, 0x0133, 0x1C);
90         err += zc0301_write_reg(cam, 0x0134, 0x16);
91         err += zc0301_write_reg(cam, 0x0135, 0x13);
92         err += zc0301_write_reg(cam, 0x0136, 0x10);
93         err += zc0301_write_reg(cam, 0x0137, 0x0D);
94         err += zc0301_write_reg(cam, 0x0138, 0x0B);
95         err += zc0301_write_reg(cam, 0x0139, 0x09);
96         err += zc0301_write_reg(cam, 0x013A, 0x07);
97         err += zc0301_write_reg(cam, 0x013B, 0x06);
98         err += zc0301_write_reg(cam, 0x013C, 0x05);
99         err += zc0301_write_reg(cam, 0x013D, 0x04);
100         err += zc0301_write_reg(cam, 0x013E, 0x03);
101         err += zc0301_write_reg(cam, 0x013F, 0x02);
102         err += zc0301_write_reg(cam, 0x010A, 0x4C);
103         err += zc0301_write_reg(cam, 0x010B, 0xF5);
104         err += zc0301_write_reg(cam, 0x010C, 0xFF);
105         err += zc0301_write_reg(cam, 0x010D, 0xF9);
106         err += zc0301_write_reg(cam, 0x010E, 0x51);
107         err += zc0301_write_reg(cam, 0x010F, 0xF5);
108         err += zc0301_write_reg(cam, 0x0110, 0xFB);
109         err += zc0301_write_reg(cam, 0x0111, 0xED);
110         err += zc0301_write_reg(cam, 0x0112, 0x5F);
111         err += zc0301_write_reg(cam, 0x0180, 0x00);
112         err += zc0301_write_reg(cam, 0x0019, 0x00);
113         err += zc0301_write_reg(cam, 0x0087, 0x20);
114         err += zc0301_write_reg(cam, 0x0088, 0x21);
115
116         err += zc0301_i2c_write(cam, 0x20, 0x02);
117         err += zc0301_i2c_write(cam, 0x21, 0x1B);
118         err += zc0301_i2c_write(cam, 0x03, 0x44);
119         err += zc0301_i2c_write(cam, 0x0E, 0x01);
120         err += zc0301_i2c_write(cam, 0x0F, 0x00);
121
122         err += zc0301_write_reg(cam, 0x01A9, 0x14);
123         err += zc0301_write_reg(cam, 0x01AA, 0x24);
124         err += zc0301_write_reg(cam, 0x0190, 0x00);
125         err += zc0301_write_reg(cam, 0x0191, 0x02);
126         err += zc0301_write_reg(cam, 0x0192, 0x1B);
127         err += zc0301_write_reg(cam, 0x0195, 0x00);
128         err += zc0301_write_reg(cam, 0x0196, 0x00);
129         err += zc0301_write_reg(cam, 0x0197, 0x4D);
130         err += zc0301_write_reg(cam, 0x018C, 0x10);
131         err += zc0301_write_reg(cam, 0x018F, 0x20);
132         err += zc0301_write_reg(cam, 0x001D, 0x44);
133         err += zc0301_write_reg(cam, 0x001E, 0x6F);
134         err += zc0301_write_reg(cam, 0x001F, 0xAD);
135         err += zc0301_write_reg(cam, 0x0020, 0xEB);
136         err += zc0301_write_reg(cam, 0x0087, 0x0F);
137         err += zc0301_write_reg(cam, 0x0088, 0x0E);
138         err += zc0301_write_reg(cam, 0x0180, 0x40);
139         err += zc0301_write_reg(cam, 0x0192, 0x1B);
140         err += zc0301_write_reg(cam, 0x0191, 0x02);
141         err += zc0301_write_reg(cam, 0x0190, 0x00);
142         err += zc0301_write_reg(cam, 0x0116, 0x1D);
143         err += zc0301_write_reg(cam, 0x0117, 0x40);
144         err += zc0301_write_reg(cam, 0x0118, 0x99);
145         err += zc0301_write_reg(cam, 0x0180, 0x42);
146         err += zc0301_write_reg(cam, 0x0116, 0x1D);
147         err += zc0301_write_reg(cam, 0x0117, 0x40);
148         err += zc0301_write_reg(cam, 0x0118, 0x99);
149         err += zc0301_write_reg(cam, 0x0007, 0x00);
150
151         err += zc0301_i2c_write(cam, 0x11, 0x01);
152
153         msleep(100);
154
155         return err;
156 }
157
158
159 static int pas202bcb_get_ctrl(struct zc0301_device* cam,
160                               struct v4l2_control* ctrl)
161 {
162         switch (ctrl->id) {
163         case V4L2_CID_EXPOSURE:
164                 {
165                         int r1 = zc0301_i2c_read(cam, 0x04, 1),
166                             r2 = zc0301_i2c_read(cam, 0x05, 1);
167                         if (r1 < 0 || r2 < 0)
168                                 return -EIO;
169                         ctrl->value = (r1 << 6) | (r2 & 0x3f);
170                 }
171                 return 0;
172         case V4L2_CID_RED_BALANCE:
173                 if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0)
174                         return -EIO;
175                 ctrl->value &= 0x0f;
176                 return 0;
177         case V4L2_CID_BLUE_BALANCE:
178                 if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0)
179                         return -EIO;
180                 ctrl->value &= 0x0f;
181                 return 0;
182         case V4L2_CID_GAIN:
183                 if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0)
184                         return -EIO;
185                 ctrl->value &= 0x1f;
186                 return 0;
187         case ZC0301_V4L2_CID_GREEN_BALANCE:
188                 if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0)
189                         return -EIO;
190                 ctrl->value &= 0x0f;
191                 return 0;
192         case ZC0301_V4L2_CID_DAC_MAGNITUDE:
193                 if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0)
194                         return -EIO;
195                 return 0;
196         default:
197                 return -EINVAL;
198         }
199 }
200
201
202 static int pas202bcb_set_ctrl(struct zc0301_device* cam,
203                               const struct v4l2_control* ctrl)
204 {
205         int err = 0;
206
207         switch (ctrl->id) {
208         case V4L2_CID_EXPOSURE:
209                 err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6);
210                 err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f);
211                 break;
212         case V4L2_CID_RED_BALANCE:
213                 err += zc0301_i2c_write(cam, 0x09, ctrl->value);
214                 break;
215         case V4L2_CID_BLUE_BALANCE:
216                 err += zc0301_i2c_write(cam, 0x07, ctrl->value);
217                 break;
218         case V4L2_CID_GAIN:
219                 err += zc0301_i2c_write(cam, 0x10, ctrl->value);
220                 break;
221         case ZC0301_V4L2_CID_GREEN_BALANCE:
222                 err += zc0301_i2c_write(cam, 0x08, ctrl->value);
223                 break;
224         case ZC0301_V4L2_CID_DAC_MAGNITUDE:
225                 err += zc0301_i2c_write(cam, 0x0c, ctrl->value);
226                 break;
227         default:
228                 return -EINVAL;
229         }
230         err += zc0301_i2c_write(cam, 0x11, 0x01);
231
232         return err ? -EIO : 0;
233 }
234
235
236 static struct zc0301_sensor pas202bcb = {
237         .name = "PAS202BCB",
238         .init = &pas202bcb_init,
239         .qctrl = {
240                 {
241                         .id = V4L2_CID_EXPOSURE,
242                         .type = V4L2_CTRL_TYPE_INTEGER,
243                         .name = "exposure",
244                         .minimum = 0x01e5,
245                         .maximum = 0x3fff,
246                         .step = 0x0001,
247                         .default_value = 0x01e5,
248                         .flags = 0,
249                 },
250                 {
251                         .id = V4L2_CID_GAIN,
252                         .type = V4L2_CTRL_TYPE_INTEGER,
253                         .name = "global gain",
254                         .minimum = 0x00,
255                         .maximum = 0x1f,
256                         .step = 0x01,
257                         .default_value = 0x0c,
258                         .flags = 0,
259                 },
260                 {
261                         .id = V4L2_CID_RED_BALANCE,
262                         .type = V4L2_CTRL_TYPE_INTEGER,
263                         .name = "red balance",
264                         .minimum = 0x00,
265                         .maximum = 0x0f,
266                         .step = 0x01,
267                         .default_value = 0x01,
268                         .flags = 0,
269                 },
270                 {
271                         .id = V4L2_CID_BLUE_BALANCE,
272                         .type = V4L2_CTRL_TYPE_INTEGER,
273                         .name = "blue balance",
274                         .minimum = 0x00,
275                         .maximum = 0x0f,
276                         .step = 0x01,
277                         .default_value = 0x05,
278                         .flags = 0,
279                 },
280                 {
281                         .id = ZC0301_V4L2_CID_GREEN_BALANCE,
282                         .type = V4L2_CTRL_TYPE_INTEGER,
283                         .name = "green balance",
284                         .minimum = 0x00,
285                         .maximum = 0x0f,
286                         .step = 0x01,
287                         .default_value = 0x00,
288                         .flags = 0,
289                 },
290                 {
291                         .id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
292                         .type = V4L2_CTRL_TYPE_INTEGER,
293                         .name = "DAC magnitude",
294                         .minimum = 0x00,
295                         .maximum = 0xff,
296                         .step = 0x01,
297                         .default_value = 0x04,
298                         .flags = 0,
299                 },
300         },
301         .get_ctrl = &pas202bcb_get_ctrl,
302         .set_ctrl = &pas202bcb_set_ctrl,
303         .cropcap = {
304                 .bounds = {
305                         .left = 0,
306                         .top = 0,
307                         .width = 640,
308                         .height = 480,
309                 },
310                 .defrect = {
311                         .left = 0,
312                         .top = 0,
313                         .width = 640,
314                         .height = 480,
315                 },
316         },
317         .pix_format = {
318                 .width = 640,
319                 .height = 480,
320                 .pixelformat = V4L2_PIX_FMT_JPEG,
321                 .priv = 8,
322         },
323 };
324
325
326 int zc0301_probe_pas202bcb(struct zc0301_device* cam)
327 {
328         int r0 = 0, r1 = 0, err = 0;
329         unsigned int pid = 0;
330
331         err += zc0301_write_reg(cam, 0x0000, 0x01);
332         err += zc0301_write_reg(cam, 0x0010, 0x0e);
333         err += zc0301_write_reg(cam, 0x0001, 0x01);
334         err += zc0301_write_reg(cam, 0x0012, 0x03);
335         err += zc0301_write_reg(cam, 0x0012, 0x01);
336         err += zc0301_write_reg(cam, 0x008d, 0x08);
337
338         msleep(10);
339
340         r0 = zc0301_i2c_read(cam, 0x00, 1);
341         r1 = zc0301_i2c_read(cam, 0x01, 1);
342
343         if (r0 < 0 || r1 < 0 || err)
344                 return -EIO;
345
346         pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
347         if (pid != 0x017)
348                 return -ENODEV;
349
350         zc0301_attach_sensor(cam, &pas202bcb);
351
352         return 0;
353 }