blob: 7914dcc6e2a261b7032e979ac3cbe1f40e6ea68a [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
Erik Andrén658efb62008-11-24 14:21:29 -030021static void po1030_dump_registers(struct sd *sd);
22
Erik Andrenc109f812008-10-01 04:51:53 -030023int 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)
Erik Andrén6dc4cff2008-11-26 04:08:10 -030043 m5602_write_sensor(sd,
Erik Andrenc109f812008-10-01 04:51:53 -030044 preinit_po1030[i][1], &data, 1);
45 else
46 m5602_write_bridge(sd, preinit_po1030[i][1], data);
47 }
48
Erik Andrénc061c972008-11-27 13:46:39 -030049 if (m5602_read_sensor(sd, 0x3, &prod_id, 1))
Erik Andrenc109f812008-10-01 04:51:53 -030050 return -ENODEV;
51
Erik Andrénc061c972008-11-27 13:46:39 -030052 if (m5602_read_sensor(sd, 0x4, &ver_id, 1))
Erik Andrenc109f812008-10-01 04:51:53 -030053 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
61sensor_found:
62 sd->gspca_dev.cam.cam_mode = po1030.modes;
63 sd->gspca_dev.cam.nmodes = po1030.nmodes;
Erik Andrend2d7e9a2008-10-03 15:29:02 -030064 sd->desc->ctrls = po1030.ctrls;
Erik Andr?ne4cc4fc2008-12-30 15:27:17 -030065 sd->desc->nctrls = ARRAY_SIZE(po1030_ctrls);
Erik Andrenc109f812008-10-01 04:51:53 -030066 return 0;
67}
68
Erik Andrenc109f812008-10-01 04:51:53 -030069int po1030_init(struct sd *sd)
70{
71 int i, err = 0;
72
73 /* Init the sensor */
Erik Andrén7b9f2462008-11-20 03:59:02 -030074 for (i = 0; i < ARRAY_SIZE(init_po1030) && !err; i++) {
Erik Andrenc109f812008-10-01 04:51:53 -030075 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];
Erik Andrén6dc4cff2008-11-26 04:08:10 -030086 err = m5602_write_sensor(sd,
Erik Andrenc109f812008-10-01 04:51:53 -030087 init_po1030[i][1], data, 1);
88 break;
89
Erik Andrenc109f812008-10-01 04:51:53 -030090 default:
91 info("Invalid stream command, exiting init");
92 return -EINVAL;
93 }
94 }
95
96 if (dump_sensor)
97 po1030_dump_registers(sd);
98
Erik Andrén7b9f2462008-11-20 03:59:02 -030099 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300100}
101
102int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300108 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_H,
Erik Andrenc109f812008-10-01 04:51:53 -0300109 &i2c_data, 1);
110 if (err < 0)
Erik Andr?n051781b2008-12-27 12:28:00 -0300111 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300112 *val = (i2c_data << 8);
113
Erik Andrénc061c972008-11-27 13:46:39 -0300114 err = m5602_read_sensor(sd, PO1030_REG_INTEGLINES_M,
Erik Andrenc109f812008-10-01 04:51:53 -0300115 &i2c_data, 1);
116 *val |= i2c_data;
117
Erik Andren17ea88a2008-10-16 16:46:07 -0300118 PDEBUG(D_V4L2, "Exposure read as %d", *val);
Erik Andr?n051781b2008-12-27 12:28:00 -0300119
Erik Andrén7b9f2462008-11-20 03:59:02 -0300120 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300121}
122
123int 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
Erik Andren17ea88a2008-10-16 16:46:07 -0300129 PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
Erik Andrenc109f812008-10-01 04:51:53 -0300130
131 i2c_data = ((val & 0xff00) >> 8);
Erik Andren17ea88a2008-10-16 16:46:07 -0300132 PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
Erik Andrenc109f812008-10-01 04:51:53 -0300133 i2c_data);
134
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300135 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_H,
Erik Andrenc109f812008-10-01 04:51:53 -0300136 &i2c_data, 1);
137 if (err < 0)
Erik Andr?n051781b2008-12-27 12:28:00 -0300138 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300139
140 i2c_data = (val & 0xff);
Erik Andren17ea88a2008-10-16 16:46:07 -0300141 PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
Erik Andrenc109f812008-10-01 04:51:53 -0300142 i2c_data);
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300143 err = m5602_write_sensor(sd, PO1030_REG_INTEGLINES_M,
Erik Andrenc109f812008-10-01 04:51:53 -0300144 &i2c_data, 1);
145
Erik Andrén7b9f2462008-11-20 03:59:02 -0300146 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300147}
148
149int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300155 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300156 &i2c_data, 1);
157 *val = i2c_data;
Erik Andren17ea88a2008-10-16 16:46:07 -0300158 PDEBUG(D_V4L2, "Read global gain %d", *val);
Erik Andrenc109f812008-10-01 04:51:53 -0300159
Erik Andrén7b9f2462008-11-20 03:59:02 -0300160 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300161}
162
Erik Andrene2c97492008-10-16 16:49:17 -0300163int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300169 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2,
Erik Andrene2c97492008-10-16 16:49:17 -0300170 &i2c_data, 1);
171
172 *val = (i2c_data >> 7) & 0x01 ;
173
174 PDEBUG(D_V4L2, "Read hflip %d", *val);
175
Erik Andrén7b9f2462008-11-20 03:59:02 -0300176 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300177}
178
179int 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);
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300186 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
187 if (err < 0)
Erik Andr?n051781b2008-12-27 12:28:00 -0300188 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300189
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300190 i2c_data = (0x7f & i2c_data) | ((val & 0x01) << 7);
Erik Andrene2c97492008-10-16 16:49:17 -0300191
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300192 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300193 &i2c_data, 1);
Erik Andrene2c97492008-10-16 16:49:17 -0300194
Erik Andrén7b9f2462008-11-20 03:59:02 -0300195 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300196}
197
198int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300204 err = m5602_read_sensor(sd, PO1030_REG_GLOBALGAIN,
Erik Andrene2c97492008-10-16 16:49:17 -0300205 &i2c_data, 1);
206
207 *val = (i2c_data >> 6) & 0x01;
208
209 PDEBUG(D_V4L2, "Read vflip %d", *val);
210
Erik Andrén7b9f2462008-11-20 03:59:02 -0300211 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300212}
213
214int 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);
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300221 err = m5602_read_sensor(sd, PO1030_REG_CONTROL2, &i2c_data, 1);
222 if (err < 0)
Erik Andr?n051781b2008-12-27 12:28:00 -0300223 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300224
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300225 i2c_data = (i2c_data & 0xbf) | ((val & 0x01) << 6);
Erik Andrene2c97492008-10-16 16:49:17 -0300226
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300227 err = m5602_write_sensor(sd, PO1030_REG_CONTROL2,
Erik Andrén1d07b6f2008-11-27 14:07:24 -0300228 &i2c_data, 1);
Erik Andrene2c97492008-10-16 16:49:17 -0300229
Erik Andrén7b9f2462008-11-20 03:59:02 -0300230 return err;
Erik Andrene2c97492008-10-16 16:49:17 -0300231}
232
Erik Andrenc109f812008-10-01 04:51:53 -0300233int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300240 PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300241 err = m5602_write_sensor(sd, PO1030_REG_GLOBALGAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300242 &i2c_data, 1);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300243 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300244}
245
246int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300252 err = m5602_read_sensor(sd, PO1030_REG_RED_GAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300253 &i2c_data, 1);
254 *val = i2c_data;
Erik Andren17ea88a2008-10-16 16:46:07 -0300255 PDEBUG(D_V4L2, "Read red gain %d", *val);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300256 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300257}
258
259int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300266 PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300267 err = m5602_write_sensor(sd, PO1030_REG_RED_GAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300268 &i2c_data, 1);
Erik Andrén7b9f2462008-11-20 03:59:02 -0300269 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300270}
271
272int 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
Erik Andrénc061c972008-11-27 13:46:39 -0300278 err = m5602_read_sensor(sd, PO1030_REG_BLUE_GAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300279 &i2c_data, 1);
280 *val = i2c_data;
Erik Andren17ea88a2008-10-16 16:46:07 -0300281 PDEBUG(D_V4L2, "Read blue gain %d", *val);
Erik Andrenc109f812008-10-01 04:51:53 -0300282
Erik Andrén7b9f2462008-11-20 03:59:02 -0300283 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300284}
285
286int 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;
Erik Andren17ea88a2008-10-16 16:46:07 -0300292 PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300293 err = m5602_write_sensor(sd, PO1030_REG_BLUE_GAIN,
Erik Andrenc109f812008-10-01 04:51:53 -0300294 &i2c_data, 1);
295
Erik Andrén7b9f2462008-11-20 03:59:02 -0300296 return err;
Erik Andrenc109f812008-10-01 04:51:53 -0300297}
298
299int po1030_power_down(struct sd *sd)
300{
301 return 0;
302}
303
Erik Andrén658efb62008-11-24 14:21:29 -0300304static void po1030_dump_registers(struct sd *sd)
Erik Andrenc109f812008-10-01 04:51:53 -0300305{
306 int address;
307 u8 value = 0;
308
309 info("Dumping the po1030 sensor core registers");
310 for (address = 0; address < 0x7f; address++) {
Erik Andrénc061c972008-11-27 13:46:39 -0300311 m5602_read_sensor(sd, address, &value, 1);
Erik Andrenc109f812008-10-01 04:51:53 -0300312 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
Erik Andrénc061c972008-11-27 13:46:39 -0300323 m5602_read_sensor(sd, address, &old_value, 1);
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300324 m5602_write_sensor(sd, address, test_value, 1);
Erik Andrénc061c972008-11-27 13:46:39 -0300325 m5602_read_sensor(sd, address, &ctrl_value, 1);
Erik Andrenc109f812008-10-01 04:51:53 -0300326
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 */
Erik Andrén6dc4cff2008-11-26 04:08:10 -0300333 m5602_write_sensor(sd, address, &old_value, 1);
Erik Andrenc109f812008-10-01 04:51:53 -0300334 }
335}