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