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