1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * BMA220 Digital triaxial acceleration sensor driver 4 * 5 * Copyright (c) 2016,2020 Intel Corporation. 6 * Copyright (c) 2025 Petre Rodan <petre.rodan@subdimension.ro> 7 */ 8 9 #include <linux/bits.h> 10 #include <linux/bitfield.h> 11 #include <linux/cleanup.h> 12 #include <linux/device.h> 13 #include <linux/errno.h> 14 #include <linux/module.h> 15 #include <linux/mutex.h> 16 #include <linux/pm.h> 17 #include <linux/regmap.h> 18 #include <linux/regulator/consumer.h> 19 #include <linux/types.h> 20 21 #include <linux/iio/buffer.h> 22 #include <linux/iio/iio.h> 23 #include <linux/iio/sysfs.h> 24 #include <linux/iio/trigger.h> 25 #include <linux/iio/trigger_consumer.h> 26 #include <linux/iio/triggered_buffer.h> 27 28 #include "bma220.h" 29 30 #define BMA220_REG_ID 0x00 31 #define BMA220_REG_REVISION_ID 0x01 32 #define BMA220_REG_ACCEL_X 0x02 33 #define BMA220_REG_ACCEL_Y 0x03 34 #define BMA220_REG_ACCEL_Z 0x04 35 #define BMA220_REG_CONF0 0x05 36 #define BMA220_HIGH_DUR_MSK GENMASK(5, 0) 37 #define BMA220_HIGH_HY_MSK GENMASK(7, 6) 38 #define BMA220_REG_CONF1 0x06 39 #define BMA220_HIGH_TH_MSK GENMASK(3, 0) 40 #define BMA220_LOW_TH_MSK GENMASK(7, 4) 41 #define BMA220_REG_CONF2 0x07 42 #define BMA220_LOW_DUR_MSK GENMASK(5, 0) 43 #define BMA220_LOW_HY_MSK GENMASK(7, 6) 44 #define BMA220_REG_CONF3 0x08 45 #define BMA220_TT_DUR_MSK GENMASK(2, 0) 46 #define BMA220_TT_TH_MSK GENMASK(6, 3) 47 #define BMA220_REG_CONF4 0x09 48 #define BMA220_SLOPE_DUR_MSK GENMASK(1, 0) 49 #define BMA220_SLOPE_TH_MSK GENMASK(5, 2) 50 #define BMA220_REG_CONF5 0x0a 51 #define BMA220_TIP_EN_MSK BIT(4) 52 #define BMA220_REG_IF0 0x0b 53 #define BMA220_REG_IF1 0x0c 54 #define BMA220_IF_SLOPE BIT(0) 55 #define BMA220_IF_DRDY BIT(1) 56 #define BMA220_IF_HIGH BIT(2) 57 #define BMA220_IF_LOW BIT(3) 58 #define BMA220_IF_TT BIT(4) 59 #define BMA220_REG_IE0 0x0d 60 #define BMA220_INT_EN_TAP_Z_MSK BIT(0) 61 #define BMA220_INT_EN_TAP_Y_MSK BIT(1) 62 #define BMA220_INT_EN_TAP_X_MSK BIT(2) 63 #define BMA220_INT_EN_SLOPE_Z_MSK BIT(3) 64 #define BMA220_INT_EN_SLOPE_Y_MSK BIT(4) 65 #define BMA220_INT_EN_SLOPE_X_MSK BIT(5) 66 #define BMA220_INT_EN_DRDY_MSK BIT(7) 67 #define BMA220_REG_IE1 0x0e 68 #define BMA220_INT_EN_HIGH_Z_MSK BIT(0) 69 #define BMA220_INT_EN_HIGH_Y_MSK BIT(1) 70 #define BMA220_INT_EN_HIGH_X_MSK BIT(2) 71 #define BMA220_INT_EN_LOW_MSK BIT(3) 72 #define BMA220_INT_LATCH_MSK GENMASK(6, 4) 73 #define BMA220_INT_RST_MSK BIT(7) 74 #define BMA220_REG_IE2 0x0f 75 #define BMA220_REG_FILTER 0x10 76 #define BMA220_FILTER_MASK GENMASK(3, 0) 77 #define BMA220_REG_RANGE 0x11 78 #define BMA220_RANGE_MASK GENMASK(1, 0) 79 #define BMA220_REG_SUSPEND 0x18 80 #define BMA220_REG_SOFTRESET 0x19 81 82 #define BMA220_CHIP_ID 0xDD 83 #define BMA220_SUSPEND_SLEEP 0xFF 84 #define BMA220_SUSPEND_WAKE 0x00 85 #define BMA220_RESET_MODE 0xFF 86 #define BMA220_NONRESET_MODE 0x00 87 88 #define BMA220_DEVICE_NAME "bma220" 89 90 #define BMA220_COF_1000Hz 0x0 91 #define BMA220_COF_500Hz 0x1 92 #define BMA220_COF_250Hz 0x2 93 #define BMA220_COF_125Hz 0x3 94 #define BMA220_COF_64Hz 0x4 95 #define BMA220_COF_32Hz 0x5 96 97 #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ 98 .type = IIO_ACCEL, \ 99 .address = reg, \ 100 .modified = 1, \ 101 .channel2 = IIO_MOD_##axis, \ 102 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 103 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 104 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 105 .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) |\ 106 BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 107 .scan_index = index, \ 108 .scan_type = { \ 109 .sign = 's', \ 110 .realbits = 6, \ 111 .storagebits = 8, \ 112 .shift = 2, \ 113 .endianness = IIO_CPU, \ 114 }, \ 115 } 116 117 enum bma220_axis { 118 AXIS_X, 119 AXIS_Y, 120 AXIS_Z, 121 }; 122 123 static const int bma220_scale_table[][2] = { 124 { 0, 623000 }, { 1, 248000 }, { 2, 491000 }, { 4, 983000 }, 125 }; 126 127 struct bma220_data { 128 struct regmap *regmap; 129 struct mutex lock; 130 u8 lpf_3dB_freq_idx; 131 u8 range_idx; 132 struct iio_trigger *trig; 133 struct { 134 s8 chans[3]; 135 /* Ensure timestamp is naturally aligned. */ 136 aligned_s64 timestamp; 137 } scan __aligned(IIO_DMA_MINALIGN); 138 }; 139 140 static const struct iio_chan_spec bma220_channels[] = { 141 BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X, X), 142 BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y, Y), 143 BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z, Z), 144 IIO_CHAN_SOFT_TIMESTAMP(3), 145 }; 146 147 /* Available cut-off frequencies of the low pass filter in Hz. */ 148 static const int bma220_lpf_3dB_freq_Hz_table[] = { 149 [BMA220_COF_1000Hz] = 1000, 150 [BMA220_COF_500Hz] = 500, 151 [BMA220_COF_250Hz] = 250, 152 [BMA220_COF_125Hz] = 125, 153 [BMA220_COF_64Hz] = 64, 154 [BMA220_COF_32Hz] = 32, 155 }; 156 157 static const unsigned long bma220_accel_scan_masks[] = { 158 BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 159 0 160 }; 161 162 static bool bma220_is_writable_reg(struct device *dev, unsigned int reg) 163 { 164 switch (reg) { 165 case BMA220_REG_CONF0: 166 case BMA220_REG_CONF1: 167 case BMA220_REG_CONF2: 168 case BMA220_REG_CONF3: 169 case BMA220_REG_CONF4: 170 case BMA220_REG_CONF5: 171 case BMA220_REG_IE0: 172 case BMA220_REG_IE1: 173 case BMA220_REG_IE2: 174 case BMA220_REG_FILTER: 175 case BMA220_REG_RANGE: 176 case BMA220_REG_WDT: 177 return true; 178 default: 179 return false; 180 } 181 } 182 183 const struct regmap_config bma220_spi_regmap_config = { 184 .reg_bits = 8, 185 .val_bits = 8, 186 .read_flag_mask = BIT(7), 187 .max_register = BMA220_REG_SOFTRESET, 188 .cache_type = REGCACHE_NONE, 189 .writeable_reg = bma220_is_writable_reg, 190 }; 191 EXPORT_SYMBOL_NS_GPL(bma220_spi_regmap_config, "IIO_BOSCH_BMA220"); 192 193 /* 194 * Based on the datasheet the memory map differs between the SPI and the I2C 195 * implementations. I2C register addresses are simply shifted to the left 196 * by 1 bit yet the register size remains unchanged. 197 * This driver employs the SPI memory map to correlate register names to 198 * addresses regardless of the bus type. 199 */ 200 201 const struct regmap_config bma220_i2c_regmap_config = { 202 .reg_bits = 8, 203 .val_bits = 8, 204 .reg_shift = -1, 205 .max_register = BMA220_REG_SOFTRESET, 206 .cache_type = REGCACHE_NONE, 207 .writeable_reg = bma220_is_writable_reg, 208 }; 209 EXPORT_SYMBOL_NS_GPL(bma220_i2c_regmap_config, "IIO_BOSCH_BMA220"); 210 211 static int bma220_data_rdy_trigger_set_state(struct iio_trigger *trig, 212 bool state) 213 { 214 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 215 struct bma220_data *data = iio_priv(indio_dev); 216 217 return regmap_update_bits(data->regmap, BMA220_REG_IE0, 218 BMA220_INT_EN_DRDY_MSK, 219 FIELD_PREP(BMA220_INT_EN_DRDY_MSK, state)); 220 } 221 222 static const struct iio_trigger_ops bma220_trigger_ops = { 223 .set_trigger_state = &bma220_data_rdy_trigger_set_state, 224 .validate_device = &iio_trigger_validate_own_device, 225 }; 226 227 static irqreturn_t bma220_trigger_handler(int irq, void *p) 228 { 229 int ret; 230 struct iio_poll_func *pf = p; 231 struct iio_dev *indio_dev = pf->indio_dev; 232 struct bma220_data *data = iio_priv(indio_dev); 233 234 ret = regmap_bulk_read(data->regmap, BMA220_REG_ACCEL_X, 235 &data->scan.chans, 236 sizeof(data->scan.chans)); 237 if (ret < 0) 238 return IRQ_NONE; 239 240 iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), 241 iio_get_time_ns(indio_dev)); 242 iio_trigger_notify_done(indio_dev->trig); 243 244 return IRQ_HANDLED; 245 } 246 247 static int bma220_read_raw(struct iio_dev *indio_dev, 248 struct iio_chan_spec const *chan, 249 int *val, int *val2, long mask) 250 { 251 int ret; 252 u8 index; 253 unsigned int reg; 254 struct bma220_data *data = iio_priv(indio_dev); 255 256 guard(mutex)(&data->lock); 257 258 switch (mask) { 259 case IIO_CHAN_INFO_RAW: 260 ret = regmap_read(data->regmap, chan->address, ®); 261 if (ret < 0) 262 return -EINVAL; 263 *val = sign_extend32(reg >> chan->scan_type.shift, 264 chan->scan_type.realbits - 1); 265 return IIO_VAL_INT; 266 case IIO_CHAN_INFO_SCALE: 267 index = data->range_idx; 268 *val = bma220_scale_table[index][0]; 269 *val2 = bma220_scale_table[index][1]; 270 return IIO_VAL_INT_PLUS_MICRO; 271 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 272 index = data->lpf_3dB_freq_idx; 273 *val = bma220_lpf_3dB_freq_Hz_table[index]; 274 return IIO_VAL_INT; 275 } 276 277 return -EINVAL; 278 } 279 280 static int bma220_find_match_2dt(const int (*tbl)[2], const int n, 281 const int val, const int val2) 282 { 283 int i; 284 285 for (i = 0; i < n; i++) { 286 if (tbl[i][0] == val && tbl[i][1] == val2) 287 return i; 288 } 289 290 return -EINVAL; 291 } 292 293 static int bma220_find_match(const int *arr, const int n, const int val) 294 { 295 int i; 296 297 for (i = 0; i < n; i++) { 298 if (arr[i] == val) 299 return i; 300 } 301 302 return -EINVAL; 303 } 304 305 static int bma220_write_raw(struct iio_dev *indio_dev, 306 struct iio_chan_spec const *chan, 307 int val, int val2, long mask) 308 { 309 int ret; 310 int index = -1; 311 struct bma220_data *data = iio_priv(indio_dev); 312 313 guard(mutex)(&data->lock); 314 315 switch (mask) { 316 case IIO_CHAN_INFO_SCALE: 317 index = bma220_find_match_2dt(bma220_scale_table, 318 ARRAY_SIZE(bma220_scale_table), 319 val, val2); 320 if (index < 0) 321 return -EINVAL; 322 323 ret = regmap_update_bits(data->regmap, BMA220_REG_RANGE, 324 BMA220_RANGE_MASK, 325 FIELD_PREP(BMA220_RANGE_MASK, index)); 326 if (ret < 0) 327 return ret; 328 data->range_idx = index; 329 330 return 0; 331 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 332 index = bma220_find_match(bma220_lpf_3dB_freq_Hz_table, 333 ARRAY_SIZE(bma220_lpf_3dB_freq_Hz_table), 334 val); 335 if (index < 0) 336 return -EINVAL; 337 338 ret = regmap_update_bits(data->regmap, BMA220_REG_FILTER, 339 BMA220_FILTER_MASK, 340 FIELD_PREP(BMA220_FILTER_MASK, index)); 341 if (ret < 0) 342 return ret; 343 data->lpf_3dB_freq_idx = index; 344 345 return 0; 346 } 347 348 return -EINVAL; 349 } 350 351 static int bma220_read_avail(struct iio_dev *indio_dev, 352 struct iio_chan_spec const *chan, 353 const int **vals, int *type, int *length, 354 long mask) 355 { 356 switch (mask) { 357 case IIO_CHAN_INFO_SCALE: 358 *vals = (int *)bma220_scale_table; 359 *type = IIO_VAL_INT_PLUS_MICRO; 360 *length = ARRAY_SIZE(bma220_scale_table) * 2; 361 return IIO_AVAIL_LIST; 362 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 363 *vals = (const int *)bma220_lpf_3dB_freq_Hz_table; 364 *type = IIO_VAL_INT; 365 *length = ARRAY_SIZE(bma220_lpf_3dB_freq_Hz_table); 366 return IIO_AVAIL_LIST; 367 default: 368 return -EINVAL; 369 } 370 } 371 372 static int bma220_reg_access(struct iio_dev *indio_dev, unsigned int reg, 373 unsigned int writeval, unsigned int *readval) 374 { 375 struct bma220_data *data = iio_priv(indio_dev); 376 377 if (readval) 378 return regmap_read(data->regmap, reg, readval); 379 return regmap_write(data->regmap, reg, writeval); 380 } 381 382 static const struct iio_info bma220_info = { 383 .read_raw = bma220_read_raw, 384 .write_raw = bma220_write_raw, 385 .read_avail = bma220_read_avail, 386 .debugfs_reg_access = &bma220_reg_access, 387 }; 388 389 static int bma220_reset(struct bma220_data *data, bool up) 390 { 391 int ret; 392 unsigned int i, val; 393 394 /* 395 * The chip can be reset by a simple register read. 396 * We need up to 2 register reads of the softreset register 397 * to make sure that the device is in the desired state. 398 */ 399 for (i = 0; i < 2; i++) { 400 ret = regmap_read(data->regmap, BMA220_REG_SOFTRESET, &val); 401 if (ret < 0) 402 return ret; 403 404 if (up && val == BMA220_RESET_MODE) 405 return 0; 406 407 if (!up && val == BMA220_NONRESET_MODE) 408 return 0; 409 } 410 411 return -EBUSY; 412 } 413 414 static int bma220_power(struct bma220_data *data, bool up) 415 { 416 int ret; 417 unsigned int i, val; 418 419 /* 420 * The chip can be suspended/woken up by a simple register read. 421 * So, we need up to 2 register reads of the suspend register 422 * to make sure that the device is in the desired state. 423 */ 424 for (i = 0; i < 2; i++) { 425 ret = regmap_read(data->regmap, BMA220_REG_SUSPEND, &val); 426 if (ret < 0) 427 return ret; 428 429 if (up && val == BMA220_SUSPEND_SLEEP) 430 return 0; 431 432 if (!up && val == BMA220_SUSPEND_WAKE) 433 return 0; 434 } 435 436 return -EBUSY; 437 } 438 439 static int bma220_init(struct device *dev, struct bma220_data *data) 440 { 441 int ret; 442 unsigned int val; 443 static const char * const regulator_names[] = { "vddd", "vddio", "vdda" }; 444 445 ret = devm_regulator_bulk_get_enable(dev, 446 ARRAY_SIZE(regulator_names), 447 regulator_names); 448 if (ret) 449 return dev_err_probe(dev, ret, "Failed to get regulators\n"); 450 451 ret = regmap_read(data->regmap, BMA220_REG_ID, &val); 452 if (ret) 453 return dev_err_probe(dev, ret, 454 "Failed to read chip id register\n"); 455 456 if (val != BMA220_CHIP_ID) 457 dev_info(dev, "Unknown chip found: 0x%02x\n", val); 458 459 ret = bma220_power(data, true); 460 if (ret) 461 return dev_err_probe(dev, ret, "Failed to power-on chip\n"); 462 463 ret = bma220_reset(data, true); 464 if (ret) 465 return dev_err_probe(dev, ret, "Failed to soft reset chip\n"); 466 467 return 0; 468 } 469 470 static void bma220_deinit(void *data_ptr) 471 { 472 struct bma220_data *data = data_ptr; 473 int ret; 474 struct device *dev = regmap_get_device(data->regmap); 475 476 ret = bma220_power(data, false); 477 if (ret) 478 dev_warn(dev, 479 "Failed to put device into suspend mode (%pe)\n", 480 ERR_PTR(ret)); 481 } 482 483 static irqreturn_t bma220_irq_handler(int irq, void *private) 484 { 485 struct iio_dev *indio_dev = private; 486 struct bma220_data *data = iio_priv(indio_dev); 487 int ret; 488 unsigned int bma220_reg_if1; 489 490 ret = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1); 491 if (ret) 492 return IRQ_NONE; 493 494 if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) 495 iio_trigger_poll_nested(data->trig); 496 497 return IRQ_HANDLED; 498 } 499 500 int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq) 501 { 502 int ret; 503 struct iio_dev *indio_dev; 504 struct bma220_data *data; 505 506 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 507 if (!indio_dev) 508 return -ENOMEM; 509 510 data = iio_priv(indio_dev); 511 data->regmap = regmap; 512 513 ret = bma220_init(dev, data); 514 if (ret) 515 return ret; 516 517 ret = devm_mutex_init(dev, &data->lock); 518 if (ret) 519 return ret; 520 521 indio_dev->info = &bma220_info; 522 indio_dev->name = BMA220_DEVICE_NAME; 523 indio_dev->modes = INDIO_DIRECT_MODE; 524 indio_dev->channels = bma220_channels; 525 indio_dev->num_channels = ARRAY_SIZE(bma220_channels); 526 indio_dev->available_scan_masks = bma220_accel_scan_masks; 527 528 if (irq > 0) { 529 data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 530 indio_dev->name, 531 iio_device_id(indio_dev)); 532 if (!data->trig) 533 return -ENOMEM; 534 535 data->trig->ops = &bma220_trigger_ops; 536 iio_trigger_set_drvdata(data->trig, indio_dev); 537 538 ret = devm_iio_trigger_register(dev, data->trig); 539 if (ret) 540 return dev_err_probe(dev, ret, 541 "iio trigger register fail\n"); 542 indio_dev->trig = iio_trigger_get(data->trig); 543 ret = devm_request_threaded_irq(dev, irq, NULL, 544 &bma220_irq_handler, IRQF_ONESHOT, 545 indio_dev->name, indio_dev); 546 if (ret) 547 return ret; 548 } 549 550 ret = devm_add_action_or_reset(dev, bma220_deinit, data); 551 if (ret) 552 return ret; 553 554 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 555 bma220_trigger_handler, NULL); 556 if (ret < 0) 557 dev_err_probe(dev, ret, "iio triggered buffer setup failed\n"); 558 559 return devm_iio_device_register(dev, indio_dev); 560 } 561 EXPORT_SYMBOL_NS_GPL(bma220_common_probe, "IIO_BOSCH_BMA220"); 562 563 static int bma220_suspend(struct device *dev) 564 { 565 struct iio_dev *indio_dev = dev_get_drvdata(dev); 566 struct bma220_data *data = iio_priv(indio_dev); 567 568 return bma220_power(data, false); 569 } 570 571 static int bma220_resume(struct device *dev) 572 { 573 struct iio_dev *indio_dev = dev_get_drvdata(dev); 574 struct bma220_data *data = iio_priv(indio_dev); 575 576 return bma220_power(data, true); 577 } 578 EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume, 579 IIO_BOSCH_BMA220); 580 581 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); 582 MODULE_DESCRIPTION("BMA220 acceleration sensor driver"); 583 MODULE_LICENSE("GPL"); 584