diff options
author | Hans de Goede <hdegoede@redhat.com> | 2009-03-30 15:46:45 -0400 |
---|---|---|
committer | Jean Delvare <khali@linux-fr.org> | 2009-03-30 15:46:45 -0400 |
commit | de15f093e666ccd542f6f7a0e3e917166a07ab44 (patch) | |
tree | ba0fb9235e3267812f2580306c27d7087d9fd7f3 | |
parent | c69ab2b78efbe388bb0fc5d885b718ff4668cceb (diff) |
hwmon: (fschmd) Add support for the FSC Hades IC
Add support for the Hades to the FSC hwmon driver.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/fschmd.c | 57 |
2 files changed, 36 insertions, 25 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 41e3f861c472..51ff9b3d7ea2 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -348,8 +348,8 @@ config SENSORS_FSCHMD | |||
348 | help | 348 | help |
349 | If you say yes here you get support for the following Fujitsu | 349 | If you say yes here you get support for the following Fujitsu |
350 | Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes, | 350 | Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes, |
351 | Heimdall, Heracles and Syleus including support for the integrated | 351 | Heimdall, Heracles, Hades and Syleus including support for the |
352 | watchdog. | 352 | integrated watchdog. |
353 | 353 | ||
354 | This is a merged driver for FSC sensor chips replacing the fscpos, | 354 | This is a merged driver for FSC sensor chips replacing the fscpos, |
355 | fscscy and fscher drivers and adding support for several other FSC | 355 | fscscy and fscher drivers and adding support for several other FSC |
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index ac515bd6b1e7..ea955edde87e 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes, | 21 | * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes, |
22 | * Scylla, Heracles, Heimdall and Syleus chips | 22 | * Scylla, Heracles, Heimdall, Hades and Syleus chips |
23 | * | 23 | * |
24 | * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6 | 24 | * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6 |
25 | * (candidate) fschmd drivers: | 25 | * (candidate) fschmd drivers: |
@@ -56,7 +56,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
56 | module_param(nowayout, int, 0); | 56 | module_param(nowayout, int, 0); |
57 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | 57 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" |
58 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 58 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
59 | I2C_CLIENT_INSMOD_6(fscpos, fscher, fscscy, fschrc, fschmd, fscsyl); | 59 | I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl); |
60 | 60 | ||
61 | /* | 61 | /* |
62 | * The FSCHMD registers and other defines | 62 | * The FSCHMD registers and other defines |
@@ -75,12 +75,12 @@ I2C_CLIENT_INSMOD_6(fscpos, fscher, fscscy, fschrc, fschmd, fscsyl); | |||
75 | #define FSCHMD_CONTROL_ALERT_LED 0x01 | 75 | #define FSCHMD_CONTROL_ALERT_LED 0x01 |
76 | 76 | ||
77 | /* watchdog */ | 77 | /* watchdog */ |
78 | static const u8 FSCHMD_REG_WDOG_CONTROL[6] = | 78 | static const u8 FSCHMD_REG_WDOG_CONTROL[7] = |
79 | { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28 }; | 79 | { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 }; |
80 | static const u8 FSCHMD_REG_WDOG_STATE[6] = | 80 | static const u8 FSCHMD_REG_WDOG_STATE[7] = |
81 | { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29 }; | 81 | { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 }; |
82 | static const u8 FSCHMD_REG_WDOG_PRESET[6] = | 82 | static const u8 FSCHMD_REG_WDOG_PRESET[7] = |
83 | { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a }; | 83 | { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a }; |
84 | 84 | ||
85 | #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 | 85 | #define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 |
86 | #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ | 86 | #define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ |
@@ -90,61 +90,66 @@ static const u8 FSCHMD_REG_WDOG_PRESET[6] = | |||
90 | #define FSCHMD_WDOG_STATE_CARDRESET 0x02 | 90 | #define FSCHMD_WDOG_STATE_CARDRESET 0x02 |
91 | 91 | ||
92 | /* voltages, weird order is to keep the same order as the old drivers */ | 92 | /* voltages, weird order is to keep the same order as the old drivers */ |
93 | static const u8 FSCHMD_REG_VOLT[6][6] = { | 93 | static const u8 FSCHMD_REG_VOLT[7][6] = { |
94 | { 0x45, 0x42, 0x48 }, /* pos */ | 94 | { 0x45, 0x42, 0x48 }, /* pos */ |
95 | { 0x45, 0x42, 0x48 }, /* her */ | 95 | { 0x45, 0x42, 0x48 }, /* her */ |
96 | { 0x45, 0x42, 0x48 }, /* scy */ | 96 | { 0x45, 0x42, 0x48 }, /* scy */ |
97 | { 0x45, 0x42, 0x48 }, /* hrc */ | 97 | { 0x45, 0x42, 0x48 }, /* hrc */ |
98 | { 0x45, 0x42, 0x48 }, /* hmd */ | 98 | { 0x45, 0x42, 0x48 }, /* hmd */ |
99 | { 0x21, 0x20, 0x22 }, /* hds */ | ||
99 | { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */ | 100 | { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */ |
100 | }; | 101 | }; |
101 | 102 | ||
102 | static const int FSCHMD_NO_VOLT_SENSORS[6] = { 3, 3, 3, 3, 3, 6 }; | 103 | static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 }; |
103 | 104 | ||
104 | /* minimum pwm at which the fan is driven (pwm can by increased depending on | 105 | /* minimum pwm at which the fan is driven (pwm can by increased depending on |
105 | the temp. Notice that for the scy some fans share there minimum speed. | 106 | the temp. Notice that for the scy some fans share there minimum speed. |
106 | Also notice that with the scy the sensor order is different than with the | 107 | Also notice that with the scy the sensor order is different than with the |
107 | other chips, this order was in the 2.4 driver and kept for consistency. */ | 108 | other chips, this order was in the 2.4 driver and kept for consistency. */ |
108 | static const u8 FSCHMD_REG_FAN_MIN[6][7] = { | 109 | static const u8 FSCHMD_REG_FAN_MIN[7][7] = { |
109 | { 0x55, 0x65 }, /* pos */ | 110 | { 0x55, 0x65 }, /* pos */ |
110 | { 0x55, 0x65, 0xb5 }, /* her */ | 111 | { 0x55, 0x65, 0xb5 }, /* her */ |
111 | { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */ | 112 | { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */ |
112 | { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */ | 113 | { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */ |
113 | { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */ | 114 | { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */ |
115 | { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hds */ | ||
114 | { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */ | 116 | { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */ |
115 | }; | 117 | }; |
116 | 118 | ||
117 | /* actual fan speed */ | 119 | /* actual fan speed */ |
118 | static const u8 FSCHMD_REG_FAN_ACT[6][7] = { | 120 | static const u8 FSCHMD_REG_FAN_ACT[7][7] = { |
119 | { 0x0e, 0x6b, 0xab }, /* pos */ | 121 | { 0x0e, 0x6b, 0xab }, /* pos */ |
120 | { 0x0e, 0x6b, 0xbb }, /* her */ | 122 | { 0x0e, 0x6b, 0xbb }, /* her */ |
121 | { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */ | 123 | { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */ |
122 | { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */ | 124 | { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */ |
123 | { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */ | 125 | { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */ |
126 | { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hds */ | ||
124 | { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */ | 127 | { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */ |
125 | }; | 128 | }; |
126 | 129 | ||
127 | /* fan status registers */ | 130 | /* fan status registers */ |
128 | static const u8 FSCHMD_REG_FAN_STATE[6][7] = { | 131 | static const u8 FSCHMD_REG_FAN_STATE[7][7] = { |
129 | { 0x0d, 0x62, 0xa2 }, /* pos */ | 132 | { 0x0d, 0x62, 0xa2 }, /* pos */ |
130 | { 0x0d, 0x62, 0xb2 }, /* her */ | 133 | { 0x0d, 0x62, 0xb2 }, /* her */ |
131 | { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */ | 134 | { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */ |
132 | { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */ | 135 | { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */ |
133 | { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */ | 136 | { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */ |
137 | { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hds */ | ||
134 | { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */ | 138 | { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */ |
135 | }; | 139 | }; |
136 | 140 | ||
137 | /* fan ripple / divider registers */ | 141 | /* fan ripple / divider registers */ |
138 | static const u8 FSCHMD_REG_FAN_RIPPLE[6][7] = { | 142 | static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = { |
139 | { 0x0f, 0x6f, 0xaf }, /* pos */ | 143 | { 0x0f, 0x6f, 0xaf }, /* pos */ |
140 | { 0x0f, 0x6f, 0xbf }, /* her */ | 144 | { 0x0f, 0x6f, 0xbf }, /* her */ |
141 | { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */ | 145 | { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */ |
142 | { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */ | 146 | { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */ |
143 | { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */ | 147 | { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */ |
148 | { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hds */ | ||
144 | { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */ | 149 | { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */ |
145 | }; | 150 | }; |
146 | 151 | ||
147 | static const int FSCHMD_NO_FAN_SENSORS[6] = { 3, 3, 6, 4, 5, 7 }; | 152 | static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 }; |
148 | 153 | ||
149 | /* Fan status register bitmasks */ | 154 | /* Fan status register bitmasks */ |
150 | #define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */ | 155 | #define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */ |
@@ -153,23 +158,25 @@ static const int FSCHMD_NO_FAN_SENSORS[6] = { 3, 3, 6, 4, 5, 7 }; | |||
153 | 158 | ||
154 | 159 | ||
155 | /* actual temperature registers */ | 160 | /* actual temperature registers */ |
156 | static const u8 FSCHMD_REG_TEMP_ACT[6][11] = { | 161 | static const u8 FSCHMD_REG_TEMP_ACT[7][11] = { |
157 | { 0x64, 0x32, 0x35 }, /* pos */ | 162 | { 0x64, 0x32, 0x35 }, /* pos */ |
158 | { 0x64, 0x32, 0x35 }, /* her */ | 163 | { 0x64, 0x32, 0x35 }, /* her */ |
159 | { 0x64, 0xD0, 0x32, 0x35 }, /* scy */ | 164 | { 0x64, 0xD0, 0x32, 0x35 }, /* scy */ |
160 | { 0x64, 0x32, 0x35 }, /* hrc */ | 165 | { 0x64, 0x32, 0x35 }, /* hrc */ |
161 | { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */ | 166 | { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */ |
167 | { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hds */ | ||
162 | { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */ | 168 | { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */ |
163 | 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 }, | 169 | 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 }, |
164 | }; | 170 | }; |
165 | 171 | ||
166 | /* temperature state registers */ | 172 | /* temperature state registers */ |
167 | static const u8 FSCHMD_REG_TEMP_STATE[6][11] = { | 173 | static const u8 FSCHMD_REG_TEMP_STATE[7][11] = { |
168 | { 0x71, 0x81, 0x91 }, /* pos */ | 174 | { 0x71, 0x81, 0x91 }, /* pos */ |
169 | { 0x71, 0x81, 0x91 }, /* her */ | 175 | { 0x71, 0x81, 0x91 }, /* her */ |
170 | { 0x71, 0xd1, 0x81, 0x91 }, /* scy */ | 176 | { 0x71, 0xd1, 0x81, 0x91 }, /* scy */ |
171 | { 0x71, 0x81, 0x91 }, /* hrc */ | 177 | { 0x71, 0x81, 0x91 }, /* hrc */ |
172 | { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */ | 178 | { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */ |
179 | { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hds */ | ||
173 | { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */ | 180 | { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */ |
174 | 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, | 181 | 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 }, |
175 | }; | 182 | }; |
@@ -179,12 +186,13 @@ static const u8 FSCHMD_REG_TEMP_STATE[6][11] = { | |||
179 | in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers | 186 | in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers |
180 | at these addresses, but doesn't want to confirm they are the same as with | 187 | at these addresses, but doesn't want to confirm they are the same as with |
181 | the fscher?? */ | 188 | the fscher?? */ |
182 | static const u8 FSCHMD_REG_TEMP_LIMIT[6][11] = { | 189 | static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = { |
183 | { 0, 0, 0 }, /* pos */ | 190 | { 0, 0, 0 }, /* pos */ |
184 | { 0x76, 0x86, 0x96 }, /* her */ | 191 | { 0x76, 0x86, 0x96 }, /* her */ |
185 | { 0x76, 0xd6, 0x86, 0x96 }, /* scy */ | 192 | { 0x76, 0xd6, 0x86, 0x96 }, /* scy */ |
186 | { 0x76, 0x86, 0x96 }, /* hrc */ | 193 | { 0x76, 0x86, 0x96 }, /* hrc */ |
187 | { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */ | 194 | { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */ |
195 | { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hds */ | ||
188 | { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */ | 196 | { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */ |
189 | 0xba, 0xca, 0xda, 0xea, 0xfa }, | 197 | 0xba, 0xca, 0xda, 0xea, 0xfa }, |
190 | }; | 198 | }; |
@@ -197,7 +205,7 @@ static const u8 FSCHMD_REG_TEMP_LIMIT[6][11] = { | |||
197 | static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; | 205 | static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; |
198 | static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ | 206 | static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ |
199 | 207 | ||
200 | static const int FSCHMD_NO_TEMP_SENSORS[6] = { 3, 3, 4, 3, 5, 11 }; | 208 | static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 }; |
201 | 209 | ||
202 | /* temp status register bitmasks */ | 210 | /* temp status register bitmasks */ |
203 | #define FSCHMD_TEMP_WORKING 0x01 | 211 | #define FSCHMD_TEMP_WORKING 0x01 |
@@ -228,6 +236,7 @@ static const struct i2c_device_id fschmd_id[] = { | |||
228 | { "fscscy", fscscy }, | 236 | { "fscscy", fscscy }, |
229 | { "fschrc", fschrc }, | 237 | { "fschrc", fschrc }, |
230 | { "fschmd", fschmd }, | 238 | { "fschmd", fschmd }, |
239 | { "fschds", fschds }, | ||
231 | { "fscsyl", fscsyl }, | 240 | { "fscsyl", fscsyl }, |
232 | { } | 241 | { } |
233 | }; | 242 | }; |
@@ -1021,6 +1030,8 @@ static int fschmd_detect(struct i2c_client *client, int kind, | |||
1021 | kind = fschrc; | 1030 | kind = fschrc; |
1022 | else if (!strcmp(id, "HMD")) | 1031 | else if (!strcmp(id, "HMD")) |
1023 | kind = fschmd; | 1032 | kind = fschmd; |
1033 | else if (!strcmp(id, "HDS")) | ||
1034 | kind = fschds; | ||
1024 | else if (!strcmp(id, "SYL")) | 1035 | else if (!strcmp(id, "SYL")) |
1025 | kind = fscsyl; | 1036 | kind = fscsyl; |
1026 | else | 1037 | else |
@@ -1036,8 +1047,8 @@ static int fschmd_probe(struct i2c_client *client, | |||
1036 | const struct i2c_device_id *id) | 1047 | const struct i2c_device_id *id) |
1037 | { | 1048 | { |
1038 | struct fschmd_data *data; | 1049 | struct fschmd_data *data; |
1039 | const char * const names[6] = { "Poseidon", "Hermes", "Scylla", | 1050 | const char * const names[7] = { "Poseidon", "Hermes", "Scylla", |
1040 | "Heracles", "Heimdall", "Syleus" }; | 1051 | "Heracles", "Heimdall", "Hades", "Syleus" }; |
1041 | const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; | 1052 | const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; |
1042 | int i, err; | 1053 | int i, err; |
1043 | enum chips kind = id->driver_data; | 1054 | enum chips kind = id->driver_data; |
@@ -1320,8 +1331,8 @@ static void __exit fschmd_exit(void) | |||
1320 | } | 1331 | } |
1321 | 1332 | ||
1322 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 1333 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
1323 | MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall and " | 1334 | MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades " |
1324 | "Syleus driver"); | 1335 | "and Syleus driver"); |
1325 | MODULE_LICENSE("GPL"); | 1336 | MODULE_LICENSE("GPL"); |
1326 | 1337 | ||
1327 | module_init(fschmd_init); | 1338 | module_init(fschmd_init); |