hwmon: (ad7418) Avoid forward declaration
[firefly-linux-kernel-4.4.55.git] / drivers / hwmon / ad7418.c
1 /*
2  * An hwmon driver for the Analog Devices AD7416/17/18
3  * Copyright (C) 2006-07 Tower Technologies
4  *
5  * Author: Alessandro Zummo <a.zummo@towertech.it>
6  *
7  * Based on lm75.c
8  * Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License,
12  * as published by the Free Software Foundation - version 2.
13  */
14
15 #include <linux/module.h>
16 #include <linux/jiffies.h>
17 #include <linux/i2c.h>
18 #include <linux/hwmon.h>
19 #include <linux/hwmon-sysfs.h>
20 #include <linux/err.h>
21 #include <linux/mutex.h>
22 #include <linux/delay.h>
23 #include <linux/slab.h>
24
25 #include "lm75.h"
26
27 #define DRV_VERSION "0.4"
28
29 enum chips { ad7416, ad7417, ad7418 };
30
31 /* AD7418 registers */
32 #define AD7418_REG_TEMP_IN      0x00
33 #define AD7418_REG_CONF         0x01
34 #define AD7418_REG_TEMP_HYST    0x02
35 #define AD7418_REG_TEMP_OS      0x03
36 #define AD7418_REG_ADC          0x04
37 #define AD7418_REG_CONF2        0x05
38
39 #define AD7418_REG_ADC_CH(x)    ((x) << 5)
40 #define AD7418_CH_TEMP          AD7418_REG_ADC_CH(0)
41
42 static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
43                                         AD7418_REG_TEMP_HYST,
44                                         AD7418_REG_TEMP_OS };
45
46 struct ad7418_data {
47         struct device           *hwmon_dev;
48         struct attribute_group  attrs;
49         enum chips              type;
50         struct mutex            lock;
51         int                     adc_max;        /* number of ADC channels */
52         char                    valid;
53         unsigned long           last_updated;   /* In jiffies */
54         s16                     temp[3];        /* Register values */
55         u16                     in[4];
56 };
57
58 static struct ad7418_data *ad7418_update_device(struct device *dev)
59 {
60         struct i2c_client *client = to_i2c_client(dev);
61         struct ad7418_data *data = i2c_get_clientdata(client);
62
63         mutex_lock(&data->lock);
64
65         if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
66                 || !data->valid) {
67                 u8 cfg;
68                 int i, ch;
69
70                 /* read config register and clear channel bits */
71                 cfg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
72                 cfg &= 0x1F;
73
74                 i2c_smbus_write_byte_data(client, AD7418_REG_CONF,
75                                                 cfg | AD7418_CH_TEMP);
76                 udelay(30);
77
78                 for (i = 0; i < 3; i++) {
79                         data->temp[i] =
80                                 i2c_smbus_read_word_swapped(client,
81                                                 AD7418_REG_TEMP[i]);
82                 }
83
84                 for (i = 0, ch = 4; i < data->adc_max; i++, ch--) {
85                         i2c_smbus_write_byte_data(client,
86                                         AD7418_REG_CONF,
87                                         cfg | AD7418_REG_ADC_CH(ch));
88
89                         udelay(15);
90                         data->in[data->adc_max - 1 - i] =
91                                 i2c_smbus_read_word_swapped(client,
92                                                 AD7418_REG_ADC);
93                 }
94
95                 /* restore old configuration value */
96                 i2c_smbus_write_word_swapped(client, AD7418_REG_CONF, cfg);
97
98                 data->last_updated = jiffies;
99                 data->valid = 1;
100         }
101
102         mutex_unlock(&data->lock);
103
104         return data;
105 }
106
107 static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
108                         char *buf)
109 {
110         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
111         struct ad7418_data *data = ad7418_update_device(dev);
112         return sprintf(buf, "%d\n",
113                 LM75_TEMP_FROM_REG(data->temp[attr->index]));
114 }
115
116 static ssize_t show_adc(struct device *dev, struct device_attribute *devattr,
117                         char *buf)
118 {
119         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
120         struct ad7418_data *data = ad7418_update_device(dev);
121
122         return sprintf(buf, "%d\n",
123                 ((data->in[attr->index] >> 6) * 2500 + 512) / 1024);
124 }
125
126 static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
127                         const char *buf, size_t count)
128 {
129         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
130         struct i2c_client *client = to_i2c_client(dev);
131         struct ad7418_data *data = i2c_get_clientdata(client);
132         long temp;
133         int ret = kstrtol(buf, 10, &temp);
134
135         if (ret < 0)
136                 return ret;
137
138         mutex_lock(&data->lock);
139         data->temp[attr->index] = LM75_TEMP_TO_REG(temp);
140         i2c_smbus_write_word_swapped(client,
141                                      AD7418_REG_TEMP[attr->index],
142                                      data->temp[attr->index]);
143         mutex_unlock(&data->lock);
144         return count;
145 }
146
147 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
148 static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
149                                 show_temp, set_temp, 1);
150 static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
151                                 show_temp, set_temp, 2);
152
153 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 0);
154 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
155 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
156 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
157
158 static struct attribute *ad7416_attributes[] = {
159         &sensor_dev_attr_temp1_max.dev_attr.attr,
160         &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
161         &sensor_dev_attr_temp1_input.dev_attr.attr,
162         NULL
163 };
164
165 static struct attribute *ad7417_attributes[] = {
166         &sensor_dev_attr_temp1_max.dev_attr.attr,
167         &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
168         &sensor_dev_attr_temp1_input.dev_attr.attr,
169         &sensor_dev_attr_in1_input.dev_attr.attr,
170         &sensor_dev_attr_in2_input.dev_attr.attr,
171         &sensor_dev_attr_in3_input.dev_attr.attr,
172         &sensor_dev_attr_in4_input.dev_attr.attr,
173         NULL
174 };
175
176 static struct attribute *ad7418_attributes[] = {
177         &sensor_dev_attr_temp1_max.dev_attr.attr,
178         &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
179         &sensor_dev_attr_temp1_input.dev_attr.attr,
180         &sensor_dev_attr_in1_input.dev_attr.attr,
181         NULL
182 };
183
184 static void ad7418_init_client(struct i2c_client *client)
185 {
186         struct ad7418_data *data = i2c_get_clientdata(client);
187
188         int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
189         if (reg < 0) {
190                 dev_err(&client->dev, "cannot read configuration register\n");
191         } else {
192                 dev_info(&client->dev, "configuring for mode 1\n");
193                 i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
194
195                 if (data->type == ad7417 || data->type == ad7418)
196                         i2c_smbus_write_byte_data(client,
197                                                 AD7418_REG_CONF2, 0x00);
198         }
199 }
200
201 static int ad7418_probe(struct i2c_client *client,
202                          const struct i2c_device_id *id)
203 {
204         struct i2c_adapter *adapter = client->adapter;
205         struct ad7418_data *data;
206         int err;
207
208         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
209                                         I2C_FUNC_SMBUS_WORD_DATA))
210                 return -EOPNOTSUPP;
211
212         data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data),
213                             GFP_KERNEL);
214         if (!data)
215                 return -ENOMEM;
216
217         i2c_set_clientdata(client, data);
218
219         mutex_init(&data->lock);
220         data->type = id->driver_data;
221
222         switch (data->type) {
223         case ad7416:
224                 data->adc_max = 0;
225                 data->attrs.attrs = ad7416_attributes;
226                 break;
227
228         case ad7417:
229                 data->adc_max = 4;
230                 data->attrs.attrs = ad7417_attributes;
231                 break;
232
233         case ad7418:
234                 data->adc_max = 1;
235                 data->attrs.attrs = ad7418_attributes;
236                 break;
237         }
238
239         dev_info(&client->dev, "%s chip found\n", client->name);
240
241         /* Initialize the AD7418 chip */
242         ad7418_init_client(client);
243
244         /* Register sysfs hooks */
245         err = sysfs_create_group(&client->dev.kobj, &data->attrs);
246         if (err)
247                 return err;
248
249         data->hwmon_dev = hwmon_device_register(&client->dev);
250         if (IS_ERR(data->hwmon_dev)) {
251                 err = PTR_ERR(data->hwmon_dev);
252                 goto exit_remove;
253         }
254
255         return 0;
256
257 exit_remove:
258         sysfs_remove_group(&client->dev.kobj, &data->attrs);
259         return err;
260 }
261
262 static int ad7418_remove(struct i2c_client *client)
263 {
264         struct ad7418_data *data = i2c_get_clientdata(client);
265         hwmon_device_unregister(data->hwmon_dev);
266         sysfs_remove_group(&client->dev.kobj, &data->attrs);
267         return 0;
268 }
269
270 static const struct i2c_device_id ad7418_id[] = {
271         { "ad7416", ad7416 },
272         { "ad7417", ad7417 },
273         { "ad7418", ad7418 },
274         { }
275 };
276 MODULE_DEVICE_TABLE(i2c, ad7418_id);
277
278 static struct i2c_driver ad7418_driver = {
279         .driver = {
280                 .name   = "ad7418",
281         },
282         .probe          = ad7418_probe,
283         .remove         = ad7418_remove,
284         .id_table       = ad7418_id,
285 };
286
287 module_i2c_driver(ad7418_driver);
288
289 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
290 MODULE_DESCRIPTION("AD7416/17/18 driver");
291 MODULE_LICENSE("GPL");
292 MODULE_VERSION(DRV_VERSION);