aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-05-25 14:43:32 -0400
committerJean Delvare <khali@endymion.delvare>2011-05-25 14:43:32 -0400
commit629c58bac082ae091e518187d63249fa7e9f796f (patch)
treef5b754d8fe64c8a819c89989b72c438d330c05ee /drivers
parent4d53811a28090b7583bb68fda294e0f009679770 (diff)
hwmon: (f71882fg) Add support for F71808A
Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/f71882fg.c87
2 files changed, 85 insertions, 4 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 9ebdb0da7f7c..a620a760397d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -329,7 +329,7 @@ config SENSORS_F71882FG
329 If you say yes here you get support for hardware monitoring 329 If you say yes here you get support for hardware monitoring
330 features of many Fintek Super-I/O (LPC) chips. The currently 330 features of many Fintek Super-I/O (LPC) chips. The currently
331 supported chips are: 331 supported chips are:
332 F71808E 332 F71808E/A
333 F71858FG 333 F71858FG
334 F71862FG 334 F71862FG
335 F71863FG 335 F71863FG
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 16330db2bcdc..a4a94a096c90 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -48,6 +48,7 @@
48 48
49#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 49#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
50#define SIO_F71808E_ID 0x0901 /* Chipset ID */ 50#define SIO_F71808E_ID 0x0901 /* Chipset ID */
51#define SIO_F71808A_ID 0x1001 /* Chipset ID */
51#define SIO_F71858_ID 0x0507 /* Chipset ID */ 52#define SIO_F71858_ID 0x0507 /* Chipset ID */
52#define SIO_F71862_ID 0x0601 /* Chipset ID */ 53#define SIO_F71862_ID 0x0601 /* Chipset ID */
53#define SIO_F71869_ID 0x0814 /* Chipset ID */ 54#define SIO_F71869_ID 0x0814 /* Chipset ID */
@@ -107,11 +108,12 @@ static unsigned short force_id;
107module_param(force_id, ushort, 0); 108module_param(force_id, ushort, 0);
108MODULE_PARM_DESC(force_id, "Override the detected device ID"); 109MODULE_PARM_DESC(force_id, "Override the detected device ID");
109 110
110enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg, 111enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
111 f71889ed, f71889a, f8000, f81865f }; 112 f71889ed, f71889a, f8000, f81865f };
112 113
113static const char *f71882fg_names[] = { 114static const char *f71882fg_names[] = {
114 "f71808e", 115 "f71808e",
116 "f71808a",
115 "f71858fg", 117 "f71858fg",
116 "f71862fg", 118 "f71862fg",
117 "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ 119 "f71869", /* Both f71869f and f71869e, reg. compatible and same id */
@@ -125,6 +127,7 @@ static const char *f71882fg_names[] = {
125 127
126static const char f71882fg_has_in[][F71882FG_MAX_INS] = { 128static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
127 [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 }, 129 [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
130 [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
128 [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 }, 131 [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
129 [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 132 [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
130 [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 133 [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
@@ -138,6 +141,7 @@ static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
138 141
139static const char f71882fg_has_in1_alarm[] = { 142static const char f71882fg_has_in1_alarm[] = {
140 [f71808e] = 0, 143 [f71808e] = 0,
144 [f71808a] = 0,
141 [f71858fg] = 0, 145 [f71858fg] = 0,
142 [f71862fg] = 0, 146 [f71862fg] = 0,
143 [f71869] = 0, 147 [f71869] = 0,
@@ -151,6 +155,7 @@ static const char f71882fg_has_in1_alarm[] = {
151 155
152static const char f71882fg_fan_has_beep[] = { 156static const char f71882fg_fan_has_beep[] = {
153 [f71808e] = 0, 157 [f71808e] = 0,
158 [f71808a] = 0,
154 [f71858fg] = 0, 159 [f71858fg] = 0,
155 [f71862fg] = 1, 160 [f71862fg] = 1,
156 [f71869] = 1, 161 [f71869] = 1,
@@ -164,6 +169,7 @@ static const char f71882fg_fan_has_beep[] = {
164 169
165static const char f71882fg_nr_fans[] = { 170static const char f71882fg_nr_fans[] = {
166 [f71808e] = 3, 171 [f71808e] = 3,
172 [f71808a] = 2, /* +1 fan which is monitor + simple pwm only */
167 [f71858fg] = 3, 173 [f71858fg] = 3,
168 [f71862fg] = 3, 174 [f71862fg] = 3,
169 [f71869] = 3, 175 [f71869] = 3,
@@ -171,12 +177,13 @@ static const char f71882fg_nr_fans[] = {
171 [f71889fg] = 3, 177 [f71889fg] = 3,
172 [f71889ed] = 3, 178 [f71889ed] = 3,
173 [f71889a] = 3, 179 [f71889a] = 3,
174 [f8000] = 3, 180 [f8000] = 3, /* +1 fan which is monitor only */
175 [f81865f] = 2, 181 [f81865f] = 2,
176}; 182};
177 183
178static const char f71882fg_temp_has_beep[] = { 184static const char f71882fg_temp_has_beep[] = {
179 [f71808e] = 0, 185 [f71808e] = 0,
186 [f71808a] = 1,
180 [f71858fg] = 0, 187 [f71858fg] = 0,
181 [f71862fg] = 1, 188 [f71862fg] = 1,
182 [f71869] = 1, 189 [f71869] = 1,
@@ -190,6 +197,7 @@ static const char f71882fg_temp_has_beep[] = {
190 197
191static const char f71882fg_nr_temps[] = { 198static const char f71882fg_nr_temps[] = {
192 [f71808e] = 2, 199 [f71808e] = 2,
200 [f71808a] = 2,
193 [f71858fg] = 3, 201 [f71858fg] = 3,
194 [f71862fg] = 3, 202 [f71862fg] = 3,
195 [f71869] = 3, 203 [f71869] = 3,
@@ -314,6 +322,10 @@ static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
314 char *buf); 322 char *buf);
315static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, 323static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
316 const char *buf, size_t count); 324 const char *buf, size_t count);
325static ssize_t show_simple_pwm(struct device *dev,
326 struct device_attribute *devattr, char *buf);
327static ssize_t store_simple_pwm(struct device *dev,
328 struct device_attribute *devattr, const char *buf, size_t count);
317static ssize_t show_pwm_enable(struct device *dev, 329static ssize_t show_pwm_enable(struct device *dev,
318 struct device_attribute *devattr, char *buf); 330 struct device_attribute *devattr, char *buf);
319static ssize_t store_pwm_enable(struct device *dev, 331static ssize_t store_pwm_enable(struct device *dev,
@@ -563,6 +575,14 @@ static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
563 show_pwm_interpolate, store_pwm_interpolate, 0, 3), 575 show_pwm_interpolate, store_pwm_interpolate, 0, 3),
564} }; 576} };
565 577
578/* Attr for the third fan of the f71808a, which only has manual pwm */
579static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {
580 SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
581 SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
582 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,
583 show_simple_pwm, store_simple_pwm, 0, 2),
584};
585
566/* Attr for models which can beep on Fan alarm */ 586/* Attr for models which can beep on Fan alarm */
567static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { 587static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
568 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 588 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
@@ -1246,7 +1266,13 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
1246 data->pwm[nr] = 1266 data->pwm[nr] =
1247 f71882fg_read8(data, F71882FG_REG_PWM(nr)); 1267 f71882fg_read8(data, F71882FG_REG_PWM(nr));
1248 } 1268 }
1249 /* The f8000 can monitor 1 more fan, but has no pwm for it */ 1269 /* Some models have 1 more fan with limited capabilities */
1270 if (data->type == f71808a) {
1271 data->fan[2] = f71882fg_read16(data,
1272 F71882FG_REG_FAN(2));
1273 data->pwm[2] = f71882fg_read8(data,
1274 F71882FG_REG_PWM(2));
1275 }
1250 if (data->type == f8000) 1276 if (data->type == f8000)
1251 data->fan[3] = f71882fg_read16(data, 1277 data->fan[3] = f71882fg_read16(data,
1252 F71882FG_REG_FAN(3)); 1278 F71882FG_REG_FAN(3));
@@ -1736,6 +1762,38 @@ leave:
1736 return count; 1762 return count;
1737} 1763}
1738 1764
1765static ssize_t show_simple_pwm(struct device *dev,
1766 struct device_attribute *devattr, char *buf)
1767{
1768 struct f71882fg_data *data = f71882fg_update_device(dev);
1769 int val, nr = to_sensor_dev_attr_2(devattr)->index;
1770
1771 val = data->pwm[nr];
1772 return sprintf(buf, "%d\n", val);
1773}
1774
1775static ssize_t store_simple_pwm(struct device *dev,
1776 struct device_attribute *devattr,
1777 const char *buf, size_t count)
1778{
1779 struct f71882fg_data *data = dev_get_drvdata(dev);
1780 int err, nr = to_sensor_dev_attr_2(devattr)->index;
1781 long val;
1782
1783 err = strict_strtol(buf, 10, &val);
1784 if (err)
1785 return err;
1786
1787 val = SENSORS_LIMIT(val, 0, 255);
1788
1789 mutex_lock(&data->update_lock);
1790 f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
1791 data->pwm[nr] = val;
1792 mutex_unlock(&data->update_lock);
1793
1794 return count;
1795}
1796
1739static ssize_t show_pwm_enable(struct device *dev, 1797static ssize_t show_pwm_enable(struct device *dev,
1740 struct device_attribute *devattr, char *buf) 1798 struct device_attribute *devattr, char *buf)
1741{ 1799{
@@ -2183,6 +2241,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2183 if (start_reg & 0x02) { 2241 if (start_reg & 0x02) {
2184 switch (data->type) { 2242 switch (data->type) {
2185 case f71808e: 2243 case f71808e:
2244 case f71808a:
2186 case f71869: 2245 case f71869:
2187 /* These always have signed auto point temps */ 2246 /* These always have signed auto point temps */
2188 data->auto_point_temp_signed = 1; 2247 data->auto_point_temp_signed = 1;
@@ -2244,6 +2303,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2244 2303
2245 switch (data->type) { 2304 switch (data->type) {
2246 case f71808e: 2305 case f71808e:
2306 case f71808a:
2247 case f71869: 2307 case f71869:
2248 case f71889fg: 2308 case f71889fg:
2249 case f71889ed: 2309 case f71889ed:
@@ -2269,6 +2329,16 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
2269 } 2329 }
2270 2330
2271 switch (data->type) { 2331 switch (data->type) {
2332 case f71808a:
2333 err = f71882fg_create_sysfs_files(pdev,
2334 &fxxxx_auto_pwm_attr[0][0],
2335 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2336 if (err)
2337 goto exit_unregister_sysfs;
2338 err = f71882fg_create_sysfs_files(pdev,
2339 f71808a_fan3_attr,
2340 ARRAY_SIZE(f71808a_fan3_attr));
2341 break;
2272 case f71862fg: 2342 case f71862fg:
2273 err = f71882fg_create_sysfs_files(pdev, 2343 err = f71882fg_create_sysfs_files(pdev,
2274 f71862fg_auto_pwm_attr, 2344 f71862fg_auto_pwm_attr,
@@ -2386,6 +2456,14 @@ static int f71882fg_remove(struct platform_device *pdev)
2386 } 2456 }
2387 2457
2388 switch (data->type) { 2458 switch (data->type) {
2459 case f71808a:
2460 f71882fg_remove_sysfs_files(pdev,
2461 &fxxxx_auto_pwm_attr[0][0],
2462 ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
2463 f71882fg_remove_sysfs_files(pdev,
2464 f71808a_fan3_attr,
2465 ARRAY_SIZE(f71808a_fan3_attr));
2466 break;
2389 case f71862fg: 2467 case f71862fg:
2390 f71882fg_remove_sysfs_files(pdev, 2468 f71882fg_remove_sysfs_files(pdev,
2391 f71862fg_auto_pwm_attr, 2469 f71862fg_auto_pwm_attr,
@@ -2438,6 +2516,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
2438 case SIO_F71808E_ID: 2516 case SIO_F71808E_ID:
2439 sio_data->type = f71808e; 2517 sio_data->type = f71808e;
2440 break; 2518 break;
2519 case SIO_F71808A_ID:
2520 sio_data->type = f71808a;
2521 break;
2441 case SIO_F71858_ID: 2522 case SIO_F71858_ID:
2442 sio_data->type = f71858fg; 2523 sio_data->type = f71858fg;
2443 break; 2524 break;