aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuerg Haefliger <juergh@gmail.com>2007-02-14 15:15:05 -0500
committerJean Delvare <khali@arrakis.delvare>2007-02-14 15:15:05 -0500
commit2219cd81a6cd186200606693b360c6429c003bb3 (patch)
tree4568b946f720f517ee1f0dc65f41b51981daf41b
parenta117dddf6bb27478e6903c9cb242601b6f45b11c (diff)
hwmon/vt1211: Add probing of alternate config index port
The configuration index port of the vt1211 can be accessed at two different addresses 0x2e or 0x4e, depending on pin strappings. This patch adds support to scan both addresses during module initialization. Signed-off-by: Juerg Haefliger <juergh@gmail.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/hwmon/vt1211.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 25cc56003d7a..89c23d6add7b 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -178,9 +178,10 @@ struct vt1211_data {
178 * Super-I/O constants and functions 178 * Super-I/O constants and functions
179 * --------------------------------------------------------------------- */ 179 * --------------------------------------------------------------------- */
180 180
181/* Configuration & data index port registers */ 181/* Configuration index port registers
182#define SIO_REG_CIP 0x2e 182 * The vt1211 can live at 2 different addresses so we need to probe both */
183#define SIO_REG_DIP 0x2f 183#define SIO_REG_CIP1 0x2e
184#define SIO_REG_CIP2 0x4e
184 185
185/* Configuration registers */ 186/* Configuration registers */
186#define SIO_VT1211_LDN 0x07 /* logical device number */ 187#define SIO_VT1211_LDN 0x07 /* logical device number */
@@ -193,33 +194,33 @@ struct vt1211_data {
193/* VT1211 logical device numbers */ 194/* VT1211 logical device numbers */
194#define SIO_VT1211_LDN_HWMON 0x0b /* HW monitor */ 195#define SIO_VT1211_LDN_HWMON 0x0b /* HW monitor */
195 196
196static inline void superio_outb(int reg, int val) 197static inline void superio_outb(int sio_cip, int reg, int val)
197{ 198{
198 outb(reg, SIO_REG_CIP); 199 outb(reg, sio_cip);
199 outb(val, SIO_REG_DIP); 200 outb(val, sio_cip + 1);
200} 201}
201 202
202static inline int superio_inb(int reg) 203static inline int superio_inb(int sio_cip, int reg)
203{ 204{
204 outb(reg, SIO_REG_CIP); 205 outb(reg, sio_cip);
205 return inb(SIO_REG_DIP); 206 return inb(sio_cip + 1);
206} 207}
207 208
208static inline void superio_select(int ldn) 209static inline void superio_select(int sio_cip, int ldn)
209{ 210{
210 outb(SIO_VT1211_LDN, SIO_REG_CIP); 211 outb(SIO_VT1211_LDN, sio_cip);
211 outb(ldn, SIO_REG_DIP); 212 outb(ldn, sio_cip + 1);
212} 213}
213 214
214static inline void superio_enter(void) 215static inline void superio_enter(int sio_cip)
215{ 216{
216 outb(0x87, SIO_REG_CIP); 217 outb(0x87, sio_cip);
217 outb(0x87, SIO_REG_CIP); 218 outb(0x87, sio_cip);
218} 219}
219 220
220static inline void superio_exit(void) 221static inline void superio_exit(int sio_cip)
221{ 222{
222 outb(0xaa, SIO_REG_CIP); 223 outb(0xaa, sio_cip);
223} 224}
224 225
225/* --------------------------------------------------------------------- 226/* ---------------------------------------------------------------------
@@ -1263,26 +1264,26 @@ EXIT:
1263 return err; 1264 return err;
1264} 1265}
1265 1266
1266static int __init vt1211_find(unsigned short *address) 1267static int __init vt1211_find(int sio_cip, unsigned short *address)
1267{ 1268{
1268 int err = -ENODEV; 1269 int err = -ENODEV;
1269 1270
1270 superio_enter(); 1271 superio_enter(sio_cip);
1271 1272
1272 if (superio_inb(SIO_VT1211_DEVID) != SIO_VT1211_ID) { 1273 if (superio_inb(sio_cip, SIO_VT1211_DEVID) != SIO_VT1211_ID) {
1273 goto EXIT; 1274 goto EXIT;
1274 } 1275 }
1275 1276
1276 superio_select(SIO_VT1211_LDN_HWMON); 1277 superio_select(sio_cip, SIO_VT1211_LDN_HWMON);
1277 1278
1278 if ((superio_inb(SIO_VT1211_ACTIVE) & 1) == 0) { 1279 if ((superio_inb(sio_cip, SIO_VT1211_ACTIVE) & 1) == 0) {
1279 printk(KERN_WARNING DRVNAME ": HW monitor is disabled, " 1280 printk(KERN_WARNING DRVNAME ": HW monitor is disabled, "
1280 "skipping\n"); 1281 "skipping\n");
1281 goto EXIT; 1282 goto EXIT;
1282 } 1283 }
1283 1284
1284 *address = ((superio_inb(SIO_VT1211_BADDR) << 8) | 1285 *address = ((superio_inb(sio_cip, SIO_VT1211_BADDR) << 8) |
1285 (superio_inb(SIO_VT1211_BADDR + 1))) & 0xff00; 1286 (superio_inb(sio_cip, SIO_VT1211_BADDR + 1))) & 0xff00;
1286 if (*address == 0) { 1287 if (*address == 0) {
1287 printk(KERN_WARNING DRVNAME ": Base address is not set, " 1288 printk(KERN_WARNING DRVNAME ": Base address is not set, "
1288 "skipping\n"); 1289 "skipping\n");
@@ -1291,10 +1292,11 @@ static int __init vt1211_find(unsigned short *address)
1291 1292
1292 err = 0; 1293 err = 0;
1293 printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, " 1294 printk(KERN_INFO DRVNAME ": Found VT1211 chip at 0x%04x, "
1294 "revision %u\n", *address, superio_inb(SIO_VT1211_DEVREV)); 1295 "revision %u\n", *address,
1296 superio_inb(sio_cip, SIO_VT1211_DEVREV));
1295 1297
1296EXIT: 1298EXIT:
1297 superio_exit(); 1299 superio_exit(sio_cip);
1298 return err; 1300 return err;
1299} 1301}
1300 1302
@@ -1303,8 +1305,8 @@ static int __init vt1211_init(void)
1303 int err; 1305 int err;
1304 unsigned short address = 0; 1306 unsigned short address = 0;
1305 1307
1306 err = vt1211_find(&address); 1308 if ((err = vt1211_find(SIO_REG_CIP1, &address)) &&
1307 if (err) { 1309 (err = vt1211_find(SIO_REG_CIP2, &address))) {
1308 goto EXIT; 1310 goto EXIT;
1309 } 1311 }
1310 1312