Lines Matching +full:bosch +full:- +full:sensortec

1 // SPDX-License-Identifier: GPL-2.0
3 * IIO driver for Bosch BNO055 IMU
5 * Copyright (C) 2021-2022 Istituto Italiano di Tecnologia
37 #define BNO055_FW_UID_FMT "bno055-caldata-%*phN.dat"
38 #define BNO055_FW_GENERIC_NAME "bno055-caldata.dat"
67 #define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2)
160 …* [0] https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BNO055-Wrong-sensitivity-resolu…
167 * where k is rad-to-deg factor
306 dev_dbg(priv->dev, "Invalid calibration file size %d (expected %d)", in bno055_calibration_load()
308 return -EINVAL; in bno055_calibration_load()
311 dev_dbg(priv->dev, "loading cal data: %*ph", BNO055_CALDATA_LEN, data); in bno055_calibration_load()
312 return regmap_bulk_write(priv->regmap, BNO055_CALDATA_START, in bno055_calibration_load()
321 ret = regmap_write(priv->regmap, BNO055_OPR_MODE_REG, in bno055_operation_mode_do_set()
336 if (priv->reset_gpio) { in bno055_system_reset()
337 gpiod_set_value_cansleep(priv->reset_gpio, 0); in bno055_system_reset()
339 gpiod_set_value_cansleep(priv->reset_gpio, 1); in bno055_system_reset()
340 } else if (priv->sw_reset) { in bno055_system_reset()
341 ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, in bno055_system_reset()
349 regcache_drop_region(priv->regmap, 0x0, 0xff); in bno055_system_reset()
363 ret = regmap_write(priv->regmap, BNO055_POWER_MODE_REG, in bno055_init()
368 ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, in bno055_init()
369 priv->clk ? BNO055_SYS_TRIGGER_CLK_SEL : 0); in bno055_init()
374 ret = regmap_write(priv->regmap, BNO055_UNIT_SEL_REG, in bno055_init()
382 dev_warn(priv->dev, "failed to load calibration data with error %d\n", in bno055_init()
395 mutex_lock(&priv->lock); in bno055_operation_mode_set()
404 ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, caldata, in bno055_operation_mode_set()
422 priv->operation_mode = operation_mode; in bno055_operation_mode_set()
425 mutex_unlock(&priv->lock); in bno055_operation_mode_set()
550 .scan_index = -1,
564 ret = regmap_read(priv->regmap, reg, &hwval); in bno055_get_regmask()
569 if (attr->hw_xlate) in bno055_get_regmask()
570 for (i = 0; i < attr->hw_xlate_len; i++) in bno055_get_regmask()
571 if (attr->hw_xlate[i] == idx) { in bno055_get_regmask()
575 if (attr->type == IIO_VAL_INT) { in bno055_get_regmask()
576 *val = attr->vals[idx]; in bno055_get_regmask()
578 *val = attr->vals[idx * 2]; in bno055_get_regmask()
579 *val2 = attr->vals[idx * 2 + 1]; in bno055_get_regmask()
582 return attr->type; in bno055_get_regmask()
605 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in bno055_set_regmask()
608 len = attr->len; in bno055_set_regmask()
613 * non-integer tables. This prevents 32-bit overflow with in bno055_set_regmask()
617 if (attr->type != IIO_VAL_INT) { in bno055_set_regmask()
624 switch (attr->type) { in bno055_set_regmask()
626 tbl_val = attr->vals[i]; in bno055_set_regmask()
629 WARN_ON(attr->vals[i * 2] > 2147); in bno055_set_regmask()
630 tbl_val = attr->vals[i * 2] * 1000000 + in bno055_set_regmask()
631 attr->vals[i * 2 + 1]; in bno055_set_regmask()
634 WARN_ON(attr->vals[i * 2] > 4294); in bno055_set_regmask()
635 tbl_val = attr->vals[i * 2] * 1000000 / in bno055_set_regmask()
636 attr->vals[i * 2 + 1]; in bno055_set_regmask()
639 return -EINVAL; in bno055_set_regmask()
641 delta = abs(tbl_val - req_val); in bno055_set_regmask()
649 if (attr->hw_xlate) in bno055_set_regmask()
650 hwval = attr->hw_xlate[hwval]; in bno055_set_regmask()
656 ret = regmap_update_bits(priv->regmap, reg, mask, hwval << shift); in bno055_set_regmask()
673 ret = regmap_bulk_read(priv->regmap, chan->address, in bno055_read_simple_chan()
680 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_read_simple_chan()
683 ret = regmap_bulk_read(priv->regmap, in bno055_read_simple_chan()
684 chan->address + in bno055_read_simple_chan()
693 *val = -sign_extend32(le16_to_cpu(raw_val), 15); in bno055_read_simple_chan()
698 switch (chan->type) { in bno055_read_simple_chan()
700 /* Table 3-35: 1 m/s^2 = 100 LSB */ in bno055_read_simple_chan()
702 /* Table 3-17: 1 m/s^2 = 100 LSB */ in bno055_read_simple_chan()
707 * Table 3-19: 1 uT = 16 LSB. But we need in bno055_read_simple_chan()
714 * Table 3-22: 1 Rps = 900 LSB in bno055_read_simple_chan()
718 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_read_simple_chan()
730 /* Table 3-28: 1 degree = 16 LSB */ in bno055_read_simple_chan()
734 return -EINVAL; in bno055_read_simple_chan()
739 if (chan->type != IIO_MAGN) in bno055_read_simple_chan()
740 return -EINVAL; in bno055_read_simple_chan()
748 switch (chan->type) { in bno055_read_simple_chan()
760 return -EINVAL; in bno055_read_simple_chan()
764 return -EINVAL; in bno055_read_simple_chan()
772 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_sysfs_attr_avail()
774 *vals = attr->fusion_vals; in bno055_sysfs_attr_avail()
775 if (attr->type == IIO_VAL_INT) in bno055_sysfs_attr_avail()
780 *vals = attr->vals; in bno055_sysfs_attr_avail()
781 *length = attr->len; in bno055_sysfs_attr_avail()
784 return attr->type; in bno055_sysfs_attr_avail()
796 switch (chan->type) { in bno055_read_avail()
802 return -EINVAL; in bno055_read_avail()
805 switch (chan->type) { in bno055_read_avail()
815 return -EINVAL; in bno055_read_avail()
820 switch (chan->type) { in bno055_read_avail()
826 return -EINVAL; in bno055_read_avail()
829 return -EINVAL; in bno055_read_avail()
839 ret = regmap_read(priv->regmap, BNO055_TEMP_REG, &raw_val); in bno055_read_temp_chan()
844 * Tables 3-36 and 3-37: one byte of priv, signed, 1 LSB = 1C. in bno055_read_temp_chan()
864 return -EINVAL; in bno055_read_quaternion()
865 ret = regmap_bulk_read(priv->regmap, in bno055_read_quaternion()
875 /* Table 3-31: 1 quaternion = 2^14 LSB */ in bno055_read_quaternion()
877 return -EINVAL; in bno055_read_quaternion()
882 return -EINVAL; in bno055_read_quaternion()
891 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in bno055_is_chan_readable()
894 switch (chan->type) { in bno055_is_chan_readable()
899 if (chan->channel2 == IIO_MOD_LINEAR_X || in bno055_is_chan_readable()
900 chan->channel2 == IIO_MOD_LINEAR_Y || in bno055_is_chan_readable()
901 chan->channel2 == IIO_MOD_LINEAR_Z) in bno055_is_chan_readable()
915 return -EBUSY; in _bno055_read_raw_multi()
917 switch (chan->type) { in _bno055_read_raw_multi()
923 return -EINVAL; in _bno055_read_raw_multi()
936 if (chan->channel2 == IIO_MOD_QUATERNION) in _bno055_read_raw_multi()
941 return -EINVAL; in _bno055_read_raw_multi()
947 return -EINVAL; in _bno055_read_raw_multi()
959 mutex_lock(&priv->lock); in bno055_read_raw_multi()
962 mutex_unlock(&priv->lock); in bno055_read_raw_multi()
972 switch (chan->type) { in _bno055_write_raw()
981 return -EINVAL; in _bno055_write_raw()
992 return -EINVAL; in _bno055_write_raw()
1007 return -EINVAL; in _bno055_write_raw()
1010 return -EINVAL; in _bno055_write_raw()
1021 mutex_lock(&priv->lock); in bno055_write_raw()
1023 mutex_unlock(&priv->lock); in bno055_write_raw()
1036 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in in_accel_range_raw_available_show()
1041 buf[len - 1] = '\n'; in in_accel_range_raw_available_show()
1053 priv->operation_mode != BNO055_OPR_MODE_AMG); in fusion_enable_show()
1065 if (indio_dev->active_scan_mask && in fusion_enable_store()
1066 !bitmap_empty(indio_dev->active_scan_mask, _BNO055_SCAN_MAX)) in fusion_enable_store()
1067 return -EBUSY; in fusion_enable_store()
1071 return -EINVAL; in fusion_enable_store()
1081 if (priv->operation_mode == BNO055_OPR_MODE_AMG) in fusion_enable_store()
1094 priv->operation_mode == BNO055_OPR_MODE_FUSION); in in_magn_calibration_fast_enable_show()
1105 if (indio_dev->active_scan_mask && in in_magn_calibration_fast_enable_store()
1106 !bitmap_empty(indio_dev->active_scan_mask, _BNO055_SCAN_MAX)) in in_magn_calibration_fast_enable_store()
1107 return -EBUSY; in in_magn_calibration_fast_enable_store()
1110 if (priv->operation_mode == BNO055_OPR_MODE_FUSION) { in in_magn_calibration_fast_enable_store()
1116 if (priv->operation_mode == BNO055_OPR_MODE_AMG) in in_magn_calibration_fast_enable_store()
1117 return -EINVAL; in in_magn_calibration_fast_enable_store()
1119 if (priv->operation_mode != BNO055_OPR_MODE_FUSION) { in in_magn_calibration_fast_enable_store()
1159 mutex_lock(&priv->lock); in in_accel_range_raw_store()
1164 mutex_unlock(&priv->lock); in in_accel_range_raw_store()
1176 if (priv->operation_mode == BNO055_OPR_MODE_AMG || in bno055_get_calib_status()
1177 (priv->operation_mode == BNO055_OPR_MODE_FUSION_FMC_OFF && in bno055_get_calib_status()
1181 mutex_lock(&priv->lock); in bno055_get_calib_status()
1182 ret = regmap_read(priv->regmap, BNO055_CALIB_STAT_REG, &val); in bno055_get_calib_status()
1183 mutex_unlock(&priv->lock); in bno055_get_calib_status()
1186 return -EIO; in bno055_get_calib_status()
1200 return sysfs_emit(buf, "%*ph\n", BNO055_UID_LEN, priv->uid); in serialnumber_show()
1217 return -EINVAL; in calibration_data_read()
1219 mutex_lock(&priv->lock); in calibration_data_read()
1224 ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, data, in calibration_data_read()
1229 ret = bno055_operation_mode_do_set(priv, priv->operation_mode); in calibration_data_read()
1237 mutex_unlock(&priv->lock); in calibration_data_read()
1275 return regmap_read(priv->regmap, reg, readval); in bno055_debugfs_reg_access()
1277 return regmap_write(priv->regmap, reg, writeval); in bno055_debugfs_reg_access()
1283 struct bno055_priv *priv = file->private_data; in bno055_show_fw_version()
1288 ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); in bno055_show_fw_version()
1292 ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); in bno055_show_fw_version()
1298 return -ENOMEM; in bno055_show_fw_version()
1317 debugfs_remove(priv->debugfs); in bno055_debugfs_remove()
1318 priv->debugfs = NULL; in bno055_debugfs_remove()
1325 priv->debugfs = debugfs_create_file("firmware_version", 0400, in bno055_debugfs_init()
1328 if (!IS_ERR(priv->debugfs)) in bno055_debugfs_init()
1329 devm_add_action_or_reset(priv->dev, bno055_debugfs_remove, in bno055_debugfs_init()
1331 if (IS_ERR_OR_NULL(priv->debugfs)) in bno055_debugfs_init()
1332 dev_warn(priv->dev, "failed to setup debugfs"); in bno055_debugfs_init()
1383 * Samples from HW are transferred into buf, then in-place copy on buf is
1407 * All channels are made up 1 16-bit sample, except for quaternion that in bno055_scan_xfer()
1408 * is made up 4 16-bit values. in bno055_scan_xfer()
1422 ret = regmap_bulk_read(priv->regmap, in bno055_scan_xfer()
1449 struct iio_dev *iio_dev = pf->indio_dev; in bno055_trigger_handler()
1459 mutex_lock(&priv->lock); in bno055_trigger_handler()
1463 * Bitmap ones-fields that are separated by gaps <= xfer_burst_break_thr in bno055_trigger_handler()
1468 for_each_set_bitrange(start, end, iio_dev->active_scan_mask, in bno055_trigger_handler()
1472 * ones-field in the bitmap in bno055_trigger_handler()
1478 * We found the next ones-field; check whether to in bno055_trigger_handler()
1485 * In case the zeros-gap contains the quaternion bit, in bno055_trigger_handler()
1493 thr_hit = (start - prev_end + quat_extra_len) > in bno055_trigger_handler()
1494 priv->xfer_burst_break_thr; in bno055_trigger_handler()
1499 * (i.e. at the start of this ones-field). in bno055_trigger_handler()
1502 mask = *iio_dev->active_scan_mask >> xfer_start; in bno055_trigger_handler()
1504 prev_end - xfer_start, in bno055_trigger_handler()
1505 mask, priv->buf.chans, &buf_idx); in bno055_trigger_handler()
1519 mask = *iio_dev->active_scan_mask >> xfer_start; in bno055_trigger_handler()
1521 prev_end - xfer_start, in bno055_trigger_handler()
1522 mask, priv->buf.chans, &buf_idx); in bno055_trigger_handler()
1526 &priv->buf, pf->timestamp); in bno055_trigger_handler()
1528 mutex_unlock(&priv->lock); in bno055_trigger_handler()
1529 iio_trigger_notify_done(iio_dev->trig); in bno055_trigger_handler()
1548 if (priv->operation_mode == BNO055_OPR_MODE_AMG && in bno055_buffer_preenable()
1549 bitmap_intersects(indio_dev->active_scan_mask, &fusion_mask, in bno055_buffer_preenable()
1551 return -EBUSY; in bno055_buffer_preenable()
1572 return -ENOMEM; in bno055_probe()
1574 iio_dev->name = "bno055"; in bno055_probe()
1576 mutex_init(&priv->lock); in bno055_probe()
1577 priv->regmap = regmap; in bno055_probe()
1578 priv->dev = dev; in bno055_probe()
1579 priv->xfer_burst_break_thr = xfer_burst_break_thr; in bno055_probe()
1580 priv->sw_reset = sw_reset; in bno055_probe()
1582 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in bno055_probe()
1583 if (IS_ERR(priv->reset_gpio)) in bno055_probe()
1584 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), "Failed to get reset GPIO\n"); in bno055_probe()
1586 priv->clk = devm_clk_get_optional_enabled(dev, "clk"); in bno055_probe()
1587 if (IS_ERR(priv->clk)) in bno055_probe()
1588 return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get CLK\n"); in bno055_probe()
1590 if (priv->reset_gpio) { in bno055_probe()
1592 gpiod_set_value_cansleep(priv->reset_gpio, 1); in bno055_probe()
1598 ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val); in bno055_probe()
1612 if (!priv->reset_gpio) { in bno055_probe()
1618 ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); in bno055_probe()
1622 ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); in bno055_probe()
1635 ret = regmap_bulk_read(priv->regmap, BNO055_UID_LOWER_REG, in bno055_probe()
1636 priv->uid, BNO055_UID_LEN); in bno055_probe()
1642 BNO055_UID_LEN, priv->uid); in bno055_probe()
1644 return -ENOMEM; in bno055_probe()
1654 ret = bno055_init(priv, caldata->data, caldata->size); in bno055_probe()
1660 priv->operation_mode = BNO055_OPR_MODE_FUSION; in bno055_probe()
1661 ret = bno055_operation_mode_do_set(priv, priv->operation_mode); in bno055_probe()
1669 iio_dev->channels = bno055_channels; in bno055_probe()
1670 iio_dev->num_channels = ARRAY_SIZE(bno055_channels); in bno055_probe()
1671 iio_dev->info = &bno055_info; in bno055_probe()
1672 iio_dev->modes = INDIO_DIRECT_MODE; in bno055_probe()
1692 MODULE_DESCRIPTION("Bosch BNO055 driver");