/* check whoami */
ret = inv_mpu_aux_read(st, INV_MPU_MAGN_I2C_ADDR, INV_MPU_MAGN_REG_WIA,
&val, sizeof(val)); if (ret) return ret; if (val != INV_MPU_MAGN_BITS_WIA) return -ENODEV;
/* software reset for MPU925x only */ switch (st->chip_type) { case INV_MPU9250: case INV_MPU9255:
ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
INV_MPU9250_MAGN_REG_CNTL2,
INV_MPU9250_MAGN_BIT_SRST); if (ret) return ret; break; default: break;
}
/* read fuse ROM data */
ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
INV_MPU_MAGN_REG_CNTL1,
INV_MPU_MAGN_BITS_MODE_FUSE); if (ret) return ret;
ret = inv_mpu_aux_read(st, INV_MPU_MAGN_I2C_ADDR, INV_MPU_MAGN_REG_ASAX,
asa, sizeof(asa)); if (ret) return ret;
/* switch back to power-down */
ret = inv_mpu_aux_write(st, INV_MPU_MAGN_I2C_ADDR,
INV_MPU_MAGN_REG_CNTL1,
INV_MPU_MAGN_BITS_MODE_PWDN); if (ret) return ret;
/* * Sensor sentivity * 1 uT = 0.01 G and value is in micron (1e6) * sensitvity = x uT * 0.01 * 1e6
*/ switch (st->chip_type) { case INV_MPU9150: /* sensor sensitivity is 0.3 uT */
sensitivity = 3000; break; case INV_MPU9250: case INV_MPU9255: /* sensor sensitivity in 16 bits mode: 0.15 uT */
sensitivity = 1500; break; default: return -EINVAL;
}
/** * inv_mpu_magn_probe() - probe and setup magnetometer chip * @st: driver internal state * * Returns 0 on success, a negative error code otherwise * * It is probing the chip and setting up all needed i2c transfers. * Noop if there is no magnetometer in the chip.
*/ int inv_mpu_magn_probe(struct inv_mpu6050_state *st)
{
uint8_t val; int ret;
/* quit if chip is not supported */ if (!inv_magn_supported(st)) return 0;
/* configure i2c master aux port */
ret = inv_mpu_aux_init(st); if (ret) return ret;
/* check and init mag chip */
ret = inv_magn_init(st); if (ret) return ret;
/* * configure mpu i2c master accesses * i2c SLV0: read sensor data, 7 bytes data(6)-ST2 * Byte swap data to store them in big-endian in impair address groups
*/
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_ADDR(0),
INV_MPU6050_BIT_I2C_SLV_RNW | INV_MPU_MAGN_I2C_ADDR); if (ret) return ret;
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_REG(0),
INV_MPU_MAGN_REG_DATA); if (ret) return ret;
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0),
INV_MPU6050_BIT_SLV_EN |
INV_MPU6050_BIT_SLV_BYTE_SW |
INV_MPU6050_BIT_SLV_GRP |
INV_MPU9X50_BYTES_MAGN); if (ret) return ret;
/* i2c SLV1: launch single measurement */
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_ADDR(1),
INV_MPU_MAGN_I2C_ADDR); if (ret) return ret;
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_REG(1),
INV_MPU_MAGN_REG_CNTL1); if (ret) return ret;
/* add 16 bits mode for MPU925x */
val = INV_MPU_MAGN_BITS_MODE_SINGLE; switch (st->chip_type) { case INV_MPU9250: case INV_MPU9255:
val |= INV_MPU9250_MAGN_BIT_OUTPUT_BIT; break; default: break;
}
ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(1), val); if (ret) return ret;
/** * inv_mpu_magn_set_rate() - set magnetometer sampling rate * @st: driver internal state * @fifo_rate: mpu set fifo rate * * Returns 0 on success, a negative error code otherwise * * Limit sampling frequency to the maximum value supported by the * magnetometer chip. Resulting in duplicated data for higher frequencies. * Noop if there is no magnetometer in the chip.
*/ int inv_mpu_magn_set_rate(conststruct inv_mpu6050_state *st, int fifo_rate)
{
uint8_t d;
/* quit if chip is not supported */ if (!inv_magn_supported(st)) return 0;
/* * update i2c master delay to limit mag sampling to max frequency * compute fifo_rate divider d: rate = fifo_rate / (d + 1)
*/ if (fifo_rate > INV_MPU_MAGN_FREQ_HZ_MAX)
d = fifo_rate / INV_MPU_MAGN_FREQ_HZ_MAX - 1; else
d = 0;
/** * inv_mpu_magn_set_orient() - fill magnetometer mounting matrix * @st: driver internal state * * Returns 0 on success, a negative error code otherwise * * Fill magnetometer mounting matrix using the provided chip matrix.
*/ int inv_mpu_magn_set_orient(struct inv_mpu6050_state *st)
{ struct device *dev = regmap_get_device(st->map); constchar *orient; char *str; int i;
/* fill magnetometer orientation */ switch (st->chip_type) { case INV_MPU9150: case INV_MPU9250: case INV_MPU9255: /* x <- y */
st->magn_orient.rotation[0] = st->orientation.rotation[3];
st->magn_orient.rotation[1] = st->orientation.rotation[4];
st->magn_orient.rotation[2] = st->orientation.rotation[5]; /* y <- x */
st->magn_orient.rotation[3] = st->orientation.rotation[0];
st->magn_orient.rotation[4] = st->orientation.rotation[1];
st->magn_orient.rotation[5] = st->orientation.rotation[2]; /* z <- -z */ for (i = 6; i < 9; ++i) {
orient = st->orientation.rotation[i];
/* * The value is negated according to one of the following * rules: * * 1) Drop leading minus. * 2) Leave 0 as is. * 3) Add leading minus.
*/ if (orient[0] == '-')
str = devm_kstrdup(dev, orient + 1, GFP_KERNEL); elseif (!strcmp(orient, "0"))
str = devm_kstrdup(dev, orient, GFP_KERNEL); else
str = devm_kasprintf(dev, GFP_KERNEL, "-%s", orient); if (!str) return -ENOMEM;
/** * inv_mpu_magn_read() - read magnetometer data * @st: driver internal state * @axis: IIO modifier axis value * @val: store corresponding axis value * * Returns 0 on success, a negative error code otherwise
*/ int inv_mpu_magn_read(struct inv_mpu6050_state *st, int axis, int *val)
{ unsignedint status;
__be16 data;
uint8_t addr; int ret;
/* quit if chip is not supported */ if (!inv_magn_supported(st)) return -ENODEV;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.