Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / usb / gspca / m5602 / m5602_s5k4aa.c
1 /*
2  * Driver for the s5k4aa 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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include "m5602_s5k4aa.h"
22
23 static int s5k4aa_s_ctrl(struct v4l2_ctrl *ctrl);
24 static void s5k4aa_dump_registers(struct sd *sd);
25
26 static const struct v4l2_ctrl_ops s5k4aa_ctrl_ops = {
27         .s_ctrl = s5k4aa_s_ctrl,
28 };
29
30 static
31     const
32         struct dmi_system_id s5k4aa_vflip_dmi_table[] = {
33         {
34                 .ident = "BRUNEINIT",
35                 .matches = {
36                         DMI_MATCH(DMI_SYS_VENDOR, "BRUNENIT"),
37                         DMI_MATCH(DMI_PRODUCT_NAME, "BRUNENIT"),
38                         DMI_MATCH(DMI_BOARD_VERSION, "00030D0000000001")
39                 }
40         }, {
41                 .ident = "Fujitsu-Siemens Amilo Xa 2528",
42                 .matches = {
43                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
44                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xa 2528")
45                 }
46         }, {
47                 .ident = "Fujitsu-Siemens Amilo Xi 2428",
48                 .matches = {
49                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
50                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428")
51                 }
52         }, {
53                 .ident = "Fujitsu-Siemens Amilo Xi 2528",
54                 .matches = {
55                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
56                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2528")
57                 }
58         }, {
59                 .ident = "Fujitsu-Siemens Amilo Xi 2550",
60                 .matches = {
61                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
62                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
63                 }
64         }, {
65                 .ident = "Fujitsu-Siemens Amilo Pa 2548",
66                 .matches = {
67                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
68                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
69                 }
70         }, {
71                 .ident = "Fujitsu-Siemens Amilo Pi 2530",
72                 .matches = {
73                         DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
74                         DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 2530")
75                 }
76         }, {
77                 .ident = "MSI GX700",
78                 .matches = {
79                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
80                         DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
81                         DMI_MATCH(DMI_BIOS_DATE, "12/02/2008")
82                 }
83         }, {
84                 .ident = "MSI GX700",
85                 .matches = {
86                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
87                         DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
88                         DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
89                 }
90         }, {
91                 .ident = "MSI GX700",
92                 .matches = {
93                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
94                         DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
95                         DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
96                 }
97         }, {
98                 .ident = "MSI GX700/GX705/EX700",
99                 .matches = {
100                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
101                         DMI_MATCH(DMI_PRODUCT_NAME, "GX700/GX705/EX700")
102                 }
103         }, {
104                 .ident = "MSI L735",
105                 .matches = {
106                         DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
107                         DMI_MATCH(DMI_PRODUCT_NAME, "MS-1717X")
108                 }
109         }, {
110                 .ident = "Lenovo Y300",
111                 .matches = {
112                         DMI_MATCH(DMI_SYS_VENDOR, "L3000 Y300"),
113                         DMI_MATCH(DMI_PRODUCT_NAME, "Y300")
114                 }
115         },
116         { }
117 };
118
119 static struct v4l2_pix_format s5k4aa_modes[] = {
120         {
121                 640,
122                 480,
123                 V4L2_PIX_FMT_SBGGR8,
124                 V4L2_FIELD_NONE,
125                 .sizeimage =
126                         640 * 480,
127                 .bytesperline = 640,
128                 .colorspace = V4L2_COLORSPACE_SRGB,
129                 .priv = 0
130         },
131         {
132                 1280,
133                 1024,
134                 V4L2_PIX_FMT_SBGGR8,
135                 V4L2_FIELD_NONE,
136                 .sizeimage =
137                         1280 * 1024,
138                 .bytesperline = 1280,
139                 .colorspace = V4L2_COLORSPACE_SRGB,
140                 .priv = 0
141         }
142 };
143
144 int s5k4aa_probe(struct sd *sd)
145 {
146         u8 prod_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
147         const u8 expected_prod_id[6] = {0x00, 0x10, 0x00, 0x4b, 0x33, 0x75};
148         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
149         int i, err = 0;
150
151         if (force_sensor) {
152                 if (force_sensor == S5K4AA_SENSOR) {
153                         pr_info("Forcing a %s sensor\n", s5k4aa.name);
154                         goto sensor_found;
155                 }
156                 /* If we want to force another sensor, don't try to probe this
157                  * one */
158                 return -ENODEV;
159         }
160
161         PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
162
163         /* Preinit the sensor */
164         for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
165                 u8 data[2] = {0x00, 0x00};
166
167                 switch (preinit_s5k4aa[i][0]) {
168                 case BRIDGE:
169                         err = m5602_write_bridge(sd,
170                                                  preinit_s5k4aa[i][1],
171                                                  preinit_s5k4aa[i][2]);
172                         break;
173
174                 case SENSOR:
175                         data[0] = preinit_s5k4aa[i][2];
176                         err = m5602_write_sensor(sd,
177                                                   preinit_s5k4aa[i][1],
178                                                   data, 1);
179                         break;
180
181                 case SENSOR_LONG:
182                         data[0] = preinit_s5k4aa[i][2];
183                         data[1] = preinit_s5k4aa[i][3];
184                         err = m5602_write_sensor(sd,
185                                                   preinit_s5k4aa[i][1],
186                                                   data, 2);
187                         break;
188                 default:
189                         pr_info("Invalid stream command, exiting init\n");
190                         return -EINVAL;
191                 }
192         }
193
194         /* Test some registers, but we don't know their exact meaning yet */
195         if (m5602_read_sensor(sd, 0x00, prod_id, 2))
196                 return -ENODEV;
197         if (m5602_read_sensor(sd, 0x02, prod_id+2, 2))
198                 return -ENODEV;
199         if (m5602_read_sensor(sd, 0x04, prod_id+4, 2))
200                 return -ENODEV;
201
202         if (memcmp(prod_id, expected_prod_id, sizeof(prod_id)))
203                 return -ENODEV;
204         else
205                 pr_info("Detected a s5k4aa sensor\n");
206
207 sensor_found:
208         sd->gspca_dev.cam.cam_mode = s5k4aa_modes;
209         sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k4aa_modes);
210
211         return 0;
212 }
213
214 int s5k4aa_start(struct sd *sd)
215 {
216         int i, err = 0;
217         u8 data[2];
218         struct cam *cam = &sd->gspca_dev.cam;
219         struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
220
221         switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
222         case 1280:
223                 PDEBUG(D_CONF, "Configuring camera for SXGA mode");
224
225                 for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
226                         switch (SXGA_s5k4aa[i][0]) {
227                         case BRIDGE:
228                                 err = m5602_write_bridge(sd,
229                                                  SXGA_s5k4aa[i][1],
230                                                  SXGA_s5k4aa[i][2]);
231                         break;
232
233                         case SENSOR:
234                                 data[0] = SXGA_s5k4aa[i][2];
235                                 err = m5602_write_sensor(sd,
236                                                  SXGA_s5k4aa[i][1],
237                                                  data, 1);
238                         break;
239
240                         case SENSOR_LONG:
241                                 data[0] = SXGA_s5k4aa[i][2];
242                                 data[1] = SXGA_s5k4aa[i][3];
243                                 err = m5602_write_sensor(sd,
244                                                   SXGA_s5k4aa[i][1],
245                                                   data, 2);
246                         break;
247
248                         default:
249                                 pr_err("Invalid stream command, exiting init\n");
250                                 return -EINVAL;
251                         }
252                 }
253                 break;
254
255         case 640:
256                 PDEBUG(D_CONF, "Configuring camera for VGA mode");
257
258                 for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
259                         switch (VGA_s5k4aa[i][0]) {
260                         case BRIDGE:
261                                 err = m5602_write_bridge(sd,
262                                                  VGA_s5k4aa[i][1],
263                                                  VGA_s5k4aa[i][2]);
264                         break;
265
266                         case SENSOR:
267                                 data[0] = VGA_s5k4aa[i][2];
268                                 err = m5602_write_sensor(sd,
269                                                  VGA_s5k4aa[i][1],
270                                                  data, 1);
271                         break;
272
273                         case SENSOR_LONG:
274                                 data[0] = VGA_s5k4aa[i][2];
275                                 data[1] = VGA_s5k4aa[i][3];
276                                 err = m5602_write_sensor(sd,
277                                                   VGA_s5k4aa[i][1],
278                                                   data, 2);
279                         break;
280
281                         default:
282                                 pr_err("Invalid stream command, exiting init\n");
283                                 return -EINVAL;
284                         }
285                 }
286                 break;
287         }
288         if (err < 0)
289                 return err;
290
291         return 0;
292 }
293
294 int s5k4aa_init(struct sd *sd)
295 {
296         int i, err = 0;
297
298         for (i = 0; i < ARRAY_SIZE(init_s5k4aa) && !err; i++) {
299                 u8 data[2] = {0x00, 0x00};
300
301                 switch (init_s5k4aa[i][0]) {
302                 case BRIDGE:
303                         err = m5602_write_bridge(sd,
304                                 init_s5k4aa[i][1],
305                                 init_s5k4aa[i][2]);
306                         break;
307
308                 case SENSOR:
309                         data[0] = init_s5k4aa[i][2];
310                         err = m5602_write_sensor(sd,
311                                 init_s5k4aa[i][1], data, 1);
312                         break;
313
314                 case SENSOR_LONG:
315                         data[0] = init_s5k4aa[i][2];
316                         data[1] = init_s5k4aa[i][3];
317                         err = m5602_write_sensor(sd,
318                                 init_s5k4aa[i][1], data, 2);
319                         break;
320                 default:
321                         pr_info("Invalid stream command, exiting init\n");
322                         return -EINVAL;
323                 }
324         }
325
326         if (dump_sensor)
327                 s5k4aa_dump_registers(sd);
328
329         return err;
330 }
331
332 int s5k4aa_init_controls(struct sd *sd)
333 {
334         struct v4l2_ctrl_handler *hdl = &sd->gspca_dev.ctrl_handler;
335
336         sd->gspca_dev.vdev.ctrl_handler = hdl;
337         v4l2_ctrl_handler_init(hdl, 6);
338
339         v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_BRIGHTNESS,
340                           0, 0x1f, 1, S5K4AA_DEFAULT_BRIGHTNESS);
341
342         v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_EXPOSURE,
343                           13, 0xfff, 1, 0x100);
344
345         v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_GAIN,
346                           0, 127, 1, S5K4AA_DEFAULT_GAIN);
347
348         v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_SHARPNESS,
349                           0, 1, 1, 1);
350
351         sd->hflip = v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_HFLIP,
352                                       0, 1, 1, 0);
353         sd->vflip = v4l2_ctrl_new_std(hdl, &s5k4aa_ctrl_ops, V4L2_CID_VFLIP,
354                                       0, 1, 1, 0);
355
356         if (hdl->error) {
357                 pr_err("Could not initialize controls\n");
358                 return hdl->error;
359         }
360
361         v4l2_ctrl_cluster(2, &sd->hflip);
362
363         return 0;
364 }
365
366 static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
367 {
368         struct sd *sd = (struct sd *) gspca_dev;
369         u8 data = S5K4AA_PAGE_MAP_2;
370         int err;
371
372         PDEBUG(D_CONF, "Set exposure to %d", val);
373         err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
374         if (err < 0)
375                 return err;
376         data = (val >> 8) & 0xff;
377         err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_HI, &data, 1);
378         if (err < 0)
379                 return err;
380         data = val & 0xff;
381         err = m5602_write_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
382
383         return err;
384 }
385
386 static int s5k4aa_set_hvflip(struct gspca_dev *gspca_dev)
387 {
388         struct sd *sd = (struct sd *) gspca_dev;
389         u8 data = S5K4AA_PAGE_MAP_2;
390         int err;
391         int hflip = sd->hflip->val;
392         int vflip = sd->vflip->val;
393
394         PDEBUG(D_CONF, "Set hvflip %d %d", hflip, vflip);
395         err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
396         if (err < 0)
397                 return err;
398
399         err = m5602_read_sensor(sd, S5K4AA_READ_MODE, &data, 1);
400         if (err < 0)
401                 return err;
402
403         if (dmi_check_system(s5k4aa_vflip_dmi_table)) {
404                 hflip = !hflip;
405                 vflip = !vflip;
406         }
407
408         data = (data & 0x7f) | (vflip << 7) | (hflip << 6);
409         err = m5602_write_sensor(sd, S5K4AA_READ_MODE, &data, 1);
410         if (err < 0)
411                 return err;
412
413         err = m5602_read_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
414         if (err < 0)
415                 return err;
416         if (hflip)
417                 data &= 0xfe;
418         else
419                 data |= 0x01;
420         err = m5602_write_sensor(sd, S5K4AA_COLSTART_LO, &data, 1);
421         if (err < 0)
422                 return err;
423
424         err = m5602_read_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
425         if (err < 0)
426                 return err;
427         if (vflip)
428                 data &= 0xfe;
429         else
430                 data |= 0x01;
431         err = m5602_write_sensor(sd, S5K4AA_ROWSTART_LO, &data, 1);
432         if (err < 0)
433                 return err;
434
435         return 0;
436 }
437
438 static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
439 {
440         struct sd *sd = (struct sd *) gspca_dev;
441         u8 data = S5K4AA_PAGE_MAP_2;
442         int err;
443
444         PDEBUG(D_CONF, "Set gain to %d", val);
445         err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
446         if (err < 0)
447                 return err;
448
449         data = val & 0xff;
450         err = m5602_write_sensor(sd, S5K4AA_GAIN, &data, 1);
451
452         return err;
453 }
454
455 static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
456 {
457         struct sd *sd = (struct sd *) gspca_dev;
458         u8 data = S5K4AA_PAGE_MAP_2;
459         int err;
460
461         PDEBUG(D_CONF, "Set brightness to %d", val);
462         err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
463         if (err < 0)
464                 return err;
465
466         data = val & 0xff;
467         return m5602_write_sensor(sd, S5K4AA_BRIGHTNESS, &data, 1);
468 }
469
470 static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
471 {
472         struct sd *sd = (struct sd *) gspca_dev;
473         u8 data = S5K4AA_PAGE_MAP_2;
474         int err;
475
476         PDEBUG(D_CONF, "Set noise to %d", val);
477         err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
478         if (err < 0)
479                 return err;
480
481         data = val & 0x01;
482         return m5602_write_sensor(sd, S5K4AA_NOISE_SUPP, &data, 1);
483 }
484
485 static int s5k4aa_s_ctrl(struct v4l2_ctrl *ctrl)
486 {
487         struct gspca_dev *gspca_dev =
488                 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
489         int err;
490
491         if (!gspca_dev->streaming)
492                 return 0;
493
494         switch (ctrl->id) {
495         case V4L2_CID_BRIGHTNESS:
496                 err = s5k4aa_set_brightness(gspca_dev, ctrl->val);
497                 break;
498         case V4L2_CID_EXPOSURE:
499                 err = s5k4aa_set_exposure(gspca_dev, ctrl->val);
500                 break;
501         case V4L2_CID_GAIN:
502                 err = s5k4aa_set_gain(gspca_dev, ctrl->val);
503                 break;
504         case V4L2_CID_SHARPNESS:
505                 err = s5k4aa_set_noise(gspca_dev, ctrl->val);
506                 break;
507         case V4L2_CID_HFLIP:
508                 err = s5k4aa_set_hvflip(gspca_dev);
509                 break;
510         default:
511                 return -EINVAL;
512         }
513
514         return err;
515 }
516
517 void s5k4aa_disconnect(struct sd *sd)
518 {
519         sd->sensor = NULL;
520 }
521
522 static void s5k4aa_dump_registers(struct sd *sd)
523 {
524         int address;
525         u8 page, old_page;
526         m5602_read_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
527         for (page = 0; page < 16; page++) {
528                 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
529                 pr_info("Dumping the s5k4aa register state for page 0x%x\n",
530                         page);
531                 for (address = 0; address <= 0xff; address++) {
532                         u8 value = 0;
533                         m5602_read_sensor(sd, address, &value, 1);
534                         pr_info("register 0x%x contains 0x%x\n",
535                                 address, value);
536                 }
537         }
538         pr_info("s5k4aa register state dump complete\n");
539
540         for (page = 0; page < 16; page++) {
541                 m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &page, 1);
542                 pr_info("Probing for which registers that are read/write for page 0x%x\n",
543                         page);
544                 for (address = 0; address <= 0xff; address++) {
545                         u8 old_value, ctrl_value, test_value = 0xff;
546
547                         m5602_read_sensor(sd, address, &old_value, 1);
548                         m5602_write_sensor(sd, address, &test_value, 1);
549                         m5602_read_sensor(sd, address, &ctrl_value, 1);
550
551                         if (ctrl_value == test_value)
552                                 pr_info("register 0x%x is writeable\n",
553                                         address);
554                         else
555                                 pr_info("register 0x%x is read only\n",
556                                         address);
557
558                         /* Restore original value */
559                         m5602_write_sensor(sd, address, &old_value, 1);
560                 }
561         }
562         pr_info("Read/write register probing complete\n");
563         m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &old_page, 1);
564 }