drm/radeon/kms: enable use of unmappable VRAM V2
[pandora-kernel.git] / drivers / staging / dream / camera / mt9d112.c
1 /*
2  * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3  */
4
5 #include <linux/delay.h>
6 #include <linux/types.h>
7 #include <linux/i2c.h>
8 #include <linux/uaccess.h>
9 #include <linux/miscdevice.h>
10 #include <media/msm_camera.h>
11 #include <mach/gpio.h>
12 #include "mt9d112.h"
13
14 /* Micron MT9D112 Registers and their values */
15 /* Sensor Core Registers */
16 #define  REG_MT9D112_MODEL_ID 0x3000
17 #define  MT9D112_MODEL_ID     0x1580
18
19 /*  SOC Registers Page 1  */
20 #define  REG_MT9D112_SENSOR_RESET     0x301A
21 #define  REG_MT9D112_STANDBY_CONTROL  0x3202
22 #define  REG_MT9D112_MCU_BOOT         0x3386
23
24 struct mt9d112_work {
25         struct work_struct work;
26 };
27
28 static struct  mt9d112_work *mt9d112_sensorw;
29 static struct  i2c_client *mt9d112_client;
30
31 struct mt9d112_ctrl {
32         const struct msm_camera_sensor_info *sensordata;
33 };
34
35
36 static struct mt9d112_ctrl *mt9d112_ctrl;
37
38 static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
39 DECLARE_MUTEX(mt9d112_sem);
40
41
42 /*=============================================================
43         EXTERNAL DECLARATIONS
44 ==============================================================*/
45 extern struct mt9d112_reg mt9d112_regs;
46
47
48 /*=============================================================*/
49
50 static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
51 {
52         int rc = 0;
53
54         rc = gpio_request(dev->sensor_reset, "mt9d112");
55
56         if (!rc) {
57                 rc = gpio_direction_output(dev->sensor_reset, 0);
58                 mdelay(20);
59                 rc = gpio_direction_output(dev->sensor_reset, 1);
60         }
61
62         gpio_free(dev->sensor_reset);
63         return rc;
64 }
65
66 static int32_t mt9d112_i2c_txdata(unsigned short saddr,
67         unsigned char *txdata, int length)
68 {
69         struct i2c_msg msg[] = {
70                 {
71                         .addr = saddr,
72                         .flags = 0,
73                         .len = length,
74                         .buf = txdata,
75                 },
76         };
77
78         if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
79                 CDBG("mt9d112_i2c_txdata failed\n");
80                 return -EIO;
81         }
82
83         return 0;
84 }
85
86 static int32_t mt9d112_i2c_write(unsigned short saddr,
87         unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
88 {
89         int32_t rc = -EIO;
90         unsigned char buf[4];
91
92         memset(buf, 0, sizeof(buf));
93         switch (width) {
94         case WORD_LEN: {
95                 buf[0] = (waddr & 0xFF00)>>8;
96                 buf[1] = (waddr & 0x00FF);
97                 buf[2] = (wdata & 0xFF00)>>8;
98                 buf[3] = (wdata & 0x00FF);
99
100                 rc = mt9d112_i2c_txdata(saddr, buf, 4);
101         }
102                 break;
103
104         case BYTE_LEN: {
105                 buf[0] = waddr;
106                 buf[1] = wdata;
107                 rc = mt9d112_i2c_txdata(saddr, buf, 2);
108         }
109                 break;
110
111         default:
112                 break;
113         }
114
115         if (rc < 0)
116                 CDBG(
117                 "i2c_write failed, addr = 0x%x, val = 0x%x!\n",
118                 waddr, wdata);
119
120         return rc;
121 }
122
123 static int32_t mt9d112_i2c_write_table(
124         struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
125         int num_of_items_in_table)
126 {
127         int i;
128         int32_t rc = -EIO;
129
130         for (i = 0; i < num_of_items_in_table; i++) {
131                 rc = mt9d112_i2c_write(mt9d112_client->addr,
132                         reg_conf_tbl->waddr, reg_conf_tbl->wdata,
133                         reg_conf_tbl->width);
134                 if (rc < 0)
135                         break;
136                 if (reg_conf_tbl->mdelay_time != 0)
137                         mdelay(reg_conf_tbl->mdelay_time);
138                 reg_conf_tbl++;
139         }
140
141         return rc;
142 }
143
144 static int mt9d112_i2c_rxdata(unsigned short saddr,
145         unsigned char *rxdata, int length)
146 {
147         struct i2c_msg msgs[] = {
148         {
149                 .addr   = saddr,
150                 .flags = 0,
151                 .len   = 2,
152                 .buf   = rxdata,
153         },
154         {
155                 .addr   = saddr,
156                 .flags = I2C_M_RD,
157                 .len   = length,
158                 .buf   = rxdata,
159         },
160         };
161
162         if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
163                 CDBG("mt9d112_i2c_rxdata failed!\n");
164                 return -EIO;
165         }
166
167         return 0;
168 }
169
170 static int32_t mt9d112_i2c_read(unsigned short   saddr,
171         unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
172 {
173         int32_t rc = 0;
174         unsigned char buf[4];
175
176         if (!rdata)
177                 return -EIO;
178
179         memset(buf, 0, sizeof(buf));
180
181         switch (width) {
182         case WORD_LEN: {
183                 buf[0] = (raddr & 0xFF00)>>8;
184                 buf[1] = (raddr & 0x00FF);
185
186                 rc = mt9d112_i2c_rxdata(saddr, buf, 2);
187                 if (rc < 0)
188                         return rc;
189
190                 *rdata = buf[0] << 8 | buf[1];
191         }
192                 break;
193
194         default:
195                 break;
196         }
197
198         if (rc < 0)
199                 CDBG("mt9d112_i2c_read failed!\n");
200
201         return rc;
202 }
203
204 static int32_t mt9d112_set_lens_roll_off(void)
205 {
206         int32_t rc = 0;
207         rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
208                                                                  mt9d112_regs.rftbl_size);
209         return rc;
210 }
211
212 static long mt9d112_reg_init(void)
213 {
214         int32_t array_length;
215         int32_t i;
216         long rc;
217
218         /* PLL Setup Start */
219         rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
220                                         mt9d112_regs.plltbl_size);
221
222         if (rc < 0)
223                 return rc;
224         /* PLL Setup End   */
225
226         array_length = mt9d112_regs.prev_snap_reg_settings_size;
227
228         /* Configure sensor for Preview mode and Snapshot mode */
229         for (i = 0; i < array_length; i++) {
230                 rc = mt9d112_i2c_write(mt9d112_client->addr,
231                   mt9d112_regs.prev_snap_reg_settings[i].register_address,
232                   mt9d112_regs.prev_snap_reg_settings[i].register_value,
233                   WORD_LEN);
234
235                 if (rc < 0)
236                         return rc;
237         }
238
239         /* Configure for Noise Reduction, Saturation and Aperture Correction */
240         array_length = mt9d112_regs.noise_reduction_reg_settings_size;
241
242         for (i = 0; i < array_length; i++) {
243                 rc = mt9d112_i2c_write(mt9d112_client->addr,
244                         mt9d112_regs.noise_reduction_reg_settings[i].register_address,
245                         mt9d112_regs.noise_reduction_reg_settings[i].register_value,
246                         WORD_LEN);
247
248                 if (rc < 0)
249                         return rc;
250         }
251
252         /* Set Color Kill Saturation point to optimum value */
253         rc =
254         mt9d112_i2c_write(mt9d112_client->addr,
255         0x35A4,
256         0x0593,
257         WORD_LEN);
258         if (rc < 0)
259                 return rc;
260
261         rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
262                                         mt9d112_regs.stbl_size);
263         if (rc < 0)
264                 return rc;
265
266         rc = mt9d112_set_lens_roll_off();
267         if (rc < 0)
268                 return rc;
269
270         return 0;
271 }
272
273 static long mt9d112_set_sensor_mode(int mode)
274 {
275         uint16_t clock;
276         long rc = 0;
277
278         switch (mode) {
279         case SENSOR_PREVIEW_MODE:
280                 rc =
281                         mt9d112_i2c_write(mt9d112_client->addr,
282                                 0x338C, 0xA20C, WORD_LEN);
283                 if (rc < 0)
284                         return rc;
285
286                 rc =
287                         mt9d112_i2c_write(mt9d112_client->addr,
288                                 0x3390, 0x0004, WORD_LEN);
289                 if (rc < 0)
290                         return rc;
291
292                 rc =
293                         mt9d112_i2c_write(mt9d112_client->addr,
294                                 0x338C, 0xA215, WORD_LEN);
295                 if (rc < 0)
296                         return rc;
297
298                 rc =
299                         mt9d112_i2c_write(mt9d112_client->addr,
300                                 0x3390, 0x0004, WORD_LEN);
301                 if (rc < 0)
302                         return rc;
303
304                 rc =
305                         mt9d112_i2c_write(mt9d112_client->addr,
306                                 0x338C, 0xA20B, WORD_LEN);
307                 if (rc < 0)
308                         return rc;
309
310                 rc =
311                         mt9d112_i2c_write(mt9d112_client->addr,
312                                 0x3390, 0x0000, WORD_LEN);
313                 if (rc < 0)
314                         return rc;
315
316                 clock = 0x0250;
317
318                 rc =
319                         mt9d112_i2c_write(mt9d112_client->addr,
320                                 0x341C, clock, WORD_LEN);
321                 if (rc < 0)
322                         return rc;
323
324                 rc =
325                         mt9d112_i2c_write(mt9d112_client->addr,
326                                 0x338C, 0xA103, WORD_LEN);
327                 if (rc < 0)
328                         return rc;
329
330                 rc =
331                         mt9d112_i2c_write(mt9d112_client->addr,
332                                 0x3390, 0x0001, WORD_LEN);
333                 if (rc < 0)
334                         return rc;
335
336                 mdelay(5);
337                 break;
338
339         case SENSOR_SNAPSHOT_MODE:
340                 /* Switch to lower fps for Snapshot */
341                 rc =
342                         mt9d112_i2c_write(mt9d112_client->addr,
343                                 0x341C, 0x0120, WORD_LEN);
344                 if (rc < 0)
345                         return rc;
346
347                 rc =
348                         mt9d112_i2c_write(mt9d112_client->addr,
349                                 0x338C, 0xA120, WORD_LEN);
350                 if (rc < 0)
351                         return rc;
352
353                 rc =
354                         mt9d112_i2c_write(mt9d112_client->addr,
355                                 0x3390, 0x0002, WORD_LEN);
356                 if (rc < 0)
357                         return rc;
358
359                 mdelay(5);
360
361                 rc =
362                         mt9d112_i2c_write(mt9d112_client->addr,
363                                 0x338C, 0xA103, WORD_LEN);
364                 if (rc < 0)
365                         return rc;
366
367                 rc =
368                         mt9d112_i2c_write(mt9d112_client->addr,
369                                 0x3390, 0x0002, WORD_LEN);
370                 if (rc < 0)
371                         return rc;
372                 break;
373
374         default:
375                 return -EINVAL;
376         }
377
378         return 0;
379 }
380
381 static long mt9d112_set_effect(int mode, int effect)
382 {
383         uint16_t reg_addr;
384         uint16_t reg_val;
385         long rc = 0;
386
387         switch (mode) {
388         case SENSOR_PREVIEW_MODE:
389                 /* Context A Special Effects */
390                 reg_addr = 0x2799;
391                 break;
392
393         case SENSOR_SNAPSHOT_MODE:
394                 /* Context B Special Effects */
395                 reg_addr = 0x279B;
396                 break;
397
398         default:
399                 reg_addr = 0x2799;
400                 break;
401         }
402
403         switch (effect) {
404         case CAMERA_EFFECT_OFF: {
405                 reg_val = 0x6440;
406
407                 rc = mt9d112_i2c_write(mt9d112_client->addr,
408                         0x338C, reg_addr, WORD_LEN);
409                 if (rc < 0)
410                         return rc;
411
412                 rc = mt9d112_i2c_write(mt9d112_client->addr,
413                         0x3390, reg_val, WORD_LEN);
414                 if (rc < 0)
415                         return rc;
416         }
417                         break;
418
419         case CAMERA_EFFECT_MONO: {
420                 reg_val = 0x6441;
421                 rc = mt9d112_i2c_write(mt9d112_client->addr,
422                         0x338C, reg_addr, WORD_LEN);
423                 if (rc < 0)
424                         return rc;
425
426                 rc = mt9d112_i2c_write(mt9d112_client->addr,
427                         0x3390, reg_val, WORD_LEN);
428                 if (rc < 0)
429                         return rc;
430         }
431                 break;
432
433         case CAMERA_EFFECT_NEGATIVE: {
434                 reg_val = 0x6443;
435                 rc = mt9d112_i2c_write(mt9d112_client->addr,
436                         0x338C, reg_addr, WORD_LEN);
437                 if (rc < 0)
438                         return rc;
439
440                 rc = mt9d112_i2c_write(mt9d112_client->addr,
441                         0x3390, reg_val, WORD_LEN);
442                 if (rc < 0)
443                         return rc;
444         }
445                 break;
446
447         case CAMERA_EFFECT_SOLARIZE: {
448                 reg_val = 0x6445;
449                 rc = mt9d112_i2c_write(mt9d112_client->addr,
450                         0x338C, reg_addr, WORD_LEN);
451                 if (rc < 0)
452                         return rc;
453
454                 rc = mt9d112_i2c_write(mt9d112_client->addr,
455                         0x3390, reg_val, WORD_LEN);
456                 if (rc < 0)
457                         return rc;
458         }
459                 break;
460
461         case CAMERA_EFFECT_SEPIA: {
462                 reg_val = 0x6442;
463                 rc = mt9d112_i2c_write(mt9d112_client->addr,
464                         0x338C, reg_addr, WORD_LEN);
465                 if (rc < 0)
466                         return rc;
467
468                 rc = mt9d112_i2c_write(mt9d112_client->addr,
469                         0x3390, reg_val, WORD_LEN);
470                 if (rc < 0)
471                         return rc;
472         }
473                 break;
474
475         case CAMERA_EFFECT_PASTEL:
476         case CAMERA_EFFECT_MOSAIC:
477         case CAMERA_EFFECT_RESIZE:
478                 return -EINVAL;
479
480         default: {
481                 reg_val = 0x6440;
482                 rc = mt9d112_i2c_write(mt9d112_client->addr,
483                         0x338C, reg_addr, WORD_LEN);
484                 if (rc < 0)
485                         return rc;
486
487                 rc = mt9d112_i2c_write(mt9d112_client->addr,
488                         0x3390, reg_val, WORD_LEN);
489                 if (rc < 0)
490                         return rc;
491
492                 return -EINVAL;
493         }
494         }
495
496         /* Refresh Sequencer */
497         rc = mt9d112_i2c_write(mt9d112_client->addr,
498                 0x338C, 0xA103, WORD_LEN);
499         if (rc < 0)
500                 return rc;
501
502         rc = mt9d112_i2c_write(mt9d112_client->addr,
503                 0x3390, 0x0005, WORD_LEN);
504
505         return rc;
506 }
507
508 static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
509 {
510         uint16_t model_id = 0;
511         int rc = 0;
512
513         CDBG("init entry \n");
514         rc = mt9d112_reset(data);
515         if (rc < 0) {
516                 CDBG("reset failed!\n");
517                 goto init_probe_fail;
518         }
519
520         mdelay(5);
521
522         /* Micron suggested Power up block Start:
523         * Put MCU into Reset - Stop MCU */
524         rc = mt9d112_i2c_write(mt9d112_client->addr,
525                 REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
526         if (rc < 0)
527                 goto init_probe_fail;
528
529         /* Pull MCU from Reset - Start MCU */
530         rc = mt9d112_i2c_write(mt9d112_client->addr,
531                 REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
532         if (rc < 0)
533                 goto init_probe_fail;
534
535         mdelay(5);
536
537         /* Micron Suggested - Power up block */
538         rc = mt9d112_i2c_write(mt9d112_client->addr,
539                 REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
540         if (rc < 0)
541                 goto init_probe_fail;
542
543         rc = mt9d112_i2c_write(mt9d112_client->addr,
544                 REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
545         if (rc < 0)
546                 goto init_probe_fail;
547
548         /* FUSED_DEFECT_CORRECTION */
549         rc = mt9d112_i2c_write(mt9d112_client->addr,
550                 0x33F4, 0x031D, WORD_LEN);
551         if (rc < 0)
552                 goto init_probe_fail;
553
554         mdelay(5);
555
556         /* Micron suggested Power up block End */
557         /* Read the Model ID of the sensor */
558         rc = mt9d112_i2c_read(mt9d112_client->addr,
559                 REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
560         if (rc < 0)
561                 goto init_probe_fail;
562
563         CDBG("mt9d112 model_id = 0x%x\n", model_id);
564
565         /* Check if it matches it with the value in Datasheet */
566         if (model_id != MT9D112_MODEL_ID) {
567                 rc = -EINVAL;
568                 goto init_probe_fail;
569         }
570
571         rc = mt9d112_reg_init();
572         if (rc < 0)
573                 goto init_probe_fail;
574
575         return rc;
576
577 init_probe_fail:
578         return rc;
579 }
580
581 int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
582 {
583         int rc = 0;
584
585         mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
586         if (!mt9d112_ctrl) {
587                 CDBG("mt9d112_init failed!\n");
588                 rc = -ENOMEM;
589                 goto init_done;
590         }
591
592         if (data)
593                 mt9d112_ctrl->sensordata = data;
594
595         /* Input MCLK = 24MHz */
596         msm_camio_clk_rate_set(24000000);
597         mdelay(5);
598
599         msm_camio_camif_pad_reg_reset();
600
601         rc = mt9d112_sensor_init_probe(data);
602         if (rc < 0) {
603                 CDBG("mt9d112_sensor_init failed!\n");
604                 goto init_fail;
605         }
606
607 init_done:
608         return rc;
609
610 init_fail:
611         kfree(mt9d112_ctrl);
612         return rc;
613 }
614
615 static int mt9d112_init_client(struct i2c_client *client)
616 {
617         /* Initialize the MSM_CAMI2C Chip */
618         init_waitqueue_head(&mt9d112_wait_queue);
619         return 0;
620 }
621
622 int mt9d112_sensor_config(void __user *argp)
623 {
624         struct sensor_cfg_data cfg_data;
625         long   rc = 0;
626
627         if (copy_from_user(&cfg_data,
628                         (void *)argp,
629                         sizeof(struct sensor_cfg_data)))
630                 return -EFAULT;
631
632         /* down(&mt9d112_sem); */
633
634         CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
635                 cfg_data.cfgtype, cfg_data.mode);
636
637                 switch (cfg_data.cfgtype) {
638                 case CFG_SET_MODE:
639                         rc = mt9d112_set_sensor_mode(
640                                                 cfg_data.mode);
641                         break;
642
643                 case CFG_SET_EFFECT:
644                         rc = mt9d112_set_effect(cfg_data.mode,
645                                                 cfg_data.cfg.effect);
646                         break;
647
648                 case CFG_GET_AF_MAX_STEPS:
649                 default:
650                         rc = -EINVAL;
651                         break;
652                 }
653
654         /* up(&mt9d112_sem); */
655
656         return rc;
657 }
658
659 int mt9d112_sensor_release(void)
660 {
661         int rc = 0;
662
663         /* down(&mt9d112_sem); */
664
665         kfree(mt9d112_ctrl);
666         /* up(&mt9d112_sem); */
667
668         return rc;
669 }
670
671 static int mt9d112_i2c_probe(struct i2c_client *client,
672         const struct i2c_device_id *id)
673 {
674         int rc = 0;
675         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
676                 rc = -ENOTSUPP;
677                 goto probe_failure;
678         }
679
680         mt9d112_sensorw =
681                 kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
682
683         if (!mt9d112_sensorw) {
684                 rc = -ENOMEM;
685                 goto probe_failure;
686         }
687
688         i2c_set_clientdata(client, mt9d112_sensorw);
689         mt9d112_init_client(client);
690         mt9d112_client = client;
691
692         CDBG("mt9d112_probe succeeded!\n");
693
694         return 0;
695
696 probe_failure:
697         kfree(mt9d112_sensorw);
698         mt9d112_sensorw = NULL;
699         CDBG("mt9d112_probe failed!\n");
700         return rc;
701 }
702
703 static const struct i2c_device_id mt9d112_i2c_id[] = {
704         { "mt9d112", 0},
705         { },
706 };
707
708 static struct i2c_driver mt9d112_i2c_driver = {
709         .id_table = mt9d112_i2c_id,
710         .probe  = mt9d112_i2c_probe,
711         .remove = __exit_p(mt9d112_i2c_remove),
712         .driver = {
713                 .name = "mt9d112",
714         },
715 };
716
717 static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
718                                 struct msm_sensor_ctrl *s)
719 {
720         int rc = i2c_add_driver(&mt9d112_i2c_driver);
721         if (rc < 0 || mt9d112_client == NULL) {
722                 rc = -ENOTSUPP;
723                 goto probe_done;
724         }
725
726         /* Input MCLK = 24MHz */
727         msm_camio_clk_rate_set(24000000);
728         mdelay(5);
729
730         rc = mt9d112_sensor_init_probe(info);
731         if (rc < 0)
732                 goto probe_done;
733
734         s->s_init = mt9d112_sensor_init;
735         s->s_release = mt9d112_sensor_release;
736         s->s_config  = mt9d112_sensor_config;
737
738 probe_done:
739         CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
740         return rc;
741 }
742
743 static int __mt9d112_probe(struct platform_device *pdev)
744 {
745         return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
746 }
747
748 static struct platform_driver msm_camera_driver = {
749         .probe = __mt9d112_probe,
750         .driver = {
751                 .name = "msm_camera_mt9d112",
752                 .owner = THIS_MODULE,
753         },
754 };
755
756 static int __init mt9d112_init(void)
757 {
758         return platform_driver_register(&msm_camera_driver);
759 }
760
761 module_init(mt9d112_init);