2306 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * IIO core driver for Bosch BMI323 6-Axis IMU.4 *5 * Copyright (C) 2023, Jagath Jog J <jagathjog1996@gmail.com>6 *7 * Datasheet: https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi323-ds000.pdf8 */9 10#include <linux/bitfield.h>11#include <linux/cleanup.h>12#include <linux/device.h>13#include <linux/interrupt.h>14#include <linux/minmax.h>15#include <linux/module.h>16#include <linux/mutex.h>17#include <linux/property.h>18#include <linux/regmap.h>19#include <linux/regulator/consumer.h>20#include <linux/units.h>21 22#include <linux/unaligned.h>23 24#include <linux/iio/buffer.h>25#include <linux/iio/events.h>26#include <linux/iio/iio.h>27#include <linux/iio/sysfs.h>28#include <linux/iio/trigger.h>29#include <linux/iio/trigger_consumer.h>30#include <linux/iio/triggered_buffer.h>31 32#include "bmi323.h"33 34enum bmi323_sensor_type {35 BMI323_ACCEL,36 BMI323_GYRO,37 BMI323_SENSORS_CNT,38};39 40enum bmi323_opr_mode {41 ACC_GYRO_MODE_DISABLE = 0x00,42 GYRO_DRIVE_MODE_ENABLED = 0x01,43 ACC_GYRO_MODE_DUTYCYCLE = 0x03,44 ACC_GYRO_MODE_CONTINOUS = 0x04,45 ACC_GYRO_MODE_HIGH_PERF = 0x07,46};47 48enum bmi323_state {49 BMI323_IDLE,50 BMI323_BUFFER_DRDY_TRIGGERED,51 BMI323_BUFFER_FIFO,52};53 54enum bmi323_irq_pin {55 BMI323_IRQ_DISABLED,56 BMI323_IRQ_INT1,57 BMI323_IRQ_INT2,58};59 60enum bmi323_3db_bw {61 BMI323_BW_ODR_BY_2,62 BMI323_BW_ODR_BY_4,63};64 65enum bmi323_scan {66 BMI323_ACCEL_X,67 BMI323_ACCEL_Y,68 BMI323_ACCEL_Z,69 BMI323_GYRO_X,70 BMI323_GYRO_Y,71 BMI323_GYRO_Z,72 BMI323_CHAN_MAX73};74 75struct bmi323_hw {76 u8 data;77 u8 config;78 const int (*scale_table)[2];79 int scale_table_len;80};81 82/*83 * The accelerometer supports +-2G/4G/8G/16G ranges, and the resolution of84 * each sample is 16 bits, signed.85 * At +-8G the scale can calculated by86 * ((8 + 8) * 9.80665 / (2^16 - 1)) * 10^6 = 2394.23819 scale in micro87 *88 */89static const int bmi323_accel_scale[][2] = {90 { 0, 598 },91 { 0, 1197 },92 { 0, 2394 },93 { 0, 4788 },94};95 96static const int bmi323_gyro_scale[][2] = {97 { 0, 66 },98 { 0, 133 },99 { 0, 266 },100 { 0, 532 },101 { 0, 1065 },102};103 104static const int bmi323_accel_gyro_avrg[] = {0, 2, 4, 8, 16, 32, 64};105 106static const struct bmi323_hw bmi323_hw[2] = {107 [BMI323_ACCEL] = {108 .data = BMI323_ACCEL_X_REG,109 .config = BMI323_ACC_CONF_REG,110 .scale_table = bmi323_accel_scale,111 .scale_table_len = ARRAY_SIZE(bmi323_accel_scale),112 },113 [BMI323_GYRO] = {114 .data = BMI323_GYRO_X_REG,115 .config = BMI323_GYRO_CONF_REG,116 .scale_table = bmi323_gyro_scale,117 .scale_table_len = ARRAY_SIZE(bmi323_gyro_scale),118 },119};120 121static const unsigned int bmi323_reg_savestate[] = {122 BMI323_INT_MAP1_REG,123 BMI323_INT_MAP2_REG,124 BMI323_IO_INT_CTR_REG,125 BMI323_IO_INT_CONF_REG,126 BMI323_ACC_CONF_REG,127 BMI323_GYRO_CONF_REG,128 BMI323_FEAT_IO0_REG,129 BMI323_FIFO_WTRMRK_REG,130 BMI323_FIFO_CONF_REG131};132 133static const unsigned int bmi323_ext_reg_savestate[] = {134 BMI323_GEN_SET1_REG,135 BMI323_TAP1_REG,136 BMI323_TAP2_REG,137 BMI323_TAP3_REG,138 BMI323_FEAT_IO0_S_TAP_MSK,139 BMI323_STEP_SC1_REG,140 BMI323_ANYMO1_REG,141 BMI323_NOMO1_REG,142 BMI323_ANYMO1_REG + BMI323_MO2_OFFSET,143 BMI323_NOMO1_REG + BMI323_MO2_OFFSET,144 BMI323_ANYMO1_REG + BMI323_MO3_OFFSET,145 BMI323_NOMO1_REG + BMI323_MO3_OFFSET146};147 148struct bmi323_regs_runtime_pm {149 unsigned int reg_settings[ARRAY_SIZE(bmi323_reg_savestate)];150 unsigned int ext_reg_settings[ARRAY_SIZE(bmi323_ext_reg_savestate)];151};152 153struct bmi323_data {154 struct device *dev;155 struct regmap *regmap;156 struct iio_mount_matrix orientation;157 enum bmi323_irq_pin irq_pin;158 struct iio_trigger *trig;159 bool drdy_trigger_enabled;160 enum bmi323_state state;161 s64 fifo_tstamp, old_fifo_tstamp;162 u32 odrns[BMI323_SENSORS_CNT];163 u32 odrhz[BMI323_SENSORS_CNT];164 unsigned int feature_events;165 struct bmi323_regs_runtime_pm runtime_pm_status;166 167 /*168 * Lock to protect the members of device's private data from concurrent169 * access and also to serialize the access of extended registers.170 * See bmi323_write_ext_reg(..) for more info.171 */172 struct mutex mutex;173 int watermark;174 __le16 fifo_buff[BMI323_FIFO_FULL_IN_WORDS] __aligned(IIO_DMA_MINALIGN);175 struct {176 __le16 channels[BMI323_CHAN_MAX];177 s64 ts __aligned(8);178 } buffer;179 __le16 steps_count[BMI323_STEP_LEN];180};181 182static const struct iio_mount_matrix *183bmi323_get_mount_matrix(const struct iio_dev *idev,184 const struct iio_chan_spec *chan)185{186 struct bmi323_data *data = iio_priv(idev);187 188 return &data->orientation;189}190 191static const struct iio_chan_spec_ext_info bmi323_ext_info[] = {192 IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, bmi323_get_mount_matrix),193 { }194};195 196static const struct iio_event_spec bmi323_step_wtrmrk_event = {197 .type = IIO_EV_TYPE_CHANGE,198 .dir = IIO_EV_DIR_NONE,199 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |200 BIT(IIO_EV_INFO_VALUE),201};202 203static const struct iio_event_spec bmi323_accel_event[] = {204 {205 .type = IIO_EV_TYPE_MAG,206 .dir = IIO_EV_DIR_FALLING,207 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |208 BIT(IIO_EV_INFO_PERIOD) |209 BIT(IIO_EV_INFO_HYSTERESIS) |210 BIT(IIO_EV_INFO_ENABLE),211 },212 {213 .type = IIO_EV_TYPE_MAG,214 .dir = IIO_EV_DIR_RISING,215 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |216 BIT(IIO_EV_INFO_PERIOD) |217 BIT(IIO_EV_INFO_HYSTERESIS) |218 BIT(IIO_EV_INFO_ENABLE),219 },220 {221 .type = IIO_EV_TYPE_GESTURE,222 .dir = IIO_EV_DIR_SINGLETAP,223 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |224 BIT(IIO_EV_INFO_VALUE) |225 BIT(IIO_EV_INFO_RESET_TIMEOUT),226 },227 {228 .type = IIO_EV_TYPE_GESTURE,229 .dir = IIO_EV_DIR_DOUBLETAP,230 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) |231 BIT(IIO_EV_INFO_VALUE) |232 BIT(IIO_EV_INFO_RESET_TIMEOUT) |233 BIT(IIO_EV_INFO_TAP2_MIN_DELAY),234 },235};236 237#define BMI323_ACCEL_CHANNEL(_type, _axis, _index) { \238 .type = _type, \239 .modified = 1, \240 .channel2 = IIO_MOD_##_axis, \241 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \242 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \243 BIT(IIO_CHAN_INFO_SCALE) | \244 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \245 .info_mask_shared_by_type_available = \246 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \247 BIT(IIO_CHAN_INFO_SCALE) | \248 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \249 .scan_index = _index, \250 .scan_type = { \251 .sign = 's', \252 .realbits = 16, \253 .storagebits = 16, \254 .endianness = IIO_LE, \255 }, \256 .ext_info = bmi323_ext_info, \257 .event_spec = bmi323_accel_event, \258 .num_event_specs = ARRAY_SIZE(bmi323_accel_event), \259}260 261#define BMI323_GYRO_CHANNEL(_type, _axis, _index) { \262 .type = _type, \263 .modified = 1, \264 .channel2 = IIO_MOD_##_axis, \265 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \266 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \267 BIT(IIO_CHAN_INFO_SCALE) | \268 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \269 .info_mask_shared_by_type_available = \270 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \271 BIT(IIO_CHAN_INFO_SCALE) | \272 BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \273 .scan_index = _index, \274 .scan_type = { \275 .sign = 's', \276 .realbits = 16, \277 .storagebits = 16, \278 .endianness = IIO_LE, \279 }, \280 .ext_info = bmi323_ext_info, \281}282 283static const struct iio_chan_spec bmi323_channels[] = {284 BMI323_ACCEL_CHANNEL(IIO_ACCEL, X, BMI323_ACCEL_X),285 BMI323_ACCEL_CHANNEL(IIO_ACCEL, Y, BMI323_ACCEL_Y),286 BMI323_ACCEL_CHANNEL(IIO_ACCEL, Z, BMI323_ACCEL_Z),287 BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, X, BMI323_GYRO_X),288 BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, Y, BMI323_GYRO_Y),289 BMI323_GYRO_CHANNEL(IIO_ANGL_VEL, Z, BMI323_GYRO_Z),290 {291 .type = IIO_TEMP,292 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |293 BIT(IIO_CHAN_INFO_OFFSET) |294 BIT(IIO_CHAN_INFO_SCALE),295 .scan_index = -1,296 },297 {298 .type = IIO_STEPS,299 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |300 BIT(IIO_CHAN_INFO_ENABLE),301 .scan_index = -1,302 .event_spec = &bmi323_step_wtrmrk_event,303 .num_event_specs = 1,304 305 },306 IIO_CHAN_SOFT_TIMESTAMP(BMI323_CHAN_MAX),307};308 309static const int bmi323_acc_gyro_odr[][2] = {310 { 0, 781250 },311 { 1, 562500 },312 { 3, 125000 },313 { 6, 250000 },314 { 12, 500000 },315 { 25, 0 },316 { 50, 0 },317 { 100, 0 },318 { 200, 0 },319 { 400, 0 },320 { 800, 0 },321};322 323static const int bmi323_acc_gyro_odrns[] = {324 1280 * MEGA,325 640 * MEGA,326 320 * MEGA,327 160 * MEGA,328 80 * MEGA,329 40 * MEGA,330 20 * MEGA,331 10 * MEGA,332 5 * MEGA,333 2500 * KILO,334 1250 * KILO,335};336 337static enum bmi323_sensor_type bmi323_iio_to_sensor(enum iio_chan_type iio_type)338{339 switch (iio_type) {340 case IIO_ACCEL:341 return BMI323_ACCEL;342 case IIO_ANGL_VEL:343 return BMI323_GYRO;344 default:345 return -EINVAL;346 }347}348 349static int bmi323_set_mode(struct bmi323_data *data,350 enum bmi323_sensor_type sensor,351 enum bmi323_opr_mode mode)352{353 guard(mutex)(&data->mutex);354 return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,355 BMI323_ACC_GYRO_CONF_MODE_MSK,356 FIELD_PREP(BMI323_ACC_GYRO_CONF_MODE_MSK,357 mode));358}359 360/*361 * When writing data to extended register there must be no communication to362 * any other register before write transaction is complete.363 * See datasheet section 6.2 Extended Register Map Description.364 */365static int bmi323_write_ext_reg(struct bmi323_data *data, unsigned int ext_addr,366 unsigned int ext_data)367{368 int ret, feature_status;369 370 ret = regmap_read(data->regmap, BMI323_FEAT_DATA_STATUS,371 &feature_status);372 if (ret)373 return ret;374 375 if (!FIELD_GET(BMI323_FEAT_DATA_TX_RDY_MSK, feature_status))376 return -EBUSY;377 378 ret = regmap_write(data->regmap, BMI323_FEAT_DATA_ADDR, ext_addr);379 if (ret)380 return ret;381 382 return regmap_write(data->regmap, BMI323_FEAT_DATA_TX, ext_data);383}384 385/*386 * When reading data from extended register there must be no communication to387 * any other register before read transaction is complete.388 * See datasheet section 6.2 Extended Register Map Description.389 */390static int bmi323_read_ext_reg(struct bmi323_data *data, unsigned int ext_addr,391 unsigned int *ext_data)392{393 int ret, feature_status;394 395 ret = regmap_read(data->regmap, BMI323_FEAT_DATA_STATUS,396 &feature_status);397 if (ret)398 return ret;399 400 if (!FIELD_GET(BMI323_FEAT_DATA_TX_RDY_MSK, feature_status))401 return -EBUSY;402 403 ret = regmap_write(data->regmap, BMI323_FEAT_DATA_ADDR, ext_addr);404 if (ret)405 return ret;406 407 return regmap_read(data->regmap, BMI323_FEAT_DATA_TX, ext_data);408}409 410static int bmi323_update_ext_reg(struct bmi323_data *data,411 unsigned int ext_addr,412 unsigned int mask, unsigned int ext_data)413{414 unsigned int value;415 int ret;416 417 ret = bmi323_read_ext_reg(data, ext_addr, &value);418 if (ret)419 return ret;420 421 set_mask_bits(&value, mask, ext_data);422 423 return bmi323_write_ext_reg(data, ext_addr, value);424}425 426static int bmi323_get_error_status(struct bmi323_data *data)427{428 int error, ret;429 430 guard(mutex)(&data->mutex);431 ret = regmap_read(data->regmap, BMI323_ERR_REG, &error);432 if (ret)433 return ret;434 435 if (error)436 dev_err(data->dev, "Sensor error 0x%x\n", error);437 438 return error;439}440 441static int bmi323_feature_engine_events(struct bmi323_data *data,442 const unsigned int event_mask,443 bool state)444{445 unsigned int value;446 int ret;447 448 ret = regmap_read(data->regmap, BMI323_FEAT_IO0_REG, &value);449 if (ret)450 return ret;451 452 /* Register must be cleared before changing an active config */453 ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0);454 if (ret)455 return ret;456 457 if (state)458 value |= event_mask;459 else460 value &= ~event_mask;461 462 ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, value);463 if (ret)464 return ret;465 466 return regmap_write(data->regmap, BMI323_FEAT_IO_STATUS_REG,467 BMI323_FEAT_IO_STATUS_MSK);468}469 470static int bmi323_step_wtrmrk_en(struct bmi323_data *data, int state)471{472 enum bmi323_irq_pin step_irq;473 int ret;474 475 guard(mutex)(&data->mutex);476 if (!FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK, data->feature_events))477 return -EINVAL;478 479 if (state)480 step_irq = data->irq_pin;481 else482 step_irq = BMI323_IRQ_DISABLED;483 484 ret = bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,485 BMI323_STEP_SC1_WTRMRK_MSK,486 FIELD_PREP(BMI323_STEP_SC1_WTRMRK_MSK,487 state ? 1 : 0));488 if (ret)489 return ret;490 491 return regmap_update_bits(data->regmap, BMI323_INT_MAP1_REG,492 BMI323_STEP_CNT_MSK,493 FIELD_PREP(BMI323_STEP_CNT_MSK, step_irq));494}495 496static int bmi323_motion_config_reg(enum iio_event_direction dir)497{498 switch (dir) {499 case IIO_EV_DIR_RISING:500 return BMI323_ANYMO1_REG;501 case IIO_EV_DIR_FALLING:502 return BMI323_NOMO1_REG;503 default:504 return -EINVAL;505 }506}507 508static int bmi323_motion_event_en(struct bmi323_data *data,509 enum iio_event_direction dir, int state)510{511 unsigned int state_value = state ? BMI323_FEAT_XYZ_MSK : 0;512 int config, ret, msk, raw, field_value;513 enum bmi323_irq_pin motion_irq;514 int irq_msk, irq_field_val;515 516 if (state)517 motion_irq = data->irq_pin;518 else519 motion_irq = BMI323_IRQ_DISABLED;520 521 switch (dir) {522 case IIO_EV_DIR_RISING:523 msk = BMI323_FEAT_IO0_XYZ_MOTION_MSK;524 raw = 512;525 config = BMI323_ANYMO1_REG;526 irq_msk = BMI323_MOTION_MSK;527 irq_field_val = FIELD_PREP(BMI323_MOTION_MSK, motion_irq);528 field_value = FIELD_PREP(BMI323_FEAT_IO0_XYZ_MOTION_MSK,529 state_value);530 break;531 case IIO_EV_DIR_FALLING:532 msk = BMI323_FEAT_IO0_XYZ_NOMOTION_MSK;533 raw = 0;534 config = BMI323_NOMO1_REG;535 irq_msk = BMI323_NOMOTION_MSK;536 irq_field_val = FIELD_PREP(BMI323_NOMOTION_MSK, motion_irq);537 field_value = FIELD_PREP(BMI323_FEAT_IO0_XYZ_NOMOTION_MSK,538 state_value);539 break;540 default:541 return -EINVAL;542 }543 544 guard(mutex)(&data->mutex);545 ret = bmi323_feature_engine_events(data, msk, state);546 if (ret)547 return ret;548 549 ret = bmi323_update_ext_reg(data, config,550 BMI323_MO1_REF_UP_MSK,551 FIELD_PREP(BMI323_MO1_REF_UP_MSK, 0));552 if (ret)553 return ret;554 555 /* Set initial value to avoid interrupts while enabling*/556 ret = bmi323_update_ext_reg(data, config,557 BMI323_MO1_SLOPE_TH_MSK,558 FIELD_PREP(BMI323_MO1_SLOPE_TH_MSK, raw));559 if (ret)560 return ret;561 562 ret = regmap_update_bits(data->regmap, BMI323_INT_MAP1_REG, irq_msk,563 irq_field_val);564 if (ret)565 return ret;566 567 set_mask_bits(&data->feature_events, msk, field_value);568 569 return 0;570}571 572static int bmi323_tap_event_en(struct bmi323_data *data,573 enum iio_event_direction dir, int state)574{575 enum bmi323_irq_pin tap_irq;576 int ret, tap_enabled;577 578 guard(mutex)(&data->mutex);579 580 if (data->odrhz[BMI323_ACCEL] < 200) {581 dev_err(data->dev, "Invalid accelerometer parameter\n");582 return -EINVAL;583 }584 585 switch (dir) {586 case IIO_EV_DIR_SINGLETAP:587 ret = bmi323_feature_engine_events(data,588 BMI323_FEAT_IO0_S_TAP_MSK,589 state);590 if (ret)591 return ret;592 593 set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_S_TAP_MSK,594 FIELD_PREP(BMI323_FEAT_IO0_S_TAP_MSK, state));595 break;596 case IIO_EV_DIR_DOUBLETAP:597 ret = bmi323_feature_engine_events(data,598 BMI323_FEAT_IO0_D_TAP_MSK,599 state);600 if (ret)601 return ret;602 603 set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_D_TAP_MSK,604 FIELD_PREP(BMI323_FEAT_IO0_D_TAP_MSK, state));605 break;606 default:607 return -EINVAL;608 }609 610 tap_enabled = FIELD_GET(BMI323_FEAT_IO0_S_TAP_MSK |611 BMI323_FEAT_IO0_D_TAP_MSK,612 data->feature_events);613 614 if (tap_enabled)615 tap_irq = data->irq_pin;616 else617 tap_irq = BMI323_IRQ_DISABLED;618 619 ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,620 BMI323_TAP_MSK,621 FIELD_PREP(BMI323_TAP_MSK, tap_irq));622 if (ret)623 return ret;624 625 if (!state)626 return 0;627 628 ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,629 BMI323_TAP1_MAX_PEAKS_MSK,630 FIELD_PREP(BMI323_TAP1_MAX_PEAKS_MSK,631 0x04));632 if (ret)633 return ret;634 635 ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,636 BMI323_TAP1_AXIS_SEL_MSK,637 FIELD_PREP(BMI323_TAP1_AXIS_SEL_MSK,638 BMI323_AXIS_XYZ_MSK));639 if (ret)640 return ret;641 642 return bmi323_update_ext_reg(data, BMI323_TAP1_REG,643 BMI323_TAP1_TIMOUT_MSK,644 FIELD_PREP(BMI323_TAP1_TIMOUT_MSK,645 0));646}647 648static ssize_t in_accel_gesture_tap_wait_dur_show(struct device *dev,649 struct device_attribute *attr,650 char *buf)651{652 struct iio_dev *indio_dev = dev_to_iio_dev(dev);653 struct bmi323_data *data = iio_priv(indio_dev);654 unsigned int reg_value, raw;655 int ret, val[2];656 657 scoped_guard(mutex, &data->mutex) {658 ret = bmi323_read_ext_reg(data, BMI323_TAP2_REG, ®_value);659 if (ret)660 return ret;661 }662 663 raw = FIELD_GET(BMI323_TAP2_MAX_DUR_MSK, reg_value);664 val[0] = raw / BMI323_MAX_GES_DUR_SCALE;665 val[1] = BMI323_RAW_TO_MICRO(raw, BMI323_MAX_GES_DUR_SCALE);666 667 return iio_format_value(buf, IIO_VAL_INT_PLUS_MICRO, ARRAY_SIZE(val),668 val);669}670 671static ssize_t in_accel_gesture_tap_wait_dur_store(struct device *dev,672 struct device_attribute *attr,673 const char *buf, size_t len)674{675 struct iio_dev *indio_dev = dev_to_iio_dev(dev);676 struct bmi323_data *data = iio_priv(indio_dev);677 int ret, val_int, val_fract, raw;678 679 ret = iio_str_to_fixpoint(buf, 100000, &val_int, &val_fract);680 if (ret)681 return ret;682 683 raw = BMI323_INT_MICRO_TO_RAW(val_int, val_fract,684 BMI323_MAX_GES_DUR_SCALE);685 if (!in_range(raw, 0, 64))686 return -EINVAL;687 688 guard(mutex)(&data->mutex);689 ret = bmi323_update_ext_reg(data, BMI323_TAP2_REG,690 BMI323_TAP2_MAX_DUR_MSK,691 FIELD_PREP(BMI323_TAP2_MAX_DUR_MSK, raw));692 if (ret)693 return ret;694 695 return len;696}697 698/*699 * Maximum duration from first tap within the second tap is expected to happen.700 * This timeout is applicable only if gesture_tap_wait_timeout is enabled.701 */702static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_wait_dur, 0);703 704static ssize_t in_accel_gesture_tap_wait_timeout_show(struct device *dev,705 struct device_attribute *attr,706 char *buf)707{708 struct iio_dev *indio_dev = dev_to_iio_dev(dev);709 struct bmi323_data *data = iio_priv(indio_dev);710 unsigned int reg_value, raw;711 int ret;712 713 scoped_guard(mutex, &data->mutex) {714 ret = bmi323_read_ext_reg(data, BMI323_TAP1_REG, ®_value);715 if (ret)716 return ret;717 }718 719 raw = FIELD_GET(BMI323_TAP1_TIMOUT_MSK, reg_value);720 721 return iio_format_value(buf, IIO_VAL_INT, 1, &raw);722}723 724static ssize_t in_accel_gesture_tap_wait_timeout_store(struct device *dev,725 struct device_attribute *attr,726 const char *buf,727 size_t len)728{729 struct iio_dev *indio_dev = dev_to_iio_dev(dev);730 struct bmi323_data *data = iio_priv(indio_dev);731 bool val;732 int ret;733 734 ret = kstrtobool(buf, &val);735 if (ret)736 return ret;737 738 guard(mutex)(&data->mutex);739 ret = bmi323_update_ext_reg(data, BMI323_TAP1_REG,740 BMI323_TAP1_TIMOUT_MSK,741 FIELD_PREP(BMI323_TAP1_TIMOUT_MSK, val));742 if (ret)743 return ret;744 745 return len;746}747 748/* Enable/disable gesture confirmation with wait time */749static IIO_DEVICE_ATTR_RW(in_accel_gesture_tap_wait_timeout, 0);750 751static IIO_CONST_ATTR(in_accel_gesture_tap_wait_dur_available,752 "[0.0 0.04 2.52]");753 754static IIO_CONST_ATTR(in_accel_gesture_doubletap_tap2_min_delay_available,755 "[0.005 0.005 0.075]");756 757static IIO_CONST_ATTR(in_accel_gesture_tap_reset_timeout_available,758 "[0.04 0.04 0.6]");759 760static IIO_CONST_ATTR(in_accel_gesture_tap_value_available, "[0.0 0.002 1.99]");761 762static IIO_CONST_ATTR(in_accel_mag_value_available, "[0.0 0.002 7.99]");763 764static IIO_CONST_ATTR(in_accel_mag_period_available, "[0.0 0.02 162.0]");765 766static IIO_CONST_ATTR(in_accel_mag_hysteresis_available, "[0.0 0.002 1.99]");767 768static struct attribute *bmi323_event_attributes[] = {769 &iio_const_attr_in_accel_gesture_tap_value_available.dev_attr.attr,770 &iio_const_attr_in_accel_gesture_tap_reset_timeout_available.dev_attr.attr,771 &iio_const_attr_in_accel_gesture_doubletap_tap2_min_delay_available.dev_attr.attr,772 &iio_const_attr_in_accel_gesture_tap_wait_dur_available.dev_attr.attr,773 &iio_dev_attr_in_accel_gesture_tap_wait_timeout.dev_attr.attr,774 &iio_dev_attr_in_accel_gesture_tap_wait_dur.dev_attr.attr,775 &iio_const_attr_in_accel_mag_value_available.dev_attr.attr,776 &iio_const_attr_in_accel_mag_period_available.dev_attr.attr,777 &iio_const_attr_in_accel_mag_hysteresis_available.dev_attr.attr,778 NULL779};780 781static const struct attribute_group bmi323_event_attribute_group = {782 .attrs = bmi323_event_attributes,783};784 785static int bmi323_write_event_config(struct iio_dev *indio_dev,786 const struct iio_chan_spec *chan,787 enum iio_event_type type,788 enum iio_event_direction dir, int state)789{790 struct bmi323_data *data = iio_priv(indio_dev);791 792 switch (type) {793 case IIO_EV_TYPE_MAG:794 return bmi323_motion_event_en(data, dir, state);795 case IIO_EV_TYPE_GESTURE:796 return bmi323_tap_event_en(data, dir, state);797 case IIO_EV_TYPE_CHANGE:798 return bmi323_step_wtrmrk_en(data, state);799 default:800 return -EINVAL;801 }802}803 804static int bmi323_read_event_config(struct iio_dev *indio_dev,805 const struct iio_chan_spec *chan,806 enum iio_event_type type,807 enum iio_event_direction dir)808{809 struct bmi323_data *data = iio_priv(indio_dev);810 int ret, value, reg_val;811 812 guard(mutex)(&data->mutex);813 814 switch (chan->type) {815 case IIO_ACCEL:816 switch (dir) {817 case IIO_EV_DIR_SINGLETAP:818 ret = FIELD_GET(BMI323_FEAT_IO0_S_TAP_MSK,819 data->feature_events);820 break;821 case IIO_EV_DIR_DOUBLETAP:822 ret = FIELD_GET(BMI323_FEAT_IO0_D_TAP_MSK,823 data->feature_events);824 break;825 case IIO_EV_DIR_RISING:826 value = FIELD_GET(BMI323_FEAT_IO0_XYZ_MOTION_MSK,827 data->feature_events);828 ret = value ? 1 : 0;829 break;830 case IIO_EV_DIR_FALLING:831 value = FIELD_GET(BMI323_FEAT_IO0_XYZ_NOMOTION_MSK,832 data->feature_events);833 ret = value ? 1 : 0;834 break;835 default:836 ret = -EINVAL;837 break;838 }839 return ret;840 case IIO_STEPS:841 ret = regmap_read(data->regmap, BMI323_INT_MAP1_REG, ®_val);842 if (ret)843 return ret;844 845 return FIELD_GET(BMI323_STEP_CNT_MSK, reg_val) ? 1 : 0;846 default:847 return -EINVAL;848 }849}850 851static int bmi323_write_event_value(struct iio_dev *indio_dev,852 const struct iio_chan_spec *chan,853 enum iio_event_type type,854 enum iio_event_direction dir,855 enum iio_event_info info,856 int val, int val2)857{858 struct bmi323_data *data = iio_priv(indio_dev);859 unsigned int raw;860 int reg;861 862 guard(mutex)(&data->mutex);863 864 switch (type) {865 case IIO_EV_TYPE_GESTURE:866 switch (info) {867 case IIO_EV_INFO_VALUE:868 if (!in_range(val, 0, 2))869 return -EINVAL;870 871 raw = BMI323_INT_MICRO_TO_RAW(val, val2,872 BMI323_TAP_THRES_SCALE);873 874 return bmi323_update_ext_reg(data, BMI323_TAP2_REG,875 BMI323_TAP2_THRES_MSK,876 FIELD_PREP(BMI323_TAP2_THRES_MSK,877 raw));878 case IIO_EV_INFO_RESET_TIMEOUT:879 if (val || !in_range(val2, 40000, 560001))880 return -EINVAL;881 882 raw = BMI323_INT_MICRO_TO_RAW(val, val2,883 BMI323_QUITE_TIM_GES_SCALE);884 885 return bmi323_update_ext_reg(data, BMI323_TAP3_REG,886 BMI323_TAP3_QT_AFT_GES_MSK,887 FIELD_PREP(BMI323_TAP3_QT_AFT_GES_MSK,888 raw));889 case IIO_EV_INFO_TAP2_MIN_DELAY:890 if (val || !in_range(val2, 5000, 70001))891 return -EINVAL;892 893 raw = BMI323_INT_MICRO_TO_RAW(val, val2,894 BMI323_DUR_BW_TAP_SCALE);895 896 return bmi323_update_ext_reg(data, BMI323_TAP3_REG,897 BMI323_TAP3_QT_BW_TAP_MSK,898 FIELD_PREP(BMI323_TAP3_QT_BW_TAP_MSK,899 raw));900 default:901 return -EINVAL;902 }903 case IIO_EV_TYPE_MAG:904 reg = bmi323_motion_config_reg(dir);905 if (reg < 0)906 return -EINVAL;907 908 switch (info) {909 case IIO_EV_INFO_VALUE:910 if (!in_range(val, 0, 8))911 return -EINVAL;912 913 raw = BMI323_INT_MICRO_TO_RAW(val, val2,914 BMI323_MOTION_THRES_SCALE);915 916 return bmi323_update_ext_reg(data, reg,917 BMI323_MO1_SLOPE_TH_MSK,918 FIELD_PREP(BMI323_MO1_SLOPE_TH_MSK,919 raw));920 case IIO_EV_INFO_PERIOD:921 if (!in_range(val, 0, 163))922 return -EINVAL;923 924 raw = BMI323_INT_MICRO_TO_RAW(val, val2,925 BMI323_MOTION_DURAT_SCALE);926 927 return bmi323_update_ext_reg(data,928 reg + BMI323_MO3_OFFSET,929 BMI323_MO3_DURA_MSK,930 FIELD_PREP(BMI323_MO3_DURA_MSK,931 raw));932 case IIO_EV_INFO_HYSTERESIS:933 if (!in_range(val, 0, 2))934 return -EINVAL;935 936 raw = BMI323_INT_MICRO_TO_RAW(val, val2,937 BMI323_MOTION_HYSTR_SCALE);938 939 return bmi323_update_ext_reg(data,940 reg + BMI323_MO2_OFFSET,941 BMI323_MO2_HYSTR_MSK,942 FIELD_PREP(BMI323_MO2_HYSTR_MSK,943 raw));944 default:945 return -EINVAL;946 }947 case IIO_EV_TYPE_CHANGE:948 if (!in_range(val, 0, 20461))949 return -EINVAL;950 951 raw = val / 20;952 return bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,953 BMI323_STEP_SC1_WTRMRK_MSK,954 FIELD_PREP(BMI323_STEP_SC1_WTRMRK_MSK,955 raw));956 default:957 return -EINVAL;958 }959}960 961static int bmi323_read_event_value(struct iio_dev *indio_dev,962 const struct iio_chan_spec *chan,963 enum iio_event_type type,964 enum iio_event_direction dir,965 enum iio_event_info info,966 int *val, int *val2)967{968 struct bmi323_data *data = iio_priv(indio_dev);969 unsigned int raw, reg_value;970 int ret, reg;971 972 guard(mutex)(&data->mutex);973 974 switch (type) {975 case IIO_EV_TYPE_GESTURE:976 switch (info) {977 case IIO_EV_INFO_VALUE:978 ret = bmi323_read_ext_reg(data, BMI323_TAP2_REG,979 ®_value);980 if (ret)981 return ret;982 983 raw = FIELD_GET(BMI323_TAP2_THRES_MSK, reg_value);984 *val = raw / BMI323_TAP_THRES_SCALE;985 *val2 = BMI323_RAW_TO_MICRO(raw, BMI323_TAP_THRES_SCALE);986 return IIO_VAL_INT_PLUS_MICRO;987 case IIO_EV_INFO_RESET_TIMEOUT:988 ret = bmi323_read_ext_reg(data, BMI323_TAP3_REG,989 ®_value);990 if (ret)991 return ret;992 993 raw = FIELD_GET(BMI323_TAP3_QT_AFT_GES_MSK, reg_value);994 *val = 0;995 *val2 = BMI323_RAW_TO_MICRO(raw,996 BMI323_QUITE_TIM_GES_SCALE);997 return IIO_VAL_INT_PLUS_MICRO;998 case IIO_EV_INFO_TAP2_MIN_DELAY:999 ret = bmi323_read_ext_reg(data, BMI323_TAP3_REG,1000 ®_value);1001 if (ret)1002 return ret;1003 1004 raw = FIELD_GET(BMI323_TAP3_QT_BW_TAP_MSK, reg_value);1005 *val = 0;1006 *val2 = BMI323_RAW_TO_MICRO(raw,1007 BMI323_DUR_BW_TAP_SCALE);1008 return IIO_VAL_INT_PLUS_MICRO;1009 default:1010 return -EINVAL;1011 }1012 case IIO_EV_TYPE_MAG:1013 reg = bmi323_motion_config_reg(dir);1014 if (reg < 0)1015 return -EINVAL;1016 1017 switch (info) {1018 case IIO_EV_INFO_VALUE:1019 ret = bmi323_read_ext_reg(data, reg, ®_value);1020 if (ret)1021 return ret;1022 1023 raw = FIELD_GET(BMI323_MO1_SLOPE_TH_MSK, reg_value);1024 *val = raw / BMI323_MOTION_THRES_SCALE;1025 *val2 = BMI323_RAW_TO_MICRO(raw,1026 BMI323_MOTION_THRES_SCALE);1027 return IIO_VAL_INT_PLUS_MICRO;1028 case IIO_EV_INFO_PERIOD:1029 ret = bmi323_read_ext_reg(data,1030 reg + BMI323_MO3_OFFSET,1031 ®_value);1032 if (ret)1033 return ret;1034 1035 raw = FIELD_GET(BMI323_MO3_DURA_MSK, reg_value);1036 *val = raw / BMI323_MOTION_DURAT_SCALE;1037 *val2 = BMI323_RAW_TO_MICRO(raw,1038 BMI323_MOTION_DURAT_SCALE);1039 return IIO_VAL_INT_PLUS_MICRO;1040 case IIO_EV_INFO_HYSTERESIS:1041 ret = bmi323_read_ext_reg(data,1042 reg + BMI323_MO2_OFFSET,1043 ®_value);1044 if (ret)1045 return ret;1046 1047 raw = FIELD_GET(BMI323_MO2_HYSTR_MSK, reg_value);1048 *val = raw / BMI323_MOTION_HYSTR_SCALE;1049 *val2 = BMI323_RAW_TO_MICRO(raw,1050 BMI323_MOTION_HYSTR_SCALE);1051 return IIO_VAL_INT_PLUS_MICRO;1052 default:1053 return -EINVAL;1054 }1055 case IIO_EV_TYPE_CHANGE:1056 ret = bmi323_read_ext_reg(data, BMI323_STEP_SC1_REG,1057 ®_value);1058 if (ret)1059 return ret;1060 1061 raw = FIELD_GET(BMI323_STEP_SC1_WTRMRK_MSK, reg_value);1062 *val = raw * 20;1063 return IIO_VAL_INT;1064 default:1065 return -EINVAL;1066 }1067}1068 1069static int __bmi323_fifo_flush(struct iio_dev *indio_dev)1070{1071 struct bmi323_data *data = iio_priv(indio_dev);1072 int i, ret, fifo_lvl, frame_count, bit, index;1073 __le16 *frame, *pchannels;1074 u64 sample_period;1075 s64 tstamp;1076 1077 guard(mutex)(&data->mutex);1078 ret = regmap_read(data->regmap, BMI323_FIFO_FILL_LEVEL_REG, &fifo_lvl);1079 if (ret)1080 return ret;1081 1082 fifo_lvl = min(fifo_lvl, BMI323_FIFO_FULL_IN_WORDS);1083 1084 frame_count = fifo_lvl / BMI323_FIFO_FRAME_LENGTH;1085 if (!frame_count)1086 return -EINVAL;1087 1088 if (fifo_lvl % BMI323_FIFO_FRAME_LENGTH)1089 dev_warn(data->dev, "Bad FIFO alignment\n");1090 1091 /*1092 * Approximate timestamps for each of the sample based on the sampling1093 * frequency, timestamp for last sample and number of samples.1094 */1095 if (data->old_fifo_tstamp) {1096 sample_period = data->fifo_tstamp - data->old_fifo_tstamp;1097 do_div(sample_period, frame_count);1098 } else {1099 sample_period = data->odrns[BMI323_ACCEL];1100 }1101 1102 tstamp = data->fifo_tstamp - (frame_count - 1) * sample_period;1103 1104 ret = regmap_noinc_read(data->regmap, BMI323_FIFO_DATA_REG,1105 &data->fifo_buff[0],1106 fifo_lvl * BMI323_BYTES_PER_SAMPLE);1107 if (ret)1108 return ret;1109 1110 for (i = 0; i < frame_count; i++) {1111 frame = &data->fifo_buff[i * BMI323_FIFO_FRAME_LENGTH];1112 pchannels = &data->buffer.channels[0];1113 1114 index = 0;1115 for_each_set_bit(bit, indio_dev->active_scan_mask,1116 BMI323_CHAN_MAX)1117 pchannels[index++] = frame[bit];1118 1119 iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,1120 tstamp);1121 1122 tstamp += sample_period;1123 }1124 1125 return frame_count;1126}1127 1128static int bmi323_set_watermark(struct iio_dev *indio_dev, unsigned int val)1129{1130 struct bmi323_data *data = iio_priv(indio_dev);1131 1132 val = min(val, (u32)BMI323_FIFO_FULL_IN_FRAMES);1133 1134 guard(mutex)(&data->mutex);1135 data->watermark = val;1136 1137 return 0;1138}1139 1140static int bmi323_fifo_disable(struct bmi323_data *data)1141{1142 int ret;1143 1144 guard(mutex)(&data->mutex);1145 ret = regmap_write(data->regmap, BMI323_FIFO_CONF_REG, 0);1146 if (ret)1147 return ret;1148 1149 ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,1150 BMI323_FIFO_WTRMRK_MSK,1151 FIELD_PREP(BMI323_FIFO_WTRMRK_MSK, 0));1152 if (ret)1153 return ret;1154 1155 data->fifo_tstamp = 0;1156 data->state = BMI323_IDLE;1157 1158 return 0;1159}1160 1161static int bmi323_buffer_predisable(struct iio_dev *indio_dev)1162{1163 struct bmi323_data *data = iio_priv(indio_dev);1164 1165 if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)1166 return 0;1167 1168 return bmi323_fifo_disable(data);1169}1170 1171static int bmi323_update_watermark(struct bmi323_data *data)1172{1173 int wtrmrk;1174 1175 wtrmrk = data->watermark * BMI323_FIFO_FRAME_LENGTH;1176 1177 return regmap_write(data->regmap, BMI323_FIFO_WTRMRK_REG, wtrmrk);1178}1179 1180static int bmi323_fifo_enable(struct bmi323_data *data)1181{1182 int ret;1183 1184 guard(mutex)(&data->mutex);1185 ret = regmap_update_bits(data->regmap, BMI323_FIFO_CONF_REG,1186 BMI323_FIFO_CONF_ACC_GYR_EN_MSK,1187 FIELD_PREP(BMI323_FIFO_CONF_ACC_GYR_EN_MSK,1188 BMI323_FIFO_ACC_GYR_MSK));1189 if (ret)1190 return ret;1191 1192 ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,1193 BMI323_FIFO_WTRMRK_MSK,1194 FIELD_PREP(BMI323_FIFO_WTRMRK_MSK,1195 data->irq_pin));1196 if (ret)1197 return ret;1198 1199 ret = bmi323_update_watermark(data);1200 if (ret)1201 return ret;1202 1203 ret = regmap_write(data->regmap, BMI323_FIFO_CTRL_REG,1204 BMI323_FIFO_FLUSH_MSK);1205 if (ret)1206 return ret;1207 1208 data->state = BMI323_BUFFER_FIFO;1209 1210 return 0;1211}1212 1213static int bmi323_buffer_preenable(struct iio_dev *indio_dev)1214{1215 struct bmi323_data *data = iio_priv(indio_dev);1216 1217 guard(mutex)(&data->mutex);1218 /*1219 * When the ODR of the accelerometer and gyroscope do not match, the1220 * maximum ODR value between the accelerometer and gyroscope is used1221 * for FIFO and the signal with lower ODR will insert dummy frame.1222 * So allow buffer read only when ODR's of accelero and gyro are equal.1223 * See datasheet section 5.7 "FIFO Data Buffering".1224 */1225 if (data->odrns[BMI323_ACCEL] != data->odrns[BMI323_GYRO]) {1226 dev_err(data->dev, "Accelero and Gyro ODR doesn't match\n");1227 return -EINVAL;1228 }1229 1230 return 0;1231}1232 1233static int bmi323_buffer_postenable(struct iio_dev *indio_dev)1234{1235 struct bmi323_data *data = iio_priv(indio_dev);1236 1237 if (iio_device_get_current_mode(indio_dev) == INDIO_BUFFER_TRIGGERED)1238 return 0;1239 1240 return bmi323_fifo_enable(data);1241}1242 1243static ssize_t hwfifo_watermark_show(struct device *dev,1244 struct device_attribute *attr, char *buf)1245{1246 struct iio_dev *indio_dev = dev_to_iio_dev(dev);1247 struct bmi323_data *data = iio_priv(indio_dev);1248 int wm;1249 1250 scoped_guard(mutex, &data->mutex)1251 wm = data->watermark;1252 1253 return sysfs_emit(buf, "%d\n", wm);1254}1255static IIO_DEVICE_ATTR_RO(hwfifo_watermark, 0);1256 1257static ssize_t hwfifo_enabled_show(struct device *dev,1258 struct device_attribute *attr,1259 char *buf)1260{1261 struct iio_dev *indio_dev = dev_to_iio_dev(dev);1262 struct bmi323_data *data = iio_priv(indio_dev);1263 bool state;1264 1265 scoped_guard(mutex, &data->mutex)1266 state = data->state == BMI323_BUFFER_FIFO;1267 1268 return sysfs_emit(buf, "%d\n", state);1269}1270static IIO_DEVICE_ATTR_RO(hwfifo_enabled, 0);1271 1272static const struct iio_dev_attr *bmi323_fifo_attributes[] = {1273 &iio_dev_attr_hwfifo_watermark,1274 &iio_dev_attr_hwfifo_enabled,1275 NULL1276};1277 1278static const struct iio_buffer_setup_ops bmi323_buffer_ops = {1279 .preenable = bmi323_buffer_preenable,1280 .postenable = bmi323_buffer_postenable,1281 .predisable = bmi323_buffer_predisable,1282};1283 1284static irqreturn_t bmi323_irq_thread_handler(int irq, void *private)1285{1286 struct iio_dev *indio_dev = private;1287 struct bmi323_data *data = iio_priv(indio_dev);1288 unsigned int status_addr, status, feature_event;1289 s64 timestamp = iio_get_time_ns(indio_dev);1290 int ret;1291 1292 if (data->irq_pin == BMI323_IRQ_INT1)1293 status_addr = BMI323_STATUS_INT1_REG;1294 else1295 status_addr = BMI323_STATUS_INT2_REG;1296 1297 scoped_guard(mutex, &data->mutex) {1298 ret = regmap_read(data->regmap, status_addr, &status);1299 if (ret)1300 return IRQ_NONE;1301 }1302 1303 if (!status || FIELD_GET(BMI323_STATUS_ERROR_MSK, status))1304 return IRQ_NONE;1305 1306 if (FIELD_GET(BMI323_STATUS_FIFO_WTRMRK_MSK, status)) {1307 data->old_fifo_tstamp = data->fifo_tstamp;1308 data->fifo_tstamp = iio_get_time_ns(indio_dev);1309 ret = __bmi323_fifo_flush(indio_dev);1310 if (ret < 0)1311 return IRQ_NONE;1312 }1313 1314 if (FIELD_GET(BMI323_STATUS_ACC_GYR_DRDY_MSK, status))1315 iio_trigger_poll_nested(data->trig);1316 1317 if (FIELD_GET(BMI323_STATUS_MOTION_MSK, status))1318 iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,1319 IIO_MOD_X_OR_Y_OR_Z,1320 IIO_EV_TYPE_MAG,1321 IIO_EV_DIR_RISING),1322 timestamp);1323 1324 if (FIELD_GET(BMI323_STATUS_NOMOTION_MSK, status))1325 iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,1326 IIO_MOD_X_OR_Y_OR_Z,1327 IIO_EV_TYPE_MAG,1328 IIO_EV_DIR_FALLING),1329 timestamp);1330 1331 if (FIELD_GET(BMI323_STATUS_STP_WTR_MSK, status))1332 iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_STEPS, 0,1333 IIO_NO_MOD,1334 IIO_EV_TYPE_CHANGE,1335 IIO_EV_DIR_NONE),1336 timestamp);1337 1338 if (FIELD_GET(BMI323_STATUS_TAP_MSK, status)) {1339 scoped_guard(mutex, &data->mutex) {1340 ret = regmap_read(data->regmap,1341 BMI323_FEAT_EVNT_EXT_REG,1342 &feature_event);1343 if (ret)1344 return IRQ_NONE;1345 }1346 1347 if (FIELD_GET(BMI323_FEAT_EVNT_EXT_S_MSK, feature_event)) {1348 iio_push_event(indio_dev,1349 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,1350 IIO_MOD_X_OR_Y_OR_Z,1351 IIO_EV_TYPE_GESTURE,1352 IIO_EV_DIR_SINGLETAP),1353 timestamp);1354 }1355 1356 if (FIELD_GET(BMI323_FEAT_EVNT_EXT_D_MSK, feature_event))1357 iio_push_event(indio_dev,1358 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0,1359 IIO_MOD_X_OR_Y_OR_Z,1360 IIO_EV_TYPE_GESTURE,1361 IIO_EV_DIR_DOUBLETAP),1362 timestamp);1363 }1364 1365 return IRQ_HANDLED;1366}1367 1368static int bmi323_set_drdy_irq(struct bmi323_data *data,1369 enum bmi323_irq_pin irq_pin)1370{1371 int ret;1372 1373 ret = regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,1374 BMI323_GYR_DRDY_MSK,1375 FIELD_PREP(BMI323_GYR_DRDY_MSK, irq_pin));1376 if (ret)1377 return ret;1378 1379 return regmap_update_bits(data->regmap, BMI323_INT_MAP2_REG,1380 BMI323_ACC_DRDY_MSK,1381 FIELD_PREP(BMI323_ACC_DRDY_MSK, irq_pin));1382}1383 1384static int bmi323_data_rdy_trigger_set_state(struct iio_trigger *trig,1385 bool state)1386{1387 struct bmi323_data *data = iio_trigger_get_drvdata(trig);1388 enum bmi323_irq_pin irq_pin;1389 1390 guard(mutex)(&data->mutex);1391 1392 if (data->state == BMI323_BUFFER_FIFO) {1393 dev_warn(data->dev, "Can't set trigger when FIFO enabled\n");1394 return -EBUSY;1395 }1396 1397 if (state) {1398 data->state = BMI323_BUFFER_DRDY_TRIGGERED;1399 irq_pin = data->irq_pin;1400 } else {1401 data->state = BMI323_IDLE;1402 irq_pin = BMI323_IRQ_DISABLED;1403 }1404 1405 return bmi323_set_drdy_irq(data, irq_pin);1406}1407 1408static const struct iio_trigger_ops bmi323_trigger_ops = {1409 .set_trigger_state = &bmi323_data_rdy_trigger_set_state,1410};1411 1412static irqreturn_t bmi323_trigger_handler(int irq, void *p)1413{1414 struct iio_poll_func *pf = p;1415 struct iio_dev *indio_dev = pf->indio_dev;1416 struct bmi323_data *data = iio_priv(indio_dev);1417 int ret, bit, index = 0;1418 1419 /* Lock to protect the data->buffer */1420 guard(mutex)(&data->mutex);1421 1422 if (*indio_dev->active_scan_mask == BMI323_ALL_CHAN_MSK) {1423 ret = regmap_bulk_read(data->regmap, BMI323_ACCEL_X_REG,1424 &data->buffer.channels,1425 ARRAY_SIZE(data->buffer.channels));1426 if (ret)1427 goto out;1428 } else {1429 for_each_set_bit(bit, indio_dev->active_scan_mask,1430 BMI323_CHAN_MAX) {1431 ret = regmap_raw_read(data->regmap,1432 BMI323_ACCEL_X_REG + bit,1433 &data->buffer.channels[index++],1434 BMI323_BYTES_PER_SAMPLE);1435 if (ret)1436 goto out;1437 }1438 }1439 1440 iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,1441 iio_get_time_ns(indio_dev));1442 1443out:1444 iio_trigger_notify_done(indio_dev->trig);1445 1446 return IRQ_HANDLED;1447}1448 1449static int bmi323_set_average(struct bmi323_data *data,1450 enum bmi323_sensor_type sensor, int avg)1451{1452 int raw = ARRAY_SIZE(bmi323_accel_gyro_avrg);1453 1454 while (raw--)1455 if (avg == bmi323_accel_gyro_avrg[raw])1456 break;1457 if (raw < 0)1458 return -EINVAL;1459 1460 guard(mutex)(&data->mutex);1461 return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,1462 BMI323_ACC_GYRO_CONF_AVG_MSK,1463 FIELD_PREP(BMI323_ACC_GYRO_CONF_AVG_MSK,1464 raw));1465}1466 1467static int bmi323_get_average(struct bmi323_data *data,1468 enum bmi323_sensor_type sensor, int *avg)1469{1470 int ret, value, raw;1471 1472 scoped_guard(mutex, &data->mutex) {1473 ret = regmap_read(data->regmap, bmi323_hw[sensor].config, &value);1474 if (ret)1475 return ret;1476 }1477 1478 raw = FIELD_GET(BMI323_ACC_GYRO_CONF_AVG_MSK, value);1479 *avg = bmi323_accel_gyro_avrg[raw];1480 1481 return IIO_VAL_INT;1482}1483 1484static int bmi323_enable_steps(struct bmi323_data *data, int val)1485{1486 int ret;1487 1488 guard(mutex)(&data->mutex);1489 if (data->odrhz[BMI323_ACCEL] < 200) {1490 dev_err(data->dev, "Invalid accelerometer parameter\n");1491 return -EINVAL;1492 }1493 1494 ret = bmi323_feature_engine_events(data, BMI323_FEAT_IO0_STP_CNT_MSK,1495 val ? 1 : 0);1496 if (ret)1497 return ret;1498 1499 set_mask_bits(&data->feature_events, BMI323_FEAT_IO0_STP_CNT_MSK,1500 FIELD_PREP(BMI323_FEAT_IO0_STP_CNT_MSK, val ? 1 : 0));1501 1502 return 0;1503}1504 1505static int bmi323_read_steps(struct bmi323_data *data, int *val)1506{1507 int ret;1508 1509 guard(mutex)(&data->mutex);1510 if (!FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK, data->feature_events))1511 return -EINVAL;1512 1513 ret = regmap_bulk_read(data->regmap, BMI323_FEAT_IO2_REG,1514 data->steps_count,1515 ARRAY_SIZE(data->steps_count));1516 if (ret)1517 return ret;1518 1519 *val = get_unaligned_le32(data->steps_count);1520 1521 return IIO_VAL_INT;1522}1523 1524static int bmi323_read_axis(struct bmi323_data *data,1525 struct iio_chan_spec const *chan, int *val)1526{1527 enum bmi323_sensor_type sensor;1528 unsigned int value;1529 u8 addr;1530 int ret;1531 1532 ret = bmi323_get_error_status(data);1533 if (ret)1534 return -EINVAL;1535 1536 sensor = bmi323_iio_to_sensor(chan->type);1537 addr = bmi323_hw[sensor].data + (chan->channel2 - IIO_MOD_X);1538 1539 scoped_guard(mutex, &data->mutex) {1540 ret = regmap_read(data->regmap, addr, &value);1541 if (ret)1542 return ret;1543 }1544 1545 *val = sign_extend32(value, chan->scan_type.realbits - 1);1546 1547 return IIO_VAL_INT;1548}1549 1550static int bmi323_get_temp_data(struct bmi323_data *data, int *val)1551{1552 unsigned int value;1553 int ret;1554 1555 ret = bmi323_get_error_status(data);1556 if (ret)1557 return -EINVAL;1558 1559 scoped_guard(mutex, &data->mutex) {1560 ret = regmap_read(data->regmap, BMI323_TEMP_REG, &value);1561 if (ret)1562 return ret;1563 }1564 1565 *val = sign_extend32(value, 15);1566 1567 return IIO_VAL_INT;1568}1569 1570static int bmi323_get_odr(struct bmi323_data *data,1571 enum bmi323_sensor_type sensor, int *odr, int *uodr)1572{1573 int ret, value, odr_raw;1574 1575 scoped_guard(mutex, &data->mutex) {1576 ret = regmap_read(data->regmap, bmi323_hw[sensor].config, &value);1577 if (ret)1578 return ret;1579 }1580 1581 odr_raw = FIELD_GET(BMI323_ACC_GYRO_CONF_ODR_MSK, value);1582 *odr = bmi323_acc_gyro_odr[odr_raw - 1][0];1583 *uodr = bmi323_acc_gyro_odr[odr_raw - 1][1];1584 1585 return IIO_VAL_INT_PLUS_MICRO;1586}1587 1588static int bmi323_configure_power_mode(struct bmi323_data *data,1589 enum bmi323_sensor_type sensor,1590 int odr_index)1591{1592 enum bmi323_opr_mode mode;1593 1594 if (bmi323_acc_gyro_odr[odr_index][0] > 25)1595 mode = ACC_GYRO_MODE_CONTINOUS;1596 else1597 mode = ACC_GYRO_MODE_DUTYCYCLE;1598 1599 return bmi323_set_mode(data, sensor, mode);1600}1601 1602static int bmi323_set_odr(struct bmi323_data *data,1603 enum bmi323_sensor_type sensor, int odr, int uodr)1604{1605 int odr_raw, ret;1606 1607 odr_raw = ARRAY_SIZE(bmi323_acc_gyro_odr);1608 1609 while (odr_raw--)1610 if (odr == bmi323_acc_gyro_odr[odr_raw][0] &&1611 uodr == bmi323_acc_gyro_odr[odr_raw][1])1612 break;1613 if (odr_raw < 0)1614 return -EINVAL;1615 1616 ret = bmi323_configure_power_mode(data, sensor, odr_raw);1617 if (ret)1618 return -EINVAL;1619 1620 guard(mutex)(&data->mutex);1621 data->odrhz[sensor] = bmi323_acc_gyro_odr[odr_raw][0];1622 data->odrns[sensor] = bmi323_acc_gyro_odrns[odr_raw];1623 1624 odr_raw++;1625 1626 return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,1627 BMI323_ACC_GYRO_CONF_ODR_MSK,1628 FIELD_PREP(BMI323_ACC_GYRO_CONF_ODR_MSK,1629 odr_raw));1630}1631 1632static int bmi323_get_scale(struct bmi323_data *data,1633 enum bmi323_sensor_type sensor, int *val2)1634{1635 int ret, value, scale_raw;1636 1637 scoped_guard(mutex, &data->mutex) {1638 ret = regmap_read(data->regmap, bmi323_hw[sensor].config,1639 &value);1640 if (ret)1641 return ret;1642 }1643 1644 scale_raw = FIELD_GET(BMI323_ACC_GYRO_CONF_SCL_MSK, value);1645 *val2 = bmi323_hw[sensor].scale_table[scale_raw][1];1646 1647 return IIO_VAL_INT_PLUS_MICRO;1648}1649 1650static int bmi323_set_scale(struct bmi323_data *data,1651 enum bmi323_sensor_type sensor, int val, int val2)1652{1653 int scale_raw;1654 1655 scale_raw = bmi323_hw[sensor].scale_table_len;1656 1657 while (scale_raw--)1658 if (val == bmi323_hw[sensor].scale_table[scale_raw][0] &&1659 val2 == bmi323_hw[sensor].scale_table[scale_raw][1])1660 break;1661 if (scale_raw < 0)1662 return -EINVAL;1663 1664 guard(mutex)(&data->mutex);1665 return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,1666 BMI323_ACC_GYRO_CONF_SCL_MSK,1667 FIELD_PREP(BMI323_ACC_GYRO_CONF_SCL_MSK,1668 scale_raw));1669}1670 1671static int bmi323_read_avail(struct iio_dev *indio_dev,1672 struct iio_chan_spec const *chan,1673 const int **vals, int *type, int *length,1674 long mask)1675{1676 enum bmi323_sensor_type sensor;1677 1678 switch (mask) {1679 case IIO_CHAN_INFO_SAMP_FREQ:1680 *type = IIO_VAL_INT_PLUS_MICRO;1681 *vals = (const int *)bmi323_acc_gyro_odr;1682 *length = ARRAY_SIZE(bmi323_acc_gyro_odr) * 2;1683 return IIO_AVAIL_LIST;1684 case IIO_CHAN_INFO_SCALE:1685 sensor = bmi323_iio_to_sensor(chan->type);1686 *type = IIO_VAL_INT_PLUS_MICRO;1687 *vals = (const int *)bmi323_hw[sensor].scale_table;1688 *length = bmi323_hw[sensor].scale_table_len * 2;1689 return IIO_AVAIL_LIST;1690 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:1691 *type = IIO_VAL_INT;1692 *vals = (const int *)bmi323_accel_gyro_avrg;1693 *length = ARRAY_SIZE(bmi323_accel_gyro_avrg);1694 return IIO_AVAIL_LIST;1695 default:1696 return -EINVAL;1697 }1698}1699 1700static int bmi323_write_raw(struct iio_dev *indio_dev,1701 struct iio_chan_spec const *chan, int val,1702 int val2, long mask)1703{1704 struct bmi323_data *data = iio_priv(indio_dev);1705 1706 switch (mask) {1707 case IIO_CHAN_INFO_SAMP_FREQ:1708 iio_device_claim_direct_scoped(return -EBUSY, indio_dev)1709 return bmi323_set_odr(data,1710 bmi323_iio_to_sensor(chan->type),1711 val, val2);1712 unreachable();1713 case IIO_CHAN_INFO_SCALE:1714 iio_device_claim_direct_scoped(return -EBUSY, indio_dev)1715 return bmi323_set_scale(data,1716 bmi323_iio_to_sensor(chan->type),1717 val, val2);1718 unreachable();1719 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:1720 iio_device_claim_direct_scoped(return -EBUSY, indio_dev)1721 return bmi323_set_average(data,1722 bmi323_iio_to_sensor(chan->type),1723 val);1724 unreachable();1725 case IIO_CHAN_INFO_ENABLE:1726 return bmi323_enable_steps(data, val);1727 case IIO_CHAN_INFO_PROCESSED: {1728 guard(mutex)(&data->mutex);1729 1730 if (val || !FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK,1731 data->feature_events))1732 return -EINVAL;1733 1734 /* Clear step counter value */1735 return bmi323_update_ext_reg(data, BMI323_STEP_SC1_REG,1736 BMI323_STEP_SC1_RST_CNT_MSK,1737 FIELD_PREP(BMI323_STEP_SC1_RST_CNT_MSK,1738 1));1739 }1740 default:1741 return -EINVAL;1742 }1743}1744 1745static int bmi323_read_raw(struct iio_dev *indio_dev,1746 struct iio_chan_spec const *chan, int *val,1747 int *val2, long mask)1748{1749 struct bmi323_data *data = iio_priv(indio_dev);1750 1751 switch (mask) {1752 case IIO_CHAN_INFO_PROCESSED:1753 return bmi323_read_steps(data, val);1754 case IIO_CHAN_INFO_RAW:1755 switch (chan->type) {1756 case IIO_ACCEL:1757 case IIO_ANGL_VEL:1758 iio_device_claim_direct_scoped(return -EBUSY,1759 indio_dev)1760 return bmi323_read_axis(data, chan, val);1761 unreachable();1762 case IIO_TEMP:1763 return bmi323_get_temp_data(data, val);1764 default:1765 return -EINVAL;1766 }1767 case IIO_CHAN_INFO_SAMP_FREQ:1768 return bmi323_get_odr(data, bmi323_iio_to_sensor(chan->type),1769 val, val2);1770 case IIO_CHAN_INFO_SCALE:1771 switch (chan->type) {1772 case IIO_ACCEL:1773 case IIO_ANGL_VEL:1774 *val = 0;1775 return bmi323_get_scale(data,1776 bmi323_iio_to_sensor(chan->type),1777 val2);1778 case IIO_TEMP:1779 *val = BMI323_TEMP_SCALE / MEGA;1780 *val2 = BMI323_TEMP_SCALE % MEGA;1781 return IIO_VAL_INT_PLUS_MICRO;1782 default:1783 return -EINVAL;1784 }1785 case IIO_CHAN_INFO_OVERSAMPLING_RATIO:1786 return bmi323_get_average(data,1787 bmi323_iio_to_sensor(chan->type),1788 val);1789 case IIO_CHAN_INFO_OFFSET:1790 switch (chan->type) {1791 case IIO_TEMP:1792 *val = BMI323_TEMP_OFFSET;1793 return IIO_VAL_INT;1794 default:1795 return -EINVAL;1796 }1797 case IIO_CHAN_INFO_ENABLE:1798 scoped_guard(mutex, &data->mutex)1799 *val = FIELD_GET(BMI323_FEAT_IO0_STP_CNT_MSK,1800 data->feature_events);1801 return IIO_VAL_INT;1802 default:1803 return -EINVAL;1804 }1805}1806 1807static const struct iio_info bmi323_info = {1808 .read_raw = bmi323_read_raw,1809 .write_raw = bmi323_write_raw,1810 .read_avail = bmi323_read_avail,1811 .hwfifo_set_watermark = bmi323_set_watermark,1812 .write_event_config = bmi323_write_event_config,1813 .read_event_config = bmi323_read_event_config,1814 .write_event_value = bmi323_write_event_value,1815 .read_event_value = bmi323_read_event_value,1816 .event_attrs = &bmi323_event_attribute_group,1817};1818 1819#define BMI323_SCAN_MASK_ACCEL_3AXIS \1820 (BIT(BMI323_ACCEL_X) | BIT(BMI323_ACCEL_Y) | BIT(BMI323_ACCEL_Z))1821 1822#define BMI323_SCAN_MASK_GYRO_3AXIS \1823 (BIT(BMI323_GYRO_X) | BIT(BMI323_GYRO_Y) | BIT(BMI323_GYRO_Z))1824 1825static const unsigned long bmi323_avail_scan_masks[] = {1826 /* 3-axis accel */1827 BMI323_SCAN_MASK_ACCEL_3AXIS,1828 /* 3-axis gyro */1829 BMI323_SCAN_MASK_GYRO_3AXIS,1830 /* 3-axis accel + 3-axis gyro */1831 BMI323_SCAN_MASK_ACCEL_3AXIS | BMI323_SCAN_MASK_GYRO_3AXIS,1832 01833};1834 1835static int bmi323_int_pin_config(struct bmi323_data *data,1836 enum bmi323_irq_pin irq_pin,1837 bool active_high, bool open_drain, bool latch)1838{1839 unsigned int mask, field_value;1840 int ret;1841 1842 ret = regmap_update_bits(data->regmap, BMI323_IO_INT_CONF_REG,1843 BMI323_IO_INT_LTCH_MSK,1844 FIELD_PREP(BMI323_IO_INT_LTCH_MSK, latch));1845 if (ret)1846 return ret;1847 1848 ret = bmi323_update_ext_reg(data, BMI323_GEN_SET1_REG,1849 BMI323_GEN_HOLD_DUR_MSK,1850 FIELD_PREP(BMI323_GEN_HOLD_DUR_MSK, 0));1851 if (ret)1852 return ret;1853 1854 switch (irq_pin) {1855 case BMI323_IRQ_INT1:1856 mask = BMI323_IO_INT1_LVL_OD_OP_MSK;1857 1858 field_value = FIELD_PREP(BMI323_IO_INT1_LVL_MSK, active_high) |1859 FIELD_PREP(BMI323_IO_INT1_OD_MSK, open_drain) |1860 FIELD_PREP(BMI323_IO_INT1_OP_EN_MSK, 1);1861 break;1862 case BMI323_IRQ_INT2:1863 mask = BMI323_IO_INT2_LVL_OD_OP_MSK;1864 1865 field_value = FIELD_PREP(BMI323_IO_INT2_LVL_MSK, active_high) |1866 FIELD_PREP(BMI323_IO_INT2_OD_MSK, open_drain) |1867 FIELD_PREP(BMI323_IO_INT2_OP_EN_MSK, 1);1868 break;1869 default:1870 return -EINVAL;1871 }1872 1873 return regmap_update_bits(data->regmap, BMI323_IO_INT_CTR_REG, mask,1874 field_value);1875}1876 1877static int bmi323_trigger_probe(struct bmi323_data *data,1878 struct iio_dev *indio_dev)1879{1880 bool open_drain, active_high, latch;1881 struct fwnode_handle *fwnode;1882 enum bmi323_irq_pin irq_pin;1883 int ret, irq, irq_type;1884 struct irq_data *desc;1885 1886 fwnode = dev_fwnode(data->dev);1887 if (!fwnode)1888 return -ENODEV;1889 1890 irq = fwnode_irq_get_byname(fwnode, "INT1");1891 if (irq > 0) {1892 irq_pin = BMI323_IRQ_INT1;1893 } else {1894 irq = fwnode_irq_get_byname(fwnode, "INT2");1895 if (irq < 0)1896 return 0;1897 1898 irq_pin = BMI323_IRQ_INT2;1899 }1900 1901 desc = irq_get_irq_data(irq);1902 if (!desc)1903 return dev_err_probe(data->dev, -EINVAL,1904 "Could not find IRQ %d\n", irq);1905 1906 irq_type = irqd_get_trigger_type(desc);1907 switch (irq_type) {1908 case IRQF_TRIGGER_RISING:1909 latch = false;1910 active_high = true;1911 break;1912 case IRQF_TRIGGER_HIGH:1913 latch = true;1914 active_high = true;1915 break;1916 case IRQF_TRIGGER_FALLING:1917 latch = false;1918 active_high = false;1919 break;1920 case IRQF_TRIGGER_LOW:1921 latch = true;1922 active_high = false;1923 break;1924 default:1925 return dev_err_probe(data->dev, -EINVAL,1926 "Invalid interrupt type 0x%x specified\n",1927 irq_type);1928 }1929 1930 open_drain = fwnode_property_read_bool(fwnode, "drive-open-drain");1931 1932 ret = bmi323_int_pin_config(data, irq_pin, active_high, open_drain,1933 latch);1934 if (ret)1935 return dev_err_probe(data->dev, ret,1936 "Failed to configure irq line\n");1937 1938 data->trig = devm_iio_trigger_alloc(data->dev, "%s-trig-%d",1939 indio_dev->name, irq_pin);1940 if (!data->trig)1941 return -ENOMEM;1942 1943 data->trig->ops = &bmi323_trigger_ops;1944 iio_trigger_set_drvdata(data->trig, data);1945 1946 ret = devm_request_threaded_irq(data->dev, irq, NULL,1947 bmi323_irq_thread_handler,1948 IRQF_ONESHOT, "bmi323-int", indio_dev);1949 if (ret)1950 return dev_err_probe(data->dev, ret, "Failed to request IRQ\n");1951 1952 ret = devm_iio_trigger_register(data->dev, data->trig);1953 if (ret)1954 return dev_err_probe(data->dev, ret,1955 "Trigger registration failed\n");1956 1957 data->irq_pin = irq_pin;1958 1959 return 0;1960}1961 1962static int bmi323_feature_engine_enable(struct bmi323_data *data, bool en)1963{1964 unsigned int feature_status;1965 int ret;1966 1967 if (!en)1968 return regmap_write(data->regmap, BMI323_FEAT_CTRL_REG, 0);1969 1970 ret = regmap_write(data->regmap, BMI323_FEAT_IO2_REG, 0x012c);1971 if (ret)1972 return ret;1973 1974 ret = regmap_write(data->regmap, BMI323_FEAT_IO_STATUS_REG,1975 BMI323_FEAT_IO_STATUS_MSK);1976 if (ret)1977 return ret;1978 1979 ret = regmap_write(data->regmap, BMI323_FEAT_CTRL_REG,1980 BMI323_FEAT_ENG_EN_MSK);1981 if (ret)1982 return ret;1983 1984 /*1985 * It takes around 4 msec to enable the Feature engine, so check1986 * the status of the feature engine every 2 msec for a maximum1987 * of 5 trials.1988 */1989 ret = regmap_read_poll_timeout(data->regmap, BMI323_FEAT_IO1_REG,1990 feature_status,1991 FIELD_GET(BMI323_FEAT_IO1_ERR_MSK,1992 feature_status) == 1,1993 BMI323_FEAT_ENG_POLL,1994 BMI323_FEAT_ENG_TIMEOUT);1995 if (ret)1996 return dev_err_probe(data->dev, -EINVAL,1997 "Failed to enable feature engine\n");1998 1999 return 0;2000}2001 2002static void bmi323_disable(void *data_ptr)2003{2004 struct bmi323_data *data = data_ptr;2005 2006 bmi323_set_mode(data, BMI323_ACCEL, ACC_GYRO_MODE_DISABLE);2007 bmi323_set_mode(data, BMI323_GYRO, ACC_GYRO_MODE_DISABLE);2008 2009 /*2010 * Place the peripheral in its lowest power consuming state.2011 */2012 regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL);2013}2014 2015static int bmi323_set_bw(struct bmi323_data *data,2016 enum bmi323_sensor_type sensor, enum bmi323_3db_bw bw)2017{2018 return regmap_update_bits(data->regmap, bmi323_hw[sensor].config,2019 BMI323_ACC_GYRO_CONF_BW_MSK,2020 FIELD_PREP(BMI323_ACC_GYRO_CONF_BW_MSK, bw));2021}2022 2023static int bmi323_init(struct bmi323_data *data)2024{2025 int ret, val;2026 2027 /*2028 * Perform soft reset to make sure the device is in a known state after2029 * start up. A delay of 1.5 ms is required after reset.2030 * See datasheet section 5.17 "Soft Reset".2031 */2032 ret = regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL);2033 if (ret)2034 return ret;2035 2036 usleep_range(1500, 2000);2037 2038 /*2039 * Dummy read is required to enable SPI interface after reset.2040 * See datasheet section 7.2.1 "Protocol Selection".2041 */2042 regmap_read(data->regmap, BMI323_CHIP_ID_REG, &val);2043 2044 ret = regmap_read(data->regmap, BMI323_STATUS_REG, &val);2045 if (ret)2046 return ret;2047 2048 if (!FIELD_GET(BMI323_STATUS_POR_MSK, val))2049 return dev_err_probe(data->dev, -EINVAL,2050 "Sensor initialization error\n");2051 2052 ret = regmap_read(data->regmap, BMI323_CHIP_ID_REG, &val);2053 if (ret)2054 return ret;2055 2056 if (FIELD_GET(BMI323_CHIP_ID_MSK, val) != BMI323_CHIP_ID_VAL)2057 return dev_err_probe(data->dev, -EINVAL, "Chip ID mismatch\n");2058 2059 ret = bmi323_feature_engine_enable(data, true);2060 if (ret)2061 return ret;2062 2063 ret = regmap_read(data->regmap, BMI323_ERR_REG, &val);2064 if (ret)2065 return ret;2066 2067 if (val)2068 return dev_err_probe(data->dev, -EINVAL,2069 "Sensor power error = 0x%x\n", val);2070 2071 return 0;2072}2073 2074static int bmi323_init_reset(struct bmi323_data *data)2075{2076 int ret;2077 2078 /*2079 * Set the Bandwidth coefficient which defines the 3 dB cutoff2080 * frequency in relation to the ODR.2081 */2082 ret = bmi323_set_bw(data, BMI323_ACCEL, BMI323_BW_ODR_BY_2);2083 if (ret)2084 return ret;2085 2086 ret = bmi323_set_bw(data, BMI323_GYRO, BMI323_BW_ODR_BY_2);2087 if (ret)2088 return ret;2089 2090 ret = bmi323_set_odr(data, BMI323_ACCEL, 25, 0);2091 if (ret)2092 return ret;2093 2094 ret = bmi323_set_odr(data, BMI323_GYRO, 25, 0);2095 if (ret)2096 return ret;2097 2098 return devm_add_action_or_reset(data->dev, bmi323_disable, data);2099}2100 2101int bmi323_core_probe(struct device *dev)2102{2103 static const char * const regulator_names[] = { "vdd", "vddio" };2104 struct iio_dev *indio_dev;2105 struct bmi323_data *data;2106 struct regmap *regmap;2107 int ret;2108 2109 regmap = dev_get_regmap(dev, NULL);2110 if (!regmap)2111 return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");2112 2113 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));2114 if (!indio_dev)2115 return dev_err_probe(dev, -ENOMEM,2116 "Failed to allocate device\n");2117 2118 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),2119 regulator_names);2120 if (ret)2121 return dev_err_probe(dev, ret, "Failed to enable regulators\n");2122 2123 data = iio_priv(indio_dev);2124 data->dev = dev;2125 data->regmap = regmap;2126 data->irq_pin = BMI323_IRQ_DISABLED;2127 data->state = BMI323_IDLE;2128 mutex_init(&data->mutex);2129 2130 ret = bmi323_init(data);2131 if (ret)2132 return -EINVAL;2133 2134 ret = bmi323_init_reset(data);2135 if (ret)2136 return -EINVAL;2137 2138 if (!iio_read_acpi_mount_matrix(dev, &data->orientation, "ROTM")) {2139 ret = iio_read_mount_matrix(dev, &data->orientation);2140 if (ret)2141 return ret;2142 }2143 2144 indio_dev->name = "bmi323-imu";2145 indio_dev->info = &bmi323_info;2146 indio_dev->channels = bmi323_channels;2147 indio_dev->num_channels = ARRAY_SIZE(bmi323_channels);2148 indio_dev->available_scan_masks = bmi323_avail_scan_masks;2149 indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;2150 dev_set_drvdata(data->dev, indio_dev);2151 2152 ret = bmi323_trigger_probe(data, indio_dev);2153 if (ret)2154 return -EINVAL;2155 2156 ret = devm_iio_triggered_buffer_setup_ext(data->dev, indio_dev,2157 &iio_pollfunc_store_time,2158 bmi323_trigger_handler,2159 IIO_BUFFER_DIRECTION_IN,2160 &bmi323_buffer_ops,2161 bmi323_fifo_attributes);2162 if (ret)2163 return dev_err_probe(data->dev, ret,2164 "Failed to setup trigger buffer\n");2165 2166 ret = devm_iio_device_register(data->dev, indio_dev);2167 if (ret)2168 return dev_err_probe(data->dev, ret,2169 "Unable to register iio device\n");2170 2171 return bmi323_fifo_disable(data);2172}2173EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323);2174 2175static int bmi323_core_runtime_suspend(struct device *dev)2176{2177 struct iio_dev *indio_dev = dev_get_drvdata(dev);2178 struct bmi323_data *data = iio_priv(indio_dev);2179 struct bmi323_regs_runtime_pm *savestate = &data->runtime_pm_status;2180 int ret;2181 2182 guard(mutex)(&data->mutex);2183 2184 ret = iio_device_suspend_triggering(indio_dev);2185 if (ret)2186 return ret;2187 2188 /* Save registers meant to be restored by resume pm callback. */2189 for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_reg_savestate); i++) {2190 ret = regmap_read(data->regmap, bmi323_reg_savestate[i],2191 &savestate->reg_settings[i]);2192 if (ret) {2193 dev_err(data->dev,2194 "Error reading bmi323 reg 0x%x: %d\n",2195 bmi323_reg_savestate[i], ret);2196 return ret;2197 }2198 }2199 2200 for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) {2201 ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i],2202 &savestate->ext_reg_settings[i]);2203 if (ret) {2204 dev_err(data->dev,2205 "Error reading bmi323 external reg 0x%x: %d\n",2206 bmi323_ext_reg_savestate[i], ret);2207 return ret;2208 }2209 }2210 2211 /* Perform soft reset to place the device in its lowest power state. */2212 ret = regmap_write(data->regmap, BMI323_CMD_REG, BMI323_RST_VAL);2213 if (ret)2214 return ret;2215 2216 return 0;2217}2218 2219static int bmi323_core_runtime_resume(struct device *dev)2220{2221 struct iio_dev *indio_dev = dev_get_drvdata(dev);2222 struct bmi323_data *data = iio_priv(indio_dev);2223 struct bmi323_regs_runtime_pm *savestate = &data->runtime_pm_status;2224 unsigned int val;2225 int ret;2226 2227 guard(mutex)(&data->mutex);2228 2229 /*2230 * Perform the device power-on and initial setup once again2231 * after being reset in the lower power state by runtime-pm.2232 */2233 ret = bmi323_init(data);2234 if (ret) {2235 dev_err(data->dev, "Device power-on and init failed: %d", ret);2236 return ret;2237 }2238 2239 /* Register must be cleared before changing an active config */2240 ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0);2241 if (ret) {2242 dev_err(data->dev, "Error stopping feature engine\n");2243 return ret;2244 }2245 2246 for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) {2247 ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i],2248 savestate->ext_reg_settings[i]);2249 if (ret) {2250 dev_err(data->dev,2251 "Error writing bmi323 external reg 0x%x: %d\n",2252 bmi323_ext_reg_savestate[i], ret);2253 return ret;2254 }2255 }2256 2257 for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_reg_savestate); i++) {2258 ret = regmap_write(data->regmap, bmi323_reg_savestate[i],2259 savestate->reg_settings[i]);2260 if (ret) {2261 dev_err(data->dev,2262 "Error writing bmi323 reg 0x%x: %d\n",2263 bmi323_reg_savestate[i], ret);2264 return ret;2265 }2266 }2267 2268 /*2269 * Clear old FIFO samples that might be generated before suspend2270 * or generated from a peripheral state not equal to the saved one.2271 */2272 if (data->state == BMI323_BUFFER_FIFO) {2273 ret = regmap_write(data->regmap, BMI323_FIFO_CTRL_REG,2274 BMI323_FIFO_FLUSH_MSK);2275 if (ret) {2276 dev_err(data->dev, "Error flushing FIFO buffer: %d\n", ret);2277 return ret;2278 }2279 }2280 2281 ret = regmap_read(data->regmap, BMI323_ERR_REG, &val);2282 if (ret) {2283 dev_err(data->dev,2284 "Error reading bmi323 error register: %d\n", ret);2285 return ret;2286 }2287 2288 if (val) {2289 dev_err(data->dev,2290 "Sensor power error in PM = 0x%x\n", val);2291 return -EINVAL;2292 }2293 2294 return iio_device_resume_triggering(indio_dev);2295}2296 2297const struct dev_pm_ops bmi323_core_pm_ops = {2298 RUNTIME_PM_OPS(bmi323_core_runtime_suspend,2299 bmi323_core_runtime_resume, NULL)2300};2301EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323);2302 2303MODULE_DESCRIPTION("Bosch BMI323 IMU driver");2304MODULE_AUTHOR("Jagath Jog J <jagathjog1996@gmail.com>");2305MODULE_LICENSE("GPL");2306