diff options
Diffstat (limited to 'arch/mips/txx9/generic/smsc_fdc37m81x.c')
-rw-r--r-- | arch/mips/txx9/generic/smsc_fdc37m81x.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/arch/mips/txx9/generic/smsc_fdc37m81x.c b/arch/mips/txx9/generic/smsc_fdc37m81x.c new file mode 100644 index 000000000..40f4098d3 --- /dev/null +++ b/arch/mips/txx9/generic/smsc_fdc37m81x.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * Interface for smsc fdc48m81x Super IO chip | ||
3 | * | ||
4 | * Author: MontaVista Software, Inc. source@mvista.com | ||
5 | * | ||
6 | * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under | ||
7 | * the terms of the GNU General Public License version 2. This program | ||
8 | * is licensed "as is" without any warranty of any kind, whether express | ||
9 | * or implied. | ||
10 | * | ||
11 | * Copyright 2004 (c) MontaVista Software, Inc. | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <asm/io.h> | ||
16 | #include <asm/txx9/smsc_fdc37m81x.h> | ||
17 | |||
18 | /* Common Registers */ | ||
19 | #define SMSC_FDC37M81X_CONFIG_INDEX 0x00 | ||
20 | #define SMSC_FDC37M81X_CONFIG_DATA 0x01 | ||
21 | #define SMSC_FDC37M81X_CONF 0x02 | ||
22 | #define SMSC_FDC37M81X_INDEX 0x03 | ||
23 | #define SMSC_FDC37M81X_DNUM 0x07 | ||
24 | #define SMSC_FDC37M81X_DID 0x20 | ||
25 | #define SMSC_FDC37M81X_DREV 0x21 | ||
26 | #define SMSC_FDC37M81X_PCNT 0x22 | ||
27 | #define SMSC_FDC37M81X_PMGT 0x23 | ||
28 | #define SMSC_FDC37M81X_OSC 0x24 | ||
29 | #define SMSC_FDC37M81X_CONFPA0 0x26 | ||
30 | #define SMSC_FDC37M81X_CONFPA1 0x27 | ||
31 | #define SMSC_FDC37M81X_TEST4 0x2B | ||
32 | #define SMSC_FDC37M81X_TEST5 0x2C | ||
33 | #define SMSC_FDC37M81X_TEST1 0x2D | ||
34 | #define SMSC_FDC37M81X_TEST2 0x2E | ||
35 | #define SMSC_FDC37M81X_TEST3 0x2F | ||
36 | |||
37 | /* Logical device numbers */ | ||
38 | #define SMSC_FDC37M81X_FDD 0x00 | ||
39 | #define SMSC_FDC37M81X_SERIAL1 0x04 | ||
40 | #define SMSC_FDC37M81X_SERIAL2 0x05 | ||
41 | #define SMSC_FDC37M81X_KBD 0x07 | ||
42 | |||
43 | /* Logical device Config Registers */ | ||
44 | #define SMSC_FDC37M81X_ACTIVE 0x30 | ||
45 | #define SMSC_FDC37M81X_BASEADDR0 0x60 | ||
46 | #define SMSC_FDC37M81X_BASEADDR1 0x61 | ||
47 | #define SMSC_FDC37M81X_INT 0x70 | ||
48 | #define SMSC_FDC37M81X_INT2 0x72 | ||
49 | #define SMSC_FDC37M81X_MODE 0xF0 | ||
50 | |||
51 | /* Chip Config Values */ | ||
52 | #define SMSC_FDC37M81X_CONFIG_ENTER 0x55 | ||
53 | #define SMSC_FDC37M81X_CONFIG_EXIT 0xaa | ||
54 | #define SMSC_FDC37M81X_CHIP_ID 0x4d | ||
55 | |||
56 | static unsigned long g_smsc_fdc37m81x_base; | ||
57 | |||
58 | static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) | ||
59 | { | ||
60 | outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
61 | |||
62 | return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); | ||
63 | } | ||
64 | |||
65 | static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) | ||
66 | { | ||
67 | outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
68 | outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); | ||
69 | } | ||
70 | |||
71 | void smsc_fdc37m81x_config_beg(void) | ||
72 | { | ||
73 | if (g_smsc_fdc37m81x_base) { | ||
74 | outb(SMSC_FDC37M81X_CONFIG_ENTER, | ||
75 | g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | void smsc_fdc37m81x_config_end(void) | ||
80 | { | ||
81 | if (g_smsc_fdc37m81x_base) | ||
82 | outb(SMSC_FDC37M81X_CONFIG_EXIT, | ||
83 | g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); | ||
84 | } | ||
85 | |||
86 | u8 smsc_fdc37m81x_config_get(u8 reg) | ||
87 | { | ||
88 | u8 val = 0; | ||
89 | |||
90 | if (g_smsc_fdc37m81x_base) | ||
91 | val = smsc_fdc37m81x_rd(reg); | ||
92 | |||
93 | return val; | ||
94 | } | ||
95 | |||
96 | void smsc_fdc37m81x_config_set(u8 reg, u8 val) | ||
97 | { | ||
98 | if (g_smsc_fdc37m81x_base) | ||
99 | smsc_dc37m81x_wr(reg, val); | ||
100 | } | ||
101 | |||
102 | unsigned long __init smsc_fdc37m81x_init(unsigned long port) | ||
103 | { | ||
104 | const int field = sizeof(unsigned long) * 2; | ||
105 | u8 chip_id; | ||
106 | |||
107 | if (g_smsc_fdc37m81x_base) | ||
108 | pr_warn("%s: stepping on old base=0x%0*lx\n", __func__, field, | ||
109 | g_smsc_fdc37m81x_base); | ||
110 | |||
111 | g_smsc_fdc37m81x_base = port; | ||
112 | |||
113 | smsc_fdc37m81x_config_beg(); | ||
114 | |||
115 | chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); | ||
116 | if (chip_id == SMSC_FDC37M81X_CHIP_ID) | ||
117 | smsc_fdc37m81x_config_end(); | ||
118 | else { | ||
119 | pr_warn("%s: unknown chip id 0x%02x\n", __func__, chip_id); | ||
120 | g_smsc_fdc37m81x_base = 0; | ||
121 | } | ||
122 | |||
123 | return g_smsc_fdc37m81x_base; | ||
124 | } | ||
125 | |||
126 | #ifdef DEBUG | ||
127 | static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg) | ||
128 | { | ||
129 | pr_info("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, | ||
130 | smsc_fdc37m81x_rd(reg)); | ||
131 | } | ||
132 | |||
133 | void smsc_fdc37m81x_config_dump(void) | ||
134 | { | ||
135 | u8 orig; | ||
136 | const char *fname = __func__; | ||
137 | |||
138 | smsc_fdc37m81x_config_beg(); | ||
139 | |||
140 | orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); | ||
141 | |||
142 | pr_info("%s: common\n", fname); | ||
143 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
144 | SMSC_FDC37M81X_DNUM); | ||
145 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
146 | SMSC_FDC37M81X_DID); | ||
147 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
148 | SMSC_FDC37M81X_DREV); | ||
149 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
150 | SMSC_FDC37M81X_PCNT); | ||
151 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, | ||
152 | SMSC_FDC37M81X_PMGT); | ||
153 | |||
154 | pr_info("%s: keyboard\n", fname); | ||
155 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); | ||
156 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
157 | SMSC_FDC37M81X_ACTIVE); | ||
158 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
159 | SMSC_FDC37M81X_INT); | ||
160 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
161 | SMSC_FDC37M81X_INT2); | ||
162 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, | ||
163 | SMSC_FDC37M81X_LDCR_F0); | ||
164 | |||
165 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); | ||
166 | |||
167 | smsc_fdc37m81x_config_end(); | ||
168 | } | ||
169 | #endif | ||