0dedd3102a5c37577bc79db1d012aed9a3e26f00
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / gspca / m5602 / m5602_mt9m111.c
1 /*
2  * Driver for the mt9m111 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_mt9m111.h"
20
21 static void mt9m111_dump_registers(struct sd *sd);
22
23 int mt9m111_probe(struct sd *sd)
24 {
25         u8 data[2] = {0x00, 0x00};
26         int i;
27
28         if (force_sensor) {
29                 if (force_sensor == MT9M111_SENSOR) {
30                         info("Forcing a %s sensor", mt9m111.name);
31                         goto sensor_found;
32                 }
33                 /* If we want to force another sensor, don't try to probe this
34                  * one */
35                 return -ENODEV;
36         }
37
38         info("Probing for a mt9m111 sensor");
39
40         /* Do the preinit */
41         for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
42                 if (preinit_mt9m111[i][0] == BRIDGE) {
43                         m5602_write_bridge(sd,
44                                 preinit_mt9m111[i][1],
45                                 preinit_mt9m111[i][2]);
46                 } else {
47                         data[0] = preinit_mt9m111[i][2];
48                         data[1] = preinit_mt9m111[i][3];
49                         m5602_write_sensor(sd,
50                                 preinit_mt9m111[i][1], data, 2);
51                 }
52         }
53
54         if (mt9m111_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2))
55                 return -ENODEV;
56
57         if ((data[0] == 0x14) && (data[1] == 0x3a)) {
58                 info("Detected a mt9m111 sensor");
59                 goto sensor_found;
60         }
61
62         return -ENODEV;
63
64 sensor_found:
65         sd->gspca_dev.cam.cam_mode = mt9m111.modes;
66         sd->gspca_dev.cam.nmodes = mt9m111.nmodes;
67         sd->desc->ctrls = mt9m111.ctrls;
68         sd->desc->nctrls = mt9m111.nctrls;
69         return 0;
70 }
71
72 int mt9m111_init(struct sd *sd)
73 {
74         int i, err = 0;
75
76         /* Init the sensor */
77         for (i = 0; i < ARRAY_SIZE(init_mt9m111) && !err; i++) {
78                 u8 data[2];
79
80                 if (init_mt9m111[i][0] == BRIDGE) {
81                         err = m5602_write_bridge(sd,
82                                 init_mt9m111[i][1],
83                                 init_mt9m111[i][2]);
84                 } else {
85                         data[0] = init_mt9m111[i][2];
86                         data[1] = init_mt9m111[i][3];
87                         err = m5602_write_sensor(sd,
88                                 init_mt9m111[i][1], data, 2);
89                 }
90         }
91
92         if (dump_sensor)
93                 mt9m111_dump_registers(sd);
94
95         return (err < 0) ? err : 0;
96 }
97
98 int mt9m111_power_down(struct sd *sd)
99 {
100         return 0;
101 }
102
103 int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
104 {
105         int err;
106         u8 data[2] = {0x00, 0x00};
107         struct sd *sd = (struct sd *) gspca_dev;
108
109         err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
110                                   data, 2);
111         *val = data[0] & MT9M111_RMB_MIRROR_ROWS;
112         PDEBUG(D_V4L2, "Read vertical flip %d", *val);
113
114         return err;
115 }
116
117 int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
118 {
119         int err;
120         u8 data[2] = {0x00, 0x00};
121         struct sd *sd = (struct sd *) gspca_dev;
122
123         PDEBUG(D_V4L2, "Set vertical flip to %d", val);
124
125         /* Set the correct page map */
126         err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
127         if (err < 0)
128                 goto out;
129
130         err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
131         if (err < 0)
132                 goto out;
133
134         data[0] = (data[0] & 0xfe) | val;
135         err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
136                                    data, 2);
137 out:
138         return err;
139 }
140
141 int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
142 {
143         int err;
144         u8 data[2] = {0x00, 0x00};
145         struct sd *sd = (struct sd *) gspca_dev;
146
147         err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
148                                   data, 2);
149         *val = data[0] & MT9M111_RMB_MIRROR_COLS;
150         PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
151
152         return err;
153 }
154
155 int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
156 {
157         int err;
158         u8 data[2] = {0x00, 0x00};
159         struct sd *sd = (struct sd *) gspca_dev;
160
161         PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
162
163         /* Set the correct page map */
164         err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
165         if (err < 0)
166                 goto out;
167
168         err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B, data, 2);
169         if (err < 0)
170                 goto out;
171
172         data[0] = (data[0] & 0xfd) | ((val << 1) & 0x02);
173         err = m5602_write_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
174                                         data, 2);
175 out:
176         return err;
177 }
178
179 int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
180 {
181         int err, tmp;
182         u8 data[2] = {0x00, 0x00};
183         struct sd *sd = (struct sd *) gspca_dev;
184
185         err = mt9m111_read_sensor(sd, MT9M111_SC_GLOBAL_GAIN, data, 2);
186         tmp = ((data[1] << 8) | data[0]);
187
188         *val = ((tmp & (1 << 10)) * 2) |
189               ((tmp & (1 <<  9)) * 2) |
190               ((tmp & (1 <<  8)) * 2) |
191                (tmp & 0x7f);
192
193         PDEBUG(D_V4L2, "Read gain %d", *val);
194
195         return err;
196 }
197
198 int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
199 {
200         int err, tmp;
201         u8 data[2] = {0x00, 0x00};
202         struct sd *sd = (struct sd *) gspca_dev;
203
204         /* Set the correct page map */
205         err = m5602_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
206         if (err < 0)
207                 goto out;
208
209         if (val >= INITIAL_MAX_GAIN * 2 * 2 * 2)
210                 return -EINVAL;
211
212         if ((val >= INITIAL_MAX_GAIN * 2 * 2) &&
213             (val < (INITIAL_MAX_GAIN - 1) * 2 * 2 * 2))
214                 tmp = (1 << 10) | (val << 9) |
215                                 (val << 8) | (val / 8);
216         else if ((val >= INITIAL_MAX_GAIN * 2) &&
217                  (val <  INITIAL_MAX_GAIN * 2 * 2))
218                 tmp = (1 << 9) | (1 << 8) | (val / 4);
219         else if ((val >= INITIAL_MAX_GAIN) &&
220                  (val < INITIAL_MAX_GAIN * 2))
221                 tmp = (1 << 8) | (val / 2);
222         else
223                 tmp = val;
224
225         data[1] = (tmp & 0xff00) >> 8;
226         data[0] = (tmp & 0xff);
227         PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
228                data[1], data[0]);
229
230         err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
231                                    data, 2);
232 out:
233         return err;
234 }
235
236 int mt9m111_read_sensor(struct sd *sd, const u8 address,
237                         u8 *i2c_data, const u8 len) {
238         int err, i;
239
240         do {
241                 err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data);
242         } while ((*i2c_data & I2C_BUSY) && !err);
243         if (err < 0)
244                 goto out;
245
246         err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR,
247                                  sd->sensor->i2c_slave_id);
248         if (err < 0)
249                 goto out;
250
251         err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address);
252         if (err < 0)
253                 goto out;
254
255         err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x1a);
256         if (err < 0)
257                 goto out;
258
259         for (i = 0; i < len && !err; i++) {
260                 err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
261
262                 PDEBUG(D_CONF, "Reading sensor register "
263                        "0x%x contains 0x%x ", address, *i2c_data);
264         }
265 out:
266         return err;
267 }
268
269 int mt9m111_write_sensor(struct sd *sd, const u8 address,
270                                 u8 *i2c_data, const u8 len)
271 {
272         int err, i;
273         u8 *p;
274         struct usb_device *udev = sd->gspca_dev.dev;
275         __u8 *buf = sd->gspca_dev.usb_buf;
276
277         /* No sensor with a data width larger
278            than 16 bits has yet been seen, nor with 0 :p*/
279         if (len > 2 || !len)
280                 return -EINVAL;
281
282         memcpy(buf, sensor_urb_skeleton,
283                sizeof(sensor_urb_skeleton));
284
285         buf[11] = sd->sensor->i2c_slave_id;
286         buf[15] = address;
287
288         p = buf + 16;
289
290         /* Copy a four byte write sequence for each byte to be written to */
291         for (i = 0; i < len; i++) {
292                 memcpy(p, sensor_urb_skeleton + 16, 4);
293                 p[3] = i2c_data[i];
294                 p += 4;
295                 PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
296                        address, i2c_data[i]);
297         }
298
299         /* Copy the tailer */
300         memcpy(p, sensor_urb_skeleton + 20, 4);
301
302         /* Set the total length */
303         p[3] = 0x10 + len;
304
305         err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
306                               0x04, 0x40, 0x19,
307                               0x0000, buf,
308                               20 + len * 4, M5602_URB_MSG_TIMEOUT);
309
310         return (err < 0) ? err : 0;
311 }
312
313 static void mt9m111_dump_registers(struct sd *sd)
314 {
315         u8 address, value[2] = {0x00, 0x00};
316
317         info("Dumping the mt9m111 register state");
318
319         info("Dumping the mt9m111 sensor core registers");
320         value[1] = MT9M111_SENSOR_CORE;
321         m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
322         for (address = 0; address < 0xff; address++) {
323                 mt9m111_read_sensor(sd, address, value, 2);
324                 info("register 0x%x contains 0x%x%x",
325                      address, value[0], value[1]);
326         }
327
328         info("Dumping the mt9m111 color pipeline registers");
329         value[1] = MT9M111_COLORPIPE;
330         m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
331         for (address = 0; address < 0xff; address++) {
332                 mt9m111_read_sensor(sd, address, value, 2);
333                 info("register 0x%x contains 0x%x%x",
334                      address, value[0], value[1]);
335         }
336
337         info("Dumping the mt9m111 camera control registers");
338         value[1] = MT9M111_CAMERA_CONTROL;
339         m5602_write_sensor(sd, MT9M111_PAGE_MAP, value, 2);
340         for (address = 0; address < 0xff; address++) {
341                 mt9m111_read_sensor(sd, address, value, 2);
342                 info("register 0x%x contains 0x%x%x",
343                      address, value[0], value[1]);
344         }
345
346         info("mt9m111 register state dump complete");
347 }