From: Hartmut Knaack <knaack.h@gmx.de>
To: Octavian Purdila <octavian.purdila@intel.com>, linux-iio@vger.kernel.org
Cc: srinivas.pandruvada@intel.com
Subject: Re: [RFC 3/8] iio: bmc150: refactor interrupt enabling
Date: Sun, 23 Nov 2014 23:02:26 +0100 [thread overview]
Message-ID: <54725972.7090104@gmx.de> (raw)
In-Reply-To: <1416246966-3083-4-git-send-email-octavian.purdila@intel.com>
Octavian Purdila schrieb am 17.11.2014 18:56:
> This patch combines the any motion and new data interrupts function
> into a single, generic, interrupt enable function. On top of this, we
> can later refactor triggers to make it easier to add new triggers.
>
> Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
> ---
> drivers/iio/accel/bmc150-accel.c | 271 +++++++++++++++++----------------------
> 1 file changed, 115 insertions(+), 156 deletions(-)
>
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index 5bfb09d..ee4afc4 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -144,6 +144,13 @@ struct bmc150_accel_chip_info {
> const struct bmc150_scale_info scale_table[4];
> };
>
> +struct bmc150_accel_interrupt_info {
> + u8 map_reg;
> + u8 map_bitmask;
> + u8 en_reg;
> + u8 en_bitmask;
> +};
> +
> struct bmc150_accel_data {
> struct i2c_client *client;
> struct iio_trigger *dready_trig;
> @@ -374,137 +381,6 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> return 0;
> }
>
> -static int bmc150_accel_setup_any_motion_interrupt(
> - struct bmc150_accel_data *data,
> - bool status)
> -{
> - int ret;
> -
> - /* Enable/Disable INT1 mapping */
> - ret = i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_MAP_0);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_map_0\n");
> - return ret;
> - }
> - if (status)
> - ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE;
> - else
> - ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE;
> -
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_MAP_0,
> - ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_map_0\n");
> - return ret;
> - }
> -
> - if (status) {
> - /*
> - * New data interrupt is always non-latched,
> - * which will have higher priority, so no need
> - * to set latched mode, we will be flooded anyway with INTR
> - */
> - if (!data->dready_trigger_on) {
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> - if (ret < 0) {
> - dev_err(&data->client->dev,
> - "Error writing reg_int_rst_latch\n");
> - return ret;
> - }
> - }
> -
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_EN_0,
> - BMC150_ACCEL_INT_EN_BIT_SLP_X |
> - BMC150_ACCEL_INT_EN_BIT_SLP_Y |
> - BMC150_ACCEL_INT_EN_BIT_SLP_Z);
> - } else
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_EN_0,
> - 0);
> -
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_en_0\n");
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> -static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data,
> - bool status)
> -{
> - int ret;
> -
> - /* Enable/Disable INT1 mapping */
> - ret = i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_MAP_1);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_map_1\n");
> - return ret;
> - }
> - if (status)
> - ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA;
> - else
> - ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA;
> -
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_MAP_1,
> - ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_map_1\n");
> - return ret;
> - }
> -
> - if (status) {
> - /*
> - * Set non latched mode interrupt and clear any latched
> - * interrupt
> - */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_NON_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> - if (ret < 0) {
> - dev_err(&data->client->dev,
> - "Error writing reg_int_rst_latch\n");
> - return ret;
> - }
> -
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_EN_1,
> - BMC150_ACCEL_INT_EN_BIT_DATA_EN);
> -
> - } else {
> - /* Restore default interrupt mode */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> - if (ret < 0) {
> - dev_err(&data->client->dev,
> - "Error writing reg_int_rst_latch\n");
> - return ret;
> - }
> -
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_EN_1,
> - 0);
> - }
> -
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_en_1\n");
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val,
> int *val2)
> {
> @@ -559,6 +435,99 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
> }
> #endif
>
> +static struct bmc150_accel_interrupt_info bmc150_accel_interrupts[] = {
> + { /* data ready interrupt */
> + .map_reg = BMC150_ACCEL_REG_INT_MAP_1,
> + .map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA,
> + .en_reg = BMC150_ACCEL_REG_INT_EN_1,
> + .en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN,
> + },
> + { /* motion interrupt */
> + .map_reg = BMC150_ACCEL_REG_INT_MAP_0,
> + .map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE,
> + .en_reg = BMC150_ACCEL_REG_INT_EN_0,
> + .en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X |
> + BMC150_ACCEL_INT_EN_BIT_SLP_Y |
> + BMC150_ACCEL_INT_EN_BIT_SLP_Z
> + },
> +};
> +
> +static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data,
> + struct bmc150_accel_interrupt_info *info,
> + bool state)
> +{
> + int ret;
> +
> + /*
> + * We will expect the enable and disable to do operation in
> + * in reverse order. This will happen here anyway as our
> + * resume operation uses sync mode runtime pm calls, the
> + * suspend operation will be delayed by autosuspend delay
> + * So the disable operation will still happen in reverse of
> + * enable operation. When runtime pm is disabled the mode
> + * is always on so sequence doesn't matter
> + */
> + ret = bmc150_accel_set_power_state(data, state);
> + if (ret < 0)
> + return ret;
> +
> +
> + /* map the interrupt to the appropriate pins */
> + if (info->map_reg) {
So, info->map_reg might be set, but info->en_reg will always be set?
> + ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
> + if (ret < 0) {
> + dev_err(&data->client->dev, "Error reading reg_int_map\n");
> + return ret;
> + }
> + if (state)
> + ret |= info->map_bitmask;
> + else
> + ret &= ~info->map_bitmask;
> +
> + ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
> + ret);
> + if (ret < 0) {
> + dev_err(&data->client->dev, "Error writing reg_int_map\n");
> + return ret;
> + }
> + }
> +
> + /* enable/disable the interrupt */
> + ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
> + if (ret < 0) {
> + dev_err(&data->client->dev, "Error reading reg_int_en\n");
> + return ret;
> + }
> +
> + if (state)
> + ret |= info->en_bitmask;
> + else
> + ret &= ~info->en_bitmask;
> +
> + ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> + if (ret < 0) {
> + dev_err(&data->client->dev, "Error writing reg_int_en\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int bmc150_accel_setup_any_motion_interrupt(
> + struct bmc150_accel_data *data,
> + bool status)
> +{
> + return bmc150_accel_set_interrupt(data, &bmc150_accel_interrupts[1],
> + status);
> +}
> +
> +static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data,
> + bool status)
> +{
> + return bmc150_accel_set_interrupt(data, &bmc150_accel_interrupts[0],
> + status);
> +}
> +
I don't think these wrappers really provide a benefit.
> static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> {
> int ret, i;
> @@ -808,22 +777,6 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev,
> return 0;
> }
>
> - /*
> - * We will expect the enable and disable to do operation in
> - * in reverse order. This will happen here anyway as our
> - * resume operation uses sync mode runtime pm calls, the
> - * suspend operation will be delayed by autosuspend delay
> - * So the disable operation will still happen in reverse of
> - * enable operation. When runtime pm is disabled the mode
> - * is always on so sequence doesn't matter
> - */
> -
> - ret = bmc150_accel_set_power_state(data, state);
> - if (ret < 0) {
> - mutex_unlock(&data->mutex);
> - return ret;
> - }
> -
> ret = bmc150_accel_setup_any_motion_interrupt(data, state);
> if (ret < 0) {
> mutex_unlock(&data->mutex);
> @@ -1055,15 +1008,6 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig,
> return 0;
> }
>
> - /*
> - * Refer to comment in bmc150_accel_write_event_config for
> - * enable/disable operation order
> - */
> - ret = bmc150_accel_set_power_state(data, state);
> - if (ret < 0) {
> - mutex_unlock(&data->mutex);
> - return ret;
> - }
> if (data->motion_trig == trig)
> ret = bmc150_accel_setup_any_motion_interrupt(data, state);
> else
> @@ -1240,6 +1184,21 @@ static int bmc150_accel_probe(struct i2c_client *client,
> if (ret)
> return ret;
>
> + /*
> + * Set latched mode interrupt. While certain interrupts are
> + * non-latched regardless of this settings (e.g. new data) we
> + * want to use latch mode when we can to prevent interrupt
> + * flooding.
> + */
> + ret = i2c_smbus_write_byte_data(data->client,
> + BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + if (ret < 0) {
> + dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> + return ret;
> + }
> +
> +
> data->dready_trig = devm_iio_trigger_alloc(&client->dev,
> "%s-dev%d",
> indio_dev->name,
>
next prev parent reply other threads:[~2014-11-23 22:02 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-17 17:55 [RFC 0/8] iio: add support for hardware fifo Octavian Purdila
2014-11-17 17:55 ` [RFC 1/8] " Octavian Purdila
2014-11-18 13:37 ` jic23
2014-11-18 15:21 ` Octavian Purdila
2014-11-17 17:56 ` [RFC 2/8] iio: bmc150: refactor slope duration and threshold update Octavian Purdila
2014-11-23 21:58 ` Hartmut Knaack
2014-11-23 22:16 ` Octavian Purdila
2014-11-17 17:56 ` [RFC 3/8] iio: bmc150: refactor interrupt enabling Octavian Purdila
2014-11-23 22:02 ` Hartmut Knaack [this message]
2014-11-23 22:24 ` Octavian Purdila
2014-11-17 17:56 ` [RFC 4/8] iio: bmc150: exit early if event / trigger state is not changed Octavian Purdila
2014-11-17 17:56 ` [RFC 5/8] iio: bmc150: introduce bmc150_accel_interrupt Octavian Purdila
2014-11-17 17:56 ` [RFC 6/8] iio: bmc150: introduce bmc150_accel_trigger Octavian Purdila
2014-11-23 23:06 ` Hartmut Knaack
2014-11-24 10:42 ` Octavian Purdila
2014-11-24 20:26 ` Hartmut Knaack
2014-11-25 16:06 ` Octavian Purdila
2014-11-17 17:56 ` [RFC 7/8] iio: bmc150: introduce bmc150_accel_event Octavian Purdila
2014-11-17 17:56 ` [RFC 8/8] iio: bmc150: add support for hardware fifo Octavian Purdila
2014-11-18 13:49 ` jic23
2014-11-18 15:31 ` Octavian Purdila
2014-11-24 10:37 ` Hartmut Knaack
2014-11-18 13:24 ` [RFC 0/8] iio: " jic23
2014-11-18 15:03 ` Octavian Purdila
2014-11-18 16:44 ` Lars-Peter Clausen
2014-11-18 17:04 ` Octavian Purdila
2014-11-18 17:23 ` Lars-Peter Clausen
2014-11-18 19:35 ` Octavian Purdila
2014-11-19 11:48 ` Lars-Peter Clausen
2014-11-19 12:33 ` Octavian Purdila
2014-12-12 12:57 ` Jonathan Cameron
2014-11-19 13:32 ` Octavian Purdila
2014-11-26 13:06 ` Octavian Purdila
2014-12-01 21:19 ` Lars-Peter Clausen
2014-12-02 9:13 ` Octavian Purdila
2014-12-12 13:10 ` Jonathan Cameron
2014-12-12 13:04 ` Jonathan Cameron
2014-12-12 12:52 ` Jonathan Cameron
2014-11-18 15:35 ` Pandruvada, Srinivas
2014-11-18 16:41 ` Lars-Peter Clausen
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=54725972.7090104@gmx.de \
--to=knaack.h@gmx.de \
--cc=linux-iio@vger.kernel.org \
--cc=octavian.purdila@intel.com \
--cc=srinivas.pandruvada@intel.com \
/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.