summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGao Pan <gaopan@freescale.com>2015-07-03 16:31:38 +0800
committerGao Pan <gaopan@freescale.com>2015-07-03 17:07:05 +0800
commit74c9af0a5806fb5c926ffdab3145fc1680fc87e6 (patch)
treed238750666e858267524b142f386c30893737ddf
parent37408077c7fd1ccae0b5f89afd632756b2cd3c67 (diff)
MLK-11218: misc: fxos8700: support ±2g/±4g/±8g dynamically
Support ±2g/±4g/±8g dynamically selection for motion sensor fxos8700. Set the sensor mode to standby mode before changing the scale range with the command "echo 0 > enable". The scale range can be changed with the command "echo 0/1/2 > range". Signed-off-by: Gao Pan <b54642@freescale.com>
-rw-r--r--drivers/misc/fxos8700.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/misc/fxos8700.c b/drivers/misc/fxos8700.c
index da517ccf9bad..558f67f9f850 100644
--- a/drivers/misc/fxos8700.c
+++ b/drivers/misc/fxos8700.c
@@ -188,6 +188,8 @@
#define FXOS8700_POLL_MAX 800
#define FXOS8700_POLL_MIN 100
+enum { MODE_2G = 0, MODE_4G, MODE_8G,
+};
struct fxos8700_data_axis {
short x;
@@ -207,6 +209,7 @@ struct fxos8700_data {
atomic_t mag_active_poll;
atomic_t mag_active;
atomic_t position;
+ atomic_t range;
};
static struct fxos8700_data *g_fxos8700_data;
@@ -264,6 +267,14 @@ static int fxos8700_change_mode(struct i2c_client *client, int type, int active)
return 0;
}
+static int fxos8700_change_range(struct i2c_client *client, int range)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, FXOS8700_XYZ_DATA_CFG, range);
+
+ return ret;
+}
static int fxos8700_set_odr(struct i2c_client *client, int type, int delay)
{
return 0;
@@ -287,10 +298,15 @@ static int fxos8700_device_init(struct i2c_client *client)
result = i2c_smbus_write_byte_data(client, FXOS8700_CTRL_REG1, 0x03 << 3);
if (result < 0)
goto out;
+ result = i2c_smbus_write_byte_data(client, FXOS8700_XYZ_DATA_CFG,
+ MODE_2G);
+ if (result < 0)
+ goto out;
atomic_set(&pdata->acc_active, FXOS8700_STANDBY);
atomic_set(&pdata->mag_active, FXOS8700_STANDBY);
atomic_set(&pdata->position, FXOS8700_POSITION_DEFAULT);
+ atomic_set(&pdata->range, MODE_2G);
return 0;
out:
dev_err(&client->dev, "Error when init fxos8700 device:(%d)", result);
@@ -652,14 +668,49 @@ static ssize_t fxos8700_position_store(struct device *dev,
return count;
}
+static ssize_t fxos8700_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ unsigned long range = atomic_read(&pdata->range);
+
+ return sprintf(buf, "%ld\n", range);
+}
+
+static ssize_t fxos8700_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long range;
+ struct fxos8700_data *pdata = g_fxos8700_data;
+ struct i2c_client *client = pdata->client;
+ int ret;
+
+ if (kstrtoul(buf, 10, &range) < 0)
+ return -EINVAL;
+
+ if (range == atomic_read(&pdata->range))
+ return count;
+
+ if (atomic_read(&pdata->acc_active) | atomic_read(&pdata->mag_active))
+ printk(KERN_INFO "Pls set the sensor standby and then actived\n");
+ ret = fxos8700_change_range(client, range);
+ if (!ret)
+ atomic_set(&pdata->range, range);
+
+ return count;
+}
+
static DEVICE_ATTR(enable, 0666, fxos8700_enable_show, fxos8700_enable_store);
static DEVICE_ATTR(poll_delay, 0666, fxos8700_poll_delay_show, fxos8700_poll_delay_store);
static DEVICE_ATTR(position, 0666, fxos8700_position_show, fxos8700_position_store);
+static DEVICE_ATTR(range, 0666, fxos8700_range_show, fxos8700_range_store);
static struct attribute *fxos8700_attributes[] = {
&dev_attr_enable.attr,
&dev_attr_poll_delay.attr,
&dev_attr_position.attr,
+ &dev_attr_range.attr,
NULL
};