blob: f9720a1e8a7c83811965d8d8695a7c23411c960e [file] [log] [blame]
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +01001/*
2 * bma180.c - IIO driver for Bosch BMA180 triaxial acceleration sensor
3 *
4 * Copyright 2013 Oleksandr Kravchenko <x0199363@ti.com>
5 *
Peter Meerwald2017cff2014-08-19 23:43:00 +01006 * Support for BMA250 (c) Peter Meerwald <pmeerw@pmeerw.net>
7 *
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +01008 * This file is subject to the terms and conditions of version 2 of
9 * the GNU General Public License. See the file COPYING in the main
10 * directory of this archive for more details.
Peter Meerwald2017cff2014-08-19 23:43:00 +010011 *
12 * SPI is not supported by driver
13 * BMA180: 7-bit I2C slave address 0x40 or 0x41
14 * BMA250: 7-bit I2C slave address 0x18 or 0x19
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010015 */
16
17#include <linux/module.h>
18#include <linux/i2c.h>
19#include <linux/interrupt.h>
20#include <linux/delay.h>
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -030021#include <linux/of_device.h>
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010022#include <linux/of.h>
23#include <linux/bitops.h>
24#include <linux/slab.h>
25#include <linux/string.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/buffer.h>
29#include <linux/iio/trigger.h>
30#include <linux/iio/trigger_consumer.h>
31#include <linux/iio/triggered_buffer.h>
32
33#define BMA180_DRV_NAME "bma180"
34#define BMA180_IRQ_NAME "bma180_event"
35
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -030036enum chip_ids {
Peter Meerwald1b9030f2014-08-19 23:43:00 +010037 BMA180,
Peter Meerwald2017cff2014-08-19 23:43:00 +010038 BMA250,
Peter Meerwald1b9030f2014-08-19 23:43:00 +010039};
40
Peter Meerwaldc1949ec2014-08-19 23:43:00 +010041struct bma180_data;
42
Peter Meerwald1b9030f2014-08-19 23:43:00 +010043struct bma180_part_info {
44 const struct iio_chan_spec *channels;
Miguel Robles7fa67902017-03-17 00:35:45 +010045 unsigned int num_channels;
Peter Meerwald1b9030f2014-08-19 23:43:00 +010046 const int *scale_table;
Miguel Robles7fa67902017-03-17 00:35:45 +010047 unsigned int num_scales;
Peter Meerwald1b9030f2014-08-19 23:43:00 +010048 const int *bw_table;
Miguel Robles7fa67902017-03-17 00:35:45 +010049 unsigned int num_bw;
Peter Meerwald2017cff2014-08-19 23:43:00 +010050
51 u8 int_reset_reg, int_reset_mask;
52 u8 sleep_reg, sleep_mask;
53 u8 bw_reg, bw_mask;
54 u8 scale_reg, scale_mask;
55 u8 power_reg, power_mask, lowpower_val;
56 u8 int_enable_reg, int_enable_mask;
57 u8 softreset_reg;
58
Peter Meerwaldc1949ec2014-08-19 23:43:00 +010059 int (*chip_config)(struct bma180_data *data);
60 void (*chip_disable)(struct bma180_data *data);
Peter Meerwald1b9030f2014-08-19 23:43:00 +010061};
62
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010063/* Register set */
64#define BMA180_CHIP_ID 0x00 /* Need to distinguish BMA180 from other */
65#define BMA180_ACC_X_LSB 0x02 /* First of 6 registers of accel data */
Peter Meerwaldb81fbab2014-08-19 23:43:00 +010066#define BMA180_TEMP 0x08
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010067#define BMA180_CTRL_REG0 0x0d
68#define BMA180_RESET 0x10
69#define BMA180_BW_TCS 0x20
70#define BMA180_CTRL_REG3 0x21
71#define BMA180_TCO_Z 0x30
72#define BMA180_OFFSET_LSB1 0x35
73
74/* BMA180_CTRL_REG0 bits */
75#define BMA180_DIS_WAKE_UP BIT(0) /* Disable wake up mode */
76#define BMA180_SLEEP BIT(1) /* 1 - chip will sleep */
77#define BMA180_EE_W BIT(4) /* Unlock writing to addr from 0x20 */
78#define BMA180_RESET_INT BIT(6) /* Reset pending interrupts */
79
80/* BMA180_CTRL_REG3 bits */
81#define BMA180_NEW_DATA_INT BIT(1) /* Intr every new accel data is ready */
82
83/* BMA180_OFFSET_LSB1 skipping mode bit */
84#define BMA180_SMP_SKIP BIT(0)
85
86/* Bit masks for registers bit fields */
Peter Meerwaldcab767d2014-08-19 23:43:00 +010087#define BMA180_RANGE 0x0e /* Range of measured accel values */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010088#define BMA180_BW 0xf0 /* Accel bandwidth */
89#define BMA180_MODE_CONFIG 0x03 /* Config operation modes */
90
91/* We have to write this value in reset register to do soft reset */
92#define BMA180_RESET_VAL 0xb6
93
Peter Meerwald9a70b142014-08-19 23:43:00 +010094#define BMA180_ID_REG_VAL 0x03
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010095
96/* Chip power modes */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +010097#define BMA180_LOW_POWER 0x03
98
Peter Meerwald2017cff2014-08-19 23:43:00 +010099#define BMA250_RANGE_REG 0x0f
100#define BMA250_BW_REG 0x10
101#define BMA250_POWER_REG 0x11
102#define BMA250_RESET_REG 0x14
103#define BMA250_INT_ENABLE_REG 0x17
104#define BMA250_INT_MAP_REG 0x1a
105#define BMA250_INT_RESET_REG 0x21
106
107#define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */
108#define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */
109#define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */
110#define BMA250_LOWPOWER_MASK BIT(6)
111#define BMA250_DATA_INTEN_MASK BIT(4)
112#define BMA250_INT1_DATA_MASK BIT(0)
113#define BMA250_INT_RESET_MASK BIT(7) /* Reset pending interrupts */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100114
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100115struct bma180_data {
116 struct i2c_client *client;
117 struct iio_trigger *trig;
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100118 const struct bma180_part_info *part_info;
H. Nikolaus Schaller587c2be2019-02-21 18:02:49 +0100119 struct iio_mount_matrix orientation;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100120 struct mutex mutex;
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100121 bool sleep_state;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100122 int scale;
123 int bw;
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100124 bool pmode;
Peter Meerwaldb9a6a2372014-08-19 23:43:00 +0100125 u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100126};
127
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100128enum bma180_chan {
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100129 AXIS_X,
130 AXIS_Y,
131 AXIS_Z,
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100132 TEMP
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100133};
134
Peter Meerwaldcab767d2014-08-19 23:43:00 +0100135static int bma180_bw_table[] = { 10, 20, 40, 75, 150, 300 }; /* Hz */
136static int bma180_scale_table[] = { 1275, 1863, 2452, 3727, 4903, 9709, 19417 };
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100137
Peter Meerwald2017cff2014-08-19 23:43:00 +0100138static int bma250_bw_table[] = { 8, 16, 31, 63, 125, 250 }; /* Hz */
139static int bma250_scale_table[] = { 0, 0, 0, 38344, 0, 76590, 0, 0, 153180, 0,
140 0, 0, 306458 };
141
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100142static int bma180_get_data_reg(struct bma180_data *data, enum bma180_chan chan)
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100143{
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100144 int ret;
145
146 if (data->sleep_state)
147 return -EBUSY;
148
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100149 switch (chan) {
150 case TEMP:
151 ret = i2c_smbus_read_byte_data(data->client, BMA180_TEMP);
152 if (ret < 0)
153 dev_err(&data->client->dev, "failed to read temp register\n");
154 break;
155 default:
156 ret = i2c_smbus_read_word_data(data->client,
157 BMA180_ACC_X_LSB + chan * 2);
158 if (ret < 0)
159 dev_err(&data->client->dev,
160 "failed to read accel_%c register\n",
161 'x' + chan);
162 }
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100163
164 return ret;
165}
166
167static int bma180_set_bits(struct bma180_data *data, u8 reg, u8 mask, u8 val)
168{
169 int ret = i2c_smbus_read_byte_data(data->client, reg);
170 u8 reg_val = (ret & ~mask) | (val << (ffs(mask) - 1));
171
172 if (ret < 0)
173 return ret;
174
175 return i2c_smbus_write_byte_data(data->client, reg, reg_val);
176}
177
178static int bma180_reset_intr(struct bma180_data *data)
179{
Peter Meerwald2017cff2014-08-19 23:43:00 +0100180 int ret = bma180_set_bits(data, data->part_info->int_reset_reg,
181 data->part_info->int_reset_mask, 1);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100182
183 if (ret)
184 dev_err(&data->client->dev, "failed to reset interrupt\n");
185
186 return ret;
187}
188
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100189static int bma180_set_new_data_intr_state(struct bma180_data *data, bool state)
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100190{
Peter Meerwald2017cff2014-08-19 23:43:00 +0100191 int ret = bma180_set_bits(data, data->part_info->int_enable_reg,
192 data->part_info->int_enable_mask, state);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100193 if (ret)
194 goto err;
195 ret = bma180_reset_intr(data);
196 if (ret)
197 goto err;
198
199 return 0;
200
201err:
202 dev_err(&data->client->dev,
203 "failed to set new data interrupt state %d\n", state);
204 return ret;
205}
206
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100207static int bma180_set_sleep_state(struct bma180_data *data, bool state)
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100208{
Peter Meerwald2017cff2014-08-19 23:43:00 +0100209 int ret = bma180_set_bits(data, data->part_info->sleep_reg,
210 data->part_info->sleep_mask, state);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100211
212 if (ret) {
213 dev_err(&data->client->dev,
214 "failed to set sleep state %d\n", state);
215 return ret;
216 }
217 data->sleep_state = state;
218
219 return 0;
220}
221
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100222static int bma180_set_ee_writing_state(struct bma180_data *data, bool state)
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100223{
224 int ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_EE_W, state);
225
226 if (ret)
227 dev_err(&data->client->dev,
228 "failed to set ee writing state %d\n", state);
229
230 return ret;
231}
232
233static int bma180_set_bw(struct bma180_data *data, int val)
234{
235 int ret, i;
236
237 if (data->sleep_state)
238 return -EBUSY;
239
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100240 for (i = 0; i < data->part_info->num_bw; ++i) {
241 if (data->part_info->bw_table[i] == val) {
Peter Meerwald2017cff2014-08-19 23:43:00 +0100242 ret = bma180_set_bits(data, data->part_info->bw_reg,
243 data->part_info->bw_mask, i);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100244 if (ret) {
245 dev_err(&data->client->dev,
246 "failed to set bandwidth\n");
247 return ret;
248 }
249 data->bw = val;
250 return 0;
251 }
252 }
253
254 return -EINVAL;
255}
256
257static int bma180_set_scale(struct bma180_data *data, int val)
258{
259 int ret, i;
260
261 if (data->sleep_state)
262 return -EBUSY;
263
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100264 for (i = 0; i < data->part_info->num_scales; ++i)
265 if (data->part_info->scale_table[i] == val) {
Peter Meerwald2017cff2014-08-19 23:43:00 +0100266 ret = bma180_set_bits(data, data->part_info->scale_reg,
267 data->part_info->scale_mask, i);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100268 if (ret) {
269 dev_err(&data->client->dev,
270 "failed to set scale\n");
271 return ret;
272 }
273 data->scale = val;
274 return 0;
275 }
276
277 return -EINVAL;
278}
279
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100280static int bma180_set_pmode(struct bma180_data *data, bool mode)
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100281{
Peter Meerwald2017cff2014-08-19 23:43:00 +0100282 u8 reg_val = mode ? data->part_info->lowpower_val : 0;
283 int ret = bma180_set_bits(data, data->part_info->power_reg,
284 data->part_info->power_mask, reg_val);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100285
286 if (ret) {
287 dev_err(&data->client->dev, "failed to set power mode\n");
288 return ret;
289 }
290 data->pmode = mode;
291
292 return 0;
293}
294
295static int bma180_soft_reset(struct bma180_data *data)
296{
297 int ret = i2c_smbus_write_byte_data(data->client,
Peter Meerwald2017cff2014-08-19 23:43:00 +0100298 data->part_info->softreset_reg, BMA180_RESET_VAL);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100299
300 if (ret)
301 dev_err(&data->client->dev, "failed to reset the chip\n");
302
303 return ret;
304}
305
306static int bma180_chip_init(struct bma180_data *data)
307{
308 /* Try to read chip_id register. It must return 0x03. */
309 int ret = i2c_smbus_read_byte_data(data->client, BMA180_CHIP_ID);
310
311 if (ret < 0)
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100312 return ret;
313 if (ret != BMA180_ID_REG_VAL)
314 return -ENODEV;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100315
316 ret = bma180_soft_reset(data);
317 if (ret)
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100318 return ret;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100319 /*
320 * No serial transaction should occur within minimum 10 us
321 * after soft_reset command
322 */
323 msleep(20);
324
Peter Meerwald2017cff2014-08-19 23:43:00 +0100325 ret = bma180_set_new_data_intr_state(data, false);
326 if (ret)
327 return ret;
328
329 return bma180_set_pmode(data, false);
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100330}
331
332static int bma180_chip_config(struct bma180_data *data)
333{
334 int ret = bma180_chip_init(data);
335
336 if (ret)
337 goto err;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100338 ret = bma180_set_bits(data, BMA180_CTRL_REG0, BMA180_DIS_WAKE_UP, 1);
339 if (ret)
340 goto err;
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100341 ret = bma180_set_ee_writing_state(data, true);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100342 if (ret)
343 goto err;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100344 ret = bma180_set_bits(data, BMA180_OFFSET_LSB1, BMA180_SMP_SKIP, 1);
345 if (ret)
346 goto err;
Peter Meerwald2017cff2014-08-19 23:43:00 +0100347 ret = bma180_set_bw(data, 20); /* 20 Hz */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100348 if (ret)
349 goto err;
Peter Meerwald2017cff2014-08-19 23:43:00 +0100350 ret = bma180_set_scale(data, 2452); /* 2 G */
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100351 if (ret)
352 goto err;
Peter Meerwald2017cff2014-08-19 23:43:00 +0100353
354 return 0;
355
356err:
357 dev_err(&data->client->dev, "failed to config the chip\n");
358 return ret;
359}
360
361static int bma250_chip_config(struct bma180_data *data)
362{
363 int ret = bma180_chip_init(data);
364
365 if (ret)
366 goto err;
367 ret = bma180_set_bw(data, 16); /* 16 Hz */
368 if (ret)
369 goto err;
370 ret = bma180_set_scale(data, 38344); /* 2 G */
371 if (ret)
372 goto err;
373 ret = bma180_set_bits(data, BMA250_INT_MAP_REG,
374 BMA250_INT1_DATA_MASK, 1);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100375 if (ret)
376 goto err;
377
378 return 0;
379
380err:
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100381 dev_err(&data->client->dev, "failed to config the chip\n");
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100382 return ret;
383}
384
385static void bma180_chip_disable(struct bma180_data *data)
386{
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100387 if (bma180_set_new_data_intr_state(data, false))
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100388 goto err;
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100389 if (bma180_set_ee_writing_state(data, false))
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100390 goto err;
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100391 if (bma180_set_sleep_state(data, true))
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100392 goto err;
393
394 return;
395
396err:
397 dev_err(&data->client->dev, "failed to disable the chip\n");
398}
399
Peter Meerwald2017cff2014-08-19 23:43:00 +0100400static void bma250_chip_disable(struct bma180_data *data)
401{
402 if (bma180_set_new_data_intr_state(data, false))
403 goto err;
404 if (bma180_set_sleep_state(data, true))
405 goto err;
406
407 return;
408
409err:
410 dev_err(&data->client->dev, "failed to disable the chip\n");
411}
412
Miguel Robles7fa67902017-03-17 00:35:45 +0100413static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned int n,
Peter Meerwald402a3242014-08-19 23:43:00 +0100414 bool micros)
415{
416 size_t len = 0;
417 int i;
418
419 for (i = 0; i < n; i++) {
420 if (!vals[i])
421 continue;
422 len += scnprintf(buf + len, PAGE_SIZE - len,
423 micros ? "0.%06d " : "%d ", vals[i]);
424 }
425 buf[len - 1] = '\n';
426
427 return len;
428}
429
430static ssize_t bma180_show_filter_freq_avail(struct device *dev,
431 struct device_attribute *attr, char *buf)
432{
433 struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
434
435 return bma180_show_avail(buf, data->part_info->bw_table,
436 data->part_info->num_bw, false);
437}
438
439static ssize_t bma180_show_scale_avail(struct device *dev,
440 struct device_attribute *attr, char *buf)
441{
442 struct bma180_data *data = iio_priv(dev_to_iio_dev(dev));
443
444 return bma180_show_avail(buf, data->part_info->scale_table,
445 data->part_info->num_scales, true);
446}
447
448static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
449 S_IRUGO, bma180_show_filter_freq_avail, NULL, 0);
450
451static IIO_DEVICE_ATTR(in_accel_scale_available,
452 S_IRUGO, bma180_show_scale_avail, NULL, 0);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100453
454static struct attribute *bma180_attributes[] = {
Peter Meerwald402a3242014-08-19 23:43:00 +0100455 &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.
456 dev_attr.attr,
457 &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100458 NULL,
459};
460
461static const struct attribute_group bma180_attrs_group = {
462 .attrs = bma180_attributes,
463};
464
465static int bma180_read_raw(struct iio_dev *indio_dev,
466 struct iio_chan_spec const *chan, int *val, int *val2,
467 long mask)
468{
469 struct bma180_data *data = iio_priv(indio_dev);
470 int ret;
471
472 switch (mask) {
473 case IIO_CHAN_INFO_RAW:
Alison Schofieldb75b58b2016-07-25 12:11:20 -0700474 ret = iio_device_claim_direct_mode(indio_dev);
475 if (ret)
476 return ret;
477
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100478 mutex_lock(&data->mutex);
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100479 ret = bma180_get_data_reg(data, chan->scan_index);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100480 mutex_unlock(&data->mutex);
Alison Schofieldb75b58b2016-07-25 12:11:20 -0700481 iio_device_release_direct_mode(indio_dev);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100482 if (ret < 0)
483 return ret;
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100484 *val = sign_extend32(ret >> chan->scan_type.shift,
485 chan->scan_type.realbits - 1);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100486 return IIO_VAL_INT;
487 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
488 *val = data->bw;
489 return IIO_VAL_INT;
490 case IIO_CHAN_INFO_SCALE:
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100491 switch (chan->type) {
492 case IIO_ACCEL:
493 *val = 0;
494 *val2 = data->scale;
495 return IIO_VAL_INT_PLUS_MICRO;
496 case IIO_TEMP:
497 *val = 500;
498 return IIO_VAL_INT;
499 default:
500 return -EINVAL;
501 }
502 case IIO_CHAN_INFO_OFFSET:
503 *val = 48; /* 0 LSB @ 24 degree C */
504 return IIO_VAL_INT;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100505 default:
506 return -EINVAL;
507 }
508}
509
510static int bma180_write_raw(struct iio_dev *indio_dev,
511 struct iio_chan_spec const *chan, int val, int val2, long mask)
512{
513 struct bma180_data *data = iio_priv(indio_dev);
514 int ret;
515
516 switch (mask) {
517 case IIO_CHAN_INFO_SCALE:
518 if (val)
519 return -EINVAL;
520 mutex_lock(&data->mutex);
521 ret = bma180_set_scale(data, val2);
522 mutex_unlock(&data->mutex);
523 return ret;
524 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
Peter Meerwald9b2a4d32014-07-16 19:32:00 +0100525 if (val2)
526 return -EINVAL;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100527 mutex_lock(&data->mutex);
528 ret = bma180_set_bw(data, val);
529 mutex_unlock(&data->mutex);
530 return ret;
531 default:
532 return -EINVAL;
533 }
534}
535
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100536static const struct iio_info bma180_info = {
537 .attrs = &bma180_attrs_group,
538 .read_raw = bma180_read_raw,
539 .write_raw = bma180_write_raw,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100540};
541
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100542static const char * const bma180_power_modes[] = { "low_noise", "low_power" };
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100543
544static int bma180_get_power_mode(struct iio_dev *indio_dev,
545 const struct iio_chan_spec *chan)
546{
547 struct bma180_data *data = iio_priv(indio_dev);
548
549 return data->pmode;
550}
551
552static int bma180_set_power_mode(struct iio_dev *indio_dev,
553 const struct iio_chan_spec *chan, unsigned int mode)
554{
555 struct bma180_data *data = iio_priv(indio_dev);
556 int ret;
557
558 mutex_lock(&data->mutex);
559 ret = bma180_set_pmode(data, mode);
560 mutex_unlock(&data->mutex);
561
562 return ret;
563}
564
H. Nikolaus Schaller587c2be2019-02-21 18:02:49 +0100565static const struct iio_mount_matrix *
566bma180_accel_get_mount_matrix(const struct iio_dev *indio_dev,
567 const struct iio_chan_spec *chan)
568{
569 struct bma180_data *data = iio_priv(indio_dev);
570
571 return &data->orientation;
572}
573
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100574static const struct iio_enum bma180_power_mode_enum = {
575 .items = bma180_power_modes,
576 .num_items = ARRAY_SIZE(bma180_power_modes),
577 .get = bma180_get_power_mode,
578 .set = bma180_set_power_mode,
579};
580
581static const struct iio_chan_spec_ext_info bma180_ext_info[] = {
582 IIO_ENUM("power_mode", true, &bma180_power_mode_enum),
583 IIO_ENUM_AVAILABLE("power_mode", &bma180_power_mode_enum),
H. Nikolaus Schaller587c2be2019-02-21 18:02:49 +0100584 IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, bma180_accel_get_mount_matrix),
585 { }
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100586};
587
Peter Meerwald6377aa42014-08-19 23:43:00 +0100588#define BMA180_ACC_CHANNEL(_axis, _bits) { \
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100589 .type = IIO_ACCEL, \
Peter Meerwald55852152014-10-01 21:37:00 +0100590 .modified = 1, \
591 .channel2 = IIO_MOD_##_axis, \
Peter Meerwald5c1449d2014-10-01 21:37:00 +0100592 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
593 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100594 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \
Peter Meerwald55852152014-10-01 21:37:00 +0100595 .scan_index = AXIS_##_axis, \
Jonathan Cameron7d7feae2013-12-11 18:45:00 +0000596 .scan_type = { \
597 .sign = 's', \
Peter Meerwald6377aa42014-08-19 23:43:00 +0100598 .realbits = _bits, \
Jonathan Cameron7d7feae2013-12-11 18:45:00 +0000599 .storagebits = 16, \
Peter Meerwald6377aa42014-08-19 23:43:00 +0100600 .shift = 16 - _bits, \
Jonathan Cameron7d7feae2013-12-11 18:45:00 +0000601 }, \
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100602 .ext_info = bma180_ext_info, \
603}
604
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100605#define BMA180_TEMP_CHANNEL { \
606 .type = IIO_TEMP, \
607 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
608 BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), \
609 .scan_index = TEMP, \
610 .scan_type = { \
611 .sign = 's', \
612 .realbits = 8, \
613 .storagebits = 16, \
614 }, \
615}
616
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100617static const struct iio_chan_spec bma180_channels[] = {
Peter Meerwald6377aa42014-08-19 23:43:00 +0100618 BMA180_ACC_CHANNEL(X, 14),
619 BMA180_ACC_CHANNEL(Y, 14),
620 BMA180_ACC_CHANNEL(Z, 14),
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100621 BMA180_TEMP_CHANNEL,
622 IIO_CHAN_SOFT_TIMESTAMP(4),
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100623};
624
Peter Meerwald2017cff2014-08-19 23:43:00 +0100625static const struct iio_chan_spec bma250_channels[] = {
626 BMA180_ACC_CHANNEL(X, 10),
627 BMA180_ACC_CHANNEL(Y, 10),
628 BMA180_ACC_CHANNEL(Z, 10),
629 BMA180_TEMP_CHANNEL,
630 IIO_CHAN_SOFT_TIMESTAMP(4),
631};
632
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100633static const struct bma180_part_info bma180_part_info[] = {
634 [BMA180] = {
635 bma180_channels, ARRAY_SIZE(bma180_channels),
636 bma180_scale_table, ARRAY_SIZE(bma180_scale_table),
637 bma180_bw_table, ARRAY_SIZE(bma180_bw_table),
Peter Meerwald2017cff2014-08-19 23:43:00 +0100638 BMA180_CTRL_REG0, BMA180_RESET_INT,
639 BMA180_CTRL_REG0, BMA180_SLEEP,
640 BMA180_BW_TCS, BMA180_BW,
641 BMA180_OFFSET_LSB1, BMA180_RANGE,
642 BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER,
643 BMA180_CTRL_REG3, BMA180_NEW_DATA_INT,
644 BMA180_RESET,
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100645 bma180_chip_config,
646 bma180_chip_disable,
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100647 },
Peter Meerwald2017cff2014-08-19 23:43:00 +0100648 [BMA250] = {
649 bma250_channels, ARRAY_SIZE(bma250_channels),
650 bma250_scale_table, ARRAY_SIZE(bma250_scale_table),
651 bma250_bw_table, ARRAY_SIZE(bma250_bw_table),
652 BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK,
653 BMA250_POWER_REG, BMA250_SUSPEND_MASK,
654 BMA250_BW_REG, BMA250_BW_MASK,
655 BMA250_RANGE_REG, BMA250_RANGE_MASK,
656 BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1,
657 BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK,
658 BMA250_RESET_REG,
659 bma250_chip_config,
660 bma250_chip_disable,
661 },
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100662};
663
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100664static irqreturn_t bma180_trigger_handler(int irq, void *p)
665{
666 struct iio_poll_func *pf = p;
667 struct iio_dev *indio_dev = pf->indio_dev;
668 struct bma180_data *data = iio_priv(indio_dev);
Gregor Boiriebc2b7da2016-03-09 19:05:49 +0100669 s64 time_ns = iio_get_time_ns(indio_dev);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100670 int bit, ret, i = 0;
671
672 mutex_lock(&data->mutex);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100673
Octavian Purdila70dddee2015-03-02 21:03:05 +0200674 for_each_set_bit(bit, indio_dev->active_scan_mask,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100675 indio_dev->masklength) {
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100676 ret = bma180_get_data_reg(data, bit);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100677 if (ret < 0) {
678 mutex_unlock(&data->mutex);
679 goto err;
680 }
681 ((s16 *)data->buff)[i++] = ret;
682 }
Peter Meerwaldb81fbab2014-08-19 23:43:00 +0100683
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100684 mutex_unlock(&data->mutex);
685
Lars-Peter Clausen6bf9d8772013-09-19 13:59:00 +0100686 iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100687err:
688 iio_trigger_notify_done(indio_dev->trig);
689
690 return IRQ_HANDLED;
691}
692
693static int bma180_data_rdy_trigger_set_state(struct iio_trigger *trig,
694 bool state)
695{
696 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
697 struct bma180_data *data = iio_priv(indio_dev);
698
699 return bma180_set_new_data_intr_state(data, state);
700}
701
702static int bma180_trig_try_reen(struct iio_trigger *trig)
703{
704 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
705 struct bma180_data *data = iio_priv(indio_dev);
706
707 return bma180_reset_intr(data);
708}
709
710static const struct iio_trigger_ops bma180_trigger_ops = {
711 .set_trigger_state = bma180_data_rdy_trigger_set_state,
712 .try_reenable = bma180_trig_try_reen,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100713};
714
715static int bma180_probe(struct i2c_client *client,
716 const struct i2c_device_id *id)
717{
718 struct bma180_data *data;
719 struct iio_dev *indio_dev;
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -0300720 enum chip_ids chip;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100721 int ret;
722
723 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
724 if (!indio_dev)
725 return -ENOMEM;
726
727 data = iio_priv(indio_dev);
728 i2c_set_clientdata(client, indio_dev);
729 data->client = client;
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -0300730 if (client->dev.of_node)
731 chip = (enum chip_ids)of_device_get_match_data(&client->dev);
732 else
733 chip = id->driver_data;
734 data->part_info = &bma180_part_info[chip];
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100735
H. Nikolaus Schaller587c2be2019-02-21 18:02:49 +0100736 ret = iio_read_mount_matrix(&client->dev, "mount-matrix",
737 &data->orientation);
738 if (ret)
739 return ret;
740
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100741 ret = data->part_info->chip_config(data);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100742 if (ret < 0)
743 goto err_chip_disable;
744
745 mutex_init(&data->mutex);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100746 indio_dev->dev.parent = &client->dev;
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100747 indio_dev->channels = data->part_info->channels;
748 indio_dev->num_channels = data->part_info->num_channels;
Peter Meerwald2017cff2014-08-19 23:43:00 +0100749 indio_dev->name = id->name;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100750 indio_dev->modes = INDIO_DIRECT_MODE;
751 indio_dev->info = &bma180_info;
752
Peter Meerwald16ed8692014-08-19 23:43:00 +0100753 if (client->irq > 0) {
754 data->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
755 indio_dev->id);
756 if (!data->trig) {
757 ret = -ENOMEM;
758 goto err_chip_disable;
759 }
760
761 ret = devm_request_irq(&client->dev, client->irq,
762 iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING,
Peter Meerwald2017cff2014-08-19 23:43:00 +0100763 "bma180_event", data->trig);
Peter Meerwald16ed8692014-08-19 23:43:00 +0100764 if (ret) {
765 dev_err(&client->dev, "unable to request IRQ\n");
766 goto err_trigger_free;
767 }
768
769 data->trig->dev.parent = &client->dev;
770 data->trig->ops = &bma180_trigger_ops;
771 iio_trigger_set_drvdata(data->trig, indio_dev);
Greg Kroah-Hartman8deab472014-09-22 07:54:10 -0700772 indio_dev->trig = iio_trigger_get(data->trig);
Peter Meerwald16ed8692014-08-19 23:43:00 +0100773
774 ret = iio_trigger_register(data->trig);
775 if (ret)
776 goto err_trigger_free;
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100777 }
778
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100779 ret = iio_triggered_buffer_setup(indio_dev, NULL,
780 bma180_trigger_handler, NULL);
781 if (ret < 0) {
782 dev_err(&client->dev, "unable to setup iio triggered buffer\n");
783 goto err_trigger_unregister;
784 }
785
786 ret = iio_device_register(indio_dev);
787 if (ret < 0) {
788 dev_err(&client->dev, "unable to register iio device\n");
789 goto err_buffer_cleanup;
790 }
791
792 return 0;
793
794err_buffer_cleanup:
795 iio_triggered_buffer_cleanup(indio_dev);
796err_trigger_unregister:
Peter Meerwald16ed8692014-08-19 23:43:00 +0100797 if (data->trig)
798 iio_trigger_unregister(data->trig);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100799err_trigger_free:
Peter Meerwald16ed8692014-08-19 23:43:00 +0100800 iio_trigger_free(data->trig);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100801err_chip_disable:
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100802 data->part_info->chip_disable(data);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100803
804 return ret;
805}
806
807static int bma180_remove(struct i2c_client *client)
808{
809 struct iio_dev *indio_dev = i2c_get_clientdata(client);
810 struct bma180_data *data = iio_priv(indio_dev);
811
812 iio_device_unregister(indio_dev);
813 iio_triggered_buffer_cleanup(indio_dev);
Peter Meerwald16ed8692014-08-19 23:43:00 +0100814 if (data->trig) {
815 iio_trigger_unregister(data->trig);
816 iio_trigger_free(data->trig);
817 }
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100818
819 mutex_lock(&data->mutex);
Peter Meerwaldc1949ec2014-08-19 23:43:00 +0100820 data->part_info->chip_disable(data);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100821 mutex_unlock(&data->mutex);
822
823 return 0;
824}
825
826#ifdef CONFIG_PM_SLEEP
827static int bma180_suspend(struct device *dev)
828{
Peter Meerwald234efa12013-09-18 22:47:00 +0100829 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100830 struct bma180_data *data = iio_priv(indio_dev);
831 int ret;
832
833 mutex_lock(&data->mutex);
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100834 ret = bma180_set_sleep_state(data, true);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100835 mutex_unlock(&data->mutex);
836
837 return ret;
838}
839
840static int bma180_resume(struct device *dev)
841{
Peter Meerwald234efa12013-09-18 22:47:00 +0100842 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100843 struct bma180_data *data = iio_priv(indio_dev);
844 int ret;
845
846 mutex_lock(&data->mutex);
Peter Meerwaldc7c69e82014-08-19 23:43:00 +0100847 ret = bma180_set_sleep_state(data, false);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100848 mutex_unlock(&data->mutex);
849
850 return ret;
851}
852
853static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
854#define BMA180_PM_OPS (&bma180_pm_ops)
855#else
856#define BMA180_PM_OPS NULL
857#endif
858
Arvind Yadave05d83b2017-08-20 00:17:36 +0530859static const struct i2c_device_id bma180_ids[] = {
Peter Meerwald2017cff2014-08-19 23:43:00 +0100860 { "bma180", BMA180 },
861 { "bma250", BMA250 },
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100862 { }
863};
864
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100865MODULE_DEVICE_TABLE(i2c, bma180_ids);
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100866
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -0300867static const struct of_device_id bma180_of_match[] = {
868 {
869 .compatible = "bosch,bma180",
870 .data = (void *)BMA180
871 },
872 {
873 .compatible = "bosch,bma250",
874 .data = (void *)BMA250
875 },
876 { }
877};
878MODULE_DEVICE_TABLE(of, bma180_of_match);
879
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100880static struct i2c_driver bma180_driver = {
881 .driver = {
Peter Meerwald2017cff2014-08-19 23:43:00 +0100882 .name = "bma180",
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100883 .pm = BMA180_PM_OPS,
Javier Martinez Canillas16f1b4f2017-03-15 01:44:57 -0300884 .of_match_table = bma180_of_match,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100885 },
886 .probe = bma180_probe,
887 .remove = bma180_remove,
Peter Meerwald1b9030f2014-08-19 23:43:00 +0100888 .id_table = bma180_ids,
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100889};
890
891module_i2c_driver(bma180_driver);
892
893MODULE_AUTHOR("Kravchenko Oleksandr <x0199363@ti.com>");
894MODULE_AUTHOR("Texas Instruments, Inc.");
Peter Meerwald2017cff2014-08-19 23:43:00 +0100895MODULE_DESCRIPTION("Bosch BMA180/BMA250 triaxial acceleration sensor");
Oleksandr Kravchenkofdadbce2013-08-28 12:01:00 +0100896MODULE_LICENSE("GPL");