aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/f71882fg.c
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/hwmon/f71882fg.c
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/hwmon/f71882fg.c')
-rw-r--r--drivers/hwmon/f71882fg.c87
1 files changed, 84 insertions, 3 deletions
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;