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