2c65f0c37ff18524858e61a897e853a4175ef079
[pandora-kernel.git] / drivers / media / video / gspca / m5602 / m5602_po1030.c
1 /*
2  * Driver for the po1030 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_po1030.h"
20
21 static void po1030_dump_registers(struct sd *sd);
22
23 int po1030_probe(struct sd *sd)
24 {
25         u8 prod_id = 0, ver_id = 0, i;
26
27         if (force_sensor) {
28                 if (force_sensor == PO1030_SENSOR) {
29                         info("Forcing a %s sensor", po1030.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 po1030 sensor");
38
39         /* Run the pre-init to actually probe the unit */
40         for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
41                 u8 data = preinit_po1030[i][2];
42                 if (preinit_po1030[i][0] == SENSOR)
43                         m5602_write_sensor(sd,
44                                 preinit_po1030[i][1], &data, 1);
45                 else
46                         m5602_write_bridge(sd, preinit_po1030[i][1], data);
47         }
48
49         if (po1030_read_sensor(sd, 0x3, &prod_id, 1))
50                 return -ENODEV;
51
52         if (po1030_read_sensor(sd, 0x4, &ver_id, 1))
53                 return -ENODEV;
54
55         if ((prod_id == 0x02) && (ver_id == 0xef)) {
56                 info("Detected a po1030 sensor");
57                 goto sensor_found;
58         }
59         return -ENODEV;
60
61 sensor_found:
62         sd->gspca_dev.cam.cam_mode = po1030.modes;
63         sd->gspca_dev.cam.nmodes = po1030.nmodes;
64         sd->desc->ctrls = po1030.ctrls;
65         sd->desc->nctrls = po1030.nctrls;
66         return 0;
67 }
68
69 int po1030_read_sensor(struct sd *sd, const u8 address,
70                         u8 *i2c_data, const u8 len)
71 {
72         int err, i;
73
74         do {
75                 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
76         } while ((*i2c_data & I2C_BUSY) && !err);
77
78         err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
79                                  sd->sensor->i2c_slave_id);
80         if (err < 0)
81                 goto out;
82         err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
83         if (err < 0)
84                 goto out;
85         err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x10 + len);
86         if (err < 0)
87                 goto out;
88         err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08);
89         if (err < 0)
90                 goto out;
91
92         for (i = 0; (i < len) && !err; i++) {
93                 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
94
95                 PDEBUG(D_CONF, "Reading sensor register "
96                                 "0x%x containing 0x%x ", address, *i2c_data);
97         }
98 out:
99         return err;
100 }
101
102 int po1030_write_sensor(struct sd *sd, const u8 address,
103                         u8 *i2c_data, const u8 len)
104 {
105         int err, i;
106         u8 *p;
107         struct usb_device *udev = sd->gspca_dev.dev;
108         __u8 *buf = sd->gspca_dev.usb_buf;
109
110         /* The po1030 only supports one byte writes */
111         if (len > 1 || !len)
112                 return -EINVAL;
113
114         memcpy(buf, sensor_urb_skeleton, sizeof(sensor_urb_skeleton));
115
116         buf[11] = sd->sensor->i2c_slave_id;
117         buf[15] = address;
118
119         p = buf + 16;
120
121         /* Copy a four byte write sequence for each byte to be written to */
122         for (i = 0; i < len; i++) {
123                 memcpy(p, sensor_urb_skeleton + 16, 4);
124                 p[3] = i2c_data[i];
125                 p += 4;
126                 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
127                        address, i2c_data[i]);
128         }
129
130         /* Copy the footer */
131         memcpy(p, sensor_urb_skeleton + 20, 4);
132
133         /* Set the total length */
134         p[3] = 0x10 + len;
135
136         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
137                               0x04, 0x40, 0x19,
138                               0x0000, buf,
139                               20 + len * 4, M5602_URB_MSG_TIMEOUT);
140
141         return (err < 0) ? err : 0;
142 }
143
144 int po1030_init(struct sd *sd)
145 {
146         int i, err = 0;
147
148         /* Init the sensor */
149         for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
150                 u8 data[2] = {0x00, 0x00};
151
152                 switch (init_po1030[i][0]) {
153                 case BRIDGE:
154                         err = m5602_write_bridge(sd,
155                                 init_po1030[i][1],
156                                 init_po1030[i][2]);
157                         break;
158
159                 case SENSOR:
160                         data[0] = init_po1030[i][2];
161                         err = m5602_write_sensor(sd,
162                                 init_po1030[i][1], data, 1);
163                         break;
164
165                 case SENSOR_LONG:
166                         data[0] = init_po1030[i][2];
167                         data[1] = init_po1030[i][3];
168                         err = m5602_write_sensor(sd,
169                                 init_po1030[i][1], data, 2);
170                         break;
171                 default:
172                         info("Invalid stream command, exiting init");
173                         return -EINVAL;
174                 }
175         }
176
177         if (dump_sensor)
178                 po1030_dump_registers(sd);
179
180         return err;
181 }
182
183 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
184 {
185         struct sd *sd = (struct sd *) gspca_dev;
186         u8 i2c_data;
187         int err;
188
189         err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_H,
190                                  &i2c_data, 1);
191         if (err < 0)
192                 goto out;
193         *val = (i2c_data << 8);
194
195         err = po1030_read_sensor(sd, PO1030_REG_INTEGLINES_M,
196                                  &i2c_data, 1);
197         *val |= i2c_data;
198
199         PDEBUG(D_V4L2, "Exposure read as %d", *val);
200 out:
201         return err;
202 }
203
204 int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
205 {
206         struct sd *sd = (struct sd *) gspca_dev;
207         u8 i2c_data;
208         int err;
209
210         PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
211
212         i2c_data = ((val & 0xff00) >> 8);
213         PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
214                i2c_data);
215
216         err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
217                                   &i2c_data, 1);
218         if (err < 0)
219                 goto out;
220
221         i2c_data = (val & 0xff);
222         PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
223                i2c_data);
224         err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
225                                   &i2c_data, 1);
226
227 out:
228         return err;
229 }
230
231 int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
232 {
233         struct sd *sd = (struct sd *) gspca_dev;
234         u8 i2c_data;
235         int err;
236
237         err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
238                                  &i2c_data, 1);
239         *val = i2c_data;
240         PDEBUG(D_V4L2, "Read global gain %d", *val);
241
242         return err;
243 }
244
245 int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
246 {
247         struct sd *sd = (struct sd *) gspca_dev;
248         u8 i2c_data;
249         int err;
250
251         err = po1030_read_sensor(sd, PO1030_REG_CONTROL2,
252                                  &i2c_data, 1);
253
254         *val = (i2c_data >> 7) & 0x01 ;
255
256         PDEBUG(D_V4L2, "Read hflip %d", *val);
257
258         return err;
259 }
260
261 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
262 {
263         struct sd *sd = (struct sd *) gspca_dev;
264         u8 i2c_data;
265         int err;
266
267         PDEBUG(D_V4L2, "Set hflip %d", val);
268
269         i2c_data = (val & 0x01) << 7;
270
271         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
272                                   &i2c_data, 1);
273
274         return err;
275 }
276
277 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
278 {
279         struct sd *sd = (struct sd *) gspca_dev;
280         u8 i2c_data;
281         int err;
282
283         err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
284                                  &i2c_data, 1);
285
286         *val = (i2c_data >> 6) & 0x01;
287
288         PDEBUG(D_V4L2, "Read vflip %d", *val);
289
290         return err;
291 }
292
293 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
294 {
295         struct sd *sd = (struct sd *) gspca_dev;
296         u8 i2c_data;
297         int err;
298
299         PDEBUG(D_V4L2, "Set vflip %d", val);
300
301         i2c_data = (val & 0x01) << 6;
302
303         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
304                                   &i2c_data, 1);
305
306         return err;
307 }
308
309 int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
310 {
311         struct sd *sd = (struct sd *) gspca_dev;
312         u8 i2c_data;
313         int err;
314
315         i2c_data = val & 0xff;
316         PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
317         err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
318                                   &i2c_data, 1);
319         return err;
320 }
321
322 int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
323 {
324         struct sd *sd = (struct sd *) gspca_dev;
325         u8 i2c_data;
326         int err;
327
328         err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
329                                  &i2c_data, 1);
330         *val = i2c_data;
331         PDEBUG(D_V4L2, "Read red gain %d", *val);
332         return err;
333 }
334
335 int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
336 {
337         struct sd *sd = (struct sd *) gspca_dev;
338         u8 i2c_data;
339         int err;
340
341         i2c_data = val & 0xff;
342         PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
343         err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
344                                   &i2c_data, 1);
345         return err;
346 }
347
348 int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
349 {
350         struct sd *sd = (struct sd *) gspca_dev;
351         u8 i2c_data;
352         int err;
353
354         err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
355                                  &i2c_data, 1);
356         *val = i2c_data;
357         PDEBUG(D_V4L2, "Read blue gain %d", *val);
358
359         return err;
360 }
361
362 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
363 {
364         struct sd *sd = (struct sd *) gspca_dev;
365         u8 i2c_data;
366         int err;
367         i2c_data = val & 0xff;
368         PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
369         err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
370                                   &i2c_data, 1);
371
372         return err;
373 }
374
375 int po1030_power_down(struct sd *sd)
376 {
377         return 0;
378 }
379
380 static void po1030_dump_registers(struct sd *sd)
381 {
382         int address;
383         u8 value = 0;
384
385         info("Dumping the po1030 sensor core registers");
386         for (address = 0; address < 0x7f; address++) {
387                 po1030_read_sensor(sd, address, &value, 1);
388                 info("register 0x%x contains 0x%x",
389                      address, value);
390         }
391
392         info("po1030 register state dump complete");
393
394         info("Probing for which registers that are read/write");
395         for (address = 0; address < 0xff; address++) {
396                 u8 old_value, ctrl_value;
397                 u8 test_value[2] = {0xff, 0xff};
398
399                 po1030_read_sensor(sd, address, &old_value, 1);
400                 m5602_write_sensor(sd, address, test_value, 1);
401                 po1030_read_sensor(sd, address, &ctrl_value, 1);
402
403                 if (ctrl_value == test_value[0])
404                         info("register 0x%x is writeable", address);
405                 else
406                         info("register 0x%x is read only", address);
407
408                 /* Restore original value */
409                 m5602_write_sensor(sd, address, &old_value, 1);
410         }
411 }