aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Meerwald <pmeerw@pmeerw.net>2014-08-19 18:43:00 -0400
committerJonathan Cameron <jic23@kernel.org>2014-09-14 13:48:39 -0400
commitb81fbab7f567aaa12aba6532681b426f3e130e11 (patch)
treea4dfb5e8425bb845589fa66b781889202779f2d9
parentc7c69e8540895be5d09bf023f1b48db3cab7a78b (diff)
iio:bma180: Expose temperature channel
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> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/accel/bma180.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c
index aa7566fc031f..91260a071fe9 100644
--- a/drivers/iio/accel/bma180.c
+++ b/drivers/iio/accel/bma180.c
@@ -29,6 +29,7 @@
29/* Register set */ 29/* Register set */
30#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */ 30#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */
31#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */ 31#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */
32#define BMA180_TEMP 0x08
32#define BMA180_CTRL_REG0 0x0d 33#define BMA180_CTRL_REG0 0x0d
33#define BMA180_RESET 0x10 34#define BMA180_RESET 0x10
34#define BMA180_BW_TCS 0x20 35#define BMA180_BW_TCS 0x20
@@ -84,27 +85,37 @@ struct bma180_data {
84 char *buff; 85 char *buff;
85}; 86};
86 87
87enum bma180_axis { 88enum bma180_chan {
88 AXIS_X, 89 AXIS_X,
89 AXIS_Y, 90 AXIS_Y,
90 AXIS_Z, 91 AXIS_Z,
92 TEMP
91}; 93};
92 94
93static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */ 95static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
94static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 }; 96static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
95 97
96static int bma180_get_acc_reg(struct bma180_data *data, enum bma180_axis axis) 98static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
97{ 99{
98 u8 reg = BMA180_ACC_X_LSB + axis * 2;
99 int ret; 100 int ret;
100 101
101 if (data->sleep_state) 102 if (data->sleep_state)
102 return -EBUSY; 103 return -EBUSY;
103 104
104 ret = i2c_smbus_read_word_data(data->client, reg); 105 switch (chan) {
105 if (ret < 0) 106 case TEMP:
106 dev_err(&data->client->dev, 107 ret = i2c_smbus_read_byte_data(data->client, BMA180_TEMP);
107 "failed to read accel_%c register\n", 'x' + axis); 108 if (ret < 0)
109 dev_err(&data->client->dev, "failed to read temp register\n");
110 break;
111 default:
112 ret = i2c_smbus_read_word_data(data->client,
113 BMA180_ACC_X_LSB + chan * 2);
114 if (ret < 0)
115 dev_err(&data->client->dev,
116 "failed to read accel_%c register\n",
117 'x' + chan);
118 }
108 119
109 return ret; 120 return ret;
110} 121}
@@ -337,22 +348,35 @@ static int bma180_read_raw(struct iio_dev *indio_dev,
337 switch (mask) { 348 switch (mask) {
338 case IIO_CHAN_INFO_RAW: 349 case IIO_CHAN_INFO_RAW:
339 mutex_lock(&data->mutex); 350 mutex_lock(&data->mutex);
340 if (iio_buffer_enabled(indio_dev)) 351 if (iio_buffer_enabled(indio_dev)) {
341 ret = -EBUSY; 352 mutex_unlock(&data->mutex);
342 else 353 return -EBUSY;
343 ret = bma180_get_acc_reg(data, chan->scan_index); 354 }
355 ret = bma180_get_data_reg(data, chan->scan_index);
344 mutex_unlock(&data->mutex); 356 mutex_unlock(&data->mutex);
345 if (ret < 0) 357 if (ret < 0)
346 return ret; 358 return ret;
347 *val = (s16)ret >> chan->scan_type.shift; 359 *val = sign_extend32(ret >> chan->scan_type.shift,
360 chan->scan_type.realbits - 1);
348 return IIO_VAL_INT; 361 return IIO_VAL_INT;
349 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 362 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
350 *val = data->bw; 363 *val = data->bw;
351 return IIO_VAL_INT; 364 return IIO_VAL_INT;
352 case IIO_CHAN_INFO_SCALE: 365 case IIO_CHAN_INFO_SCALE:
353 *val = 0; 366 switch (chan->type) {
354 *val2 = data->scale; 367 case IIO_ACCEL:
355 return IIO_VAL_INT_PLUS_MICRO; 368 *val = 0;
369 *val2 = data->scale;
370 return IIO_VAL_INT_PLUS_MICRO;
371 case IIO_TEMP:
372 *val = 500;
373 return IIO_VAL_INT;
374 default:
375 return -EINVAL;
376 }
377 case IIO_CHAN_INFO_OFFSET:
378 *val = 48; /* 0 LSB @ 24 degree C */
379 return IIO_VAL_INT;
356 default: 380 default:
357 return -EINVAL; 381 return -EINVAL;
358 } 382 }
@@ -443,7 +467,7 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
443 { }, 467 { },
444}; 468};
445 469
446#define BMA180_CHANNEL(_axis) { \ 470#define BMA180_ACC_CHANNEL(_axis) { \
447 .type = IIO_ACCEL, \ 471 .type = IIO_ACCEL, \
448 .modified = 1, \ 472 .modified = 1, \
449 .channel2 = IIO_MOD_##_axis, \ 473 .channel2 = IIO_MOD_##_axis, \
@@ -460,11 +484,24 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
460 .ext_info = bma180_ext_info, \ 484 .ext_info = bma180_ext_info, \
461} 485}
462 486
487#define BMA180_TEMP_CHANNEL { \
488 .type = IIO_TEMP, \
489 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
490 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), \
491 .scan_index = TEMP, \
492 .scan_type = { \
493 .sign = 's', \
494 .realbits = 8, \
495 .storagebits = 16, \
496 }, \
497}
498
463static const struct iio_chan_spec bma180_channels[] = { 499static const struct iio_chan_spec bma180_channels[] = {
464 BMA180_CHANNEL(X), 500 BMA180_ACC_CHANNEL(X),
465 BMA180_CHANNEL(Y), 501 BMA180_ACC_CHANNEL(Y),
466 BMA180_CHANNEL(Z), 502 BMA180_ACC_CHANNEL(Z),
467 IIO_CHAN_SOFT_TIMESTAMP(3), 503 BMA180_TEMP_CHANNEL,
504 IIO_CHAN_SOFT_TIMESTAMP(4),
468}; 505};
469 506
470static irqreturn_t bma180_trigger_handler(int irq, void *p) 507static irqreturn_t bma180_trigger_handler(int irq, void *p)
@@ -479,13 +516,14 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
479 516
480 for_each_set_bit(bit, indio_dev->buffer->scan_mask, 517 for_each_set_bit(bit, indio_dev->buffer->scan_mask,
481 indio_dev->masklength) { 518 indio_dev->masklength) {
482 ret = bma180_get_acc_reg(data, bit); 519 ret = bma180_get_data_reg(data, bit);
483 if (ret < 0) { 520 if (ret < 0) {
484 mutex_unlock(&data->mutex); 521 mutex_unlock(&data->mutex);
485 goto err; 522 goto err;
486 } 523 }
487 ((s16 *)data->buff)[i++] = ret; 524 ((s16 *)data->buff)[i++] = ret;
488 } 525 }
526
489 mutex_unlock(&data->mutex); 527 mutex_unlock(&data->mutex);
490 528
491 iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns); 529 iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);