From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
Cc: Jonathan Cameron <jic23@kernel.org>, <linux-iio@vger.kernel.org>,
"Lorenzo BIANCONI" <lorenzo.bianconi@st.com>
Subject: Re: [PATCH] iio: accel: st_accel: add SPI-3wire support
Date: Wed, 5 Jul 2017 16:41:35 +0800 [thread overview]
Message-ID: <20170705164135.00002f50@huawei.com> (raw)
In-Reply-To: <CAA2SeNL=LKkSdBy5Wk3ECTp5_1UcxFX+k4dVzGFZKvnidv+DUQ@mail.gmail.com>
On Wed, 5 Jul 2017 10:27:17 +0200
Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> wrote:
> > On Mon, 3 Jul 2017 20:07:11 +0200
> > Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> wrote:
> >
> >> Add sensor interface mode (SIM) lookup table to support devices
> >> (like LSM303AGR accel sensor) that support just SPI-3wire
> >> communication mode. SIM mode has to be configured before any
> >> other operation since it is not enabled by default and the driver
> >> is not able to read without that configuration
> >>
> >> Fixes: ddc05fa28606 (iio: st-accel: add support for lsm303agr
> >> accel) Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@st.com>
> > Just checked and the 3-wire device tree property is documented in
> > spi-bus.txt
> >
> > So, that's all fine. However, I'm not keen on introducing a
> > special look up table for this when we already have a convenient
> > one covering all the other per device registers etc.
>
> Hi Jonathan,
>
> thanks for the review
>
> >
> > Another approach suggested inline...
> >> ---
> >> drivers/iio/accel/st_accel_core.c | 37
> >> +++++++++++++++++++++++++
> >> drivers/iio/common/st_sensors/st_sensors_core.c | 36
> >> ++++++++++++++++++++++++
> >> include/linux/iio/common/st_sensors.h | 11 ++++++++
> >> include/linux/platform_data/st_sensors_pdata.h | 2 ++ 4 files
> >> changed, 86 insertions(+)
> >>
> >> diff --git a/drivers/iio/accel/st_accel_core.c
> >> b/drivers/iio/accel/st_accel_core.c index
> >> 07d1489cd457..195966e82516 100644 ---
> >> a/drivers/iio/accel/st_accel_core.c +++
> >> b/drivers/iio/accel/st_accel_core.c @@ -619,6 +619,38 @@ static
> >> const struct st_sensor_settings st_accel_sensors_settings[] = { },
> >> };
> >>
> >> +static const struct st_sensor_sim st_accel_sim_table[] = {
> >> + {
> >> + .sensors = {
> >> + [0] = LSM303AGR_ACCEL_DEV_NAME,
> >> + [1] = LIS3DH_ACCEL_DEV_NAME,
> >> + [2] = LIS2DH12_ACCEL_DEV_NAME,
> >> + [3] = LIS331DLH_ACCEL_DEV_NAME,
> >> + [4] = LNG2DM_ACCEL_DEV_NAME,
> >> + [5] = LSM330D_ACCEL_DEV_NAME,
> >> + [6] = LSM330DL_ACCEL_DEV_NAME,
> >> + [7] = LSM330DLC_ACCEL_DEV_NAME,
> > The index has no meaning as we really have an unordered
> > list so perhaps drop it and let it automatically place them.
>
> Ack
>
> >
> > Doing it by name is particularly ugly given we already
> > have a big look up table for device differences.
> >
> > One option would be to split the st_sensors_check_device_support
> > function into two parts - the first does the match by name
> > and the second does the wai check. That way you could
> > then stick your configuration in between the two and
> > put this info in with all the other device specific
> > characteristics.
> >
> > To make the transition easy you could add the two split
> > functions and call them from the original. Then you can
> > introduce the split as needed into the various st sensor
> > drivers.
>
> Fine. I guess it is enough to add a static version of
> st_sensors_init_interface_mode
> with a reference to the right entry in st_sensor_settings from the top
> half of st_sensors_check_device_support.
> If the everything is ok with SIM configuration we will go forward to
> wai check in st_sensors_check_device_support bottom half.
> Maybe it is not necessary to split st_sensors_check_device_support in
> two separate functions. Do you agree?
As long as the logic ends up as
1) Look up table entry to get the address to configure 3 wire if
necessary.
2) Configure
3) Check WAI
Then I'm fine with any code arrangement that you want to use.
Jonathan
>
> Regards,
> Lorenzo
>
> >> + },
> >> + .addr = 0x23,
> >> + .val = BIT(0),
> >> + },
> >> + {
> >> + .sensors = {
> >> + [0] = LSM330_ACCEL_DEV_NAME,
> >> + },
> >> + .addr = 0x24,
> >> + .val = BIT(0),
> >> + },
> >> + {
> >> + .sensors = {
> >> + [0] = LIS3L02DQ_ACCEL_DEV_NAME,
> >> + [1] = LIS3LV02DL_ACCEL_DEV_NAME,
> >> + },
> >> + .addr = 0x21,
> >> + .val = BIT(1),
> >> + },
> >> +};
> >> +
> >> static int st_accel_read_raw(struct iio_dev *indio_dev,
> >> struct iio_chan_spec const *ch, int *val,
> >> int *val2,
> >> long mask) @@ -719,6 +751,11 @@ int st_accel_common_probe(struct
> >> iio_dev *indio_dev) indio_dev->info = &accel_info;
> >> mutex_init(&adata->tb.buf_lock);
> >>
> >> + err = st_sensors_init_interface_mode(indio_dev,
> >> st_accel_sim_table,
> >> +
> >> ARRAY_SIZE(st_accel_sim_table));
> >> + if (err < 0)
> >> + return err;
> >> +
> >> err = st_sensors_power_enable(indio_dev);
> >> if (err)
> >> return err;
> >> diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c
> >> b/drivers/iio/common/st_sensors/st_sensors_core.c index
> >> 274868100fd0..50c281b6286d 100644 ---
> >> a/drivers/iio/common/st_sensors/st_sensors_core.c +++
> >> b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -384,6
> >> +384,42 @@ static struct st_sensors_platform_data
> >> *st_sensors_of_probe(struct device *dev, } #endif
> >>
> >> +int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
> >> + const struct st_sensor_sim
> >> *sim_table,
> >> + int sim_len)
> >> +{
> >> + struct st_sensor_data *sdata = iio_priv(indio_dev);
> >> + struct device_node *np = sdata->dev->of_node;
> >> + struct st_sensors_platform_data *pdata;
> >> + int err = 0;
> >> +
> >> + pdata = (struct st_sensors_platform_data
> >> *)sdata->dev->platform_data;
> >> + if ((np && of_property_read_bool(np, "spi-3wire")) ||
> >> + (pdata && pdata->spi_3wire)) {
> >> + int i, j;
> >> +
> >> + for (i = 0; i < sim_len; i++) {
> >> + for (j = 0; j < ST_SENSORS_MAX_SIM; j++) {
> >> + if (!strcmp(sim_table[i].sensors[j],
> >> + indio_dev->name))
> >> + break;
> >> + }
> >> + if (j < ST_SENSORS_MAX_SIM)
> >> + break;
> >> + }
> >> +
> >> + if (i == sim_len)
> >> + return -EINVAL;
> >> +
> >> + err = sdata->tf->write_byte(&sdata->tb, sdata->dev,
> >> + sim_table[i].addr,
> >> + sim_table[i].val);
> >> + }
> >> +
> >> + return err;
> >> +}
> >> +EXPORT_SYMBOL(st_sensors_init_interface_mode);
> >> +
> >> int st_sensors_init_sensor(struct iio_dev *indio_dev,
> >> struct
> >> st_sensors_platform_data *pdata) {
> >> diff --git a/include/linux/iio/common/st_sensors.h
> >> b/include/linux/iio/common/st_sensors.h index
> >> 1f8211b6438b..15ce0cb360d7 100644 ---
> >> a/include/linux/iio/common/st_sensors.h +++
> >> b/include/linux/iio/common/st_sensors.h @@ -41,6 +41,7 @@
> >>
> >> #define ST_SENSORS_MAX_NAME 17
> >> #define ST_SENSORS_MAX_4WAI 7
> >> +#define ST_SENSORS_MAX_SIM 9
> >>
> >> #define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \
> >> ch2, s, endian, rbits,
> >> sbits, addr) \ @@ -105,6 +106,12 @@ struct st_sensor_fullscale {
> >> struct st_sensor_fullscale_avl
> >> fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX]; };
> >>
> >> +struct st_sensor_sim {
> >> + char sensors[ST_SENSORS_MAX_SIM][ST_SENSORS_MAX_NAME];
> >> + u8 addr;
> >> + u8 val;
> >> +};
> >> +
> >> /**
> >> * struct st_sensor_bdu - ST sensor device block data update
> >> * @addr: address of the register.
> >> @@ -325,6 +332,10 @@ ssize_t
> >> st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
> >> ssize_t st_sensors_sysfs_scale_avail(struct device *dev, struct
> >> device_attribute *attr, char *buf);
> >>
> >> +int st_sensors_init_interface_mode(struct iio_dev *indio_dev,
> >> + const struct st_sensor_sim
> >> *sim_table,
> >> + int sim_len);
> >> +
> >> #ifdef CONFIG_OF
> >> void st_sensors_of_name_probe(struct device *dev,
> >> const struct of_device_id *match,
> >> diff --git a/include/linux/platform_data/st_sensors_pdata.h
> >> b/include/linux/platform_data/st_sensors_pdata.h index
> >> 79b0e4cdb814..f8274b0c6888 100644 ---
> >> a/include/linux/platform_data/st_sensors_pdata.h +++
> >> b/include/linux/platform_data/st_sensors_pdata.h @@ -17,10 +17,12
> >> @@
> >> * Available only for accelerometer and pressure sensors.
> >> * Accelerometer DRDY on LSM330 available only on pin 1 (see
> >> datasheet).
> >> * @open_drain: set the interrupt line to be open drain if
> >> possible.
> >> + * @spi_3wire: enable spi-3wire mode.
> >> */
> >> struct st_sensors_platform_data {
> >> u8 drdy_int_pin;
> >> bool open_drain;
> >> + bool spi_3wire;
> >> };
> >>
> >> #endif /* ST_SENSORS_PDATA_H */
> >
>
>
>
prev parent reply other threads:[~2017-07-05 8:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-03 18:07 [PATCH] iio: accel: st_accel: add SPI-3wire support Lorenzo Bianconi
2017-07-04 19:26 ` Jonathan Cameron
2017-07-05 8:27 ` Lorenzo Bianconi
2017-07-05 8:41 ` Jonathan Cameron [this message]
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=20170705164135.00002f50@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=lorenzo.bianconi83@gmail.com \
--cc=lorenzo.bianconi@st.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox