I'm still not entirely convinced that the previous version was flawed,
but this one has more features, and covers some of what Uwe had marked
as TODO anyways, with more that I'll fix up later.
This is a port from SMSC LPC47M10x's _early_serial.c to the ITE IT8705f
that works with my configuration. I've also ported the superio.c, since
it has more features than the current one, and it came out in the end
looking almost identical to Uwe's for the features they share. If anyone
has the hardware, please test and let me know if it does or doesn't work
for you (or if the old one did), I haven't booted a payload with it yet
to test it fully.
Signed-off-by: Corey Osgood <[EMAIL PROTECTED]>
Index: src/superio/ite/it8705f/it8705f_early_serial.c
===================================================================
--- src/superio/ite/it8705f/it8705f_early_serial.c (revision 2573)
+++ src/superio/ite/it8705f/it8705f_early_serial.c (working copy)
@@ -1,8 +1,12 @@
/*
* This file is part of the LinuxBIOS project.
*
- * Copyright (C) 2006 Uwe Hermann <[EMAIL PROTECTED]>
+ * it8705f_early_serial.c: Pre-RAM driver for IT8705F Super I/O chip
+ * Ported from SMSC LPC47M10x by Corey Osgood
*
+ * Copyright (C) 2005 Digital Design Corporation
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,75 +19,58 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <arch/romcc_io.h>
#include "it8705f.h"
-/* The base address is 0x2e or 0x4e, depending on config bytes. */
-#define SIO_BASE 0x2e
-#define SIO_INDEX SIO_BASE
-#define SIO_DATA SIO_BASE+1
+/*----------------------------------------------------------------------------------
+ * Function: pnp_enter_conf_state
+ * Parameters: dev - high 8 bits = Super I/O port
+ * Return Value: None
+ * Description: Enable access to the IT8705F's configuration registers.
+ */
+static inline void pnp_enter_conf_state(device_t dev) {
+ /* Port 0x2e is constant, no matter what */
+ outb(0x87, 0x2e);
+ outb(0x01, 0x2e);
+ outb(0x55, 0x2e);
+ /* NOTE: this doesn't work in superio.c. Fix there before using port 0x4e */
+ if( (dev >> 8) == 0x4e ){
+ outb(0xaa, 0x2e);
+ }
+ else{
+ outb(0x55, 0x2e);
+ }
+}
-/* Global configuration registers. */
-#define IT8705F_CONFIG_REG_CC 0x02 /* Configure Control (write-only). */
-#define IT8705F_CONFIG_REG_LDN 0x07 /* Logical Device Number. */
-#define IT8705F_CONFIG_REG_CONFIGSEL 0x22 /* Configuration Select. */
-
-/* WTF? 0x23 and 0x24 are swapped here (when compared to other IT87xx). */
-#define IT8705F_CONFIG_REG_CLOCKSEL 0x24 /* Clock Selection, Flash I/F. */
-#define IT8705F_CONFIG_REG_SWSUSP 0x23 /* Software Suspend. */
-
-#define IT8705F_CONFIGURATION_PORT 0x2e /* Write-only. */
-
-/* The content of IT8705F_CONFIG_REG_LDN (index 0x07) must be set to the
- LDN the register belongs to, before you can access the register. */
-static void it8705f_sio_write(uint8_t ldn, uint8_t index, uint8_t value)
-{
- outb(IT8705F_CONFIG_REG_LDN, SIO_BASE);
- outb(ldn, SIO_DATA);
- outb(index, SIO_BASE);
- outb(value, SIO_DATA);
+/*----------------------------------------------------------------------------------
+ * Function: pnp_exit_conf_state
+ * Parameters: dev - high 8 bits = Super I/O port
+ * Return Value: None
+ * Description: Disable access to the IT8705F's configuration registers.
+ */
+static void pnp_exit_conf_state(device_t dev) {
+ outb(0xaa, 0x2e);
}
-/* Enable the peripheral devices on the IT8705F Super I/O chip. */
+/*----------------------------------------------------------------------------------
+ * Function: it8507f_enable_serial
+ * Parameters: dev - high 8 bits = Super I/O port,
+ * low 8 bits = logical device number (per it8705f.h)
+ * iobase - processor I/O port address to assign to
+ * this serial device
+ * Return Value: None
+ * Description: Configure the base I/O port of the specified serial device
+ * and enable the serial device.
+ */
static void it8705f_enable_serial(device_t dev, unsigned iobase)
{
- /* (1) Enter the configuration state (MB PnP mode). */
-
- /* Perform MB PnP setup to put the SIO chip at 0x2e. */
- /* Base address 0x2e: 0x87 0x01 0x55 0x55. */
- /* Base address 0x4e: 0x87 0x01 0x55 0xaa. */
- outb(0x87, IT8705F_CONFIGURATION_PORT);
- outb(0x01, IT8705F_CONFIGURATION_PORT);
- outb(0x55, IT8705F_CONFIGURATION_PORT);
- outb(0x55, IT8705F_CONFIGURATION_PORT);
-
- /* (2) Modify the data of configuration registers. */
-
- /* Select the chip to configure (if there's more than one).
- Set bit 7 to select JP3=1, clear bit 7 to select JP3=0.
- If this register is not written, both chips are configured. */
- /* it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CONFIGSEL, 0x00); */
-
- /* Enable all devices. */
- it8705f_sio_write(IT8705F_FDC, 0x30, 0x1); /* Floppy */
- it8705f_sio_write(IT8705F_SP1, 0x30, 0x1); /* Serial port 1 */
- it8705f_sio_write(IT8705F_SP2, 0x30, 0x1); /* Serial port 2 */
- it8705f_sio_write(IT8705F_PP, 0x30, 0x1); /* Parallel port */
- it8705f_sio_write(IT8705F_EC, 0x30, 0x1); /* Environment controller */
- it8705f_sio_write(IT8705F_GAME, 0x30, 0x1); /* GAME port */
- it8705f_sio_write(IT8705F_IR, 0x30, 0x1); /* Consumer IR */
- it8705f_sio_write(IT8705F_MIDI, 0x30, 0x1); /* MIDI port */
-
- /* Select 24MHz CLKIN (set bit 0). */
- it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CLOCKSEL, 0x01);
-
- /* Clear software suspend mode (clear bit 0). TODO: Needed? */
- /* it8705f_sio_write(0x00, IT8705F_CONFIG_REG_SWSUSP, 0x00); */
-
- /* (3) Exit the configuration state (MB PnP mode). */
- it8705f_sio_write(0x00, IT8705F_CONFIG_REG_CC, 0x02);
+ pnp_enter_conf_state(dev);
+ pnp_set_logical_device(dev);
+ pnp_set_enable(dev, 0);
+ pnp_set_iobase(dev, PNP_IDX_IO0, iobase);
+ pnp_set_enable(dev, 1);
+ pnp_exit_conf_state(dev);
}
-
Index: src/superio/ite/it8705f/superio.c
===================================================================
--- src/superio/ite/it8705f/superio.c (revision 2573)
+++ src/superio/ite/it8705f/superio.c (working copy)
@@ -1,8 +1,16 @@
/*
* This file is part of the LinuxBIOS project.
*
- * Copyright (C) 2006 Uwe Hermann <[EMAIL PROTECTED]>
+ * superio.c: RAM driver for ITE IT8705F Super I/O chip
+ * Ported from SMSC LPC47M10x by Corey Osgood
*
+ * Copyright 2000 AG Electronics Ltd.
+ * Copyright 2003-2004 Linux Networx
+ * Copyright 2004 Tyan
+ * Copyright (C) 2005 Digital Design Corporation
+ * Copyright (C) Ron Minnich, LANL
+ * Copyright (C) 2007 Corey Osgood <[EMAIL PROTECTED]>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -15,76 +23,209 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* This chip doesn't seem to have keyboard and mouse support. */
-
+#include <arch/io.h>
#include <device/device.h>
#include <device/pnp.h>
+#include <console/console.h>
+#include <device/smbus.h>
+#include <string.h>
+#include <bitops.h>
#include <uart8250.h>
+#include <pc80/keyboard.h>
#include "chip.h"
#include "it8705f.h"
-static void init(device_t dev)
+// Forward declarations
+static void enable_dev(device_t dev);
+void it8705f_pnp_set_resources(device_t dev);
+void it8705f_pnp_set_resources(device_t dev);
+void it8705f_pnp_enable_resources(device_t dev);
+void it8705f_pnp_enable(device_t dev);
+static void it8705f_init(device_t dev);
+
+static void pnp_enter_conf_state(device_t dev);
+static void pnp_exit_conf_state(device_t dev);
+static void dump_pnp_device(device_t dev);
+
+
+struct chip_operations superio_ite_it8705f_ops = {
+ CHIP_NAME("ITE IT8705F Super I/O")
+ .enable_dev = enable_dev
+};
+
+static struct device_operations ops = {
+ .read_resources = pnp_read_resources,
+ .set_resources = it8705f_pnp_set_resources,
+ .enable_resources = it8705f_pnp_enable_resources,
+ .enable = it8705f_pnp_enable,
+ .init = it8705f_init,
+};
+
+static struct pnp_info pnp_dev_info[] = {
+ { &ops, IT8705F_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x7f8, 0}, },
+ { &ops, IT8705F_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, IT8705F_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
+ { &ops, IT8705F_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, { 0x7f8, 0}, },
+ /* TODO: the rest of these */
+};
+
+/**********************************************************************************/
+/* PUBLIC INTERFACE */
+/**********************************************************************************/
+
+/*----------------------------------------------------------------------------------
+ * Function: enable_dev
+ * Parameters: dev - pointer to structure describing a Super I/O device
+ * Return Value: None
+ * Description: Create device structures and allocate resources to devices
+ * specified in the pnp_dev_info array (above).
+ */
+static void enable_dev(device_t dev)
{
- struct superio_ite_it8705f_config *conf;
- struct resource *res0, *res1;
+ pnp_enable_devices(dev, &pnp_ops, sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]),
+ pnp_dev_info);
+}
- if (!dev->enabled) {
- return;
+/*----------------------------------------------------------------------------------
+ * Function: it8705f_pnp_set_resources
+ * Parameters: dev - pointer to structure describing a Super I/O device
+ * Return Value: None
+ * Description: Configure the specified Super I/O device with the resources
+ * (I/O space, etc.) that have been allocated for it.
+ */
+void it8705f_pnp_set_resources(device_t dev)
+{
+ pnp_enter_conf_state(dev);
+ pnp_set_resources(dev);
+ pnp_exit_conf_state(dev);
+}
+
+void it8705f_pnp_enable_resources(device_t dev)
+{
+ pnp_enter_conf_state(dev);
+ pnp_enable_resources(dev);
+ pnp_exit_conf_state(dev);
+}
+
+void it8705f_pnp_enable(device_t dev)
+{
+ pnp_enter_conf_state(dev);
+ pnp_set_logical_device(dev);
+
+ if(dev->enabled) {
+ pnp_set_enable(dev, 1);
}
+ else {
+ pnp_set_enable(dev, 0);
+ }
+ pnp_exit_conf_state(dev);
+}
- conf = dev->chip_info;
+/*----------------------------------------------------------------------------------
+ * Function: it8705f_init
+ * Parameters: dev - pointer to structure describing a Super I/O device
+ * Return Value: None
+ * Description: Initialize the specified Super I/O device.
+ * Devices other than COM ports are ignored.
+ * For COM ports, we configure the baud rate.
+ */
+static void it8705f_init(device_t dev)
+{
+ struct superio_ite_it8705f_config *conf = dev->chip_info;
+ struct resource *res0, *res1;
- switch (dev->path.u.pnp.device) {
- case IT8705F_FDC: /* TODO. */
- break;
- case IT8705F_SP1:
+ if (!dev->enabled)
+ return;
+
+ switch(dev->path.u.pnp.device) {
+ case IT8705F_SP1:
res0 = find_resource(dev, PNP_IDX_IO0);
init_uart8250(res0->base, &conf->com1);
break;
+
case IT8705F_SP2:
res0 = find_resource(dev, PNP_IDX_IO0);
init_uart8250(res0->base, &conf->com2);
break;
- case IT8705F_PP: /* TODO. */
- break;
- case IT8705F_EC: /* TODO. */
- break;
- case IT8705F_GPIO: /* TODO. */
- break;
- case IT8705F_GAME: /* TODO. */
- break;
- case IT8705F_IR: /* TODO. */
- break;
- case IT8705F_MIDI: /* TODO. */
- break;
}
}
-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,
-};
+/**********************************************************************************/
+/* PRIVATE FUNCTIONS */
+/**********************************************************************************/
-/* TODO: FDC, PP, EC, GPIO, GAME, IR, MIDI. */
-static struct pnp_info pnp_dev_info[] = {
- { &ops, IT8705F_SP1, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, },
- { &ops, IT8705F_SP2, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0 | PNP_DRQ1, { 0x7f8, 0 }, },
-};
+/*----------------------------------------------------------------------------------
+ * Function: pnp_enter_conf_state
+ * Parameters: dev - pointer to structure describing a Super I/O device
+ * Return Value: None
+ * Description: Enable access to the IT8705F's configuration registers.
+ */
+static void pnp_enter_conf_state(device_t dev)
+{
+ /* NOTE: 0x2e is standard and non-configurable for IT8705f */
+ outb(0x87, 0x2e);
+ outb(0x01, 0x2e);
+ outb(0x55, 0x2e);
+ if( (dev->path.u.pnp.device) == 0x4e ){
+ outb(0xaa, 0x2e);
+ }
+ else{
+ outb(0x55, 0x2e);
+ }
+}
-static void enable_dev(struct device *dev)
+/*----------------------------------------------------------------------------------
+ * Function: pnp_exit_conf_state
+ * Parameters: None - dev remains for compatibilities sake, but unnused
+ * Return Value: None
+ * Description: Disable access to the IT8705F's configuration registers.
+ */
+static void pnp_exit_conf_state(device_t dev)
{
- pnp_enable_devices(dev, &pnp_ops,
- sizeof(pnp_dev_info)/sizeof(pnp_dev_info[0]), pnp_dev_info);
+ outb(0xaa, 0x2e);
}
-struct chip_operations superio_ite_it8705f_ops = {
- CHIP_NAME("ITE IT8705F Super I/O")
- .enable_dev = enable_dev,
-};
+#if 0
+/* Note: This portion has only been given a quick check, and may not even build
+ * USE WITH CAUTION! */
+/*----------------------------------------------------------------------------------
+ * Function: dump_pnp_device
+ * Parameters: dev - pointer to structure describing a Super I/O device
+ * Return Value: None
+ * Description: Print the values of all of the IT8705F's configuration registers.
+ * NOTE: The IT8705F must be in configuration mode when this
+ * function is called.
+ */
+static void dump_pnp_device(device_t dev)
+{
+ int register_index;
+ print_debug("\r\n");
+
+ for(register_index = 0; register_index <= IT8705F_MAX_CONFIG_REGISTER; register_index++) {
+ uint8_t register_value;
+
+ if ((register_index & 0x0f) == 0) {
+ print_debug_hex8(register_index);
+ print_debug_char(':');
+ }
+
+ // Skip over 'register' that would cause exit from configuration mode
+ if (register_index == 0xaa)
+ register_value = 0xaa;
+ else
+ register_value = pnp_read_config(dev, register_index);
+
+ print_debug_char(' ');
+ print_debug_hex8(register_value);
+ if ((register_index & 0x0f) == 0x0f) {
+ print_debug("\r\n");
+ }
+ }
+
+ print_debug("\r\n");
+}
+#endif
--
linuxbios mailing list
[email protected]
http://www.linuxbios.org/mailman/listinfo/linuxbios