1 #include <linux/ioport.h> 2 #include <asm/io.h> 3 4 #include "pc873xx.h" 5 6 static unsigned pc873xx_probelist[] = {0x398, 0x26e, 0}; 7 8 static char *pc873xx_names[] = { 9 "PC87303", "PC87306", "PC87312", "PC87332", "PC87334" 10 }; 11 12 static unsigned int base, model; 13 14 15 unsigned int __init pc873xx_get_base() 16 { 17 return base; 18 } 19 20 char *__init pc873xx_get_model() 21 { 22 return pc873xx_names[model]; 23 } 24 25 static unsigned char __init pc873xx_read(unsigned int base, int reg) 26 { 27 outb(reg, base); 28 return inb(base + 1); 29 } 30 31 static void __init pc873xx_write(unsigned int base, int reg, unsigned char data) 32 { 33 unsigned long flags; 34 35 local_irq_save(flags); 36 outb(reg, base); 37 outb(data, base + 1); 38 outb(data, base + 1); /* Must be written twice */ 39 local_irq_restore(flags); 40 } 41 42 int __init pc873xx_probe(void) 43 { 44 int val, index = 0; 45 46 while ((base = pc873xx_probelist[index++])) { 47 48 if (request_region(base, 2, "Super IO PC873xx") == NULL) 49 continue; 50 51 val = pc873xx_read(base, REG_SID); 52 if ((val & 0xf0) == 0x10) { 53 model = PC87332; 54 break; 55 } else if ((val & 0xf8) == 0x70) { 56 model = PC87306; 57 break; 58 } else if ((val & 0xf8) == 0x50) { 59 model = PC87334; 60 break; 61 } else if ((val & 0xf8) == 0x40) { 62 model = PC87303; 63 break; 64 } 65 66 release_region(base, 2); 67 } 68 69 return (base == 0) ? -1 : 1; 70 } 71 72 void __init pc873xx_enable_epp19(void) 73 { 74 unsigned char data; 75 76 printk(KERN_INFO "PC873xx enabling EPP v1.9\n"); 77 data = pc873xx_read(base, REG_PCR); 78 pc873xx_write(base, REG_PCR, (data & 0xFC) | 0x02); 79 } 80 81 void __init pc873xx_enable_ide(void) 82 { 83 unsigned char data; 84 85 printk(KERN_INFO "PC873xx enabling IDE interrupt\n"); 86 data = pc873xx_read(base, REG_FER); 87 pc873xx_write(base, REG_FER, data | 0x40); 88 } 89