Commit 380b107b authored by Nuno Sá's avatar Nuno Sá Committed by Jonathan Cameron
Browse files

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: default avatarNuno Sá <nuno.sa@analog.com>
Signed-off-by: default avatarAlexandru Ardelean <alexandru.ardelean@analog.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 687d39d4
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -233,6 +233,12 @@ static const char * const adis16201_status_error_msgs[] = {
	[ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
};

static const struct adis_timeout adis16201_timeouts = {
	.reset_ms = ADIS16201_STARTUP_DELAY_MS,
	.sw_reset_ms = ADIS16201_STARTUP_DELAY_MS,
	.self_test_ms = ADIS16201_STARTUP_DELAY_MS,
};

static const struct adis_data adis16201_data = {
	.read_delay = 20,
	.msc_ctrl_reg = ADIS16201_MSC_CTRL_REG,
@@ -242,6 +248,7 @@ static const struct adis_data adis16201_data = {
	.self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN,
	.self_test_no_autoclear = true,
	.startup_delay = ADIS16201_STARTUP_DELAY_MS,
	.timeouts = &adis16201_timeouts,

	.status_error_msgs = adis16201_status_error_msgs,
	.status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) |
+7 −0
Original line number Diff line number Diff line
@@ -243,6 +243,12 @@ static const char * const adis16209_status_error_msgs[] = {
	[ADIS16209_STAT_POWER_LOW_BIT] = "Power supply below 2.975V",
};

static const struct adis_timeout adis16209_timeouts = {
	.reset_ms = ADIS16209_STARTUP_DELAY_MS,
	.self_test_ms = ADIS16209_STARTUP_DELAY_MS,
	.sw_reset_ms = ADIS16209_STARTUP_DELAY_MS,
};

static const struct adis_data adis16209_data = {
	.read_delay = 30,
	.msc_ctrl_reg = ADIS16209_MSC_CTRL_REG,
@@ -252,6 +258,7 @@ static const struct adis_data adis16209_data = {
	.self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN,
	.self_test_no_autoclear = true,
	.startup_delay = ADIS16209_STARTUP_DELAY_MS,
	.timeouts = &adis16209_timeouts,

	.status_error_msgs = adis16209_status_error_msgs,
	.status_error_mask = BIT(ADIS16209_STAT_SELFTEST_FAIL_BIT) |
+39 −1
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@
struct adis16136_chip_info {
	unsigned int precision;
	unsigned int fullscale;
	const struct adis_timeout *timeouts;
};

struct adis16136 {
@@ -490,30 +491,63 @@ 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,
		.timeouts = &adis16133_timeouts,
	},
	[ID_ADIS16135] = {
		.precision = IIO_DEGREE_TO_RAD(300),
		.fullscale = 24000,
		.timeouts = &adis16133_timeouts,
	},
	[ID_ADIS16136] = {
		.precision = IIO_DEGREE_TO_RAD(450),
		.fullscale = 24623,
		.timeouts = &adis16136_timeouts,
	},
	[ID_ADIS16137] = {
		.precision = IIO_DEGREE_TO_RAD(1000),
		.fullscale = 24609,
		.timeouts = &adis16136_timeouts,
	},
};

static struct adis_data *adis16136_adis_data_alloc(struct adis16136 *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, &adis16136_data, sizeof(*data));

	data->timeouts = st->chip_info->timeouts;

	return 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));
@@ -532,7 +566,11 @@ static int adis16136_probe(struct spi_device *spi)
	indio_dev->info = &adis16136_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
	adis16136_data = adis16136_adis_data_alloc(adis16136, &spi->dev);
	if (IS_ERR(adis16136_data))
		return PTR_ERR(adis16136_data);

	ret = adis_init(&adis16136->adis, indio_dev, spi, adis16136_data);
	if (ret)
		return ret;

+7 −0
Original line number Diff line number Diff line
@@ -332,6 +332,12 @@ static const char * const adis1620_status_error_msgs[] = {
	[ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75",
};

static const struct adis_timeout adis16260_timeouts = {
	.reset_ms = ADIS16260_STARTUP_DELAY,
	.sw_reset_ms = ADIS16260_STARTUP_DELAY,
	.self_test_ms = ADIS16260_STARTUP_DELAY,
};

static const struct adis_data adis16260_data = {
	.write_delay = 30,
	.read_delay = 30,
@@ -341,6 +347,7 @@ static const struct adis_data adis16260_data = {

	.self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST,
	.startup_delay = ADIS16260_STARTUP_DELAY,
	.timeouts = &adis16260_timeouts,

	.status_error_msgs = adis1620_status_error_msgs,
	.status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) |
+14 −4
Original line number Diff line number Diff line
@@ -317,19 +317,25 @@ EXPORT_SYMBOL_GPL(__adis_check_status);
int __adis_reset(struct adis *adis)
{
	int ret;
	const struct adis_timeout *timeouts = adis->data->timeouts;

	ret = __adis_write_reg_8(adis, adis->data->glob_cmd_reg,
			ADIS_GLOB_CMD_SW_RESET);
	if (ret)
	if (ret) {
		dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret);

		return ret;
	}

	msleep(timeouts->sw_reset_ms);

	return 0;
}
EXPORT_SYMBOL_GPL(__adis_reset);

static int adis_self_test(struct adis *adis)
{
	int ret;
	const struct adis_timeout *timeouts = adis->data->timeouts;

	ret = __adis_write_reg_16(adis, adis->data->msc_ctrl_reg,
			adis->data->self_test_mask);
@@ -339,7 +345,7 @@ static int adis_self_test(struct adis *adis)
		return ret;
	}

	msleep(adis->data->startup_delay);
	msleep(timeouts->self_test_ms);

	ret = __adis_check_status(adis);

@@ -368,7 +374,6 @@ int adis_initial_startup(struct adis *adis)
	if (ret) {
		dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n");
		__adis_reset(adis);
		msleep(adis->data->startup_delay);
		ret = adis_self_test(adis);
		if (ret) {
			dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n");
@@ -444,6 +449,11 @@ EXPORT_SYMBOL_GPL(adis_single_conversion);
int adis_init(struct adis *adis, struct iio_dev *indio_dev,
	struct spi_device *spi, const struct adis_data *data)
{
	if (!data || !data->timeouts) {
		dev_err(&spi->dev, "No config data or timeouts not defined!\n");
		return -EINVAL;
	}

	mutex_init(&adis->state_lock);
	adis->spi = spi;
	adis->data = data;
Loading