The first patch will add Fintek F81866/F71868 SuperIO
with H/W monitor function to f71882fg.c
But some F81866 functional address is differ from F71882fg.
The following 2 patches will fix this problem.
Peter Hung (3):
hwmon:f71882fg add f81866/f71868 SuperIO support
hwmon:f71882fg fix f81866a temp/beep setting
hwmon:f71882fg fix f81866a voltage protection
drivers/hwmon/f71882fg.c | 160 ++++++++++++++++++++++++++++++++++++++---------
1 file changed, 129 insertions(+), 31 deletions(-)
--
1.9.1
Add New Fintek SuperIO F81866(0x1010) & F71868(0x1106)
with H/W Monitor functions.
Signed-off-by: Peter Hung <[email protected]>
---
drivers/hwmon/f71882fg.c | 50 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 2e5c6f4..10bc8b3 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -59,6 +59,8 @@
#define SIO_F71889A_ID 0x1005 /* Chipset ID */
#define SIO_F8000_ID 0x0581 /* Chipset ID */
#define SIO_F81865_ID 0x0704 /* Chipset ID */
+#define SIO_F81866_ID 0x1010 /* Chipset ID */
+#define SIO_F71868_ID 0x1106 /* Chipset ID */
#define REGION_LENGTH 8
#define ADDR_REG_OFFSET 5
@@ -101,7 +103,7 @@
#define F71882FG_REG_START 0x01
-#define F71882FG_MAX_INS 9
+#define F71882FG_MAX_INS 10
#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
@@ -110,7 +112,7 @@ module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
- f71889fg, f71889ed, f71889a, f8000, f81865f };
+ f71889fg, f71889ed, f71889a, f8000, f81865f, f81866a, f71868a };
static const char *const f71882fg_names[] = {
"f71808e",
@@ -125,21 +127,25 @@ static const char *const f71882fg_names[] = {
"f71889a",
"f8000",
"f81865f",
+ "f81866a",
+ "f71868a",
};
static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
- [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
- [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
- [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
- [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
- [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 0 },
+ [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 },
+ [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+ [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+ [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ [f81866a] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ [f71868a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};
static const char f71882fg_has_in1_alarm[] = {
@@ -155,6 +161,8 @@ static const char f71882fg_has_in1_alarm[] = {
[f71889a] = 1,
[f8000] = 0,
[f81865f] = 1,
+ [f81866a] = 1,
+ [f71868a] = 0,
};
static const char f71882fg_fan_has_beep[] = {
@@ -170,6 +178,8 @@ static const char f71882fg_fan_has_beep[] = {
[f71889a] = 1,
[f8000] = 0,
[f81865f] = 1,
+ [f81866a] = 1,
+ [f71868a] = 1,
};
static const char f71882fg_nr_fans[] = {
@@ -185,6 +195,8 @@ static const char f71882fg_nr_fans[] = {
[f71889a] = 3,
[f8000] = 3, /* +1 fan which is monitor only */
[f81865f] = 2,
+ [f81866a] = 3,
+ [f71868a] = 3,
};
static const char f71882fg_temp_has_beep[] = {
@@ -200,6 +212,8 @@ static const char f71882fg_temp_has_beep[] = {
[f71889a] = 1,
[f8000] = 0,
[f81865f] = 1,
+ [f81866a] = 1,
+ [f71868a] = 1,
};
static const char f71882fg_nr_temps[] = {
@@ -215,6 +229,8 @@ static const char f71882fg_nr_temps[] = {
[f71889a] = 3,
[f8000] = 3,
[f81865f] = 2,
+ [f81866a] = 3,
+ [f71868a] = 3,
};
static struct platform_device *f71882fg_pdev;
@@ -2575,6 +2591,12 @@ static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)
case SIO_F81865_ID:
sio_data->type = f81865f;
break;
+ case SIO_F81866_ID:
+ sio_data->type = f81866a;
+ break;
+ case SIO_F71868_ID:
+ sio_data->type = f71868a;
+ break;
default:
pr_info("Unsupported Fintek device: %04x\n",
(unsigned int)devid);
--
1.9.1
The temperature value of Fintek F81866 is the same with
f71882fg. It located with 0x6c + 2*(nr), others located
with 0x6c + 2*(nr+1). We change the rule in f71882fg_probe(),
If type = f71858fg/f8000/f81866a. the temp_start will set to 0,
others are 1.
The F81866 over-temperature beep setting is not the same with
f71882fg too. They are using the same address 63H, but F81866 is
using bit 0/1/2 & 4/5/6, others are using bit 1/2/3 & 5/6/7,
So we copy from fxxxx_temp_beep_attr[] to f81866_temp_beep_attr
and change bit setting.
Signed-off-by: Peter Hung <[email protected]>
---
drivers/hwmon/f71882fg.c | 60 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 10bc8b3..e1ba586 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -506,6 +506,23 @@ static struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { {
store_temp_beep, 0, 7),
} };
+static struct sensor_device_attribute_2 f81866_temp_beep_attr[3][2] = { {
+ SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 0),
+ SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 4),
+}, {
+ SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 1),
+ SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 5),
+}, {
+ SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 2),
+ SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
+ store_temp_beep, 0, 6),
+} };
+
/*
* Temp attr for the f8000
* Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
@@ -2286,6 +2303,7 @@ static int f71882fg_probe(struct platform_device *pdev)
int nr_fans = f71882fg_nr_fans[sio_data->type];
int nr_temps = f71882fg_nr_temps[sio_data->type];
int err, i;
+ int size;
u8 start_reg, reg;
data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data),
@@ -2296,7 +2314,8 @@ static int f71882fg_probe(struct platform_device *pdev)
data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
data->type = sio_data->type;
data->temp_start =
- (data->type == f71858fg || data->type == f8000) ? 0 : 1;
+ (data->type == f71858fg || data->type == f8000 ||
+ data->type == f81866a) ? 0 : 1;
mutex_init(&data->update_lock);
platform_set_drvdata(pdev, data);
@@ -2338,6 +2357,11 @@ static int f71882fg_probe(struct platform_device *pdev)
f8000_temp_attr,
ARRAY_SIZE(f8000_temp_attr));
break;
+ case f81866a:
+ err = f71882fg_create_sysfs_files(pdev,
+ f71858fg_temp_attr,
+ ARRAY_SIZE(f71858fg_temp_attr));
+ break;
default:
err = f71882fg_create_sysfs_files(pdev,
&fxxxx_temp_attr[0][0],
@@ -2347,10 +2371,18 @@ static int f71882fg_probe(struct platform_device *pdev)
goto exit_unregister_sysfs;
if (f71882fg_temp_has_beep[data->type]) {
- err = f71882fg_create_sysfs_files(pdev,
- &fxxxx_temp_beep_attr[0][0],
- ARRAY_SIZE(fxxxx_temp_beep_attr[0])
- * nr_temps);
+ if (data->type == f81866a) {
+ size = ARRAY_SIZE(f81866_temp_beep_attr[0]);
+ err = f71882fg_create_sysfs_files(pdev,
+ &f81866_temp_beep_attr[0][0],
+ size * nr_temps);
+
+ } else {
+ size = ARRAY_SIZE(fxxxx_temp_beep_attr[0];
+ err = f71882fg_create_sysfs_files(pdev,
+ &fxxxx_temp_beep_attr[0][0],
+ size * nr_temps);
+ }
if (err)
goto exit_unregister_sysfs;
}
@@ -2467,15 +2499,27 @@ static int f71882fg_remove(struct platform_device *pdev)
f8000_temp_attr,
ARRAY_SIZE(f8000_temp_attr));
break;
+ case f81866a:
+ f71882fg_remove_sysfs_files(pdev,
+ f71858fg_temp_attr,
+ ARRAY_SIZE(f71858fg_temp_attr));
+ break;
default:
f71882fg_remove_sysfs_files(pdev,
&fxxxx_temp_attr[0][0],
ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
}
if (f71882fg_temp_has_beep[data->type]) {
- f71882fg_remove_sysfs_files(pdev,
- &fxxxx_temp_beep_attr[0][0],
- ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
+ if (data->type == f81866a)
+ f71882fg_remove_sysfs_files(pdev,
+ &f81866_temp_beep_attr[0][0],
+ ARRAY_SIZE(f81866_temp_beep_attr[0])
+ * nr_temps);
+ else
+ f71882fg_remove_sysfs_files(pdev,
+ &fxxxx_temp_beep_attr[0][0],
+ ARRAY_SIZE(fxxxx_temp_beep_attr[0])
+ * nr_temps);
}
for (i = 0; i < F71882FG_MAX_INS; i++) {
--
1.9.1
The f81866a voltage-1 protector(VIN1) address
is differ from f71882.
f71882 status:12H, beep:13H, v-high:32H
f81866a status:16H, beep:17H, v-high:3aH
Signed-off-by: Peter Hung <[email protected]>
---
drivers/hwmon/f71882fg.c | 50 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 41 insertions(+), 9 deletions(-)
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index e1ba586..946ac25 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -71,6 +71,10 @@
#define F71882FG_REG_IN(nr) (0x20 + (nr))
#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */
+#define F81866_REG_IN_STATUS 0x16 /* F81866 only */
+#define F81866_REG_IN_BEEP 0x17 /* F81866 only */
+#define F81866_REG_IN1_HIGH 0x3a /* F81866 only */
+
#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
@@ -1203,10 +1207,21 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
if (time_after(jiffies, data->last_limits + 60 * HZ) ||
!data->valid) {
if (f71882fg_has_in1_alarm[data->type]) {
- data->in1_max =
- f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
- data->in_beep =
- f71882fg_read8(data, F71882FG_REG_IN_BEEP);
+ if (data->type == f81866a) {
+ data->in1_max =
+ f71882fg_read8(data,
+ F81866_REG_IN1_HIGH);
+ data->in_beep =
+ f71882fg_read8(data,
+ F81866_REG_IN_BEEP);
+ } else {
+ data->in1_max =
+ f71882fg_read8(data,
+ F71882FG_REG_IN1_HIGH);
+ data->in_beep =
+ f71882fg_read8(data,
+ F71882FG_REG_IN_BEEP);
+ }
}
/* Get High & boundary temps*/
@@ -1330,9 +1345,16 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
data->fan[3] = f71882fg_read16(data,
F71882FG_REG_FAN(3));
- if (f71882fg_has_in1_alarm[data->type])
- data->in_status = f71882fg_read8(data,
+ if (f71882fg_has_in1_alarm[data->type]) {
+ if (data->type == f81866a)
+ data->in_status = f71882fg_read8(data,
+ F81866_REG_IN_STATUS);
+
+ else
+ data->in_status = f71882fg_read8(data,
F71882FG_REG_IN_STATUS);
+ }
+
for (nr = 0; nr < F71882FG_MAX_INS; nr++)
if (f71882fg_has_in[data->type][nr])
data->in[nr] = f71882fg_read8(data,
@@ -1473,7 +1495,10 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute
val = clamp_val(val, 0, 255);
mutex_lock(&data->update_lock);
- f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
+ if (data->type == f81866a)
+ f71882fg_write8(data, F81866_REG_IN1_HIGH, val);
+ else
+ f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
data->in1_max = val;
mutex_unlock(&data->update_lock);
@@ -1504,13 +1529,20 @@ static ssize_t store_in_beep(struct device *dev, struct device_attribute
return err;
mutex_lock(&data->update_lock);
- data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
+ if (data->type == f81866a)
+ data->in_beep = f71882fg_read8(data, F81866_REG_IN_BEEP);
+ else
+ data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
+
if (val)
data->in_beep |= 1 << nr;
else
data->in_beep &= ~(1 << nr);
- f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
+ if (data->type == f81866a)
+ f71882fg_write8(data, F81866_REG_IN_BEEP, data->in_beep);
+ else
+ f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
mutex_unlock(&data->update_lock);
return count;
--
1.9.1
Hi Peter,
On 06/25/2015 12:30 AM, Peter Hung wrote:
> Add New Fintek SuperIO F81866(0x1010) & F71868(0x1106)
> with H/W Monitor functions.
>
> Signed-off-by: Peter Hung <[email protected]>
> ---
> drivers/hwmon/f71882fg.c | 50 ++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 36 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
> index 2e5c6f4..10bc8b3 100644
> --- a/drivers/hwmon/f71882fg.c
> +++ b/drivers/hwmon/f71882fg.c
> @@ -59,6 +59,8 @@
> #define SIO_F71889A_ID 0x1005 /* Chipset ID */
> #define SIO_F8000_ID 0x0581 /* Chipset ID */
> #define SIO_F81865_ID 0x0704 /* Chipset ID */
> +#define SIO_F81866_ID 0x1010 /* Chipset ID */
> +#define SIO_F71868_ID 0x1106 /* Chipset ID */
>
> #define REGION_LENGTH 8
> #define ADDR_REG_OFFSET 5
> @@ -101,7 +103,7 @@
>
> #define F71882FG_REG_START 0x01
>
> -#define F71882FG_MAX_INS 9
> +#define F71882FG_MAX_INS 10
>
> #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
>
> @@ -110,7 +112,7 @@ module_param(force_id, ushort, 0);
> MODULE_PARM_DESC(force_id, "Override the detected device ID");
>
> enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
> - f71889fg, f71889ed, f71889a, f8000, f81865f };
> + f71889fg, f71889ed, f71889a, f8000, f81865f, f81866a, f71868a };
>
Unless there is a special reason to not do so, please keep the chip IDs
in numeric order.
> static const char *const f71882fg_names[] = {
> "f71808e",
> @@ -125,21 +127,25 @@ static const char *const f71882fg_names[] = {
> "f71889a",
> "f8000",
> "f81865f",
> + "f81866a",
> + "f71868a",
Same here and everywhere else.
Thanks,
Guenter