import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / tcl8127_c_mlc / cam_cal / dummy_cam_cal.c
CommitLineData
6fa3eb70
S
1/*
2 * Driver for CAM_CAL
3 *
4 *
5 */
6
7#include <linux/i2c.h>
8#include <linux/platform_device.h>
9#include <linux/delay.h>
10#include <linux/cdev.h>
11#include <linux/uaccess.h>
12#include <linux/slab.h>
13#include <linux/fs.h>
14#include "kd_camera_hw.h"
15#include "cam_cal.h"
16#include "cam_cal_define.h"
17
18#include "dummy_cam_cal.h"
19#include <asm/system.h> // for SMP
20
21//#define CAM_CALGETDLT_DEBUG //test
22//#define CAM_CAL_DEBUG //test
23#ifdef CAM_CAL_DEBUG
24#define CAM_CALDB printk
25#else
26#define CAM_CALDB(x,...)
27#endif
28
29
30static DEFINE_SPINLOCK(g_CAM_CALLock); // for SMP
31
32#define CAM_CAL_I2C_BUSNUM 1
33static struct i2c_board_info __initdata kd_cam_cal_dev={ I2C_BOARD_INFO("dummy_cam_cal", 0xAB>>1)}; //make dummy_eeprom co-exist
34
35/*******************************************************************************
36*
37********************************************************************************/
38#define CAM_CAL_ICS_REVISION 1 //seanlin111208
39/*******************************************************************************
40*
41********************************************************************************/
42#define CAM_CAL_DRVNAME "dummy_cam_cal"
43#define CAM_CAL_I2C_GROUP_ID 0
44/*******************************************************************************
45*
46********************************************************************************/
47/* fix warning MSG
48static unsigned short g_pu2Normal_i2c[] = {S24CS64A_DEVICE_ID , I2C_CLIENT_END};
49static unsigned short g_u2Ignore = I2C_CLIENT_END;
50static struct i2c_client_address_data g_stCAM_CAL_Addr_data = {
51 .normal_i2c = g_pu2Normal_i2c,
52 .probe = &g_u2Ignore,
53 .ignore = &g_u2Ignore
54}; */
55static struct i2c_client * g_pstI2Cclient = NULL;
56
57//81 is used for V4L driver
58static dev_t g_CAM_CALdevno = MKDEV(CAM_CAL_DEV_MAJOR_NUMBER,0);
59static struct cdev * g_pCAM_CAL_CharDrv = NULL;
60//static spinlock_t g_CAM_CALLock;
61static struct class *CAM_CAL_class = NULL;
62static atomic_t g_CAM_CALatomic;
63/*******************************************************************************
64*
65********************************************************************************/
66// maximun read length is limited at "I2C_FIFO_SIZE" in I2c-mt65xx.c which is 8 bytes
67int iWriteCAM_CAL(u16 a_u2Addr , u32 a_u4Bytes, u8 * puDataInBytes)
68{
69 int i4RetValue = 0;
70 u32 u4Index = 0;
71 char puSendCmd[8] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF) ,
72 0, 0, 0, 0, 0, 0};
73 if(a_u4Bytes + 2 > 8)
74 {
75 CAM_CALDB("[CAM_CAL] exceed I2c-mt65xx.c 8 bytes limitation (include address 2 Byte)\n");
76 return -1;
77 }
78
79 for(u4Index = 0 ; u4Index < a_u4Bytes ; u4Index += 1 )
80 {
81 puSendCmd[(u4Index + 2)] = puDataInBytes[u4Index];
82 }
83
84 i4RetValue = i2c_master_send(g_pstI2Cclient, puSendCmd, (a_u4Bytes + 2));
85 if (i4RetValue != (a_u4Bytes + 2))
86 {
87 CAM_CALDB("[CAM_CAL] I2C write failed!! \n");
88 return -1;
89 }
90 mdelay(10); //for tWR singnal --> write data form buffer to memory.
91
92 //CAM_CALDB("[CAM_CAL] iWriteCAM_CAL done!! \n");
93 return 0;
94}
95
96
97// maximun read length is limited at "I2C_FIFO_SIZE" in I2c-mt65xx.c which is 8 bytes
98int iReadCAM_CAL(u16 a_u2Addr, u32 ui4_length, u8 * a_puBuff)
99{
100 int i4RetValue = 0;
101 char puReadCmd[2] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF)};
102
103 //CAM_CALDB("[CAM_CAL] iReadCAM_CAL!! \n");
104
105 if(ui4_length > 8)
106 {
107 CAM_CALDB("[CAM_CAL] exceed I2c-mt65xx.c 8 bytes limitation\n");
108 return -1;
109 }
110 spin_lock(&g_CAM_CALLock); //for SMP
111 g_pstI2Cclient->addr = g_pstI2Cclient->addr & (I2C_MASK_FLAG | I2C_WR_FLAG);
112 spin_unlock(&g_CAM_CALLock); // for SMP
113
114 //CAM_CALDB("[EERPOM] i2c_master_send \n");
115 i4RetValue = i2c_master_send(g_pstI2Cclient, puReadCmd, 2);
116 if (i4RetValue != 2)
117 {
118 CAM_CALDB("[CAM_CAL] I2C send read address failed!! \n");
119 return -1;
120 }
121
122 //CAM_CALDB("[EERPOM] i2c_master_recv \n");
123 i4RetValue = i2c_master_recv(g_pstI2Cclient, (char *)a_puBuff, ui4_length);
124 if (i4RetValue != ui4_length)
125 {
126 CAM_CALDB("[CAM_CAL] I2C read data failed!! \n");
127 return -1;
128 }
129 spin_lock(&g_CAM_CALLock); //for SMP
130 g_pstI2Cclient->addr = g_pstI2Cclient->addr & I2C_MASK_FLAG;
131 spin_unlock(&g_CAM_CALLock); // for SMP
132
133 //CAM_CALDB("[CAM_CAL] iReadCAM_CAL done!! \n");
134 return 0;
135}
136
137
138static int iWriteData(unsigned int ui4_offset, unsigned int ui4_length, unsigned char * pinputdata)
139{
140 int i4RetValue = 0;
141 int i4ResidueDataLength;
142 u32 u4IncOffset = 0;
143 u32 u4CurrentOffset;
144 u8 * pBuff;
145
146 CAM_CALDB("[CAM_CAL] iWriteData\n" );
147
148
149 if (ui4_offset + ui4_length >= 0x2000)
150 {
151 CAM_CALDB("[CAM_CAL] Write Error!! S-24CS64A not supprt address >= 0x2000!! \n" );
152 return -1;
153 }
154
155 i4ResidueDataLength = (int)ui4_length;
156 u4CurrentOffset = ui4_offset;
157 pBuff = pinputdata;
158 CAM_CALDB("[CAM_CAL] iWriteData u4CurrentOffset is %d \n",u4CurrentOffset);
159 do
160 {
161 if(i4ResidueDataLength >= 6)
162 {
163 i4RetValue = iWriteCAM_CAL((u16)u4CurrentOffset, 6, pBuff);
164 if (i4RetValue != 0)
165 {
166 CAM_CALDB("[CAM_CAL] I2C iWriteData failed!! \n");
167 return -1;
168 }
169 u4IncOffset += 6;
170 i4ResidueDataLength -= 6;
171 u4CurrentOffset = ui4_offset + u4IncOffset;
172 pBuff = pinputdata + u4IncOffset;
173 }
174 else
175 {
176 i4RetValue = iWriteCAM_CAL((u16)u4CurrentOffset, i4ResidueDataLength, pBuff);
177 if (i4RetValue != 0)
178 {
179 CAM_CALDB("[CAM_CAL] I2C iWriteData failed!! \n");
180 return -1;
181 }
182 u4IncOffset += 6;
183 i4ResidueDataLength -= 6;
184 u4CurrentOffset = ui4_offset + u4IncOffset;
185 pBuff = pinputdata + u4IncOffset;
186 //break;
187 }
188 }while (i4ResidueDataLength > 0);
189 CAM_CALDB("[CAM_CAL] iWriteData done\n" );
190
191 return 0;
192}
193
194//int iReadData(stCAM_CAL_INFO_STRUCT * st_pOutputBuffer)
195static int iReadData(unsigned int ui4_offset, unsigned int ui4_length, unsigned char * pinputdata)
196{
197 int i4RetValue = 0;
198 int i4ResidueDataLength;
199 u32 u4IncOffset = 0;
200 u32 u4CurrentOffset;
201 u8 * pBuff;
202 CAM_CALDB("[CAM_CAL] iReadData \n" );
203
204 if (ui4_offset + ui4_length >= 0x2000)
205 {
206 CAM_CALDB("[CAM_CAL] Read Error!! S-24CS64A not supprt address >= 0x2000!! \n" );
207 return -1;
208 }
209
210 i4ResidueDataLength = (int)ui4_length;
211 u4CurrentOffset = ui4_offset;
212 pBuff = pinputdata;
213 do
214 {
215 if(i4ResidueDataLength >= 8)
216 {
217 i4RetValue = iReadCAM_CAL((u16)u4CurrentOffset, 8, pBuff);
218 if (i4RetValue != 0)
219 {
220 CAM_CALDB("[CAM_CAL] I2C iReadData failed!! \n");
221 return -1;
222 }
223 u4IncOffset += 8;
224 i4ResidueDataLength -= 8;
225 u4CurrentOffset = ui4_offset + u4IncOffset;
226 pBuff = pinputdata + u4IncOffset;
227 }
228 else
229 {
230 i4RetValue = iReadCAM_CAL((u16)u4CurrentOffset, i4ResidueDataLength, pBuff);
231 if (i4RetValue != 0)
232 {
233 CAM_CALDB("[CAM_CAL] I2C iReadData failed!! \n");
234 return -1;
235 }
236 u4IncOffset += 8;
237 i4ResidueDataLength -= 8;
238 u4CurrentOffset = ui4_offset + u4IncOffset;
239 pBuff = pinputdata + u4IncOffset;
240 //break;
241 }
242 }while (i4ResidueDataLength > 0);
243//fix warning MSG CAM_CALDB("[CAM_CAL] iReadData finial address is %d length is %d buffer address is 0x%x\n",u4CurrentOffset, i4ResidueDataLength, pBuff);
244 CAM_CALDB("[CAM_CAL] iReadData done\n" );
245 return 0;
246}
247
248
249/*******************************************************************************
250*
251********************************************************************************/
252#define NEW_UNLOCK_IOCTL
253#ifndef NEW_UNLOCK_IOCTL
254static int CAM_CAL_Ioctl(struct inode * a_pstInode,
255struct file * a_pstFile,
256unsigned int a_u4Command,
257unsigned long a_u4Param)
258#else
259static long CAM_CAL_Ioctl(
260 struct file *file,
261 unsigned int a_u4Command,
262 unsigned long a_u4Param
263)
264#endif
265{
266 int i4RetValue = 0;
267 u8 * pBuff = NULL;
268 u8 * pWorkingBuff = NULL;
269 stCAM_CAL_INFO_STRUCT *ptempbuf;
270
271#ifdef CAM_CALGETDLT_DEBUG
272 struct timeval ktv1, ktv2;
273 unsigned long TimeIntervalUS;
274#endif
275
276 if(_IOC_NONE == _IOC_DIR(a_u4Command))
277 {
278 }
279 else
280 {
281 pBuff = (u8 *)kmalloc(sizeof(stCAM_CAL_INFO_STRUCT),GFP_KERNEL);
282
283 if(NULL == pBuff)
284 {
285 CAM_CALDB("[CAM_CAL] ioctl allocate mem failed\n");
286 return -ENOMEM;
287 }
288
289 if(_IOC_WRITE & _IOC_DIR(a_u4Command))
290 {
291 if(copy_from_user((u8 *) pBuff , (u8 *) a_u4Param, sizeof(stCAM_CAL_INFO_STRUCT)))
292 { //get input structure address
293 kfree(pBuff);
294 CAM_CALDB("[CAM_CAL] ioctl copy from user failed\n");
295 return -EFAULT;
296 }
297 }
298 }
299
300 ptempbuf = (stCAM_CAL_INFO_STRUCT *)pBuff;
301 pWorkingBuff = (u8*)kmalloc(ptempbuf->u4Length,GFP_KERNEL);
302 if(NULL == pWorkingBuff)
303 {
304 kfree(pBuff);
305 CAM_CALDB("[CAM_CAL] ioctl allocate mem failed\n");
306 return -ENOMEM;
307 }
308//fix warning MSG CAM_CALDB("[CAM_CAL] init Working buffer address 0x%x command is 0x%08x\n", pWorkingBuff, a_u4Command);
309
310
311 if(copy_from_user((u8*)pWorkingBuff , (u8*)ptempbuf->pu1Params, ptempbuf->u4Length))
312 {
313 kfree(pBuff);
314 kfree(pWorkingBuff);
315 CAM_CALDB("[CAM_CAL] ioctl copy from user failed\n");
316 return -EFAULT;
317 }
318
319 switch(a_u4Command)
320 {
321 case CAM_CALIOC_S_WRITE:
322 CAM_CALDB("[CAM_CAL] Write CMD \n");
323#ifdef CAM_CALGETDLT_DEBUG
324 do_gettimeofday(&ktv1);
325#endif
326 i4RetValue = iWriteData((u16)ptempbuf->u4Offset, ptempbuf->u4Length, pWorkingBuff);
327#ifdef CAM_CALGETDLT_DEBUG
328 do_gettimeofday(&ktv2);
329 if(ktv2.tv_sec > ktv1.tv_sec)
330 {
331 TimeIntervalUS = ktv1.tv_usec + 1000000 - ktv2.tv_usec;
332 }
333 else
334 {
335 TimeIntervalUS = ktv2.tv_usec - ktv1.tv_usec;
336 }
337 printk("Write data %d bytes take %lu us\n",ptempbuf->u4Length, TimeIntervalUS);
338#endif
339 break;
340 case CAM_CALIOC_G_READ:
341 CAM_CALDB("[CAM_CAL] Read CMD \n");
342#ifdef CAM_CALGETDLT_DEBUG
343 do_gettimeofday(&ktv1);
344#endif
345 CAM_CALDB("[CAM_CAL] offset %d \n", ptempbuf->u4Offset);
346 CAM_CALDB("[CAM_CAL] length %d \n", ptempbuf->u4Length);
347//fix warning MSG CAM_CALDB("[CAM_CAL] Before read Working buffer address 0x%x \n", pWorkingBuff);
348
349 i4RetValue = iReadData((u16)ptempbuf->u4Offset, ptempbuf->u4Length, pWorkingBuff);
350//fix warning MSG CAM_CALDB("[CAM_CAL] After read Working buffer address 0x%x \n", pWorkingBuff);
351
352
353#ifdef CAM_CALGETDLT_DEBUG
354 do_gettimeofday(&ktv2);
355 if(ktv2.tv_sec > ktv1.tv_sec)
356 {
357 TimeIntervalUS = ktv1.tv_usec + 1000000 - ktv2.tv_usec;
358 }
359 else
360 {
361 TimeIntervalUS = ktv2.tv_usec - ktv1.tv_usec;
362 }
363 printk("Read data %d bytes take %lu us\n",ptempbuf->u4Length, TimeIntervalUS);
364#endif
365
366 break;
367 default :
368 CAM_CALDB("[CAM_CAL] No CMD \n");
369 i4RetValue = -EPERM;
370 break;
371 }
372
373 if(_IOC_READ & _IOC_DIR(a_u4Command))
374 {
375 //copy data to user space buffer, keep other input paremeter unchange.
376 CAM_CALDB("[CAM_CAL] to user length %d \n", ptempbuf->u4Length);
377//fix warning MSG CAM_CALDB("[CAM_CAL] to user Working buffer address 0x%x \n", pWorkingBuff);
378 if(copy_to_user((u8 __user *) ptempbuf->pu1Params , (u8 *)pWorkingBuff , ptempbuf->u4Length))
379 {
380 kfree(pBuff);
381 kfree(pWorkingBuff);
382 CAM_CALDB("[CAM_CAL] ioctl copy to user failed\n");
383 return -EFAULT;
384 }
385 }
386
387 kfree(pBuff);
388 kfree(pWorkingBuff);
389 return i4RetValue;
390}
391
392
393static u32 g_u4Opened = 0;
394//#define
395//Main jobs:
396// 1.check for device-specified errors, device not ready.
397// 2.Initialize the device if it is opened for the first time.
398static int CAM_CAL_Open(struct inode * a_pstInode, struct file * a_pstFile)
399{
400 CAM_CALDB("[S24CAM_CAL] CAM_CAL_Open\n");
401 spin_lock(&g_CAM_CALLock);
402 if(g_u4Opened)
403 {
404 spin_unlock(&g_CAM_CALLock);
405 return -EBUSY;
406 }
407 else
408 {
409 g_u4Opened = 1;
410 atomic_set(&g_CAM_CALatomic,0);
411 }
412 spin_unlock(&g_CAM_CALLock);
413
414//#if defined(MT6572)
415 // do nothing
416//#else
417 //if(TRUE != hwPowerOn(MT65XX_POWER_LDO_VCAMA, VOL_2800, "S24CS64A"))
418 //{
419 // CAM_CALDB("[CAM_CAL] Fail to enable analog gain\n");
420 // return -EIO;
421 //}
422//#endif
423
424 return 0;
425}
426
427//Main jobs:
428// 1.Deallocate anything that "open" allocated in private_data.
429// 2.Shut down the device on last close.
430// 3.Only called once on last time.
431// Q1 : Try release multiple times.
432static int CAM_CAL_Release(struct inode * a_pstInode, struct file * a_pstFile)
433{
434 spin_lock(&g_CAM_CALLock);
435
436 g_u4Opened = 0;
437
438 atomic_set(&g_CAM_CALatomic,0);
439
440 spin_unlock(&g_CAM_CALLock);
441
442 return 0;
443}
444
445static const struct file_operations g_stCAM_CAL_fops =
446{
447 .owner = THIS_MODULE,
448 .open = CAM_CAL_Open,
449 .release = CAM_CAL_Release,
450 //.ioctl = CAM_CAL_Ioctl
451 .unlocked_ioctl = CAM_CAL_Ioctl
452};
453
454#define CAM_CAL_DYNAMIC_ALLOCATE_DEVNO 1
455inline static int RegisterCAM_CALCharDrv(void)
456{
457 struct device* CAM_CAL_device = NULL;
458
459#if CAM_CAL_DYNAMIC_ALLOCATE_DEVNO
460 if( alloc_chrdev_region(&g_CAM_CALdevno, 0, 1,CAM_CAL_DRVNAME) )
461 {
462 CAM_CALDB("[CAM_CAL] Allocate device no failed\n");
463
464 return -EAGAIN;
465 }
466#else
467 if( register_chrdev_region( g_CAM_CALdevno , 1 , CAM_CAL_DRVNAME) )
468 {
469 CAM_CALDB("[CAM_CAL] Register device no failed\n");
470
471 return -EAGAIN;
472 }
473#endif
474
475 //Allocate driver
476 g_pCAM_CAL_CharDrv = cdev_alloc();
477
478 if(NULL == g_pCAM_CAL_CharDrv)
479 {
480 unregister_chrdev_region(g_CAM_CALdevno, 1);
481
482 CAM_CALDB("[CAM_CAL] Allocate mem for kobject failed\n");
483
484 return -ENOMEM;
485 }
486
487 //Attatch file operation.
488 cdev_init(g_pCAM_CAL_CharDrv, &g_stCAM_CAL_fops);
489
490 g_pCAM_CAL_CharDrv->owner = THIS_MODULE;
491
492 //Add to system
493 if(cdev_add(g_pCAM_CAL_CharDrv, g_CAM_CALdevno, 1))
494 {
495 CAM_CALDB("[CAM_CAL] Attatch file operation failed\n");
496
497 unregister_chrdev_region(g_CAM_CALdevno, 1);
498
499 return -EAGAIN;
500 }
501
502 CAM_CAL_class = class_create(THIS_MODULE, "CAM_CALdrv");
503 if (IS_ERR(CAM_CAL_class)) {
504 int ret = PTR_ERR(CAM_CAL_class);
505 CAM_CALDB("Unable to create class, err = %d\n", ret);
506 return ret;
507 }
508 CAM_CAL_device = device_create(CAM_CAL_class, NULL, g_CAM_CALdevno, NULL, CAM_CAL_DRVNAME);
509
510 return 0;
511}
512
513inline static void UnregisterCAM_CALCharDrv(void)
514{
515 //Release char driver
516 cdev_del(g_pCAM_CAL_CharDrv);
517
518 unregister_chrdev_region(g_CAM_CALdevno, 1);
519
520 device_destroy(CAM_CAL_class, g_CAM_CALdevno);
521 class_destroy(CAM_CAL_class);
522}
523
524
525//////////////////////////////////////////////////////////////////////
526#ifndef CAM_CAL_ICS_REVISION
527static int CAM_CAL_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info);
528#elif 0
529static int CAM_CAL_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
530#else
531#endif
532static int CAM_CAL_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
533static int CAM_CAL_i2c_remove(struct i2c_client *);
534
535static const struct i2c_device_id CAM_CAL_i2c_id[] = {{CAM_CAL_DRVNAME,0},{}};
536#if 0 //test110314 Please use the same I2C Group ID as Sensor
537static unsigned short force[] = {CAM_CAL_I2C_GROUP_ID, S24CS64A_DEVICE_ID, I2C_CLIENT_END, I2C_CLIENT_END};
538#else
539//static unsigned short force[] = {CAM_CAL_I2C_GROUP_ID, S24CS64A_DEVICE_ID, I2C_CLIENT_END, I2C_CLIENT_END};
540#endif
541//static const unsigned short * const forces[] = { force, NULL };
542//static struct i2c_client_address_data addr_data = { .forces = forces,};
543
544
545static struct i2c_driver CAM_CAL_i2c_driver = {
546 .probe = CAM_CAL_i2c_probe,
547 .remove = CAM_CAL_i2c_remove,
548// .detect = CAM_CAL_i2c_detect,
549 .driver.name = CAM_CAL_DRVNAME,
550 .id_table = CAM_CAL_i2c_id,
551};
552
553#ifndef CAM_CAL_ICS_REVISION
554static int CAM_CAL_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) {
555 strcpy(info->type, CAM_CAL_DRVNAME);
556 return 0;
557}
558#endif
559static int CAM_CAL_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) {
560int i4RetValue = 0;
561 CAM_CALDB("[CAM_CAL] Attach I2C \n");
562// spin_lock_init(&g_CAM_CALLock);
563
564 //get sensor i2c client
565 spin_lock(&g_CAM_CALLock); //for SMP
566 g_pstI2Cclient = client;
567 g_pstI2Cclient->addr = S24CS64A_DEVICE_ID>>1;
568 spin_unlock(&g_CAM_CALLock); // for SMP
569
570 CAM_CALDB("[CAM_CAL] g_pstI2Cclient->addr = 0x%8x \n",g_pstI2Cclient->addr);
571 //Register char driver
572 i4RetValue = RegisterCAM_CALCharDrv();
573
574 if(i4RetValue){
575 CAM_CALDB("[CAM_CAL] register char device failed!\n");
576 return i4RetValue;
577 }
578
579
580 CAM_CALDB("[CAM_CAL] Attached!! \n");
581 return 0;
582}
583
584static int CAM_CAL_i2c_remove(struct i2c_client *client)
585{
586 return 0;
587}
588
589static int CAM_CAL_probe(struct platform_device *pdev)
590{
591 return i2c_add_driver(&CAM_CAL_i2c_driver);
592}
593
594static int CAM_CAL_remove(struct platform_device *pdev)
595{
596 i2c_del_driver(&CAM_CAL_i2c_driver);
597 return 0;
598}
599
600// platform structure
601static struct platform_driver g_stCAM_CAL_Driver = {
602 .probe = CAM_CAL_probe,
603 .remove = CAM_CAL_remove,
604 .driver = {
605 .name = CAM_CAL_DRVNAME,
606 .owner = THIS_MODULE,
607 }
608};
609
610
611static struct platform_device g_stCAM_CAL_Device = {
612 .name = CAM_CAL_DRVNAME,
613 .id = 0,
614 .dev = {
615 }
616};
617
618static int __init CAM_CAL_i2C_init(void)
619{
620 i2c_register_board_info(CAM_CAL_I2C_BUSNUM, &kd_cam_cal_dev, 1);
621 if(platform_driver_register(&g_stCAM_CAL_Driver)){
622 CAM_CALDB("failed to register CAM_CAL driver\n");
623 return -ENODEV;
624 }
625
626 if (platform_device_register(&g_stCAM_CAL_Device))
627 {
628 CAM_CALDB("failed to register CAM_CAL driver\n");
629 return -ENODEV;
630 }
631
632 return 0;
633}
634
635static void __exit CAM_CAL_i2C_exit(void)
636{
637 platform_driver_unregister(&g_stCAM_CAL_Driver);
638}
639
640module_init(CAM_CAL_i2C_init);
641module_exit(CAM_CAL_i2C_exit);
642
643MODULE_DESCRIPTION("CAM_CAL driver");
644MODULE_AUTHOR("Sean Lin <Sean.Lin@Mediatek.com>");
645MODULE_LICENSE("GPL");
646
647