* [PATCH 00/13] iio:bma180: Fixes and BMA250 support
@ 2014-07-16 18:32 Peter Meerwald
2014-07-16 18:32 ` [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units Peter Meerwald
` (12 more replies)
0 siblings, 13 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23
Hello,
patches 1 and 2 are fixes
patch 3 allows to use the device without an IRQ
patches 4, 5, 6 are cleanup
patch 7 exposes the temperature channel not supported previously
patch 8, 9, 10, 11, 12 rework the driver to make it easier to add similar devices
patch 13 adds support for the BMA250 sensor
the BMA250 shared measurement registers with the BMA180, but the configuration
registers are totally different
regards, p.
Peter Meerwald (13):
iio:bma180: Fix scale factors to report correct acceleration units
iio:bma180: Missing check for frequency fractional part
iio:bma180: Enable use of device without IRQ
iio:bma180: Prefix remaining tables and functions with bma18_
iio:bma180: Rename BMA_180 to BMA180_
iio:bma180: Use bool instead of int for state
iio:bma180: Expose temperature channel
iio:bma180: Drop _update_scan_mode()
iio:bma180: Introduce part_info to differentiate further chip variants
iio:bma180: Introduce part-specific _config() and disable() code
iio:bma180: Prepare for accelerometer channels with different
resolutions
iio:bma180: Implement _available sysfs attribute dynamically
iio:bma180: Add BMA250 chip support
drivers/iio/accel/bma180.c | 477 +++++++++++++++++++++++++++++++--------------
1 file changed, 329 insertions(+), 148 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-20 16:39 ` Jonathan Cameron
2014-07-16 18:32 ` [PATCH 02/13] iio:bma180: Missing check for frequency fractional part Peter Meerwald
` (11 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
The userspace interface for acceleration sensors is documented as using
m/s^2 units [Documentation/ABI/testing/sysfs-bus-iio]
The fullscale raw values for the BMA80 corresponds to -/+ 1, 1.5, 2, etc G
depending on the selected mode.
The scale table was converting to G rather than m/s^2.
Change the scaling table to match the documented interface.
See commit 71702e6e, iio: mma8452: Use correct acceleration units,
for a related fix.
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index a7e68c8..28388bb 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -68,13 +68,13 @@
/* Defaults values */
#define BMA180_DEF_PMODE 0
#define BMA180_DEF_BW 20
-#define BMA180_DEF_SCALE 250
+#define BMA180_DEF_SCALE 2452
/* Available values for sysfs */
#define BMA180_FLP_FREQ_AVAILABLE \
"10 20 40 75 150 300"
#define BMA180_SCALE_AVAILABLE \
- "0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
+ "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"
struct bma180_data {
struct i2c_client *client;
@@ -94,7 +94,7 @@ enum bma180_axis {
};
static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
-static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
+static int scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
{
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/13] iio:bma180: Missing check for frequency fractional part
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
2014-07-16 18:32 ` [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-20 16:41 ` Jonathan Cameron
2014-07-16 18:32 ` [PATCH 03/13] iio:bma180: Enable use of device without IRQ Peter Meerwald
` (10 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
val2 should be zero
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 28388bb..a077cc8 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -376,6 +376,8 @@ static int bma180_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&data->mutex);
return ret;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+ if (val2)
+ return -EINVAL;
mutex_lock(&data->mutex);
ret = bma180_set_bw(data, val);
mutex_unlock(&data->mutex);
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/13] iio:bma180: Enable use of device without IRQ
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
2014-07-16 18:32 ` [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units Peter Meerwald
2014-07-16 18:32 ` [PATCH 02/13] iio:bma180: Missing check for frequency fractional part Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 04/13] iio:bma180: Prefix remaining tables and functions with bma18_ Peter Meerwald
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 54 +++++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 25 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index a077cc8..f5e26fb 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -529,7 +529,6 @@ static int bma180_probe(struct i2c_client *client,
{
struct bma180_data *data;
struct iio_dev *indio_dev;
- struct iio_trigger *trig;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
@@ -553,29 +552,31 @@ static int bma180_probe(struct i2c_client *client,
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &bma180_info;
- trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id);
- if (!trig) {
- ret = -ENOMEM;
- goto err_chip_disable;
- }
+ if (client->irq > 0) {
+ data->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
+ indio_dev->id);
+ if (!data->trig) {
+ ret = -ENOMEM;
+ goto err_chip_disable;
+ }
- ret = devm_request_irq(&client->dev, client->irq,
- iio_trigger_generic_data_rdy_poll,
- IRQF_TRIGGER_RISING, BMA180_IRQ_NAME, trig);
- if (ret) {
- dev_err(&client->dev, "unable to request IRQ\n");
- goto err_trigger_free;
- }
+ ret = devm_request_irq(&client->dev, client->irq,
+ iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING,
+ BMA180_IRQ_NAME, data->trig);
+ if (ret) {
+ dev_err(&client->dev, "unable to request IRQ\n");
+ goto err_trigger_free;
+ }
- trig->dev.parent = &client->dev;
- trig->ops = &bma180_trigger_ops;
- iio_trigger_set_drvdata(trig, indio_dev);
- data->trig = trig;
- indio_dev->trig = trig;
+ data->trig->dev.parent = &client->dev;
+ data->trig->ops = &bma180_trigger_ops;
+ iio_trigger_set_drvdata(data->trig, indio_dev);
+ indio_dev->trig = data->trig;
- ret = iio_trigger_register(trig);
- if (ret)
- goto err_trigger_free;
+ ret = iio_trigger_register(data->trig);
+ if (ret)
+ goto err_trigger_free;
+ }
ret = iio_triggered_buffer_setup(indio_dev, NULL,
bma180_trigger_handler, NULL);
@@ -595,9 +596,10 @@ static int bma180_probe(struct i2c_client *client,
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_trigger_unregister:
- iio_trigger_unregister(trig);
+ if (data->trig)
+ iio_trigger_unregister(data->trig);
err_trigger_free:
- iio_trigger_free(trig);
+ iio_trigger_free(data->trig);
err_chip_disable:
bma180_chip_disable(data);
@@ -611,8 +613,10 @@ static int bma180_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
- iio_trigger_unregister(data->trig);
- iio_trigger_free(data->trig);
+ if (data->trig) {
+ iio_trigger_unregister(data->trig);
+ iio_trigger_free(data->trig);
+ }
mutex_lock(&data->mutex);
bma180_chip_disable(data);
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/13] iio:bma180: Prefix remaining tables and functions with bma18_
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (2 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 03/13] iio:bma180: Enable use of device without IRQ Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 05/13] iio:bma180: Rename BMA_180 to BMA180_ Peter Meerwald
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
and minor cleanups
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index f5e26fb..d7f34b4 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -49,7 +49,7 @@
#define BMA180_SMP_SKIP BIT(0)
/* Bit masks for registers bit fields */
-#define BMA180_RANGE 0x0e /* Range of measured accel values*/
+#define BMA180_RANGE 0x0e /* Range of measured accel values */
#define BMA180_BW 0xf0 /* Accel bandwidth */
#define BMA180_MODE_CONFIG 0x03 /* Config operation modes */
@@ -93,8 +93,8 @@ enum bma180_axis {
AXIS_Z,
};
-static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
-static int scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
+static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
+static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
{
@@ -107,7 +107,7 @@ static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
ret = i2c_smbus_read_word_data(data->client, reg);
if (ret < 0)
dev_err(&data->client->dev,
- "failed to read accel_%c registers\n", 'x' + axis);
+ "failed to read accel_%c register\n", 'x' + axis);
return ret;
}
@@ -185,8 +185,8 @@ static int bma180_set_bw(struct bma180_data *data, int val)
if (data->sleep_state)
return -EBUSY;
- for (i = 0; i < ARRAY_SIZE(bw_table); ++i) {
- if (bw_table[i] == val) {
+ for (i = 0; i < ARRAY_SIZE(bma180_bw_table); ++i) {
+ if (bma180_bw_table[i] == val) {
ret = bma180_set_bits(data,
BMA180_BW_TCS, BMA180_BW, i);
if (ret) {
@@ -209,8 +209,8 @@ static int bma180_set_scale(struct bma180_data *data, int val)
if (data->sleep_state)
return -EBUSY;
- for (i = 0; i < ARRAY_SIZE(scale_table); ++i)
- if (scale_table[i] == val) {
+ for (i = 0; i < ARRAY_SIZE(bma180_scale_table); ++i)
+ if (bma180_scale_table[i] == val) {
ret = bma180_set_bits(data,
BMA180_OFFSET_LSB1, BMA180_RANGE, i);
if (ret) {
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/13] iio:bma180: Rename BMA_180 to BMA180_
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (3 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 04/13] iio:bma180: Prefix remaining tables and functions with bma18_ Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 06/13] iio:bma180: Use bool instead of int for state Peter Meerwald
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index d7f34b4..284598d 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -56,7 +56,7 @@
/* We have to write this value in reset register to do soft reset */
#define BMA180_RESET_VAL 0xb6
-#define BMA_180_ID_REG_VAL 0x03
+#define BMA180_ID_REG_VAL 0x03
/* Chip power modes */
#define BMA180_LOW_NOISE 0x00
@@ -258,7 +258,7 @@ static int bma180_chip_init(struct bma180_data *data)
if (ret < 0)
goto err;
- if (ret != BMA_180_ID_REG_VAL) {
+ if (ret != BMA180_ID_REG_VAL) {
ret = -ENODEV;
goto err;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/13] iio:bma180: Use bool instead of int for state
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (4 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 05/13] iio:bma180: Rename BMA_180 to BMA180_ Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 07/13] iio:bma180: Expose temperature channel Peter Meerwald
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 284598d..aa7566f 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -62,11 +62,8 @@
#define BMA180_LOW_NOISE 0x00
#define BMA180_LOW_POWER 0x03
-#define BMA180_LOW_NOISE_STR "low_noise"
-#define BMA180_LOW_POWER_STR "low_power"
-
/* Defaults values */
-#define BMA180_DEF_PMODE 0
+#define BMA180_DEF_PMODE false
#define BMA180_DEF_BW 20
#define BMA180_DEF_SCALE 2452
@@ -80,10 +77,10 @@ struct bma180_data {
struct i2c_client *client;
struct iio_trigger *trig;
struct mutex mutex;
- int sleep_state;
+ bool sleep_state;
int scale;
int bw;
- int pmode;
+ bool pmode;
char *buff;
};
@@ -133,7 +130,7 @@ static int bma180_reset_intr(struct bma180_data *data)
return ret;
}
-static int bma180_set_new_data_intr_state(struct bma180_data *data, int state)
+static int bma180_set_new_data_intr_state(struct bma180_data *data, bool state)
{
u8 reg_val = state ? BMA180_NEW_DATA_INT : 0x00;
int ret = i2c_smbus_write_byte_data(data->client, BMA180_CTRL_REG3,
@@ -153,7 +150,7 @@ err:
return ret;
}
-static int bma180_set_sleep_state(struct bma180_data *data, int state)
+static int bma180_set_sleep_state(struct bma180_data *data, bool state)
{
int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_SLEEP, state);
@@ -167,7 +164,7 @@ static int bma180_set_sleep_state(struct bma180_data *data, int state)
return 0;
}
-static int bma180_set_ee_writing_state(struct bma180_data *data, int state)
+static int bma180_set_ee_writing_state(struct bma180_data *data, bool state)
{
int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_EE_W, state);
@@ -225,7 +222,7 @@ static int bma180_set_scale(struct bma180_data *data, int val)
return -EINVAL;
}
-static int bma180_set_pmode(struct bma180_data *data, int mode)
+static int bma180_set_pmode(struct bma180_data *data, bool mode)
{
u8 reg_val = mode ? BMA180_LOW_POWER : BMA180_LOW_NOISE;
int ret = bma180_set_bits(data, BMA180_TCO_Z, BMA180_MODE_CONFIG,
@@ -275,10 +272,10 @@ static int bma180_chip_init(struct bma180_data *data)
ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_DIS_WAKE_UP, 1);
if (ret)
goto err;
- ret = bma180_set_ee_writing_state(data, 1);
+ ret = bma180_set_ee_writing_state(data, true);
if (ret)
goto err;
- ret = bma180_set_new_data_intr_state(data, 0);
+ ret = bma180_set_new_data_intr_state(data, false);
if (ret)
goto err;
ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
@@ -303,11 +300,11 @@ err:
static void bma180_chip_disable(struct bma180_data *data)
{
- if (bma180_set_new_data_intr_state(data, 0))
+ if (bma180_set_new_data_intr_state(data, false))
goto err;
- if (bma180_set_ee_writing_state(data, 0))
+ if (bma180_set_ee_writing_state(data, false))
goto err;
- if (bma180_set_sleep_state(data, 1))
+ if (bma180_set_sleep_state(data, true))
goto err;
return;
@@ -410,10 +407,7 @@ static const struct iio_info bma180_info = {
.driver_module = THIS_MODULE,
};
-static const char * const bma180_power_modes[] = {
- BMA180_LOW_NOISE_STR,
- BMA180_LOW_POWER_STR,
-};
+static const char * const bma180_power_modes[] = { "low_noise", "low_power" };
static int bma180_get_power_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
@@ -633,7 +627,7 @@ static int bma180_suspend(struct device *dev)
int ret;
mutex_lock(&data->mutex);
- ret = bma180_set_sleep_state(data, 1);
+ ret = bma180_set_sleep_state(data, true);
mutex_unlock(&data->mutex);
return ret;
@@ -646,7 +640,7 @@ static int bma180_resume(struct device *dev)
int ret;
mutex_lock(&data->mutex);
- ret = bma180_set_sleep_state(data, 0);
+ ret = bma180_set_sleep_state(data, false);
mutex_unlock(&data->mutex);
return ret;
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/13] iio:bma180: Expose temperature channel
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (5 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 06/13] iio:bma180: Use bool instead of int for state Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 08/13] iio:bma180: Drop _update_scan_mode() Peter Meerwald
` (5 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
8-bit signed; 0 LSB @ 24 °C, 0.5 °C per LSB
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 80 ++++++++++++++++++++++++++++++++++------------
1 file changed, 59 insertions(+), 21 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index aa7566f..91260a0 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -29,6 +29,7 @@
/* Register set */
#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */
#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */
+#define BMA180_TEMP 0x08
#define BMA180_CTRL_REG0 0x0d
#define BMA180_RESET 0x10
#define BMA180_BW_TCS 0x20
@@ -84,27 +85,37 @@ struct bma180_data {
char *buff;
};
-enum bma180_axis {
+enum bma180_chan {
AXIS_X,
AXIS_Y,
AXIS_Z,
+ TEMP
};
static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
-static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
+static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
{
- u8 reg = BMA180_ACC_X_LSB + axis * 2;
int ret;
if (data->sleep_state)
return -EBUSY;
- ret = i2c_smbus_read_word_data(data->client, reg);
- if (ret < 0)
- dev_err(&data->client->dev,
- "failed to read accel_%c register\n", 'x' + axis);
+ switch (chan) {
+ case TEMP:
+ ret = i2c_smbus_read_byte_data(data->client, BMA180_TEMP);
+ if (ret < 0)
+ dev_err(&data->client->dev, "failed to read temp register\n");
+ break;
+ default:
+ ret = i2c_smbus_read_word_data(data->client,
+ BMA180_ACC_X_LSB + chan * 2);
+ if (ret < 0)
+ dev_err(&data->client->dev,
+ "failed to read accel_%c register\n",
+ 'x' + chan);
+ }
return ret;
}
@@ -337,22 +348,35 @@ static int bma180_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&data->mutex);
- if (iio_buffer_enabled(indio_dev))
- ret = -EBUSY;
- else
- ret = bma180_get_acc_reg(data, chan->scan_index);
+ if (iio_buffer_enabled(indio_dev)) {
+ mutex_unlock(&data->mutex);
+ return -EBUSY;
+ }
+ ret = bma180_get_data_reg(data, chan->scan_index);
mutex_unlock(&data->mutex);
if (ret < 0)
return ret;
- *val = (s16)ret >> chan->scan_type.shift;
+ *val = sign_extend32(ret >> chan->scan_type.shift,
+ chan->scan_type.realbits - 1);
return IIO_VAL_INT;
case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
*val = data->bw;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = 0;
- *val2 = data->scale;
- return IIO_VAL_INT_PLUS_MICRO;
+ switch (chan->type) {
+ case IIO_ACCEL:
+ *val = 0;
+ *val2 = data->scale;
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_TEMP:
+ *val = 500;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ case IIO_CHAN_INFO_OFFSET:
+ *val = 48; /* 0 LSB @ 24 degree C */
+ return IIO_VAL_INT;
default:
return -EINVAL;
}
@@ -443,7 +467,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
{ },
};
-#define BMA180_CHANNEL(_axis) { \
+#define BMA180_ACC_CHANNEL(_axis) { \
.type = IIO_ACCEL, \
.modified = 1, \
.channel2 = IIO_MOD_##_axis, \
@@ -460,11 +484,24 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
.ext_info = bma180_ext_info, \
}
+#define BMA180_TEMP_CHANNEL { \
+ .type = IIO_TEMP, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), \
+ .scan_index = TEMP, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 8, \
+ .storagebits = 16, \
+ }, \
+}
+
static const struct iio_chan_spec bma180_channels[] = {
- BMA180_CHANNEL(X),
- BMA180_CHANNEL(Y),
- BMA180_CHANNEL(Z),
- IIO_CHAN_SOFT_TIMESTAMP(3),
+ BMA180_ACC_CHANNEL(X),
+ BMA180_ACC_CHANNEL(Y),
+ BMA180_ACC_CHANNEL(Z),
+ BMA180_TEMP_CHANNEL,
+ IIO_CHAN_SOFT_TIMESTAMP(4),
};
static irqreturn_t bma180_trigger_handler(int irq, void *p)
@@ -479,13 +516,14 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
indio_dev->masklength) {
- ret = bma180_get_acc_reg(data, bit);
+ ret = bma180_get_data_reg(data, bit);
if (ret < 0) {
mutex_unlock(&data->mutex);
goto err;
}
((s16 *)data->buff)[i++] = ret;
}
+
mutex_unlock(&data->mutex);
iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/13] iio:bma180: Drop _update_scan_mode()
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (6 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 07/13] iio:bma180: Expose temperature channel Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 09/13] iio:bma180: Introduce part_info to differentiate further chip variants Peter Meerwald
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
statically allocate maximum size
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 91260a0..5838318 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -82,7 +82,7 @@ struct bma180_data {
int scale;
int bw;
bool pmode;
- char *buff;
+ u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */
};
enum bma180_chan {
@@ -408,26 +408,10 @@ static int bma180_write_raw(struct iio_dev *indio_dev,
}
}
-static int bma180_update_scan_mode(struct iio_dev *indio_dev,
- const unsigned long *scan_mask)
-{
- struct bma180_data *data = iio_priv(indio_dev);
-
- if (data->buff)
- devm_kfree(&indio_dev->dev, data->buff);
- data->buff = devm_kzalloc(&indio_dev->dev,
- indio_dev->scan_bytes, GFP_KERNEL);
- if (!data->buff)
- return -ENOMEM;
-
- return 0;
-}
-
static const struct iio_info bma180_info = {
.attrs = &bma180_attrs_group,
.read_raw = bma180_read_raw,
.write_raw = bma180_write_raw,
- .update_scan_mode = bma180_update_scan_mode,
.driver_module = THIS_MODULE,
};
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/13] iio:bma180: Introduce part_info to differentiate further chip variants
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (7 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 08/13] iio:bma180: Drop _update_scan_mode() Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 10/13] iio:bma180: Introduce part-specific _config() and disable() code Peter Meerwald
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 41 ++++++++++++++++++++++++++++++++---------
1 file changed, 32 insertions(+), 9 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 5838318..fc7c7b8 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -26,6 +26,19 @@
#define BMA180_DRV_NAME "bma180"
#define BMA180_IRQ_NAME "bma180_event"
+enum {
+ BMA180,
+};
+
+struct bma180_part_info {
+ const struct iio_chan_spec *channels;
+ unsigned num_channels;
+ const int *scale_table;
+ unsigned num_scales;
+ const int *bw_table;
+ unsigned num_bw;
+};
+
/* Register set */
#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */
#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */
@@ -77,6 +90,7 @@
struct bma180_data {
struct i2c_client *client;
struct iio_trigger *trig;
+ const struct bma180_part_info *part_info;
struct mutex mutex;
bool sleep_state;
int scale;
@@ -193,8 +207,8 @@ static int bma180_set_bw(struct bma180_data *data, int val)
if (data->sleep_state)
return -EBUSY;
- for (i = 0; i < ARRAY_SIZE(bma180_bw_table); ++i) {
- if (bma180_bw_table[i] == val) {
+ for (i = 0; i < data->part_info->num_bw; ++i) {
+ if (data->part_info->bw_table[i] == val) {
ret = bma180_set_bits(data,
BMA180_BW_TCS, BMA180_BW, i);
if (ret) {
@@ -217,8 +231,8 @@ static int bma180_set_scale(struct bma180_data *data, int val)
if (data->sleep_state)
return -EBUSY;
- for (i = 0; i < ARRAY_SIZE(bma180_scale_table); ++i)
- if (bma180_scale_table[i] == val) {
+ for (i = 0; i < data->part_info->num_scales; ++i)
+ if (data->part_info->scale_table[i] == val) {
ret = bma180_set_bits(data,
BMA180_OFFSET_LSB1, BMA180_RANGE, i);
if (ret) {
@@ -488,6 +502,14 @@ static const struct iio_chan_spec bma180_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(4),
};
+static const struct bma180_part_info bma180_part_info[] = {
+ [BMA180] = {
+ bma180_channels, ARRAY_SIZE(bma180_channels),
+ bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
+ bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
+ },
+};
+
static irqreturn_t bma180_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
@@ -554,6 +576,7 @@ static int bma180_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
+ data->part_info = &bma180_part_info[id->driver_data];
ret = bma180_chip_init(data);
if (ret < 0)
@@ -562,8 +585,8 @@ static int bma180_probe(struct i2c_client *client,
mutex_init(&data->mutex);
indio_dev->dev.parent = &client->dev;
- indio_dev->channels = bma180_channels;
- indio_dev->num_channels = ARRAY_SIZE(bma180_channels);
+ indio_dev->channels = data->part_info->channels;
+ indio_dev->num_channels = data->part_info->num_channels;
indio_dev->name = BMA180_DRV_NAME;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &bma180_info;
@@ -674,8 +697,8 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#define BMA180_PM_OPS NULL
#endif
-static struct i2c_device_id bma180_id[] = {
- { BMA180_DRV_NAME, 0 },
+static struct i2c_device_id bma180_ids[] = {
+ { BMA180_DRV_NAME, BMA180 },
{ }
};
@@ -689,7 +712,7 @@ static struct i2c_driver bma180_driver = {
},
.probe = bma180_probe,
.remove = bma180_remove,
- .id_table = bma180_id,
+ .id_table = bma180_ids,
};
module_i2c_driver(bma180_driver);
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/13] iio:bma180: Introduce part-specific _config() and disable() code
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (8 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 09/13] iio:bma180: Introduce part_info to differentiate further chip variants Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 11/13] iio:bma180: Prepare for accelerometer channels with different resolutions Peter Meerwald
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
move part of bma180_init() to bma180_config() (split initialization and
configuration code); configuration is heavily chip-specific
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index fc7c7b8..a25b060 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -37,6 +37,8 @@ struct bma180_part_info {
unsigned num_scales;
const int *bw_table;
unsigned num_bw;
+ int (*chip_config)(struct bma180_data *data);
+ void (*chip_disable)(struct bma180_data *data);
};
/* Register set */
@@ -279,21 +281,28 @@ static int bma180_chip_init(struct bma180_data *data)
int ret = i2c_smbus_read_byte_data(data->client, BMA180_CHIP_ID);
if (ret < 0)
- goto err;
- if (ret != BMA180_ID_REG_VAL) {
- ret = -ENODEV;
- goto err;
- }
+ return ret;
+ if (ret != BMA180_ID_REG_VAL)
+ return -ENODEV;
ret = bma180_soft_reset(data);
if (ret)
- goto err;
+ return ret;
/*
* No serial transaction should occur within minimum 10 us
* after soft_reset command
*/
msleep(20);
+ return 0;
+}
+
+static int bma180_chip_config(struct bma180_data *data)
+{
+ int ret = bma180_chip_init(data);
+
+ if (ret)
+ goto err;
ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_DIS_WAKE_UP, 1);
if (ret)
goto err;
@@ -319,7 +328,7 @@ static int bma180_chip_init(struct bma180_data *data)
return 0;
err:
- dev_err(&data->client->dev, "failed to init the chip\n");
+ dev_err(&data->client->dev, "failed to config the chip\n");
return ret;
}
@@ -507,6 +516,8 @@ static const struct bma180_part_info bma180_part_info[] = {
bma180_channels, ARRAY_SIZE(bma180_channels),
bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
+ bma180_chip_config,
+ bma180_chip_disable,
},
};
@@ -578,7 +589,7 @@ static int bma180_probe(struct i2c_client *client,
data->client = client;
data->part_info = &bma180_part_info[id->driver_data];
- ret = bma180_chip_init(data);
+ ret = data->part_info->chip_config(data);
if (ret < 0)
goto err_chip_disable;
@@ -640,7 +651,7 @@ err_trigger_unregister:
err_trigger_free:
iio_trigger_free(data->trig);
err_chip_disable:
- bma180_chip_disable(data);
+ data->part_info->chip_disable(data);
return ret;
}
@@ -658,7 +669,7 @@ static int bma180_remove(struct i2c_client *client)
}
mutex_lock(&data->mutex);
- bma180_chip_disable(data);
+ data->part_info->chip_disable(data);
mutex_unlock(&data->mutex);
return 0;
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/13] iio:bma180: Prepare for accelerometer channels with different resolutions
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (9 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 10/13] iio:bma180: Introduce part-specific _config() and disable() code Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 12/13] iio:bma180: Implement _available sysfs attribute dynamically Peter Meerwald
2014-07-16 18:32 ` [PATCH 13/13] iio:bma180: Add BMA250 chip support Peter Meerwald
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
allow to specify channels resolution and compute shift assuming
16-bit registers and MSB allocation
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index a25b060..6e940b0 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -474,7 +474,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
{ },
};
-#define BMA180_ACC_CHANNEL(_axis) { \
+#define BMA180_ACC_CHANNEL(_axis, _bits) { \
.type = IIO_ACCEL, \
.modified = 1, \
.channel2 = IIO_MOD_##_axis, \
@@ -484,9 +484,9 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
.scan_index = AXIS_##_axis, \
.scan_type = { \
.sign = 's', \
- .realbits = 14, \
+ .realbits = _bits, \
.storagebits = 16, \
- .shift = 2, \
+ .shift = 16 - _bits, \
}, \
.ext_info = bma180_ext_info, \
}
@@ -504,9 +504,9 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
}
static const struct iio_chan_spec bma180_channels[] = {
- BMA180_ACC_CHANNEL(X),
- BMA180_ACC_CHANNEL(Y),
- BMA180_ACC_CHANNEL(Z),
+ BMA180_ACC_CHANNEL(X, 14),
+ BMA180_ACC_CHANNEL(Y, 14),
+ BMA180_ACC_CHANNEL(Z, 14),
BMA180_TEMP_CHANNEL,
IIO_CHAN_SOFT_TIMESTAMP(4),
};
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/13] iio:bma180: Implement _available sysfs attribute dynamically
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (10 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 11/13] iio:bma180: Prepare for accelerometer channels with different resolutions Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
2014-07-16 18:32 ` [PATCH 13/13] iio:bma180: Add BMA250 chip support Peter Meerwald
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
makes it easier to add more chip variants and removes redundancy:
scales and frequencies are now stated just once
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 54 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 43 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 6e940b0..9fbc81f 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -83,12 +83,6 @@ struct bma180_part_info {
#define BMA180_DEF_BW 20
#define BMA180_DEF_SCALE 2452
-/* Available values for sysfs */
-#define BMA180_FLP_FREQ_AVAILABLE \
- "10 20 40 75 150 300"
-#define BMA180_SCALE_AVAILABLE \
- "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"
-
struct bma180_data {
struct i2c_client *client;
struct iio_trigger *trig;
@@ -347,13 +341,51 @@ err:
dev_err(&data->client->dev, "failed to disable the chip\n");
}
-static IIO_CONST_ATTR(in_accel_filter_low_pass_3db_frequency_available,
- BMA180_FLP_FREQ_AVAILABLE);
-static IIO_CONST_ATTR(in_accel_scale_available, BMA180_SCALE_AVAILABLE);
+static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned n,
+ bool micros)
+{
+ size_t len = 0;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (!vals[i])
+ continue;
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ micros ? "0.%06d " : "%d ", vals[i]);
+ }
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t bma180_show_filter_freq_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ return bma180_show_avail(buf, data->part_info->bw_table,
+ data->part_info->num_bw, false);
+}
+
+static ssize_t bma180_show_scale_avail(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
+
+ return bma180_show_avail(buf, data->part_info->scale_table,
+ data->part_info->num_scales, true);
+}
+
+static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
+ S_IRUGO, bma180_show_filter_freq_avail, NULL, 0);
+
+static IIO_DEVICE_ATTR(in_accel_scale_available,
+ S_IRUGO, bma180_show_scale_avail, NULL, 0);
static struct attribute *bma180_attributes[] = {
- &iio_const_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
- &iio_const_attr_in_accel_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.
+ dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
NULL,
};
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 13/13] iio:bma180: Add BMA250 chip support
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
` (11 preceding siblings ...)
2014-07-16 18:32 ` [PATCH 12/13] iio:bma180: Implement _available sysfs attribute dynamically Peter Meerwald
@ 2014-07-16 18:32 ` Peter Meerwald
12 siblings, 0 replies; 16+ messages in thread
From: Peter Meerwald @ 2014-07-16 18:32 UTC (permalink / raw)
To: linux-iio; +Cc: jic23, Peter Meerwald, Oleksandr Kravchenko
the BMA250 has only 10-bit resolution; while the data readout registers
have identical layout, the configuration is completely different compared
to the BMA180
datasheet: http://ae-bst.resource.bosch.com/media/products/dokumente/bma250/BST-BMA250-DS002-05.pdf
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
---
drivers/iio/accel/bma180.c | 161 +++++++++++++++++++++++++++++++++++----------
1 file changed, 127 insertions(+), 34 deletions(-)
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index 9fbc81f..c8e0a0a 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -3,9 +3,15 @@
*
* Copyright 2013 Oleksandr Kravchenko <x0199363@ti.com>
*
+ * Support for BMA250 (c) Peter Meerwald <pmeerw@pmeerw.net>
+ *
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
+ *
+ * SPI is not supported by driver
+ * BMA180: 7-bit I2C slave address 0x40 or 0x41
+ * BMA250: 7-bit I2C slave address 0x18 or 0x19
*/
#include <linux/module.h>
@@ -23,13 +29,13 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
-#define BMA180_DRV_NAME "bma180"
-#define BMA180_IRQ_NAME "bma180_event"
-
enum {
BMA180,
+ BMA250,
};
+struct bma180_data;
+
struct bma180_part_info {
const struct iio_chan_spec *channels;
unsigned num_channels;
@@ -37,6 +43,15 @@ struct bma180_part_info {
unsigned num_scales;
const int *bw_table;
unsigned num_bw;
+
+ u8 int_reset_reg, int_reset_mask;
+ u8 sleep_reg, sleep_mask;
+ u8 bw_reg, bw_mask;
+ u8 scale_reg, scale_mask;
+ u8 power_reg, power_mask, lowpower_val;
+ u8 int_enable_reg, int_enable_mask;
+ u8 softreset_reg;
+
int (*chip_config)(struct bma180_data *data);
void (*chip_disable)(struct bma180_data *data);
};
@@ -75,13 +90,23 @@ struct bma180_part_info {
#define BMA180_ID_REG_VAL 0x03
/* Chip power modes */
-#define BMA180_LOW_NOISE 0x00
#define BMA180_LOW_POWER 0x03
-/* Defaults values */
-#define BMA180_DEF_PMODE false
-#define BMA180_DEF_BW 20
-#define BMA180_DEF_SCALE 2452
+#define BMA250_RANGE_REG 0x0f
+#define BMA250_BW_REG 0x10
+#define BMA250_POWER_REG 0x11
+#define BMA250_RESET_REG 0x14
+#define BMA250_INT_ENABLE_REG 0x17
+#define BMA250_INT_MAP_REG 0x1a
+#define BMA250_INT_RESET_REG 0x21
+
+#define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */
+#define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */
+#define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */
+#define BMA250_LOWPOWER_MASK BIT(6)
+#define BMA250_DATA_INTEN_MASK BIT(4)
+#define BMA250_INT1_DATA_MASK BIT(0)
+#define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */
struct bma180_data {
struct i2c_client *client;
@@ -105,6 +130,10 @@ enum bma180_chan {
static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
+static int bma250_bw_table[] = { 8, 16, 31, 63, 125, 250 }; /* Hz */
+static int bma250_scale_table[] = { 0, 0, 0, 38344, 0, 76590, 0, 0, 153180, 0,
+ 0, 0, 306458 };
+
static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
{
int ret;
@@ -143,7 +172,8 @@ static int bma180_set_bits(struct bma180_data *data, u8 reg, u8 mask, u8 val)
static int bma180_reset_intr(struct bma180_data *data)
{
- int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_RESET_INT, 1);
+ int ret = bma180_set_bits(data, data->part_info->int_reset_reg,
+ data->part_info->int_reset_mask, 1);
if (ret)
dev_err(&data->client->dev, "failed to reset interrupt\n");
@@ -153,10 +183,8 @@ static int bma180_reset_intr(struct bma180_data *data)
static int bma180_set_new_data_intr_state(struct bma180_data *data, bool state)
{
- u8 reg_val = state ? BMA180_NEW_DATA_INT : 0x00;
- int ret = i2c_smbus_write_byte_data(data->client, BMA180_CTRL_REG3,
- reg_val);
-
+ int ret = bma180_set_bits(data, data->part_info->int_enable_reg,
+ data->part_info->int_enable_mask, state);
if (ret)
goto err;
ret = bma180_reset_intr(data);
@@ -173,7 +201,8 @@ err:
static int bma180_set_sleep_state(struct bma180_data *data, bool state)
{
- int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_SLEEP, state);
+ int ret = bma180_set_bits(data, data->part_info->sleep_reg,
+ data->part_info->sleep_mask, state);
if (ret) {
dev_err(&data->client->dev,
@@ -205,8 +234,8 @@ static int bma180_set_bw(struct bma180_data *data, int val)
for (i = 0; i < data->part_info->num_bw; ++i) {
if (data->part_info->bw_table[i] == val) {
- ret = bma180_set_bits(data,
- BMA180_BW_TCS, BMA180_BW, i);
+ ret = bma180_set_bits(data, data->part_info->bw_reg,
+ data->part_info->bw_mask, i);
if (ret) {
dev_err(&data->client->dev,
"failed to set bandwidth\n");
@@ -229,8 +258,8 @@ static int bma180_set_scale(struct bma180_data *data, int val)
for (i = 0; i < data->part_info->num_scales; ++i)
if (data->part_info->scale_table[i] == val) {
- ret = bma180_set_bits(data,
- BMA180_OFFSET_LSB1, BMA180_RANGE, i);
+ ret = bma180_set_bits(data, data->part_info->scale_reg,
+ data->part_info->scale_mask, i);
if (ret) {
dev_err(&data->client->dev,
"failed to set scale\n");
@@ -245,9 +274,9 @@ static int bma180_set_scale(struct bma180_data *data, int val)
static int bma180_set_pmode(struct bma180_data *data, bool mode)
{
- u8 reg_val = mode ? BMA180_LOW_POWER : BMA180_LOW_NOISE;
- int ret = bma180_set_bits(data, BMA180_TCO_Z, BMA180_MODE_CONFIG,
- reg_val);
+ u8 reg_val = mode ? data->part_info->lowpower_val : 0;
+ int ret = bma180_set_bits(data, data->part_info->power_reg,
+ data->part_info->power_mask, reg_val);
if (ret) {
dev_err(&data->client->dev, "failed to set power mode\n");
@@ -261,7 +290,7 @@ static int bma180_set_pmode(struct bma180_data *data, bool mode)
static int bma180_soft_reset(struct bma180_data *data)
{
int ret = i2c_smbus_write_byte_data(data->client,
- BMA180_RESET, BMA180_RESET_VAL);
+ data->part_info->softreset_reg, BMA180_RESET_VAL);
if (ret)
dev_err(&data->client->dev, "failed to reset the chip\n");
@@ -288,7 +317,11 @@ static int bma180_chip_init(struct bma180_data *data)
*/
msleep(20);
- return 0;
+ ret = bma180_set_new_data_intr_state(data, false);
+ if (ret)
+ return ret;
+
+ return bma180_set_pmode(data, false);
}
static int bma180_chip_config(struct bma180_data *data)
@@ -303,19 +336,37 @@ static int bma180_chip_config(struct bma180_data *data)
ret = bma180_set_ee_writing_state(data, true);
if (ret)
goto err;
- ret = bma180_set_new_data_intr_state(data, false);
+ ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
if (ret)
goto err;
- ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
+ ret = bma180_set_bw(data, 20); /* 20 Hz */
if (ret)
goto err;
- ret = bma180_set_pmode(data, BMA180_DEF_PMODE);
+ ret = bma180_set_scale(data, 2452); /* 2 G */
if (ret)
goto err;
- ret = bma180_set_bw(data, BMA180_DEF_BW);
+
+ return 0;
+
+err:
+ dev_err(&data->client->dev, "failed to config the chip\n");
+ return ret;
+}
+
+static int bma250_chip_config(struct bma180_data *data)
+{
+ int ret = bma180_chip_init(data);
+
+ if (ret)
+ goto err;
+ ret = bma180_set_bw(data, 16); /* 16 Hz */
+ if (ret)
+ goto err;
+ ret = bma180_set_scale(data, 38344); /* 2 G */
if (ret)
goto err;
- ret = bma180_set_scale(data, BMA180_DEF_SCALE);
+ ret = bma180_set_bits(data, BMA250_INT_MAP_REG,
+ BMA250_INT1_DATA_MASK, 1);
if (ret)
goto err;
@@ -341,6 +392,19 @@ err:
dev_err(&data->client->dev, "failed to disable the chip\n");
}
+static void bma250_chip_disable(struct bma180_data *data)
+{
+ if (bma180_set_new_data_intr_state(data, false))
+ goto err;
+ if (bma180_set_sleep_state(data, true))
+ goto err;
+
+ return;
+
+err:
+ dev_err(&data->client->dev, "failed to disable the chip\n");
+}
+
static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned n,
bool micros)
{
@@ -543,14 +607,43 @@ static const struct iio_chan_spec bma180_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(4),
};
+static const struct iio_chan_spec bma250_channels[] = {
+ BMA180_ACC_CHANNEL(X, 10),
+ BMA180_ACC_CHANNEL(Y, 10),
+ BMA180_ACC_CHANNEL(Z, 10),
+ BMA180_TEMP_CHANNEL,
+ IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
static const struct bma180_part_info bma180_part_info[] = {
[BMA180] = {
bma180_channels, ARRAY_SIZE(bma180_channels),
bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
+ BMA180_CTRL_REG0, BMA180_RESET_INT,
+ BMA180_CTRL_REG0, BMA180_SLEEP,
+ BMA180_BW_TCS, BMA180_BW,
+ BMA180_OFFSET_LSB1, BMA180_RANGE,
+ BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
+ BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
+ BMA180_RESET,
bma180_chip_config,
bma180_chip_disable,
},
+ [BMA250] = {
+ bma250_channels, ARRAY_SIZE(bma250_channels),
+ bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
+ bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
+ BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
+ BMA250_POWER_REG, BMA250_SUSPEND_MASK,
+ BMA250_BW_REG, BMA250_BW_MASK,
+ BMA250_RANGE_REG, BMA250_RANGE_MASK,
+ BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
+ BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
+ BMA250_RESET_REG,
+ bma250_chip_config,
+ bma250_chip_disable,
+ },
};
static irqreturn_t bma180_trigger_handler(int irq, void *p)
@@ -626,11 +719,10 @@ static int bma180_probe(struct i2c_client *client,
goto err_chip_disable;
mutex_init(&data->mutex);
-
indio_dev->dev.parent = &client->dev;
indio_dev->channels = data->part_info->channels;
indio_dev->num_channels = data->part_info->num_channels;
- indio_dev->name = BMA180_DRV_NAME;
+ indio_dev->name = id->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &bma180_info;
@@ -644,7 +736,7 @@ static int bma180_probe(struct i2c_client *client,
ret = devm_request_irq(&client->dev, client->irq,
iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING,
- BMA180_IRQ_NAME, data->trig);
+ "bma180_event", data->trig);
if (ret) {
dev_err(&client->dev, "unable to request IRQ\n");
goto err_trigger_free;
@@ -741,7 +833,8 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#endif
static struct i2c_device_id bma180_ids[] = {
- { BMA180_DRV_NAME, BMA180 },
+ { "bma180", BMA180 },
+ { "bma250", BMA250 },
{ }
};
@@ -749,7 +842,7 @@ MODULE_DEVICE_TABLE(i2c, bma180_id);
static struct i2c_driver bma180_driver = {
.driver = {
- .name = BMA180_DRV_NAME,
+ .name = "bma180",
.owner = THIS_MODULE,
.pm = BMA180_PM_OPS,
},
@@ -762,5 +855,5 @@ module_i2c_driver(bma180_driver);
MODULE_AUTHOR("Kravchenko Oleksandr <x0199363@ti.com>");
MODULE_AUTHOR("Texas Instruments, Inc.");
-MODULE_DESCRIPTION("Bosch BMA180 triaxial acceleration sensor");
+MODULE_DESCRIPTION("Bosch BMA180/BMA250 triaxial acceleration sensor");
MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units
2014-07-16 18:32 ` [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units Peter Meerwald
@ 2014-07-20 16:39 ` Jonathan Cameron
0 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2014-07-20 16:39 UTC (permalink / raw)
To: Peter Meerwald, linux-iio; +Cc: Oleksandr Kravchenko
On 16/07/14 19:32, Peter Meerwald wrote:
> The userspace interface for acceleration sensors is documented as using
> m/s^2 units [Documentation/ABI/testing/sysfs-bus-iio]
>
> The fullscale raw values for the BMA80 corresponds to -/+ 1, 1.5, 2, etc G
> depending on the selected mode.
>
> The scale table was converting to G rather than m/s^2.
> Change the scaling table to match the documented interface.
>
> See commit 71702e6e, iio: mma8452: Use correct acceleration units,
> for a related fix.
>
> Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
> Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
Applied to the fixes-togreg branch of iio.git and marked for stable.
> ---
> drivers/iio/accel/bma180.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
> index a7e68c8..28388bb 100644
> --- a/drivers/iio/accel/bma180.c
> +++ b/drivers/iio/accel/bma180.c
> @@ -68,13 +68,13 @@
> /* Defaults values */
> #define BMA180_DEF_PMODE 0
> #define BMA180_DEF_BW 20
> -#define BMA180_DEF_SCALE 250
> +#define BMA180_DEF_SCALE 2452
>
> /* Available values for sysfs */
> #define BMA180_FLP_FREQ_AVAILABLE \
> "10 20 40 75 150 300"
> #define BMA180_SCALE_AVAILABLE \
> - "0.000130 0.000190 0.000250 0.000380 0.000500 0.000990 0.001980"
> + "0.001275 0.001863 0.002452 0.003727 0.004903 0.009709 0.019417"
>
> struct bma180_data {
> struct i2c_client *client;
> @@ -94,7 +94,7 @@ enum bma180_axis {
> };
>
> static int bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
> -static int scale_table[] = { 130, 190, 250, 380, 500, 990, 1980 };
> +static int scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
>
> static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis)
> {
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 02/13] iio:bma180: Missing check for frequency fractional part
2014-07-16 18:32 ` [PATCH 02/13] iio:bma180: Missing check for frequency fractional part Peter Meerwald
@ 2014-07-20 16:41 ` Jonathan Cameron
0 siblings, 0 replies; 16+ messages in thread
From: Jonathan Cameron @ 2014-07-20 16:41 UTC (permalink / raw)
To: Peter Meerwald, linux-iio; +Cc: Oleksandr Kravchenko
On 16/07/14 19:32, Peter Meerwald wrote:
> val2 should be zero
>
> Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
> Cc: Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
Applied to the fixes-togreg branch of iio.git and marked for stable.
I added a bit more explanation to the the description of what the actual
result was.
> ---
> drivers/iio/accel/bma180.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
> index 28388bb..a077cc8 100644
> --- a/drivers/iio/accel/bma180.c
> +++ b/drivers/iio/accel/bma180.c
> @@ -376,6 +376,8 @@ static int bma180_write_raw(struct iio_dev *indio_dev,
> mutex_unlock(&data->mutex);
> return ret;
> case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
> + if (val2)
> + return -EINVAL;
> mutex_lock(&data->mutex);
> ret = bma180_set_bw(data, val);
> mutex_unlock(&data->mutex);
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2014-07-20 16:39 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-16 18:32 [PATCH 00/13] iio:bma180: Fixes and BMA250 support Peter Meerwald
2014-07-16 18:32 ` [PATCH 01/13] iio:bma180: Fix scale factors to report correct acceleration units Peter Meerwald
2014-07-20 16:39 ` Jonathan Cameron
2014-07-16 18:32 ` [PATCH 02/13] iio:bma180: Missing check for frequency fractional part Peter Meerwald
2014-07-20 16:41 ` Jonathan Cameron
2014-07-16 18:32 ` [PATCH 03/13] iio:bma180: Enable use of device without IRQ Peter Meerwald
2014-07-16 18:32 ` [PATCH 04/13] iio:bma180: Prefix remaining tables and functions with bma18_ Peter Meerwald
2014-07-16 18:32 ` [PATCH 05/13] iio:bma180: Rename BMA_180 to BMA180_ Peter Meerwald
2014-07-16 18:32 ` [PATCH 06/13] iio:bma180: Use bool instead of int for state Peter Meerwald
2014-07-16 18:32 ` [PATCH 07/13] iio:bma180: Expose temperature channel Peter Meerwald
2014-07-16 18:32 ` [PATCH 08/13] iio:bma180: Drop _update_scan_mode() Peter Meerwald
2014-07-16 18:32 ` [PATCH 09/13] iio:bma180: Introduce part_info to differentiate further chip variants Peter Meerwald
2014-07-16 18:32 ` [PATCH 10/13] iio:bma180: Introduce part-specific _config() and disable() code Peter Meerwald
2014-07-16 18:32 ` [PATCH 11/13] iio:bma180: Prepare for accelerometer channels with different resolutions Peter Meerwald
2014-07-16 18:32 ` [PATCH 12/13] iio:bma180: Implement _available sysfs attribute dynamically Peter Meerwald
2014-07-16 18:32 ` [PATCH 13/13] iio:bma180: Add BMA250 chip support Peter Meerwald
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).