static long MT9P017AF_Ioctl( struct file * a_pstFile, unsigned int a_u4Command, unsigned long a_u4Param) { long i4RetValue = 0; MT9P017AFDB("test\n"); switch(a_u4Command) { case MT9P017AFIOC_G_MOTORINFO : i4RetValue = getMT9P017AFInfo((__user stMT9P017AF_MotorInfo *)(a_u4Param)); break; case MT9P017AFIOC_T_MOVETO : i4RetValue = moveMT9P017AF(a_u4Param); break; case MT9P017AFIOC_T_SETINFPOS : i4RetValue = setMT9P017AFInf(a_u4Param); break; case MT9P017AFIOC_T_SETMACROPOS : i4RetValue = setMT9P017AFMacro(a_u4Param); break; default : MT9P017AFDB("[MT9P017AF] No CMD \n"); i4RetValue = -EPERM; break; } return i4RetValue; }
/* Kirby: add new-style driver {*/ static int MT9P017AF_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Kirby: } */ { int i4RetValue = 0; MT9P017AFDB("[MT9P017AF] Attach I2C \n"); /* Kirby: remove old-style driver //Check I2C driver capability if (!i2c_check_functionality(a_pstAdapter, I2C_FUNC_SMBUS_BYTE_DATA)) { MT9P017AFDB("[MT9P017AF] I2C port cannot support the format \n"); return -EPERM; } if (!(g_pstMT9P017AF_I2Cclient = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) { return -ENOMEM; } g_pstMT9P017AF_I2Cclient->addr = a_i4Address; g_pstMT9P017AF_I2Cclient->adapter = a_pstAdapter; g_pstMT9P017AF_I2Cclient->driver = &MT9P017AF_i2c_driver; g_pstMT9P017AF_I2Cclient->flags = 0; strncpy(g_pstMT9P017AF_I2Cclient->name, MT9P017AF_DRVNAME, I2C_NAME_SIZE); if(i2c_attach_client(g_pstMT9P017AF_I2Cclient)) { kfree(g_pstMT9P017AF_I2Cclient); } */ /* Kirby: add new-style driver { */ g_pstMT9P017AF_I2Cclient = client; /* Kirby: } */ g_pstMT9P017AF_I2Cclient->addr = MT9P017AF_VCM_WRITE_ID >> 1; //Register char driver i4RetValue = Register_MT9P017AF_CharDrv(); if(i4RetValue){ MT9P017AFDB("[MT9P017AF] register char device failed!\n"); /* Kirby: remove old-style driver kfree(g_pstMT9P017AF_I2Cclient); */ return i4RetValue; } spin_lock_init(&g_MT9P017AF_SpinLock); MT9P017AFDB("[MT9P017AF] Attached!! \n"); return 0; }
inline static int Register_MT9P017AF_CharDrv(void) { struct device* vcm_device = NULL; //Allocate char driver no. if( alloc_chrdev_region(&g_MT9P017AF_devno, 0, 1,MT9P017AF_DRVNAME) ) { MT9P017AFDB("[MT9P017AF] Allocate device no failed\n"); return -EAGAIN; } //Allocate driver g_pMT9P017AF_CharDrv = cdev_alloc(); if(NULL == g_pMT9P017AF_CharDrv) { unregister_chrdev_region(g_MT9P017AF_devno, 1); MT9P017AFDB("[MT9P017AF] Allocate mem for kobject failed\n"); return -ENOMEM; } //Attatch file operation. cdev_init(g_pMT9P017AF_CharDrv, &g_stMT9P017AF_fops); g_pMT9P017AF_CharDrv->owner = THIS_MODULE; //Add to system if(cdev_add(g_pMT9P017AF_CharDrv, g_MT9P017AF_devno, 1)) { MT9P017AFDB("[MT9P017AF] Attatch file operation failed\n"); unregister_chrdev_region(g_MT9P017AF_devno, 1); return -EAGAIN; } actuator_class = class_create(THIS_MODULE, "actuatordrv2"); if (IS_ERR(actuator_class)) { int ret = PTR_ERR(actuator_class); MT9P017AFDB("Unable to create class, err = %d\n", ret); return ret; } vcm_device = device_create(actuator_class, NULL, g_MT9P017AF_devno, NULL, MT9P017AF_DRVNAME); if(NULL == vcm_device) { return -EIO; } return 0; }
static int s4MT9P017AF_ReadReg(unsigned short * a_pu2Result) { int i4RetValue = 0; char pBuff[2]; i4RetValue = i2c_master_recv(g_pstMT9P017AF_I2Cclient, pBuff , 2); if (i4RetValue < 0) { MT9P017AFDB("[MT9P017AF] I2C read failed!! \n"); return -1; } *a_pu2Result = pBuff[1]; MT9P017AFDB("[MT9P017AF] I2C read succeed!! \n"); return 0; }
static int __init MT9P017AF_i2C_init(void) { if(platform_driver_register(&g_stMT9P017AF_Driver)){ MT9P017AFDB("failed to register MT9P017AF driver\n"); return -ENODEV; } return 0; }
inline static int getMT9P017AFInfo(__user stMT9P017AF_MotorInfo * pstMotorInfo) { stMT9P017AF_MotorInfo stMotorInfo; stMotorInfo.u4MacroPosition = g_u4MT9P017AF_MACRO; stMotorInfo.u4InfPosition = g_u4MT9P017AF_INF; stMotorInfo.u4CurrentPosition = g_u4CurrPosition; if (g_i4MotorStatus == 1) {stMotorInfo.bIsMotorMoving = TRUE;} else {stMotorInfo.bIsMotorMoving = FALSE;} if (g_s4MT9P017AF_Opened >= 1) {stMotorInfo.bIsMotorOpen = TRUE;} else {stMotorInfo.bIsMotorOpen = FALSE;} if(copy_to_user(pstMotorInfo , &stMotorInfo , sizeof(stMT9P017AF_MotorInfo))) { MT9P017AFDB("[MT9P017AF] copy to user failed when getting motor information \n"); } // MT9P017AFDB("test\n"); return 0; }
static int s4MT9P017AF_ReadReg(unsigned short * a_pu2Result) { // MT9P017AFDB("test\n"); /*int i4RetValue = 0; char pBuff[2]; i4RetValue = i2c_master_recv(g_pstMT9P017AF_I2Cclient, pBuff , 2); if (i4RetValue < 0) { MT9P017AFDB("[MT9P017AF] I2C read failed!! \n"); return -1; }*/ *a_pu2Result = MT9P017_read_cmos_sensor(0x30f2)<<2; // *a_pu2Result = MT9P017_read_cmos_sensor(0x30f2)<<2; // *a_pu2Result = MT9P017MIPI_read_cmos_sensor(0x30f2); MT9P017AFDB("s4MT9P017AF_ReadReg =0x%x \n", *a_pu2Result); return 0; }
//Main jobs: // 1.check for device-specified errors, device not ready. // 2.Initialize the device if it is opened for the first time. // 3.Update f_op pointer. // 4.Fill data structures into private_data //CAM_RESET static int MT9P017AF_Open(struct inode * a_pstInode, struct file * a_pstFile) { spin_lock(&g_MT9P017AF_SpinLock); if(g_s4MT9P017AF_Opened) { spin_unlock(&g_MT9P017AF_SpinLock); MT9P017AFDB("[MT9P017AF] the device is opened \n"); return -EBUSY; } g_s4MT9P017AF_Opened = 1; spin_unlock(&g_MT9P017AF_SpinLock); // --- Config Interrupt --- //g_GPTconfig.num = XGPT7; //g_GPTconfig.mode = XGPT_REPEAT; //g_GPTconfig.clkDiv = XGPT_CLK_DIV_1;//32K //g_GPTconfig.u4Compare = 32*2; // 2ms //g_GPTconfig.bIrqEnable = TRUE; //XGPT_Reset(g_GPTconfig.num); //XGPT_Init(g_GPTconfig.num, MT9P017AF_ISR); //if (XGPT_Config(g_GPTconfig) == FALSE) //{ //MT9P017AFDB("[MT9P017AF] ISR Config Fail\n"); // return -EPERM; //} //XGPT_Start(g_GPTconfig.num); // --- WorkQueue --- //INIT_WORK(&g_stWork,MT9P017AF_WORK); MT9P017_write_cmos_sensor(0x30f0,0x8000); // s4MT9P017AF_WriteReg(0x8000); //fenggy add return 0; }
inline static int setMT9P017AFMacro(unsigned long a_u4Position) { MT9P017AFDB("setMT9P017AFMacro a_u4Position = %d\n",a_u4Position); g_u4MT9P017AF_MACRO = a_u4Position; return 0; }
inline static int setMT9P017AFInf(unsigned long a_u4Position) { MT9P017AFDB("setMT9P017AFInf a_u4Position = %d\n",a_u4Position); g_u4MT9P017AF_INF = a_u4Position; return 0; }
inline static int moveMT9P017AF(unsigned long a_u4Position) { MT9P017AFDB("a_u4Position =%d,g_u4MT9P017AF_MACRO = %d,g_u4MT9P017AF_INF=%d\n", a_u4Position,g_u4MT9P017AF_MACRO,g_u4MT9P017AF_INF); if((a_u4Position > g_u4MT9P017AF_MACRO) || (a_u4Position < g_u4MT9P017AF_INF)) { MT9P017AFDB("[MT9P017AF] out of range \n"); return -EINVAL; } if (g_s4MT9P017AF_Opened == 1) { unsigned short InitPos; if(s4MT9P017AF_ReadReg(&InitPos) == 0) { MT9P017AFDB("[MT9P017AF] Init Pos %6d \n", InitPos); g_u4CurrPosition = (unsigned long)InitPos; } else { g_u4CurrPosition = 0; } g_s4MT9P017AF_Opened = 2; } if (g_u4CurrPosition < a_u4Position) {g_i4Dir = 1;} else if (g_u4CurrPosition > a_u4Position) {g_i4Dir = -1;} else {return 0;} if (1) { g_i4Position = (long)g_u4CurrPosition; g_u4TargetPosition = a_u4Position; if (g_i4Dir == 1) { //if ((g_u4TargetPosition - g_u4CurrPosition)<60) { g_i4MotorStatus = 0; if(s4MT9P017AF_WriteReg((unsigned short)g_u4TargetPosition) == 0) { g_u4CurrPosition = (unsigned long)g_u4TargetPosition; } else { MT9P017AFDB("[MT9P017AF] set I2C failed when moving the motor \n"); g_i4MotorStatus = -1; } } //else //{ // g_i4MotorStatus = 1; //} } else if (g_i4Dir == -1) { //if ((g_u4CurrPosition - g_u4TargetPosition)<60) { g_i4MotorStatus = 0; if(s4MT9P017AF_WriteReg((unsigned short)g_u4TargetPosition) == 0) { g_u4CurrPosition = (unsigned long)g_u4TargetPosition; } else { MT9P017AFDB("[MT9P017AF] set I2C failed when moving the motor \n"); g_i4MotorStatus = -1; } } //else //{ // g_i4MotorStatus = 1; //} } } else { g_i4Position = (long)g_u4CurrPosition; g_u4TargetPosition = a_u4Position; g_i4MotorStatus = 1; } return 0; }