diff options
Diffstat (limited to 'drivers/iio/gyro/adis16136.c')
| -rw-r--r-- | drivers/iio/gyro/adis16136.c | 168 |
1 files changed, 84 insertions, 84 deletions
diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c index 605eee23780c..369c7428e1ef 100644 --- a/drivers/iio/gyro/adis16136.c +++ b/drivers/iio/gyro/adis16136.c @@ -1,25 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ADIS16133/ADIS16135/ADIS16136 gyroscope driver * * Copyright 2012 Analog Devices Inc. * Author: Lars-Peter Clausen <lars@metafoo.de> - * - * Licensed under the GPL-2. */ -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/mutex.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> -#include <linux/slab.h> #include <linux/sysfs.h> #include <linux/module.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> -#include <linux/iio/buffer.h> #include <linux/iio/imu/adis.h> #include <linux/debugfs.h> @@ -60,6 +54,7 @@ struct adis16136_chip_info { unsigned int precision; unsigned int fullscale; + const struct adis_data adis_data; }; struct adis16136 { @@ -81,19 +76,19 @@ static ssize_t adis16136_show_serial(struct file *file, ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SERIAL_NUM, &serial); - if (ret < 0) + if (ret) return ret; ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT1, &lot1); - if (ret < 0) + if (ret) return ret; ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT2, &lot2); - if (ret < 0) + if (ret) return ret; ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT3, &lot3); - if (ret < 0) + if (ret) return ret; len = snprintf(buf, sizeof(buf), "%.4x%.4x%.4x-%.4x\n", lot1, lot2, @@ -117,7 +112,7 @@ static int adis16136_show_product_id(void *arg, u64 *val) ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID, &prod_id); - if (ret < 0) + if (ret) return ret; *val = prod_id; @@ -135,7 +130,7 @@ static int adis16136_show_flash_count(void *arg, u64 *val) ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_FLASH_CNT, &flash_count); - if (ret < 0) + if (ret) return ret; *val = flash_count; @@ -148,16 +143,14 @@ DEFINE_DEBUGFS_ATTRIBUTE(adis16136_flash_count_fops, static int adis16136_debugfs_init(struct iio_dev *indio_dev) { struct adis16136 *adis16136 = iio_priv(indio_dev); + struct dentry *d = iio_get_debugfs_dentry(indio_dev); debugfs_create_file_unsafe("serial_number", 0400, - indio_dev->debugfs_dentry, adis16136, - &adis16136_serial_fops); + d, adis16136, &adis16136_serial_fops); debugfs_create_file_unsafe("product_id", 0400, - indio_dev->debugfs_dentry, - adis16136, &adis16136_product_id_fops); + d, adis16136, &adis16136_product_id_fops); debugfs_create_file_unsafe("flash_count", 0400, - indio_dev->debugfs_dentry, - adis16136, &adis16136_flash_count_fops); + d, adis16136, &adis16136_flash_count_fops); return 0; } @@ -186,13 +179,13 @@ static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq) return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t); } -static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq) +static int __adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq) { uint16_t t; int ret; - ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t); - if (ret < 0) + ret = __adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t); + if (ret) return ret; *freq = 32768 / (t + 1); @@ -228,11 +221,12 @@ static ssize_t adis16136_read_frequency(struct device *dev, unsigned int freq; int ret; - ret = adis16136_get_freq(adis16136, &freq); - if (ret < 0) + adis_dev_auto_lock(&adis16136->adis); + ret = __adis16136_get_freq(adis16136, &freq); + if (ret) return ret; - return sprintf(buf, "%d\n", freq); + return sysfs_emit(buf, "%d\n", freq); } static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, @@ -256,8 +250,9 @@ static int adis16136_set_filter(struct iio_dev *indio_dev, int val) unsigned int freq; int i, ret; - ret = adis16136_get_freq(adis16136, &freq); - if (ret < 0) + adis_dev_auto_lock(&adis16136->adis); + ret = __adis16136_get_freq(adis16136, &freq); + if (ret) return ret; for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) { @@ -265,7 +260,7 @@ static int adis16136_set_filter(struct iio_dev *indio_dev, int val) break; } - return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i); + return __adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i); } static int adis16136_get_filter(struct iio_dev *indio_dev, int *val) @@ -275,22 +270,20 @@ static int adis16136_get_filter(struct iio_dev *indio_dev, int *val) uint16_t val16; int ret; - mutex_lock(&indio_dev->mlock); + adis_dev_auto_lock(&adis16136->adis); - ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16); - if (ret < 0) - goto err_unlock; + ret = __adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, + &val16); + if (ret) + return ret; - ret = adis16136_get_freq(adis16136, &freq); - if (ret < 0) - goto err_unlock; + ret = __adis16136_get_freq(adis16136, &freq); + if (ret) + return ret; *val = freq / adis16136_3db_divisors[val16 & 0x07]; -err_unlock: - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : IIO_VAL_INT; + return IIO_VAL_INT; } static int adis16136_read_raw(struct iio_dev *indio_dev, @@ -319,7 +312,7 @@ static int adis16136_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: ret = adis_read_reg_32(&adis16136->adis, ADIS16136_REG_GYRO_OFF2, &val32); - if (ret < 0) + if (ret) return ret; *val = sign_extend32(val32, 31); @@ -428,7 +421,7 @@ static int adis16136_initial_setup(struct iio_dev *indio_dev) uint16_t prod_id; int ret; - ret = adis_initial_startup(&adis16136->adis); + ret = __adis_initial_startup(&adis16136->adis); if (ret) return ret; @@ -455,23 +448,22 @@ static const char * const adis16136_status_error_msgs[] = { [ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL] = "Flash checksum error", }; -static const struct adis_data adis16136_data = { - .diag_stat_reg = ADIS16136_REG_DIAG_STAT, - .glob_cmd_reg = ADIS16136_REG_GLOB_CMD, - .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL, - - .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST, - .startup_delay = 80, - - .read_delay = 10, - .write_delay = 10, - - .status_error_msgs = adis16136_status_error_msgs, - .status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) | - BIT(ADIS16136_DIAG_STAT_SPI_FAIL) | - BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) | - BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL), -}; +#define ADIS16136_DATA(_timeouts) \ +{ \ + .diag_stat_reg = ADIS16136_REG_DIAG_STAT, \ + .glob_cmd_reg = ADIS16136_REG_GLOB_CMD, \ + .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL, \ + .self_test_reg = ADIS16136_REG_MSC_CTRL, \ + .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST, \ + .read_delay = 10, \ + .write_delay = 10, \ + .status_error_msgs = adis16136_status_error_msgs, \ + .status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) | \ + BIT(ADIS16136_DIAG_STAT_SPI_FAIL) | \ + BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) | \ + BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL), \ + .timeouts = (_timeouts), \ +} enum adis16136_id { ID_ADIS16133, @@ -480,30 +472,52 @@ enum adis16136_id { ID_ADIS16137, }; +static const struct adis_timeout adis16133_timeouts = { + .reset_ms = 75, + .sw_reset_ms = 75, + .self_test_ms = 50, +}; + +static const struct adis_timeout adis16136_timeouts = { + .reset_ms = 128, + .sw_reset_ms = 75, + .self_test_ms = 245, +}; + static const struct adis16136_chip_info adis16136_chip_info[] = { [ID_ADIS16133] = { .precision = IIO_DEGREE_TO_RAD(1200), .fullscale = 24000, + .adis_data = ADIS16136_DATA(&adis16133_timeouts), }, [ID_ADIS16135] = { .precision = IIO_DEGREE_TO_RAD(300), .fullscale = 24000, + .adis_data = ADIS16136_DATA(&adis16133_timeouts), }, [ID_ADIS16136] = { .precision = IIO_DEGREE_TO_RAD(450), .fullscale = 24623, + .adis_data = ADIS16136_DATA(&adis16136_timeouts), }, [ID_ADIS16137] = { .precision = IIO_DEGREE_TO_RAD(1000), .fullscale = 24609, + .adis_data = ADIS16136_DATA(&adis16136_timeouts), }, }; +static void adis16136_stop(void *data) +{ + adis16136_stop_device(data); +} + static int adis16136_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); struct adis16136 *adis16136; struct iio_dev *indio_dev; + const struct adis_data *adis16136_data; int ret; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136)); @@ -515,49 +529,35 @@ static int adis16136_probe(struct spi_device *spi) adis16136 = iio_priv(indio_dev); adis16136->chip_info = &adis16136_chip_info[id->driver_data]; - indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->channels = adis16136_channels; indio_dev->num_channels = ARRAY_SIZE(adis16136_channels); indio_dev->info = &adis16136_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data); + adis16136_data = &adis16136->chip_info->adis_data; + + ret = adis_init(&adis16136->adis, indio_dev, spi, adis16136_data); if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); if (ret) return ret; ret = adis16136_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16136_stop, indio_dev); if (ret) - goto error_stop_device; - - adis16136_debugfs_init(indio_dev); - - return 0; - -error_stop_device: - adis16136_stop_device(indio_dev); -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); - return ret; -} - -static int adis16136_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16136 *adis16136 = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16136_stop_device(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); + adis16136_debugfs_init(indio_dev); return 0; } @@ -577,10 +577,10 @@ static struct spi_driver adis16136_driver = { }, .id_table = adis16136_ids, .probe = adis16136_probe, - .remove = adis16136_remove, }; module_spi_driver(adis16136_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS("IIO_ADISLIB"); |
