2 * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302
4 * Copyright 2010 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/sysfs.h>
13 #include <linux/spi/spi.h>
21 #define AD7314_PD 0x2000
24 * AD7314 temperature masks
26 #define AD7314_TEMP_SIGN 0x200
27 #define AD7314_TEMP_MASK 0x7FE0
28 #define AD7314_TEMP_OFFSET 5
29 #define AD7314_TEMP_FLOAT_OFFSET 2
30 #define AD7314_TEMP_FLOAT_MASK 0x3
33 * ADT7301 and ADT7302 temperature masks
35 #define ADT7301_TEMP_SIGN 0x2000
36 #define ADT7301_TEMP_MASK 0x2FFF
37 #define ADT7301_TEMP_FLOAT_OFFSET 5
38 #define ADT7301_TEMP_FLOAT_MASK 0x1F
41 * struct ad7314_chip_info - chip specifc information
44 struct ad7314_chip_info
{
45 struct spi_device
*spi_dev
;
51 * ad7314 register access by SPI
54 static int ad7314_spi_read(struct ad7314_chip_info
*chip
, u16
*data
)
56 struct spi_device
*spi_dev
= chip
->spi_dev
;
60 ret
= spi_read(spi_dev
, (u8
*)&value
, sizeof(value
));
62 dev_err(&spi_dev
->dev
, "SPI read error\n");
66 *data
= be16_to_cpu((u16
)value
);
71 static int ad7314_spi_write(struct ad7314_chip_info
*chip
, u16 data
)
73 struct spi_device
*spi_dev
= chip
->spi_dev
;
75 u16 value
= cpu_to_be16(data
);
77 ret
= spi_write(spi_dev
, (u8
*)&value
, sizeof(value
));
79 dev_err(&spi_dev
->dev
, "SPI write error\n");
84 static ssize_t
ad7314_show_mode(struct device
*dev
,
85 struct device_attribute
*attr
,
88 struct iio_dev
*dev_info
= dev_get_drvdata(dev
);
89 struct ad7314_chip_info
*chip
= iio_priv(dev_info
);
92 return sprintf(buf
, "power-save\n");
94 return sprintf(buf
, "full\n");
97 static ssize_t
ad7314_store_mode(struct device
*dev
,
98 struct device_attribute
*attr
,
102 struct iio_dev
*dev_info
= dev_get_drvdata(dev
);
103 struct ad7314_chip_info
*chip
= iio_priv(dev_info
);
107 if (!strcmp(buf
, "full"))
110 ret
= ad7314_spi_write(chip
, mode
);
119 static IIO_DEVICE_ATTR(mode
, S_IRUGO
| S_IWUSR
,
124 static ssize_t
ad7314_show_available_modes(struct device
*dev
,
125 struct device_attribute
*attr
,
128 return sprintf(buf
, "full\npower-save\n");
131 static IIO_DEVICE_ATTR(available_modes
, S_IRUGO
, ad7314_show_available_modes
, NULL
, 0);
133 static ssize_t
ad7314_show_temperature(struct device
*dev
,
134 struct device_attribute
*attr
,
137 struct iio_dev
*dev_info
= dev_get_drvdata(dev
);
138 struct ad7314_chip_info
*chip
= iio_priv(dev_info
);
144 ret
= ad7314_spi_write(chip
, 0);
149 ret
= ad7314_spi_read(chip
, &data
);
154 ad7314_spi_write(chip
, chip
->mode
);
156 if (strcmp(dev_info
->name
, "ad7314")) {
157 data
= (data
& AD7314_TEMP_MASK
) >>
159 if (data
& AD7314_TEMP_SIGN
) {
160 data
= (AD7314_TEMP_SIGN
<< 1) - data
;
164 return sprintf(buf
, "%c%d.%.2d\n", sign
,
165 data
>> AD7314_TEMP_FLOAT_OFFSET
,
166 (data
& AD7314_TEMP_FLOAT_MASK
) * 25);
168 data
&= ADT7301_TEMP_MASK
;
169 if (data
& ADT7301_TEMP_SIGN
) {
170 data
= (ADT7301_TEMP_SIGN
<< 1) - data
;
174 return sprintf(buf
, "%c%d.%.5d\n", sign
,
175 data
>> ADT7301_TEMP_FLOAT_OFFSET
,
176 (data
& ADT7301_TEMP_FLOAT_MASK
) * 3125);
180 static IIO_DEVICE_ATTR(temperature
, S_IRUGO
, ad7314_show_temperature
, NULL
, 0);
182 static struct attribute
*ad7314_attributes
[] = {
183 &iio_dev_attr_available_modes
.dev_attr
.attr
,
184 &iio_dev_attr_mode
.dev_attr
.attr
,
185 &iio_dev_attr_temperature
.dev_attr
.attr
,
189 static const struct attribute_group ad7314_attribute_group
= {
190 .attrs
= ad7314_attributes
,
193 static const struct iio_info ad7314_info
= {
194 .attrs
= &ad7314_attribute_group
,
195 .driver_module
= THIS_MODULE
,
198 * device probe and remove
201 static int __devinit
ad7314_probe(struct spi_device
*spi_dev
)
203 struct ad7314_chip_info
*chip
;
204 struct iio_dev
*indio_dev
;
207 indio_dev
= iio_allocate_device(sizeof(*chip
));
208 if (indio_dev
== NULL
) {
212 chip
= iio_priv(indio_dev
);
213 /* this is only used for device removal purposes */
214 dev_set_drvdata(&spi_dev
->dev
, chip
);
216 chip
->spi_dev
= spi_dev
;
218 indio_dev
->name
= spi_get_device_id(spi_dev
)->name
;
219 indio_dev
->dev
.parent
= &spi_dev
->dev
;
220 indio_dev
->info
= &ad7314_info
;
222 ret
= iio_device_register(indio_dev
);
226 dev_info(&spi_dev
->dev
, "%s temperature sensor registered.\n",
231 iio_free_device(indio_dev
);
236 static int __devexit
ad7314_remove(struct spi_device
*spi_dev
)
238 struct iio_dev
*indio_dev
= dev_get_drvdata(&spi_dev
->dev
);
240 dev_set_drvdata(&spi_dev
->dev
, NULL
);
241 iio_device_unregister(indio_dev
);
242 iio_free_device(indio_dev
);
247 static const struct spi_device_id ad7314_id
[] = {
254 static struct spi_driver ad7314_driver
= {
257 .bus
= &spi_bus_type
,
258 .owner
= THIS_MODULE
,
260 .probe
= ad7314_probe
,
261 .remove
= __devexit_p(ad7314_remove
),
262 .id_table
= ad7314_id
,
265 static __init
int ad7314_init(void)
267 return spi_register_driver(&ad7314_driver
);
270 static __exit
void ad7314_exit(void)
272 spi_unregister_driver(&ad7314_driver
);
275 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
276 MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital"
277 " temperature sensor driver");
278 MODULE_LICENSE("GPL v2");
280 module_init(ad7314_init
);
281 module_exit(ad7314_exit
);