static int sensor_get_id(struct i2c_client *client, int *value) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); int result = 0; char temp = sensor->ops->id_reg; int i = 0; if(sensor->ops->id_reg >= 0) { for(i=0; i<3; i++) { result = sensor_rx_data(client, &temp, 1); *value = temp; if(!result) break; } if(result) return result; if(*value != sensor->ops->id_data) { printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data); result = -1; } DBG("%s:devid=0x%x\n",__func__,*value); } return result; }
static int sensor_report_value(struct i2c_client *client) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); int result = 0; //char msb = 0, lsb = 0; char data[2] = {0}; unsigned short value = 0; int index = 0; //sensor->client->addr = CM3232_ADDR_DATA; data[0] = CM3232_ADDR_DATA; sensor_rx_data(sensor->client, data, 2); value = (data[1] << 8) | data[0] ; DBG("%s:result=%d\n",__func__,value); //printk("%s:result=%d\n",__func__,value); index = light_report_value(sensor->input_dev, value); DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index); if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register { result= sensor_read_reg(client, sensor->ops->int_status_reg); if(result) { printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result); } } return result; }
static int sensor_report_value(struct i2c_client *client) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); struct sensor_platform_data *pdata = sensor->pdata; int ret = 0; int x = 0, y = 0, z = 0; struct sensor_axis axis; char buffer[6] = {0}; int i = 0; int value = 0; memset(buffer, 0, 6); #if 0 /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ do { buffer[0] = sensor->ops->read_reg; ret = sensor_rx_data(client, buffer, sensor->ops->read_len); if (ret < 0) return ret; } while (0); #else for(i=0; i<6; i++) { i2c_read_byte(client, sensor->ops->read_reg + i,&buffer[i]); } #endif x = (short) (((buffer[0]) << 8) | buffer[1]); y = (short) (((buffer[2]) << 8) | buffer[3]); z = (short) (((buffer[4]) << 8) | buffer[5]); //printk("%s: x=%d y=%d z=%d \n",__func__, x,y,z); if(pdata && pdata->orientation) { axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z; axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z; axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z; } else { axis.x = x; axis.y = y; axis.z = z; } //filter gyro data if((abs(axis.x) > pdata->x_min)||(abs(axis.y) > pdata->y_min)||(abs(axis.z) > pdata->z_min)) { gyro_report_value(client, &axis); /* »¥³âµØ»º´æÊý¾Ý. */ mutex_lock(&(sensor->data_mutex) ); sensor->axis = axis; mutex_unlock(&(sensor->data_mutex) ); } return ret; }
static int sensor_report_value(struct i2c_client *client) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); int result = 0; int value = 0; char buffer[2] = {0}; char index = 0; if(sensor->ops->read_len < 2) //sensor->ops->read_len = 2 { printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len); return -1; } memset(buffer, 0, 2); buffer[0] = sensor->ops->read_reg; result = sensor_rx_data(client, buffer, sensor->ops->read_len); if(result) { printk("%s:line=%d,error\n",__func__,__LINE__); return result; } value = (buffer[0] << 8) | buffer[1]; index = light_report_value(sensor->input_dev, value); DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index); if(sensor->pdata->irq_enable) { if(sensor->ops->int_status_reg) { value = sensor_read_reg(client, sensor->ops->int_status_reg); } if(value & STA_ALS_INT) { value &= ~STA_ALS_INT; result = sensor_write_reg(client, sensor->ops->int_status_reg,value); //clear int if(result) { printk("%s:line=%d,error\n",__func__,__LINE__); return result; } } } return result; }
int sensor_read_reg(struct i2c_client *client, int addr) { char tmp[1] = {0}; int ret = 0; struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client); mutex_lock(&sensor->i2c_mutex); tmp[0] = addr; ret = sensor_rx_data(client, tmp, 1); mutex_unlock(&sensor->i2c_mutex); return tmp[0]; }
int sensor_get_data(struct i2c_client *client) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); char data[2] = {0}; unsigned short value = 0; sensor->ops->active(client, 1, 0); mutex_lock(&sensor->sensor_mutex); data[0] = 50;//CM3232_ADDR_DATA; sensor_rx_data(sensor->client, data, 2); value = (data[1] << 8) | data[0] ; mutex_unlock(&sensor->sensor_mutex); return value; }
/* 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; }
static int sensor_report_value(struct i2c_client *client) { struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client); char buffer[8] = {0}; unsigned char *stat; unsigned char *stat2; int ret = 0; char value = 0; #ifdef SENSOR_DEBUG_TYPE int i; #endif if(sensor->ops->read_len < 8) //sensor->ops->read_len = 8 { printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len); return -1; } memset(buffer, 0, 8); /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ do { *buffer = sensor->ops->read_reg; ret = sensor_rx_data(client, buffer, sensor->ops->read_len); if (ret < 0) return ret; } while (0); stat = &buffer[0]; stat2 = &buffer[7]; /* * ST : data ready - * Measurement has been completed and data is ready to be read. */ if ((*stat & 0x01) != 0x01) { DBG(KERN_ERR "%s:ST is not set\n",__func__); return -1; } /* * ST2 : data error - * occurs when data read is started outside of a readable period; * data read would not be correct. * Valid in continuous measurement mode only. * In single measurement mode this error should not occour but we * stil account for it and return an error, since the data would be * corrupted. * DERR bit is self-clearing when ST2 register is read. */ if (*stat2 & 0x04) { DBG(KERN_ERR "%s:compass data error\n",__func__); return -2; } /* * ST2 : overflow - * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT. * This is likely to happen in presence of an external magnetic * disturbance; it indicates, the sensor data is incorrect and should * be ignored. * An error is returned. * HOFL bit clears when a new measurement starts. */ if (*stat2 & 0x08) { DBG(KERN_ERR "%s:compass data overflow\n",__func__); return -3; } /* »¥³âµØ»º´æÊý¾Ý. */ mutex_lock(&sensor->data_mutex); memcpy(sensor->sensor_data, buffer, sensor->ops->read_len); mutex_unlock(&sensor->data_mutex); #ifdef SENSOR_DEBUG_TYPE DBG("%s:",__func__); for(i=0; i<sensor->ops->read_len; i++) DBG("%d,",buffer[i]); DBG("\n"); #endif if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)) //read sensor intterupt status register { value = sensor_read_reg(client, sensor->ops->int_status_reg); DBG("%s:sensor int status :0x%x\n",__func__,value); } //trigger next measurement ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data); if(ret) { printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data); return ret; } return ret; }
/* 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; }