static int __init CAM_CAL_init(void) { int i4RetValue = 0; CAM_CALDB("CAM_CAL_i2C_init\n"); //Register char driver i4RetValue = RegisterCAM_CALCharDrv(); if(i4RetValue){ CAM_CALDB(" register char device failed!\n"); return i4RetValue; } CAM_CALDB(" Attached!! \n"); // i2c_register_board_info(CAM_CAL_I2C_BUSNUM, &kd_cam_cal_dev, 1); if(platform_driver_register(&g_stCAM_CAL_Driver)){ CAM_CALERR("failed to register 135otp driver\n"); return -ENODEV; } if (platform_device_register(&g_stCAM_CAL_Device)) { CAM_CALERR("failed to register 135otp driver, 2nd time\n"); return -ENODEV; } return 0; }
inline static int RegisterCAM_CALCharDrv(void) { struct device* CAM_CAL_device = NULL; CAM_CALDB("RegisterCAM_CALCharDrv\n"); #if CAM_CAL_DYNAMIC_ALLOCATE_DEVNO if( alloc_chrdev_region(&g_CAM_CALdevno, 0, 1,CAM_CAL_DRVNAME) ) { CAM_CALERR(" Allocate device no failed\n"); return -EAGAIN; } #else if( register_chrdev_region( g_CAM_CALdevno , 1 , CAM_CAL_DRVNAME) ) { CAM_CALERR(" Register device no failed\n"); return -EAGAIN; } #endif //Allocate driver g_pCAM_CAL_CharDrv = cdev_alloc(); if(NULL == g_pCAM_CAL_CharDrv) { unregister_chrdev_region(g_CAM_CALdevno, 1); CAM_CALERR(" Allocate mem for kobject failed\n"); return -ENOMEM; } //Attatch file operation. cdev_init(g_pCAM_CAL_CharDrv, &g_stCAM_CAL_fops); g_pCAM_CAL_CharDrv->owner = THIS_MODULE; //Add to system if(cdev_add(g_pCAM_CAL_CharDrv, g_CAM_CALdevno, 1)) { CAM_CALERR(" Attatch file operation failed\n"); unregister_chrdev_region(g_CAM_CALdevno, 1); return -EAGAIN; } CAM_CAL_class = class_create(THIS_MODULE, "CAM_CALdrv"); if (IS_ERR(CAM_CAL_class)) { int ret = PTR_ERR(CAM_CAL_class); CAM_CALERR("Unable to create class, err = %d\n", ret); return ret; } CAM_CAL_device = device_create(CAM_CAL_class, NULL, g_CAM_CALdevno, NULL, CAM_CAL_DRVNAME); return 0; }
static int iWriteReg(u16 a_u2Addr , u32 a_u4Data , u32 a_u4Bytes , u16 i2cId) { int i4RetValue = 0; int u4Index = 0; u8 * puDataInBytes = (u8 *)&a_u4Data; int retry = 3; char puSendCmd[6] = {(char)(a_u2Addr >> 8) , (char)(a_u2Addr & 0xFF) , 0 , 0 , 0 , 0}; spin_lock(&g_CAM_CALLock); g_pstI2Cclient->addr = (i2cId >> 1); g_pstI2Cclient->ext_flag = (g_pstI2Cclient->ext_flag)&(~I2C_DMA_FLAG); spin_unlock(&g_CAM_CALLock); if(a_u4Bytes > 2) { CAM_CALERR(" exceed 2 bytes \n"); return -1; } if(a_u4Data >> (a_u4Bytes << 3)) { CAM_CALERR(" warning!! some data is not sent!! \n"); } for(u4Index = 0 ; u4Index < a_u4Bytes ; u4Index += 1 ) { puSendCmd[(u4Index + 2)] = puDataInBytes[(a_u4Bytes - u4Index-1)]; } do { i4RetValue = i2c_master_send(g_pstI2Cclient, puSendCmd, (a_u4Bytes + 2)); if (i4RetValue != (a_u4Bytes + 2)) { CAM_CALERR(" I2C send failed addr = 0x%x, data = 0x%x !! \n", a_u2Addr, a_u4Data); } else { break; } mdelay(5); } while ((retry --) > 0); return 0; }
int read_imx135_otp(u8 page, u16 offset, u8* data) { if(!start_read_otp(page)) { CAM_CALERR("OTP Start read Page %d Fail!\n", page); return 0; } else { *data = read_cmos_sensor(offset); //CAM_CALDB("OTP read page 0x%x offset 0x%x data 0x%x\n", page,offset,*data); } return 1; }
bool selective_read_byte(u32 addr, BYTE* data,u16 i2c_id) { // CAM_CALDB("selective_read_byte\n"); u8 page = addr/PAGE_SIZE_; /* size of page was 256 */ u8 offset = addr%PAGE_SIZE_; kdSetI2CSpeed(EEPROM_I2C_SPEED); if(iReadRegI2C(&offset, 1, (u8*)data, 1, i2c_id+(page<<1))<0) { CAM_CALERR("fail selective_read_byte addr =0x%x data = 0x%x,page %d, offset 0x%x", addr, *data,page,offset); return false; } //CAM_CALDB("selective_read_byte addr =0x%x data = 0x%x,page %d, offset 0x%x", addr, *data,page,offset); return true; }
//#define //Main jobs: // 1.check for device-specified errors, device not ready. // 2.Initialize the device if it is opened for the first time. static int CAM_CAL_Open(struct inode * a_pstInode, struct file * a_pstFile) { CAM_CALDB("CAM_CAL_Open\n"); spin_lock(&g_CAM_CALLock); if(g_u4Opened) { spin_unlock(&g_CAM_CALLock); CAM_CALERR("Opened, return -EBUSY\n"); return -EBUSY; } else { g_u4Opened = 1; atomic_set(&g_CAM_CALatomic,0); } spin_unlock(&g_CAM_CALLock); return 0; }
static long CAM_CAL_Ioctl_Compat(struct file *filp, unsigned int cmd, unsigned long arg) { long ret; int err; COMPAT_stCAM_CAL_INFO_STRUCT __user *data32; stCAM_CAL_INFO_STRUCT __user *data; CAM_CALDB("[CAMERA SENSOR] CAM_CAL_Ioctl_Compat,%p %p %x ioc size %d\n", filp->f_op , filp->f_op->unlocked_ioctl, cmd, _IOC_SIZE(cmd)); if (!filp->f_op || !filp->f_op->unlocked_ioctl) return -ENOTTY; switch (cmd) { case COMPAT_CAM_CALIOC_G_READ: { data32 = compat_ptr(arg); data = compat_alloc_user_space(sizeof(*data)); if (data == NULL) return -EFAULT; err = compat_get_cal_info_struct(data32, data); if (err) return err; ret = filp->f_op->unlocked_ioctl(filp, CAM_CALIOC_G_READ, (unsigned long)data); err = compat_put_cal_info_struct(data32, data); if (err != 0) CAM_CALERR("[CAMERA SENSOR] compat_put_acdk_sensor_getinfo_struct failed\n"); return ret; } default: return -ENOIOCTLCMD; } }
/************************************************************************************************* * Function : start_read_otp * Description : before read otp , set the reading block setting * Parameters : [BYTE] zone : OTP PAGE index , 0x00~0x0f * Return : 0, reading block setting err 1, reading block setting ok **************************************************************************************************/ bool start_read_otp(BYTE zone) { BYTE val = 0; int i; write_cmos_sensor_8(0x0104, 0x01); write_cmos_sensor(0x3B02, zone); //PAGE write_cmos_sensor(0x3B00, 0x01); write_cmos_sensor_8(0x0104, 0x00); Sleep(5); for(i=0; i<100; i++) { val = read_cmos_sensor(0x3B01); if((val & 0x01) == 0x01) break; Sleep(2); } if(i == 100) { CAM_CALERR("Read Page %d Err!\n", zone); // print log return 0; } return 1; }
static long CAM_CAL_Ioctl( struct file *file, unsigned int a_u4Command, unsigned long a_u4Param ) #endif { int i4RetValue = 0; u8 * pBuff = NULL; u8 * pu1Params = NULL; stCAM_CAL_INFO_STRUCT *ptempbuf; #ifdef CAM_CALGETDLT_DEBUG struct timeval ktv1, ktv2; unsigned long TimeIntervalUS; #endif if(_IOC_NONE == _IOC_DIR(a_u4Command)) { } else { pBuff = (u8 *)kmalloc(sizeof(stCAM_CAL_INFO_STRUCT),GFP_KERNEL); if(NULL == pBuff) { CAM_CALERR(" ioctl allocate mem failed\n"); return -ENOMEM; } if(_IOC_WRITE & _IOC_DIR(a_u4Command)) { if(copy_from_user((u8 *) pBuff , (u8 *) a_u4Param, sizeof(stCAM_CAL_INFO_STRUCT))) { //get input structure address kfree(pBuff); CAM_CALERR("ioctl copy from user failed\n"); return -EFAULT; } } } ptempbuf = (stCAM_CAL_INFO_STRUCT *)pBuff; pu1Params = (u8*)kmalloc(ptempbuf->u4Length,GFP_KERNEL); if(NULL == pu1Params) { kfree(pBuff); CAM_CALERR("ioctl allocate mem failed\n"); return -ENOMEM; } if(copy_from_user((u8*)pu1Params , (u8*)ptempbuf->pu1Params, ptempbuf->u4Length)) { kfree(pBuff); kfree(pu1Params); CAM_CALERR(" ioctl copy from user failed\n"); return -EFAULT; } switch(a_u4Command) { case CAM_CALIOC_S_WRITE: CAM_CALDB("Write CMD \n"); #ifdef CAM_CALGETDLT_DEBUG do_gettimeofday(&ktv1); #endif i4RetValue = 0;//iWriteData((u16)ptempbuf->u4Offset, ptempbuf->u4Length, pu1Params); #ifdef CAM_CALGETDLT_DEBUG do_gettimeofday(&ktv2); if(ktv2.tv_sec > ktv1.tv_sec) { TimeIntervalUS = ktv1.tv_usec + 1000000 - ktv2.tv_usec; } else { TimeIntervalUS = ktv2.tv_usec - ktv1.tv_usec; } CAM_CALDB("Write data %d bytes take %lu us\n",ptempbuf->u4Length, TimeIntervalUS); #endif break; case CAM_CALIOC_G_READ: CAM_CALDB("[CAM_CAL] Read CMD \n"); #ifdef CAM_CALGETDLT_DEBUG do_gettimeofday(&ktv1); #endif i4RetValue = selective_read_region(ptempbuf->u4Offset, pu1Params, IMX135_OTP_DEVICE_ID,ptempbuf->u4Length); #ifdef CAM_CALGETDLT_DEBUG do_gettimeofday(&ktv2); if(ktv2.tv_sec > ktv1.tv_sec) { TimeIntervalUS = ktv1.tv_usec + 1000000 - ktv2.tv_usec; } else { TimeIntervalUS = ktv2.tv_usec - ktv1.tv_usec; } CAM_CALDB("Read data %d bytes take %lu us\n",ptempbuf->u4Length, TimeIntervalUS); #endif break; default : CAM_CALINF("[CAM_CAL] No CMD \n"); i4RetValue = -EPERM; break; } if(_IOC_READ & _IOC_DIR(a_u4Command)) { //copy data to user space buffer, keep other input paremeter unchange. if(copy_to_user((u8 __user *) ptempbuf->pu1Params , (u8 *)pu1Params , ptempbuf->u4Length)) { kfree(pBuff); kfree(pu1Params); CAM_CALERR("[CAM_CAL] ioctl copy to user failed\n"); return -EFAULT; } } kfree(pBuff); kfree(pu1Params); return i4RetValue; }
int read_imx219_eeprom_mtk_fmt(void){ int i = 0; int offset = 0; CAM_CALINF("OTP readed =%d \n",imx219_eeprom_read); if(1 == imx219_eeprom_read ) { CAM_CALDB("OTP readed ! skip\n"); return 1; } spin_lock(&g_CAM_CALLock); imx219_eeprom_read = 1; spin_unlock(&g_CAM_CALLock); #if 0 read_imx219_eeprom_size(0xA0,0x00,&imx219_eeprom_data.Data[0x00],1); #endif //read calibration version 0xff000b01 if(read_imx219_eeprom_size(0xA0,0x01,&imx219_eeprom_data.Data[0x01],4) != 0) { CAM_CALERR("read imx219_eeprom GT24C16 i2c fail !?\n"); return -1; } //read serial number read_imx219_eeprom_size(0xA0,0x05,&imx219_eeprom_data.Data[0x05],2); //read AF config read_imx219_eeprom_size(0xA0,0x07,&imx219_eeprom_data.Data[0x07],2); //read AWB read_imx219_eeprom_size(0xA0,0x09,&imx219_eeprom_data.Data[0x09],8); //read AF calibration read_imx219_eeprom_size(0xA0,0x11,&imx219_eeprom_data.Data[0x011],4); //read LSC size read_imx219_eeprom_size(0xA0,0x15,&imx219_eeprom_data.Data[0x015],2); #if 0 int size = 0; size = imx219_eeprom_data.Data[0x015]+imx219_eeprom_data.Data[0x016]<<4; #endif //for lsc data read_imx219_eeprom_size(0xA0,0x17,&imx219_eeprom_data.Data[0x017],(0xFF-0X17+1)); offset = 256; for(i = 0xA2; i<0xA6; i+=2 ){ read_imx219_eeprom_size(i,0x00, &imx219_eeprom_data.Data[offset],256); offset += 256; } read_imx219_eeprom_size(0xA6,0x00,&imx219_eeprom_data.Data[offset],0xBA-0+1); CAM_CALDB("final offset offset %d ! \n",offset+0xBA); #if 0 CAM_CALDB("size %d readed %d! \n",size,offset+0xBA-0x17+1); u8 data[9]; read_imx219_eeprom_size(0xAA,0xE0,&data[0],8); #endif return 0; }