This patch removes the need to manually set up the function enable bits for the vt8237r, by setting them up automatically depending on if the function is enabled or not (based on the i82801xx). Also makes writeback use printk() instead of print().

Signed-off-by: Corey Osgood <corey.osgood@gmail.com>

Index: src/southbridge/via/vt8237r/vt8237r.c
===================================================================
--- src/southbridge/via/vt8237r/vt8237r.c	(revision 2952)
+++ src/southbridge/via/vt8237r/vt8237r.c	(working copy)
@@ -2,6 +2,7 @@
  * This file is part of the LinuxBIOS project.
  *
  * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License v2 as published by
@@ -30,6 +31,37 @@
  *		VT8237R_SouthBridge_Revision2.06_Lead-Free.zip
  */
 
+/**
+ * List of device control functions, and their enable bits.
+ * We're going to treat rx0x50 and rx0x51 like a 16-bit register, for 
+ * simplicity's sake. Device numbers are in decimal notation, not hex.
+ *
+ * bit 0: KBC
+ * bit 1: KBC Config
+ * bit 2: PS/2 mouse
+ * bit 3: RTC
+ * bit 4: LAN (D18F0)
+ * bit 5: LAN clock gating
+ * bit 6: Reserved
+ * bit 7: USB Device mode (D16F5)
+ * bit 8: UHCI (D16F3)
+ * bit 9: EHCI (D16F4)
+ * bit a: UHCI (D16F2)
+ * bit b: SATA (D15F0)
+ * bit c: UHCI (D16F0)
+ * bit d: UHCI (D16F1)
+ * bit e: AC97 (D17F5)
+ * bit f: MC97 (D17F6)
+ */
+const static u8 vt8237r_disable_bits[5][7] = {
+{ 0xb, 0x0 },
+{ 0xc, 0xb, 0xa, 0x8, 0x9, 0x7, 0x0 },
+{ 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x0 },
+{ 0x4, 0x0 },
+{ 0x0 }
+};
+
+
 void hard_reset(void)
 {
 	printk_err("NO HARD RESET ON VT8237R! FIX ME!\n");
@@ -44,11 +76,8 @@
 	regval = pci_read_config8(dev, where);
 
 	if (regval != what) {
-		print_debug("Writeback to ");
-		print_debug_hex8(where);
-		print_debug("failed ");
-		print_debug_hex8(regval);
-		print_debug("\n ");	/* TODO: Drop the space? */
+		printk_debug("Writeback to 0x%02x failed!\nShould have returned"
+			" 0x%02x but returned 0x%02x\n", where, what, regval);
 	}
 }
 #else
@@ -73,13 +102,62 @@
 
 static void vt8237r_enable(struct device *dev)
 {
-	struct southbridge_via_vt8237r_config *sb =
-	    (struct southbridge_via_vt8237r_config *)dev->chip_info;
+	u8 disable_bit, enabled;
+	u16 cur_disable_mask, new_disable_mask;
+	//TODO: Use a static device for lpc_dev
+	struct device *lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
+					PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
 
-	pci_write_config8(dev, 0x50, sb->fn_ctrl_lo);
-	pci_write_config8(dev, 0x51, sb->fn_ctrl_hi);
+	disable_bit = vt8237r_disable_bits[PCI_SLOT(dev->path.u.pci.devfn) - 15]
+					[PCI_FUNC(dev->path.u.pci.devfn)];
 
-	/* TODO: If SATA is disabled, move IDE to fn0 to conform PCI specs. */
+	if (!disable_bit) return;
+
+	/* If SATA's disabled, move IDE to D15F0 */
+	if (disable_bit == 0xb && !dev->enabled) {
+		u8 enables;
+	
+		if (pci_read_config16(dev, 0x2) != PCI_DEVICE_ID_VIA_VT6420_SATA)
+			//SATA's already been disabled, now we're looking at IDE
+			return;
+
+		enables = pci_read_config8(dev, 0xd1);
+		enables |= (1 << 3);
+		pci_write_config8(dev, 0xd1, enables);
+
+		enables = pci_read_config8(dev, 0x49);
+		enables |= (1 << 7);
+		pci_write_config8(dev, 0x49, enables);
+	}
+
+	enabled = dev->enabled;
+	
+	/* LAN is an exception, where most other bits are 0 to enable and 1 to
+	 * disable, it's the other way around. This accounts for that */
+	/* TODO: Make LAN clock gating configurable */
+	if (disable_bit == 0x4) enabled = 0;
+
+	cur_disable_mask = pci_read_config16(lpc_dev, 0x50);
+	if (enabled)
+		new_disable_mask = cur_disable_mask & ~(1 << disable_bit);
+	else
+		new_disable_mask = cur_disable_mask | (1 << disable_bit);
+
+	/* Make sure keyboard and RTC are enabled (set to 1). Enabling keyboard 
+	 * config should be done only during keyboard init.
+	 * TODO: What do we do about PS/2 mouse? */
+	new_disable_mask |= ((1 << 3) | 1);
+
+	/* For any other D15Fn device to be enabled, D15F0 must be enabled (to
+	 * comply with PCI spec). 0x2780 is the disable bits for all D15Fn
+	 * devices */
+	if ((new_disable_mask & (1 << 0xc)) && (new_disable_mask & ~0x2780)) {
+		printk_err("UHCI0 needs to be enabled to use any other USB device\n");
+		new_disable_mask |= (1 << 0xc);
+	}
+
+	if (new_disable_mask != cur_disable_mask)
+		pci_write_config16(lpc_dev, 0x50, new_disable_mask);
 }
 
 struct chip_operations southbridge_via_vt8237r_ops = {
Index: src/southbridge/via/vt8237r/chip.h
===================================================================
--- src/southbridge/via/vt8237r/chip.h	(revision 2952)
+++ src/southbridge/via/vt8237r/chip.h	(working copy)
@@ -25,31 +25,6 @@
 extern struct chip_operations southbridge_via_vt8237r_ops;
 
 struct southbridge_via_vt8237r_config {
-	/**
-	 * Function disable. 1 = disabled.
-	 * 7 Dev 17 fn 6 MC97
-	 * 6 Dev 17 fn 5 AC97
-	 * 5 Dev 16 fn 1 USB 1.1 UHCI Ports 2-3
-	 * 4 Dev 16 fn 0 USB 1.1 UHCI Ports 0-1
-	 * 3 Dev 15 fn 0 Serial ATA
-	 * 2 Dev 16 fn 2 USB 1.1 UHCI Ports 4-5
-	 * 1 Dev 16 fn 4 USB 2.0 EHCI
-	 * 0 Dev 16 fn 3 USB 1.1 UHCI Ports 6-7
-	 */
-	u16 fn_ctrl_lo;
-
-	/**
-	 * 7 USB Device Mode 1=dis
-	 * 6 Reserved
-	 * 5 Internal LAN Controller Clock Gating 1=gated
-	 * 4 Internal LAN Controller 1=di
-	 * 3 Internal RTC 1=en
-	 * 2 Internal PS2 Mouse 1=en
-	 * 1 Internal KBC Configuration 0=dis ports 0x2e/0x2f off 0xe0-0xef
-	 * 0 Internal Keyboard Controller 1=en
-	 */
-	u16 fn_ctrl_hi;
-
 	int ide0_enable:1;
 	int ide1_enable:1;
 
Index: src/mainboard/asus/a8v-e_se/Config.lb
===================================================================
--- src/mainboard/asus/a8v-e_se/Config.lb	(revision 2952)
+++ src/mainboard/asus/a8v-e_se/Config.lb	(working copy)
@@ -190,9 +190,6 @@
 					#both cables are 80pin
 					register "ide0_80pin_cable" = "1"
 					register "ide1_80pin_cable" = "1"
-					#enables the functions of SB
-					register "fn_ctrl_lo" = "0"
-					register "fn_ctrl_hi" = "0xad"
 					
                                        device pci 0.0 on end   # HT
                                        device pci f.1 on end   # IDE
