adding support for the w83877tf
This commit is contained in:
parent
05d93f1aa3
commit
a17d649936
2 changed files with 312 additions and 0 deletions
52
src/superio/winbond/w83877tf/setup_serial.inc
Normal file
52
src/superio/winbond/w83877tf/setup_serial.inc
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#define OUTIT(val, port) movb val, %al; \
|
||||
movw port, %dx; \
|
||||
outb %al, %dx
|
||||
|
||||
/* the second outit is a cheap delay */
|
||||
#define OUTPNPADDR(val) OUTIT(val, $0x3f0); OUTIT(val, $0xeb)
|
||||
#define OUTPNPDATA(val) OUTIT(val, $0x3f1); OUTIT(val, $0xeb)
|
||||
|
||||
/* to do: move this to a common include file! */
|
||||
#define WRITESIOBYTE(register, value) movw register, %dx ;\
|
||||
movb value, %al ;\
|
||||
outb %al, %dx; OUTIT(%al, $0x80)
|
||||
|
||||
#define WRITESIOWORD(register, value) movw register, %dx ;\
|
||||
movw value, %ax ;\
|
||||
outw %ax, %dx; OUTIT(%al, $0x80)
|
||||
|
||||
/* turn on PnP */
|
||||
OUTPNPADDR($0x87)
|
||||
OUTPNPADDR($0x87)
|
||||
|
||||
/* select com1 */
|
||||
OUTPNPADDR($7)
|
||||
OUTPNPDATA($2)
|
||||
/* set the enable in reg. 0x30 */
|
||||
OUTPNPADDR($0x30)
|
||||
OUTPNPDATA($1)
|
||||
/* set the proper control bits for clock etc. in register 0x24 */
|
||||
OUTPNPADDR($0x24)
|
||||
OUTPNPDATA($0xc4)
|
||||
/* who knows if we need this, but the bios does it. Set PIN58S to GP13 */
|
||||
OUTPNPADDR($0x2b)
|
||||
OUTPNPDATA($0x1)
|
||||
|
||||
/* turn off PnP */
|
||||
OUTPNPADDR($0xaa)
|
||||
/* all done that nonsense -- from here on it's standard pc80 */
|
||||
// set up register to set baud rate.
|
||||
WRITESIOBYTE($0x3fb, $0x80)
|
||||
// Set 115 kb
|
||||
// I don't think this thing can run at that rate.
|
||||
// WRITESIOWORD($0x3f8, $1)
|
||||
// Set 38.4 kb
|
||||
WRITESIOWORD($0x3f8, $3)
|
||||
// now set no parity, one stop, 8 bits
|
||||
WRITESIOBYTE($0x3fb, $3)
|
||||
// now turn on RTS, DRT
|
||||
WRITESIOBYTE($0x3fc, $3)
|
||||
// Enable interrupts
|
||||
WRITESIOBYTE($0x3f9, $0xf)
|
||||
// should be done. Dump a char for fun.
|
||||
WRITESIOBYTE($0x3f8, $48)
|
||||
260
src/superio/winbond/w83877tf/superio.c
Normal file
260
src/superio/winbond/w83877tf/superio.c
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#include <pci.h>
|
||||
#include <cpu/p5/io.h>
|
||||
#include <serial_subr.h>
|
||||
#include <printk.h>
|
||||
|
||||
#define FLOPPY_DEVICE 0
|
||||
#define PARALLEL_DEVICE 1
|
||||
#define COM1_DEVICE 2
|
||||
#define COM2_DEVICE 3
|
||||
#define KBC_DEVICE 5
|
||||
#define CIR_DEVICE 6
|
||||
#define GAME_PORT_DEVICE 7
|
||||
#define GPIO_PORT2_DEVICE 8
|
||||
#define GPIO_PORT3_DEVICE 9
|
||||
#define ACPI_DEVICE 0xa
|
||||
#define HW_MONITOR_DEVICE 0xb
|
||||
|
||||
|
||||
#define FLOPPY_DEFAULT_IOBASE 0x3f0
|
||||
#define FLOPPY_DEFAULT_IRQ 6
|
||||
#define FLOPPY_DEFAULT_DRQ 2
|
||||
#define PARALLEL_DEFAULT_IOBASE 0x378
|
||||
#define PARALLEL_DEFAULT_IRQ 7
|
||||
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
|
||||
#define COM1_DEFAULT_IOBASE 0x3f8
|
||||
#define COM1_DEFAULT_IRQ 4
|
||||
#define COM1_DEFAULT_BAUD 115200
|
||||
#define COM2_DEFAULT_IOBASE 0x2f8
|
||||
#define COM2_DEFAULT_IRQ 3
|
||||
#define COM2_DEFAULT_BAUD 115200
|
||||
#define KBC_DEFAULT_IOBASE0 0x60
|
||||
#define KBC_DEFAULT_IOBASE1 0x64
|
||||
#define KBC_DEFAULT_IRQ0 0x1
|
||||
#define KBC_DEFAULT_IRQ1 0xc
|
||||
|
||||
|
||||
static void enter_pnp(struct superio *sio)
|
||||
{
|
||||
outb(0x87, sio->port);
|
||||
outb(0x87, sio->port);
|
||||
}
|
||||
|
||||
static void exit_pnp(struct superio *sio)
|
||||
{
|
||||
outb(0xaa, sio->port);
|
||||
}
|
||||
|
||||
static void write_config(struct superio *sio,
|
||||
unsigned char value, unsigned char reg)
|
||||
{
|
||||
outb(reg, sio->port);
|
||||
outb(value, sio->port +1);
|
||||
}
|
||||
|
||||
static unsigned char read_config(struct superio *sio, unsigned char reg)
|
||||
{
|
||||
outb(reg, sio->port);
|
||||
return inb(sio->port +1);
|
||||
}
|
||||
static void set_logical_device(struct superio *sio, int device)
|
||||
{
|
||||
write_config(sio, device, 0x07);
|
||||
}
|
||||
|
||||
static void set_enable(struct superio *sio, int enable)
|
||||
{
|
||||
write_config(sio, enable?0x1:0x0, 0x30);
|
||||
#if 0
|
||||
if (enable) {
|
||||
printk_debug("enabled superio device: %d\n",
|
||||
read_config(sio, 0x07));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_iobase0(struct superio *sio, unsigned iobase)
|
||||
{
|
||||
write_config(sio, (iobase >> 8) & 0xff, 0x60);
|
||||
write_config(sio, iobase & 0xff, 0x61);
|
||||
}
|
||||
|
||||
static void set_iobase1(struct superio *sio, unsigned iobase)
|
||||
{
|
||||
write_config(sio, (iobase >> 8) & 0xff, 0x62);
|
||||
write_config(sio, iobase & 0xff, 0x63);
|
||||
}
|
||||
|
||||
static void set_irq0(struct superio *sio, unsigned irq)
|
||||
{
|
||||
write_config(sio, irq, 0x70);
|
||||
}
|
||||
|
||||
static void set_irq1(struct superio *sio, unsigned irq)
|
||||
{
|
||||
write_config(sio, irq, 0x72);
|
||||
}
|
||||
|
||||
static void set_drq(struct superio *sio, unsigned drq)
|
||||
{
|
||||
write_config(sio, drq & 0xff, 0x74);
|
||||
}
|
||||
|
||||
static void setup_com(struct superio *sio,
|
||||
struct com_ports *com, int device)
|
||||
{
|
||||
int divisor = 115200/com->baud;
|
||||
printk_debug("Enabling com device: %02x\n", device);
|
||||
printk_debug(" iobase = 0x%04x irq=%d\n", com->base, com->irq);
|
||||
/* Select the device */
|
||||
set_logical_device(sio, device);
|
||||
/* Disable it while it is initialized */
|
||||
set_enable(sio, 0);
|
||||
if (com->enable) {
|
||||
set_iobase0(sio, com->base);
|
||||
set_irq0(sio, com->irq);
|
||||
/* We are initialized so enable the device */
|
||||
set_enable(sio, 1);
|
||||
/* Now initialize the com port */
|
||||
uart_init(com->base, divisor);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_floppy(struct superio *sio)
|
||||
{
|
||||
/* Remember the default resources */
|
||||
unsigned iobase = FLOPPY_DEFAULT_IOBASE;
|
||||
unsigned irq = FLOPPY_DEFAULT_IRQ;
|
||||
unsigned drq = FLOPPY_DEFAULT_DRQ;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, FLOPPY_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
if (sio->floppy) {
|
||||
set_iobase0(sio, iobase);
|
||||
set_irq0(sio, irq);
|
||||
set_drq(sio, drq);
|
||||
set_enable(sio, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_parallel(struct superio *sio)
|
||||
{
|
||||
/* Remember the default resources */
|
||||
unsigned iobase = PARALLEL_DEFAULT_IOBASE;
|
||||
unsigned irq = PARALLEL_DEFAULT_IRQ;
|
||||
unsigned drq = PARALLEL_DEFAULT_DRQ;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, PARALLEL_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
if (sio->lpt) {
|
||||
set_iobase0(sio, iobase);
|
||||
set_irq0(sio, irq);
|
||||
set_drq(sio, drq);
|
||||
set_enable(sio, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_keyboard(struct superio *sio)
|
||||
{
|
||||
/* Remember the default resources */
|
||||
unsigned iobase0 = KBC_DEFAULT_IOBASE0;
|
||||
unsigned iobase1 = KBC_DEFAULT_IOBASE1;
|
||||
unsigned irq0 = KBC_DEFAULT_IRQ0;
|
||||
unsigned irq1 = KBC_DEFAULT_IRQ1;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, KBC_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
if (sio->keyboard) {
|
||||
set_iobase0(sio, iobase0);
|
||||
set_iobase1(sio, iobase1);
|
||||
set_irq0(sio, irq0);
|
||||
set_irq1(sio, irq1);
|
||||
set_enable(sio, 1);
|
||||
/* Initialize the keyboard */
|
||||
pc_keyboard_init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void setup_acpi_registers(struct superio *sio)
|
||||
{
|
||||
set_logical_device(sio, ACPI_DEVICE);
|
||||
/* Enable power on after power fail */
|
||||
write_config(sio, (1 << 7)|(0 <<5), 0xe4);
|
||||
set_enable(sio, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void enable_devices(struct superio *sio)
|
||||
{
|
||||
if (sio->port == 0) {
|
||||
sio->port = sio->super->defaultport;
|
||||
}
|
||||
if (sio->com1.base == 0) sio->com1.base = COM1_DEFAULT_IOBASE;
|
||||
if (sio->com1.irq == 0) sio->com1.irq = COM1_DEFAULT_IRQ;
|
||||
if (sio->com1.baud == 0) sio->com1.baud = COM1_DEFAULT_BAUD;
|
||||
if (sio->com2.base == 0) sio->com2.base = COM2_DEFAULT_IOBASE;
|
||||
if (sio->com2.irq == 0) sio->com2.irq = COM2_DEFAULT_IRQ;
|
||||
if (sio->com2.baud == 0) sio->com2.baud = COM2_DEFAULT_BAUD;
|
||||
|
||||
enter_pnp(sio);
|
||||
|
||||
/* enable/disable floppy */
|
||||
setup_floppy(sio);
|
||||
|
||||
/* enable or disable parallel */
|
||||
setup_parallel(sio);
|
||||
|
||||
/* enable/disable com1 */
|
||||
setup_com(sio, &sio->com1, COM1_DEVICE);
|
||||
|
||||
/* enable/disable com2 */
|
||||
setup_com(sio, &sio->com2, COM2_DEVICE);
|
||||
|
||||
/* enable/disable keyboard */
|
||||
setup_keyboard(sio);
|
||||
|
||||
/* enable/disable cir */
|
||||
set_logical_device(sio, CIR_DEVICE);
|
||||
set_enable(sio, sio->cir);
|
||||
|
||||
/* game */
|
||||
set_logical_device(sio, GAME_PORT_DEVICE);
|
||||
set_enable(sio, sio->game);
|
||||
|
||||
/* gpio_port2 */
|
||||
set_logical_device(sio, GPIO_PORT2_DEVICE);
|
||||
set_enable(sio, sio->gpio2);
|
||||
|
||||
/* gpio_port3 */
|
||||
set_logical_device(sio, GPIO_PORT3_DEVICE);
|
||||
set_enable(sio, sio->gpio3);
|
||||
|
||||
/* enable/disable acpi */
|
||||
set_logical_device(sio, ACPI_DEVICE);
|
||||
set_enable(sio, sio->acpi);
|
||||
|
||||
/* enable/disable hw monitor */
|
||||
set_logical_device(sio, HW_MONITOR_DEVICE);
|
||||
set_enable(sio, sio->hwmonitor);
|
||||
|
||||
#if 0
|
||||
/* setup acpi registers so I am certain to get
|
||||
* power on after power fail.
|
||||
*/
|
||||
setup_acpi_registers(sio);
|
||||
#endif
|
||||
|
||||
// what's this.
|
||||
write_config(sio, 1, 0x30);
|
||||
exit_pnp(sio);
|
||||
}
|
||||
|
||||
/* The base address is either 0x2e or 0x4e */
|
||||
struct superio_control superio_winbond_w83627hf_control = {
|
||||
(void *)0, enable_devices, (void *)0, 0x2e, "w83627hf"
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue