aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2014-05-08 17:58:00 -0400
committerJonathan Cameron <jic23@kernel.org>2014-08-07 06:27:41 -0400
commita735e3d7f03ab40d746290954baaf535719d9025 (patch)
tree2fce9f451e56e6775dc0e6864eea20be9be0c249 /drivers/iio
parent124e1b1d0924ca51ded8bb6f52844b2bc9e485f7 (diff)
iio: accel: kxcjk-1013: Set adjustable range
This chip can support 3 different ranges. Allowing range specification. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/accel/kxcjk-1013.c100
1 files changed, 95 insertions, 5 deletions
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index b32bdd10e0c4..57c515bf0fd2 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -82,6 +82,7 @@ struct kxcjk1013_data {
82 struct mutex mutex; 82 struct mutex mutex;
83 s16 buffer[8]; 83 s16 buffer[8];
84 u8 odr_bits; 84 u8 odr_bits;
85 u8 range;
85 bool active_high_intr; 86 bool active_high_intr;
86 bool trigger_on; 87 bool trigger_on;
87}; 88};
@@ -97,6 +98,12 @@ enum kxcjk1013_mode {
97 OPERATION, 98 OPERATION,
98}; 99};
99 100
101enum kxcjk1013_range {
102 KXCJK1013_RANGE_2G,
103 KXCJK1013_RANGE_4G,
104 KXCJK1013_RANGE_8G,
105};
106
100static const struct { 107static const struct {
101 int val; 108 int val;
102 int val2; 109 int val2;
@@ -116,6 +123,14 @@ static const struct {
116 {0x02, 21000}, {0x03, 11000}, {0x04, 6400}, 123 {0x02, 21000}, {0x03, 11000}, {0x04, 6400},
117 {0x05, 3900}, {0x06, 2700}, {0x07, 2100} }; 124 {0x05, 3900}, {0x06, 2700}, {0x07, 2100} };
118 125
126static const struct {
127 u16 scale;
128 u8 gsel_0;
129 u8 gsel_1;
130} KXCJK1013_scale_table[] = { {9582, 0, 0},
131 {19163, 1, 0},
132 {38326, 0, 1} };
133
119static int kxcjk1013_set_mode(struct kxcjk1013_data *data, 134static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
120 enum kxcjk1013_mode mode) 135 enum kxcjk1013_mode mode)
121{ 136{
@@ -161,6 +176,32 @@ static int kxcjk1013_get_mode(struct kxcjk1013_data *data,
161 return 0; 176 return 0;
162} 177}
163 178
179static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index)
180{
181 int ret;
182
183 ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
184 if (ret < 0) {
185 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
186 return ret;
187 }
188
189 ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3);
190 ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4);
191
192 ret = i2c_smbus_write_byte_data(data->client,
193 KXCJK1013_REG_CTRL1,
194 ret);
195 if (ret < 0) {
196 dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
197 return ret;
198 }
199
200 data->range = range_index;
201
202 return 0;
203}
204
164static int kxcjk1013_chip_init(struct kxcjk1013_data *data) 205static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
165{ 206{
166 int ret; 207 int ret;
@@ -183,10 +224,6 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
183 return ret; 224 return ret;
184 } 225 }
185 226
186 /* Setting range to 4G */
187 ret |= KXCJK1013_REG_CTRL1_BIT_GSEL0;
188 ret &= ~KXCJK1013_REG_CTRL1_BIT_GSEL1;
189
190 /* Set 12 bit mode */ 227 /* Set 12 bit mode */
191 ret |= KXCJK1013_REG_CTRL1_BIT_RES; 228 ret |= KXCJK1013_REG_CTRL1_BIT_RES;
192 229
@@ -197,6 +234,14 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
197 return ret; 234 return ret;
198 } 235 }
199 236
237 /* Setting range to 4G */
238 ret = kxcjk1013_set_range(data, KXCJK1013_RANGE_4G);
239 if (ret < 0)
240 return ret;
241
242 data->range = KXCJK1013_RANGE_4G;
243
244
200 ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL); 245 ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL);
201 if (ret < 0) { 246 if (ret < 0) {
202 dev_err(&data->client->dev, "Error reading reg_data_ctrl\n"); 247 dev_err(&data->client->dev, "Error reading reg_data_ctrl\n");
@@ -403,6 +448,40 @@ static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis)
403 return ret; 448 return ret;
404} 449}
405 450
451static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val)
452{
453 int ret, i;
454 enum kxcjk1013_mode store_mode;
455
456
457 for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) {
458 if (KXCJK1013_scale_table[i].scale == val) {
459
460 ret = kxcjk1013_get_mode(data, &store_mode);
461 if (ret < 0)
462 return ret;
463
464 ret = kxcjk1013_set_mode(data, STANDBY);
465 if (ret < 0)
466 return ret;
467
468 ret = kxcjk1013_set_range(data, i);
469 if (ret < 0)
470 return ret;
471
472 if (store_mode == OPERATION) {
473 ret = kxcjk1013_set_mode(data, OPERATION);
474 if (ret)
475 return ret;
476 }
477
478 return 0;
479 }
480 }
481
482 return -EINVAL;
483}
484
406static int kxcjk1013_read_raw(struct iio_dev *indio_dev, 485static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
407 struct iio_chan_spec const *chan, int *val, 486 struct iio_chan_spec const *chan, int *val,
408 int *val2, long mask) 487 int *val2, long mask)
@@ -439,7 +518,7 @@ static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
439 518
440 case IIO_CHAN_INFO_SCALE: 519 case IIO_CHAN_INFO_SCALE:
441 *val = 0; 520 *val = 0;
442 *val2 = 19163; /* range +-4g (4/2047*9.806650) */ 521 *val2 = KXCJK1013_scale_table[data->range].scale;
443 return IIO_VAL_INT_PLUS_MICRO; 522 return IIO_VAL_INT_PLUS_MICRO;
444 523
445 case IIO_CHAN_INFO_SAMP_FREQ: 524 case IIO_CHAN_INFO_SAMP_FREQ:
@@ -466,6 +545,14 @@ static int kxcjk1013_write_raw(struct iio_dev *indio_dev,
466 ret = kxcjk1013_set_odr(data, val, val2); 545 ret = kxcjk1013_set_odr(data, val, val2);
467 mutex_unlock(&data->mutex); 546 mutex_unlock(&data->mutex);
468 break; 547 break;
548 case IIO_CHAN_INFO_SCALE:
549 if (val)
550 return -EINVAL;
551
552 mutex_lock(&data->mutex);
553 ret = kxcjk1013_set_scale(data, val2);
554 mutex_unlock(&data->mutex);
555 break;
469 default: 556 default:
470 ret = -EINVAL; 557 ret = -EINVAL;
471 } 558 }
@@ -487,8 +574,11 @@ static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev,
487static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( 574static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
488 "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600"); 575 "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600");
489 576
577static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019163 0.038326");
578
490static struct attribute *kxcjk1013_attributes[] = { 579static struct attribute *kxcjk1013_attributes[] = {
491 &iio_const_attr_sampling_frequency_available.dev_attr.attr, 580 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
581 &iio_const_attr_in_accel_scale_available.dev_attr.attr,
492 NULL, 582 NULL,
493}; 583};
494 584