Ejemplo n.º 1
0
static int ami304daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		unsigned long arg)
{
	int valuebuf[4];
	int calidata[7];
	int controlbuf[10];
	char strbuf[AMI304_BUFSIZE];
	void __user *data;
	int retval=0;
	int mode;
	int en_dis_Report;

	//check the authority is root or not
	if (!capable(CAP_SYS_ADMIN)) {
		retval = -EPERM;
		goto err_out;
	}

	switch (cmd) {

		case AMI304MID_IOCTL_GET_SENSORDATA:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_GET_SENSORDATA\n");
#endif
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadSensorData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf) + 1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304MID_IOCTL_SET_POSTURE:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_SET_POSTURE\n");
#endif
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&valuebuf, data, sizeof(valuebuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.yaw   = valuebuf[0];
			ami304mid_data.pitch = valuebuf[1];
			ami304mid_data.roll  = valuebuf[2];
			ami304mid_data.mag_status = valuebuf[3];
			write_unlock(&ami304mid_data.datalock);
			break;

		case AMI304MID_IOCTL_SET_CALIDATA:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_SET_CALIDATA\n");
#endif
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&calidata, data, sizeof(calidata))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.nmx = calidata[0];
			ami304mid_data.nmy = calidata[1];
			ami304mid_data.nmz = calidata[2];
			ami304mid_data.nax = calidata[3];
			ami304mid_data.nay = calidata[4];
			ami304mid_data.naz = calidata[5];
			ami304mid_data.mag_status = calidata[6];
			write_unlock(&ami304mid_data.datalock);
			//			AMI304_Report_Value(en_dis_Report);
			break;

		case AMI304MID_IOCTL_GET_CONTROL:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_GET_CONTROL\n");
#endif
			read_lock(&ami304mid_data.ctrllock);
			memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
			read_unlock(&ami304mid_data.ctrllock);
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, controlbuf, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304MID_IOCTL_SET_CONTROL:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_SET_CONTROL\n");
#endif

			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(controlbuf, data, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.controldata[0], controlbuf, sizeof(controlbuf));
			write_unlock(&ami304mid_data.ctrllock);
			break;

		case AMI304MID_IOCTL_SET_MODE:
#if DEBUG_DAEMON_IOCTL
			printk("Release ami304daemon_ioctl, :AMI304MID_IOCTL_SET_MODE\n");
#endif

			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&mode, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}
			AMI304_SetMode(mode);
			break;

			//Add for input_device sync
		case AMI304MID_IOCTL_SET_REPORT:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&en_dis_Report, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}
			read_lock(&ami304mid_data.datalock);
			AMI304_Report_Value(en_dis_Report);
			read_unlock(&ami304mid_data.datalock);
			break;

		default:
			printk(KERN_ERR "%s not supported = 0x%04x", __FUNCTION__, cmd);
			retval = -ENOIOCTLCMD;
			break;
	}

err_out:
	return retval;
}
Ejemplo n.º 2
0
static int ami304daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	   unsigned long arg)
{
	int valuebuf[4];
	int calidata[7];
	int gyrodata[3];
	long pedodata[3];
	int controlbuf[AMI304_CB_LENGTH];
	char strbuf[AMI304_BUFSIZE];
	int pedoparam[AMI304_PD_LENGTH];	
	char i2creaddata[3];
	void __user *data;
	int retval=0;
	int mode;
#if !defined(CONFIG_HAS_EARLYSUSPEND)
	int iEnReport;
#endif

	switch (cmd) {
		case AMI304DAE_IOCTL_GET_SENSORDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadSensorData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304DAE_IOCTL_SET_POSTURE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&valuebuf, data, sizeof(valuebuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.yaw   = valuebuf[0];
			ami304mid_data.pitch = valuebuf[1];
			ami304mid_data.roll  = valuebuf[2];
			ami304mid_data.status = valuebuf[3];
			write_unlock(&ami304mid_data.datalock);
			break;

		case AMI304DAE_IOCTL_SET_CALIDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&calidata, data, sizeof(calidata))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.nm.x = calidata[0];
			ami304mid_data.nm.y = calidata[1];
			ami304mid_data.nm.z = calidata[2];
			ami304mid_data.na.x = calidata[3];
			ami304mid_data.na.y = calidata[4];
			ami304mid_data.na.z = calidata[5];
			ami304mid_data.status = calidata[6];
			write_unlock(&ami304mid_data.datalock);
#if defined(CONFIG_HAS_EARLYSUSPEND)
			/*
			 * Disable input report at early suspend state
			 * On-Demand Governor set max cpu frequency when input event is appeared
			 */
			AMI304_Report_Value(atomic_read(&ami304_report_enabled));
#endif
			break;


		case AMI304DAE_IOCTL_SET_GYRODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&gyrodata, data, sizeof(gyrodata))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.datalock);			
			ami304mid_data.gyro.x = gyrodata[0];
			ami304mid_data.gyro.y = gyrodata[1];
			ami304mid_data.gyro.z = gyrodata[2];
			write_unlock(&ami304mid_data.datalock);
			break;
        
		case AMI304DAE_IOCTL_SET_PEDODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&pedodata, data, sizeof(pedodata))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.datalock);			
			ami304mid_data.pedo.pedo_step = pedodata[0];
			ami304mid_data.pedo.pedo_time = pedodata[1];
			ami304mid_data.pedo.pedo_stat = (int)pedodata[2];
			write_unlock(&ami304mid_data.datalock);				
			break;								

		case AMI304DAE_IOCTL_GET_PEDOPARAM:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(pedoparam, &ami304mid_data.pedometerparam[0],
					sizeof(pedoparam));
			read_unlock(&ami304mid_data.ctrllock);			
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_to_user(data, pedoparam, sizeof(pedoparam))) {
				retval = -EFAULT;
				goto err_out;
			}					
			break;

		case AMI304DAE_IOCTL_SET_PEDOPARAM:
			data = (void __user *) arg;			
			if (data == NULL)
				break;	
			if (copy_from_user(pedoparam, data, sizeof(pedoparam))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.pedometerparam[0], pedoparam, sizeof(pedoparam));
			write_unlock(&ami304mid_data.ctrllock);					
			break;	

		case AMI304DAE_IOCTL_GET_CONTROL:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
			read_unlock(&ami304mid_data.ctrllock);
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, controlbuf, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304DAE_IOCTL_SET_CONTROL:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(controlbuf, data, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.controldata[0], controlbuf, sizeof(controlbuf));
			write_unlock(&ami304mid_data.ctrllock);
			break;

		case AMI304DAE_IOCTL_SET_MODE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&mode, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}
			AMI304_SetMode(mode);
			break;
								
		//Add for input_device sync			
		case AMI304DAE_IOCTL_SET_REPORT:
#if defined(CONFIG_HAS_EARLYSUSPEND)
			break;
#else
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&iEnReport, data, sizeof(iEnReport))) {
				retval = -EFAULT;
				goto err_out;
			}				
			AMI304_Report_Value(iEnReport);
#endif
			break;
		
		case AMI304DAE_IOCTL_GET_WIA:
			data = (void __user *) arg;
			if (data == NULL)
				break;		
			AMI304_WIA(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304DAE_IOCTL_SET_I2CDATA:
			data = (void __user *)arg;
			if (data == NULL)
				break;
			if (copy_from_user(strbuf, data, sizeof(strbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			AMI304_I2c_Write(strbuf[0], &strbuf[2], strbuf[1]);
			break;

		case AMI304DAE_IOCTL_SET_I2CADDR:
			data = (void __user *)arg;
			if (data == NULL)
				break;
			if (copy_from_user(i2creaddata, data, 2)) {
				retval = -EFAULT;
				goto err_out;
			}
			i2c_read_addr = i2creaddata[0];
			i2c_read_len = i2creaddata[1];
			break;

		case AMI304DAE_IOCTL_GET_I2CDATA:
			AMI304_I2c_Read(i2c_read_addr, &strbuf[0], i2c_read_len);
			data = (void __user *)arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, strbuf, i2c_read_len)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		default:
			if (AMI304_DEBUG_USER_ERROR & ami304_debug_mask)
				AMIE("not supported command= 0x%04x\n", cmd);
			retval = -ENOIOCTLCMD;
			break;
	}

err_out:
	return retval;
}
Ejemplo n.º 3
0
static int ami304daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	   unsigned long arg)
{
	int valuebuf[4];
	int calidata[7];
	int controlbuf[10];
	char strbuf[AMI304_BUFSIZE];
	void __user *data;
	int retval=0;
	int mode;
#if !defined(CONFIG_HAS_EARLYSUSPEND)
	int en_dis_Report=1;
#endif

        //LGE_CHANGE_S, [[email protected]], 2010-12-31, <Block Root Authorization Check>
        //check the authority is root or not
        //    if(!capable(CAP_SYS_ADMIN)) {
        //        retval = -EPERM;
        //        goto err_out;
        //    }
        //LGE_CHANGE_E, [[email protected]], 2010-12-31, <Block Root Authorization Check>

	switch (cmd) {

		case AMI304MID_IOCTL_GET_SENSORDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadSensorData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304MID_IOCTL_SET_POSTURE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&valuebuf, data, sizeof(valuebuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.yaw   = valuebuf[0];
			ami304mid_data.pitch = valuebuf[1];
			ami304mid_data.roll  = valuebuf[2];
			ami304mid_data.mag_status = valuebuf[3];
			write_unlock(&ami304mid_data.datalock);
			break;

		case AMI304MID_IOCTL_SET_CALIDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&calidata, data, sizeof(calidata))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.nmx = calidata[0];
			ami304mid_data.nmy = calidata[1];
			ami304mid_data.nmz = calidata[2];
			ami304mid_data.nax = calidata[3];
			ami304mid_data.nay = calidata[4];
			ami304mid_data.naz = calidata[5];
			ami304mid_data.mag_status = calidata[6];
			write_unlock(&ami304mid_data.datalock);
#if defined(CONFIG_HAS_EARLYSUSPEND)
			/*
				Disable input report at early suspend state
				On-Demand Governor set max cpu frequency when input evnet is appeared
			*/
			AMI304_Report_Value(	atomic_read(&ami304_report_enabled));
#else
			AMI304_Report_Value(en_dis_Report);
#endif
			break;

		case AMI304MID_IOCTL_GET_CONTROL:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
			read_unlock(&ami304mid_data.ctrllock);
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, controlbuf, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304MID_IOCTL_SET_CONTROL:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(controlbuf, data, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.controldata[0], controlbuf, sizeof(controlbuf));
			write_unlock(&ami304mid_data.ctrllock);
			break;

		case AMI304MID_IOCTL_SET_MODE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&mode, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}
			AMI304_SetMode(mode);
			break;

		default:
			if (AMI304_DEBUG_USER_ERROR & ami304_debug_mask)
				AMIE("not supported command= 0x%04x\n", cmd);
			retval = -ENOIOCTLCMD;
			break;
	}

err_out:
	return retval;
}
Ejemplo n.º 4
0
static int ami304_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
{
	char strbuf[AMI304_BUFSIZE];
	int controlbuf[AMI304_CB_LENGTH];
	int valuebuf[4];
	int calidata[7];
	int gyrodata[3];
	long pedodata[3];	
	int pedoparam[AMI304_PD_LENGTH];
	void __user *data;
	int retval=0;
	int mode=0,chipset=0;
	int iEnReport;
	
	switch (cmd) {
		case AMI304_IOCTL_INIT:
			read_lock(&ami304_data.lock);
			mode = ami304_data.mode;
			chipset = ami304_data.chipset;
			read_unlock(&ami304_data.lock);
			AMI304_Chipset_Init(mode, chipset);			
			break;

		case AMI304_IOCTL_READ_CHIPINFO:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadChipInfo(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304_IOCTL_READ_SENSORDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadSensorData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304_IOCTL_READ_POSTUREDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadPostureData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;
	 
	 	case AMI304_IOCTL_WRITE_POSTUREDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&valuebuf, data, sizeof(valuebuf))) {
				retval = -EFAULT;
				goto err_out;
			}				
			write_lock(&ami304mid_data.datalock);
			ami304mid_data.yaw   = valuebuf[0];
			ami304mid_data.pitch = valuebuf[1];
			ami304mid_data.roll  = valuebuf[2];
			ami304mid_data.status = valuebuf[3];
			write_unlock(&ami304mid_data.datalock);		 	
	 		break;
	 	 
	        case AMI304_IOCTL_READ_CALIDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadCaliData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
	        	break;
	        
		case AMI304_IOCTL_WRITE_CALIDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&calidata, data, sizeof(calidata))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.datalock);			
			ami304mid_data.nm.x = calidata[0];
			ami304mid_data.nm.y = calidata[1];
			ami304mid_data.nm.z = calidata[2];
			ami304mid_data.na.x = calidata[3];
			ami304mid_data.na.y = calidata[4];
			ami304mid_data.na.z = calidata[5];
			ami304mid_data.status = calidata[6];
			write_unlock(&ami304mid_data.datalock);
			break;    

		case AMI304_IOCTL_READ_GYRODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			AMI304_ReadGyroData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}				
			break;
			
		case AMI304_IOCTL_WRITE_GYRODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&gyrodata, data, sizeof(gyrodata))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.datalock);			
			ami304mid_data.gyro.x = gyrodata[0];
			ami304mid_data.gyro.y = gyrodata[1];
			ami304mid_data.gyro.z = gyrodata[2];
			write_unlock(&ami304mid_data.datalock);		
			break;
			
		case AMI304_IOCTL_READ_PEDODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			AMI304_ReadPedoData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}				
			break;

		case AMI304_IOCTL_WRITE_PEDODATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&pedodata, data, sizeof(pedodata))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.datalock);			
			ami304mid_data.pedo.pedo_step = pedodata[0];
			ami304mid_data.pedo.pedo_time = pedodata[1];
			ami304mid_data.pedo.pedo_stat = (int)pedodata[2];
			write_unlock(&ami304mid_data.datalock);  		
			break;

		case AMI304_IOCTL_READ_PEDOPARAM:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(pedoparam, &ami304mid_data.pedometerparam[0], sizeof(pedoparam));
			read_unlock(&ami304mid_data.ctrllock);			
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_to_user(data, pedoparam, sizeof(pedoparam))) {
				retval = -EFAULT;
				goto err_out;
			}			
			break;
			
		case AMI304_IOCTL_WRITE_PEDOPARAM:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(pedoparam, data, sizeof(pedoparam))) {
				retval = -EFAULT;
				goto err_out;
			}	
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.pedometerparam[0], pedoparam, sizeof(pedoparam));
			write_unlock(&ami304mid_data.ctrllock);
			break;	
	        
	        case AMI304_IOCTL_READ_CONTROL:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
			read_unlock(&ami304mid_data.ctrllock);
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, controlbuf, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
	        	break;

		case AMI304_IOCTL_WRITE_CONTROL:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(controlbuf, data, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.controldata[0], controlbuf, sizeof(controlbuf));
			write_unlock(&ami304mid_data.ctrllock);
			break;

		case AMI304_IOCTL_WRITE_MODE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(&mode, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}
			AMI304_SetMode(mode);
			break;
					        				
		case AMI304_IOCTL_WRITE_REPORT:
			data = (void __user *) arg;
			if (data == NULL)
				break;	
			if (copy_from_user(&iEnReport, data, sizeof(iEnReport))) {
				retval = -EFAULT;
				goto err_out;
			}				
			AMI304_Report_Value(iEnReport);		
			break;
		
		case AMI304_IOCTL_READ_WIA:
			data = (void __user *) arg;
			if (data == NULL)
				break;		
			AMI304_WIA(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}								
			break;
					        				
		default:
			if (AMI304_DEBUG_USER_ERROR & ami304_debug_mask)
				AMIE("not supported command= 0x%04x\n", cmd);
			retval = -ENOIOCTLCMD;
			break;
	}

err_out:
	return retval;
}