aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sensorhub/factory/pressure_bmp182.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sensorhub/factory/pressure_bmp182.c')
-rw-r--r--drivers/sensorhub/factory/pressure_bmp182.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/drivers/sensorhub/factory/pressure_bmp182.c b/drivers/sensorhub/factory/pressure_bmp182.c
new file mode 100644
index 0000000..b3d580a
--- /dev/null
+++ b/drivers/sensorhub/factory/pressure_bmp182.c
@@ -0,0 +1,190 @@
+/*
+ * 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"
+
+#define VENDOR "BOSCH"
+#define CHIP_ID "BMP180"
+
+#define CALIBRATION_FILE_PATH "/efs/FactoryApp/baro_delta"
+
+#define PR_ABS_MAX 8388607 /* 24 bit 2'compl */
+#define PR_ABS_MIN -8388608
+
+/*************************************************************************/
+/* factory Sysfs */
+/*************************************************************************/
+
+static ssize_t sea_level_pressure_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct ssp_data *data = dev_get_drvdata(dev);
+ int iNewSeaLevelPressure;
+
+ sscanf(buf, "%d", &iNewSeaLevelPressure);
+
+ if (iNewSeaLevelPressure == 0) {
+ pr_info("%s, our->temperature = 0\n", __func__);
+ iNewSeaLevelPressure = -1;
+ }
+
+ input_report_rel(data->pressure_input_dev, REL_DIAL,
+ iNewSeaLevelPressure);
+ input_sync(data->pressure_input_dev);
+
+ return size;
+}
+
+int pressure_open_calibration(struct ssp_data *data)
+{
+ char chBuf[10] = {0,};
+ int iErr = 0;
+ mm_segment_t old_fs;
+ struct file *cal_filp = NULL;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
+ if (IS_ERR(cal_filp)) {
+ iErr = PTR_ERR(cal_filp);
+ if (iErr != -ENOENT)
+ pr_err("[SSP]: %s - Can't open calibration file(%d)\n",
+ __func__, iErr);
+ set_fs(old_fs);
+ return iErr;
+ }
+ iErr = cal_filp->f_op->read(cal_filp,
+ chBuf, 10 * sizeof(char), &cal_filp->f_pos);
+ if (iErr < 0) {
+ pr_err("[SSP]: %s - Can't read the cal data from file (%d)\n",
+ __func__, iErr);
+ return iErr;
+ }
+ filp_close(cal_filp, current->files);
+ set_fs(old_fs);
+
+ iErr = kstrtoint(chBuf, 10, &data->iPressureCal);
+ if (iErr < 0) {
+ pr_err("[SSP]: %s - kstrtoint failed. %d", __func__, iErr);
+ return iErr;
+ }
+
+ ssp_dbg("[SSP]: open barometer calibration %d\n", data->iPressureCal);
+
+ if (data->iPressureCal < PR_ABS_MIN || data->iPressureCal > PR_ABS_MAX)
+ pr_err("[SSP]: %s - wrong offset value!!!\n", __func__);
+
+ return iErr;
+}
+
+static ssize_t pressure_cabratioin_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct ssp_data *data = dev_get_drvdata(dev);
+ int iPressureCal = 0, iErr = 0;
+
+ iErr = kstrtoint(buf, 10, &iPressureCal);
+ if (iErr < 0) {
+ pr_err("[SSP]: %s - kstrtoint failed.(%d)", __func__, iErr);
+ return iErr;
+ }
+
+ if (iPressureCal < PR_ABS_MIN || iPressureCal > PR_ABS_MAX)
+ return -EINVAL;
+
+ data->iPressureCal = (s32)iPressureCal;
+
+ return size;
+}
+
+static ssize_t pressure_cabratioin_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ssp_data *data = dev_get_drvdata(dev);
+
+ pressure_open_calibration(data);
+
+ return sprintf(buf, "%d\n", data->iPressureCal);
+}
+
+static ssize_t eeprom_check_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ bool bSuccess = false;
+ char chTempBuf[2] = {0, 10};
+ int iRet, iDelayCnt = 0;
+ struct ssp_data *data = dev_get_drvdata(dev);
+
+ data->uFactorydataReady = 0;
+ memset(data->uFactorydata, 0, sizeof(char) * FACTORY_DATA_MAX);
+
+ iRet = send_instruction(data, FACTORY_MODE, PRESSURE_FACTORY,
+ chTempBuf, 2);
+
+ while (!(data->uFactorydataReady & (1 << PRESSURE_FACTORY))
+ && (iDelayCnt++ < 150)
+ && (iRet == SUCCESS))
+ msleep(20);
+
+ if ((iDelayCnt >= 150) || (iRet != SUCCESS)) {
+ pr_err("[SSP]: %s - Pressure Selftest Timeout!!\n",
+ __func__);
+ goto exit;
+ }
+
+ bSuccess = (bool)(!!data->uFactorydata[0]);
+ ssp_dbg("[SSP]: %s - %u\n", __func__, bSuccess);
+
+exit:
+ return snprintf(buf, PAGE_SIZE, "%d", bSuccess);
+}
+
+/* sysfs for vendor & name */
+static ssize_t pressure_vendor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", VENDOR);
+}
+
+static ssize_t pressure_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", CHIP_ID);
+}
+
+static DEVICE_ATTR(vendor, S_IRUGO, pressure_vendor_show, NULL);
+static DEVICE_ATTR(name, S_IRUGO, pressure_name_show, NULL);
+static DEVICE_ATTR(eeprom_check, S_IRUGO, eeprom_check_show, NULL);
+static DEVICE_ATTR(calibration, S_IRUGO | S_IWUSR | S_IWGRP,
+ pressure_cabratioin_show, pressure_cabratioin_store);
+static DEVICE_ATTR(sea_level_pressure, S_IRUGO | S_IWUSR | S_IWGRP,
+ NULL, sea_level_pressure_store);
+
+static struct device_attribute *pressure_attrs[] = {
+ &dev_attr_vendor,
+ &dev_attr_name,
+ &dev_attr_calibration,
+ &dev_attr_sea_level_pressure,
+ &dev_attr_eeprom_check,
+ NULL,
+};
+
+void initialize_pressure_factorytest(struct ssp_data *data)
+{
+ struct device *pressure_device = NULL;
+
+ sensors_register(pressure_device, data, pressure_attrs,
+ "barometer_sensor");
+}