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;
}
Esempio n. 4
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;
}