[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-iio
Subject:    Re: [PATCH 2/2] staging:iio: Consolidate adt7310 and adt7410 driver
From:       Jonathan Cameron <jic23 () kernel ! org>
Date:       2012-10-31 10:51:54
Message-ID: 509102CA.3060204 () kernel ! org
[Download RAW message or body]

On 10/22/2012 10:42 AM, Lars-Peter Clausen wrote:
> The adt7310 is the SPI version of the adt7410, so there is no need to have a
> separate driver for it. The register map layout is a bit different, i.e. the
> addresses of the register differ, but the individual register layouts are
> identical. We solve this by adding a small look-up table, which translates
> adt7410 register addresses to ad7310 register addresses.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Nice work.
Added to togreg branch of iio.git

> ---
>  drivers/staging/iio/adc/Kconfig   |   13 +-
>  drivers/staging/iio/adc/Makefile  |    1 -
>  drivers/staging/iio/adc/adt7310.c |  881 -------------------------------------
>  drivers/staging/iio/adc/adt7410.c |  458 +++++++++++++++----
>  4 files changed, 364 insertions(+), 989 deletions(-)
>  delete mode 100644 drivers/staging/iio/adc/adt7310.c
> 
> diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
> index a525143..71a515d 100644
> --- a/drivers/staging/iio/adc/Kconfig
> +++ b/drivers/staging/iio/adc/Kconfig
> @@ -126,18 +126,11 @@ config AD7192
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called ad7192.
>  
> -config ADT7310
> -	tristate "Analog Devices ADT7310 temperature sensor driver"
> -	depends on SPI
> -	help
> -	  Say yes here to build support for Analog Devices ADT7310
> -	  temperature sensors.
> -
>  config ADT7410
> -	tristate "Analog Devices ADT7410 temperature sensor driver"
> -	depends on I2C
> +	tristate "Analog Devices ADT7310/ADT7410 temperature sensor driver"
> +	depends on I2C || SPI_MASTER
>  	help
> -	  Say yes here to build support for Analog Devices ADT7410
> +	  Say yes here to build support for Analog Devices ADT7310/ADT7410
>  	  temperature sensors.
>  
>  config AD7280
> diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
> index 62ee02e..ff561c5 100644
> --- a/drivers/staging/iio/adc/Makefile
> +++ b/drivers/staging/iio/adc/Makefile
> @@ -30,7 +30,6 @@ obj-$(CONFIG_AD7780) += ad7780.o
>  obj-$(CONFIG_AD7793) += ad7793.o
>  obj-$(CONFIG_AD7816) += ad7816.o
>  obj-$(CONFIG_AD7192) += ad7192.o
> -obj-$(CONFIG_ADT7310) += adt7310.o
>  obj-$(CONFIG_ADT7410) += adt7410.o
>  obj-$(CONFIG_AD7280) += ad7280a.o
>  obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o
> diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c
> deleted file mode 100644
> index 72460b6..0000000
> --- a/drivers/staging/iio/adc/adt7310.c
> +++ /dev/null
> @@ -1,881 +0,0 @@
> -/*
> - * ADT7310 digital temperature sensor driver supporting ADT7310
> - *
> - * Copyright 2010 Analog Devices Inc.
> - *
> - * Licensed under the GPL-2 or later.
> - */
> -
> -#include <linux/interrupt.h>
> -#include <linux/device.h>
> -#include <linux/kernel.h>
> -#include <linux/slab.h>
> -#include <linux/sysfs.h>
> -#include <linux/list.h>
> -#include <linux/spi/spi.h>
> -#include <linux/module.h>
> -
> -#include <linux/iio/iio.h>
> -#include <linux/iio/sysfs.h>
> -#include <linux/iio/events.h>
> -/*
> - * ADT7310 registers definition
> - */
> -
> -#define ADT7310_STATUS			0
> -#define ADT7310_CONFIG			1
> -#define ADT7310_TEMPERATURE		2
> -#define ADT7310_ID			3
> -#define ADT7310_T_CRIT			4
> -#define ADT7310_T_HYST			5
> -#define ADT7310_T_ALARM_HIGH		6
> -#define ADT7310_T_ALARM_LOW		7
> -
> -/*
> - * ADT7310 status
> - */
> -#define ADT7310_STAT_T_LOW		0x10
> -#define ADT7310_STAT_T_HIGH		0x20
> -#define ADT7310_STAT_T_CRIT		0x40
> -#define ADT7310_STAT_NOT_RDY		0x80
> -
> -/*
> - * ADT7310 config
> - */
> -#define ADT7310_FAULT_QUEUE_MASK	0x3
> -#define ADT7310_CT_POLARITY		0x4
> -#define ADT7310_INT_POLARITY		0x8
> -#define ADT7310_EVENT_MODE		0x10
> -#define ADT7310_MODE_MASK		0x60
> -#define ADT7310_ONESHOT			0x20
> -#define ADT7310_SPS			0x40
> -#define ADT7310_PD			0x60
> -#define ADT7310_RESOLUTION		0x80
> -
> -/*
> - * ADT7310 masks
> - */
> -#define ADT7310_T16_VALUE_SIGN			0x8000
> -#define ADT7310_T16_VALUE_FLOAT_OFFSET		7
> -#define ADT7310_T16_VALUE_FLOAT_MASK		0x7F
> -#define ADT7310_T13_VALUE_SIGN			0x1000
> -#define ADT7310_T13_VALUE_OFFSET		3
> -#define ADT7310_T13_VALUE_FLOAT_OFFSET		4
> -#define ADT7310_T13_VALUE_FLOAT_MASK		0xF
> -#define ADT7310_T_HYST_MASK			0xF
> -#define ADT7310_DEVICE_ID_MASK			0x7
> -#define ADT7310_MANUFACTORY_ID_MASK		0xF8
> -#define ADT7310_MANUFACTORY_ID_OFFSET		3
> -
> -
> -#define ADT7310_CMD_REG_MASK			0x28
> -#define ADT7310_CMD_REG_OFFSET			3
> -#define ADT7310_CMD_READ			0x40
> -#define ADT7310_CMD_CON_READ			0x4
> -
> -#define ADT7310_IRQS				2
> -
> -/*
> - * struct adt7310_chip_info - chip specifc information
> - */
> -
> -struct adt7310_chip_info {
> -	struct spi_device *spi_dev;
> -	u8  config;
> -};
> -
> -/*
> - * adt7310 register access by SPI
> - */
> -
> -static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data)
> -{
> -	struct spi_device *spi_dev = chip->spi_dev;
> -	u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
> -	int ret = 0;
> -
> -	command |= ADT7310_CMD_READ;
> -	ret = spi_write(spi_dev, &command, sizeof(command));
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI write command error\n");
> -		return ret;
> -	}
> -
> -	ret = spi_read(spi_dev, (u8 *)data, sizeof(*data));
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI read word error\n");
> -		return ret;
> -	}
> -
> -	*data = be16_to_cpu(*data);
> -
> -	return 0;
> -}
> -
> -static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data)
> -{
> -	struct spi_device *spi_dev = chip->spi_dev;
> -	u8 buf[3];
> -	int ret = 0;
> -
> -	buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
> -	buf[1] = (u8)(data >> 8);
> -	buf[2] = (u8)(data & 0xFF);
> -
> -	ret = spi_write(spi_dev, buf, 3);
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI write word error\n");
> -		return ret;
> -	}
> -
> -	return ret;
> -}
> -
> -static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data)
> -{
> -	struct spi_device *spi_dev = chip->spi_dev;
> -	u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
> -	int ret = 0;
> -
> -	command |= ADT7310_CMD_READ;
> -	ret = spi_write(spi_dev, &command, sizeof(command));
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI write command error\n");
> -		return ret;
> -	}
> -
> -	ret = spi_read(spi_dev, data, sizeof(*data));
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI read byte error\n");
> -		return ret;
> -	}
> -
> -	return 0;
> -}
> -
> -static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data)
> -{
> -	struct spi_device *spi_dev = chip->spi_dev;
> -	u8 buf[2];
> -	int ret = 0;
> -
> -	buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK;
> -	buf[1] = data;
> -
> -	ret = spi_write(spi_dev, buf, 2);
> -	if (ret < 0) {
> -		dev_err(&spi_dev->dev, "SPI write byte error\n");
> -		return ret;
> -	}
> -
> -	return ret;
> -}
> -
> -static ssize_t adt7310_show_mode(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u8 config;
> -
> -	config = chip->config & ADT7310_MODE_MASK;
> -
> -	switch (config) {
> -	case ADT7310_PD:
> -		return sprintf(buf, "power-down\n");
> -	case ADT7310_ONESHOT:
> -		return sprintf(buf, "one-shot\n");
> -	case ADT7310_SPS:
> -		return sprintf(buf, "sps\n");
> -	default:
> -		return sprintf(buf, "full\n");
> -	}
> -}
> -
> -static ssize_t adt7310_store_mode(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u16 config;
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	config = chip->config & (~ADT7310_MODE_MASK);
> -	if (strcmp(buf, "power-down"))
> -		config |= ADT7310_PD;
> -	else if (strcmp(buf, "one-shot"))
> -		config |= ADT7310_ONESHOT;
> -	else if (strcmp(buf, "sps"))
> -		config |= ADT7310_SPS;
> -
> -	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
> -	if (ret)
> -		return -EIO;
> -
> -	chip->config = config;
> -
> -	return len;
> -}
> -
> -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
> -		adt7310_show_mode,
> -		adt7310_store_mode,
> -		0);
> -
> -static ssize_t adt7310_show_available_modes(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	return sprintf(buf, "full\none-shot\nsps\npower-down\n");
> -}
> -
> -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0);
> -
> -static ssize_t adt7310_show_resolution(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	int ret;
> -	int bits;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	if (chip->config & ADT7310_RESOLUTION)
> -		bits = 16;
> -	else
> -		bits = 13;
> -
> -	return sprintf(buf, "%d bits\n", bits);
> -}
> -
> -static ssize_t adt7310_store_resolution(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	unsigned long data;
> -	u16 config;
> -	int ret;
> -
> -	ret = strict_strtoul(buf, 10, &data);
> -	if (ret)
> -		return -EINVAL;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	config = chip->config & (~ADT7310_RESOLUTION);
> -	if (data)
> -		config |= ADT7310_RESOLUTION;
> -
> -	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
> -	if (ret)
> -		return -EIO;
> -
> -	chip->config = config;
> -
> -	return len;
> -}
> -
> -static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR,
> -		adt7310_show_resolution,
> -		adt7310_store_resolution,
> -		0);
> -
> -static ssize_t adt7310_show_id(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u8 id;
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id);
> -	if (ret)
> -		return -EIO;
> -
> -	return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n",
> -			id & ADT7310_DEVICE_ID_MASK,
> -			(id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET);
> -}
> -
> -static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR,
> -		adt7310_show_id,
> -		NULL,
> -		0);
> -
> -static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip,
> -		u16 data, char *buf)
> -{
> -	char sign = ' ';
> -
> -	if (chip->config & ADT7310_RESOLUTION) {
> -		if (data & ADT7310_T16_VALUE_SIGN) {
> -			/* convert supplement to positive value */
> -			data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
> -			sign = '-';
> -		}
> -		return sprintf(buf, "%c%d.%.7d\n", sign,
> -				(data >> ADT7310_T16_VALUE_FLOAT_OFFSET),
> -				(data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125);
> -	} else {
> -		if (data & ADT7310_T13_VALUE_SIGN) {
> -			/* convert supplement to positive value */
> -			data >>= ADT7310_T13_VALUE_OFFSET;
> -			data = (ADT7310_T13_VALUE_SIGN << 1) - data;
> -			sign = '-';
> -		}
> -		return sprintf(buf, "%c%d.%.4d\n", sign,
> -				(data >> ADT7310_T13_VALUE_FLOAT_OFFSET),
> -				(data & ADT7310_T13_VALUE_FLOAT_MASK) * 625);
> -	}
> -}
> -
> -static ssize_t adt7310_show_value(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u8 status;
> -	u16 data;
> -	int ret, i = 0;
> -
> -	do {
> -		ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
> -		if (ret)
> -			return -EIO;
> -		i++;
> -		if (i == 10000)
> -			return -EIO;
> -	} while (status & ADT7310_STAT_NOT_RDY);
> -
> -	ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data);
> -	if (ret)
> -		return -EIO;
> -
> -	return adt7310_convert_temperature(chip, data, buf);
> -}
> -
> -static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
> -
> -static struct attribute *adt7310_attributes[] = {
> -	&iio_dev_attr_available_modes.dev_attr.attr,
> -	&iio_dev_attr_mode.dev_attr.attr,
> -	&iio_dev_attr_resolution.dev_attr.attr,
> -	&iio_dev_attr_id.dev_attr.attr,
> -	&iio_dev_attr_value.dev_attr.attr,
> -	NULL,
> -};
> -
> -static const struct attribute_group adt7310_attribute_group = {
> -	.attrs = adt7310_attributes,
> -};
> -
> -static irqreturn_t adt7310_event_handler(int irq, void *private)
> -{
> -	struct iio_dev *indio_dev = private;
> -	struct adt7310_chip_info *chip = iio_priv(indio_dev);
> -	s64 timestamp = iio_get_time_ns();
> -	u8 status;
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
> -	if (ret)
> -		goto done;
> -
> -	if (status & ADT7310_STAT_T_HIGH)
> -		iio_push_event(indio_dev,
> -			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
> -						    IIO_EV_TYPE_THRESH,
> -						    IIO_EV_DIR_RISING),
> -			       timestamp);
> -	if (status & ADT7310_STAT_T_LOW)
> -		iio_push_event(indio_dev,
> -			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
> -						    IIO_EV_TYPE_THRESH,
> -						    IIO_EV_DIR_FALLING),
> -			       timestamp);
> -	if (status & ADT7310_STAT_T_CRIT)
> -		iio_push_event(indio_dev,
> -			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
> -						    IIO_EV_TYPE_THRESH,
> -						    IIO_EV_DIR_RISING),
> -			timestamp);
> -
> -done:
> -	return IRQ_HANDLED;
> -}
> -
> -static ssize_t adt7310_show_event_mode(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	if (chip->config & ADT7310_EVENT_MODE)
> -		return sprintf(buf, "interrupt\n");
> -	else
> -		return sprintf(buf, "comparator\n");
> -}
> -
> -static ssize_t adt7310_set_event_mode(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u16 config;
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	config = chip->config &= ~ADT7310_EVENT_MODE;
> -	if (strcmp(buf, "comparator") != 0)
> -		config |= ADT7310_EVENT_MODE;
> -
> -	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
> -	if (ret)
> -		return -EIO;
> -
> -	chip->config = config;
> -
> -	return len;
> -}
> -
> -static ssize_t adt7310_show_available_event_modes(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	return sprintf(buf, "comparator\ninterrupt\n");
> -}
> -
> -static ssize_t adt7310_show_fault_queue(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	int ret;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK);
> -}
> -
> -static ssize_t adt7310_set_fault_queue(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	unsigned long data;
> -	int ret;
> -	u8 config;
> -
> -	ret = strict_strtoul(buf, 10, &data);
> -	if (ret || data > 3)
> -		return -EINVAL;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -	if (ret)
> -		return -EIO;
> -
> -	config = chip->config & ~ADT7310_FAULT_QUEUE_MASK;
> -	config |= data;
> -	ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config);
> -	if (ret)
> -		return -EIO;
> -
> -	chip->config = config;
> -
> -	return len;
> -}
> -
> -static inline ssize_t adt7310_show_t_bound(struct device *dev,
> -		struct device_attribute *attr,
> -		u8 bound_reg,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	u16 data;
> -	int ret;
> -
> -	ret = adt7310_spi_read_word(chip, bound_reg, &data);
> -	if (ret)
> -		return -EIO;
> -
> -	return adt7310_convert_temperature(chip, data, buf);
> -}
> -
> -static inline ssize_t adt7310_set_t_bound(struct device *dev,
> -		struct device_attribute *attr,
> -		u8 bound_reg,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	long tmp1, tmp2;
> -	u16 data;
> -	char *pos;
> -	int ret;
> -
> -	pos = strchr(buf, '.');
> -
> -	ret = strict_strtol(buf, 10, &tmp1);
> -
> -	if (ret || tmp1 > 127 || tmp1 < -128)
> -		return -EINVAL;
> -
> -	if (pos) {
> -		len = strlen(pos);
> -
> -		if (chip->config & ADT7310_RESOLUTION) {
> -			if (len > ADT7310_T16_VALUE_FLOAT_OFFSET)
> -				len = ADT7310_T16_VALUE_FLOAT_OFFSET;
> -			pos[len] = 0;
> -			ret = strict_strtol(pos, 10, &tmp2);
> -
> -			if (!ret)
> -				tmp2 = (tmp2 / 78125) * 78125;
> -		} else {
> -			if (len > ADT7310_T13_VALUE_FLOAT_OFFSET)
> -				len = ADT7310_T13_VALUE_FLOAT_OFFSET;
> -			pos[len] = 0;
> -			ret = strict_strtol(pos, 10, &tmp2);
> -
> -			if (!ret)
> -				tmp2 = (tmp2 / 625) * 625;
> -		}
> -	}
> -
> -	if (tmp1 < 0)
> -		data = (u16)(-tmp1);
> -	else
> -		data = (u16)tmp1;
> -
> -	if (chip->config & ADT7310_RESOLUTION) {
> -		data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) |
> -			(tmp2 & ADT7310_T16_VALUE_FLOAT_MASK);
> -
> -		if (tmp1 < 0)
> -			/* convert positive value to supplyment */
> -			data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data);
> -	} else {
> -		data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) |
> -			(tmp2 & ADT7310_T13_VALUE_FLOAT_MASK);
> -
> -		if (tmp1 < 0)
> -			/* convert positive value to supplyment */
> -			data = (ADT7310_T13_VALUE_SIGN << 1) - data;
> -		data <<= ADT7310_T13_VALUE_OFFSET;
> -	}
> -
> -	ret = adt7310_spi_write_word(chip, bound_reg, data);
> -	if (ret)
> -		return -EIO;
> -
> -	return len;
> -}
> -
> -static ssize_t adt7310_show_t_alarm_high(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	return adt7310_show_t_bound(dev, attr,
> -			ADT7310_T_ALARM_HIGH, buf);
> -}
> -
> -static inline ssize_t adt7310_set_t_alarm_high(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	return adt7310_set_t_bound(dev, attr,
> -			ADT7310_T_ALARM_HIGH, buf, len);
> -}
> -
> -static ssize_t adt7310_show_t_alarm_low(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	return adt7310_show_t_bound(dev, attr,
> -			ADT7310_T_ALARM_LOW, buf);
> -}
> -
> -static inline ssize_t adt7310_set_t_alarm_low(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	return adt7310_set_t_bound(dev, attr,
> -			ADT7310_T_ALARM_LOW, buf, len);
> -}
> -
> -static ssize_t adt7310_show_t_crit(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	return adt7310_show_t_bound(dev, attr,
> -			ADT7310_T_CRIT, buf);
> -}
> -
> -static inline ssize_t adt7310_set_t_crit(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	return adt7310_set_t_bound(dev, attr,
> -			ADT7310_T_CRIT, buf, len);
> -}
> -
> -static ssize_t adt7310_show_t_hyst(struct device *dev,
> -		struct device_attribute *attr,
> -		char *buf)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	int ret;
> -	u8 t_hyst;
> -
> -	ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst);
> -	if (ret)
> -		return -EIO;
> -
> -	return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK);
> -}
> -
> -static inline ssize_t adt7310_set_t_hyst(struct device *dev,
> -		struct device_attribute *attr,
> -		const char *buf,
> -		size_t len)
> -{
> -	struct iio_dev *dev_info = dev_to_iio_dev(dev);
> -	struct adt7310_chip_info *chip = iio_priv(dev_info);
> -	int ret;
> -	unsigned long data;
> -	u8 t_hyst;
> -
> -	ret = strict_strtol(buf, 10, &data);
> -
> -	if (ret || data > ADT7310_T_HYST_MASK)
> -		return -EINVAL;
> -
> -	t_hyst = (u8)data;
> -
> -	ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst);
> -	if (ret)
> -		return -EIO;
> -
> -	return len;
> -}
> -
> -static IIO_DEVICE_ATTR(event_mode,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_event_mode, adt7310_set_event_mode, 0);
> -static IIO_DEVICE_ATTR(available_event_modes,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_available_event_modes, NULL, 0);
> -static IIO_DEVICE_ATTR(fault_queue,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
> -static IIO_DEVICE_ATTR(t_alarm_high,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
> -static IIO_DEVICE_ATTR(t_alarm_low,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
> -static IIO_DEVICE_ATTR(t_crit,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_t_crit, adt7310_set_t_crit, 0);
> -static IIO_DEVICE_ATTR(t_hyst,
> -		       S_IRUGO | S_IWUSR,
> -		       adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
> -
> -static struct attribute *adt7310_event_int_attributes[] = {
> -	&iio_dev_attr_event_mode.dev_attr.attr,
> -	&iio_dev_attr_available_event_modes.dev_attr.attr,
> -	&iio_dev_attr_fault_queue.dev_attr.attr,
> -	&iio_dev_attr_t_alarm_high.dev_attr.attr,
> -	&iio_dev_attr_t_alarm_low.dev_attr.attr,
> -	&iio_dev_attr_t_crit.dev_attr.attr,
> -	&iio_dev_attr_t_hyst.dev_attr.attr,
> -	NULL,
> -};
> -
> -static struct attribute_group adt7310_event_attribute_group = {
> -	.attrs = adt7310_event_int_attributes,
> -	.name = "events",
> -};
> -
> -static const struct iio_info adt7310_info = {
> -	.attrs = &adt7310_attribute_group,
> -	.event_attrs = &adt7310_event_attribute_group,
> -	.driver_module = THIS_MODULE,
> -};
> -
> -/*
> - * device probe and remove
> - */
> -
> -static int __devinit adt7310_probe(struct spi_device *spi_dev)
> -{
> -	struct adt7310_chip_info *chip;
> -	struct iio_dev *indio_dev;
> -	int ret = 0;
> -	unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
> -	unsigned long irq_flags;
> -
> -	indio_dev = iio_device_alloc(sizeof(*chip));
> -	if (indio_dev == NULL) {
> -		ret = -ENOMEM;
> -		goto error_ret;
> -	}
> -	chip = iio_priv(indio_dev);
> -	/* this is only used for device removal purposes */
> -	dev_set_drvdata(&spi_dev->dev, indio_dev);
> -
> -	chip->spi_dev = spi_dev;
> -
> -	indio_dev->dev.parent = &spi_dev->dev;
> -	indio_dev->name = spi_get_device_id(spi_dev)->name;
> -	indio_dev->info = &adt7310_info;
> -	indio_dev->modes = INDIO_DIRECT_MODE;
> -
> -	/* CT critcal temperature event. line 0 */
> -	if (spi_dev->irq) {
> -		if (adt7310_platform_data[2])
> -			irq_flags = adt7310_platform_data[2];
> -		else
> -			irq_flags = IRQF_TRIGGER_LOW;
> -		ret = request_threaded_irq(spi_dev->irq,
> -					   NULL,
> -					   &adt7310_event_handler,
> -					   irq_flags | IRQF_ONESHOT,
> -					   indio_dev->name,
> -					   indio_dev);
> -		if (ret)
> -			goto error_free_dev;
> -	}
> -
> -	/* INT bound temperature alarm event. line 1 */
> -	if (adt7310_platform_data[0]) {
> -		ret = request_threaded_irq(adt7310_platform_data[0],
> -					   NULL,
> -					   &adt7310_event_handler,
> -					   adt7310_platform_data[1] |
> -					   IRQF_ONESHOT,
> -					   indio_dev->name,
> -					   indio_dev);
> -		if (ret)
> -			goto error_unreg_ct_irq;
> -	}
> -
> -	if (spi_dev->irq && adt7310_platform_data[0]) {
> -		ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
> -		if (ret) {
> -			ret = -EIO;
> -			goto error_unreg_int_irq;
> -		}
> -
> -		/* set irq polarity low level */
> -		chip->config &= ~ADT7310_CT_POLARITY;
> -
> -		if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH)
> -			chip->config |= ADT7310_INT_POLARITY;
> -		else
> -			chip->config &= ~ADT7310_INT_POLARITY;
> -
> -		ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config);
> -		if (ret) {
> -			ret = -EIO;
> -			goto error_unreg_int_irq;
> -		}
> -	}
> -
> -	ret = iio_device_register(indio_dev);
> -	if (ret)
> -		goto error_unreg_int_irq;
> -
> -	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
> -			indio_dev->name);
> -
> -	return 0;
> -
> -error_unreg_int_irq:
> -	free_irq(adt7310_platform_data[0], indio_dev);
> -error_unreg_ct_irq:
> -	free_irq(spi_dev->irq, indio_dev);
> -error_free_dev:
> -	iio_device_free(indio_dev);
> -error_ret:
> -	return ret;
> -}
> -
> -static int __devexit adt7310_remove(struct spi_device *spi_dev)
> -{
> -	struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
> -	unsigned long *adt7310_platform_data = spi_dev->dev.platform_data;
> -
> -	iio_device_unregister(indio_dev);
> -	dev_set_drvdata(&spi_dev->dev, NULL);
> -	if (adt7310_platform_data[0])
> -		free_irq(adt7310_platform_data[0], indio_dev);
> -	if (spi_dev->irq)
> -		free_irq(spi_dev->irq, indio_dev);
> -	iio_device_free(indio_dev);
> -
> -	return 0;
> -}
> -
> -static const struct spi_device_id adt7310_id[] = {
> -	{ "adt7310", 0 },
> -	{}
> -};
> -
> -MODULE_DEVICE_TABLE(spi, adt7310_id);
> -
> -static struct spi_driver adt7310_driver = {
> -	.driver = {
> -		.name = "adt7310",
> -		.owner = THIS_MODULE,
> -	},
> -	.probe = adt7310_probe,
> -	.remove = __devexit_p(adt7310_remove),
> -	.id_table = adt7310_id,
> -};
> -module_spi_driver(adt7310_driver);
> -
> -MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
> -MODULE_DESCRIPTION("Analog Devices ADT7310 digital"
> -			" temperature sensor driver");
> -MODULE_LICENSE("GPL v2");
> diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c
> index 3cf5103..6493cd0 100644
> --- a/drivers/staging/iio/adc/adt7410.c
> +++ b/drivers/staging/iio/adc/adt7410.c
> @@ -1,5 +1,5 @@
>  /*
> - * ADT7410 digital temperature sensor driver supporting ADT7410
> + * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410
>   *
>   * Copyright 2010 Analog Devices Inc.
>   *
> @@ -13,6 +13,7 @@
>  #include <linux/sysfs.h>
>  #include <linux/list.h>
>  #include <linux/i2c.h>
> +#include <linux/spi/spi.h>
>  #include <linux/module.h>
>  
>  #include <linux/iio/iio.h>
> @@ -34,6 +35,19 @@
>  #define ADT7410_RESET			0x2F
>  
>  /*
> + * ADT7310 registers definition
> + */
> +
> +#define ADT7310_STATUS			0
> +#define ADT7310_CONFIG			1
> +#define ADT7310_TEMPERATURE		2
> +#define ADT7310_ID			3
> +#define ADT7310_T_CRIT			4
> +#define ADT7310_T_HYST			5
> +#define ADT7310_T_ALARM_HIGH		6
> +#define ADT7310_T_ALARM_LOW		7
> +
> +/*
>   * ADT7410 status
>   */
>  #define ADT7410_STAT_T_LOW		0x10
> @@ -69,75 +83,52 @@
>  #define ADT7410_MANUFACTORY_ID_MASK		0xF0
>  #define ADT7410_MANUFACTORY_ID_OFFSET		4
>  
> +
> +#define ADT7310_CMD_REG_MASK			0x28
> +#define ADT7310_CMD_REG_OFFSET			3
> +#define ADT7310_CMD_READ			0x40
> +#define ADT7310_CMD_CON_READ			0x4
> +
>  #define ADT7410_IRQS				2
>  
>  /*
>   * struct adt7410_chip_info - chip specifc information
>   */
>  
> +struct adt7410_chip_info;
> +
> +struct adt7410_ops {
> +	int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data);
> +	int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data);
> +	int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data);
> +	int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data);
> +};
> +
>  struct adt7410_chip_info {
> -	struct i2c_client *client;
> +	struct device *dev;
>  	u8  config;
> -};
>  
> -/*
> - * adt7410 register access by I2C
> - */
> +	const struct adt7410_ops *ops;
> +};
>  
> -static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
> +static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data)
>  {
> -	struct i2c_client *client = chip->client;
> -	int ret = 0;
> -
> -	ret = i2c_smbus_read_word_data(client, reg);
> -	if (ret < 0) {
> -		dev_err(&client->dev, "I2C read error\n");
> -		return ret;
> -	}
> -
> -	*data = swab16((u16)ret);
> -
> -	return 0;
> +	return chip->ops->read_word(chip, reg, data);
>  }
>  
> -static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
> +static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data)
>  {
> -	struct i2c_client *client = chip->client;
> -	int ret = 0;
> -
> -	ret = i2c_smbus_write_word_data(client, reg, swab16(data));
> -	if (ret < 0)
> -		dev_err(&client->dev, "I2C write error\n");
> -
> -	return ret;
> +	return chip->ops->write_word(chip, reg, data);
>  }
>  
> -static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
> +static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data)
>  {
> -	struct i2c_client *client = chip->client;
> -	int ret = 0;
> -
> -	ret = i2c_smbus_read_byte_data(client, reg);
> -	if (ret < 0) {
> -		dev_err(&client->dev, "I2C read error\n");
> -		return ret;
> -	}
> -
> -	*data = (u8)ret;
> -
> -	return 0;
> +	return chip->ops->read_byte(chip, reg, data);
>  }
>  
> -static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
> +static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data)
>  {
> -	struct i2c_client *client = chip->client;
> -	int ret = 0;
> -
> -	ret = i2c_smbus_write_byte_data(client, reg, data);
> -	if (ret < 0)
> -		dev_err(&client->dev, "I2C write error\n");
> -
> -	return ret;
> +	return chip->ops->write_byte(chip, reg, data);
>  }
>  
>  static ssize_t adt7410_show_mode(struct device *dev,
> @@ -172,7 +163,7 @@ static ssize_t adt7410_store_mode(struct device *dev,
>  	u16 config;
>  	int ret;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -184,7 +175,7 @@ static ssize_t adt7410_store_mode(struct device *dev,
>  	else if (strcmp(buf, "sps"))
>  		config |= ADT7410_SPS;
>  
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
> +	ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -216,7 +207,7 @@ static ssize_t adt7410_show_resolution(struct device *dev,
>  	int ret;
>  	int bits;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -243,7 +234,7 @@ static ssize_t adt7410_store_resolution(struct device *dev,
>  	if (ret)
>  		return -EINVAL;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -251,7 +242,7 @@ static ssize_t adt7410_store_resolution(struct device *dev,
>  	if (data)
>  		config |= ADT7410_RESOLUTION;
>  
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
> +	ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -274,7 +265,7 @@ static ssize_t adt7410_show_id(struct device *dev,
>  	u8 id;
>  	int ret;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id);
> +	ret = adt7410_read_byte(chip, ADT7410_ID, &id);
>  	if (ret)
>  		return -EIO;
>  
> @@ -317,7 +308,7 @@ static ssize_t adt7410_show_value(struct device *dev,
>  	int ret, i = 0;
>  
>  	do {
> -		ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status);
> +		ret = adt7410_read_byte(chip, ADT7410_STATUS, &status);
>  		if (ret)
>  			return -EIO;
>  		i++;
> @@ -325,7 +316,7 @@ static ssize_t adt7410_show_value(struct device *dev,
>  			return -EIO;
>  	} while (status & ADT7410_STAT_NOT_RDY);
>  
> -	ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data);
> +	ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data);
>  	if (ret)
>  		return -EIO;
>  
> @@ -354,7 +345,7 @@ static irqreturn_t adt7410_event_handler(int irq, void *private)
>  	s64 timestamp = iio_get_time_ns();
>  	u8 status;
>  
> -	if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
> +	if (adt7410_read_byte(chip, ADT7410_STATUS, &status))
>  		return IRQ_HANDLED;
>  
>  	if (status & ADT7410_STAT_T_HIGH)
> @@ -387,7 +378,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev,
>  	struct adt7410_chip_info *chip = iio_priv(dev_info);
>  	int ret;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -407,7 +398,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev,
>  	u16 config;
>  	int ret;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -415,7 +406,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev,
>  	if (strcmp(buf, "comparator") != 0)
>  		config |= ADT7410_EVENT_MODE;
>  
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
> +	ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -439,7 +430,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev,
>  	struct adt7410_chip_info *chip = iio_priv(dev_info);
>  	int ret;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -461,13 +452,13 @@ static ssize_t adt7410_set_fault_queue(struct device *dev,
>  	if (ret || data > 3)
>  		return -EINVAL;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret)
>  		return -EIO;
>  
>  	config = chip->config & ~ADT7410_FAULT_QUEUE_MASK;
>  	config |= data;
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config);
> +	ret = adt7410_write_byte(chip, ADT7410_CONFIG, config);
>  	if (ret)
>  		return -EIO;
>  
> @@ -486,7 +477,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev,
>  	u16 data;
>  	int ret;
>  
> -	ret = adt7410_i2c_read_word(chip, bound_reg, &data);
> +	ret = adt7410_read_word(chip, bound_reg, &data);
>  	if (ret)
>  		return -EIO;
>  
> @@ -557,7 +548,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev,
>  		data <<= ADT7410_T13_VALUE_OFFSET;
>  	}
>  
> -	ret = adt7410_i2c_write_word(chip, bound_reg, data);
> +	ret = adt7410_write_word(chip, bound_reg, data);
>  	if (ret)
>  		return -EIO;
>  
> @@ -624,7 +615,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev,
>  	int ret;
>  	u8 t_hyst;
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst);
> +	ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst);
>  	if (ret)
>  		return -EIO;
>  
> @@ -649,7 +640,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev,
>  
>  	t_hyst = (u8)data;
>  
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst);
> +	ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst);
>  	if (ret)
>  		return -EIO;
>  
> @@ -704,14 +695,14 @@ static const struct iio_info adt7410_info = {
>   * device probe and remove
>   */
>  
> -static int __devinit adt7410_probe(struct i2c_client *client,
> -		const struct i2c_device_id *id)
> +static int __devinit adt7410_probe(struct device *dev, int irq,
> +	const char *name, const struct adt7410_ops *ops)
>  {
> +	unsigned long *adt7410_platform_data = dev->platform_data;
> +	unsigned long local_pdata[] = {0, 0};
>  	struct adt7410_chip_info *chip;
>  	struct iio_dev *indio_dev;
>  	int ret = 0;
> -	unsigned long *adt7410_platform_data = client->dev.platform_data;
> -	unsigned long local_pdata[] = {0, 0};
>  
>  	indio_dev = iio_device_alloc(sizeof(*chip));
>  	if (indio_dev == NULL) {
> @@ -720,12 +711,13 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  	}
>  	chip = iio_priv(indio_dev);
>  	/* this is only used for device removal purposes */
> -	i2c_set_clientdata(client, indio_dev);
> +	dev_set_drvdata(dev, indio_dev);
>  
> -	chip->client = client;
> +	chip->dev = dev;
> +	chip->ops = ops;
>  
> -	indio_dev->name = id->name;
> -	indio_dev->dev.parent = &client->dev;
> +	indio_dev->name = name;
> +	indio_dev->dev.parent = dev;
>  	indio_dev->info = &adt7410_info;
>  	indio_dev->modes = INDIO_DIRECT_MODE;
>  
> @@ -733,12 +725,12 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  		adt7410_platform_data = local_pdata;
>  
>  	/* CT critcal temperature event. line 0 */
> -	if (client->irq) {
> -		ret = request_threaded_irq(client->irq,
> +	if (irq) {
> +		ret = request_threaded_irq(irq,
>  					   NULL,
>  					   &adt7410_event_handler,
>  					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> -					   id->name,
> +					   name,
>  					   indio_dev);
>  		if (ret)
>  			goto error_free_dev;
> @@ -751,13 +743,13 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  					   &adt7410_event_handler,
>  					   adt7410_platform_data[1] |
>  					   IRQF_ONESHOT,
> -					   id->name,
> +					   name,
>  					   indio_dev);
>  		if (ret)
>  			goto error_unreg_ct_irq;
>  	}
>  
> -	ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
> +	ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config);
>  	if (ret) {
>  		ret = -EIO;
>  		goto error_unreg_int_irq;
> @@ -765,7 +757,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  
>  	chip->config |= ADT7410_RESOLUTION;
>  
> -	if (client->irq && adt7410_platform_data[0]) {
> +	if (irq && adt7410_platform_data[0]) {
>  
>  		/* set irq polarity low level */
>  		chip->config &= ~ADT7410_CT_POLARITY;
> @@ -776,7 +768,7 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  			chip->config &= ~ADT7410_INT_POLARITY;
>  	}
>  
> -	ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config);
> +	ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config);
>  	if (ret) {
>  		ret = -EIO;
>  		goto error_unreg_int_irq;
> @@ -785,36 +777,117 @@ static int __devinit adt7410_probe(struct i2c_client *client,
>  	if (ret)
>  		goto error_unreg_int_irq;
>  
> -	dev_info(&client->dev, "%s temperature sensor registered.\n",
> -			 id->name);
> +	dev_info(dev, "%s temperature sensor registered.\n",
> +			 name);
>  
>  	return 0;
>  
>  error_unreg_int_irq:
>  	free_irq(adt7410_platform_data[0], indio_dev);
>  error_unreg_ct_irq:
> -	free_irq(client->irq, indio_dev);
> +	free_irq(irq, indio_dev);
>  error_free_dev:
>  	iio_device_free(indio_dev);
>  error_ret:
>  	return ret;
>  }
>  
> -static int __devexit adt7410_remove(struct i2c_client *client)
> +static int __devexit adt7410_remove(struct device *dev, int irq)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> -	unsigned long *adt7410_platform_data = client->dev.platform_data;
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +	unsigned long *adt7410_platform_data = dev->platform_data;
>  
>  	iio_device_unregister(indio_dev);
>  	if (adt7410_platform_data[0])
>  		free_irq(adt7410_platform_data[0], indio_dev);
> -	if (client->irq)
> -		free_irq(client->irq, indio_dev);
> +	if (irq)
> +		free_irq(irq, indio_dev);
>  	iio_device_free(indio_dev);
>  
>  	return 0;
>  }
>  
> +#if IS_ENABLED(CONFIG_I2C)
> +
> +static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg,
> +	u16 *data)
> +{
> +	struct i2c_client *client = to_i2c_client(chip->dev);
> +	int ret = 0;
> +
> +	ret = i2c_smbus_read_word_data(client, reg);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "I2C read error\n");
> +		return ret;
> +	}
> +
> +	*data = swab16((u16)ret);
> +
> +	return 0;
> +}
> +
> +static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg,
> +	u16 data)
> +{
> +	struct i2c_client *client = to_i2c_client(chip->dev);
> +	int ret = 0;
> +
> +	ret = i2c_smbus_write_word_data(client, reg, swab16(data));
> +	if (ret < 0)
> +		dev_err(&client->dev, "I2C write error\n");
> +
> +	return ret;
> +}
> +
> +static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg,
> +	u8 *data)
> +{
> +	struct i2c_client *client = to_i2c_client(chip->dev);
> +	int ret = 0;
> +
> +	ret = i2c_smbus_read_byte_data(client, reg);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "I2C read error\n");
> +		return ret;
> +	}
> +
> +	*data = (u8)ret;
> +
> +	return 0;
> +}
> +
> +static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg,
> +	u8 data)
> +{
> +	struct i2c_client *client = to_i2c_client(chip->dev);
> +	int ret = 0;
> +
> +	ret = i2c_smbus_write_byte_data(client, reg, data);
> +	if (ret < 0)
> +		dev_err(&client->dev, "I2C write error\n");
> +
> +	return ret;
> +}
> +
> +static const struct adt7410_ops adt7410_i2c_ops = {
> +	.read_word = adt7410_i2c_read_word,
> +	.write_word = adt7410_i2c_write_word,
> +	.read_byte = adt7410_i2c_read_byte,
> +	.write_byte = adt7410_i2c_write_byte,
> +};
> +
> +static int __devinit adt7410_i2c_probe(struct i2c_client *client,
> +	const struct i2c_device_id *id)
> +{
> +	return adt7410_probe(&client->dev, client->irq, id->name,
> +		&adt7410_i2c_ops);
> +}
> +
> +static int __devexit adt7410_i2c_remove(struct i2c_client *client)
> +{
> +	return adt7410_remove(&client->dev, client->irq);
> +}
> +
>  static const struct i2c_device_id adt7410_id[] = {
>  	{ "adt7410", 0 },
>  	{}
> @@ -826,13 +899,204 @@ static struct i2c_driver adt7410_driver = {
>  	.driver = {
>  		.name = "adt7410",
>  	},
> -	.probe = adt7410_probe,
> -	.remove = __devexit_p(adt7410_remove),
> +	.probe = adt7410_i2c_probe,
> +	.remove = __devexit_p(adt7410_i2c_remove),
>  	.id_table = adt7410_id,
>  };
> -module_i2c_driver(adt7410_driver);
> +
> +static int __init adt7410_i2c_init(void)
> +{
> +	return i2c_add_driver(&adt7410_driver);
> +}
> +
> +static void __exit adt7410_i2c_exit(void)
> +{
> +	i2c_del_driver(&adt7410_driver);
> +}
> +
> +#else
> +
> +static int  __init adt7410_i2c_init(void) { return 0; };
> +static void __exit adt7410_i2c_exit(void) {};
> +
> +#endif
> +
> +#if IS_ENABLED(CONFIG_SPI_MASTER)
> +
> +static const u8 adt7371_reg_table[] = {
> +	[ADT7410_TEMPERATURE]   = ADT7310_TEMPERATURE,
> +	[ADT7410_STATUS]	= ADT7310_STATUS,
> +	[ADT7410_CONFIG]	= ADT7310_CONFIG,
> +	[ADT7410_T_ALARM_HIGH]	= ADT7310_T_ALARM_HIGH,
> +	[ADT7410_T_ALARM_LOW]	= ADT7310_T_ALARM_LOW,
> +	[ADT7410_T_CRIT]	= ADT7310_T_CRIT,
> +	[ADT7410_T_HYST]	= ADT7310_T_HYST,
> +	[ADT7410_ID]		= ADT7310_ID,
> +};
> +
> +#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET)
> +
> +static int adt7310_spi_read_word(struct adt7410_chip_info *chip,
> +	u8 reg, u16 *data)
> +{
> +	struct spi_device *spi = to_spi_device(chip->dev);
> +	u8 command = AD7310_COMMAND(reg);
> +	int ret = 0;
> +
> +	command |= ADT7310_CMD_READ;
> +	ret = spi_write(spi, &command, sizeof(command));
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI write command error\n");
> +		return ret;
> +	}
> +
> +	ret = spi_read(spi, (u8 *)data, sizeof(*data));
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI read word error\n");
> +		return ret;
> +	}
> +
> +	*data = be16_to_cpu(*data);
> +
> +	return 0;
> +}
> +
> +static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg,
> +	u16 data)
> +{
> +	struct spi_device *spi = to_spi_device(chip->dev);
> +	u8 buf[3];
> +	int ret = 0;
> +
> +	buf[0] = AD7310_COMMAND(reg);
> +	buf[1] = (u8)(data >> 8);
> +	buf[2] = (u8)(data & 0xFF);
> +
> +	ret = spi_write(spi, buf, 3);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI write word error\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg,
> +	u8 *data)
> +{
> +	struct spi_device *spi = to_spi_device(chip->dev);
> +	u8 command = AD7310_COMMAND(reg);
> +	int ret = 0;
> +
> +	command |= ADT7310_CMD_READ;
> +	ret = spi_write(spi, &command, sizeof(command));
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI write command error\n");
> +		return ret;
> +	}
> +
> +	ret = spi_read(spi, data, sizeof(*data));
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI read byte error\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg,
> +	u8 data)
> +{
> +	struct spi_device *spi = to_spi_device(chip->dev);
> +	u8 buf[2];
> +	int ret = 0;
> +
> +	buf[0] = AD7310_COMMAND(reg);
> +	buf[1] = data;
> +
> +	ret = spi_write(spi, buf, 2);
> +	if (ret < 0) {
> +		dev_err(&spi->dev, "SPI write byte error\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct adt7410_ops adt7310_spi_ops = {
> +	.read_word = adt7310_spi_read_word,
> +	.write_word = adt7310_spi_write_word,
> +	.read_byte = adt7310_spi_read_byte,
> +	.write_byte = adt7310_spi_write_byte,
> +};
> +
> +static int __devinit adt7310_spi_probe(struct spi_device *spi)
> +{
> +	return adt7410_probe(&spi->dev, spi->irq,
> +		spi_get_device_id(spi)->name, &adt7310_spi_ops);
> +}
> +
> +static int __devexit adt7310_spi_remove(struct spi_device *spi)
> +{
> +	return adt7410_remove(&spi->dev, spi->irq);
> +}
> +
> +static const struct spi_device_id adt7310_id[] = {
> +	{ "adt7310", 0 },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(spi, adt7310_id);
> +
> +static struct spi_driver adt7310_driver = {
> +	.driver = {
> +		.name = "adt7310",
> +		.owner = THIS_MODULE,
> +	},
> +	.probe = adt7310_spi_probe,
> +	.remove = __devexit_p(adt7310_spi_remove),
> +	.id_table = adt7310_id,
> +};
> +
> +static int __init adt7310_spi_init(void)
> +{
> +	return spi_register_driver(&adt7310_driver);
> +}
> +
> +static void adt7310_spi_exit(void)
> +{
> +	spi_unregister_driver(&adt7310_driver);
> +}
> +
> +#else
> +
> +static int __init adt7310_spi_init(void) { return 0; };
> +static void adt7310_spi_exit(void) {};
> +
> +#endif
> +
> +static int __init adt7410_init(void)
> +{
> +	int ret;
> +
> +	ret = adt7310_spi_init();
> +	if (ret)
> +		return ret;
> +
> +	ret = adt7410_i2c_init();
> +	if (ret)
> +		adt7310_spi_exit();
> +
> +	return ret;
> +}
> +module_init(adt7410_init);
> +
> +static void __exit adt7410_exit(void)
> +{
> +	adt7410_i2c_exit();
> +	adt7310_spi_exit();
> +}
> +module_exit(adt7410_exit);
>  
>  MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
> -MODULE_DESCRIPTION("Analog Devices ADT7410 digital"
> -			" temperature sensor driver");
> +MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver");
>  MODULE_LICENSE("GPL v2");
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic