Merge branch 'iommu-fixes-2.6.28' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6] / drivers / media / video / gspca / m5602 / m5602_s5k4aa.c
1 /*
2  * Driver for the s5k4aa sensor
3  *
4  * Copyright (C) 2008 Erik AndrĂ©n
5  * Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
6  * Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
7  *
8  * Portions of code to USB interface and ALi driver software,
9  * Copyright (c) 2006 Willem Duinker
10  * v4l2 interface modeled after the V4L2 driver
11  * for SN9C10x PC Camera Controllers
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License as
15  * published by the Free Software Foundation, version 2.
16  *
17  */
18
19 #include "m5602_s5k4aa.h"
20
21 int s5k4aa_probe(struct sd *sd)
22 {
23         u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
24         const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
25         int i, err = 0;
26
27         if (force_sensor) {
28                 if (force_sensor == S5K4AA_SENSOR) {
29                         info("Forcing a %s sensor", s5k4aa.name);
30                         goto sensor_found;
31                 }
32                 /* If we want to force another sensor, don't try to probe this
33                  * one */
34                 return -ENODEV;
35         }
36
37         info("Probing for a s5k4aa sensor");
38
39         /* Preinit the sensor */
40         for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
41                 u8 data[2] = {0x00, 0x00};
42
43                 switch (preinit_s5k4aa[i][0]) {
44                 case BRIDGE:
45                         err = m5602_write_bridge(sd,
46                                                  preinit_s5k4aa[i][1],
47                                                  preinit_s5k4aa[i][2]);
48                         break;
49
50                 case SENSOR:
51                         data[0] = preinit_s5k4aa[i][2];
52                         err = s5k4aa_write_sensor(sd,
53                                                   preinit_s5k4aa[i][1],
54                                                   data, 1);
55                         break;
56
57                 case SENSOR_LONG:
58                         data[0] = preinit_s5k4aa[i][2];
59                         data[1] = preinit_s5k4aa[i][3];
60                         err = s5k4aa_write_sensor(sd,
61                                                   preinit_s5k4aa[i][1],
62                                                   data, 2);
63                         break;
64                 default:
65                         info("Invalid stream command, exiting init");
66                         return -EINVAL;
67                 }
68         }
69
70         /* Test some registers, but we don't know their exact meaning yet */
71         if (s5k4aa_read_sensor(sd, 0x00, prod_id, sizeof(prod_id)))
72                 return -ENODEV;
73
74         if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
75                 return -ENODEV;
76         else
77                 info("Detected a s5k4aa sensor");
78 sensor_found:
79         sd->gspca_dev.cam.cam_mode = s5k4aa.modes;
80         sd->gspca_dev.cam.nmodes = s5k4aa.nmodes;
81         sd->desc->ctrls = s5k4aa.ctrls;
82         sd->desc->nctrls = s5k4aa.nctrls;
83
84         return 0;
85 }
86
87 int s5k4aa_read_sensor(struct sd *sd, const u8 address,
88                        u8 *i2c_data, const u8 len)
89 {
90         int err, i;
91
92         do {
93                 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
94         } while ((*i2c_data & I2C_BUSY) && !err);
95         if (err < 0)
96                 goto out;
97
98         err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
99                                  sd->sensor->i2c_slave_id);
100         if (err < 0)
101                 goto out;
102
103         err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
104         if (err < 0)
105                 goto out;
106
107         err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len);
108         if (err < 0)
109                 goto out;
110
111         do {
112                 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
113         } while ((*i2c_data & I2C_BUSY) && !err);
114         if (err < 0)
115                 goto out;
116
117         for (i = 0; (i < len) & !err; i++) {
118                 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
119
120                 PDEBUG(D_CONF, "Reading sensor register "
121                                   "0x%x containing 0x%x ", address, *i2c_data);
122         }
123 out:
124         return (err < 0) ? err : 0;
125 }
126
127 int s5k4aa_write_sensor(struct sd *sd, const u8 address,
128                         u8 *i2c_data, const u8 len)
129 {
130         int err, i;
131         u8 *p;
132         struct usb_device *udev = sd->gspca_dev.dev;
133         __u8 *buf = sd->gspca_dev.usb_buf;
134
135         /* No sensor with a data width larger than 16 bits has yet been seen */
136         if (len > 2 || !len)
137                 return -EINVAL;
138
139         memcpy(buf, sensor_urb_skeleton,
140                sizeof(sensor_urb_skeleton));
141
142         buf[11] = sd->sensor->i2c_slave_id;
143         buf[15] = address;
144
145         /* Special case larger sensor writes */
146         p = buf + 16;
147
148         /* Copy a four byte write sequence for each byte to be written to */
149         for (i = 0; i < len; i++) {
150                 memcpy(p, sensor_urb_skeleton + 16, 4);
151                 p[3] = i2c_data[i];
152                 p += 4;
153                 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
154                        address, i2c_data[i]);
155         }
156
157         /* Copy the tailer */
158         memcpy(p, sensor_urb_skeleton + 20, 4);
159
160         /* Set the total length */
161         p[3] = 0x10 + len;
162
163         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164                               0x04, 0x40, 0x19,
165                               0x0000, buf,
166                               20 + len * 4, M5602_URB_MSG_TIMEOUT);
167
168         return (err < 0) ? err : 0;
169 }
170
171 int s5k4aa_init(struct sd *sd)
172 {
173         int i, err = 0;
174
175         for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
176                 u8 data[2] = {0x00, 0x00};
177
178                 switch (init_s5k4aa[i][0]) {
179                 case BRIDGE:
180                         err = m5602_write_bridge(sd,
181                                 init_s5k4aa[i][1],
182                                 init_s5k4aa[i][2]);
183                         break;
184
185                 case SENSOR:
186                         data[0] = init_s5k4aa[i][2];
187                         err = s5k4aa_write_sensor(sd,
188                                 init_s5k4aa[i][1], data, 1);
189                         break;
190
191                 case SENSOR_LONG:
192                         data[0] = init_s5k4aa[i][2];
193                         data[1] = init_s5k4aa[i][3];
194                         err = s5k4aa_write_sensor(sd,
195                                 init_s5k4aa[i][1], data, 2);
196                         break;
197                 default:
198                         info("Invalid stream command, exiting init");
199                         return -EINVAL;
200                 }
201         }
202
203         if (dump_sensor)
204                 s5k4aa_dump_registers(sd);
205
206         if (!err && dmi_check_system(s5k4aa_vflip_dmi_table)) {
207                 u8 data = 0x02;
208                 info("vertical flip quirk active");
209                 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
210                 s5k4aa_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
211                 data |= S5K4AA_RM_V_FLIP;
212                 data &= ~S5K4AA_RM_H_FLIP;
213                 s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
214
215                 /* Decrement COLSTART to preserve color order (BGGR) */
216                 s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
217                 data--;
218                 s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
219
220                 /* Increment ROWSTART to preserve color order (BGGR) */
221                 s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
222                 data++;
223                 s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
224         }
225
226         return (err < 0) ? err : 0;
227 }
228
229 int s5k4aa_power_down(struct sd *sd)
230 {
231         return 0;
232 }
233
234 int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
235 {
236         struct sd *sd = (struct sd *) gspca_dev;
237         u8 data = S5K4AA_PAGE_MAP_2;
238         int err;
239
240         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
241         if (err < 0)
242                 goto out;
243
244         err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
245         if (err < 0)
246                 goto out;
247
248         *val = data << 8;
249         err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
250         *val |= data;
251         PDEBUG(D_V4L2, "Read exposure %d", *val);
252 out:
253         return (err < 0) ? err : 0;
254 }
255
256 int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
257 {
258         struct sd *sd = (struct sd *) gspca_dev;
259         u8 data = S5K4AA_PAGE_MAP_2;
260         int err;
261
262         PDEBUG(D_V4L2, "Set exposure to %d", val);
263         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
264         if (err < 0)
265                 goto out;
266         data = (val >> 8) & 0xff;
267         err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
268         if (err < 0)
269                 goto out;
270         data = val & 0xff;
271         err = s5k4aa_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
272 out:
273         return (err < 0) ? err : 0;
274 }
275
276 int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
277 {
278         struct sd *sd = (struct sd *) gspca_dev;
279         u8 data = S5K4AA_PAGE_MAP_2;
280         int err;
281
282         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
283         if (err < 0)
284                 goto out;
285
286         err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
287         *val = (data & S5K4AA_RM_V_FLIP) >> 7;
288         PDEBUG(D_V4L2, "Read vertical flip %d", *val);
289
290 out:
291         return (err < 0) ? err : 0;
292 }
293
294 int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
295 {
296         struct sd *sd = (struct sd *) gspca_dev;
297         u8 data = S5K4AA_PAGE_MAP_2;
298         int err;
299
300         PDEBUG(D_V4L2, "Set vertical flip to %d", val);
301         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
302         if (err < 0)
303                 goto out;
304         err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
305         if (err < 0)
306                 goto out;
307         data = ((data & ~S5K4AA_RM_V_FLIP)
308                         | ((val & 0x01) << 7));
309         err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
310         if (err < 0)
311                 goto out;
312
313         if (val) {
314                 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
315                 if (err < 0)
316                         goto out;
317
318                 data++;
319                 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
320         } else {
321                 err = s5k4aa_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
322                 if (err < 0)
323                         goto out;
324
325                 data--;
326                 err = s5k4aa_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
327         }
328 out:
329         return (err < 0) ? err : 0;
330 }
331
332 int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
333 {
334         struct sd *sd = (struct sd *) gspca_dev;
335         u8 data = S5K4AA_PAGE_MAP_2;
336         int err;
337
338         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
339         if (err < 0)
340                 goto out;
341
342         err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
343         *val = (data & S5K4AA_RM_H_FLIP) >> 6;
344         PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
345 out:
346         return (err < 0) ? err : 0;
347 }
348
349 int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
350 {
351         struct sd *sd = (struct sd *) gspca_dev;
352         u8 data = S5K4AA_PAGE_MAP_2;
353         int err;
354
355         PDEBUG(D_V4L2, "Set horizontal flip to %d",
356                val);
357         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
358         if (err < 0)
359                 goto out;
360         err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
361         if (err < 0)
362                 goto out;
363
364         data = ((data & ~S5K4AA_RM_H_FLIP) | ((val & 0x01) << 6));
365         err = s5k4aa_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
366         if (err < 0)
367                 goto out;
368
369         if (val) {
370                 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
371                 if (err < 0)
372                         goto out;
373                 data++;
374                 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
375                 if (err < 0)
376                         goto out;
377         } else {
378                 err = s5k4aa_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
379                 if (err < 0)
380                         goto out;
381                 data--;
382                 err = s5k4aa_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
383         }
384 out:
385         return (err < 0) ? err : 0;
386 }
387
388 int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
389 {
390         struct sd *sd = (struct sd *) gspca_dev;
391         u8 data = S5K4AA_PAGE_MAP_2;
392         int err;
393
394         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
395         if (err < 0)
396                 goto out;
397
398         err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
399         *val = data;
400         PDEBUG(D_V4L2, "Read gain %d", *val);
401
402 out:
403         return (err < 0) ? err : 0;
404 }
405
406 int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
407 {
408         struct sd *sd = (struct sd *) gspca_dev;
409         u8 data = S5K4AA_PAGE_MAP_2;
410         int err;
411
412         PDEBUG(D_V4L2, "Set gain to %d", val);
413         err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
414         if (err < 0)
415                 goto out;
416
417         data = val & 0xff;
418         err = s5k4aa_write_sensor(sd, S5K4AA_GAIN_2, &data, 1);
419
420 out:
421         return (err < 0) ? err : 0;
422 }
423
424 void s5k4aa_dump_registers(struct sd *sd)
425 {
426         int address;
427         u8 page, old_page;
428         s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
429         for (page = 0; page < 16; page++) {
430                 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
431                 info("Dumping the s5k4aa register state for page 0x%x", page);
432                 for (address = 0; address <= 0xff; address++) {
433                         u8 value = 0;
434                         s5k4aa_read_sensor(sd, address, &value, 1);
435                         info("register 0x%x contains 0x%x",
436                              address, value);
437                 }
438         }
439         info("s5k4aa register state dump complete");
440
441         for (page = 0; page < 16; page++) {
442                 s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
443                 info("Probing for which registers that are "
444                      "read/write for page 0x%x", page);
445                 for (address = 0; address <= 0xff; address++) {
446                         u8 old_value, ctrl_value, test_value = 0xff;
447
448                         s5k4aa_read_sensor(sd, address, &old_value, 1);
449                         s5k4aa_write_sensor(sd, address, &test_value, 1);
450                         s5k4aa_read_sensor(sd, address, &ctrl_value, 1);
451
452                         if (ctrl_value == test_value)
453                                 info("register 0x%x is writeable", address);
454                         else
455                                 info("register 0x%x is read only", address);
456
457                         /* Restore original value */
458                         s5k4aa_write_sensor(sd, address, &old_value, 1);
459                 }
460         }
461         info("Read/write register probing complete");
462         s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
463 }