blob: 1fd1eb0bedfddb7a0dad2b66c715d2f073cddfb2 [file] [log] [blame]
Ronald G. Minnich142babf2004-03-12 16:54:31 +00001/* Copyright 2000 AG Electronics Ltd. */
2/* Copyright 2003-2004 Linux Networx */
3/* Copyright 2004 Tyan
4 By LYH change from PC87360 */
5/* This code is distributed without warranty under the GPL v2 (see COPYING) */
6
7#include <arch/io.h>
8#include <device/device.h>
9#include <device/pnp.h>
Ronald G. Minnich142babf2004-03-12 16:54:31 +000010#include <console/console.h>
11#include <string.h>
12#include <bitops.h>
13#include <uart8250.h>
14#include <pc80/keyboard.h>
15#include "chip.h"
16#include "w83627hf.h"
17
Yinghai Lu70093f72004-07-01 03:55:03 +000018
19void pnp_enter_ext_func_mode(device_t dev) {
20 outb(0x87, dev->path.u.pnp.port);
21 outb(0x87, dev->path.u.pnp.port);
22}
23void pnp_exit_ext_func_mode(device_t dev) {
24 outb(0xaa, dev->path.u.pnp.port);
25}
26
27void pnp_write_hwm(unsigned long port_base, uint8_t reg, uint8_t value)
28{
29 outb(reg, port_base+5);
30 outb(value, port_base+6);
31}
32
33uint8_t pnp_read_hwm(unsigned long port_base, uint8_t reg)
34{
35 outb(reg, port_base + 5);
36 return inb(port_base + 6);
37}
38
39static void enable_hwm_smbus(device_t dev) {
40 uint8_t reg, value;
41 reg = 0x2b;
42 value = pnp_read_config(dev, reg);
43 value &= 0x3f;
44 pnp_write_config(dev, reg, value);
45}
46
47#if 0
48static void dump_pnp_device(device_t dev)
49{
50 int i;
51 print_debug("\r\n");
52
53 for(i = 0; i <= 255; i++) {
54 uint8_t reg, val;
55 if ((i & 0x0f) == 0) {
56 print_debug_hex8(i);
57 print_debug_char(':');
58 }
59 reg = i;
60 if(i!=0xaa) {
61 val = pnp_read_config(dev, reg);
62 }
63 else {
64 val = 0xaa;
65 }
66 print_debug_char(' ');
67 print_debug_hex8(val);
68 if ((i & 0x0f) == 0x0f) {
69 print_debug("\r\n");
70 }
71 }
72}
73#endif
74
75static void init_hwm(unsigned long base)
76{
77 uint8_t reg, value;
78 int i;
79
80 unsigned hwm_reg_values[] = {
81// reg mask data
82 0x40 , 0xff , 0x81, // ; Start Hardware Monitoring for WIN627
83 0x48 , 0xaa , 0x2a, // ; Program SIO SMBus BAR to 54h>>1
84// 0x48 , 0xc8 , 0x48, // ; Program SIO SMBus BAR to 90h>>1
85 0x4A , 0x21 , 0x21, // ; Program T2 SMBus BAR to 92h>>1 &
86 // ; Program T3 SMBus BAR to 94h>>1
87 0x4E , 0x80 , 0x00,
88 0x43 , 0x00 , 0xFF,
89 0x44 , 0x00 , 0x3F,
90 0x4C , 0xBF , 0x18,
91 0x4D , 0xFF , 0x80 // ; Turn Off Beep
92
93 };
94
95 for(i = 0; i< sizeof(hwm_reg_values)/sizeof(hwm_reg_values[0]); i+=3 ) {
96 reg = hwm_reg_values[i];
97 value = pnp_read_hwm(base, reg);
98 value &= 0xff & hwm_reg_values[i+1];
99 value |= 0xff & hwm_reg_values[i+2];
100#if 0
101 printk_debug("base = 0x%04x, reg = 0x%02x, value = 0x%02x\r\n", base,reg,value);
102#endif
103 pnp_write_hwm(base,reg, value);
104 }
105}
106
107
108static void w83627hf_init(device_t dev)
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000109{
110 struct superio_winbond_w83627hf_config *conf;
111 struct resource *res0, *res1;
Li-Ta Lo69c5a902004-04-29 20:08:54 +0000112 if (!dev->enabled) {
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000113 return;
114 }
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000115 conf = dev->chip_info;
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000116 switch(dev->path.u.pnp.device) {
117 case W83627HF_SP1:
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000118 res0 = find_resource(dev, PNP_IDX_IO0);
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000119 init_uart8250(res0->base, &conf->com1);
120 break;
121 case W83627HF_SP2:
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000122 res0 = find_resource(dev, PNP_IDX_IO0);
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000123 init_uart8250(res0->base, &conf->com2);
124 break;
125 case W83627HF_KBC:
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000126 res0 = find_resource(dev, PNP_IDX_IO0);
127 res1 = find_resource(dev, PNP_IDX_IO1);
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000128 init_pc_keyboard(res0->base, res1->base, &conf->keyboard);
129 break;
Yinghai Lu70093f72004-07-01 03:55:03 +0000130 case W83627HF_HWM:
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000131 res0 = find_resource(dev, PNP_IDX_IO0);
Yinghai Lu70093f72004-07-01 03:55:03 +0000132 init_hwm(res0->base);
133 break;
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000134 }
Yinghai Lu70093f72004-07-01 03:55:03 +0000135
136}
137
138void w83627hf_pnp_set_resources(device_t dev)
139{
140
141 pnp_enter_ext_func_mode(dev);
142
143 pnp_set_resources(dev);
144
145#if 0
146 dump_pnp_device(dev);
147#endif
148
149 pnp_exit_ext_func_mode(dev);
150
151}
152
153void w83627hf_pnp_enable_resources(device_t dev)
154{
155 pnp_enter_ext_func_mode(dev);
156
157 pnp_enable_resources(dev);
158
159 switch(dev->path.u.pnp.device) {
160 case W83627HF_HWM:
161 //set the pin 91,92 as I2C bus
162 printk_debug("w83627hf hwm smbus enabled\r\n");
163 enable_hwm_smbus(dev);
164 break;
165 }
166
167#if 0
168 dump_pnp_device(dev);
169#endif
170
171 pnp_exit_ext_func_mode(dev);
172
173}
174
175void w83627hf_pnp_enable(device_t dev)
176{
177
178 if (!dev->enabled) {
179 pnp_enter_ext_func_mode(dev);
180
181 pnp_set_logical_device(dev);
182 pnp_set_enable(dev, 0);
183
184 pnp_exit_ext_func_mode(dev);
185 }
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000186}
187
188static struct device_operations ops = {
189 .read_resources = pnp_read_resources,
Yinghai Lu70093f72004-07-01 03:55:03 +0000190 .set_resources = w83627hf_pnp_set_resources,
191 .enable_resources = w83627hf_pnp_enable_resources,
192 .enable = w83627hf_pnp_enable,
193 .init = w83627hf_init,
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000194};
195
196static struct pnp_info pnp_dev_info[] = {
197 { &ops, W83627HF_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
198 { &ops, W83627HF_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
199 { &ops, W83627HF_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
200 { &ops, W83627HF_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
201 // No 4 { 0,},
202 { &ops, W83627HF_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
203 { &ops, W83627HF_CIR, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
204 { &ops, W83627HF_GAME_MIDI_GPIO1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7ff, 0 }, {0x7fe, 4} },
Yinghai Lu70093f72004-07-01 03:55:03 +0000205 { &ops, W83627HF_GPIO2,},
206 { &ops, W83627HF_GPIO3,},
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000207 { &ops, W83627HF_ACPI, PNP_IRQ0, },
208 { &ops, W83627HF_HWM, PNP_IO0 | PNP_IRQ0, { 0xff8, 0 } },
209};
210
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000211static void enable_dev(struct device *dev)
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000212{
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000213 pnp_enable_devices(dev, &pnp_ops,
214 sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000215}
216
Yinghai Lu6a61d6a2004-10-20 05:07:16 +0000217struct chip_operations superio_winbond_w83627hf_ops = {
218 .name = "Winbond w83627hf",
219 .enable_dev = enable_dev,
Ronald G. Minnich142babf2004-03-12 16:54:31 +0000220};
Yinghai Lu70093f72004-07-01 03:55:03 +0000221