Re: [PATCH 3/4] iio: accel: Add event subsystem to st_accel driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 07/02/13 13:15, Lukasz Czerwinski wrote:
> This patch adds event support for iio st_accel driver.
>
> Signed-off-by: Lukasz Czerwinski <l.czerwinski@xxxxxxxxxxx>
> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>

Now I may have gotten lost in the driver, but I believe the underlying
channel specs are constant and in this patch you edit their event masks.
Not a good idea ;)

Also, I am going to guess you haven't tried building this version as
modules.  You are missing some symbol exports in the previous patch.

> ---
>  .../bindings/iio/accelerometer/st_accel.txt        |    1 +
>  drivers/iio/accel/st_accel_core.c                  |  149 ++++++++++++++++++++
>  2 files changed, 150 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
> index 9eab7d9..f461a77 100644
> --- a/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
> +++ b/Documentation/devicetree/bindings/iio/accelerometer/st_accel.txt
> @@ -21,6 +21,7 @@ Optional properties:
>    - interrupt-parent : phandle to the interrupt map subnode
>    - interrupts : interrupt mapping for st_accel interrupt sources:
>  	0: INT1 irq_data_ready
> +	1: INT2 irq_event
>    - irq-map : irq sub-node defining interrupt map
>                (all properties listed below are required):
>        - #interrupt-cells : should be 1
> diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
> index 385cd86..983e8c4 100644
> --- a/drivers/iio/accel/st_accel_core.c
> +++ b/drivers/iio/accel/st_accel_core.c
> @@ -19,6 +19,7 @@
>  #include <linux/gpio.h>
>  #include <linux/irq.h>
>  #include <linux/iio/iio.h>
> +#include <linux/iio/events.h>
>  #include <linux/iio/sysfs.h>
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/buffer.h>
> @@ -68,6 +69,20 @@
>  #define ST_ACCEL_1_DRDY_IRQ_INT1_MASK		0x10
>  #define ST_ACCEL_1_DRDY_IRQ_INT2_MASK		0x08
>  #define ST_ACCEL_1_MULTIREAD_BIT		true
> +#define ST_ACCEL_1_EVENT_IRQ_ADDR		0x22
> +#define ST_ACCEL_1_EVENT_IRQ_MASK		0x40
> +#define ST_ACCEL_1_EVENT_CTRL_REG		0x30
> +#define ST_ACCEL_1_EVENT_CTRL_MASK		0xc0
> +#define ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL	0x01
> +#define ST_ACCEL_1_THS_REG			0x32
> +#define ST_ACCEL_1_EVENT_STATUS_REG		0x31
> +#define ST_ACCEL_1_EVENT_STATUS_REG_MASK	0x7f
> +#define ST_ACCEL_1_INT1_XL			0
> +#define ST_ACCEL_1_INT1_XH			1
> +#define ST_ACCEL_1_INT1_YL			2
> +#define ST_ACCEL_1_INT1_YH			3
> +#define ST_ACCEL_1_INT1_ZL			4
> +#define ST_ACCEL_1_INT1_ZH			5
>
>  /* CUSTOM VALUES FOR SENSOR 2 */
>  #define ST_ACCEL_2_WAI_EXP			0x32
> @@ -93,6 +108,20 @@
>  #define ST_ACCEL_2_DRDY_IRQ_INT1_MASK		0x02
>  #define ST_ACCEL_2_DRDY_IRQ_INT2_MASK		0x10
>  #define ST_ACCEL_2_MULTIREAD_BIT		true
> +#define ST_ACCEL_2_EVENT_IRQ_ADDR		0x22
> +#define ST_ACCEL_2_EVENT_IRQ_MASK		0x01
> +#define ST_ACCEL_2_EVENT_CTRL_REG		0x30
> +#define ST_ACCEL_2_EVENT_CTRL_MASK		0xc0
> +#define ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL	0x01
> +#define ST_ACCEL_2_THS_REG			0x32
> +#define ST_ACCEL_2_EVENT_STATUS_REG		0x31
> +#define ST_ACCEL_2_EVENT_STATUS_REG_MASK	0x7f
> +#define ST_ACCEL_2_INT1_XL			0
> +#define ST_ACCEL_2_INT1_XH			1
> +#define ST_ACCEL_2_INT1_YL			2
> +#define ST_ACCEL_2_INT1_YH			3
> +#define ST_ACCEL_2_INT1_ZL			4
> +#define ST_ACCEL_2_INT1_ZH			5
>
>  /* CUSTOM VALUES FOR SENSOR 3 */
>  #define ST_ACCEL_3_WAI_EXP			0x40
> @@ -129,6 +158,20 @@
>  #define ST_ACCEL_3_IG1_EN_MASK			0x08
>  #define ST_ACCEL_3_MULTIREAD_BIT		false
>
> +#define ST_SENSORS_LSM_ACCEL_EVENT(ch, mod, dir, bit_pos, ths_reg) \
> +{ \
> +	.bit = bit_pos,\
Hmm. A lot of this replicates info already available in the iio_chan_spec.
I guess this 'might' be the cleanest way of doing things but it seems
a little convoluted.
> +	.chan = ch, \
> +	.chan_type = IIO_ACCEL, \
> +	.modifier = mod, \
> +	.event_type = IIO_EV_TYPE_THRESH, \
> +	.direction = dir, \
> +	.event_ths_reg = { \
> +		.addr = ths_reg, \
> +		.mask = 0x7f, \
> +	}, \
> +}
> +
>  static const struct iio_chan_spec st_accel_12bit_channels[] = {
>  	ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
>  			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> @@ -232,6 +275,46 @@ static const struct st_sensors st_accel_sensors[] = {
>  		},
>  		.multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
>  		.bootime = 2,
> +		.event_irq = {
> +			.addr = ST_ACCEL_1_EVENT_IRQ_ADDR,
> +			.mask = ST_ACCEL_1_EVENT_IRQ_MASK,
> +			.event_count = 6,
> +			.ctrl_reg = {
> +				.addr = ST_ACCEL_1_EVENT_CTRL_REG,
> +				.mask = ST_ACCEL_1_EVENT_CTRL_MASK,
> +				.val = ST_ACCEL_1_EVENT_CTRL_DEFAULT_VAL,
> +			},
> +			.status_reg = {
> +				.addr = ST_ACCEL_1_EVENT_STATUS_REG,
> +				.mask = ST_ACCEL_1_EVENT_STATUS_REG_MASK,
> +			},
> +			.events = {
> +				ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_1_INT1_XL,
> +						ST_ACCEL_1_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_1_INT1_XH,
> +						ST_ACCEL_1_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_1_INT1_YL,
> +						ST_ACCEL_1_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_1_INT1_YH,
> +						ST_ACCEL_1_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_1_INT1_ZL,
> +						ST_ACCEL_1_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_1_INT1_ZH,
> +						ST_ACCEL_1_THS_REG),
> +			},
> +		},
>  	},
>  	{
>  		.wai = ST_ACCEL_2_WAI_EXP,
> @@ -294,6 +377,47 @@ static const struct st_sensors st_accel_sensors[] = {
>  		},
>  		.multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
>  		.bootime = 2,
> +		.event_irq = {
> +			.addr = ST_ACCEL_2_EVENT_IRQ_ADDR,
> +			.mask = ST_ACCEL_2_EVENT_IRQ_MASK,
> +			.event_count = 6,
> +			.ctrl_reg = {
> +				.addr = ST_ACCEL_2_EVENT_CTRL_REG,
> +				.mask = ST_ACCEL_2_EVENT_CTRL_MASK,
> +				.val = ST_ACCEL_2_EVENT_CTRL_DEFAULT_VAL,
> +			},
> +			.status_reg = {
> +				.addr = ST_ACCEL_2_EVENT_STATUS_REG,
> +				.mask = ST_ACCEL_2_EVENT_STATUS_REG_MASK,
> +			},
> +			.events = {
> +				ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_2_INT1_XL,
> +						ST_ACCEL_2_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(0, IIO_MOD_X,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_2_INT1_XH,
> +						ST_ACCEL_2_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_2_INT1_YL,
> +						ST_ACCEL_2_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(1, IIO_MOD_Y,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_2_INT1_YH,
> +						ST_ACCEL_2_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
> +						IIO_EV_DIR_FALLING,
> +						ST_ACCEL_2_INT1_ZL,
> +						ST_ACCEL_2_THS_REG),
> +				ST_SENSORS_LSM_ACCEL_EVENT(2, IIO_MOD_Z,
> +						IIO_EV_DIR_RISING,
> +						ST_ACCEL_2_INT1_ZH,
> +						ST_ACCEL_2_THS_REG),
> +			},
> +		},
> +
>  	},
>  	{
>  		.wai = ST_ACCEL_3_WAI_EXP,
> @@ -437,6 +561,10 @@ static const struct iio_info accel_info = {
>  	.attrs = &st_accel_attribute_group,
>  	.read_raw = &st_accel_read_raw,
>  	.write_raw = &st_accel_write_raw,
> +	.read_event_value = &st_sensors_read_event_value,
> +	.write_event_value = &st_sensors_write_event_value,
> +	.read_event_config = &st_sensors_read_event_config,
> +	.write_event_config = &st_sensors_write_event_config,
>  };
>
>  #ifdef CONFIG_IIO_TRIGGER
> @@ -452,6 +580,7 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
>  int st_accel_common_probe(struct iio_dev *indio_dev)
>  {
>  	int err;
> +	int i;
>  	struct st_sensor_data *adata = iio_priv(indio_dev);
>
>  	indio_dev->modes = INDIO_DIRECT_MODE;
> @@ -489,6 +618,20 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>  			goto st_accel_probe_trigger_error;
>  	}
>
> +	if (adata->get_irq_event(indio_dev) > 0) {
> +		err = st_sensors_request_event_irq(indio_dev);
Compile error as not exported in the previous patch.

> +		if (err < 0)
> +			goto st_accel_request_irq_event_error;
> +
> +		for (i = 0; i < indio_dev->num_channels; i++)
> +			adata->sensor->ch[i].event_mask =
> +				ST_SENSORS_LSM_EVENTS_MASK;

This is an easy driver to get lost in, but I think that adata->sensor is
pointing at some constant data, so you can't do the above.  Actually,
ideally this would be made explicit throughout the driver by making the
data pointed to by those pointers constant as well as the pointer.

> +
> +		err = st_sensors_enable_events(indio_dev);
> +		if (err < 0)
> +			goto st_accel_enable_events_error;
> +	}
> +
>  	err = iio_device_register(indio_dev);
>  	if (err)
>  		goto st_accel_device_register_error;
> @@ -496,6 +639,10 @@ int st_accel_common_probe(struct iio_dev *indio_dev)
>  	return err;
>
>  st_accel_device_register_error:
> +st_accel_enable_events_error:
> +	if (adata->get_irq_event(indio_dev) > 0)
> +		free_irq(adata->get_irq_event(indio_dev), indio_dev);
> +st_accel_request_irq_event_error:
>  	if (adata->get_irq_data_ready(indio_dev) > 0)
>  		st_sensors_deallocate_trigger(indio_dev);
>  st_accel_probe_trigger_error:
> @@ -515,6 +662,8 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
>  		st_sensors_deallocate_trigger(indio_dev);
>  		st_accel_deallocate_ring(indio_dev);
>  	}
> +	if (adata->get_irq_event(indio_dev) > 0)
> +		free_irq(adata->get_irq_event(indio_dev), indio_dev);
>  	iio_device_free(indio_dev);
>  }
>  EXPORT_SYMBOL(st_accel_common_remove);
>
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux