I made some change, please check it

Acked_by: Yinghai Lu <[EMAIL PROTECTED]>

YH

On 5/16/07, Ward Vandewege <[EMAIL PROTECTED]> wrote:
Hi all,

Please find the revised fan control patch for the Tyan s2881 attached.
Everything is now in the tyan/s2881/mainboard.c file.

It works, but the implementation is a bit silly with the dummy PNP device I
had to create. I'd greatly appreciate comments to make this code more
elegant.

The mainboard.c file did not have a copyright header; I've added it. Yinghai,
I've assumed you were the author of the original 5-line file, and put AMD as
a copyright holder. I've also assumed you wrote it in 2005 since I know it's
been around at least since then. Is that correct?

Suggestions are of course welcome.

Thanks,
Ward.

--
Ward Vandewege <[EMAIL PROTECTED]>
Free Software Foundation - Senior System Administrator


Initialize the fans on the adt7463 chip to be dynamically regulated by the
hardware, rather than always on at full speed. Set temperature treshold values
to safe defaults, rather than the not-so-safe power-on defaults.

Signed-off-by: Ward Vandewege <[EMAIL PROTECTED]>

Index: mainboard/tyan/s2881/mainboard.c
===================================================================
--- mainboard/tyan/s2881/mainboard.c	(revision 2662)
+++ mainboard/tyan/s2881/mainboard.c	(working copy)
@@ -1,9 +1,150 @@
+/*
+ * This file is part of the LinuxBIOS project.
+ *
+ * Copyright (C) 2005 Tyan
+ * Written by Yinghai Lu <[EMAIL PROTECTED]> for Tyan.
+ * Copyright (C) 2007 Ward Vandewege <[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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+
 #include <device/device.h>
 #include "chip.h"
+#include <console/console.h>
+#include <device/smbus.h>
 
+/**
+ * Do some s2881-specific HWM initialization for the ADT7463 chip
+ * See Analog Devices ADT7463 datasheet, Rev C (2004):
+ * http://www.analog.com/en/prod/0,,766_825_ADT7463,00.html
+ */
+static void dummy_init(device_t dev)
+{
+	device_t smbus_dev;
+	device_t adt7463;
+	struct device_path path;
+
+	int result;
+
+	/* Find the smbus controller (amd-8111) */
+	smbus_dev = dev_find_device(0x1022, 0x746b, 0);
+	if (!smbus_dev) {
+		die("SMBUS controller not found\n");
+	}
+	printk_debug("smbus controller found\n");
+
+	/* Find the adt7463 device */
+	path.type = DEVICE_PATH_I2C;
+	path.u.i2c.device = 0x2d;
+	adt7463 = find_dev_path(smbus_dev->link, &path);
+	if (!adt7463) {
+		die("adt7463 not found\n");
+	}
+	printk_debug("adt7463 found\n");
+
+	/* Set all fans to 'Fastest Speed Calculated by All 3 Temperature Channels Controls PWMx.' */
+	result = smbus_write_byte(adt7463, 0x5c, 0xc2);
+	result = smbus_write_byte(adt7463, 0x5d, 0xc2);
+	result = smbus_write_byte(adt7463, 0x5e, 0xc2);
+
+	/* Make sure that our fans never stop when temp falls below Tmin, 
+	   but rather keep going at minimum duty cycle (applies to automatic 
+	   fan control mode only) */
+	result = smbus_write_byte(adt7463, 0x62, 0xc0);
+
+	/* Set minimum PWM duty cycle to 25%, rather than the default 50% */
+	result = smbus_write_byte(adt7463, 0x64, 0x40);
+	result = smbus_write_byte(adt7463, 0x65, 0x40);
+	result = smbus_write_byte(adt7463, 0x66, 0x40);
+
+	/* Set Tmin to 55C, rather than the default 90C. Above this temperature
+	   the fans will start blowing harder as temperature increases
+	   (automatic mode only) */
+	result = smbus_write_byte(adt7463, 0x67, 0x37);
+	result = smbus_write_byte(adt7463, 0x68, 0x37);
+	result = smbus_write_byte(adt7463, 0x69, 0x37);
+
+	/* Set THERM limit to 70C, rather than the default 100C
+	   The fans will kick in at 100% if the sensors reach this temperature,
+	   (only in automatic mode, but supposedly even when hardware is locked up)
+	   This is a failsafe measure. */
+	result = smbus_write_byte(adt7463, 0x6a, 0x46);
+	result = smbus_write_byte(adt7463, 0x6b, 0x46);
+	result = smbus_write_byte(adt7463, 0x6c, 0x46);
+
+	/* Remote temperature 1 offset (LSB == 0.25C) */
+	result = smbus_write_byte(adt7463, 0x70, 0x02);
+	/* Remote temperature 2 offset (LSB == 0.25C) */
+	result = smbus_write_byte(adt7463, 0x72, 0x01);
+
+	/* set TACH measurements to normal (1/second) */
+	result = smbus_write_byte(adt7463, 0x78, 0xf0);
+
+	printk_debug("adt7463 properly initilized");
+}
+
+static void dummy_noop(device_t dummy)
+{
+}
+
+static struct device_operations dummy_operations = {
+	.read_resources = dummy_noop,
+	.set_resources = dummy_noop,
+	.enable_resources = dummy_noop,
+	.init = dummy_init,
+};
+
+static unsigned int scan_root_bus(device_t root, unsigned int max)
+{
+	struct device_path path;
+	device_t dummy;
+	max = root_dev_scan_bus(root, max);
+
+	printk_debug("scan_root_bus ok\n");
+
+	/* The following is a little silly. We need a hook into the boot process *after* 
+	 * the ADT7643 device has been initialized. So we create this dummy device, and we 
+	 * put the ADT7643 s2881 specific settings in its init function, which gets called
+	 * as the last device to be initialized.
+	 */
+	unsigned link_i;
+	link_i = root->links;
+	if (link_i >= MAX_LINKS) 
+		return max;
+	root->link[link_i].link = link_i;
+	root->link[link_i].dev = root;
+	root->link[link_i].child = 0;
+	root->links++;
+	path.type = DEVICE_PATH_PNP;
+	path.u.pnp.port = 0;
+	path.u.pnp.device = 0;
+	dummy = alloc_dev(&root->link[link_i], &path);
+	dummy->ops = &dummy_operations;
+
+	return max;
+}
+
+static struct device_operations mainboard_operations = {
+	.read_resources = root_dev_read_resources,
+	.set_resources = root_dev_set_resources,
+	.enable_resources = root_dev_enable_resources,
+	.init = root_dev_init,
+	.scan_bus = scan_root_bus,
+};
+
+static void enable_dev(struct device *dev)
+{
+	dev->ops = &mainboard_operations;
+}
+
 #if CONFIG_CHIP_NAME == 1
 struct chip_operations mainboard_tyan_s2881_ops = {
 	CHIP_NAME("Tyan S2881 Mainboard")
+	    .enable_dev = enable_dev,
 };
 #endif
-
-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to