1 /* Copyright 2000 AG Electronics Ltd. */
2 /* This code is distributed without warranty under the GPL v2 (see COPYING) */
5 #include <device/device.h>
6 #include <device/chip.h>
7 #include <console/console.h>
12 void pnp_output(char address, char data)
14 outb(address, PNP_INDEX_REG);
15 outb(data, PNP_DATA_REG);
18 static void sio_enable(struct chip *chip, enum chip_pass pass)
21 struct superio_NSC_pc87360_config *conf = (struct superio_NSC_pc87360_config *)chip->chip_info;
24 case CONF_PASS_PRE_CONSOLE:
25 /* Enable Super IO Chip */
26 pnp_output(0x07, 6); /* LD 6 = UART1 */
27 pnp_output(0x30, 0); /* Dectivate */
28 pnp_output(0x60, conf->port >> 8); /* IO Base */
29 pnp_output(0x61, conf->port & 0xFF); /* IO Base */
30 pnp_output(0x30, 1); /* Activate */
38 static void pnp_write_config(device_t dev, unsigned char value, unsigned char reg)
40 outb(reg, dev->path.u.pnp.port);
41 outb(value, dev->path.u.pnp.port + 1);
44 static unsigned char pnp_read_config(device_t dev, unsigned char reg)
46 outb(reg, dev->path.u.pnp.port);
47 return inb(dev->path.u.pnp.port + 1);
50 static void pnp_set_logical_device(device_t dev)
52 pnp_write_config(dev, dev->path.u.pnp.device, 0x07);
55 static void pnp_set_enable(device_t dev, int enable)
57 pnp_write_config(dev, enable?0x1:0x0, 0x30);
60 static int pnp_read_enable(device_t dev)
62 return !!pnp_read_config(dev, 0x30);
65 #define FLOPPY_DEVICE 0
66 #define PARALLEL_DEVICE 1
70 #define MOUSE_DEVICE 5
88 struct io_info io0, io1;
91 static struct pnp_info pnp_dev_info[] = {
92 [ 0] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
93 [ 1] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x04f8, 0}, },
94 [ 2] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, { 0x7f8, 0 }, },
95 [ 3] = { PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
96 [ 4] = { PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 }, },
98 [ 6] = { PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
99 [ 7] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
100 [ 8] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
101 [ 9] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
102 [10] = { PNP_IO0 | PNP_IRQ0, { 0xfffc, 0 } },
105 static struct resource *get_resource(device_t dev, unsigned index)
107 struct resource *resource;
110 for(i = 0; i < dev->resources; i++) {
111 resource = &dev->resource[i];
112 if (resource->index == index) {
116 if (!resource || (resource->index != index)) {
117 resource = &dev->resource[dev->resources];
118 memset(resource, 0, sizeof(*resource));
121 /* Initialize the resource values */
122 if (!(resource->flags & IORESOURCE_FIXED)) {
129 resource->index = index;
136 static void pnp_read_ioresource(device_t dev, unsigned index, struct io_info *info)
138 struct resource *resource;
140 resource = get_resource(dev, index);
142 /* Initilize the resource */
143 resource->limit = 0xffff;
144 resource->flags |= IORESOURCE_IO;
146 /* Set the resource size and alignment */
147 size = (0xffff & info->mask);
148 resource->size = (~(size | 0xfffff800) + 1);
149 resource->align = log2(resource->size);
150 resource->gran = resource->align;
154 static void pnp_read_resources(device_t dev)
156 struct pnp_info *info;
157 struct resource *resource;
158 pnp_set_logical_device(dev);
160 info = &pnp_dev_info[dev->path.u.pnp.device];
162 if (info->flags & PNP_IO0) {
163 pnp_read_ioresource(dev, 0x60, &info->io0);
165 if (info->flags & PNP_IO1) {
166 pnp_read_ioresource(dev, 0x62, &info->io1);
168 if (info->flags & PNP_IRQ0) {
169 resource = get_resource(dev, 0x70);
171 resource->flags |= IORESOURCE_IRQ;
173 if (info->flags & PNP_IRQ1) {
174 resource = get_resource(dev, 0x72);
176 resource->flags |= IORESOURCE_IRQ;
178 if (info->flags & PNP_DRQ0) {
179 resource = get_resource(dev, 0x74);
181 resource->flags |= IORESOURCE_DRQ;
183 if (info->flags & PNP_DRQ1) {
184 resource = get_resource(dev, 0x75);
186 resource->flags |= IORESOURCE_DRQ;
190 static void pnp_set_iobase(device_t dev, unsigned iobase, unsigned index)
192 /* Index == 0x60 or 0x62 */
193 pnp_write_config(dev, (iobase >> 8) & 0xff, index);
194 pnp_write_config(dev, iobase & 0xff, index + 1);
197 static void pnp_set_irq(device_t dev, unsigned irq, unsigned index)
199 /* Index == 0x70 or 0x72 */
200 pnp_write_config(dev, irq, index);
203 static void pnp_set_drq(device_t dev, unsigned drq, unsigned index)
206 pnp_write_config(dev, drq & 0xff, index);
210 static void pnp_set_resource(device_t dev, struct resource *resource)
212 if (!(resource->flags & IORESOURCE_SET)) {
214 printk_err("ERROR: %s %02x not allocated\n",
215 dev_path(dev), resource->index);
219 if (resource->flags & IORESOURCE_IO) {
220 pnp_set_iobase(dev, resource->base, resource->index);
222 else if (resource->flags & IORESOURCE_DRQ) {
223 pnp_set_drq(dev, resource->base, resource->index);
225 else if (resource->flags & IORESOURCE_IRQ) {
226 pnp_set_irq(dev, resource->base, resource->index);
229 printk_err("ERROR: %s %02x unknown resource type\n",
230 dev_path(dev), resource->index);
234 "%s %02x <- [0x%08lx - 0x%08lx %s\n",
237 resource->base, resource->base + resource->size - 1,
238 (resource->flags & IORESOURCE_IO)? "io":
239 (resource->flags & IORESOURCE_DRQ)? "drq":
240 (resource->flags & IORESOURCE_IRQ)? "irq":
241 (resource->flags & IORESOURCE_MEM)? "mem":
245 static void pnp_set_resources(device_t dev)
248 pnp_set_logical_device(dev);
249 for(i = 0; i < dev->resources; i++) {
250 pnp_set_resource(dev, &dev->resource[i]);
254 static void pnp_enable_resources(device_t dev)
256 pnp_set_logical_device(dev);
257 pnp_set_enable(dev, 1);
260 static void pnp_enable(device_t dev)
262 pnp_set_logical_device(dev);
264 pnp_set_enable(dev, 0);
268 static struct device_operations pnp_ops = {
269 .read_resources = pnp_read_resources,
270 .set_resources = pnp_set_resources,
271 .enable_resources = pnp_enable_resources,
272 .enable = pnp_enable,
275 #define MAX_FUNCTION 10
276 static void enumerate(struct chip *chip)
278 struct superio_NSC_pc87360_config *conf = (struct superio_NSC_pc87360_config *)chip->chip_info;
279 struct resource *resource;
280 struct device_path path;
284 chip_enumerate(chip);
285 path.type = DEVICE_PATH_PNP;
286 path.u.pnp.port = chip->dev->path.u.pnp.port;
288 /* Set the ops on the newly allocated devices */
289 for(i = 0; i <= WDT_DEVICE; i++) {
290 path.u.pnp.device = i;
291 dev = alloc_find_dev(chip->bus, &path);
295 /* Processes the hard codes for com1 */
296 path.u.pnp.device = COM1_DEVICE;
297 dev = alloc_find_dev(chip->bus, &path);
298 resource = get_resource(dev, 0x60);
299 if (conf->com1.base) {
300 resource->base = conf->com1.base;
301 resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
303 resource = get_resource(dev, 0x70);
304 if (conf->com1.irq) {
305 resource->base = conf->com1.irq;
306 resource->flags = IORESOURCE_IRQ | IORESOURCE_FIXED | IORESOURCE_SET;
311 struct chip_control superio_NSC_pc87360_control = {
312 .enable = sio_enable,
313 .enumerate = enumerate,