diff options
author | Nuno Sá <nuno.sa@analog.com> | 2020-01-07 14:17:04 +0300 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2020-01-12 14:34:12 +0300 |
commit | 380b107bbf9449ddea0637cefe65a6cbf7b6ca84 (patch) | |
tree | d1b5b4ae244e546eac2abf5955cde0f81f334e06 /drivers/iio/imu/adis16480.c | |
parent | 687d39d4512aa5f644450d0662f40aeeac1e84a7 (diff) | |
download | linux-380b107bbf9449ddea0637cefe65a6cbf7b6ca84.tar.xz |
iio: adis: Introduce timeouts structure
The adis library only allows to define a `startup_delay` which for some
devices is enough. However, other devices define different timeouts with
significantly different timings which could lead to devices to not wait
enough time or to wait a lot more than necessary (which is not
efficient). This patch introduces a new timeout struct that must be
passed into `adis_init()`. There are mainly, for now, three timeouts
used. This is also an introductory patch with the goal of refactoring
`adis_initial_startup()`. New driver's (eg: adis16480, adis16460) are
replicating code for the device initial setup. With some changes (being
this the first one) we can pass this to `adis_initial_startup()`.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio/imu/adis16480.c')
-rw-r--r-- | drivers/iio/imu/adis16480.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index f73094e8d35d..f0ad7ce64861 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -138,6 +138,7 @@ struct adis16480_chip_info { unsigned int max_dec_rate; const unsigned int *filter_freqs; bool has_pps_clk_mode; + const struct adis_timeout *timeouts; }; enum adis16480_int_pin { @@ -794,6 +795,30 @@ enum adis16480_variant { ADIS16497_3, }; +static const struct adis_timeout adis16485_timeouts = { + .reset_ms = 560, + .sw_reset_ms = 120, + .self_test_ms = 12, +}; + +static const struct adis_timeout adis16480_timeouts = { + .reset_ms = 560, + .sw_reset_ms = 560, + .self_test_ms = 12, +}; + +static const struct adis_timeout adis16495_timeouts = { + .reset_ms = 170, + .sw_reset_ms = 130, + .self_test_ms = 40, +}; + +static const struct adis_timeout adis16495_1_timeouts = { + .reset_ms = 250, + .sw_reset_ms = 210, + .self_test_ms = 20, +}; + static const struct adis16480_chip_info adis16480_chip_info[] = { [ADIS16375] = { .channels = adis16485_channels, @@ -812,6 +837,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .int_clk = 2460000, .max_dec_rate = 2048, .filter_freqs = adis16480_def_filter_freqs, + .timeouts = &adis16485_timeouts, }, [ADIS16480] = { .channels = adis16480_channels, @@ -824,6 +850,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .int_clk = 2460000, .max_dec_rate = 2048, .filter_freqs = adis16480_def_filter_freqs, + .timeouts = &adis16480_timeouts, }, [ADIS16485] = { .channels = adis16485_channels, @@ -836,6 +863,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .int_clk = 2460000, .max_dec_rate = 2048, .filter_freqs = adis16480_def_filter_freqs, + .timeouts = &adis16485_timeouts, }, [ADIS16488] = { .channels = adis16480_channels, @@ -848,6 +876,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .int_clk = 2460000, .max_dec_rate = 2048, .filter_freqs = adis16480_def_filter_freqs, + .timeouts = &adis16485_timeouts, }, [ADIS16495_1] = { .channels = adis16485_channels, @@ -861,6 +890,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, [ADIS16495_2] = { .channels = adis16485_channels, @@ -874,6 +904,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, [ADIS16495_3] = { .channels = adis16485_channels, @@ -887,6 +918,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, [ADIS16497_1] = { .channels = adis16485_channels, @@ -900,6 +932,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, [ADIS16497_2] = { .channels = adis16485_channels, @@ -913,6 +946,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, [ADIS16497_3] = { .channels = adis16485_channels, @@ -926,6 +960,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { .max_dec_rate = 4250, .filter_freqs = adis16495_def_filter_freqs, .has_pps_clk_mode = true, + .timeouts = &adis16495_1_timeouts, }, }; @@ -1195,9 +1230,26 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) return 0; } +static struct adis_data *adis16480_adis_data_alloc(struct adis16480 *st, + struct device *dev) +{ + struct adis_data *data; + + data = devm_kmalloc(dev, sizeof(struct adis_data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + + memcpy(data, &adis16480_data, sizeof(*data)); + + data->timeouts = st->chip_info->timeouts; + + return data; +} + static int adis16480_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); + const struct adis_data *adis16480_data; struct iio_dev *indio_dev; struct adis16480 *st; int ret; @@ -1218,7 +1270,11 @@ static int adis16480_probe(struct spi_device *spi) indio_dev->info = &adis16480_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data); + adis16480_data = adis16480_adis_data_alloc(st, &spi->dev); + if (IS_ERR(adis16480_data)) + return PTR_ERR(adis16480_data); + + ret = adis_init(&st->adis, indio_dev, spi, adis16480_data); if (ret) return ret; |