]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/video/gspca/m5602/m5602_s5k83a.c
V4L/DVB (11631): gspca - m5602: Remove useless error check
[mirror_ubuntu-jammy-kernel.git] / drivers / media / video / gspca / m5602 / m5602_s5k83a.c
CommitLineData
c109f816
EA
1/*
2 * Driver for the s5k83a sensor
3 *
0c505e68 4 * Copyright (C) 2008 Erik Andrén
c109f816
EA
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
ac3d5bfe 19#include <linux/kthread.h>
c109f816
EA
20#include "m5602_s5k83a.h"
21
cf811d50
EA
22static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
24static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
25static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
26static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
27static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
28static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
29static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
30static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
31static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
32
74cadfe1
EA
33static struct v4l2_pix_format s5k83a_modes[] = {
34 {
35 640,
36 480,
37 V4L2_PIX_FMT_SBGGR8,
38 V4L2_FIELD_NONE,
39 .sizeimage =
40 640 * 480,
41 .bytesperline = 640,
42 .colorspace = V4L2_COLORSPACE_SRGB,
43 .priv = 0
44 }
45};
46
e17cc08c 47const static struct ctrl s5k83a_ctrls[] = {
ac3d5bfe 48#define GAIN_IDX 0
e17cc08c
EA
49 {
50 {
ac3d5bfe 51 .id = V4L2_CID_GAIN,
e17cc08c 52 .type = V4L2_CTRL_TYPE_INTEGER,
ac3d5bfe 53 .name = "gain",
e17cc08c
EA
54 .minimum = 0x00,
55 .maximum = 0xff,
56 .step = 0x01,
ac3d5bfe 57 .default_value = S5K83A_DEFAULT_GAIN,
e17cc08c
EA
58 .flags = V4L2_CTRL_FLAG_SLIDER
59 },
ac3d5bfe
LK
60 .set = s5k83a_set_gain,
61 .get = s5k83a_get_gain
e17cc08c 62
ac3d5bfe
LK
63 },
64#define BRIGHTNESS_IDX 1
65 {
e17cc08c 66 {
ac3d5bfe 67 .id = V4L2_CID_BRIGHTNESS,
e17cc08c 68 .type = V4L2_CTRL_TYPE_INTEGER,
ac3d5bfe 69 .name = "brightness",
e17cc08c
EA
70 .minimum = 0x00,
71 .maximum = 0xff,
72 .step = 0x01,
ac3d5bfe 73 .default_value = S5K83A_DEFAULT_BRIGHTNESS,
e17cc08c
EA
74 .flags = V4L2_CTRL_FLAG_SLIDER
75 },
ac3d5bfe
LK
76 .set = s5k83a_set_brightness,
77 .get = s5k83a_get_brightness,
78 },
79#define EXPOSURE_IDX 2
80 {
e17cc08c 81 {
ac3d5bfe 82 .id = V4L2_CID_EXPOSURE,
e17cc08c 83 .type = V4L2_CTRL_TYPE_INTEGER,
ac3d5bfe 84 .name = "exposure",
e17cc08c 85 .minimum = 0x00,
ac3d5bfe 86 .maximum = S5K83A_MAXIMUM_EXPOSURE,
e17cc08c 87 .step = 0x01,
ac3d5bfe 88 .default_value = S5K83A_DEFAULT_EXPOSURE,
e17cc08c
EA
89 .flags = V4L2_CTRL_FLAG_SLIDER
90 },
ac3d5bfe
LK
91 .set = s5k83a_set_exposure,
92 .get = s5k83a_get_exposure
93 },
94#define HFLIP_IDX 3
95 {
e17cc08c 96 {
00e02567
EA
97 .id = V4L2_CID_HFLIP,
98 .type = V4L2_CTRL_TYPE_BOOLEAN,
99 .name = "horizontal flip",
100 .minimum = 0,
101 .maximum = 1,
102 .step = 1,
103 .default_value = 0
e17cc08c
EA
104 },
105 .set = s5k83a_set_hflip,
106 .get = s5k83a_get_hflip
ac3d5bfe
LK
107 },
108#define VFLIP_IDX 4
109 {
e17cc08c 110 {
00e02567
EA
111 .id = V4L2_CID_VFLIP,
112 .type = V4L2_CTRL_TYPE_BOOLEAN,
113 .name = "vertical flip",
114 .minimum = 0,
115 .maximum = 1,
116 .step = 1,
117 .default_value = 0
e17cc08c
EA
118 },
119 .set = s5k83a_set_vflip,
120 .get = s5k83a_get_vflip
121 }
122};
123
658efb63 124static void s5k83a_dump_registers(struct sd *sd);
ac3d5bfe
LK
125static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
126static int s5k83a_set_led_indication(struct sd *sd, u8 val);
127int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip);
658efb63 128
c109f816
EA
129int s5k83a_probe(struct sd *sd)
130{
ac3d5bfe 131 struct s5k83a_priv *sens_priv;
c109f816
EA
132 u8 prod_id = 0, ver_id = 0;
133 int i, err = 0;
134
135 if (force_sensor) {
136 if (force_sensor == S5K83A_SENSOR) {
137 info("Forcing a %s sensor", s5k83a.name);
138 goto sensor_found;
139 }
140 /* If we want to force another sensor, don't try to probe this
141 * one */
142 return -ENODEV;
143 }
144
145 info("Probing for a s5k83a sensor");
146
147 /* Preinit the sensor */
148 for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
149 u8 data[2] = {preinit_s5k83a[i][2], preinit_s5k83a[i][3]};
150 if (preinit_s5k83a[i][0] == SENSOR)
6dc4cff0 151 err = m5602_write_sensor(sd, preinit_s5k83a[i][1],
c109f816
EA
152 data, 2);
153 else
154 err = m5602_write_bridge(sd, preinit_s5k83a[i][1],
155 data[0]);
156 }
157
158 /* We don't know what register (if any) that contain the product id
159 * Just pick the first addresses that seem to produce the same results
160 * on multiple machines */
6b9c0a2a 161 if (m5602_read_sensor(sd, 0x00, &prod_id, 1))
c109f816
EA
162 return -ENODEV;
163
6b9c0a2a 164 if (m5602_read_sensor(sd, 0x01, &ver_id, 1))
c109f816
EA
165 return -ENODEV;
166
167 if ((prod_id == 0xff) || (ver_id == 0xff))
168 return -ENODEV;
169 else
170 info("Detected a s5k83a sensor");
171
172sensor_found:
ac3d5bfe
LK
173 sens_priv = kmalloc(
174 sizeof(struct s5k83a_priv), GFP_KERNEL);
175 if (!sens_priv)
176 return -ENOMEM;
177
178 sens_priv->settings =
179 kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
180 if (!sens_priv->settings)
181 return -ENOMEM;
182
74cadfe1
EA
183 sd->gspca_dev.cam.cam_mode = s5k83a_modes;
184 sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
e17cc08c 185 sd->desc->ctrls = s5k83a_ctrls;
e4cc4fcc 186 sd->desc->nctrls = ARRAY_SIZE(s5k83a_ctrls);
ac3d5bfe
LK
187
188 /* null the pointer! thread is't running now */
189 sens_priv->rotation_thread = NULL;
190
191 for (i = 0; i < ARRAY_SIZE(s5k83a_ctrls); i++)
192 sens_priv->settings[i] = s5k83a_ctrls[i].qctrl.default_value;
193
194 sd->sensor_priv = sens_priv;
c109f816
EA
195 return 0;
196}
197
c109f816
EA
198int s5k83a_init(struct sd *sd)
199{
200 int i, err = 0;
201
202 for (i = 0; i < ARRAY_SIZE(init_s5k83a) && !err; i++) {
203 u8 data[2] = {0x00, 0x00};
204
205 switch (init_s5k83a[i][0]) {
206 case BRIDGE:
207 err = m5602_write_bridge(sd,
208 init_s5k83a[i][1],
209 init_s5k83a[i][2]);
210 break;
211
212 case SENSOR:
213 data[0] = init_s5k83a[i][2];
6dc4cff0 214 err = m5602_write_sensor(sd,
c109f816
EA
215 init_s5k83a[i][1], data, 1);
216 break;
217
218 case SENSOR_LONG:
219 data[0] = init_s5k83a[i][2];
220 data[1] = init_s5k83a[i][3];
6dc4cff0 221 err = m5602_write_sensor(sd,
c109f816
EA
222 init_s5k83a[i][1], data, 2);
223 break;
224 default:
225 info("Invalid stream command, exiting init");
226 return -EINVAL;
227 }
228 }
229
230 if (dump_sensor)
231 s5k83a_dump_registers(sd);
232
233 return (err < 0) ? err : 0;
234}
235
ac3d5bfe
LK
236static int rotation_thread_function(void *data)
237{
238 struct sd *sd = (struct sd *) data;
239 struct s5k83a_priv *sens_priv = sd->sensor_priv;
240 u8 reg, previous_rotation = 0;
241 __s32 vflip, hflip;
242
243 set_current_state(TASK_INTERRUPTIBLE);
244 while (!schedule_timeout(100)) {
245 if (mutex_lock_interruptible(&sd->gspca_dev.usb_lock))
246 break;
247
248 s5k83a_get_rotation(sd, &reg);
249 if (previous_rotation != reg) {
250 previous_rotation = reg;
251 info("Camera was flipped");
252
253 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
254 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
255
256 if (reg) {
257 vflip = !vflip;
258 hflip = !hflip;
259 }
260 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
261 }
262
263 mutex_unlock(&sd->gspca_dev.usb_lock);
264 set_current_state(TASK_INTERRUPTIBLE);
265 }
266
267 /* return to "front" flip */
268 if (previous_rotation) {
269 s5k83a_get_vflip((struct gspca_dev *) sd, &vflip);
270 s5k83a_get_hflip((struct gspca_dev *) sd, &hflip);
271 s5k83a_set_flip_real((struct gspca_dev *) sd, vflip, hflip);
272 }
273
274 sens_priv->rotation_thread = NULL;
275 return 0;
276}
277
4a7581f0
LK
278int s5k83a_start(struct sd *sd)
279{
ac3d5bfe
LK
280 struct s5k83a_priv *sens_priv = sd->sensor_priv;
281
282 /* Create another thread, polling the GPIO ports of the camera to check
283 if it got rotated. This is how the windows driver does it so we have
284 to assume that there is no better way of accomplishing this */
285 sens_priv->rotation_thread = kthread_create(rotation_thread_function, sd, "rotation thread");
286 wake_up_process(sens_priv->rotation_thread);
287
4a7581f0
LK
288 return s5k83a_set_led_indication(sd, 1);
289}
290
291int s5k83a_stop(struct sd *sd)
292{
ac3d5bfe
LK
293 struct s5k83a_priv *sens_priv = sd->sensor_priv;
294
295 if (sens_priv->rotation_thread)
296 kthread_stop(sens_priv->rotation_thread);
297
4a7581f0
LK
298 return s5k83a_set_led_indication(sd, 0);
299}
300
ac3d5bfe 301void s5k83a_disconnect(struct sd *sd)
c109f816 302{
ac3d5bfe 303 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 304
ac3d5bfe 305 s5k83a_stop(sd);
c109f816 306
ac3d5bfe
LK
307 sd->sensor = NULL;
308 kfree(sens_priv->settings);
309 kfree(sens_priv);
310}
c109f816 311
cf811d50 312static int s5k83a_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
c109f816 313{
c109f816 314 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 315 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 316
ac3d5bfe
LK
317 *val = sens_priv->settings[GAIN_IDX];
318 return 0;
c109f816
EA
319}
320
cf811d50 321static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val)
c109f816
EA
322{
323 int err;
324 u8 data[2];
325 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe
LK
326 struct s5k83a_priv *sens_priv = sd->sensor_priv;
327
328 sens_priv->settings[GAIN_IDX] = val;
c109f816
EA
329
330 data[0] = 0x00;
331 data[1] = 0x20;
6dc4cff0 332 err = m5602_write_sensor(sd, 0x14, data, 2);
c109f816 333 if (err < 0)
051781b3 334 return err;
c109f816
EA
335
336 data[0] = 0x01;
337 data[1] = 0x00;
6dc4cff0 338 err = m5602_write_sensor(sd, 0x0d, data, 2);
c109f816 339 if (err < 0)
051781b3 340 return err;
c109f816
EA
341
342 /* FIXME: This is not sane, we need to figure out the composition
343 of these registers */
ac3d5bfe
LK
344 data[0] = val >> 3; /* gain, high 5 bits */
345 data[1] = val >> 1; /* gain, high 7 bits */
346 err = m5602_write_sensor(sd, S5K83A_GAIN, data, 2);
c109f816 347
7b2cd079 348 return err;
c109f816
EA
349}
350
cf811d50 351static int s5k83a_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
c109f816 352{
c109f816 353 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 354 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 355
ac3d5bfe
LK
356 *val = sens_priv->settings[BRIGHTNESS_IDX];
357 return 0;
c109f816
EA
358}
359
cf811d50 360static int s5k83a_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
c109f816
EA
361{
362 int err;
363 u8 data[1];
364 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 365 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 366
ac3d5bfe 367 sens_priv->settings[BRIGHTNESS_IDX] = val;
c109f816 368 data[0] = val;
ac3d5bfe 369 err = m5602_write_sensor(sd, S5K83A_BRIGHTNESS, data, 1);
7b2cd079 370 return err;
c109f816
EA
371}
372
cf811d50 373static int s5k83a_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
c109f816 374{
c109f816 375 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 376 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 377
ac3d5bfe
LK
378 *val = sens_priv->settings[EXPOSURE_IDX];
379 return 0;
c109f816
EA
380}
381
cf811d50 382static int s5k83a_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
c109f816 383{
18f8fae1 384 int err;
c109f816
EA
385 u8 data[2];
386 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 387 struct s5k83a_priv *sens_priv = sd->sensor_priv;
c109f816 388
ac3d5bfe 389 sens_priv->settings[EXPOSURE_IDX] = val;
c109f816
EA
390 data[0] = 0;
391 data[1] = val;
ac3d5bfe 392 err = m5602_write_sensor(sd, S5K83A_EXPOSURE, data, 2);
7b2cd079 393 return err;
c109f816 394}
18f8fae1 395
cf811d50 396static int s5k83a_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
18f8fae1 397{
18f8fae1 398 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 399 struct s5k83a_priv *sens_priv = sd->sensor_priv;
18f8fae1 400
ac3d5bfe
LK
401 *val = sens_priv->settings[VFLIP_IDX];
402 return 0;
18f8fae1
EA
403}
404
ac3d5bfe 405int s5k83a_set_flip_real(struct gspca_dev *gspca_dev, __s32 vflip, __s32 hflip)
18f8fae1
EA
406{
407 int err;
408 u8 data[1];
409 struct sd *sd = (struct sd *) gspca_dev;
410
411 data[0] = 0x05;
6dc4cff0 412 err = m5602_write_sensor(sd, S5K83A_PAGE_MAP, data, 1);
18f8fae1 413 if (err < 0)
051781b3 414 return err;
18f8fae1 415
ac3d5bfe
LK
416 /* six bit is vflip, seven is hflip */
417 data[0] = S5K83A_FLIP_MASK;
418 data[0] = (vflip) ? data[0] | 0x40 : data[0];
419 data[0] = (hflip) ? data[0] | 0x80 : data[0];
18f8fae1 420
6dc4cff0 421 err = m5602_write_sensor(sd, S5K83A_FLIP, data, 1);
18f8fae1 422 if (err < 0)
051781b3 423 return err;
18f8fae1 424
ac3d5bfe 425 data[0] = (vflip) ? 0x0b : 0x0a;
6dc4cff0 426 err = m5602_write_sensor(sd, S5K83A_VFLIP_TUNE, data, 1);
ac3d5bfe
LK
427 if (err < 0)
428 return err;
18f8fae1 429
ac3d5bfe
LK
430 data[0] = (hflip) ? 0x0a : 0x0b;
431 err = m5602_write_sensor(sd, S5K83A_HFLIP_TUNE, data, 1);
7b2cd079 432 return err;
18f8fae1
EA
433}
434
cf811d50 435static int s5k83a_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
18f8fae1
EA
436{
437 int err;
ac3d5bfe
LK
438 u8 reg;
439 __s32 hflip;
18f8fae1 440 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 441 struct s5k83a_priv *sens_priv = sd->sensor_priv;
18f8fae1 442
ac3d5bfe
LK
443 sens_priv->settings[VFLIP_IDX] = val;
444
445 s5k83a_get_hflip(gspca_dev, &hflip);
446
447 err = s5k83a_get_rotation(sd, &reg);
18f8fae1 448 if (err < 0)
051781b3 449 return err;
ac3d5bfe
LK
450 if (reg) {
451 val = !val;
452 hflip = !hflip;
453 }
18f8fae1 454
ac3d5bfe 455 err = s5k83a_set_flip_real(gspca_dev, val, hflip);
7b2cd079 456 return err;
18f8fae1
EA
457}
458
cf811d50 459static int s5k83a_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
ac3d5bfe
LK
460{
461 struct sd *sd = (struct sd *) gspca_dev;
462 struct s5k83a_priv *sens_priv = sd->sensor_priv;
463
464 *val = sens_priv->settings[HFLIP_IDX];
465 return 0;
466}
467
cf811d50 468static int s5k83a_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
18f8fae1
EA
469{
470 int err;
ac3d5bfe
LK
471 u8 reg;
472 __s32 vflip;
18f8fae1 473 struct sd *sd = (struct sd *) gspca_dev;
ac3d5bfe 474 struct s5k83a_priv *sens_priv = sd->sensor_priv;
18f8fae1 475
ac3d5bfe 476 sens_priv->settings[HFLIP_IDX] = val;
18f8fae1 477
ac3d5bfe 478 s5k83a_get_vflip(gspca_dev, &vflip);
18f8fae1 479
ac3d5bfe 480 err = s5k83a_get_rotation(sd, &reg);
18f8fae1 481 if (err < 0)
051781b3 482 return err;
ac3d5bfe
LK
483 if (reg) {
484 val = !val;
485 vflip = !vflip;
486 }
18f8fae1 487
ac3d5bfe 488 err = s5k83a_set_flip_real(gspca_dev, vflip, val);
7b2cd079 489 return err;
18f8fae1 490}
4a7581f0 491
ac3d5bfe 492static int s5k83a_set_led_indication(struct sd *sd, u8 val)
4a7581f0
LK
493{
494 int err = 0;
495 u8 data[1];
496
497 err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data);
498 if (err < 0)
499 return err;
500
501 if (val)
502 data[0] = data[0] | S5K83A_GPIO_LED_MASK;
503 else
504 data[0] = data[0] & ~S5K83A_GPIO_LED_MASK;
505
506 err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]);
507
508 return (err < 0) ? err : 0;
509}
ac3d5bfe
LK
510
511/* Get camera rotation on Acer notebooks */
512static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data)
513{
514 int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data);
515 *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1;
516 return err;
517}
518
519static void s5k83a_dump_registers(struct sd *sd)
520{
521 int address;
522 u8 page, old_page;
523 m5602_read_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
524
525 for (page = 0; page < 16; page++) {
526 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
527 info("Dumping the s5k83a register state for page 0x%x", page);
528 for (address = 0; address <= 0xff; address++) {
529 u8 val = 0;
530 m5602_read_sensor(sd, address, &val, 1);
531 info("register 0x%x contains 0x%x",
532 address, val);
533 }
534 }
535 info("s5k83a register state dump complete");
536
537 for (page = 0; page < 16; page++) {
538 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &page, 1);
539 info("Probing for which registers that are read/write "
540 "for page 0x%x", page);
541 for (address = 0; address <= 0xff; address++) {
542 u8 old_val, ctrl_val, test_val = 0xff;
543
544 m5602_read_sensor(sd, address, &old_val, 1);
545 m5602_write_sensor(sd, address, &test_val, 1);
546 m5602_read_sensor(sd, address, &ctrl_val, 1);
547
548 if (ctrl_val == test_val)
549 info("register 0x%x is writeable", address);
550 else
551 info("register 0x%x is read only", address);
552
553 /* Restore original val */
554 m5602_write_sensor(sd, address, &old_val, 1);
555 }
556 }
557 info("Read/write register probing complete");
558 m5602_write_sensor(sd, S5K83A_PAGE_MAP, &old_page, 1);
559}