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(value: reg, port: base); |
29 | return inb(port: 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(value: reg, port: base); |
38 | outb(value: data, port: base + 1); |
39 | outb(value: data, port: 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: (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: data | 0x40); |
89 | } |
90 | |