blob: 739f2df55e0d7bfa633ce0960903a57fa0a9958c [file] [log] [blame]
Erik Andrenc109f812008-10-01 04:51:53 -03001/*
2 * Driver for the po1030 sensor
3 *
Erik Andren0c505e682008-10-16 16:43:16 -03004 * Copyright (c) 2008 Erik Andrén
Erik Andrenc109f812008-10-01 04:51:53 -03005 * 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
21int 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
59sensor_found:
60 sd->gspca_dev.cam.cam_mode = po1030.modes;
61 sd->gspca_dev.cam.nmodes = po1030.nmodes;
Erik Andrend2d7e9a2008-10-03 15:29:02 -030062 sd->desc->ctrls = po1030.ctrls;
63 sd->desc->nctrls = po1030.nctrls;
Erik Andrenc109f812008-10-01 04:51:53 -030064 return 0;
65}
66
67int 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
Erik Andrén7b9f2462008-11-20 03:59:02 -030076 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;
Erik Andrenc109f812008-10-01 04:51:53 -030089
Erik Andrén7b9f2462008-11-20 03:59:02 -030090 for (i = 0; (i < len) && !err; i++) {
Erik Andrenc109f812008-10-01 04:51:53 -030091 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
92
Erik Andren17ea88a2008-10-16 16:46:07 -030093 PDEBUG(D_CONF, "Reading sensor register "
Erik Andrenc109f812008-10-01 04:51:53 -030094 "0x%x containing 0x%x ", address, *i2c_data);
95 }
Erik Andrén7b9f2462008-11-20 03:59:02 -030096out:
97 return err;
Erik Andrenc109f812008-10-01 04:51:53 -030098}
99
100int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300124 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
Erik Andrenc109f812008-10-01 04:51:53 -0300125 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
142int po1030_init(struct sd *sd)
143{
144 int i, err = 0;
145
146 /* Init the sensor */
Erik Andrén7b9f2462008-11-20 03:59:02 -0300147 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
Erik Andrenc109f812008-10-01 04:51:53 -0300148 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
Erik Andrén7b9f2462008-11-20 03:59:02 -0300178 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300179}
180
181int 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
Erik Andren17ea88a2008-10-16 16:46:07 -0300197 PDEBUG(D_V4L2, "Exposure read as %d", *val);
Erik Andrenc109f812008-10-01 04:51:53 -0300198out:
Erik Andrén7b9f2462008-11-20 03:59:02 -0300199 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300200}
201
202int 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
Erik Andren17ea88a2008-10-16 16:46:07 -0300208 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
Erik Andrenc109f812008-10-01 04:51:53 -0300209
210 i2c_data = ((val & 0xff00) >> 8);
Erik Andren17ea88a2008-10-16 16:46:07 -0300211 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
Erik Andrenc109f812008-10-01 04:51:53 -0300212 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);
Erik Andren17ea88a2008-10-16 16:46:07 -0300220 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
Erik Andrenc109f812008-10-01 04:51:53 -0300221 i2c_data);
222 err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
223 &i2c_data, 1);
224
225out:
Erik Andrén7b9f2462008-11-20 03:59:02 -0300226 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300227}
228
229int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300238 PDEBUG(D_V4L2, "Read global gain %d", *val);
Erik Andrenc109f812008-10-01 04:51:53 -0300239
Erik Andrén7b9f2462008-11-20 03:59:02 -0300240 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300241}
242
Erik Andrene2c97492008-10-16 16:49:17 -0300243int 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
Erik Andrén7b9f2462008-11-20 03:59:02 -0300256 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300257}
258
259int 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
Erik Andrén7b9f2462008-11-20 03:59:02 -0300272 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300273}
274
275int 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
Erik Andrén7b9f2462008-11-20 03:59:02 -0300288 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300289}
290
291int 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
Erik Andrén7b9f2462008-11-20 03:59:02 -0300304 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300305}
306
Erik Andrenc109f812008-10-01 04:51:53 -0300307int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300314 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
Erik Andrenc109f812008-10-01 04:51:53 -0300315 err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
316 &i2c_data, 1);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300317 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300318}
319
320int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300329 PDEBUG(D_V4L2, "Read red gain %d", *val);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300330 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300331}
332
333int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300340 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
Erik Andrenc109f812008-10-01 04:51:53 -0300341 err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
342 &i2c_data, 1);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300343 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300344}
345
346int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300355 PDEBUG(D_V4L2, "Read blue gain %d", *val);
Erik Andrenc109f812008-10-01 04:51:53 -0300356
Erik Andrén7b9f2462008-11-20 03:59:02 -0300357 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300358}
359
360int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300366 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
Erik Andrenc109f812008-10-01 04:51:53 -0300367 err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
368 &i2c_data, 1);
369
Erik Andrén7b9f2462008-11-20 03:59:02 -0300370 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300371}
372
373int po1030_power_down(struct sd *sd)
374{
375 return 0;
376}
377
378void 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}