Fresh pull from upstream
[librecmc/librecmc.git] / package / kernel / hwmon-gsc / src / gsc.c
1 /*
2  * A hwmon driver for the Gateworks System Controller 
3  * Copyright (C) 2009 Gateworks Corporation
4  *
5  * Author: Chris Lang <clang@gateworks.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License,
9  * as published by the Free Software Foundation - version 2.
10  */
11
12 #include <linux/module.h>
13 #include <linux/i2c.h>
14 #include <linux/hwmon.h>
15 #include <linux/hwmon-sysfs.h>
16 #include <linux/err.h>
17 #include <linux/slab.h>
18
19 #define DRV_VERSION "0.2"
20
21 enum chips { gsp };
22
23 /* AD7418 registers */
24 #define GSP_REG_TEMP_IN         0x00
25 #define GSP_REG_VIN             0x02
26 #define GSP_REG_3P3             0x05
27 #define GSP_REG_BAT             0x08
28 #define GSP_REG_5P0             0x0b
29 #define GSP_REG_CORE            0x0e
30 #define GSP_REG_CPU1            0x11
31 #define GSP_REG_CPU2            0x14
32 #define GSP_REG_DRAM            0x17
33 #define GSP_REG_EXT_BAT         0x1a
34 #define GSP_REG_IO1             0x1d
35 #define GSP_REG_IO2             0x20
36 #define GSP_REG_PCIE            0x23
37 #define GSP_REG_CURRENT         0x26
38 #define GSP_FAN_0               0x2C
39 #define GSP_FAN_1               0x2E
40 #define GSP_FAN_2               0x30
41 #define GSP_FAN_3               0x32
42 #define GSP_FAN_4               0x34
43 #define GSP_FAN_5               0x36
44
45 struct gsp_sensor_info {
46         const char* name;
47         int reg;
48 };
49
50 static const struct gsp_sensor_info gsp_sensors[] = {
51         {"temp", GSP_REG_TEMP_IN},
52         {"vin", GSP_REG_VIN},
53         {"3p3", GSP_REG_3P3},
54         {"bat", GSP_REG_BAT},
55         {"5p0", GSP_REG_5P0},
56         {"core", GSP_REG_CORE},
57         {"cpu1", GSP_REG_CPU1},
58         {"cpu2", GSP_REG_CPU2},
59         {"dram", GSP_REG_DRAM},
60         {"ext_bat", GSP_REG_EXT_BAT},
61         {"io1", GSP_REG_IO1},
62         {"io2", GSP_REG_IO2},
63         {"pci2", GSP_REG_PCIE},
64         {"current", GSP_REG_CURRENT},
65         {"fan_point0", GSP_FAN_0},
66         {"fan_point1", GSP_FAN_1},
67         {"fan_point2", GSP_FAN_2},
68         {"fan_point3", GSP_FAN_3},
69         {"fan_point4", GSP_FAN_4},
70         {"fan_point5", GSP_FAN_5},
71 };
72
73 struct gsp_data {
74         struct device           *hwmon_dev;
75         struct attribute_group  attrs;
76         enum chips              type;
77 };
78
79 static int gsp_probe(struct i2c_client *client,
80                         const struct i2c_device_id *id);
81 static int gsp_remove(struct i2c_client *client);
82
83 static const struct i2c_device_id gsp_id[] = {
84         { "gsp", 0 },
85         { }
86 };
87 MODULE_DEVICE_TABLE(i2c, gsp_id);
88
89 static struct i2c_driver gsp_driver = {
90         .driver = {
91                 .name   = "gsp",
92         },
93         .probe          = gsp_probe,
94         .remove         = gsp_remove,
95         .id_table       = gsp_id,
96 };
97
98 /* All registers are word-sized, except for the configuration registers.
99  * AD7418 uses a high-byte first convention. Do NOT use those functions to
100  * access the configuration registers CONF and CONF2, as they are byte-sized.
101  */
102 static inline int gsp_read(struct i2c_client *client, u8 reg)
103 {
104         unsigned int adc = 0;
105         if (reg == GSP_REG_TEMP_IN || reg > GSP_REG_CURRENT)
106         {
107                 adc |= i2c_smbus_read_byte_data(client, reg);
108                 adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
109                 return adc;
110         }
111         else
112         {
113                 adc |= i2c_smbus_read_byte_data(client, reg);
114                 adc |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
115                 adc |= i2c_smbus_read_byte_data(client, reg + 2) << 16;
116                 return adc;
117         }
118 }
119
120 static inline int gsp_write(struct i2c_client *client, u8 reg, u16 value)
121 {
122         i2c_smbus_write_byte_data(client, reg, value & 0xff);
123         i2c_smbus_write_byte_data(client, reg + 1, ((value >> 8) & 0xff));
124         return 1;
125 }
126
127 static ssize_t show_adc(struct device *dev, struct device_attribute *devattr,
128                         char *buf)
129 {
130         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
131         struct i2c_client *client = to_i2c_client(dev);
132         return sprintf(buf, "%d\n", gsp_read(client, gsp_sensors[attr->index].reg));
133 }
134
135 static ssize_t show_label(struct device *dev,
136                         struct device_attribute *devattr, char *buf)
137 {
138         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
139
140         return sprintf(buf, "%s\n", gsp_sensors[attr->index].name);
141 }
142
143 static ssize_t store_fan(struct device *dev,
144                         struct device_attribute *devattr, const char *buf, size_t count)
145 {
146         u16 val;
147         struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
148         struct i2c_client *client = to_i2c_client(dev);
149         val = simple_strtoul(buf, NULL, 10);
150         gsp_write(client, gsp_sensors[attr->index].reg, val);
151         return count;
152 }
153
154 static SENSOR_DEVICE_ATTR(temp0_input, S_IRUGO, show_adc, NULL, 0);
155 static SENSOR_DEVICE_ATTR(temp0_label, S_IRUGO, show_label, NULL, 0);
156
157 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_adc, NULL, 1);
158 static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, 1);
159 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 2);
160 static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_label, NULL, 2);
161 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 3);
162 static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_label, NULL, 3);
163 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 4);
164 static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 4);
165 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 5);
166 static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, 5);
167 static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_adc, NULL, 6);
168 static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, 6);
169 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_adc, NULL, 7);
170 static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, 7);
171 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_adc, NULL, 8);
172 static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 8);
173 static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_adc, NULL, 9);
174 static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 9);
175 static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_adc, NULL, 10);
176 static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 10);
177 static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_adc, NULL, 11);
178 static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_label, NULL, 11);
179 static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_adc, NULL, 12);
180 static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_label, NULL, 12);
181 static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_adc, NULL, 13);
182 static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_label, NULL, 13);
183
184 static SENSOR_DEVICE_ATTR(fan0_point0, S_IRUGO | S_IWUSR, show_adc, store_fan, 14);
185 static SENSOR_DEVICE_ATTR(fan0_point1, S_IRUGO | S_IWUSR, show_adc, store_fan, 15);
186 static SENSOR_DEVICE_ATTR(fan0_point2, S_IRUGO | S_IWUSR, show_adc, store_fan, 16);
187 static SENSOR_DEVICE_ATTR(fan0_point3, S_IRUGO | S_IWUSR, show_adc, store_fan, 17);
188 static SENSOR_DEVICE_ATTR(fan0_point4, S_IRUGO | S_IWUSR, show_adc, store_fan, 18);
189 static SENSOR_DEVICE_ATTR(fan0_point5, S_IRUGO | S_IWUSR, show_adc, store_fan, 19);
190
191 static struct attribute *gsp_attributes[] = {
192         &sensor_dev_attr_temp0_input.dev_attr.attr,
193         &sensor_dev_attr_in0_input.dev_attr.attr,
194         &sensor_dev_attr_in1_input.dev_attr.attr,
195         &sensor_dev_attr_in2_input.dev_attr.attr,
196         &sensor_dev_attr_in3_input.dev_attr.attr,
197         &sensor_dev_attr_in4_input.dev_attr.attr,
198         &sensor_dev_attr_in5_input.dev_attr.attr,
199         &sensor_dev_attr_in6_input.dev_attr.attr,
200         &sensor_dev_attr_in7_input.dev_attr.attr,
201         &sensor_dev_attr_in8_input.dev_attr.attr,
202         &sensor_dev_attr_in9_input.dev_attr.attr,
203         &sensor_dev_attr_in10_input.dev_attr.attr,
204         &sensor_dev_attr_in11_input.dev_attr.attr,
205         &sensor_dev_attr_in12_input.dev_attr.attr,
206
207         &sensor_dev_attr_temp0_label.dev_attr.attr,
208         &sensor_dev_attr_in0_label.dev_attr.attr,
209         &sensor_dev_attr_in1_label.dev_attr.attr,
210         &sensor_dev_attr_in2_label.dev_attr.attr,
211         &sensor_dev_attr_in3_label.dev_attr.attr,
212         &sensor_dev_attr_in4_label.dev_attr.attr,
213         &sensor_dev_attr_in5_label.dev_attr.attr,
214         &sensor_dev_attr_in6_label.dev_attr.attr,
215         &sensor_dev_attr_in7_label.dev_attr.attr,
216         &sensor_dev_attr_in8_label.dev_attr.attr,
217         &sensor_dev_attr_in9_label.dev_attr.attr,
218         &sensor_dev_attr_in10_label.dev_attr.attr,
219         &sensor_dev_attr_in11_label.dev_attr.attr,
220         &sensor_dev_attr_in12_label.dev_attr.attr,
221
222         &sensor_dev_attr_fan0_point0.dev_attr.attr,
223         &sensor_dev_attr_fan0_point1.dev_attr.attr,
224         &sensor_dev_attr_fan0_point2.dev_attr.attr,
225         &sensor_dev_attr_fan0_point3.dev_attr.attr,
226         &sensor_dev_attr_fan0_point4.dev_attr.attr,
227         &sensor_dev_attr_fan0_point5.dev_attr.attr,
228         NULL
229 };
230
231
232 static int gsp_probe(struct i2c_client *client,
233                          const struct i2c_device_id *id)
234 {
235         struct i2c_adapter *adapter = client->adapter;
236         struct gsp_data *data;
237         int err;
238
239         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
240                                         I2C_FUNC_SMBUS_WORD_DATA)) {
241                 err = -EOPNOTSUPP;
242                 goto exit;
243         }
244
245         if (!(data = kzalloc(sizeof(struct gsp_data), GFP_KERNEL))) {
246                 err = -ENOMEM;
247                 goto exit;
248         }
249
250         i2c_set_clientdata(client, data);
251
252         data->type = id->driver_data;
253
254         switch (data->type) {
255         case 0:
256                 data->attrs.attrs = gsp_attributes;
257                 break;
258         }
259
260         dev_info(&client->dev, "%s chip found\n", client->name);
261
262         /* Register sysfs hooks */
263         if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs)))
264                 goto exit_free;
265
266         data->hwmon_dev = hwmon_device_register(&client->dev);
267         if (IS_ERR(data->hwmon_dev)) {
268                 err = PTR_ERR(data->hwmon_dev);
269                 goto exit_remove;
270         }
271
272         return 0;
273
274 exit_remove:
275         sysfs_remove_group(&client->dev.kobj, &data->attrs);
276 exit_free:
277         kfree(data);
278 exit:
279         return err;
280 }
281
282 static int gsp_remove(struct i2c_client *client)
283 {
284         struct gsp_data *data = i2c_get_clientdata(client);
285         hwmon_device_unregister(data->hwmon_dev);
286         sysfs_remove_group(&client->dev.kobj, &data->attrs);
287         kfree(data);
288         return 0;
289 }
290
291 static int __init gsp_init(void)
292 {
293         return i2c_add_driver(&gsp_driver);
294 }
295
296 static void __exit gsp_exit(void)
297 {
298         i2c_del_driver(&gsp_driver);
299 }
300
301 module_init(gsp_init);
302 module_exit(gsp_exit);
303
304 MODULE_AUTHOR("Chris Lang <clang@gateworks.com>");
305 MODULE_DESCRIPTION("GSC HWMON driver");
306 MODULE_LICENSE("GPL");
307 MODULE_VERSION(DRV_VERSION);
308