Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[linux-2.6] / 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                 goto out;
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 out:
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                 goto out;
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 out:
147         return err;
148 }
149
150 int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
151 {
152         struct sd *sd = (struct sd *) gspca_dev;
153         u8 i2c_data;
154         int err;
155
156         err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
157                                  &i2c_data, 1);
158         *val = i2c_data;
159         PDEBUG(D_V4L2, "Read global gain %d", *val);
160
161         return err;
162 }
163
164 int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
165 {
166         struct sd *sd = (struct sd *) gspca_dev;
167         u8 i2c_data;
168         int err;
169
170         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
171                                  &i2c_data, 1);
172
173         *val = (i2c_data >> 7) & 0x01 ;
174
175         PDEBUG(D_V4L2, "Read hflip %d", *val);
176
177         return err;
178 }
179
180 int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
181 {
182         struct sd *sd = (struct sd *) gspca_dev;
183         u8 i2c_data;
184         int err;
185
186         PDEBUG(D_V4L2, "Set hflip %d", val);
187         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
188         if (err < 0)
189                 goto out;
190
191         i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
192
193         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
194                                  &i2c_data, 1);
195
196 out:
197         return err;
198 }
199
200 int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
201 {
202         struct sd *sd = (struct sd *) gspca_dev;
203         u8 i2c_data;
204         int err;
205
206         err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
207                                  &i2c_data, 1);
208
209         *val = (i2c_data >> 6) & 0x01;
210
211         PDEBUG(D_V4L2, "Read vflip %d", *val);
212
213         return err;
214 }
215
216 int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
217 {
218         struct sd *sd = (struct sd *) gspca_dev;
219         u8 i2c_data;
220         int err;
221
222         PDEBUG(D_V4L2, "Set vflip %d", val);
223         err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
224         if (err < 0)
225                 goto out;
226
227         i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
228
229         err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
230                                  &i2c_data, 1);
231
232 out:
233         return err;
234 }
235
236 int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
237 {
238         struct sd *sd = (struct sd *) gspca_dev;
239         u8 i2c_data;
240         int err;
241
242         i2c_data = val & 0xff;
243         PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
244         err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
245                                   &i2c_data, 1);
246         return err;
247 }
248
249 int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
250 {
251         struct sd *sd = (struct sd *) gspca_dev;
252         u8 i2c_data;
253         int err;
254
255         err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
256                                  &i2c_data, 1);
257         *val = i2c_data;
258         PDEBUG(D_V4L2, "Read red gain %d", *val);
259         return err;
260 }
261
262 int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
263 {
264         struct sd *sd = (struct sd *) gspca_dev;
265         u8 i2c_data;
266         int err;
267
268         i2c_data = val & 0xff;
269         PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
270         err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
271                                   &i2c_data, 1);
272         return err;
273 }
274
275 int po1030_get_blue_balance(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 = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
282                                  &i2c_data, 1);
283         *val = i2c_data;
284         PDEBUG(D_V4L2, "Read blue gain %d", *val);
285
286         return err;
287 }
288
289 int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
290 {
291         struct sd *sd = (struct sd *) gspca_dev;
292         u8 i2c_data;
293         int err;
294         i2c_data = val & 0xff;
295         PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
296         err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
297                                   &i2c_data, 1);
298
299         return err;
300 }
301
302 int po1030_power_down(struct sd *sd)
303 {
304         return 0;
305 }
306
307 static void po1030_dump_registers(struct sd *sd)
308 {
309         int address;
310         u8 value = 0;
311
312         info("Dumping the po1030 sensor core registers");
313         for (address = 0; address < 0x7f; address++) {
314                 m5602_read_sensor(sd, address, &value, 1);
315                 info("register 0x%x contains 0x%x",
316                      address, value);
317         }
318
319         info("po1030 register state dump complete");
320
321         info("Probing for which registers that are read/write");
322         for (address = 0; address < 0xff; address++) {
323                 u8 old_value, ctrl_value;
324                 u8 test_value[2] = {0xff, 0xff};
325
326                 m5602_read_sensor(sd, address, &old_value, 1);
327                 m5602_write_sensor(sd, address, test_value, 1);
328                 m5602_read_sensor(sd, address, &ctrl_value, 1);
329
330                 if (ctrl_value == test_value[0])
331                         info("register 0x%x is writeable", address);
332                 else
333                         info("register 0x%x is read only", address);
334
335                 /* Restore original value */
336                 m5602_write_sensor(sd, address, &old_value, 1);
337         }
338 }