123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974 |
- /*
- * 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 <linux/math64.h>
- #include "../../staging/iio/events.h"
- #include "../../staging/iio/iio.h"
- #define BATCH_IOCTL_MAGIC 0xFC
- struct batch_config {
- int64_t timeout;
- int64_t delay;
- int flag;
- };
- /*************************************************************************/
- /* SSP data delay function */
- /*************************************************************************/
- int get_msdelay(int64_t dDelayRate) {
- /*
- * From Android 5.0, There is MaxDelay Concept.
- * If App request lower frequency then MaxDelay,
- * Sensor have to work with MaxDelay.
- */
- if (dDelayRate > 200000000)
- dDelayRate = 200000000;
- return div_s64(dDelayRate, 1000000);
- }
- static void enable_sensor(struct ssp_data *data,
- int iSensorType, int64_t dNewDelay)
- {
- u8 uBuf[9];
- unsigned int uNewEnable = 0;
- s32 maxBatchReportLatency = 0;
- s8 batchOptions = 0;
- int64_t dTempDelay = data->adDelayBuf[iSensorType];
- s32 dMsDelay = get_msdelay(dNewDelay);
- int ret = 0;
- data->adDelayBuf[iSensorType] = dNewDelay;
- maxBatchReportLatency = data->batchLatencyBuf[iSensorType];
- batchOptions = data->batchOptBuf[iSensorType];
- switch (data->aiCheckStatus[iSensorType]) {
- case ADD_SENSOR_STATE:
- pr_debug("[SSP]: %s - add %u, New = %lldns\n",
- __func__, 1 << iSensorType, dNewDelay);
- memcpy(&uBuf[0], &dMsDelay, 4);
- memcpy(&uBuf[4], &maxBatchReportLatency, 4);
- uBuf[8] = batchOptions;
- if (iSensorType == TEMPERATURE_HUMIDITY_SENSOR &&
- dMsDelay == 10000)
- pr_info("[SSP] Skip Add Temphumidity Sensor\n");
- else
- ret = send_instruction(data, ADD_SENSOR,
- iSensorType, uBuf, 9);
- pr_info("[SSP], delay %d, timeout %d, flag=%d, ret%d",
- dMsDelay, maxBatchReportLatency, uBuf[8], ret);
- if (ret <= 0) {
- uNewEnable =
- (unsigned int)atomic_read(&data->aSensorEnable)
- & (~(unsigned int)(1 << iSensorType));
- atomic_set(&data->aSensorEnable, uNewEnable);
- data->aiCheckStatus[iSensorType] = NO_SENSOR_STATE;
- break;
- }
- data->aiCheckStatus[iSensorType] = RUNNING_SENSOR_STATE;
- if (iSensorType == PROXIMITY_SENSOR) {
- proximity_open_lcd_ldi(data);
- proximity_open_calibration(data);
- set_proximity_threshold(data, data->uProxHiThresh, data->uProxLoThresh);
- }
- break;
- case RUNNING_SENSOR_STATE:
- if (get_msdelay(dTempDelay)
- == get_msdelay(data->adDelayBuf[iSensorType]))
- break;
- pr_debug("[SSP]: %s - Change %u, New = %lldns\n",
- __func__, 1 << iSensorType, dNewDelay);
- memcpy(&uBuf[0], &dMsDelay, 4);
- memcpy(&uBuf[4], &maxBatchReportLatency, 4);
- uBuf[8] = batchOptions;
- send_instruction(data, CHANGE_DELAY, iSensorType, uBuf, 9);
- break;
- default:
- data->aiCheckStatus[iSensorType] = ADD_SENSOR_STATE;
- }
- }
- static void change_sensor_delay(struct ssp_data *data,
- int iSensorType, int64_t dNewDelay)
- {
- u8 uBuf[9];
- s32 maxBatchReportLatency = 0;
- s8 batchOptions = 0;
- int64_t dTempDelay = data->adDelayBuf[iSensorType];
- s32 dMsDelay = get_msdelay(dNewDelay);
- data->adDelayBuf[iSensorType] = dNewDelay;
- data->batchLatencyBuf[iSensorType] = maxBatchReportLatency;
- data->batchOptBuf[iSensorType] = batchOptions;
- switch (data->aiCheckStatus[iSensorType]) {
- case RUNNING_SENSOR_STATE:
- if (get_msdelay(dTempDelay)
- == get_msdelay(data->adDelayBuf[iSensorType]))
- break;
- ssp_dbg("[SSP]: %s - Change %u, New = %lldns\n",
- __func__, 1 << iSensorType, dNewDelay);
- memcpy(&uBuf[0], &dMsDelay, 4);
- memcpy(&uBuf[4], &maxBatchReportLatency, 4);
- uBuf[8] = batchOptions;
- send_instruction(data, CHANGE_DELAY, iSensorType, uBuf, 9);
- break;
- default:
- break;
- }
- }
- /*************************************************************************/
- /* SSP data enable function */
- /*************************************************************************/
- static int ssp_remove_sensor(struct ssp_data *data,
- unsigned int uChangedSensor, unsigned int uNewEnable)
- {
- u8 uBuf[4];
- int64_t dSensorDelay = data->adDelayBuf[uChangedSensor];
- pr_debug("[SSP]: %s - remove sensor = %d, current state = %d\n",
- __func__, (1 << uChangedSensor), uNewEnable);
- data->adDelayBuf[uChangedSensor] = DEFUALT_POLLING_DELAY;
- data->batchLatencyBuf[uChangedSensor] = 0;
- data->batchOptBuf[uChangedSensor] = 0;
- if (uChangedSensor == ORIENTATION_SENSOR) {
- if (!(atomic_read(&data->aSensorEnable)
- & (1 << ACCELEROMETER_SENSOR))) {
- uChangedSensor = ACCELEROMETER_SENSOR;
- } else {
- change_sensor_delay(data, ACCELEROMETER_SENSOR,
- data->adDelayBuf[ACCELEROMETER_SENSOR]);
- return 0;
- }
- } else if (uChangedSensor == ACCELEROMETER_SENSOR) {
- if (atomic_read(&data->aSensorEnable)
- & (1 << ORIENTATION_SENSOR)) {
- change_sensor_delay(data, ORIENTATION_SENSOR,
- data->adDelayBuf[ORIENTATION_SENSOR]);
- return 0;
- }
- }
- if (!data->bSspShutdown)
- if (atomic_read(&data->aSensorEnable) & (1 << uChangedSensor)) {
- s32 dMsDelay = get_msdelay(dSensorDelay);
- memcpy(&uBuf[0], &dMsDelay, 4);
- send_instruction(data, REMOVE_SENSOR, uChangedSensor, uBuf, 4);
- }
- data->aiCheckStatus[uChangedSensor] = NO_SENSOR_STATE;
- return 0;
- }
- /*************************************************************************/
- /* ssp Sysfs */
- /*************************************************************************/
- static ssize_t show_enable_irq(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- ssp_dbg("[SSP]: %s - %d\n", __func__, !data->bSspShutdown);
- return sprintf(buf, "%d\n", !data->bSspShutdown);
- }
- static ssize_t set_enable_irq(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- u8 dTemp;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtou8(buf, 10, &dTemp) < 0)
- return -1;
- pr_info("[SSP] %s - %d start\n", __func__, dTemp);
- if (dTemp) {
- reset_mcu(data);
- enable_debug_timer(data);
- } else if (!dTemp) {
- disable_debug_timer(data);
- ssp_enable(data, 0);
- } else
- pr_err("[SSP] %s - invalid value\n", __func__);
- pr_info("[SSP] %s - %d end\n", __func__, dTemp);
- return size;
- }
- static ssize_t show_sensors_enable(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- pr_debug("[SSP]: %s - cur_enable = %d\n", __func__,
- atomic_read(&data->aSensorEnable));
- return sprintf(buf, "%9u\n", atomic_read(&data->aSensorEnable));
- }
- static ssize_t set_sensors_enable(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dTemp;
- int iRet;
- unsigned int uNewEnable = 0, uChangedSensor = 0;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dTemp) < 0)
- return -EINVAL;
- uNewEnable = (unsigned int)dTemp;
- ssp_dbg("[SSP]: %s - new_enable = %u, old_enable = %u\n", __func__,
- uNewEnable, atomic_read(&data->aSensorEnable));
- if ((uNewEnable != atomic_read(&data->aSensorEnable)) &&
- !(data->uSensorState & (uNewEnable - atomic_read(&data->aSensorEnable)))) {
- pr_info("[SSP] %s - %u is not connected(sensortate: 0x%x)\n",
- __func__, uNewEnable - atomic_read(&data->aSensorEnable), data->uSensorState);
- return -EINVAL;
- }
- if (uNewEnable == atomic_read(&data->aSensorEnable))
- return size;
- for (uChangedSensor = 0; uChangedSensor < SENSOR_MAX; uChangedSensor++) {
- if ((atomic_read(&data->aSensorEnable) & (1 << uChangedSensor))
- != (uNewEnable & (1 << uChangedSensor))) {
- if (!(uNewEnable & (1 << uChangedSensor))) {
- data->reportedData[uChangedSensor] = false;
- ssp_remove_sensor(data, uChangedSensor,
- uNewEnable); /* disable */
- } else { /* Change to ADD_SENSOR_STATE from KitKat */
- if (data->aiCheckStatus[uChangedSensor] == INITIALIZATION_STATE) {
- if (uChangedSensor == ACCELEROMETER_SENSOR) {
- accel_open_calibration(data);
- iRet = set_accel_cal(data);
- if (iRet < 0)
- pr_err("[SSP]: %s - set_accel_cal failed %d\n", __func__, iRet);
- }
- else if (uChangedSensor == GYROSCOPE_SENSOR) {
- gyro_open_calibration(data);
- iRet = set_gyro_cal(data);
- if (iRet < 0)
- pr_err("[SSP]: %s - set_gyro_cal failed %d\n", __func__, iRet);
- }
- else if (uChangedSensor == PRESSURE_SENSOR)
- pressure_open_calibration(data);
- else if (uChangedSensor == PROXIMITY_SENSOR) {
- proximity_open_lcd_ldi(data);
- proximity_open_calibration(data);
- set_proximity_threshold(data, data->uProxHiThresh, data->uProxLoThresh);
- }
- }
- data->aiCheckStatus[uChangedSensor] = ADD_SENSOR_STATE;
- enable_sensor(data, uChangedSensor, data->adDelayBuf[uChangedSensor]);
- }
- break;
- }
- }
- atomic_set(&data->aSensorEnable, uNewEnable);
- return size;
- }
- static ssize_t set_flush(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dTemp;
- u8 sensor_type = 0;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dTemp) < 0)
- return -EINVAL;
- sensor_type = (u8)dTemp;
- if (!(atomic_read(&data->aSensorEnable) & (1 << sensor_type)))
- return -EINVAL;
- if (flush(data, sensor_type) < 0) {
- pr_err("[SSP] ssp returns error for flush(%x)", sensor_type);
- return -EINVAL;
- }
- return size;
- }
- static ssize_t show_acc_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[ACCELEROMETER_SENSOR]);
- }
- static ssize_t set_acc_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- if ((atomic_read(&data->aSensorEnable) & (1 << ORIENTATION_SENSOR)) &&
- (data->adDelayBuf[ORIENTATION_SENSOR] < dNewDelay))
- data->adDelayBuf[ACCELEROMETER_SENSOR] = dNewDelay;
- else
- change_sensor_delay(data, ACCELEROMETER_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_gyro_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GYROSCOPE_SENSOR]);
- }
- static ssize_t set_gyro_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GYROSCOPE_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_mag_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GEOMAGNETIC_SENSOR]);
- }
- static ssize_t set_mag_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GEOMAGNETIC_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_uncal_mag_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GEOMAGNETIC_UNCALIB_SENSOR]);
- }
- static ssize_t set_uncal_mag_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GEOMAGNETIC_UNCALIB_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_rot_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[ROTATION_VECTOR]);
- }
- static ssize_t set_rot_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, ROTATION_VECTOR, dNewDelay);
- return size;
- }
- static ssize_t show_game_rot_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GAME_ROTATION_VECTOR]);
- }
- static ssize_t set_game_rot_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GAME_ROTATION_VECTOR, dNewDelay);
- return size;
- }
- static ssize_t show_step_det_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n",
- data->adDelayBuf[STEP_DETECTOR]);
- }
- static ssize_t set_step_det_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -1;
- change_sensor_delay(data, STEP_DETECTOR, dNewDelay);
- return size;
- }
- static ssize_t show_sig_motion_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n",
- data->adDelayBuf[SIG_MOTION_SENSOR]);
- }
- static ssize_t set_sig_motion_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -1;
- change_sensor_delay(data, SIG_MOTION_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_step_cnt_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n",
- data->adDelayBuf[STEP_COUNTER]);
- }
- static ssize_t set_step_cnt_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -1;
- change_sensor_delay(data, STEP_COUNTER, dNewDelay);
- return size;
- }
- static ssize_t show_uncalib_gyro_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GYRO_UNCALIB_SENSOR]);
- }
- static ssize_t set_uncalib_gyro_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GYRO_UNCALIB_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_pressure_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[PRESSURE_SENSOR]);
- }
- static ssize_t set_pressure_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, PRESSURE_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_gesture_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[GESTURE_SENSOR]);
- }
- static ssize_t set_gesture_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, GESTURE_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_light_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[LIGHT_SENSOR]);
- }
- static ssize_t set_light_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, LIGHT_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_prox_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n", data->adDelayBuf[PROXIMITY_SENSOR]);
- }
- static ssize_t set_prox_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, PROXIMITY_SENSOR, dNewDelay);
- return size;
- }
- static ssize_t show_temp_humi_delay(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%lld\n",
- data->adDelayBuf[TEMPERATURE_HUMIDITY_SENSOR]);
- }
- static ssize_t set_temp_humi_delay(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t size)
- {
- int64_t dNewDelay;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (kstrtoll(buf, 10, &dNewDelay) < 0)
- return -EINVAL;
- change_sensor_delay(data, TEMPERATURE_HUMIDITY_SENSOR, dNewDelay);
- return size;
- }
- ssize_t ssp_sensorhub_voicel_pcmdump_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- int status = ssp_sensorhub_pcm_dump(data->hub_data);
- return sprintf(buf, "%s\n", (status ? "OK" : "NG"));
- }
- static DEVICE_ATTR(voice_pcmdump, S_IRUGO, ssp_sensorhub_voicel_pcmdump_show, NULL);
- static struct device_attribute *voice_attrs[] = {
- &dev_attr_voice_pcmdump,
- NULL,
- };
- static void initialize_voice_sysfs(struct ssp_data *data)
- {
- sensors_register(data->voice_device, data, voice_attrs, "ssp_voice");
- }
- static void remove_voice_sysfs(struct ssp_data *data)
- {
- sensors_unregister(data->voice_device, voice_attrs);
- }
- static DEVICE_ATTR(mcu_rev, S_IRUGO, mcu_revision_show, NULL);
- static DEVICE_ATTR(mcu_name, S_IRUGO, mcu_model_name_show, NULL);
- static DEVICE_ATTR(mcu_update, S_IRUGO, mcu_update_kernel_bin_show, NULL);
- static DEVICE_ATTR(mcu_update2, S_IRUGO,
- mcu_update_kernel_crashed_bin_show, NULL);
- static DEVICE_ATTR(mcu_update_ums, S_IRUGO, mcu_update_ums_bin_show, NULL);
- static DEVICE_ATTR(mcu_reset, S_IRUGO, mcu_reset_show, NULL);
- static DEVICE_ATTR(mcu_dump, S_IRUGO, mcu_dump_show, NULL);
- static DEVICE_ATTR(mcu_test, S_IRUGO | S_IWUSR | S_IWGRP,
- mcu_factorytest_show, mcu_factorytest_store);
- static DEVICE_ATTR(mcu_sleep_test, S_IRUGO | S_IWUSR | S_IWGRP,
- mcu_sleep_factorytest_show, mcu_sleep_factorytest_store);
- static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
- show_sensors_enable, set_sensors_enable);
- static DEVICE_ATTR(enable_irq, S_IRUGO | S_IWUSR | S_IWGRP,
- show_enable_irq, set_enable_irq);
- static DEVICE_ATTR(rot_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_rot_delay, set_rot_delay);
- static DEVICE_ATTR(game_rot_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_game_rot_delay, set_game_rot_delay);
- static DEVICE_ATTR(step_det_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_step_det_delay, set_step_det_delay);
- static DEVICE_ATTR(pressure_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_pressure_delay, set_pressure_delay);
- static DEVICE_ATTR(accel_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_acc_delay, set_acc_delay);
- static DEVICE_ATTR(gyro_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_gyro_delay, set_gyro_delay);
- static DEVICE_ATTR(uncalib_gyro_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_uncalib_gyro_delay, set_uncalib_gyro_delay);
- static DEVICE_ATTR(mag_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_mag_delay, set_mag_delay);
- static DEVICE_ATTR(uncal_mag_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_uncal_mag_delay, set_uncal_mag_delay);
- static DEVICE_ATTR(ssp_flush, S_IWUSR | S_IWGRP,
- NULL, set_flush);
- static struct device_attribute dev_attr_gesture_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_gesture_delay, set_gesture_delay);
- static struct device_attribute dev_attr_light_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_light_delay, set_light_delay);
- static struct device_attribute dev_attr_prox_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_prox_delay, set_prox_delay);
- static struct device_attribute dev_attr_temp_humi_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_temp_humi_delay, set_temp_humi_delay);
- static struct device_attribute dev_attr_sig_motion_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_sig_motion_delay, set_sig_motion_delay);
- static struct device_attribute dev_attr_step_cnt_poll_delay
- = __ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
- show_step_cnt_delay, set_step_cnt_delay);
- static struct device_attribute *mcu_attrs[] = {
- &dev_attr_enable,
- &dev_attr_mcu_rev,
- &dev_attr_mcu_name,
- &dev_attr_mcu_test,
- &dev_attr_mcu_reset,
- &dev_attr_mcu_dump,
- &dev_attr_mcu_update,
- &dev_attr_mcu_update2,
- &dev_attr_mcu_update_ums,
- &dev_attr_mcu_sleep_test,
- &dev_attr_enable_irq,
- &dev_attr_accel_poll_delay,
- &dev_attr_mag_poll_delay,
- &dev_attr_uncal_mag_poll_delay,
- &dev_attr_gyro_poll_delay,
- &dev_attr_uncalib_gyro_poll_delay,
- &dev_attr_rot_poll_delay,
- &dev_attr_game_rot_poll_delay,
- &dev_attr_step_det_poll_delay,
- &dev_attr_pressure_poll_delay,
- &dev_attr_ssp_flush,
- NULL,
- };
- static long ssp_batch_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
- {
- struct ssp_data *data
- = container_of(file->private_data,
- struct ssp_data, batch_io_device);
- struct batch_config batch;
- void __user *argp = (void __user *)arg;
- int retries = 2;
- int ret = 0;
- int sensor_type, ms_delay;
- int timeout_ms = 0;
- u8 uBuf[9];
- sensor_type = (cmd & 0xFF);
- if ((cmd >> 8 & 0xFF) != BATCH_IOCTL_MAGIC) {
- pr_err("[SSP] Invalid BATCH CMD %x", cmd);
- return -EINVAL;
- }
- while (retries--) {
- ret = copy_from_user(&batch, argp, sizeof(batch));
- if (likely(!ret))
- break;
- }
- if (unlikely(ret)) {
- pr_err("[SSP] batch ioctl err(%d)", ret);
- return -EINVAL;
- }
- ms_delay = get_msdelay(batch.delay);
- timeout_ms = div_s64(batch.timeout, 1000000);
- memcpy(&uBuf[0], &ms_delay, 4);
- memcpy(&uBuf[4], &timeout_ms, 4);
- uBuf[8] = batch.flag;
- if (batch.timeout){ /* add or dry */
- if(!(batch.flag & SENSORS_BATCH_DRY_RUN)) { /* real batch, NOT DRY, change delay */
- ret = 1;
- /* if sensor is not running state, enable will be called.
- MCU return fail when receive chage delay inst during NO_SENSOR STATE */
- if (data->aiCheckStatus[sensor_type] == RUNNING_SENSOR_STATE) {
- ret = send_instruction_sync(data, CHANGE_DELAY, sensor_type, uBuf, 9);
- }
- if (ret > 0) { // ret 1 is success
- data->batchOptBuf[sensor_type] = (u8)batch.flag;
- data->batchLatencyBuf[sensor_type] = timeout_ms;
- data->adDelayBuf[sensor_type] = batch.delay;
- }
- } else { /* real batch, DRY RUN */
- ret = send_instruction_sync(data, CHANGE_DELAY, sensor_type, uBuf, 9);
- if (ret > 0) { // ret 1 is success
- data->batchOptBuf[sensor_type] = (u8)batch.flag;
- data->batchLatencyBuf[sensor_type] = timeout_ms;
- data->adDelayBuf[sensor_type] = batch.delay;
- }
- }
- } else { /* remove batch or normal change delay, remove or add will be called. */
- if (!(batch.flag & SENSORS_BATCH_DRY_RUN)) { /* no batch, NOT DRY, change delay */
- data->batchOptBuf[sensor_type] = 0;
- data->batchLatencyBuf[sensor_type] = 0;
- data->adDelayBuf[sensor_type] = batch.delay;
- if (data->aiCheckStatus[sensor_type] == RUNNING_SENSOR_STATE) {
- send_instruction(data, CHANGE_DELAY, sensor_type, uBuf, 9);
- }
- }
- }
- pr_info("[SSP] batch %d: delay %lld, timeout %lld, flag %d, ret %d",
- sensor_type, batch.delay, batch.timeout, batch.flag, ret);
- if (!batch.timeout)
- return 0;
- if (ret <= 0)
- return -EINVAL;
- else
- return 0;
- }
- static struct file_operations ssp_batch_fops = {
- .owner = THIS_MODULE,
- .open = nonseekable_open,
- .unlocked_ioctl = ssp_batch_ioctl,
- };
- static void initialize_mcu_factorytest(struct ssp_data *data)
- {
- sensors_register(data->mcu_device, data, mcu_attrs, "ssp_sensor");
- }
- static void remove_mcu_factorytest(struct ssp_data *data)
- {
- sensors_unregister(data->mcu_device, mcu_attrs);
- }
- int initialize_sysfs(struct ssp_data *data)
- {
- if (device_create_file(&data->gesture_input_dev->dev,
- &dev_attr_gesture_poll_delay))
- goto err_gesture_input_dev;
- if (device_create_file(&data->light_input_dev->dev,
- &dev_attr_light_poll_delay))
- goto err_light_input_dev;
- if (device_create_file(&data->prox_input_dev->dev,
- &dev_attr_prox_poll_delay))
- goto err_prox_input_dev;
- if (device_create_file(&data->temp_humi_input_dev->dev,
- &dev_attr_temp_humi_poll_delay))
- goto err_temp_humi_input_dev;
- if (device_create_file(&data->sig_motion_input_dev->dev,
- &dev_attr_sig_motion_poll_delay))
- goto err_sig_motion_input_dev;
- if (device_create_file(&data->step_cnt_input_dev->dev,
- &dev_attr_step_cnt_poll_delay))
- goto err_step_cnt_input_dev;
- data->batch_io_device.minor = MISC_DYNAMIC_MINOR;
- data->batch_io_device.name = "batch_io";
- data->batch_io_device.fops = &ssp_batch_fops;
- if (misc_register(&data->batch_io_device))
- goto err_batch_io_dev;
- initialize_accel_factorytest(data);
- initialize_gyro_factorytest(data);
- initialize_prox_factorytest(data);
- initialize_light_factorytest(data);
- initialize_pressure_factorytest(data);
- initialize_magnetic_factorytest(data);
- initialize_mcu_factorytest(data);
- initialize_gesture_factorytest(data);
- #ifdef CONFIG_SENSORS_SSP_SHTC1
- initialize_temphumidity_factorytest(data);
- #endif
- #ifdef CONFIG_SENSORS_SSP_MOBEAM
- initialize_mobeam(data);
- #endif
- /*snamy.jeong_0630 voice dump & data*/
- initialize_voice_sysfs(data);
- return SUCCESS;
- err_batch_io_dev:
- device_remove_file(&data->step_cnt_input_dev->dev,
- &dev_attr_step_cnt_poll_delay);
- err_step_cnt_input_dev:
- device_remove_file(&data->sig_motion_input_dev->dev,
- &dev_attr_sig_motion_poll_delay);
- err_sig_motion_input_dev:
- device_remove_file(&data->temp_humi_input_dev->dev,
- &dev_attr_temp_humi_poll_delay);
- err_temp_humi_input_dev:
- device_remove_file(&data->prox_input_dev->dev,
- &dev_attr_prox_poll_delay);
- err_prox_input_dev:
- device_remove_file(&data->light_input_dev->dev,
- &dev_attr_light_poll_delay);
- err_light_input_dev:
- device_remove_file(&data->gesture_input_dev->dev,
- &dev_attr_gesture_poll_delay);
- err_gesture_input_dev:
- pr_err("[SSP] error init sysfs");
- return ERROR;
- }
- void remove_sysfs(struct ssp_data *data)
- {
- device_remove_file(&data->gesture_input_dev->dev,
- &dev_attr_gesture_poll_delay);
- device_remove_file(&data->light_input_dev->dev,
- &dev_attr_light_poll_delay);
- device_remove_file(&data->prox_input_dev->dev,
- &dev_attr_prox_poll_delay);
- device_remove_file(&data->temp_humi_input_dev->dev,
- &dev_attr_temp_humi_poll_delay);
- device_remove_file(&data->sig_motion_input_dev->dev,
- &dev_attr_sig_motion_poll_delay);
- device_remove_file(&data->step_cnt_input_dev->dev,
- &dev_attr_step_cnt_poll_delay);
- ssp_batch_fops.unlocked_ioctl = NULL;
- misc_deregister(&data->batch_io_device);
- remove_accel_factorytest(data);
- remove_gyro_factorytest(data);
- remove_prox_factorytest(data);
- remove_light_factorytest(data);
- remove_pressure_factorytest(data);
- remove_magnetic_factorytest(data);
- remove_mcu_factorytest(data);
- remove_gesture_factorytest(data);
- #ifdef CONFIG_SENSORS_SSP_SHTC1
- remove_temphumidity_factorytest(data);
- #endif
- #ifdef CONFIG_SENSORS_SSP_MOBEAM
- remove_mobeam(data);
- #endif
- /*snamy.jeong_0630 voice dump & data*/
- remove_voice_sysfs(data);
- destroy_sensor_class();
- }
|