/* * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #include "ssp.h" #include #include #include #include #include #include /*************************************************************************/ /* SSP Kernel -> HAL input evnet function */ /*************************************************************************/ #define IIO_BUFFER_12_BYTES 20 /* 12 + timestamp 8*/ #define IIO_BUFFER_6_BYTES 14 #define IIO_BUFFER_1_BYTES 9 #define IIO_BUFFER_17_BYTES 25 #define IIO_BUFFER_24_BYTES 20 #define IIO_BUFFER_7_BYTES 15 #define IIO_ST(si, rb, sb, sh) \ { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } static int ssp_push_iio_buffer(struct iio_dev *indio_dev, u64 timestamp, u8 *data, int data_len) { u8 buf[data_len+sizeof(timestamp)]; memcpy(buf, data, data_len); memcpy(&buf[data_len], ×tamp, sizeof(timestamp)); mutex_lock(&indio_dev->mlock); iio_push_to_buffers(indio_dev, buf); mutex_unlock(&indio_dev->mlock); return 0; } void report_meta_data(struct ssp_data *data, struct sensor_value *s) { pr_info("[SSP]: %s - what: %d, sensor: %d\n", __func__, s->meta_data.what, s->meta_data.sensor); if (s->meta_data.sensor == ACCELEROMETER_SENSOR) { s16 accel_buf[3]; memset(accel_buf, 0, sizeof(s16) * 3); ssp_push_iio_buffer(data->accel_indio_dev, 0, (u8 *)accel_buf, sizeof(accel_buf)); } else if (s->meta_data.sensor == GYROSCOPE_SENSOR) { int gyro_buf[3]; memset(gyro_buf, 0, sizeof(int) * 3); ssp_push_iio_buffer(data->gyro_indio_dev, 0, (u8 *)gyro_buf, sizeof(gyro_buf)); } else if (s->meta_data.sensor == GYRO_UNCALIB_SENSOR) { s32 uncal_gyro_buf[6]; memset(uncal_gyro_buf, 0, sizeof(s32) * 6); ssp_push_iio_buffer(data->uncal_gyro_indio_dev, 0, (u8 *)uncal_gyro_buf, sizeof(uncal_gyro_buf)); } else if (s->meta_data.sensor == GEOMAGNETIC_SENSOR) { u8 mag_buf[7]; memset(mag_buf, 0, 7); ssp_push_iio_buffer(data->mag_indio_dev, 0, (u8 *)mag_buf, sizeof(mag_buf)); } else if (s->meta_data.sensor == GEOMAGNETIC_UNCALIB_SENSOR) { s16 uncal_mag_buf[6]; memset(uncal_mag_buf, 0, sizeof(s16) * 6); ssp_push_iio_buffer(data->uncal_mag_indio_dev, 0, (u8 *)uncal_mag_buf, sizeof(uncal_mag_buf)); } else if (s->meta_data.sensor == PRESSURE_SENSOR) { int pressure_buf[3]; memset(pressure_buf, 0, sizeof(int) * 3); ssp_push_iio_buffer(data->pressure_indio_dev, 0, (u8 *)pressure_buf, sizeof(pressure_buf)); } else if (s->meta_data.sensor == ROTATION_VECTOR) { int rot_buf[5]; memset(rot_buf, 0, sizeof(int) * 5); ssp_push_iio_buffer(data->rot_indio_dev, 0, (u8 *)rot_buf, sizeof(rot_buf)); } else if (s->meta_data.sensor == GAME_ROTATION_VECTOR) { int grot_buf[5]; memset(grot_buf, 0, sizeof(int) * 5); ssp_push_iio_buffer(data->game_rot_indio_dev, 0, (u8 *)grot_buf, sizeof(grot_buf)); } else if (s->meta_data.sensor == STEP_DETECTOR) { u8 step_buf[1] = {0}; ssp_push_iio_buffer(data->step_det_indio_dev, 0, (u8 *)step_buf, sizeof(step_buf)); } else { input_report_rel(data->meta_input_dev, REL_DIAL, s->meta_data.what); input_report_rel(data->meta_input_dev, REL_HWHEEL, s->meta_data.sensor + 1); input_sync(data->meta_input_dev); } } void report_acc_data(struct ssp_data *data, struct sensor_value *accdata) { s16 accel_buf[3]; /* *#if defined (CONFIG_SENSORS_SSP_VLTE) * if(data->change_axis == true && folder_state == true) * { * //pr_info("[SSP] %s folder_state %d, changed axis changed %d\n", * __func__, folder_state, data->change_axis); * data->buf[ACCELEROMETER_SENSOR].x = (accdata->x) * (-1); * data->buf[ACCELEROMETER_SENSOR].y = (accdata->y); * data->buf[ACCELEROMETER_SENSOR].z = (accdata->z) * (-1); * } * else * { * data->change_axis = false; * //pr_info("[SSP] %s unfolder_state %d, changed axis changed %d\n", * __func__, folder_state, data->change_axis); * data->buf[ACCELEROMETER_SENSOR].x = accdata->x; * data->buf[ACCELEROMETER_SENSOR].y = accdata->y; * data->buf[ACCELEROMETER_SENSOR].z = accdata->z; * } *#else */ data->buf[ACCELEROMETER_SENSOR].x = accdata->x; data->buf[ACCELEROMETER_SENSOR].y = accdata->y; data->buf[ACCELEROMETER_SENSOR].z = accdata->z; //#endif accel_buf[0] = data->buf[ACCELEROMETER_SENSOR].x; accel_buf[1] = data->buf[ACCELEROMETER_SENSOR].y; accel_buf[2] = data->buf[ACCELEROMETER_SENSOR].z; ssp_push_iio_buffer(data->accel_indio_dev, accdata->timestamp, (u8 *)accel_buf, sizeof(accel_buf)); } void report_gyro_data(struct ssp_data *data, struct sensor_value *gyrodata) { int lTemp[3] = {0,}; /* *#if defined (CONFIG_SENSORS_SSP_VLTE) * if(data->change_axis == true && folder_state == true) * { * //pr_info("[SSP] %s folder_state %d, changed axis %d\n", * __func__, folder_state, data->change_axis); * data->buf[GYROSCOPE_SENSOR].x = (gyrodata->x) * (-1); * data->buf[GYROSCOPE_SENSOR].y = (gyrodata->y); * data->buf[GYROSCOPE_SENSOR].z = (gyrodata->z) * (-1); * } * else * { * data->change_axis = false; * //pr_info("[SSP] %s unfolder_state %d, changed axis %d\n", * __func__, folder_state, data->change_axis); * data->buf[GYROSCOPE_SENSOR].x = gyrodata->x; * data->buf[GYROSCOPE_SENSOR].y = gyrodata->y; * data->buf[GYROSCOPE_SENSOR].z = gyrodata->z; * } *#else */ data->buf[GYROSCOPE_SENSOR].gyro.x = gyrodata->gyro.x; data->buf[GYROSCOPE_SENSOR].gyro.y = gyrodata->gyro.y; data->buf[GYROSCOPE_SENSOR].gyro.z = gyrodata->gyro.z; //#endif if (data->uGyroDps == GYROSCOPE_DPS500) { lTemp[0] = (int)data->buf[GYROSCOPE_SENSOR].gyro.x >> 2; lTemp[1] = (int)data->buf[GYROSCOPE_SENSOR].gyro.y >> 2; lTemp[2] = (int)data->buf[GYROSCOPE_SENSOR].gyro.z >> 2; } else if (data->uGyroDps == GYROSCOPE_DPS250) { lTemp[0] = (int)data->buf[GYROSCOPE_SENSOR].gyro.x >> 3; lTemp[1] = (int)data->buf[GYROSCOPE_SENSOR].gyro.y >> 3; lTemp[2] = (int)data->buf[GYROSCOPE_SENSOR].gyro.z >> 3; } else { lTemp[0] = (int)data->buf[GYROSCOPE_SENSOR].gyro.x; lTemp[1] = (int)data->buf[GYROSCOPE_SENSOR].gyro.y; lTemp[2] = (int)data->buf[GYROSCOPE_SENSOR].gyro.z; } ssp_push_iio_buffer(data->gyro_indio_dev, gyrodata->timestamp, (u8 *)lTemp, sizeof(lTemp)); } #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR void report_interrupt_gyro_data(struct ssp_data *data, struct sensor_value *gyrodata) { data->buf[INTERRUPT_GYRO_SENSOR].gyro.x = gyrodata->gyro.x; data->buf[INTERRUPT_GYRO_SENSOR].gyro.y = gyrodata->gyro.y; data->buf[INTERRUPT_GYRO_SENSOR].gyro.z = gyrodata->gyro.z; input_report_rel(data->interrupt_gyro_input_dev, REL_RX, data->buf[INTERRUPT_GYRO_SENSOR].gyro.x); input_report_rel(data->interrupt_gyro_input_dev, REL_RY, data->buf[INTERRUPT_GYRO_SENSOR].gyro.y); input_report_rel(data->interrupt_gyro_input_dev, REL_RZ, data->buf[INTERRUPT_GYRO_SENSOR].gyro.z); input_sync(data->interrupt_gyro_input_dev); } #endif void report_geomagnetic_raw_data(struct ssp_data *data, struct sensor_value *magrawdata) { data->buf[GEOMAGNETIC_RAW].x = magrawdata->x; data->buf[GEOMAGNETIC_RAW].y = magrawdata->y; data->buf[GEOMAGNETIC_RAW].z = magrawdata->z; } void report_mag_data(struct ssp_data *data, struct sensor_value *magdata) { u8 lTemp[8] = { 0, }; data->buf[GEOMAGNETIC_SENSOR].cal_x = magdata->cal_x; data->buf[GEOMAGNETIC_SENSOR].cal_y = magdata->cal_y; data->buf[GEOMAGNETIC_SENSOR].cal_z = magdata->cal_z; data->buf[GEOMAGNETIC_SENSOR].accuracy = magdata->accuracy; #ifdef CONFIG_SSP_SUPPORT_MAGNETIC_OVERFLOW data->buf[GEOMAGNETIC_SENSOR].overflow = magdata->overflow; #endif memcpy(lTemp, magdata, sizeof(u8)*MAGNETIC_SIZE); ssp_push_iio_buffer(data->mag_indio_dev, magdata->timestamp, (u8 *)lTemp, sizeof(u8)*MAGNETIC_SIZE); } void report_mag_uncaldata(struct ssp_data *data, struct sensor_value *magdata) { u8 lTemp[13] = {0,}; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].uncal_x = magdata->uncal_x; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].uncal_y = magdata->uncal_y; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].uncal_z = magdata->uncal_z; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].offset_x = magdata->offset_x; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].offset_y = magdata->offset_y; data->buf[GEOMAGNETIC_UNCALIB_SENSOR].offset_z = magdata->offset_z; #ifdef CONFIG_SSP_SUPPORT_MAGNETIC_OVERFLOW data->buf[GEOMAGNETIC_UNCALIB_SENSOR].uncaloverflow = magdata->uncaloverflow; #endif memcpy(lTemp, magdata, sizeof(u8)*UNCAL_MAGNETIC_SIZE); ssp_push_iio_buffer(data->uncal_mag_indio_dev, magdata->timestamp, (u8 *)lTemp, sizeof(u8)*UNCAL_MAGNETIC_SIZE); } void report_uncalib_gyro_data(struct ssp_data *data, struct sensor_value *gyrodata) { int lTemp[6] = {0,}; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.x = gyrodata->uncal_gyro.x; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.y = gyrodata->uncal_gyro.y; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.z = gyrodata->uncal_gyro.z; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.offset_x = gyrodata->uncal_gyro.offset_x; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.offset_y = gyrodata->uncal_gyro.offset_y; data->buf[GYRO_UNCALIB_SENSOR].uncal_gyro.offset_z = gyrodata->uncal_gyro.offset_z; lTemp[0] = gyrodata->uncal_gyro.x; lTemp[1] = gyrodata->uncal_gyro.y; lTemp[2] = gyrodata->uncal_gyro.z; lTemp[3] = gyrodata->uncal_gyro.offset_x; lTemp[4] = gyrodata->uncal_gyro.offset_y; lTemp[5] = gyrodata->uncal_gyro.offset_z; ssp_push_iio_buffer(data->uncal_gyro_indio_dev, gyrodata->timestamp, (u8 *)lTemp, sizeof(lTemp)); } void report_sig_motion_data(struct ssp_data *data, struct sensor_value *sig_motion_data) { data->buf[SIG_MOTION_SENSOR].sig_motion = sig_motion_data->sig_motion; input_report_rel(data->sig_motion_input_dev, REL_MISC, data->buf[SIG_MOTION_SENSOR].sig_motion); input_sync(data->sig_motion_input_dev); wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); } void report_rot_data(struct ssp_data *data, struct sensor_value *rotdata) { u8 rot_buf[17]; data->buf[ROTATION_VECTOR].quat_a = rotdata->quat_a; data->buf[ROTATION_VECTOR].quat_b = rotdata->quat_b; data->buf[ROTATION_VECTOR].quat_c = rotdata->quat_c; data->buf[ROTATION_VECTOR].quat_d = rotdata->quat_d; data->buf[ROTATION_VECTOR].acc_rot = rotdata->acc_rot; rot_buf[0] = rotdata->quat_a; rot_buf[1] = rotdata->quat_b; rot_buf[2] = rotdata->quat_c; rot_buf[3] = rotdata->quat_d; rot_buf[4] = rotdata->acc_rot; memcpy(rot_buf, rotdata, sizeof(rot_buf)); ssp_push_iio_buffer(data->rot_indio_dev, rotdata->timestamp, rot_buf, sizeof(rot_buf)); } void report_game_rot_data(struct ssp_data *data, struct sensor_value *grvec_data) { u8 grot_buf[17]; data->buf[GAME_ROTATION_VECTOR].quat_a = grvec_data->quat_a; data->buf[GAME_ROTATION_VECTOR].quat_b = grvec_data->quat_b; data->buf[GAME_ROTATION_VECTOR].quat_c = grvec_data->quat_c; data->buf[GAME_ROTATION_VECTOR].quat_d = grvec_data->quat_d; data->buf[GAME_ROTATION_VECTOR].acc_rot = grvec_data->acc_rot; grot_buf[0] = grvec_data->quat_a; grot_buf[1] = grvec_data->quat_b; grot_buf[2] = grvec_data->quat_c; grot_buf[3] = grvec_data->quat_d; grot_buf[4] = grvec_data->acc_rot; memcpy(grot_buf, grvec_data, sizeof(grot_buf)); ssp_push_iio_buffer(data->game_rot_indio_dev, grvec_data->timestamp, grot_buf, sizeof(grot_buf)); } void report_gesture_data(struct ssp_data *data, struct sensor_value *gesdata) { int i = 0; for (i = 0; i < 20; i++) data->buf[GESTURE_SENSOR].data[i] = gesdata->data[i]; input_report_abs(data->gesture_input_dev, ABS_X, data->buf[GESTURE_SENSOR].data[0]); input_report_abs(data->gesture_input_dev, ABS_Y, data->buf[GESTURE_SENSOR].data[1]); input_report_abs(data->gesture_input_dev, ABS_Z, data->buf[GESTURE_SENSOR].data[2]); input_report_abs(data->gesture_input_dev, ABS_RX, data->buf[GESTURE_SENSOR].data[3]); input_report_abs(data->gesture_input_dev, ABS_RY, data->buf[GESTURE_SENSOR].data[4]); input_report_abs(data->gesture_input_dev, ABS_RZ, data->buf[GESTURE_SENSOR].data[5]); input_report_abs(data->gesture_input_dev, ABS_THROTTLE, data->buf[GESTURE_SENSOR].data[6]); input_report_abs(data->gesture_input_dev, ABS_RUDDER, data->buf[GESTURE_SENSOR].data[7]); input_report_abs(data->gesture_input_dev, ABS_WHEEL, data->buf[GESTURE_SENSOR].data[8]); input_report_abs(data->gesture_input_dev, ABS_GAS, data->buf[GESTURE_SENSOR].data[9]); input_report_abs(data->gesture_input_dev, ABS_BRAKE, data->buf[GESTURE_SENSOR].data[10]); input_report_abs(data->gesture_input_dev, ABS_HAT0X, data->buf[GESTURE_SENSOR].data[11]); input_report_abs(data->gesture_input_dev, ABS_HAT0Y, data->buf[GESTURE_SENSOR].data[12]); input_report_abs(data->gesture_input_dev, ABS_HAT1X, data->buf[GESTURE_SENSOR].data[13]); input_report_abs(data->gesture_input_dev, ABS_HAT1Y, data->buf[GESTURE_SENSOR].data[14]); input_report_abs(data->gesture_input_dev, ABS_HAT2X, data->buf[GESTURE_SENSOR].data[15]); input_report_abs(data->gesture_input_dev, ABS_HAT2Y, data->buf[GESTURE_SENSOR].data[16]); input_report_abs(data->gesture_input_dev, ABS_HAT3X, data->buf[GESTURE_SENSOR].data[17]); input_report_abs(data->gesture_input_dev, ABS_HAT3Y, data->buf[GESTURE_SENSOR].data[18]); input_report_abs(data->gesture_input_dev, ABS_PRESSURE, data->buf[GESTURE_SENSOR].data[19]); input_sync(data->gesture_input_dev); } void report_pressure_data(struct ssp_data *data, struct sensor_value *predata) { int temp[3] = {0, }; data->buf[PRESSURE_SENSOR].pressure = predata->pressure - data->iPressureCal; data->buf[PRESSURE_SENSOR].temperature = predata->temperature; temp[0] = data->buf[PRESSURE_SENSOR].pressure; temp[1] = data->buf[PRESSURE_SENSOR].temperature; temp[2] = data->sealevelpressure; ssp_push_iio_buffer(data->pressure_indio_dev, predata->timestamp, (u8 *)temp, sizeof(temp)); } void report_light_data(struct ssp_data *data, struct sensor_value *lightdata) { #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX data->buf[LIGHT_SENSOR].lux = lightdata->lux; data->buf[LIGHT_SENSOR].cct = lightdata->cct; #endif data->buf[LIGHT_SENSOR].r = lightdata->r; data->buf[LIGHT_SENSOR].g = lightdata->g; data->buf[LIGHT_SENSOR].b = lightdata->b; data->buf[LIGHT_SENSOR].w = lightdata->w; data->buf[LIGHT_SENSOR].a_time = lightdata->a_time; data->buf[LIGHT_SENSOR].a_gain = lightdata->a_gain; #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX input_report_rel(data->light_input_dev, REL_RX, data->buf[LIGHT_SENSOR].lux + 1); input_report_rel(data->light_input_dev, REL_X, data->buf[LIGHT_SENSOR].cct + 1); #endif input_report_rel(data->light_input_dev, REL_HWHEEL, data->buf[LIGHT_SENSOR].r + 1); input_report_rel(data->light_input_dev, REL_DIAL, data->buf[LIGHT_SENSOR].g + 1); input_report_rel(data->light_input_dev, REL_WHEEL, data->buf[LIGHT_SENSOR].b + 1); input_report_rel(data->light_input_dev, REL_MISC, data->buf[LIGHT_SENSOR].w + 1); input_report_rel(data->light_input_dev, REL_RY, data->buf[LIGHT_SENSOR].a_time + 1); input_report_rel(data->light_input_dev, REL_RZ, data->buf[LIGHT_SENSOR].a_gain + 1); if (data->light_log_cnt < 3) { #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX ssp_dbg("[SSP] #>L lux=%u cct=%d r=%d g=%d b=%d c=%d atime=%d again=%d", data->buf[LIGHT_SENSOR].lux, data->buf[LIGHT_SENSOR].cct, data->buf[LIGHT_SENSOR].r, data->buf[LIGHT_SENSOR].g, data->buf[LIGHT_SENSOR].b, data->buf[LIGHT_SENSOR].w, data->buf[LIGHT_SENSOR].a_time, data->buf[LIGHT_SENSOR].a_gain); #else ssp_dbg("[SSP] #>L r=%d g=%d b=%d c=%d atime=%d again=%d", data->buf[LIGHT_SENSOR].r, data->buf[LIGHT_SENSOR].g, data->buf[LIGHT_SENSOR].b, data->buf[LIGHT_SENSOR].w, data->buf[LIGHT_SENSOR].a_time, data->buf[LIGHT_SENSOR].a_gain); #endif data->light_log_cnt++; } input_sync(data->light_input_dev); } #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA void report_light_ir_data(struct ssp_data *data, struct sensor_value *lightirdata) { data->buf[LIGHT_IR_SENSOR].irdata = lightirdata->irdata; data->buf[LIGHT_IR_SENSOR].ir_r = lightirdata->ir_r; data->buf[LIGHT_IR_SENSOR].ir_g = lightirdata->ir_g; data->buf[LIGHT_IR_SENSOR].ir_b = lightirdata->ir_b; data->buf[LIGHT_IR_SENSOR].ir_w = lightirdata->ir_w; data->buf[LIGHT_IR_SENSOR].ir_a_time = lightirdata->ir_a_time; data->buf[LIGHT_IR_SENSOR].ir_a_gain = lightirdata->ir_a_gain; input_report_rel(data->light_ir_input_dev, REL_RX, data->buf[LIGHT_IR_SENSOR].irdata + 1); input_report_rel(data->light_ir_input_dev, REL_HWHEEL, data->buf[LIGHT_IR_SENSOR].ir_r + 1); input_report_rel(data->light_ir_input_dev, REL_DIAL, data->buf[LIGHT_IR_SENSOR].ir_g + 1); input_report_rel(data->light_ir_input_dev, REL_WHEEL, data->buf[LIGHT_IR_SENSOR].ir_b + 1); input_report_rel(data->light_ir_input_dev, REL_MISC, data->buf[LIGHT_IR_SENSOR].ir_w + 1); input_report_rel(data->light_ir_input_dev, REL_RY, data->buf[LIGHT_IR_SENSOR].ir_a_time + 1); input_report_rel(data->light_ir_input_dev, REL_RZ, data->buf[LIGHT_IR_SENSOR].ir_a_gain + 1); input_sync(data->light_ir_input_dev); if (data->light_ir_log_cnt < 3) { ssp_dbg("[SSP]#>IR irdata=%d r=%d g=%d b=%d c=%d atime=%d again=%d\n", data->buf[LIGHT_IR_SENSOR].irdata, data->buf[LIGHT_IR_SENSOR].ir_r, data->buf[LIGHT_IR_SENSOR].ir_g, data->buf[LIGHT_IR_SENSOR].ir_b, data->buf[LIGHT_IR_SENSOR].ir_w, data->buf[LIGHT_IR_SENSOR].ir_a_time, data->buf[LIGHT_IR_SENSOR].ir_a_gain); data->light_ir_log_cnt++; } } #endif void report_light_flicker_data(struct ssp_data *data, struct sensor_value *lightFlickerData) { data->buf[LIGHT_FLICKER_SENSOR].light_flicker = lightFlickerData->light_flicker; input_report_rel(data->light_flicker_input_dev, REL_RX, data->buf[LIGHT_FLICKER_SENSOR].light_flicker + 1); input_sync(data->light_flicker_input_dev); } void report_prox_data(struct ssp_data *data, struct sensor_value *proxdata) { u32 ts_high, ts_low; ts_high = (u32)((proxdata->timestamp)>>32); ts_low = (u32)((proxdata->timestamp)&0x00000000ffffffff); usleep_range(500, 1000); ssp_dbg("[SSP] Proximity Sensor Detect : %u, raw : %u ts : %llu %d %d\n", proxdata->prox_detect, proxdata->prox_adc, proxdata->timestamp, ts_high, ts_low); data->buf[PROXIMITY_SENSOR].prox_detect = proxdata->prox_detect; data->buf[PROXIMITY_SENSOR].prox_adc = proxdata->prox_adc; input_report_rel(data->prox_input_dev, REL_DIAL, ((!proxdata->prox_detect)) + 1); input_report_rel(data->prox_input_dev, REL_WHEEL, ts_high); input_report_rel(data->prox_input_dev, REL_MISC, ts_low); input_sync(data->prox_input_dev); wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); } void report_prox_raw_data(struct ssp_data *data, struct sensor_value *proxrawdata) { if (data->uFactoryProxAvg[0]++ >= PROX_AVG_READ_NUM) { data->uFactoryProxAvg[2] /= PROX_AVG_READ_NUM; data->buf[PROXIMITY_RAW].prox_raw[1] = (u16)data->uFactoryProxAvg[1]; data->buf[PROXIMITY_RAW].prox_raw[2] = (u16)data->uFactoryProxAvg[2]; data->buf[PROXIMITY_RAW].prox_raw[3] = (u16)data->uFactoryProxAvg[3]; data->uFactoryProxAvg[0] = 0; data->uFactoryProxAvg[1] = 0; data->uFactoryProxAvg[2] = 0; data->uFactoryProxAvg[3] = 0; } else { data->uFactoryProxAvg[2] += proxrawdata->prox_raw[0]; if (data->uFactoryProxAvg[0] == 1) data->uFactoryProxAvg[1] = proxrawdata->prox_raw[0]; else if (proxrawdata->prox_raw[0] < data->uFactoryProxAvg[1]) data->uFactoryProxAvg[1] = proxrawdata->prox_raw[0]; if (proxrawdata->prox_raw[0] > data->uFactoryProxAvg[3]) data->uFactoryProxAvg[3] = proxrawdata->prox_raw[0]; } data->buf[PROXIMITY_RAW].prox_raw[0] = proxrawdata->prox_raw[0]; } void report_prox_alert_data(struct ssp_data *data, struct sensor_value *prox_alert_data) { u32 ts_high, ts_low; ts_high = (u32)((prox_alert_data->timestamp)>>32); ts_low = (u32)((prox_alert_data->timestamp)&0x00000000ffffffff); ssp_dbg("[SSP] Proximity alert Sensor Detect : %d, raw : %u ts : %llu %d %d\n", prox_alert_data->prox_alert_detect, prox_alert_data->prox_alert_adc, prox_alert_data->timestamp, ts_high, ts_low); data->buf[PROXIMITY_ALERT_SENSOR].prox_alert_detect = prox_alert_data->prox_alert_detect; data->buf[PROXIMITY_ALERT_SENSOR].prox_alert_adc = prox_alert_data->prox_alert_adc; input_report_rel(data->prox_alert_input_dev, REL_DIAL, (prox_alert_data->prox_alert_detect+1)); input_report_rel(data->prox_alert_input_dev, REL_WHEEL, ts_high); input_report_rel(data->prox_alert_input_dev, REL_MISC, ts_low); input_sync(data->prox_alert_input_dev); } #ifdef CONFIG_SENSORS_SSP_SX9306 void report_grip_data(struct ssp_data *data, struct sensor_value *gripdata) { pr_err("[SSP] grip = %d %d %d 0x%02x\n", gripdata->cap_main, gripdata->useful, gripdata->offset, gripdata->irq_stat); if (data->grip_off) { pr_err("[SSP] grip_off = true, skip reporting grip data\n"); return; } #if defined(CONFIG_MUIC_NOTIFIER) if (data->jig_is_attached) { pr_err("[SSP] jig_is_attached, skip reporting grip data\n"); return; } #endif data->buf[GRIP_SENSOR].cap_main = gripdata->cap_main; data->buf[GRIP_SENSOR].useful = gripdata->useful; data->buf[GRIP_SENSOR].offset = gripdata->offset; data->buf[GRIP_SENSOR].irq_stat = gripdata->irq_stat; input_report_rel(data->grip_input_dev, REL_MISC, data->buf[GRIP_SENSOR].irq_stat + 1); input_sync(data->grip_input_dev); wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); } #endif void report_step_det_data(struct ssp_data *data, struct sensor_value *stepdet_data) { data->buf[STEP_DETECTOR].step_det = stepdet_data->step_det; ssp_push_iio_buffer(data->step_det_indio_dev, stepdet_data->timestamp, (u8 *)&stepdet_data->step_det, 1); } void report_step_cnt_data(struct ssp_data *data, struct sensor_value *sig_motion_data) { data->buf[STEP_COUNTER].step_diff = sig_motion_data->step_diff; data->step_count_total += data->buf[STEP_COUNTER].step_diff; input_report_rel(data->step_cnt_input_dev, REL_MISC, data->step_count_total + 1); input_sync(data->step_cnt_input_dev); } void report_temp_humidity_data(struct ssp_data *data, struct sensor_value *temp_humi_data) { data->buf[TEMPERATURE_HUMIDITY_SENSOR].x = temp_humi_data->x; data->buf[TEMPERATURE_HUMIDITY_SENSOR].y = temp_humi_data->y; data->buf[TEMPERATURE_HUMIDITY_SENSOR].z = temp_humi_data->z; /* Temperature */ input_report_rel(data->temp_humi_input_dev, REL_HWHEEL, data->buf[TEMPERATURE_HUMIDITY_SENSOR].x); /* Humidity */ input_report_rel(data->temp_humi_input_dev, REL_DIAL, data->buf[TEMPERATURE_HUMIDITY_SENSOR].y); input_sync(data->temp_humi_input_dev); if (data->buf[TEMPERATURE_HUMIDITY_SENSOR].z) wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); } #ifdef CONFIG_SENSORS_SSP_SHTC1 void report_bulk_comp_data(struct ssp_data *data) { input_report_rel(data->temp_humi_input_dev, REL_WHEEL, data->bulk_buffer->len); input_sync(data->temp_humi_input_dev); } #endif void report_tilt_data(struct ssp_data *data, struct sensor_value *tilt_data) { data->buf[TILT_DETECTOR].tilt_detector = tilt_data->tilt_detector; ssp_push_iio_buffer(data->tilt_indio_dev, tilt_data->timestamp, &tilt_data->tilt_detector, 1); wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); pr_err("[SSP]: %s: %d", __func__, tilt_data->tilt_detector); } void report_pickup_data(struct ssp_data *data, struct sensor_value *pickup_data) { data->buf[PICKUP_GESTURE].pickup_gesture = pickup_data->pickup_gesture; ssp_push_iio_buffer(data->pickup_indio_dev, pickup_data->timestamp, &pickup_data->pickup_gesture, 1); wake_lock_timeout(&data->ssp_wake_lock, 0.3*HZ); pr_err("[SSP]: %s: %d", __func__, pickup_data->pickup_gesture); } int initialize_event_symlink(struct ssp_data *data) { int iRet = 0; iRet = sensors_create_symlink(data->gesture_input_dev); if (iRet < 0) goto iRet_gesture_sysfs_create_link; iRet = sensors_create_symlink(data->light_input_dev); if (iRet < 0) goto iRet_light_sysfs_create_link; iRet = sensors_create_symlink(data->light_flicker_input_dev); if (iRet < 0) goto iRet_light_flicker_sysfs_create_link; #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA iRet = sensors_create_symlink(data->light_ir_input_dev); if (iRet < 0) goto iRet_light_ir_sysfs_create_link; #endif iRet = sensors_create_symlink(data->prox_input_dev); if (iRet < 0) goto iRet_prox_sysfs_create_link; #ifdef CONFIG_SENSORS_SSP_SX9306 iRet = sensors_create_symlink(data->grip_input_dev); if (iRet < 0) goto iRet_grip_sysfs_create_link; #endif iRet = sensors_create_symlink(data->temp_humi_input_dev); if (iRet < 0) goto iRet_temp_humi_sysfs_create_link; iRet = sensors_create_symlink(data->sig_motion_input_dev); if (iRet < 0) goto iRet_sig_motion_sysfs_create_link; iRet = sensors_create_symlink(data->step_cnt_input_dev); if (iRet < 0) goto iRet_step_cnt_sysfs_create_link; #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR iRet = sensors_create_symlink(data->interrupt_gyro_input_dev); if (iRet < 0) goto iRet_interrupt_gyro_sysfs_create_link; #endif iRet = sensors_create_symlink(data->meta_input_dev); if (iRet < 0) goto iRet_meta_sysfs_create_link; iRet = sensors_create_symlink(data->prox_alert_input_dev); if (iRet < 0) goto iRet_prox_alert_sysfs_create_link; return SUCCESS; iRet_prox_alert_sysfs_create_link: sensors_remove_symlink(data->meta_input_dev); iRet_meta_sysfs_create_link: #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR sensors_remove_symlink(data->interrupt_gyro_input_dev); iRet_interrupt_gyro_sysfs_create_link: #endif sensors_remove_symlink(data->step_cnt_input_dev); iRet_step_cnt_sysfs_create_link: sensors_remove_symlink(data->sig_motion_input_dev); iRet_sig_motion_sysfs_create_link: sensors_remove_symlink(data->temp_humi_input_dev); iRet_temp_humi_sysfs_create_link: #ifdef CONFIG_SENSORS_SSP_SX9306 sensors_remove_symlink(data->grip_input_dev); iRet_grip_sysfs_create_link: #endif sensors_remove_symlink(data->prox_input_dev); iRet_prox_sysfs_create_link: sensors_remove_symlink(data->light_flicker_input_dev); iRet_light_flicker_sysfs_create_link: #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA sensors_remove_symlink(data->light_ir_input_dev); iRet_light_ir_sysfs_create_link: #endif sensors_remove_symlink(data->light_input_dev); iRet_light_sysfs_create_link: sensors_remove_symlink(data->gesture_input_dev); iRet_gesture_sysfs_create_link: pr_err("[SSP]: %s - could not create event symlink\n", __func__); return FAIL; } void remove_event_symlink(struct ssp_data *data) { sensors_remove_symlink(data->gesture_input_dev); sensors_remove_symlink(data->light_flicker_input_dev); sensors_remove_symlink(data->light_input_dev); #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA sensors_remove_symlink(data->light_ir_input_dev); #endif sensors_remove_symlink(data->prox_input_dev); #ifdef CONFIG_SENSORS_SSP_SX9306 sensors_remove_symlink(data->grip_input_dev); #endif sensors_remove_symlink(data->temp_humi_input_dev); sensors_remove_symlink(data->sig_motion_input_dev); sensors_remove_symlink(data->step_cnt_input_dev); #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR sensors_remove_symlink(data->interrupt_gyro_input_dev); #endif sensors_remove_symlink(data->meta_input_dev); sensors_remove_symlink(data->prox_alert_input_dev); } static const struct iio_info accel_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec accel_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_6_BYTES*8, IIO_BUFFER_6_BYTES*8, 0) } }; static const struct iio_info gyro_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec gyro_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_12_BYTES*8, IIO_BUFFER_12_BYTES*8, 0) } }; static const struct iio_info uncal_gyro_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec uncal_gyro_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = { .sign = 's', .realbits = 16 * 8, .storagebits = 16 * 8, .shift = 0, .repeat = 2 } } }; static const struct iio_info mag_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec mag_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_7_BYTES * 8, IIO_BUFFER_7_BYTES * 8, 0) } }; static const struct iio_info uncal_mag_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec uncal_mag_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_12_BYTES * 8, IIO_BUFFER_12_BYTES * 8, 0) } }; static const struct iio_info game_rot_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec game_rot_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_17_BYTES*8, IIO_BUFFER_17_BYTES*8, 0) } }; static const struct iio_info rot_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec rot_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_17_BYTES*8, IIO_BUFFER_17_BYTES*8, 0) } }; static const struct iio_info step_det_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec step_det_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_1_BYTES*8, IIO_BUFFER_1_BYTES*8, 0) } }; static const struct iio_info pressure_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec pressure_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_12_BYTES * 8, IIO_BUFFER_12_BYTES * 8, 0) } }; static const struct iio_info tilt_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec tilt_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_1_BYTES*8, IIO_BUFFER_1_BYTES*8, 0) } }; static const struct iio_info pickup_info = { .driver_module = THIS_MODULE, }; static const struct iio_chan_spec pickup_channels[] = { { .type = IIO_TIMESTAMP, .channel = -1, .scan_index = 3, .scan_type = IIO_ST('s', IIO_BUFFER_1_BYTES*8, IIO_BUFFER_1_BYTES*8, 0) } }; int initialize_input_device(struct input_dev *dev, struct ssp_data *data) { int iRet = 0; iRet = input_register_device(dev); if (iRet < 0) { pr_err("[SSP]: %s - could not allocate %s input device\n", __func__, dev->name); input_unregister_device(dev); input_free_device(dev); return iRet; } input_set_drvdata(dev, data); return iRet; } int initialize_iio_buffer_and_device(struct iio_dev *indio_dev) { int iRet = 0; iRet = ssp_iio_configure_ring(indio_dev); if (iRet) goto err_config_ring_buffer; iRet = iio_device_register(indio_dev); if (iRet) goto err_register_device; return iRet; err_register_device: pr_err("[SSP]: failed to register %s device\n", indio_dev->name); iio_device_unregister(indio_dev); err_config_ring_buffer: pr_err("[SSP]: failed to configure %s buffer\n", indio_dev->name); ssp_iio_unconfigure_ring(indio_dev); return iRet; } int initialize_input_dev(struct ssp_data *data) { int iRet = 0; /* Registering iio device - start */ // accelerometer sensor data->accel_indio_dev = iio_device_alloc(0); if (data->accel_indio_dev) { data->accel_indio_dev->name = "accelerometer_sensor"; data->accel_indio_dev->dev.parent = &data->spi->dev; data->accel_indio_dev->info = &accel_info; data->accel_indio_dev->channels = accel_channels; data->accel_indio_dev->num_channels = ARRAY_SIZE(accel_channels); data->accel_indio_dev->modes = INDIO_DIRECT_MODE; data->accel_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->accel_indio_dev); } // gyroscope sensor data->gyro_indio_dev = iio_device_alloc(0); if (data->gyro_indio_dev) { data->gyro_indio_dev->name = "gyro_sensor"; data->gyro_indio_dev->dev.parent = &data->spi->dev; data->gyro_indio_dev->info = &gyro_info; data->gyro_indio_dev->channels = gyro_channels; data->gyro_indio_dev->num_channels = ARRAY_SIZE(gyro_channels); data->gyro_indio_dev->modes = INDIO_DIRECT_MODE; data->gyro_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->gyro_indio_dev); } // uncalibrate gyro sensor data->uncal_gyro_indio_dev = iio_device_alloc(0); if (data->uncal_gyro_indio_dev) { data->uncal_gyro_indio_dev->name = "uncal_gyro_sensor"; data->uncal_gyro_indio_dev->dev.parent = &data->spi->dev; data->uncal_gyro_indio_dev->info = &uncal_gyro_info; data->uncal_gyro_indio_dev->channels = uncal_gyro_channels; data->uncal_gyro_indio_dev->num_channels = ARRAY_SIZE(uncal_gyro_channels); data->uncal_gyro_indio_dev->modes = INDIO_DIRECT_MODE; data->uncal_gyro_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->uncal_gyro_indio_dev); } // geomagnetic sensor data->mag_indio_dev = iio_device_alloc(0); if (data->mag_indio_dev) { data->mag_indio_dev->name = "geomagnetic_sensor"; data->mag_indio_dev->dev.parent = &data->spi->dev; data->mag_indio_dev->info = &mag_info; data->mag_indio_dev->channels = mag_channels; data->mag_indio_dev->num_channels = ARRAY_SIZE(mag_channels); data->mag_indio_dev->modes = INDIO_DIRECT_MODE; data->mag_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->mag_indio_dev); } // uncalibrate geomagnetic sensor data->uncal_mag_indio_dev = iio_device_alloc(0); if (data->uncal_mag_indio_dev) { data->uncal_mag_indio_dev->name = "uncal_geomagnetic_sensor"; data->uncal_mag_indio_dev->dev.parent = &data->spi->dev; data->uncal_mag_indio_dev->info = &uncal_mag_info; data->uncal_mag_indio_dev->channels = uncal_mag_channels; data->uncal_mag_indio_dev->num_channels = ARRAY_SIZE(uncal_mag_channels); data->uncal_mag_indio_dev->modes = INDIO_DIRECT_MODE; data->uncal_mag_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->uncal_mag_indio_dev); } // game rotation vector sensor data->game_rot_indio_dev = iio_device_alloc(0); if (data->game_rot_indio_dev) { data->game_rot_indio_dev->name = "game_rotation_vector"; data->game_rot_indio_dev->dev.parent = &data->spi->dev; data->game_rot_indio_dev->info = &game_rot_info; data->game_rot_indio_dev->channels = game_rot_channels; data->game_rot_indio_dev->num_channels = ARRAY_SIZE(game_rot_channels); data->game_rot_indio_dev->modes = INDIO_DIRECT_MODE; data->game_rot_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->game_rot_indio_dev); } // rotation vector sensor data->rot_indio_dev = iio_device_alloc(0); if (data->rot_indio_dev) { data->rot_indio_dev->name = "rotation_vector_sensor"; data->rot_indio_dev->dev.parent = &data->spi->dev; data->rot_indio_dev->info = &rot_info; data->rot_indio_dev->channels = rot_channels; data->rot_indio_dev->num_channels = ARRAY_SIZE(rot_channels); data->rot_indio_dev->modes = INDIO_DIRECT_MODE; data->rot_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->rot_indio_dev); } // step detector sensor data->step_det_indio_dev = iio_device_alloc(0); if (data->step_det_indio_dev) { data->step_det_indio_dev->name = "step_det_sensor"; data->step_det_indio_dev->dev.parent = &data->spi->dev; data->step_det_indio_dev->info = &step_det_info; data->step_det_indio_dev->channels = step_det_channels; data->step_det_indio_dev->num_channels = ARRAY_SIZE(step_det_channels); data->step_det_indio_dev->modes = INDIO_DIRECT_MODE; data->step_det_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->step_det_indio_dev); } // pressure sensor data->pressure_indio_dev = iio_device_alloc(0); if (data->pressure_indio_dev) { data->pressure_indio_dev->name = "pressure_sensor"; data->pressure_indio_dev->dev.parent = &data->spi->dev; data->pressure_indio_dev->info = &pressure_info; data->pressure_indio_dev->channels = pressure_channels; data->pressure_indio_dev->num_channels = ARRAY_SIZE(pressure_channels); data->pressure_indio_dev->modes = INDIO_DIRECT_MODE; data->pressure_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->pressure_indio_dev); } // tilt dectector sensor data->tilt_indio_dev = iio_device_alloc(0); if (data->tilt_indio_dev) { data->tilt_indio_dev->name = "tilt_detector"; data->tilt_indio_dev->dev.parent = &data->spi->dev; data->tilt_indio_dev->info = &tilt_info; data->tilt_indio_dev->channels = tilt_channels; data->tilt_indio_dev->num_channels = ARRAY_SIZE(tilt_channels); data->tilt_indio_dev->modes = INDIO_DIRECT_MODE; data->tilt_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->tilt_indio_dev); } // pickup gesture sensor data->pickup_indio_dev = iio_device_alloc(0); if (data->pickup_indio_dev) { data->pickup_indio_dev->name = "pickup_gesture"; data->pickup_indio_dev->dev.parent = &data->spi->dev; data->pickup_indio_dev->info = &pickup_info; data->pickup_indio_dev->channels = pickup_channels; data->pickup_indio_dev->num_channels = ARRAY_SIZE(pickup_channels); data->pickup_indio_dev->modes = INDIO_DIRECT_MODE; data->pickup_indio_dev->currentmode = INDIO_DIRECT_MODE; iRet = initialize_iio_buffer_and_device(data->pickup_indio_dev); } /* end - iio buffer initialize*/ /* Registering Input device - start */ // light sensor data->light_input_dev = input_allocate_device(); if (data->light_input_dev) { data->light_input_dev->name = "light_sensor"; #ifdef CONFIG_SENSORS_SSP_LIGHT_REPORT_LUX input_set_capability(data->light_input_dev, EV_REL, REL_RX); input_set_capability(data->light_input_dev, EV_REL, REL_X); #endif input_set_capability(data->light_input_dev, EV_REL, REL_HWHEEL); input_set_capability(data->light_input_dev, EV_REL, REL_DIAL); input_set_capability(data->light_input_dev, EV_REL, REL_WHEEL); input_set_capability(data->light_input_dev, EV_REL, REL_MISC); input_set_capability(data->light_input_dev, EV_REL, REL_RY); input_set_capability(data->light_input_dev, EV_REL, REL_RZ); iRet = initialize_input_device(data->light_input_dev, data); } // light ir sensor #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA data->light_ir_input_dev = input_allocate_device(); if (data->light_ir_input_dev) { data->light_ir_input_dev->name = "light_ir_sensor"; input_set_capability(data->light_ir_input_dev, EV_REL, REL_HWHEEL); input_set_capability(data->light_ir_input_dev, EV_REL, REL_DIAL); input_set_capability(data->light_ir_input_dev, EV_REL, REL_WHEEL); input_set_capability(data->light_ir_input_dev, EV_REL, REL_MISC); input_set_capability(data->light_ir_input_dev, EV_REL, REL_RY); input_set_capability(data->light_ir_input_dev, EV_REL, REL_RZ); input_set_capability(data->light_ir_input_dev, EV_REL, REL_RX); iRet = initialize_input_device(data->light_ir_input_dev, data); } #endif // light_flicker_sensor data->light_flicker_input_dev = input_allocate_device(); if (data->light_flicker_input_dev) { data->light_flicker_input_dev->name = "light_flicker_sensor"; input_set_capability(data->light_flicker_input_dev, EV_REL, REL_RX); iRet = initialize_input_device(data->light_flicker_input_dev, data); } // proximity sensor data->prox_input_dev = input_allocate_device(); if (data->prox_input_dev) { data->prox_input_dev->name = "proximity_sensor"; input_set_capability(data->prox_input_dev, EV_REL, REL_DIAL); input_set_capability(data->prox_input_dev, EV_REL, REL_WHEEL); input_set_capability(data->prox_input_dev, EV_REL, REL_MISC); iRet = initialize_input_device(data->prox_input_dev, data); } // proximity alert sensor data->prox_alert_input_dev = input_allocate_device(); if (data->prox_alert_input_dev) { data->prox_alert_input_dev->name = "proximity_alert_sensor"; input_set_capability(data->prox_alert_input_dev, EV_REL, REL_DIAL); input_set_capability(data->prox_alert_input_dev, EV_REL, REL_WHEEL); input_set_capability(data->prox_alert_input_dev, EV_REL, REL_MISC); iRet = initialize_input_device(data->prox_alert_input_dev, data); } #ifdef CONFIG_SENSORS_SSP_SX9306 // grip sensor data->grip_input_dev = input_allocate_device(); if (data->grip_input_dev) { data->grip_input_dev->name = "grip_sensor"; input_set_capability(data->grip_input_dev, EV_REL, REL_MISC); iRet = initialize_input_device(data->grip_input_dev, data); } #endif // temperature sensor data->temp_humi_input_dev = input_allocate_device(); if (data->temp_humi_input_dev) { data->temp_humi_input_dev->name = "temp_humidity_sensor"; input_set_capability(data->temp_humi_input_dev, EV_REL, REL_HWHEEL); input_set_capability(data->temp_humi_input_dev, EV_REL, REL_DIAL); input_set_capability(data->temp_humi_input_dev, EV_REL, REL_WHEEL); iRet = initialize_input_device(data->temp_humi_input_dev, data); } // gesture sensor data->gesture_input_dev = input_allocate_device(); if (data->gesture_input_dev) { data->gesture_input_dev->name = "gesture_sensor"; input_set_capability(data->gesture_input_dev, EV_ABS, ABS_X); input_set_abs_params(data->gesture_input_dev, ABS_X, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_Y); input_set_abs_params(data->gesture_input_dev, ABS_Y, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_Z); input_set_abs_params(data->gesture_input_dev, ABS_Z, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_RX); input_set_abs_params(data->gesture_input_dev, ABS_RX, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_RY); input_set_abs_params(data->gesture_input_dev, ABS_RY, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_RZ); input_set_abs_params(data->gesture_input_dev, ABS_RZ, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_THROTTLE); input_set_abs_params(data->gesture_input_dev, ABS_THROTTLE, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_RUDDER); input_set_abs_params(data->gesture_input_dev, ABS_RUDDER, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_WHEEL); input_set_abs_params(data->gesture_input_dev, ABS_WHEEL, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_GAS); input_set_abs_params(data->gesture_input_dev, ABS_GAS, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_BRAKE); input_set_abs_params(data->gesture_input_dev, ABS_BRAKE, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT0X); input_set_abs_params(data->gesture_input_dev, ABS_HAT0X, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT0Y); input_set_abs_params(data->gesture_input_dev, ABS_HAT0Y, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT1X); input_set_abs_params(data->gesture_input_dev, ABS_HAT1X, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT1Y); input_set_abs_params(data->gesture_input_dev, ABS_HAT1Y, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT2X); input_set_abs_params(data->gesture_input_dev, ABS_HAT2X, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT2Y); input_set_abs_params(data->gesture_input_dev, ABS_HAT2Y, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT3X); input_set_abs_params(data->gesture_input_dev, ABS_HAT3X, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_HAT3Y); input_set_abs_params(data->gesture_input_dev, ABS_HAT3Y, 0, 1024, 0, 0); input_set_capability(data->gesture_input_dev, EV_ABS, ABS_PRESSURE); input_set_abs_params(data->gesture_input_dev, ABS_PRESSURE, 0, 1024, 0, 0); iRet = initialize_input_device(data->gesture_input_dev, data); } // sig motion sensor data->sig_motion_input_dev = input_allocate_device(); if (data->sig_motion_input_dev) { data->sig_motion_input_dev->name = "sig_motion_sensor"; input_set_capability(data->sig_motion_input_dev, EV_REL, REL_MISC); iRet = initialize_input_device(data->sig_motion_input_dev, data); } // step counter sensor data->step_cnt_input_dev = input_allocate_device(); if (data->step_cnt_input_dev) { data->step_cnt_input_dev->name = "step_cnt_sensor"; input_set_capability(data->step_cnt_input_dev, EV_REL, REL_MISC); iRet = initialize_input_device(data->step_cnt_input_dev, data); } #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR // interrupt gyro sensor data->interrupt_gyro_input_dev = input_allocate_device(); if (data->interrupt_gyro_input_dev) { data->interrupt_gyro_input_dev->name = "interrupt_gyro_sensor"; input_set_capability(data->interrupt_gyro_input_dev, EV_REL, REL_RX); input_set_capability(data->interrupt_gyro_input_dev, EV_REL, REL_RY); input_set_capability(data->interrupt_gyro_input_dev, EV_REL, REL_RZ); iRet = initialize_input_device(data->interrupt_gyro_input_dev, data); } #endif // meta sensor data->meta_input_dev = input_allocate_device(); if (data->meta_input_dev) { data->meta_input_dev->name = "meta_event"; input_set_capability(data->meta_input_dev, EV_REL, REL_HWHEEL); input_set_capability(data->meta_input_dev, EV_REL, REL_DIAL); iRet = initialize_input_device(data->meta_input_dev, data); } return iRet; } void remove_input_dev(struct ssp_data *data) { input_unregister_device(data->gesture_input_dev); input_unregister_device(data->light_flicker_input_dev); input_unregister_device(data->light_input_dev); #ifdef CONFIG_SENSORS_SSP_IRDATA_FOR_CAMERA input_unregister_device(data->light_ir_input_dev); #endif input_unregister_device(data->prox_input_dev); input_unregister_device(data->prox_alert_input_dev); input_unregister_device(data->temp_humi_input_dev); input_unregister_device(data->sig_motion_input_dev); input_unregister_device(data->step_cnt_input_dev); #ifdef CONFIG_SENSORS_SSP_INTERRUPT_GYRO_SENSOR input_unregister_device(data->interrupt_gyro_input_dev); #endif input_unregister_device(data->meta_input_dev); }