tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / sprd_sensor / otp / sensor_otp_coreprime3g_ve.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/init.h>
18 #include <linux/bitops.h>
19 #include <linux/delay.h>
20 #include <linux/kernel.h>
21 #include <linux/kthread.h>
22 #include <linux/fs.h>
23
24 #include <video/sensor_drv_k.h>
25 #include <linux/vmalloc.h>
26 #include <linux/sprd_mm.h>
27
28 #include "sensor_otp.h"
29
30
31 #define DW9807_EEPROM_SLAVE_ADDR  (0xB0 >> 1)
32
33 #define SENSOR_SUCCESS      0
34 #define cmr_bzero(b, len)                     memset((b), '\0', (len))
35 #define cmr_copy(b, a, len)                   memcpy((b), (a), (len))
36
37
38 enum sensor_cmd {
39   SENSOR_ACCESS_VAL,
40 };
41
42 typedef enum {
43   SENSOR_VAL_TYPE_READ_OTP,
44 } SENSOR_IOCTL_VAL_TYPE;
45
46
47 typedef struct _sensor_val_tag {
48   uint8_t type;
49   void *pval;
50 } SENSOR_VAL_T, *SENSOR_VAL_T_PTR;
51
52 struct isp_data_t {
53   uint32_t size;
54   void *data_ptr;
55 };
56
57
58         //static struct task_struct * otp_task = NULL;
59 static struct file *pfile = NULL;
60 static struct file *pdebugfile = NULL;
61
62 static int fw_version_len=0;
63 static uint8_t fw_version[12] = {0};
64
65 static int z_ioctl (struct file *f, unsigned int cmd, unsigned long arg)
66 {
67   if (f->f_op->compat_ioctl)
68     return f->f_op->compat_ioctl (f, cmd, arg);
69   else if (f->f_op->unlocked_ioctl)
70     return f->f_op->unlocked_ioctl (f, cmd, arg);
71 }
72
73 static void Sensor_PowerOn (uint32_t power_on)
74 {
75   struct sensor_power_info_tag power_cfg;
76   uint32_t mclk = 24;
77
78   memset (&power_cfg, 0, sizeof (struct sensor_power_info_tag));
79   power_cfg.op_sensor_id = 0;
80   if (power_on)  {
81       power_cfg.is_on = 1;
82     } else {
83       power_cfg.is_on = 0;
84     }
85   z_ioctl (pfile, SENSOR_IO_POWER_CFG, &power_cfg);
86
87   if (power_on) {
88       z_ioctl (pfile, SENSOR_IO_SET_MCLK, &mclk);
89     }
90 }
91
92 static int Sensor_WriteI2C (uint16_t slave_addr, uint8_t * cmd, uint16_t cmd_length)
93 {
94   struct sensor_i2c_tag i2c_tab;
95   int ret = SENSOR_SUCCESS;
96
97   i2c_tab.slave_addr = slave_addr;
98   i2c_tab.i2c_data = cmd;
99   i2c_tab.i2c_count = cmd_length;
100
101   MM_TRACE ("Sensor_ReadI2C, slave_addr=0x%x, ptr=0x%p, count=%d\n",
102             i2c_tab.slave_addr, i2c_tab.i2c_data, i2c_tab.i2c_count);
103
104   ret = z_ioctl (pfile, SENSOR_IO_I2C_WRITE_EXT, &i2c_tab);
105
106   return ret;
107 }
108
109 static int Sensor_ReadI2C (uint16_t slave_addr, uint8_t * cmd, uint16_t cmd_length)
110 {
111   struct sensor_i2c_tag i2c_tab;
112   int ret = SENSOR_SUCCESS;
113
114   i2c_tab.slave_addr = slave_addr;
115   i2c_tab.i2c_data = cmd;
116   i2c_tab.i2c_count = cmd_length;
117
118 //       MM_TRACE("Sensor_ReadI2C, slave_addr=0x%x, ptr=0x%p, count=%d\n",
119 //            i2c_tab.slave_addr, i2c_tab.i2c_data, i2c_tab.i2c_count);
120
121   ret = z_ioctl (pfile, SENSOR_IO_I2C_READ_EXT, &i2c_tab);
122
123   return ret;
124 }
125
126 static uint32_t _read_otp (void *sensor_handle, int sensor_id, int cmd, long arg)
127 {
128   uint32_t rtn = SENSOR_SUCCESS;
129   SENSOR_OTP_PARAM_T *param_ptr = (SENSOR_OTP_PARAM_T *) (((SENSOR_VAL_T *) arg)->pval);
130   uint32_t start_addr = 0;
131   uint32_t len = 0;
132   uint8_t *buff = NULL;
133   uint8_t cmd_val[3] = { 0x00 };
134   uint16_t cmd_len;
135   uint32_t i;
136
137   if (NULL == param_ptr) {
138       return -1;
139     }
140
141   MM_TRACE ("SENSOR_s5k4h5yc: _s5k4h5yc_read_otp E\n");
142
143   cmd_len = 2;
144   cmd_val[0] = 0x00;
145   cmd_val[1] = 0x00;
146   rtn = Sensor_WriteI2C (DW9807_EEPROM_SLAVE_ADDR, (uint8_t *) & cmd_val[0], cmd_len);
147   udelay (1000);                //usleep(1000);
148
149   MM_TRACE ("write i2c rtn %d type %d\n", rtn, param_ptr->type);
150
151   buff = param_ptr->buff;
152   if (SENSOR_OTP_PARAM_NORMAL == param_ptr->type) {
153       start_addr = param_ptr->start_addr;
154       len = 8192;
155     } else if (SENSOR_OTP_PARAM_CHECKSUM == param_ptr->type) {
156       start_addr = 0xFC;
157       len = 4;
158     } else if (SENSOR_OTP_PARAM_READBYTE == param_ptr->type) {
159       start_addr = param_ptr->start_addr;
160       len = param_ptr->len;
161     } else if (SENSOR_OTP_PARAM_FW_VERSION == param_ptr->type) {
162       start_addr = 0x30;
163       len = 11;
164     }
165
166   // EEPROM READ
167   for (i = 0; i < len; i++) {
168       cmd_val[0] = ((start_addr + i) >> 8) & 0xff;
169       cmd_val[1] = (start_addr + i) & 0xff;
170       rtn =     Sensor_ReadI2C (DW9807_EEPROM_SLAVE_ADDR, (uint8_t *) & cmd_val[0], cmd_len);
171       if (SENSOR_SUCCESS == rtn) {
172           buff[i] = (cmd_val[0]) & 0xff;
173         }
174       //MM_TRACE("rtn %d value %d addr 0x%x\ns", rtn, buff[i], start_addr + i);
175     }
176   param_ptr->len = len;
177
178   MM_TRACE ("SENSOR_s5k4h5yc: _s5k4h5yc_read_otp X\n");
179
180   return rtn;
181
182 }
183
184 int sensor_reloadinfo_thread (void *data)
185 {
186   int32_t rtn = 0;
187   int ret = 0;
188   SENSOR_OTP_PARAM_T *param_ptr = (SENSOR_OTP_PARAM_T *) data;
189
190   uint32_t clock = 400000;
191
192   loff_t otp_start_addr = 0;
193   uint32_t otp_data_len = 0;
194   SENSOR_VAL_T val;
195   struct isp_data_t checksum_otp;
196   struct isp_data_t sensor_otp;
197   uint32_t is_need_checksum = 0;
198
199   uint32_t count = 0;
200   MM_TRACE ("sensor_reloadinfo_thread start\n");
201
202   cmr_bzero (&checksum_otp, sizeof (checksum_otp));
203   cmr_bzero (&sensor_otp, sizeof (sensor_otp));
204   cmr_bzero (param_ptr, sizeof (SENSOR_OTP_PARAM_T));
205
206   while(1){
207           pfile = filp_open ("/dev/sprd_sensor", O_RDWR, 0);
208           if (IS_ERR (pfile)){
209                     if(count++ < 100) {
210                       mdelay(100);
211                           MM_TRACE ("open /dev/sprd_sensor mdelay 100 \n");
212                     }else{
213                       MM_TRACE ("open /dev/sprd_sensor failed\n");
214                       return -1;
215                     }
216           }else{
217                 break;
218           }
219   }
220
221   Sensor_PowerOn (1);
222
223   ret = z_ioctl (pfile, SENSOR_IO_SET_I2CCLOCK, &clock);
224
225   /*read fw_version */
226   fw_version_len = 11;
227
228   cmr_bzero (param_ptr, sizeof (SENSOR_OTP_PARAM_T));
229   param_ptr->start_addr = 0;
230   param_ptr->len = fw_version_len;
231   param_ptr->buff = fw_version;
232   param_ptr->type = SENSOR_OTP_PARAM_FW_VERSION;
233   val.type = SENSOR_VAL_TYPE_READ_OTP;
234   val.pval = param_ptr;
235   ret = _read_otp (NULL, 0, SENSOR_ACCESS_VAL, (long) &val);
236   if (ret || 0 == param_ptr->len) {
237       MM_TRACE ("read otp data failed\n");
238       goto EXIT;
239   }
240
241   //checksum
242   checksum_otp.size = 4;
243   checksum_otp.data_ptr = vmalloc (checksum_otp.size);
244   if (NULL == checksum_otp.data_ptr) {
245       MM_TRACE ("malloc checksum_otp buffer failed\n");
246       goto EXIT;
247     }
248
249   cmr_bzero (param_ptr, sizeof (SENSOR_OTP_PARAM_T));
250   param_ptr->start_addr = 0;
251   param_ptr->len = checksum_otp.size;
252   param_ptr->buff = checksum_otp.data_ptr;
253   param_ptr->type = SENSOR_OTP_PARAM_CHECKSUM;
254   val.type = SENSOR_VAL_TYPE_READ_OTP;
255   val.pval = param_ptr;
256   ret = _read_otp (NULL, 0, SENSOR_ACCESS_VAL, (long) &val);
257   if (ret || 0 == param_ptr->len) {
258       MM_TRACE ("read otp data checksum failed\n");
259       goto EXIT;
260     }
261
262   /*read lsc, awb from real otp */
263   //camera_calibrationconfigure_load(&otp_start_addr, &otp_data_len);
264   otp_data_len = 8192;
265   sensor_otp.data_ptr = vmalloc (otp_data_len);
266   if (NULL == sensor_otp.data_ptr) {
267       MM_TRACE ("malloc random lsc file failed\n");
268       goto EXIT;
269     }
270
271   cmr_bzero (param_ptr, sizeof (SENSOR_OTP_PARAM_T));
272   param_ptr->start_addr = 0;
273   param_ptr->len = 0;
274   param_ptr->buff = sensor_otp.data_ptr;
275   param_ptr->type = SENSOR_OTP_PARAM_NORMAL;
276   val.type = SENSOR_VAL_TYPE_READ_OTP;
277   val.pval = param_ptr;
278   ret = _read_otp (NULL, 0, SENSOR_ACCESS_VAL, (long) &val);
279   if (ret || 0 == param_ptr->len) {
280       MM_TRACE ("read otp data failed\n");
281       goto EXIT;
282     }
283   param_ptr->golden.size = checksum_otp.size;
284   param_ptr->golden.data_ptr = checksum_otp.data_ptr;
285 #if 0
286         pdebugfile = filp_open ("/data/otp.bin", O_CREAT|O_RDWR, 0);
287         if (IS_ERR (pdebugfile)) {
288                 MM_TRACE ("open /data/otp.bin failed\n");
289                 return -1;
290           }
291         vfs_write(pdebugfile, param_ptr->buff,otp_data_len, &otp_start_addr);
292         filp_close(pdebugfile, NULL);
293 #endif
294
295 EXIT:
296   Sensor_PowerOn (0);
297   filp_close (pfile, NULL);
298   MM_TRACE ("sensor_reloadinfo_thread end\n");
299   return rtn;
300 }
301
302 void sensor_get_fw_version_otp(void *read_fw_version)
303 {
304         if(read_fw_version) {
305                 sprintf(read_fw_version, fw_version);
306         }
307 }
308