kernel: move the gateworks system controller driver to an out-of-tree package
[openwrt/staging/lynxis.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