Root/target/linux/generic/patches-3.3/880-gateworks_system_controller.patch

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

Archive Download this file



interactive