Updating FSF address in the code.
[coreboot.git] / src / superio / via / vt1211 / vt1211.c
1 /*
2  * (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
3  *
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
18  * MA 02110-1301 USA
19  */
20
21  /* vt1211 routines and defines*/
22
23
24 #include <arch/io.h>
25 #include <console/console.h>
26 #include <device/device.h>
27 #include <device/pnp.h>
28 #include <uart8250.h>
29
30 #include "vt1211.h"
31 #include "chip.h"
32
33
34 static unsigned char vt1211hwmonitorinits[]={
35  0x10,0x3, 0x11,0x10, 0x12,0xd, 0x13,0x7f,
36  0x14,0x21, 0x15,0x81, 0x16,0xbd, 0x17,0x8a,
37  0x18,0x0, 0x19,0x0, 0x1a,0x0, 0x1b,0x0,
38  0x1d,0xff, 0x1e,0x0, 0x1f,0x73, 0x20,0x67,
39  0x21,0xc1, 0x22,0xca, 0x23,0x74, 0x24,0xc2,
40  0x25,0xc7, 0x26,0xc9, 0x27,0x7f, 0x29,0x0,
41  0x2a,0x0, 0x2b,0xff, 0x2c,0x0, 0x2d,0xff,
42  0x2e,0x0, 0x2f,0xff, 0x30,0x0, 0x31,0xff,
43  0x32,0x0, 0x33,0xff, 0x34,0x0, 0x39,0xff,
44  0x3a,0x0, 0x3b,0xff, 0x3c,0xff, 0x3d,0xff,
45  0x3e,0x0, 0x3f,0xb0, 0x43,0xff, 0x44,0xff,
46  0x46,0xff, 0x47,0x50, 0x4a,0x3, 0x4b,0xc0,
47  0x4c,0x0, 0x4d,0x0, 0x4e,0xf, 0x5d,0x77,
48  0x5c,0x0, 0x5f,0x33, 0x40,0x1};
49
50 static void pnp_enter_ext_func_mode(device_t dev) 
51 {
52         outb(0x87, dev->path.u.pnp.port);
53         outb(0x87, dev->path.u.pnp.port);
54 }
55
56 static void pnp_exit_ext_func_mode(device_t dev) 
57 {
58         outb(0xaa, dev->path.u.pnp.port);
59 }
60
61 static void init_hwm(unsigned long base)
62 {
63         int i;
64
65         // initialize vt1211 hardware monitor registers, which are at 0xECXX
66         for(i = 0; i < sizeof(vt1211hwmonitorinits); i += 2) {
67                         outb(vt1211hwmonitorinits[i + 1],
68                                         base + vt1211hwmonitorinits[i]);
69         }
70 }
71
72 static void vt1211_init(struct device *dev)
73 {
74         struct superio_via_vt1211_config *conf = dev->chip_info;
75         struct resource *res0;
76
77         if (!dev->enabled) {
78                 return;
79         }
80
81         switch (dev->path.u.pnp.device) {
82         case VT1211_SP1:
83                 res0 = find_resource(dev, PNP_IDX_IO0);
84                 init_uart8250(res0->base, &conf->com1);
85                 break;
86         case VT1211_SP2:
87                 res0 = find_resource(dev, PNP_IDX_IO0);
88                 init_uart8250(res0->base, &conf->com2);
89                 break;
90         case VT1211_HWM:
91                 res0 = find_resource(dev, PNP_IDX_IO0);
92                 init_hwm(res0->base);
93                 break;
94         default:
95                 printk_info("vt1211 asked to initialise unknown device!\n");
96         }
97         
98         /* activate com2
99         start_conf_pnp(3);
100         write_pnp(0x60,0xbe);
101         write_pnp(0x70,0x3);
102         write_pnp(0xf0,0x02);
103         write_pnp(0x30,0x01);
104         end_conf_pnp();
105
106         // Activate the vt1211 hardware monitor
107         start_conf_pnp(0x0b);
108         write_pnp(0x60,0xec); 
109         write_pnp(0x30,1);
110         end_conf_pnp(); */
111
112 }
113
114 void vt1211_pnp_enable_resources(device_t dev)
115 {
116         pnp_enter_ext_func_mode(dev);
117         pnp_enable_resources(dev);
118         pnp_exit_ext_func_mode(dev);
119 }
120
121 void vt1211_pnp_set_resources(struct device *dev)
122 {
123         pnp_enter_ext_func_mode(dev);
124         pnp_set_resources(dev);
125         pnp_exit_ext_func_mode(dev);
126 }
127
128 void vt1211_pnp_enable(device_t dev)
129 {
130         if (!dev->enabled) {
131                 pnp_enter_ext_func_mode(dev);
132                 pnp_set_logical_device(dev);
133                 pnp_set_enable(dev, 0);
134                 pnp_exit_ext_func_mode(dev);
135         }
136 }
137
138 struct device_operations ops = {
139         .read_resources   = pnp_read_resources,
140         .set_resources    = vt1211_pnp_set_resources,
141         .enable_resources = vt1211_pnp_enable_resources,
142         .enable           = vt1211_pnp_enable,
143         .init             = vt1211_init,
144 };
145
146 static struct pnp_info pnp_dev_info[] = {
147         { &ops, VT1211_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
148         { &ops, VT1211_PP,  PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07f8, 0}, },
149         { &ops, VT1211_SP1, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
150         { &ops, VT1211_SP2, PNP_IO0 | PNP_IRQ0,            { 0x07f8, 0}, },
151         { &ops, VT1211_HWM, PNP_IO0 , { 0xfff8, 0 }, },
152 };
153
154 static void enable_dev(struct device *dev)
155 {
156         printk_debug("vt1211 enabling PNP devices.\n");
157         pnp_enable_devices(dev,
158                         &ops,
159                         sizeof(pnp_dev_info) / sizeof(pnp_dev_info[0]),
160                         pnp_dev_info);
161 }
162
163 struct chip_operations superio_via_vt1211_ops = {
164         CHIP_NAME("VIA vt1211")
165         .enable_dev = enable_dev,
166 };