This patch fixes the dbm690t keyboard not working issue. It should also
[coreboot.git] / src / superio / ite / it8712f / superio.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2006 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2007 Philipp Degler <pdegler@rumms.uni-mannheim.de>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21
22 #include <device/device.h>
23 #include <device/pnp.h>
24 #include <uart8250.h>
25 #include <pc80/keyboard.h>
26 #include <arch/io.h>
27 #include "chip.h"
28 #include "it8712f.h"
29
30 /* Base address 0x2e: 0x87 0x01 0x55 0x55. */
31 /* Base address 0x4e: 0x87 0x01 0x55 0xaa. */
32 static void pnp_enter_ext_func_mode(device_t dev)
33 {
34         outb(0x87, dev->path.u.pnp.port);
35         outb(0x01, dev->path.u.pnp.port);
36         outb(0x55, dev->path.u.pnp.port);
37
38         if (dev->path.u.pnp.port == 0x4e) {
39                 outb(0xaa, dev->path.u.pnp.port);
40         } else {
41                 outb(0x55, dev->path.u.pnp.port);
42         }
43 }
44
45 static void pnp_exit_ext_func_mode(device_t dev)
46 {
47         pnp_write_config(dev, 0x02, 0x02);
48 }
49
50 static void it8712f_init(device_t dev)
51 {
52         struct superio_ite_it8712f_config *conf;
53         struct resource *res0, *res1;
54
55         if (!dev->enabled) {
56                 return;
57         }
58
59         conf = dev->chip_info;
60
61         switch (dev->path.u.pnp.device) {
62         case IT8712F_FDC: /* TODO. */
63                 break;
64         case IT8712F_SP1:
65                 res0 = find_resource(dev, PNP_IDX_IO0);
66                 init_uart8250(res0->base, &conf->com1);
67                 break;
68         case IT8712F_SP2:
69                 res0 = find_resource(dev, PNP_IDX_IO0);
70                 init_uart8250(res0->base, &conf->com2);
71                 break;
72         case IT8712F_PP: /* TODO. */
73                 break;
74         case IT8712F_EC: /* TODO. */
75                 break;
76         case IT8712F_KBCK:
77                 res0 = find_resource(dev, PNP_IDX_IO0);
78                 res1 = find_resource(dev, PNP_IDX_IO1);
79                 set_kbc_ps2_mode();
80                 init_pc_keyboard(res0->base, res1->base, &conf->keyboard);
81                 break;
82         case IT8712F_KBCM: /* TODO. */
83                 break;
84         case IT8712F_MIDI: /* TODO. */
85                 break;
86         case IT8712F_GAME: /* TODO. */
87                 break;
88         case IT8712F_IR: /* TODO. */
89                 break;
90         }
91 }
92
93 static void it8712f_pnp_set_resources(device_t dev)
94 {
95         pnp_enter_ext_func_mode(dev);
96         pnp_set_resources(dev);
97         pnp_exit_ext_func_mode(dev);
98 }
99
100 static void it8712f_pnp_enable_resources(device_t dev)
101 {
102         pnp_enter_ext_func_mode(dev);
103         pnp_enable_resources(dev);
104         pnp_exit_ext_func_mode(dev);
105 }
106
107 static void it8712f_pnp_enable(device_t dev)
108 {
109         pnp_enter_ext_func_mode(dev);
110         pnp_set_logical_device(dev);
111         pnp_set_enable(dev, dev->enabled);
112         pnp_exit_ext_func_mode(dev);
113 }
114
115 static struct device_operations ops = {
116         .read_resources         = pnp_read_resources,
117         .set_resources          = it8712f_pnp_set_resources,
118         .enable_resources       = it8712f_pnp_enable_resources,
119         .enable                 = it8712f_pnp_enable,
120         .init                   = it8712f_init,
121 };
122
123 /* TODO: FDC, MIDI, GAME, IR. */
124 static struct pnp_info pnp_dev_info[] = {
125         {&ops, IT8712F_SP1, PNP_IO0 | PNP_IRQ0, {0x7f8, 0}, },
126         {&ops, IT8712F_SP2, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, {0x7f8, 0}, },
127         {&ops, IT8712F_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, {0x07f8, 0},},
128         {&ops, IT8712F_EC, PNP_IO0 | PNP_IO1 | PNP_IRQ0, {0x7f8, 0}, {0x7f8, 0x4},},
129         {&ops, IT8712F_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, {0x7f8, 0}, {0x7f8, 0x4}, },
130         {&ops, IT8712F_KBCM, PNP_IRQ0, },
131         {&ops, IT8712F_GPIO, },
132 };
133
134 static void enable_dev(struct device *dev)
135 {
136         pnp_enable_devices(dev, &pnp_ops,
137                 sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
138 }
139
140 struct chip_operations superio_ite_it8712f_ops = {
141         CHIP_NAME("ITE IT8712F Super I/O")
142         .enable_dev = enable_dev,
143 };
144