V4L/DVB (11405): gspca - m5602: Simplify error handling
[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 (m5602_read_sensor(sd, 0x3, &prod_id, 1))
50                 return -ENODEV;
51
52         if (m5602_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_init(struct sd *sd)
70 {
71         int i, err = 0;
72
73         /* Init the sensor */
74         for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
75                 u8 data[2] = {0x00, 0x00};
76
77                 switch (init_po1030[i][0]) {
78                 case BRIDGE:
79                         err = m5602_write_bridge(sd,
80                                 init_po1030[i][1],
81                                 init_po1030[i][2]);
82                         break;
83
84                 case SENSOR:
85                         data[0] = init_po1030[i][2];
86                         err = m5602_write_sensor(sd,
87                                 init_po1030[i][1], data, 1);
88                         break;
89
90                 default:
91                         info("Invalid stream command, exiting init");
92                         return -EINVAL;
93                 }
94         }
95
96         if (dump_sensor)
97                 po1030_dump_registers(sd);
98
99         return err;
100 }
101
102 int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
103 {
104         struct sd *sd = (struct sd *) gspca_dev;
105         u8 i2c_data;
106         int err;
107
108         err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
109                                  &i2c_data, 1);
110         if (err < 0)
111                 return err;
112         *val = (i2c_data << 8);
113
114         err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
115                                  &i2c_data, 1);
116         *val |= i2c_data;
117
118         PDEBUG(D_V4L2, "Exposure read as %d", *val);
119
120         return err;
121 }
122
123 int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
124 {
125         struct sd *sd = (struct sd *) gspca_dev;
126         u8 i2c_data;
127         int err;
128
129         PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
130
131         i2c_data = ((val & 0xff00) >> 8);
132         PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
133                i2c_data);
134
135         err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
136                                   &i2c_data, 1);
137         if (err < 0)
138                 return err;
139
140         i2c_data = (val & 0xff);
141         PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
142                i2c_data);
143         err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
144                                   &i2c_data, 1);
145
146         return err;
147 }
148
149 int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
150 {
151         struct sd *sd = (struct sd *) gspca_dev;
152         u8 i2c_data;
153         int err;
154
155         err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
156                                  &i2c_data, 1);
157         *val = i2c_data;
158         PDEBUG(D_V4L2, "Read global gain %d", *val);
159
160         return err;
161 }
162
163 int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
164 {
165         struct sd *sd = (struct sd *) gspca_dev;
166         u8 i2c_data;
167         int err;
168
169         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
170                                  &i2c_data, 1);
171
172         *val = (i2c_data >> 7) & 0x01 ;
173
174         PDEBUG(D_V4L2, "Read hflip %d", *val);
175
176         return err;
177 }
178
179 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
180 {
181         struct sd *sd = (struct sd *) gspca_dev;
182         u8 i2c_data;
183         int err;
184
185         PDEBUG(D_V4L2, "Set hflip %d", val);
186         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
187         if (err < 0)
188                 return err;
189
190         i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
191
192         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
193                                  &i2c_data, 1);
194
195         return err;
196 }
197
198 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
199 {
200         struct sd *sd = (struct sd *) gspca_dev;
201         u8 i2c_data;
202         int err;
203
204         err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
205                                  &i2c_data, 1);
206
207         *val = (i2c_data >> 6) & 0x01;
208
209         PDEBUG(D_V4L2, "Read vflip %d", *val);
210
211         return err;
212 }
213
214 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
215 {
216         struct sd *sd = (struct sd *) gspca_dev;
217         u8 i2c_data;
218         int err;
219
220         PDEBUG(D_V4L2, "Set vflip %d", val);
221         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
222         if (err < 0)
223                 return err;
224
225         i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
226
227         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
228                                  &i2c_data, 1);
229
230         return err;
231 }
232
233 int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
234 {
235         struct sd *sd = (struct sd *) gspca_dev;
236         u8 i2c_data;
237         int err;
238
239         i2c_data = val & 0xff;
240         PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
241         err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
242                                   &i2c_data, 1);
243         return err;
244 }
245
246 int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
247 {
248         struct sd *sd = (struct sd *) gspca_dev;
249         u8 i2c_data;
250         int err;
251
252         err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
253                                  &i2c_data, 1);
254         *val = i2c_data;
255         PDEBUG(D_V4L2, "Read red gain %d", *val);
256         return err;
257 }
258
259 int po1030_set_red_balance(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         i2c_data = val & 0xff;
266         PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
267         err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
268                                   &i2c_data, 1);
269         return err;
270 }
271
272 int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
273 {
274         struct sd *sd = (struct sd *) gspca_dev;
275         u8 i2c_data;
276         int err;
277
278         err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
279                                  &i2c_data, 1);
280         *val = i2c_data;
281         PDEBUG(D_V4L2, "Read blue gain %d", *val);
282
283         return err;
284 }
285
286 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
287 {
288         struct sd *sd = (struct sd *) gspca_dev;
289         u8 i2c_data;
290         int err;
291         i2c_data = val & 0xff;
292         PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
293         err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
294                                   &i2c_data, 1);
295
296         return err;
297 }
298
299 int po1030_power_down(struct sd *sd)
300 {
301         return 0;
302 }
303
304 static void po1030_dump_registers(struct sd *sd)
305 {
306         int address;
307         u8 value = 0;
308
309         info("Dumping the po1030 sensor core registers");
310         for (address = 0; address < 0x7f; address++) {
311                 m5602_read_sensor(sd, address, &value, 1);
312                 info("register 0x%x contains 0x%x",
313                      address, value);
314         }
315
316         info("po1030 register state dump complete");
317
318         info("Probing for which registers that are read/write");
319         for (address = 0; address < 0xff; address++) {
320                 u8 old_value, ctrl_value;
321                 u8 test_value[2] = {0xff, 0xff};
322
323                 m5602_read_sensor(sd, address, &old_value, 1);
324                 m5602_write_sensor(sd, address, test_value, 1);
325                 m5602_read_sensor(sd, address, &ctrl_value, 1);
326
327                 if (ctrl_value == test_value[0])
328                         info("register 0x%x is writeable", address);
329                 else
330                         info("register 0x%x is read only", address);
331
332                 /* Restore original value */
333                 m5602_write_sensor(sd, address, &old_value, 1);
334         }
335 }