diff options
author | Gao Pan <gaopan@freescale.com> | 2015-07-03 16:31:38 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-23 16:42:31 +0300 |
commit | c389f8252427f5f96b3a53c3c802bea7a12e854c (patch) | |
tree | ca8c890493e2813e72278d3a1bae5411d13a718a /drivers/misc | |
parent | 7347740ac10fcad9be5eb61dbc0c0a907965a85d (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>
Signed-off-by: Fugang Duan <B38611@freescale.com>
(cherry picked from commit: 74c9af0a5806fb5c926ffdab3145fc1680fc87e6)
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/fxos8700.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/misc/fxos8700.c b/drivers/misc/fxos8700.c index fdd936cb1fcc..326e2accde1b 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, S_IWUSR | S_IRUGO, fxos8700_enable_show, fxos8700_enable_store); static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO, fxos8700_poll_delay_show, fxos8700_poll_delay_store); static DEVICE_ATTR(position, S_IWUSR | S_IRUGO, fxos8700_position_show, fxos8700_position_store); +static DEVICE_ATTR(range, S_IWUSR | S_IRUGO, 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 }; |