From: Jonathan Cameron <jic23@cam.ac.uk>
To: Mike Frysinger <vapier@gentoo.org>
Cc: linux-iio@vger.kernel.org,
device-drivers-devel@blackfin.uclinux.org,
Sonic Zhang <sonic.zhang@analog.com>
Subject: Re: [PATCH 04/14] staging: iio: adc: new driver for AD7314 devices
Date: Sun, 24 Oct 2010 22:56:56 +0100 [thread overview]
Message-ID: <4CC4ABA8.2010401@cam.ac.uk> (raw)
In-Reply-To: <1287865757-1031-4-git-send-email-vapier@gentoo.org>
On 10/23/10 21:29, Mike Frysinger wrote:
> From: Sonic Zhang <sonic.zhang@analog.com>
>
Why IIO? Do you have a use case that needs features off IIO
and wouldn't be covered by hwmon?
Not using any here, so I'm doubtful about this (Sonic and I
exchanged a few emails about this a while back).
Few comments inline and I guess iio then moving to hwmon is
fine with me if you want to do it... (hwmon is simpler!).
> Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
> drivers/staging/iio/adc/Kconfig | 7 +
> drivers/staging/iio/adc/Makefile | 1 +
> drivers/staging/iio/adc/ad7314.c | 308 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 316 insertions(+), 0 deletions(-)
> create mode 100644 drivers/staging/iio/adc/ad7314.c
>
> diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
> index 847f5f2..6d3b8bc 100644
> --- a/drivers/staging/iio/adc/Kconfig
> +++ b/drivers/staging/iio/adc/Kconfig
> @@ -54,3 +54,10 @@ config AD7298
> help
> Say yes here to build support for Analog Devices AD7298
> temperature sensors and ADC.
> +
> +config AD7314
> + tristate "Analog Devices AD7314 temperature sensor driver"
> + depends on SPI
Please list all parts supported (appear to be several others in the
id table.)
> + help
> + Say yes here to build support for Analog Devices AD7314
> + temperature sensors.
> diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
> index d0ea747..04fd93b 100644
> --- a/drivers/staging/iio/adc/Makefile
> +++ b/drivers/staging/iio/adc/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_AD7150) += ad7150.o
> obj-$(CONFIG_AD7152) += ad7152.o
> obj-$(CONFIG_AD7291) += ad7291.o
> obj-$(CONFIG_AD7298) += ad7298.o
> +obj-$(CONFIG_AD7314) += ad7314.o
> diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c
> new file mode 100644
> index 0000000..8c17b1f
> --- /dev/null
> +++ b/drivers/staging/iio/adc/ad7314.c
> @@ -0,0 +1,308 @@
> +/*
> + * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302
> + *
> + * Copyright 2010 Analog Devices Inc.
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/gpio.h>
> +#include <linux/workqueue.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/rtc.h>
> +
> +#include "../iio.h"
> +#include "../sysfs.h"
> +
> +/*
> + * AD7314 power mode
> + */
> +#define AD7314_PD 0x2000
> +
> +/*
> + * AD7314 temperature masks
> + */
> +#define AD7314_TEMP_SIGN 0x200
> +#define AD7314_TEMP_MASK 0x7FE0
> +#define AD7314_TEMP_OFFSET 5
> +#define AD7314_TEMP_FLOAT_OFFSET 2
> +#define AD7314_TEMP_FLOAT_MASK 0x3
> +
> +/*
> + * ADT7301 and ADT7302 temperature masks
> + */
> +#define ADT7301_TEMP_SIGN 0x2000
> +#define ADT7301_TEMP_MASK 0x2FFF
> +#define ADT7301_TEMP_FLOAT_OFFSET 5
> +#define ADT7301_TEMP_FLOAT_MASK 0x1F
> +
> +/*
> + * struct ad7314_chip_info - chip specifc information
> + */
> +
> +struct ad7314_chip_info {
> + const char *name;
> + struct spi_device *spi_dev;
> + struct iio_dev *indio_dev;
> + s64 last_timestamp;
> + u8 mode;
> +};
> +
> +/*
> + * ad7314 register access by SPI
> + */
> +
> +static int ad7314_spi_read(struct ad7314_chip_info *chip, u16 *data)
> +{
> + struct spi_device *spi_dev = chip->spi_dev;
> + int ret = 0;
> + u16 value;
> +
> + ret = spi_read(spi_dev, (u8 *)&value, sizeof(value));
> + if (ret < 0) {
> + dev_err(&spi_dev->dev, "SPI read error\n");
> + return ret;
> + }
> +
> + *data = be16_to_cpu((u16)value);
> +
> + return ret;
> +}
> +
> +static int ad7314_spi_write(struct ad7314_chip_info *chip, u16 data)
> +{
> + struct spi_device *spi_dev = chip->spi_dev;
> + int ret = 0;
> + u16 value = cpu_to_be16(data);
> +
> + ret = spi_write(spi_dev, (u8 *)&value, sizeof(value));
> + if (ret < 0)
> + dev_err(&spi_dev->dev, "SPI write error\n");
> +
> + return ret;
> +}
> +
> +static ssize_t ad7314_show_mode(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct iio_dev *dev_info = dev_get_drvdata(dev);
> + struct ad7314_chip_info *chip = dev_info->dev_data;
> +
> + if (chip->mode)
> + return sprintf(buf, "power-save\n");
> + else
> + return sprintf(buf, "full\n");
> +}
> +
> +static ssize_t ad7314_store_mode(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t len)
> +{
> + struct iio_dev *dev_info = dev_get_drvdata(dev);
> + struct ad7314_chip_info *chip = dev_info->dev_data;
> + u16 mode = 0;
> + int ret;
> +
> + if (!strcmp(buf, "full"))
> + mode = AD7314_PD;
> +
> + ret = ad7314_spi_write(chip, mode);
> + if (ret)
> + return -EIO;
> +
> + chip->mode = mode;
> +
> + return len;
> +}
> +
> +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
> + ad7314_show_mode,
> + ad7314_store_mode,
> + 0);
I'm still anti 'mode' attributes. They just don't generalize.
> +
> +static ssize_t ad7314_show_available_modes(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + return sprintf(buf, "full\npower-save\n");
Do this via sampling_frequency (assuming that is what changes!)
> +}
> +
> +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7314_show_available_modes, NULL, 0);
mode_available please.
> +
> +static ssize_t ad7314_show_temperature(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct iio_dev *dev_info = dev_get_drvdata(dev);
> + struct ad7314_chip_info *chip = dev_info->dev_data;
> + u16 data;
> + char sign = ' ';
> + int ret;
> +
> + if (chip->mode) {
> + ret = ad7314_spi_write(chip, 0);
> + if (ret)
> + return -EIO;
Error eating.
> + }
> +
> + ret = ad7314_spi_read(chip, &data);
> + if (ret)
> + return -EIO;
> +
> + if (chip->mode)
> + ad7314_spi_write(chip, chip->mode);
> +
> + if (strcmp(chip->name, "ad7314")) {
> + data = (data & AD7314_TEMP_MASK) >>
> + AD7314_TEMP_OFFSET;
> + if (data & AD7314_TEMP_SIGN) {
> + data = (AD7314_TEMP_SIGN << 1) - data;
> + sign = '-';
> + }
> +
> + return sprintf(buf, "%c%d.%.2d\n", sign,
> + data >> AD7314_TEMP_FLOAT_OFFSET,
> + (data & AD7314_TEMP_FLOAT_MASK) * 25);
> + } else {
> + data &= ADT7301_TEMP_MASK;
> + if (data & ADT7301_TEMP_SIGN) {
> + data = (ADT7301_TEMP_SIGN << 1) - data;
> + sign = '-';
> + }
> +
> + return sprintf(buf, "%c%d.%.5d\n", sign,
> + data >> ADT7301_TEMP_FLOAT_OFFSET,
> + (data & ADT7301_TEMP_FLOAT_MASK) * 3125);
> + }
> +}
> +
> +static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0);
> +
> +static ssize_t ad7314_show_name(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct iio_dev *dev_info = dev_get_drvdata(dev);
> + struct ad7314_chip_info *chip = dev_info->dev_data;
> + return sprintf(buf, "%s\n", chip->name);
> +}
> +
> +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0);
> +
> +static struct attribute *ad7314_attributes[] = {
> + &iio_dev_attr_available_modes.dev_attr.attr,
> + &iio_dev_attr_mode.dev_attr.attr,
> + &iio_dev_attr_temperature.dev_attr.attr,
temp_input please (we match hwmon where possible).
> + &iio_dev_attr_name.dev_attr.attr,
> + NULL,
> +};
> +
> +static const struct attribute_group ad7314_attribute_group = {
> + .attrs = ad7314_attributes,
> +};
> +
> +/*
> + * device probe and remove
> + */
> +
> +static int __devinit ad7314_probe(struct spi_device *spi_dev)
> +{
> + struct ad7314_chip_info *chip;
> + int ret = 0;
> +
> + chip = kzalloc(sizeof(struct ad7314_chip_info), GFP_KERNEL);
> +
> + if (chip == NULL)
> + return -ENOMEM;
> +
> + /* this is only used for device removal purposes */
> + dev_set_drvdata(&spi_dev->dev, chip);
> +
> + chip->spi_dev = spi_dev;
> + chip->name = spi_dev->modalias;
> +
> + chip->indio_dev = iio_allocate_device();
> + if (chip->indio_dev == NULL) {
> + ret = -ENOMEM;
> + goto error_free_chip;
> + }
> +
> + chip->indio_dev->dev.parent = &spi_dev->dev;
> + chip->indio_dev->attrs = &ad7314_attribute_group;
> + chip->indio_dev->dev_data = (void *)chip;
> + chip->indio_dev->driver_module = THIS_MODULE;
> +
> + ret = iio_device_register(chip->indio_dev);
> + if (ret)
> + goto error_free_dev;
> +
> + dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
> + chip->name);
> +
> + return 0;
> +error_free_dev:
> + iio_free_device(chip->indio_dev);
> +error_free_chip:
> + kfree(chip);
> +
> + return ret;
> +}
> +
> +static int __devexit ad7314_remove(struct spi_device *spi_dev)
> +{
> + struct ad7314_chip_info *chip = dev_get_drvdata(&spi_dev->dev);
> + struct iio_dev *indio_dev = chip->indio_dev;
> +
> + dev_set_drvdata(&spi_dev->dev, NULL);
> + if (spi_dev->irq)
> + iio_unregister_interrupt_line(indio_dev, 0);
> + iio_device_unregister(indio_dev);
> + iio_free_device(chip->indio_dev);
> + kfree(chip);
> +
> + return 0;
> +}
> +
> +static const struct spi_device_id ad7314_id[] = {
> + { "adt7301", 0 },
> + { "adt7302", 0 },
> + { "ad7314", 0 },
> + {}
> +};
> +
> +static struct spi_driver ad7314_driver = {
> + .driver = {
> + .name = "ad7314",
> + .bus = &spi_bus_type,
> + .owner = THIS_MODULE,
> + },
> + .probe = ad7314_probe,
> + .remove = __devexit_p(ad7314_remove),
> + .id_table = ad7314_id,
> +};
> +
> +static __init int ad7314_init(void)
> +{
> + return spi_register_driver(&ad7314_driver);
> +}
> +
> +static __exit void ad7314_exit(void)
> +{
> + spi_unregister_driver(&ad7314_driver);
> +}
> +
> +MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
> +MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
> + " temperature sensor driver");
> +MODULE_LICENSE("GPL v2");
> +
> +module_init(ad7314_init);
> +module_exit(ad7314_exit);
next prev parent reply other threads:[~2010-10-24 21:51 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-23 20:29 [PATCH 01/14] staging: iio: adc: new driver for AD7152/3 devices Mike Frysinger
2010-10-23 20:29 ` [PATCH 02/14] staging: iio: adc: new driver for AD7291 devices Mike Frysinger
2010-10-24 21:32 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 03/14] staging: iio: adc: new driver for AD7298 devices Mike Frysinger
2010-10-24 21:49 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 04/14] staging: iio: adc: new driver for AD7314 devices Mike Frysinger
2010-10-24 21:56 ` Jonathan Cameron [this message]
2010-10-26 3:35 ` Zhang, Sonic
2010-10-23 20:29 ` [PATCH 05/14] staging: iio: adc: new driver for AD7414/5 devices Mike Frysinger
2010-10-24 22:03 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 06/14] staging: iio: adc: new driver for AD7416/7/8 devices Mike Frysinger
2010-10-24 22:19 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 07/14] staging: iio: adc: new driver for AD7475/6/6A/7/7A/8/8A and AD7495 devices Mike Frysinger
2010-10-24 21:14 ` [Device-drivers-devel] " Mike Frysinger
2010-10-24 22:21 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 08/14] staging: iio: adc: new driver for AD7745/6/7 devices Mike Frysinger
2010-10-24 22:36 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 09/14] staging: iio: adc: new driver for AD7816 devices Mike Frysinger
2010-10-23 20:29 ` [PATCH 10/14] staging: iio: adc: new driver for ADT75 temperature sensors Mike Frysinger
2010-10-23 20:29 ` [PATCH 11/14] staging: iio: adc: new driver for ADT7310 " Mike Frysinger
2010-10-23 20:29 ` [PATCH 12/14] staging: iio: adc: new driver for ADT7408 " Mike Frysinger
2010-10-24 22:53 ` Jonathan Cameron
2010-10-24 23:47 ` Guenter Roeck
2010-10-25 10:28 ` Jonathan Cameron
2010-10-26 4:20 ` Zhang, Sonic
2010-10-26 5:08 ` Guenter Roeck
2010-10-26 5:38 ` Zhang, Sonic
2010-10-26 9:14 ` Jonathan Cameron
2010-10-25 0:46 ` Guenter Roeck
2010-10-25 10:32 ` Jonathan Cameron
2010-10-25 11:19 ` Guenter Roeck
2010-10-25 11:43 ` Jonathan Cameron
2010-10-25 14:12 ` Guenter Roeck
2010-10-25 16:18 ` Hennerich, Michael
2010-10-25 11:47 ` [Device-drivers-devel] " Hennerich, Michael
2010-10-26 3:21 ` Zhang, Sonic
2010-10-26 3:27 ` Zhang, Sonic
2010-10-26 3:52 ` Guenter Roeck
2010-10-26 9:15 ` Jonathan Cameron
2010-10-26 14:33 ` Guenter Roeck
2010-11-01 10:56 ` Jonathan Cameron
2010-11-01 14:37 ` Guenter Roeck
2010-11-01 15:19 ` Jonathan Cameron
2010-10-23 20:29 ` [PATCH 13/14] staging: iio: adc: new driver for ADT7410 " Mike Frysinger
2010-10-23 20:29 ` [PATCH 14/14] staging: iio: adc: new ad799x driver Mike Frysinger
2010-10-24 21:14 ` [Device-drivers-devel] " Mike Frysinger
2010-10-24 22:55 ` Jonathan Cameron
2010-10-24 21:09 ` [PATCH 01/14] staging: iio: adc: new driver for AD7152/3 devices Jonathan Cameron
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=4CC4ABA8.2010401@cam.ac.uk \
--to=jic23@cam.ac.uk \
--cc=device-drivers-devel@blackfin.uclinux.org \
--cc=linux-iio@vger.kernel.org \
--cc=sonic.zhang@analog.com \
--cc=vapier@gentoo.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.