Ejemplo n.º 1
0
/* ioctl - I/O control */
static long compass_dev_ioctl(struct file *file,
			  unsigned int cmd, unsigned long arg)
{
    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
	struct i2c_client *client = this_client;
	void __user *argp = (void __user *)arg;
	int result = 0;
	struct akm8975_platform_data compass;
		
	/* NOTE: In this function the size of "char" should be 1-byte. */
	char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */
	char rwbuf[RWBUF_SIZE];		/* for READ/WRITE */
	char mode;					/* for SET_MODE*/
	short value[12];			/* for SET_YPR */
	short delay;				/* for GET_DELAY */
	int status;					/* for OPEN/CLOSE_STATUS */
	int ret = -1;				/* Return value. */
	
	switch (cmd) {
		case ECS_IOCTL_WRITE:
		case ECS_IOCTL_READ:
			if (argp == NULL) {
				return -EINVAL;
			}
			if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
				return -EFAULT;
			}
			break;
		case ECS_IOCTL_SET_MODE:
			if (argp == NULL) {
				return -EINVAL;
			}
			if (copy_from_user(&mode, argp, sizeof(mode))) {
				return -EFAULT;
			}
			break;
		case ECS_IOCTL_SET_YPR:
			if (argp == NULL) {
				return -EINVAL;
			}
			if (copy_from_user(&value, argp, sizeof(value))) {
				return -EFAULT;
			}
			break;
		default:
			break;
	}
	
	switch (cmd) {
		case ECS_IOCTL_WRITE:
			DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
			mutex_lock(&sensor->operation_mutex);
			if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {			
				mutex_unlock(&sensor->operation_mutex);
				return -EINVAL;
			}
			ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
			if (ret < 0) {	
				mutex_unlock(&sensor->operation_mutex);		
				printk("%s:fait to tx data\n",__func__);
				return ret;
			}			
			mutex_unlock(&sensor->operation_mutex);
			break;
		case ECS_IOCTL_READ:				
			DBG("%s:ECS_IOCTL_READ start\n",__func__);
			mutex_lock(&sensor->operation_mutex);
			if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {		
				mutex_unlock(&sensor->operation_mutex);			
				printk("%s:data is error\n",__func__);
				return -EINVAL;
			}
			ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
			if (ret < 0) {	
				mutex_unlock(&sensor->operation_mutex);		
				printk("%s:fait to rx data\n",__func__);
				return ret;
			}		
			mutex_unlock(&sensor->operation_mutex);
			break;
		case ECS_IOCTL_SET_MODE:		
			DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);		
			mutex_lock(&sensor->operation_mutex);
			if(sensor->ops->ctrl_data != mode)
			{
				ret = compass_akm_set_mode(client, mode);
				if (ret < 0) {
					printk("%s:fait to set mode\n",__func__);		
					mutex_unlock(&sensor->operation_mutex);
					return ret;
				}
				
				sensor->ops->ctrl_data = mode;
			}
			mutex_unlock(&sensor->operation_mutex);
			break;
		case ECS_IOCTL_GETDATA:		
			DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
			mutex_lock(&sensor->data_mutex);	
			memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);	//get data from buffer
			mutex_unlock(&sensor->data_mutex);
			break;
		case ECS_IOCTL_SET_YPR:			
			DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
			mutex_lock(&sensor->data_mutex);
			compass_set_YPR(value);		
			mutex_unlock(&sensor->data_mutex);
			break;
		case ECS_IOCTL_GET_OPEN_STATUS:
			status = compass_akm_get_openstatus();	
			DBG("%s:openstatus=%d\n",__func__,status);
			break;
		case ECS_IOCTL_GET_CLOSE_STATUS:
			status = compass_akm_get_closestatus();	
			DBG("%s:closestatus=%d\n",__func__,status);
			break;
		case ECS_IOCTL_GET_DELAY:
			delay = akmd_delay;
			break;
		case ECS_IOCTL_GET_PLATFORM_DATA:			
			DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
			memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
			memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
			ret = copy_to_user(argp, &compass, sizeof(compass));
			if(ret < 0)
			{
				printk("%s:error,ret=%d\n",__FUNCTION__, ret);
				return ret;
			}
			break;
			
		default:
			return -ENOTTY;
	}
	
	switch (cmd) {
		case ECS_IOCTL_READ:
			if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
				return -EFAULT;
			}
			break;
		case ECS_IOCTL_GETDATA:
			if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
				return -EFAULT;
			}
			break;
		case ECS_IOCTL_GET_OPEN_STATUS:
		case ECS_IOCTL_GET_CLOSE_STATUS:
			if (copy_to_user(argp, &status, sizeof(status))) {
				return -EFAULT;
			}
			break;
		case ECS_IOCTL_GET_DELAY:
			if (copy_to_user(argp, &delay, sizeof(delay))) {
				return -EFAULT;
			}
			break;
		default:
			break;
	}

	return result;
}
Ejemplo n.º 2
0
/* ioctl - I/O control */
static long compass_dev_ioctl(struct file *file,
			  unsigned int cmd, unsigned long arg)
{
    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
	struct i2c_client *client = this_client;
	void __user *argp = (void __user *)arg;
	int result = 0;
	struct akm_platform_data compass;
		
	/* NOTE: In this function the size of "char" should be 1-byte. */
	char compass_data[SENSOR_DATA_SIZE];	/* for GETDATA */
	char rwbuf[RWBUF_SIZE]; 		/* for READ/WRITE */
	char mode;				/* for SET_MODE*/
	int value[12];			/* for SET_YPR */
	int status;				/* for OPEN/CLOSE_STATUS */
	int ret = -1;				/* Return value. */
	
	//int8_t sensor_buf[SENSOR_DATA_SIZE];	/* for GETDATA */
	//int32_t ypr_buf[YPR_DATA_SIZE]; 	/* for SET_YPR */
	int16_t acc_buf[3];			/* for GET_ACCEL */
	int64_t delay[AKM_NUM_SENSORS]; 	/* for GET_DELAY */

	char layout;		/* for GET_LAYOUT */
	char outbit;		/* for GET_OUTBIT */

	switch (cmd) {
	case ECS_IOCTL_WRITE:
	case ECS_IOCTL_READ:
		if (argp == NULL) {
			return -EINVAL;
		}
		if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_SET_MODE:
		if (argp == NULL) {
			return -EINVAL;
		}
		if (copy_from_user(&mode, argp, sizeof(mode))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_SET_YPR:
		if (argp == NULL) {
			return -EINVAL;
		}
		if (copy_from_user(&value, argp, sizeof(value))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GETDATA:
	case ECS_IOCTL_GET_OPEN_STATUS:
	case ECS_IOCTL_GET_CLOSE_STATUS:
	case ECS_IOCTL_GET_DELAY:
	case ECS_IOCTL_GET_LAYOUT:
	case ECS_IOCTL_GET_OUTBIT:
	case ECS_IOCTL_GET_ACCEL:
		/* Just check buffer pointer */
		if (argp == NULL) {
			printk("%s:invalid argument\n",__func__);
			return -EINVAL;
		}
		break;
	default:
		break;
	}

	switch (cmd) {
	case ECS_IOCTL_WRITE:
		DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
		mutex_lock(&sensor->operation_mutex);
		if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {			
			mutex_unlock(&sensor->operation_mutex);
			return -EINVAL;
		}
		ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
		if (ret < 0) {	
			mutex_unlock(&sensor->operation_mutex); 	
			printk("%s:fait to tx data\n",__func__);
			return ret;
		}			
		mutex_unlock(&sensor->operation_mutex);
		break;
	case ECS_IOCTL_READ:				
		DBG("%s:ECS_IOCTL_READ start\n",__func__);
		mutex_lock(&sensor->operation_mutex);
		if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {		
			mutex_unlock(&sensor->operation_mutex); 		
			printk("%s:data is error\n",__func__);
			return -EINVAL;
		}
		ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
		if (ret < 0) {	
			mutex_unlock(&sensor->operation_mutex); 	
			printk("%s:fait to rx data\n",__func__);
			return ret;
		}		
		mutex_unlock(&sensor->operation_mutex);
		break;
	case ECS_IOCTL_SET_MODE:
		DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);		
		mutex_lock(&sensor->operation_mutex);
		if(sensor->ops->ctrl_data != mode)
		{
			ret = compass_akm_set_mode(client, mode);
			if (ret < 0) {
				printk("%s:fait to set mode\n",__func__);		
				mutex_unlock(&sensor->operation_mutex);
				return ret;
			}
			
			sensor->ops->ctrl_data = mode;
		}
		mutex_unlock(&sensor->operation_mutex);
		break;
	case ECS_IOCTL_GETDATA:
			DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
			mutex_lock(&sensor->data_mutex);	
			memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);	//get data from buffer
			mutex_unlock(&sensor->data_mutex);
			break;
	case ECS_IOCTL_SET_YPR: 		
			DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
			mutex_lock(&sensor->data_mutex);
			compass_set_YPR(value); 	
			mutex_unlock(&sensor->data_mutex);
		break;
	case ECS_IOCTL_GET_OPEN_STATUS:
		status = compass_akm_get_openstatus();	
		DBG("%s:openstatus=%d\n",__func__,status);
		break;
	case ECS_IOCTL_GET_CLOSE_STATUS:
		status = compass_akm_get_closestatus(); 
		DBG("%s:closestatus=%d\n",__func__,status);
		break;
	case ECS_IOCTL_GET_DELAY:
		DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);
		mutex_lock(&sensor->operation_mutex);
		delay[0] = sensor->flags.delay;
		delay[1] = sensor->flags.delay;
		delay[2] = sensor->flags.delay;
		mutex_unlock(&sensor->operation_mutex);
		break;
	
	case ECS_IOCTL_GET_PLATFORM_DATA:			
		DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
		memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
		memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
		ret = copy_to_user(argp, &compass, sizeof(compass));
		if(ret < 0)
		{
			printk("%s:error,ret=%d\n",__FUNCTION__, ret);
			return ret;
		}
		break;
	case ECS_IOCTL_GET_LAYOUT:
		DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);
		layout = 1;	//sensor->pdata->layout;
		break;
	case ECS_IOCTL_GET_OUTBIT:
		DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
		outbit = 1;	//sensor->pdata->outbit;
		break;
	case ECS_IOCTL_RESET:
		DBG("%s:ECS_IOCTL_RESET start\n",__func__);
		ret = compass_akm_reset(client);
		if (ret < 0)
			return ret;
		break;
	case ECS_IOCTL_GET_ACCEL:
		DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);
		mutex_lock(&sensor->operation_mutex);
		acc_buf[0] = g_akm_rbuf[6];
		acc_buf[1] = g_akm_rbuf[7];
		acc_buf[2] = g_akm_rbuf[8];
		mutex_unlock(&sensor->operation_mutex);
		break;

	default:
		return -ENOTTY;
	}

	switch (cmd) {
	case ECS_IOCTL_READ:
		if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GETDATA:
		if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GET_OPEN_STATUS:
	case ECS_IOCTL_GET_CLOSE_STATUS:
		if (copy_to_user(argp, &status, sizeof(status))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GET_DELAY:
		if (copy_to_user(argp, &delay, sizeof(delay))) {
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GET_LAYOUT:
		if (copy_to_user(argp, &layout, sizeof(layout))) {
			printk("%s:error:%d\n",__FUNCTION__,__LINE__);
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GET_OUTBIT:
		if (copy_to_user(argp, &outbit, sizeof(outbit))) {
			printk("%s:error:%d\n",__FUNCTION__,__LINE__);
			return -EFAULT;
		}
		break;
	case ECS_IOCTL_GET_ACCEL:
		if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
			printk("%s:error:%d\n",__FUNCTION__,__LINE__);
			return -EFAULT;
		}
		break;
	default:
		break;
	}

	return result;
}