35 #include <linux/module.h>
37 #include <linux/slab.h>
39 #include <linux/i2c.h>
47 #include <linux/watchdog.h>
53 static const unsigned short normal_i2c[] = { 0x73,
I2C_CLIENT_END };
58 MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
68 #define FSCHMD_REG_IDENT_0 0x00
69 #define FSCHMD_REG_IDENT_1 0x01
70 #define FSCHMD_REG_IDENT_2 0x02
71 #define FSCHMD_REG_REVISION 0x03
74 #define FSCHMD_REG_EVENT_STATE 0x04
75 #define FSCHMD_REG_CONTROL 0x05
77 #define FSCHMD_CONTROL_ALERT_LED 0x01
80 static const u8 FSCHMD_REG_WDOG_CONTROL[7] = {
81 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
82 static const u8 FSCHMD_REG_WDOG_STATE[7] = {
83 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
84 static const u8 FSCHMD_REG_WDOG_PRESET[7] = {
85 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
87 #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
88 #define FSCHMD_WDOG_CONTROL_STARTED 0x10
89 #define FSCHMD_WDOG_CONTROL_STOP 0x20
90 #define FSCHMD_WDOG_CONTROL_RESOLUTION 0x40
92 #define FSCHMD_WDOG_STATE_CARDRESET 0x02
95 static const u8 FSCHMD_REG_VOLT[7][6] = {
100 { 0x45, 0x42, 0x48 },
101 { 0x21, 0x20, 0x22 },
102 { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 },
105 static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
113 static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
115 { 0x55, 0x65, 0xb5 },
116 { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 },
117 { 0x55, 0x65, 0xa5, 0xb5 },
118 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 },
119 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 },
120 { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 },
124 static const u8 FSCHMD_REG_FAN_ACT[7][7] = {
125 { 0x0e, 0x6b, 0xab },
126 { 0x0e, 0x6b, 0xbb },
127 { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb },
128 { 0x0e, 0x6b, 0xab, 0xbb },
129 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb },
130 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb },
131 { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 },
135 static const u8 FSCHMD_REG_FAN_STATE[7][7] = {
136 { 0x0d, 0x62, 0xa2 },
137 { 0x0d, 0x62, 0xb2 },
138 { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 },
139 { 0x0d, 0x62, 0xa2, 0xb2 },
140 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 },
141 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 },
142 { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 },
146 static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = {
147 { 0x0f, 0x6f, 0xaf },
148 { 0x0f, 0x6f, 0xbf },
149 { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf },
150 { 0x0f, 0x6f, 0xaf, 0xbf },
151 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf },
152 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf },
153 { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 },
156 static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 };
159 #define FSCHMD_FAN_ALARM 0x04
160 #define FSCHMD_FAN_NOT_PRESENT 0x08
161 #define FSCHMD_FAN_DISABLED 0x80
165 static const u8 FSCHMD_REG_TEMP_ACT[7][11] = {
166 { 0x64, 0x32, 0x35 },
167 { 0x64, 0x32, 0x35 },
168 { 0x64, 0xD0, 0x32, 0x35 },
169 { 0x64, 0x32, 0x35 },
170 { 0x70, 0x80, 0x90, 0xd0, 0xe0 },
171 { 0x70, 0x80, 0x90, 0xd0, 0xe0 },
172 { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8,
173 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 },
177 static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
178 { 0x71, 0x81, 0x91 },
179 { 0x71, 0x81, 0x91 },
180 { 0x71, 0xd1, 0x81, 0x91 },
181 { 0x71, 0x81, 0x91 },
182 { 0x71, 0x81, 0x91, 0xd1, 0xe1 },
183 { 0x71, 0x81, 0x91, 0xd1, 0xe1 },
184 { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9,
185 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
195 static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
197 { 0x76, 0x86, 0x96 },
198 { 0x76, 0xd6, 0x86, 0x96 },
199 { 0x76, 0x86, 0x96 },
200 { 0x76, 0x86, 0x96, 0xd6, 0xe6 },
201 { 0x76, 0x86, 0x96, 0xd6, 0xe6 },
202 { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa,
203 0xba, 0xca, 0xda, 0xea, 0xfa },
216 static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
219 #define FSCHMD_TEMP_WORKING 0x01
220 #define FSCHMD_TEMP_ALERT 0x02
221 #define FSCHMD_TEMP_DISABLED 0x80
223 #define FSCHMD_TEMP_ALARM_MASK \
224 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
258 .probe = fschmd_probe,
259 .remove = fschmd_remove,
260 .id_table = fschmd_id,
261 .detect = fschmd_detect,
262 .address_list = normal_i2c,
307 static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
308 static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
309 static int dmi_vref = -1;
324 static void fschmd_release_resources(
struct kref *ref)
337 const int max_reading[3] = { 14200, 6600, 3300 };
342 return sprintf(buf,
"%d\n", (data->
volt[index] * dmi_vref *
343 dmi_mult[index]) / 255 + dmi_offset[index]);
346 max_reading[index] + 128) / 255);
350 #define TEMP_FROM_REG(val) (((val) - 128) * 1000)
356 struct fschmd_data *data = fschmd_update_device(dev);
365 struct fschmd_data *data = fschmd_update_device(dev);
371 *devattr,
const char *buf,
size_t count)
378 err = kstrtol(buf, 10, &v);
382 v = SENSORS_LIMIT(v / 1000, -128, 127) + 128;
386 FSCHMD_REG_TEMP_LIMIT[data->
kind][index], v);
397 struct fschmd_data *data = fschmd_update_device(dev);
410 struct fschmd_data *data = fschmd_update_device(dev);
413 FSCHMD_TEMP_ALARM_MASK)
420 #define RPM_FROM_REG(val) ((val) * 60)
426 struct fschmd_data *data = fschmd_update_device(dev);
435 struct fschmd_data *data = fschmd_update_device(dev);
442 *devattr,
const char *buf,
size_t count)
451 err = kstrtoul(buf, 10, &v);
466 dev_err(dev,
"fan_div value %lu not supported. "
467 "Choose one of 2, 4 or 8!\n", v);
474 FSCHMD_REG_FAN_RIPPLE[data->
kind][index]);
481 FSCHMD_REG_FAN_RIPPLE[data->
kind][index], reg);
494 struct fschmd_data *data = fschmd_update_device(dev);
506 struct fschmd_data *data = fschmd_update_device(dev);
519 struct fschmd_data *data = fschmd_update_device(dev);
526 return sprintf(buf,
"%d\n", val);
537 err = kstrtoul(buf, 10, &v);
543 v = SENSORS_LIMIT(v, 128, 255);
544 v = (v - 128) * 2 + 1;
550 FSCHMD_REG_FAN_MIN[data->
kind][index], v);
566 struct fschmd_data *data = fschmd_update_device(dev);
582 err = kstrtoul(buf, 10, &v);
604 static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led);
617 SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0),
621 SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1),
625 SENSOR_ATTR(temp3_max, 0644, show_temp_max, store_temp_max, 2),
629 SENSOR_ATTR(temp4_max, 0644, show_temp_max, store_temp_max, 3),
633 SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
637 SENSOR_ATTR(temp6_max, 0644, show_temp_max, store_temp_max, 5),
641 SENSOR_ATTR(temp7_max, 0644, show_temp_max, store_temp_max, 6),
645 SENSOR_ATTR(temp8_max, 0644, show_temp_max, store_temp_max, 7),
649 SENSOR_ATTR(temp9_max, 0644, show_temp_max, store_temp_max, 8),
653 SENSOR_ATTR(temp10_max, 0644, show_temp_max, store_temp_max, 9),
657 SENSOR_ATTR(temp11_max, 0644, show_temp_max, store_temp_max, 10),
664 SENSOR_ATTR(fan1_div, 0644, show_fan_div, store_fan_div, 0),
667 SENSOR_ATTR(pwm1_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
668 store_pwm_auto_point1_pwm, 0),
670 SENSOR_ATTR(fan2_div, 0644, show_fan_div, store_fan_div, 1),
673 SENSOR_ATTR(pwm2_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
674 store_pwm_auto_point1_pwm, 1),
676 SENSOR_ATTR(fan3_div, 0644, show_fan_div, store_fan_div, 2),
679 SENSOR_ATTR(pwm3_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
680 store_pwm_auto_point1_pwm, 2),
682 SENSOR_ATTR(fan4_div, 0644, show_fan_div, store_fan_div, 3),
685 SENSOR_ATTR(pwm4_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
686 store_pwm_auto_point1_pwm, 3),
688 SENSOR_ATTR(fan5_div, 0644, show_fan_div, store_fan_div, 4),
691 SENSOR_ATTR(pwm5_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
692 store_pwm_auto_point1_pwm, 4),
694 SENSOR_ATTR(fan6_div, 0644, show_fan_div, store_fan_div, 5),
697 SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
698 store_pwm_auto_point1_pwm, 5),
700 SENSOR_ATTR(fan7_div, 0644, show_fan_div, store_fan_div, 6),
703 SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
704 store_pwm_auto_point1_pwm, 6),
712 static int watchdog_set_timeout(
struct fschmd_data *data,
int timeout)
723 if (timeout < resolution || timeout > (resolution * 255))
744 FSCHMD_REG_WDOG_CONTROL[data->
kind],
754 static int watchdog_get_timeout(
struct fschmd_data *data)
768 static int watchdog_trigger(
struct fschmd_data *data)
780 FSCHMD_REG_WDOG_CONTROL[data->
kind],
803 FSCHMD_REG_WDOG_CONTROL[data->
kind],
831 if (!watchdog_is_open)
832 kref_get(&data->
kref);
835 if (watchdog_is_open)
839 watchdog_trigger(data);
845 static int watchdog_release(
struct inode *inode,
struct file *filp)
853 watchdog_trigger(data);
854 dev_crit(&data->
client->dev,
855 "unexpected close, not stopping watchdog!\n");
861 kref_put(&data->
kref, fschmd_release_resources);
867 static ssize_t watchdog_write(
struct file *filp,
const char __user *buf,
868 size_t count, loff_t *
offset)
880 for (i = 0; i !=
count; i++) {
888 ret = watchdog_trigger(data);
895 static long watchdog_ioctl(
struct file *filp,
unsigned int cmd,
901 .identity =
"FSC watchdog"
911 if (
copy_to_user((
void __user *)arg, &ident,
sizeof(ident)))
916 ret =
put_user(0, (
int __user *)arg);
923 ret =
put_user(0, (
int __user *)arg);
927 ret = watchdog_trigger(data);
931 i = watchdog_get_timeout(data);
932 ret =
put_user(i, (
int __user *)arg);
936 if (
get_user(i, (
int __user *)arg)) {
940 ret = watchdog_set_timeout(data, i);
942 ret =
put_user(ret, (
int __user *)arg);
946 if (
get_user(i, (
int __user *)arg)) {
952 ret = watchdog_stop(data);
954 ret = watchdog_trigger(data);
968 .open = watchdog_open,
969 .release = watchdog_release,
970 .write = watchdog_write,
971 .unlocked_ioctl = watchdog_ioctl,
985 int i,
mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
993 u8 *dmi_data = (
u8 *)header;
996 if (header->
type != 185)
1003 if (header->
length < 5 || dmi_data[4] != 19)
1011 for (i = 6; (i + 4) < header->
length; i += 5) {
1013 if (dmi_data[i] >= 1 && dmi_data[i] <= 3) {
1015 const int shuffle[3] = { 1, 0, 2 };
1016 int in = shuffle[dmi_data[
i] - 1];
1019 if (found & (1 << in))
1022 mult[
in] = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
1023 offset[
in] = dmi_data[i + 3] | (dmi_data[i + 4] << 8);
1029 if (dmi_data[i] == 7) {
1034 vref = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
1040 if (found == 0x0F) {
1041 for (i = 0; i < 3; i++) {
1042 dmi_mult[
i] = mult[
i] * 10;
1043 dmi_offset[
i] = offset[
i] * 10;
1050 dmi_mult[3] = dmi_mult[2];
1051 dmi_mult[4] = dmi_mult[1];
1052 dmi_mult[5] = dmi_mult[2];
1053 dmi_offset[3] = dmi_offset[2];
1054 dmi_offset[4] = dmi_offset[1];
1055 dmi_offset[5] = dmi_offset[2];
1078 else if (!
strcmp(
id,
"HER"))
1080 else if (!
strcmp(
id,
"SCY"))
1082 else if (!
strcmp(
id,
"HRC"))
1084 else if (!
strcmp(
id,
"HMD"))
1086 else if (!
strcmp(
id,
"HDS"))
1088 else if (!
strcmp(
id,
"SYL"))
1098 static int fschmd_probe(
struct i2c_client *client,
1102 const char *
const names[7] = {
"Poseidon",
"Hermes",
"Scylla",
1103 "Heracles",
"Heimdall",
"Hades",
"Syleus" };
1104 const int watchdog_minors[] = {
WATCHDOG_MINOR, 212, 213, 214, 215 };
1106 enum chips kind =
id->driver_data;
1112 i2c_set_clientdata(client, data);
1115 INIT_LIST_HEAD(&data->
list);
1116 kref_init(&data->
kref);
1136 if ((kind ==
fscher || kind >=
fschrc) && dmi_vref == -1) {
1138 if (dmi_vref == -1) {
1140 "Couldn't get voltage scaling factors from "
1141 "BIOS DMI table, using builtin defaults\n");
1151 FSCHMD_REG_WDOG_CONTROL[data->
kind]);
1153 FSCHMD_REG_WDOG_STATE[data->
kind]);
1155 FSCHMD_REG_WDOG_PRESET[data->
kind]);
1161 for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->
kind]; i++) {
1168 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->
kind] * 4); i++) {
1178 FSCHMD_REG_TEMP_STATE
1179 [data->
kind][i / 4]);
1190 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->
kind] * 5); i++) {
1194 "pwm3_auto_point1_pwm"))
1201 FSCHMD_REG_FAN_STATE
1202 [data->
kind][i / 5]);
1226 for (i = 0; i <
ARRAY_SIZE(watchdog_minors); i++) {
1229 "watchdog%c", (i == 0) ?
'\0' : (
'0' + i));
1239 "Registering watchdog chardev: %d\n", err);
1243 list_add(&data->
list, &watchdog_data_list);
1244 watchdog_set_timeout(data, 60);
1246 "Registered watchdog chardev major 10, minor: %d\n",
1247 watchdog_minors[i]);
1252 dev_warn(&client->
dev,
"Couldn't register watchdog chardev "
1253 "(due to no free minor)\n");
1257 dev_info(&client->
dev,
"Detected FSC %s chip, revision: %d\n",
1263 fschmd_remove(client);
1267 static int fschmd_remove(
struct i2c_client *client)
1269 struct fschmd_data *data = i2c_get_clientdata(client);
1277 "i2c client detached with watchdog open! "
1278 "Stopping watchdog.\n");
1279 watchdog_stop(data);
1298 for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->
kind]); i++)
1300 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->
kind] * 4); i++)
1303 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->
kind] * 5); i++)
1308 kref_put(&data->
kref, fschmd_release_resources);
1317 struct fschmd_data *data = i2c_get_clientdata(client);
1324 for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->
kind]; i++) {
1326 FSCHMD_REG_TEMP_ACT[data->
kind][i]);
1328 FSCHMD_REG_TEMP_STATE[data->
kind][i]);
1331 if (FSCHMD_REG_TEMP_LIMIT[data->
kind][i])
1334 FSCHMD_REG_TEMP_LIMIT[data->
kind][i]);
1341 FSCHMD_TEMP_ALARM_MASK &&
1344 FSCHMD_REG_TEMP_STATE[data->
kind][i],
1348 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->
kind]; i++) {
1350 FSCHMD_REG_FAN_ACT[data->
kind][i]);
1352 FSCHMD_REG_FAN_STATE[data->
kind][i]);
1354 FSCHMD_REG_FAN_RIPPLE[data->
kind][i]);
1357 if (FSCHMD_REG_FAN_MIN[data->
kind][i])
1360 FSCHMD_REG_FAN_MIN[data->
kind][i]);
1366 FSCHMD_REG_FAN_STATE[data->
kind][i],
1370 for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->
kind]; i++)
1372 FSCHMD_REG_VOLT[data->
kind][i]);
1387 "and Syleus driver");