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