From: Jonathan Cameron <jic23@kernel.org>
To: Jean-Baptiste Maneyrol <JManeyrol@invensense.com>
Cc: "linux-iio@vger.kernel.org" <linux-iio@vger.kernel.org>
Subject: Re: [PATCH v3 5/7] iio: imu: inv_mpu6050: helpers for using i2c master on auxiliary bus
Date: Sat, 5 Oct 2019 12:06:38 +0100 [thread overview]
Message-ID: <20191005120638.110ae8f1@archlinux> (raw)
In-Reply-To: <20190916094128.30122-6-jmaneyrol@invensense.com>
On Mon, 16 Sep 2019 09:42:05 +0000
Jean-Baptiste Maneyrol <JManeyrol@invensense.com> wrote:
> Add helper functions to use the i2c auxiliary bus with the MPU i2c
> master block.
>
> Support only register based chip, reading and 1 byte writing. These
> will be useful for initializing magnetometers inside MPU9x50 chips.
>
> Signed-off-by: Jean-Baptiste Maneyrol <jmaneyrol@invensense.com>
I'm getting sparse warnings on this one about not marking the functions
static because the header isn't included by the c file. Fixed up.
Applied to the togreg branch of iio.git and pushed out as testing
for the autobuilders to play with it.
Thanks,
Jonathan
> ---
> drivers/iio/imu/inv_mpu6050/Makefile | 3 +-
> drivers/iio/imu/inv_mpu6050/inv_mpu_aux.c | 203 ++++++++++++++++++++++
> drivers/iio/imu/inv_mpu6050/inv_mpu_aux.h | 19 ++
> 3 files changed, 224 insertions(+), 1 deletion(-)
> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_aux.c
> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_aux.h
>
> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
> index 33bec09fee9b..2cfbd926522f 100644
> --- a/drivers/iio/imu/inv_mpu6050/Makefile
> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
> @@ -4,7 +4,8 @@
> #
>
> obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o
> -inv-mpu6050-y := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
> +inv-mpu6050-y := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o \
> + inv_mpu_aux.o
>
> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
> inv-mpu6050-i2c-y := inv_mpu_i2c.o inv_mpu_acpi.o
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.c
> new file mode 100644
> index 000000000000..576548e28120
> --- /dev/null
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.c
> @@ -0,0 +1,203 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 TDK-InvenSense, Inc.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +#include <linux/delay.h>
> +
> +#include "inv_mpu_iio.h"
> +
> +/*
> + * i2c master auxiliary bus transfer function.
> + * Requires the i2c operations to be correctly setup before.
> + */
> +static int inv_mpu_i2c_master_xfer(const struct inv_mpu6050_state *st)
> +{
> + /* use 50hz frequency for xfer */
> + const unsigned int freq = 50;
> + const unsigned int period_ms = 1000 / freq;
> + uint8_t d;
> + unsigned int user_ctrl;
> + int ret;
> +
> + /* set sample rate */
> + d = INV_MPU6050_FIFO_RATE_TO_DIVIDER(freq);
> + ret = regmap_write(st->map, st->reg->sample_rate_div, d);
> + if (ret)
> + return ret;
> +
> + /* start i2c master */
> + user_ctrl = st->chip_config.user_ctrl | INV_MPU6050_BIT_I2C_MST_EN;
> + ret = regmap_write(st->map, st->reg->user_ctrl, user_ctrl);
> + if (ret)
> + goto error_restore_rate;
> +
> + /* wait for xfer: 1 period + half-period margin */
> + msleep(period_ms + period_ms / 2);
> +
> + /* stop i2c master */
> + user_ctrl = st->chip_config.user_ctrl;
> + ret = regmap_write(st->map, st->reg->user_ctrl, user_ctrl);
> + if (ret)
> + goto error_stop_i2c;
> +
> + /* restore sample rate */
> + d = st->chip_config.divider;
> + ret = regmap_write(st->map, st->reg->sample_rate_div, d);
> + if (ret)
> + goto error_restore_rate;
> +
> + return 0;
> +
> +error_stop_i2c:
> + regmap_write(st->map, st->reg->user_ctrl, st->chip_config.user_ctrl);
> +error_restore_rate:
> + regmap_write(st->map, st->reg->sample_rate_div, st->chip_config.divider);
> + return ret;
> +}
> +
> +/**
> + * inv_mpu_aux_init() - init i2c auxiliary bus
> + * @st: driver internal state
> + *
> + * Returns 0 on success, a negative error code otherwise.
> + */
> +int inv_mpu_aux_init(const struct inv_mpu6050_state *st)
> +{
> + unsigned int val;
> + int ret;
> +
> + /* configure i2c master */
> + val = INV_MPU6050_BITS_I2C_MST_CLK_400KHZ |
> + INV_MPU6050_BIT_WAIT_FOR_ES;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_MST_CTRL, val);
> + if (ret)
> + return ret;
> +
> + /* configure i2c master delay */
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV4_CTRL, 0);
> + if (ret)
> + return ret;
> +
> + val = INV_MPU6050_BIT_I2C_SLV0_DLY_EN |
> + INV_MPU6050_BIT_I2C_SLV1_DLY_EN |
> + INV_MPU6050_BIT_I2C_SLV2_DLY_EN |
> + INV_MPU6050_BIT_I2C_SLV3_DLY_EN |
> + INV_MPU6050_BIT_DELAY_ES_SHADOW;
> + return regmap_write(st->map, INV_MPU6050_REG_I2C_MST_DELAY_CTRL, val);
> +}
> +
> +/**
> + * inv_mpu_aux_read() - read register function for i2c auxiliary bus
> + * @st: driver internal state.
> + * @addr: chip i2c Address
> + * @reg: chip register address
> + * @val: buffer for storing read bytes
> + * @size: number of bytes to read
> + *
> + * Returns 0 on success, a negative error code otherwise.
> + */
> +int inv_mpu_aux_read(const struct inv_mpu6050_state *st, uint8_t addr,
> + uint8_t reg, uint8_t *val, size_t size)
> +{
> + unsigned int status;
> + int ret;
> +
> + if (size > 0x0F)
> + return -EINVAL;
> +
> + /* setup i2c SLV0 control: i2c addr, register, enable + size */
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_ADDR(0),
> + INV_MPU6050_BIT_I2C_SLV_RNW | addr);
> + if (ret)
> + return ret;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_REG(0), reg);
> + if (ret)
> + return ret;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0),
> + INV_MPU6050_BIT_SLV_EN | size);
> + if (ret)
> + return ret;
> +
> + /* do i2c xfer */
> + ret = inv_mpu_i2c_master_xfer(st);
> + if (ret)
> + goto error_disable_i2c;
> +
> + /* disable i2c slave */
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0), 0);
> + if (ret)
> + goto error_disable_i2c;
> +
> + /* check i2c status */
> + ret = regmap_read(st->map, INV_MPU6050_REG_I2C_MST_STATUS, &status);
> + if (ret)
> + return ret;
> + if (status & INV_MPU6050_BIT_I2C_SLV0_NACK)
> + return -EIO;
> +
> + /* read data in registers */
> + return regmap_bulk_read(st->map, INV_MPU6050_REG_EXT_SENS_DATA,
> + val, size);
> +
> +error_disable_i2c:
> + regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0), 0);
> + return ret;
> +}
> +
> +/**
> + * inv_mpu_aux_write() - write register function for i2c auxiliary bus
> + * @st: driver internal state.
> + * @addr: chip i2c Address
> + * @reg: chip register address
> + * @val: 1 byte value to write
> + *
> + * Returns 0 on success, a negative error code otherwise.
> + */
> +int inv_mpu_aux_write(const struct inv_mpu6050_state *st, uint8_t addr,
> + uint8_t reg, uint8_t val)
> +{
> + unsigned int status;
> + int ret;
> +
> + /* setup i2c SLV0 control: i2c addr, register, value, enable + size */
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_ADDR(0), addr);
> + if (ret)
> + return ret;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_REG(0), reg);
> + if (ret)
> + return ret;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_DO(0), val);
> + if (ret)
> + return ret;
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0),
> + INV_MPU6050_BIT_SLV_EN | 1);
> + if (ret)
> + return ret;
> +
> + /* do i2c xfer */
> + ret = inv_mpu_i2c_master_xfer(st);
> + if (ret)
> + goto error_disable_i2c;
> +
> + /* disable i2c slave */
> + ret = regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0), 0);
> + if (ret)
> + goto error_disable_i2c;
> +
> + /* check i2c status */
> + ret = regmap_read(st->map, INV_MPU6050_REG_I2C_MST_STATUS, &status);
> + if (ret)
> + return ret;
> + if (status & INV_MPU6050_BIT_I2C_SLV0_NACK)
> + return -EIO;
> +
> + return 0;
> +
> +error_disable_i2c:
> + regmap_write(st->map, INV_MPU6050_REG_I2C_SLV_CTRL(0), 0);
> + return ret;
> +}
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.h
> new file mode 100644
> index 000000000000..b66997545762
> --- /dev/null
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_aux.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2019 TDK-InvenSense, Inc.
> + */
> +
> +#ifndef INV_MPU_AUX_H_
> +#define INV_MPU_AUX_H_
> +
> +#include "inv_mpu_iio.h"
> +
> +int inv_mpu_aux_init(const struct inv_mpu6050_state *st);
> +
> +int inv_mpu_aux_read(const struct inv_mpu6050_state *st, uint8_t addr,
> + uint8_t reg, uint8_t *val, size_t size);
> +
> +int inv_mpu_aux_write(const struct inv_mpu6050_state *st, uint8_t addr,
> + uint8_t reg, uint8_t val);
> +
> +#endif /* INV_MPU_AUX_H_ */
next prev parent reply other threads:[~2019-10-05 11:06 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-16 9:41 [PATCH v3 0/7] add magnetometer support for MPU925x Jean-Baptiste Maneyrol
2019-09-16 9:41 ` [PATCH v3 1/7] iio: imu: inv_mpu6050: disable i2c mux " Jean-Baptiste Maneyrol
2019-10-05 10:57 ` Jonathan Cameron
2019-09-16 9:42 ` [PATCH v3 2/7] iio: imu: inv_mpu6050: add header include protection macro Jean-Baptiste Maneyrol
2019-10-05 10:58 ` Jonathan Cameron
2019-09-16 9:42 ` [PATCH v3 3/7] iio: imu: inv_mpu6050: add defines for supporting 9-axis chips Jean-Baptiste Maneyrol
2019-10-05 10:58 ` Jonathan Cameron
2019-09-16 9:42 ` [PATCH v3 4/7] iio: imu: inv_mpu6050: fix objects syntax in Makefile Jean-Baptiste Maneyrol
2019-10-05 11:00 ` Jonathan Cameron
2019-09-16 9:42 ` [PATCH v3 5/7] iio: imu: inv_mpu6050: helpers for using i2c master on auxiliary bus Jean-Baptiste Maneyrol
2019-10-05 11:06 ` Jonathan Cameron [this message]
2019-09-16 9:42 ` [PATCH v3 6/7] iio: imu: inv_mpu6050: add MPU925x magnetometer support Jean-Baptiste Maneyrol
2019-10-05 11:13 ` Jonathan Cameron
2019-09-16 9:42 ` [PATCH v3 7/7] iio: imu: inv_mpu6050: add fifo support for magnetometer data Jean-Baptiste Maneyrol
2019-10-05 11:15 ` Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191005120638.110ae8f1@archlinux \
--to=jic23@kernel.org \
--cc=JManeyrol@invensense.com \
--cc=linux-iio@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.