Lines Matching +full:calib +full:- +full:sensitivity

1 // SPDX-License-Identifier: GPL-2.0
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)
159 …* [0] https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BNO055-Wrong-sensitivity-resolu…
166 * where k is rad-to-deg factor
301 dev_dbg(priv->dev, "Invalid calibration file size %d (expected %d)", in bno055_calibration_load()
303 return -EINVAL; in bno055_calibration_load()
306 dev_dbg(priv->dev, "loading cal data: %*ph", BNO055_CALDATA_LEN, data); in bno055_calibration_load()
307 return regmap_bulk_write(priv->regmap, BNO055_CALDATA_START, in bno055_calibration_load()
316 ret = regmap_write(priv->regmap, BNO055_OPR_MODE_REG, in bno055_operation_mode_do_set()
331 if (priv->reset_gpio) { in bno055_system_reset()
332 gpiod_set_value_cansleep(priv->reset_gpio, 0); in bno055_system_reset()
334 gpiod_set_value_cansleep(priv->reset_gpio, 1); in bno055_system_reset()
335 } else if (priv->sw_reset) { in bno055_system_reset()
336 ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, in bno055_system_reset()
344 regcache_drop_region(priv->regmap, 0x0, 0xff); in bno055_system_reset()
358 ret = regmap_write(priv->regmap, BNO055_POWER_MODE_REG, in bno055_init()
363 ret = regmap_write(priv->regmap, BNO055_SYS_TRIGGER_REG, in bno055_init()
364 priv->clk ? BNO055_SYS_TRIGGER_CLK_SEL : 0); in bno055_init()
369 ret = regmap_write(priv->regmap, BNO055_UNIT_SEL_REG, in bno055_init()
377 dev_warn(priv->dev, "failed to load calibration data with error %d\n", in bno055_init()
390 mutex_lock(&priv->lock); in bno055_operation_mode_set()
399 ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, caldata, in bno055_operation_mode_set()
417 priv->operation_mode = operation_mode; in bno055_operation_mode_set()
420 mutex_unlock(&priv->lock); in bno055_operation_mode_set()
545 .scan_index = -1,
558 ret = regmap_read(priv->regmap, reg, &hwval); in bno055_get_regmask()
563 if (attr->hw_xlate) in bno055_get_regmask()
564 for (i = 0; i < attr->len; i++) in bno055_get_regmask()
565 if (attr->hw_xlate[i] == idx) { in bno055_get_regmask()
569 if (attr->type == IIO_VAL_INT) { in bno055_get_regmask()
570 *val = attr->vals[idx]; in bno055_get_regmask()
572 *val = attr->vals[idx * 2]; in bno055_get_regmask()
573 *val2 = attr->vals[idx * 2 + 1]; in bno055_get_regmask()
576 return attr->type; in bno055_get_regmask()
598 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in bno055_set_regmask()
601 len = attr->len; in bno055_set_regmask()
606 * non-integer tables. This prevents 32-bit overflow with in bno055_set_regmask()
610 if (attr->type != IIO_VAL_INT) { in bno055_set_regmask()
617 switch (attr->type) { in bno055_set_regmask()
619 tbl_val = attr->vals[i]; in bno055_set_regmask()
622 WARN_ON(attr->vals[i * 2] > 2147); in bno055_set_regmask()
623 tbl_val = attr->vals[i * 2] * 1000000 + in bno055_set_regmask()
624 attr->vals[i * 2 + 1]; in bno055_set_regmask()
627 WARN_ON(attr->vals[i * 2] > 4294); in bno055_set_regmask()
628 tbl_val = attr->vals[i * 2] * 1000000 / in bno055_set_regmask()
629 attr->vals[i * 2 + 1]; in bno055_set_regmask()
632 return -EINVAL; in bno055_set_regmask()
634 delta = abs(tbl_val - req_val); in bno055_set_regmask()
642 if (attr->hw_xlate) in bno055_set_regmask()
643 hwval = attr->hw_xlate[hwval]; in bno055_set_regmask()
649 ret = regmap_update_bits(priv->regmap, reg, mask, hwval << shift); in bno055_set_regmask()
666 ret = regmap_bulk_read(priv->regmap, chan->address, in bno055_read_simple_chan()
673 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_read_simple_chan()
676 ret = regmap_bulk_read(priv->regmap, in bno055_read_simple_chan()
677 chan->address + in bno055_read_simple_chan()
686 *val = -sign_extend32(le16_to_cpu(raw_val), 15); in bno055_read_simple_chan()
691 switch (chan->type) { in bno055_read_simple_chan()
693 /* Table 3-35: 1 m/s^2 = 100 LSB */ in bno055_read_simple_chan()
695 /* Table 3-17: 1 m/s^2 = 100 LSB */ in bno055_read_simple_chan()
700 * Table 3-19: 1 uT = 16 LSB. But we need in bno055_read_simple_chan()
707 * Table 3-22: 1 Rps = 900 LSB in bno055_read_simple_chan()
711 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_read_simple_chan()
723 /* Table 3-28: 1 degree = 16 LSB */ in bno055_read_simple_chan()
727 return -EINVAL; in bno055_read_simple_chan()
732 if (chan->type != IIO_MAGN) in bno055_read_simple_chan()
733 return -EINVAL; in bno055_read_simple_chan()
741 switch (chan->type) { in bno055_read_simple_chan()
753 return -EINVAL; in bno055_read_simple_chan()
757 return -EINVAL; in bno055_read_simple_chan()
764 if (priv->operation_mode != BNO055_OPR_MODE_AMG) { in bno055_sysfs_attr_avail()
766 *vals = attr->fusion_vals; in bno055_sysfs_attr_avail()
767 if (attr->type == IIO_VAL_INT) in bno055_sysfs_attr_avail()
772 *vals = attr->vals; in bno055_sysfs_attr_avail()
773 *length = attr->len; in bno055_sysfs_attr_avail()
776 return attr->type; in bno055_sysfs_attr_avail()
788 switch (chan->type) { in bno055_read_avail()
794 return -EINVAL; in bno055_read_avail()
797 switch (chan->type) { in bno055_read_avail()
807 return -EINVAL; in bno055_read_avail()
812 switch (chan->type) { in bno055_read_avail()
818 return -EINVAL; in bno055_read_avail()
821 return -EINVAL; in bno055_read_avail()
831 ret = regmap_read(priv->regmap, BNO055_TEMP_REG, &raw_val); in bno055_read_temp_chan()
836 * Tables 3-36 and 3-37: one byte of priv, signed, 1 LSB = 1C. in bno055_read_temp_chan()
856 return -EINVAL; in bno055_read_quaternion()
857 ret = regmap_bulk_read(priv->regmap, in bno055_read_quaternion()
867 /* Table 3-31: 1 quaternion = 2^14 LSB */ in bno055_read_quaternion()
869 return -EINVAL; in bno055_read_quaternion()
874 return -EINVAL; in bno055_read_quaternion()
883 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in bno055_is_chan_readable()
886 switch (chan->type) { in bno055_is_chan_readable()
891 if (chan->channel2 == IIO_MOD_LINEAR_X || in bno055_is_chan_readable()
892 chan->channel2 == IIO_MOD_LINEAR_Y || in bno055_is_chan_readable()
893 chan->channel2 == IIO_MOD_LINEAR_Z) in bno055_is_chan_readable()
907 return -EBUSY; in _bno055_read_raw_multi()
909 switch (chan->type) { in _bno055_read_raw_multi()
915 return -EINVAL; in _bno055_read_raw_multi()
928 if (chan->channel2 == IIO_MOD_QUATERNION) in _bno055_read_raw_multi()
933 return -EINVAL; in _bno055_read_raw_multi()
939 return -EINVAL; in _bno055_read_raw_multi()
951 mutex_lock(&priv->lock); in bno055_read_raw_multi()
954 mutex_unlock(&priv->lock); in bno055_read_raw_multi()
964 switch (chan->type) { in _bno055_write_raw()
973 return -EINVAL; in _bno055_write_raw()
984 return -EINVAL; in _bno055_write_raw()
999 return -EINVAL; in _bno055_write_raw()
1002 return -EINVAL; in _bno055_write_raw()
1013 mutex_lock(&priv->lock); in bno055_write_raw()
1015 mutex_unlock(&priv->lock); in bno055_write_raw()
1028 if (priv->operation_mode != BNO055_OPR_MODE_AMG) in in_accel_range_raw_available_show()
1033 buf[len - 1] = '\n'; in in_accel_range_raw_available_show()
1045 priv->operation_mode != BNO055_OPR_MODE_AMG); in fusion_enable_show()
1057 if (indio_dev->active_scan_mask && in fusion_enable_store()
1058 !bitmap_empty(indio_dev->active_scan_mask, _BNO055_SCAN_MAX)) in fusion_enable_store()
1059 return -EBUSY; in fusion_enable_store()
1063 return -EINVAL; in fusion_enable_store()
1073 if (priv->operation_mode == BNO055_OPR_MODE_AMG) in fusion_enable_store()
1086 priv->operation_mode == BNO055_OPR_MODE_FUSION); in in_magn_calibration_fast_enable_show()
1097 if (indio_dev->active_scan_mask && in in_magn_calibration_fast_enable_store()
1098 !bitmap_empty(indio_dev->active_scan_mask, _BNO055_SCAN_MAX)) in in_magn_calibration_fast_enable_store()
1099 return -EBUSY; in in_magn_calibration_fast_enable_store()
1102 if (priv->operation_mode == BNO055_OPR_MODE_FUSION) { in in_magn_calibration_fast_enable_store()
1108 if (priv->operation_mode == BNO055_OPR_MODE_AMG) in in_magn_calibration_fast_enable_store()
1109 return -EINVAL; in in_magn_calibration_fast_enable_store()
1111 if (priv->operation_mode != BNO055_OPR_MODE_FUSION) { in in_magn_calibration_fast_enable_store()
1151 mutex_lock(&priv->lock); in in_accel_range_raw_store()
1156 mutex_unlock(&priv->lock); in in_accel_range_raw_store()
1164 int calib; in bno055_get_calib_status() local
1168 if (priv->operation_mode == BNO055_OPR_MODE_AMG || in bno055_get_calib_status()
1169 (priv->operation_mode == BNO055_OPR_MODE_FUSION_FMC_OFF && in bno055_get_calib_status()
1171 calib = 0; in bno055_get_calib_status()
1173 mutex_lock(&priv->lock); in bno055_get_calib_status()
1174 ret = regmap_read(priv->regmap, BNO055_CALIB_STAT_REG, &val); in bno055_get_calib_status()
1175 mutex_unlock(&priv->lock); in bno055_get_calib_status()
1178 return -EIO; in bno055_get_calib_status()
1180 calib = ((val >> which) & GENMASK(1, 0)) + 1; in bno055_get_calib_status()
1183 return sysfs_emit(buf, "%d\n", calib); in bno055_get_calib_status()
1192 return sysfs_emit(buf, "%*ph\n", BNO055_UID_LEN, priv->uid); in serialnumber_show()
1209 return -EINVAL; in calibration_data_read()
1211 mutex_lock(&priv->lock); in calibration_data_read()
1216 ret = regmap_bulk_read(priv->regmap, BNO055_CALDATA_START, data, in calibration_data_read()
1221 ret = bno055_operation_mode_do_set(priv, priv->operation_mode); in calibration_data_read()
1229 mutex_unlock(&priv->lock); in calibration_data_read()
1267 return regmap_read(priv->regmap, reg, readval); in bno055_debugfs_reg_access()
1269 return regmap_write(priv->regmap, reg, writeval); in bno055_debugfs_reg_access()
1275 struct bno055_priv *priv = file->private_data; in bno055_show_fw_version()
1280 ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); in bno055_show_fw_version()
1284 ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); in bno055_show_fw_version()
1290 return -ENOMEM; in bno055_show_fw_version()
1309 debugfs_remove(priv->debugfs); in bno055_debugfs_remove()
1310 priv->debugfs = NULL; in bno055_debugfs_remove()
1317 priv->debugfs = debugfs_create_file("firmware_version", 0400, in bno055_debugfs_init()
1320 if (!IS_ERR(priv->debugfs)) in bno055_debugfs_init()
1321 devm_add_action_or_reset(priv->dev, bno055_debugfs_remove, in bno055_debugfs_init()
1323 if (IS_ERR_OR_NULL(priv->debugfs)) in bno055_debugfs_init()
1324 dev_warn(priv->dev, "failed to setup debugfs"); in bno055_debugfs_init()
1375 * Samples from HW are transferred into buf, then in-place copy on buf is
1399 * All channels are made up 1 16-bit sample, except for quaternion that in bno055_scan_xfer()
1400 * is made up 4 16-bit values. in bno055_scan_xfer()
1414 ret = regmap_bulk_read(priv->regmap, in bno055_scan_xfer()
1441 struct iio_dev *iio_dev = pf->indio_dev; in bno055_trigger_handler()
1451 mutex_lock(&priv->lock); in bno055_trigger_handler()
1455 * Bitmap ones-fields that are separated by gaps <= xfer_burst_break_thr in bno055_trigger_handler()
1460 for_each_set_bitrange(start, end, iio_dev->active_scan_mask, in bno055_trigger_handler()
1464 * ones-field in the bitmap in bno055_trigger_handler()
1470 * We found the next ones-field; check whether to in bno055_trigger_handler()
1477 * In case the zeros-gap contains the quaternion bit, in bno055_trigger_handler()
1485 thr_hit = (start - prev_end + quat_extra_len) > in bno055_trigger_handler()
1486 priv->xfer_burst_break_thr; in bno055_trigger_handler()
1491 * (i.e. at the start of this ones-field). in bno055_trigger_handler()
1494 mask = *iio_dev->active_scan_mask >> xfer_start; in bno055_trigger_handler()
1496 prev_end - xfer_start, in bno055_trigger_handler()
1497 mask, priv->buf.chans, &buf_idx); in bno055_trigger_handler()
1511 mask = *iio_dev->active_scan_mask >> xfer_start; in bno055_trigger_handler()
1513 prev_end - xfer_start, in bno055_trigger_handler()
1514 mask, priv->buf.chans, &buf_idx); in bno055_trigger_handler()
1518 &priv->buf, pf->timestamp); in bno055_trigger_handler()
1520 mutex_unlock(&priv->lock); in bno055_trigger_handler()
1521 iio_trigger_notify_done(iio_dev->trig); in bno055_trigger_handler()
1540 if (priv->operation_mode == BNO055_OPR_MODE_AMG && in bno055_buffer_preenable()
1541 bitmap_intersects(indio_dev->active_scan_mask, &fusion_mask, in bno055_buffer_preenable()
1543 return -EBUSY; in bno055_buffer_preenable()
1564 return -ENOMEM; in bno055_probe()
1566 iio_dev->name = "bno055"; in bno055_probe()
1568 mutex_init(&priv->lock); in bno055_probe()
1569 priv->regmap = regmap; in bno055_probe()
1570 priv->dev = dev; in bno055_probe()
1571 priv->xfer_burst_break_thr = xfer_burst_break_thr; in bno055_probe()
1572 priv->sw_reset = sw_reset; in bno055_probe()
1574 priv->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in bno055_probe()
1575 if (IS_ERR(priv->reset_gpio)) in bno055_probe()
1576 return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), "Failed to get reset GPIO\n"); in bno055_probe()
1578 priv->clk = devm_clk_get_optional_enabled(dev, "clk"); in bno055_probe()
1579 if (IS_ERR(priv->clk)) in bno055_probe()
1580 return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get CLK\n"); in bno055_probe()
1582 if (priv->reset_gpio) { in bno055_probe()
1584 gpiod_set_value_cansleep(priv->reset_gpio, 1); in bno055_probe()
1590 ret = regmap_read(priv->regmap, BNO055_CHIP_ID_REG, &val); in bno055_probe()
1604 if (!priv->reset_gpio) { in bno055_probe()
1610 ret = regmap_read(priv->regmap, BNO055_SW_REV_LSB_REG, &rev); in bno055_probe()
1614 ret = regmap_read(priv->regmap, BNO055_SW_REV_MSB_REG, &ver); in bno055_probe()
1627 ret = regmap_bulk_read(priv->regmap, BNO055_UID_LOWER_REG, in bno055_probe()
1628 priv->uid, BNO055_UID_LEN); in bno055_probe()
1634 BNO055_UID_LEN, priv->uid); in bno055_probe()
1636 return -ENOMEM; in bno055_probe()
1646 ret = bno055_init(priv, caldata->data, caldata->size); in bno055_probe()
1652 priv->operation_mode = BNO055_OPR_MODE_FUSION; in bno055_probe()
1653 ret = bno055_operation_mode_do_set(priv, priv->operation_mode); in bno055_probe()
1661 iio_dev->channels = bno055_channels; in bno055_probe()
1662 iio_dev->num_channels = ARRAY_SIZE(bno055_channels); in bno055_probe()
1663 iio_dev->info = &bno055_info; in bno055_probe()
1664 iio_dev->modes = INDIO_DIRECT_MODE; in bno055_probe()