summaryrefslogtreecommitdiff
path: root/src/superio/NSC/pc87360/superio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/superio/NSC/pc87360/superio.c')
-rw-r--r--src/superio/NSC/pc87360/superio.c339
1 files changed, 46 insertions, 293 deletions
diff --git a/src/superio/NSC/pc87360/superio.c b/src/superio/NSC/pc87360/superio.c
index 8765eb35cc..50d71ea927 100644
--- a/src/superio/NSC/pc87360/superio.c
+++ b/src/superio/NSC/pc87360/superio.c
@@ -1,324 +1,77 @@
/* Copyright 2000 AG Electronics Ltd. */
+/* Copyright 2003-2004 Linux Networx */
/* This code is distributed without warranty under the GPL v2 (see COPYING) */
#include <arch/io.h>
#include <device/device.h>
+#include <device/pnp.h>
#include <device/chip.h>
#include <console/console.h>
#include <string.h>
#include <bitops.h>
+#include <uart8250.h>
+#include <pc80/keyboard.h>
#include "chip.h"
+#include "pc87360.h"
-void pnp_output(char address, char data)
+static void init(device_t dev)
{
- outb(address, PNP_INDEX_REG);
- outb(data, PNP_DATA_REG);
-}
-
-static void sio_enable(struct chip *chip, enum chip_pass pass)
-{
-
- struct superio_NSC_pc87360_config *conf = (struct superio_NSC_pc87360_config *)chip->chip_info;
-
- switch (pass) {
- case CONF_PASS_PRE_CONSOLE:
- /* Enable Super IO Chip */
- pnp_output(0x07, 6); /* LD 6 = UART1 */
- pnp_output(0x30, 0); /* Dectivate */
- pnp_output(0x60, conf->port >> 8); /* IO Base */
- pnp_output(0x61, conf->port & 0xFF); /* IO Base */
- pnp_output(0x30, 1); /* Activate */
- break;
- default:
- /* nothing yet */
- break;
- }
-}
-
-static void pnp_write_config(device_t dev, unsigned char value, unsigned char reg)
-{
- outb(reg, dev->path.u.pnp.port);
- outb(value, dev->path.u.pnp.port + 1);
-}
-
-static unsigned char pnp_read_config(device_t dev, unsigned char reg)
-{
- outb(reg, dev->path.u.pnp.port);
- return inb(dev->path.u.pnp.port + 1);
-}
-
-static void pnp_set_logical_device(device_t dev)
-{
- pnp_write_config(dev, dev->path.u.pnp.device, 0x07);
-}
-
-static void pnp_set_enable(device_t dev, int enable)
-{
- pnp_write_config(dev, enable?0x1:0x0, 0x30);
-}
-
-static int pnp_read_enable(device_t dev)
-{
- return !!pnp_read_config(dev, 0x30);
-}
-
-#define FLOPPY_DEVICE 0
-#define PARALLEL_DEVICE 1
-#define COM2_DEVICE 2
-#define COM1_DEVICE 3
-#define SWC_DEVICE 4
-#define MOUSE_DEVICE 5
-#define KBC_DEVICE 6
-#define GPIO_DEVICE 7
-#define ACB_DEVICE 8
-#define FSCM_DEVICE 9
-#define WDT_DEVICE 10
-
-struct io_info {
- unsigned mask, set;
-};
-struct pnp_info {
- unsigned flags;
-#define PNP_IO0 0x01
-#define PNP_IO1 0x02
-#define PNP_IRQ0 0x04
-#define PNP_IRQ1 0x08
-#define PNP_DRQ0 0x10
-#define PNP_DRQ1 0x20
- struct io_info io0, io1;
-};
-
-static struct pnp_info pnp_dev_info[] = {
- [ 0] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
- [ 1] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x04f8, 0}, },
- [ 2] = { PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, { 0x7f8, 0 }, },
- [ 3] = { PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
- [ 4] = { PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 }, },
- [ 5] = { PNP_IRQ0 },
- [ 6] = { PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
- [ 7] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
- [ 8] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
- [ 9] = { PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
- [10] = { PNP_IO0 | PNP_IRQ0, { 0xfffc, 0 } },
-};
-
-static struct resource *get_resource(device_t dev, unsigned index)
-{
- struct resource *resource;
- int i;
- resource = 0;
- for(i = 0; i < dev->resources; i++) {
- resource = &dev->resource[i];
- if (resource->index == index) {
- break;
- }
- }
- if (!resource || (resource->index != index)) {
- resource = &dev->resource[dev->resources];
- memset(resource, 0, sizeof(*resource));
- dev->resources++;
- }
- /* Initialize the resource values */
- if (!(resource->flags & IORESOURCE_FIXED)) {
- resource->flags = 0;
- resource->base = 0;
- }
- resource->size = 0;
- resource->limit = 0;
- resource->flags = 0;
- resource->index = index;
- resource->align = 0;
- resource->gran = 0;
-
- return resource;
-}
-
-static void pnp_read_ioresource(device_t dev, unsigned index, struct io_info *info)
-{
- struct resource *resource;
- uint32_t size;
- resource = get_resource(dev, index);
-
- /* Initilize the resource */
- resource->limit = 0xffff;
- resource->flags |= IORESOURCE_IO;
-
- /* Set the resource size and alignment */
- size = (0xffff & info->mask);
- resource->size = (~(size | 0xfffff800) + 1);
- resource->align = log2(resource->size);
- resource->gran = resource->align;
-}
-
-
-static void pnp_read_resources(device_t dev)
-{
- struct pnp_info *info;
- struct resource *resource;
- pnp_set_logical_device(dev);
-
- info = &pnp_dev_info[dev->path.u.pnp.device];
-
- if (info->flags & PNP_IO0) {
- pnp_read_ioresource(dev, 0x60, &info->io0);
- }
- if (info->flags & PNP_IO1) {
- pnp_read_ioresource(dev, 0x62, &info->io1);
- }
- if (info->flags & PNP_IRQ0) {
- resource = get_resource(dev, 0x70);
- resource->size = 1;
- resource->flags |= IORESOURCE_IRQ;
- }
- if (info->flags & PNP_IRQ1) {
- resource = get_resource(dev, 0x72);
- resource->size = 1;
- resource->flags |= IORESOURCE_IRQ;
- }
- if (info->flags & PNP_DRQ0) {
- resource = get_resource(dev, 0x74);
- resource->size = 1;
- resource->flags |= IORESOURCE_DRQ;
- }
- if (info->flags & PNP_DRQ1) {
- resource = get_resource(dev, 0x75);
- resource->size = 1;
- resource->flags |= IORESOURCE_DRQ;
- }
-}
-
-static void pnp_set_iobase(device_t dev, unsigned iobase, unsigned index)
-{
- /* Index == 0x60 or 0x62 */
- pnp_write_config(dev, (iobase >> 8) & 0xff, index);
- pnp_write_config(dev, iobase & 0xff, index + 1);
-}
-
-static void pnp_set_irq(device_t dev, unsigned irq, unsigned index)
-{
- /* Index == 0x70 or 0x72 */
- pnp_write_config(dev, irq, index);
-}
-
-static void pnp_set_drq(device_t dev, unsigned drq, unsigned index)
-{
- /* Index == 0x74 */
- pnp_write_config(dev, drq & 0xff, index);
-}
-
-
-static void pnp_set_resource(device_t dev, struct resource *resource)
-{
- if (!(resource->flags & IORESOURCE_SET)) {
-#if 1
- printk_err("ERROR: %s %02x not allocated\n",
- dev_path(dev), resource->index);
-#endif
- return;
- }
- if (resource->flags & IORESOURCE_IO) {
- pnp_set_iobase(dev, resource->base, resource->index);
- }
- else if (resource->flags & IORESOURCE_DRQ) {
- pnp_set_drq(dev, resource->base, resource->index);
- }
- else if (resource->flags & IORESOURCE_IRQ) {
- pnp_set_irq(dev, resource->base, resource->index);
- }
- else {
- printk_err("ERROR: %s %02x unknown resource type\n",
- dev_path(dev), resource->index);
+ struct superio_NSC_pc87360_config *conf;
+ struct resource *res0, *res1;
+ /* Wishlist handle well known programming interfaces more
+ * generically.
+ */
+ if (!dev->enable) {
return;
}
- printk_debug(
- "%s %02x <- [0x%08lx - 0x%08lx %s\n",
- dev_path(dev),
- resource->index,
- resource->base, resource->base + resource->size - 1,
- (resource->flags & IORESOURCE_IO)? "io":
- (resource->flags & IORESOURCE_DRQ)? "drq":
- (resource->flags & IORESOURCE_IRQ)? "irq":
- (resource->flags & IORESOURCE_MEM)? "mem":
- "???");
-}
-
-static void pnp_set_resources(device_t dev)
-{
- int i;
- pnp_set_logical_device(dev);
- for(i = 0; i < dev->resources; i++) {
- pnp_set_resource(dev, &dev->resource[i]);
- }
-
-}
-static void pnp_enable_resources(device_t dev)
-{
- pnp_set_logical_device(dev);
- pnp_set_enable(dev, 1);
-
-}
-static void pnp_enable(device_t dev)
-{
- pnp_set_logical_device(dev);
- if (!dev->enable) {
- pnp_set_enable(dev, 0);
+ conf = dev->chip->chip_info;
+ switch(dev->path.u.pnp.device) {
+ case PC87360_SP1:
+ res0 = get_resource(dev, PNP_IDX_IO0);
+ init_uart8250(res0->base, &conf->com1);
+ break;
+ case PC87360_SP2:
+ res0 = get_resource(dev, PNP_IDX_IO0);
+ init_uart8250(res0->base, &conf->com2);
+ break;
+ case PC87360_KBCK:
+ res0 = get_resource(dev, PNP_IDX_IO0);
+ res1 = get_resource(dev, PNP_IDX_IO1);
+ init_pc_keyboard(res0->base, res1->base, &conf->keyboard);
+ break;
}
}
-static struct device_operations pnp_ops = {
+static struct device_operations ops = {
.read_resources = pnp_read_resources,
.set_resources = pnp_set_resources,
.enable_resources = pnp_enable_resources,
.enable = pnp_enable,
+ .init = init,
};
-#define MAX_FUNCTION 10
-static void enumerate(struct chip *chip)
-{
- struct superio_NSC_pc87360_config *conf = (struct superio_NSC_pc87360_config *)chip->chip_info;
- struct resource *resource;
- struct device_path path;
- device_t dev;
- int i;
-
- chip_enumerate(chip);
- path.type = DEVICE_PATH_PNP;
- path.u.pnp.port = chip->dev->path.u.pnp.port;
-
- /* Set the ops on the newly allocated devices */
- for(i = 0; i <= WDT_DEVICE; i++) {
- path.u.pnp.device = i;
- dev = alloc_find_dev(chip->bus, &path);
- dev->ops = &pnp_ops;
- }
+static struct pnp_info pnp_dev_info[] = {
+ { &ops, PC87360_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x07fa, 0}, },
+ { &ops, PC87360_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x04f8, 0}, },
+ { &ops, PC87360_SP2, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, { 0x7f8, 0 }, },
+ { &ops, PC87360_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, PC87360_SWC, PNP_IO0 | PNP_IRQ0, { 0xfff0, 0 }, },
+ { &ops, PC87360_KBCM, PNP_IRQ0 },
+ { &ops, PC87360_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, { 0x7f8, 0 }, { 0x7f8, 0x4}, },
+ { &ops, PC87360_GPIO, PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
+ { &ops, PC87360_ACB, PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
+ { &ops, PC87360_FSCM, PNP_IO0 | PNP_IRQ0, { 0xfff8, 0 } },
+ { &ops, PC87360_WDT, PNP_IO0 | PNP_IRQ0, { 0xfffc, 0 } },
+};
- /* Processes the hard codes for com1 */
- path.u.pnp.device = COM1_DEVICE;
- dev = alloc_find_dev(chip->bus, &path);
- resource = get_resource(dev, 0x60);
- if (conf->com1.base) {
- resource->base = conf->com1.base;
- resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
- }
- resource = get_resource(dev, 0x70);
- if (conf->com1.irq) {
- resource->base = conf->com1.irq;
- resource->flags = IORESOURCE_IRQ | IORESOURCE_FIXED | IORESOURCE_SET;
- }
- /* Process the hard codes for the keyboard controller */
- path.u.pnp.device = KBC_DEVICE;
- dev = alloc_find_dev(dev, &path);
- resource = get_resource(dev, 0x60);
- resource->base = 0x60;
- resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
- resource = get_resource(dev, 0x62);
- resource->base = 0x64;
- resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_SET;
+static void enumerate(struct chip *chip)
+{
+ pnp_enumerate(chip, sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]),
+ &pnp_ops, pnp_dev_info);
}
struct chip_control superio_NSC_pc87360_control = {
- .enable = sio_enable,
.enumerate = enumerate,
.name = "NSC 87360"
};