Minor cosmetics (trivial).
[coreboot.git] / src / mainboard / tyan / s2881 / mainboard.c
1 /*
2  * This file is part of the LinuxBIOS project.
3  *
4  * Copyright (C) 2005 Tyan
5  * Written by Yinghai Lu <yhlu@tyan.com> for Tyan.
6  * Copyright (C) 2007 Ward Vandewege <ward@gnu.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 #include <device/device.h>
24 #include "chip.h"
25 #include <console/console.h>
26 #include <device/smbus.h>
27
28 /**
29  * Do some S2881-specific HWM initialization for the ADT7463 chip.
30  *
31  * See Analog Devices ADT7463 datasheet, Rev C (2004):
32  * http://www.analog.com/en/prod/0,,766_825_ADT7463,00.html
33  */
34 static void dummy_init(device_t dev)
35 {
36         device_t smbus_dev;
37         device_t adt7463;
38         struct device_path path;
39
40         int result;
41
42         /* Find the SMBus controller (AMD-8111). */
43         smbus_dev = dev_find_device(0x1022, 0x746b, 0);
44         if (!smbus_dev) {
45                 die("SMBus controller not found\n");
46         }
47         printk_debug("SMBus controller found\n");
48
49         /* Find the ADT7463 device. */
50         path.type = DEVICE_PATH_I2C;
51         path.u.i2c.device = 0x2d;
52         adt7463 = find_dev_path(smbus_dev->link, &path);
53         if (!adt7463) {
54                 die("ADT7463 not found\n");
55         }
56         printk_debug("ADT7463 found\n");
57
58         /* Set all fans to 'Fastest Speed Calculated by All 3 Temperature
59          * Channels Controls PWMx'.
60          */
61         result = smbus_write_byte(adt7463, 0x5c, 0xc2);
62         result = smbus_write_byte(adt7463, 0x5d, 0xc2);
63         result = smbus_write_byte(adt7463, 0x5e, 0xc2);
64
65         /* Make sure that our fans never stop when temp. falls below Tmin, 
66            but rather keep going at minimum duty cycle (applies to automatic 
67            fan control mode only). */
68         result = smbus_write_byte(adt7463, 0x62, 0xc0);
69
70         /* Set minimum PWM duty cycle to 25%, rather than the default 50%. */
71         result = smbus_write_byte(adt7463, 0x64, 0x40);
72         result = smbus_write_byte(adt7463, 0x65, 0x40);
73         result = smbus_write_byte(adt7463, 0x66, 0x40);
74
75         /* Set Tmin to 55C, rather than the default 90C. Above this temperature
76            the fans will start blowing harder as temperature increases
77            (automatic mode only). */
78         result = smbus_write_byte(adt7463, 0x67, 0x37);
79         result = smbus_write_byte(adt7463, 0x68, 0x37);
80         result = smbus_write_byte(adt7463, 0x69, 0x37);
81
82         /* Set THERM limit to 70C, rather than the default 100C.
83            The fans will kick in at 100% if the sensors reach this temperature,
84            (only in automatic mode, but supposedly even when hardware is
85            locked up). This is a failsafe measure. */
86         result = smbus_write_byte(adt7463, 0x6a, 0x46);
87         result = smbus_write_byte(adt7463, 0x6b, 0x46);
88         result = smbus_write_byte(adt7463, 0x6c, 0x46);
89
90         /* Remote temperature 1 offset (LSB == 0.25C). */
91         result = smbus_write_byte(adt7463, 0x70, 0x02);
92
93         /* Remote temperature 2 offset (LSB == 0.25C). */
94         result = smbus_write_byte(adt7463, 0x72, 0x01);
95
96         /* Set TACH measurements to normal (1/second). */
97         result = smbus_write_byte(adt7463, 0x78, 0xf0);
98
99         printk_debug("ADT7463 properly initialized");
100 }
101
102 static void dummy_noop(device_t dummy)
103 {
104 }
105
106 static struct device_operations dummy_operations = {
107         .read_resources         = dummy_noop,
108         .set_resources          = dummy_noop,
109         .enable_resources       = dummy_noop,
110         .init                   = dummy_init,
111 };
112
113 static unsigned int scan_root_bus(device_t root, unsigned int max)
114 {
115         struct device_path path;
116         device_t dummy;
117         unsigned link_i;
118
119         max = root_dev_scan_bus(root, max);
120
121         printk_debug("scan_root_bus ok\n");
122
123         /* The following is a little silly. We need a hook into the boot
124          * process *after* the ADT7643 device has been initialized. So we
125          * create this dummy device, and we put the ADT7643 S2881 specific
126          * settings in its init function, which gets called
127          * as the last device to be initialized.
128          */
129
130         link_i = root->links;
131         if (link_i >= MAX_LINKS) {
132                 printk_debug("Reached MAX_LINKS, not configuring ADT7463");
133                 return max;
134         }
135         root->link[link_i].link = link_i;
136         root->link[link_i].dev = root;
137         root->link[link_i].children = 0;
138         root->links++;
139
140         path.type = DEVICE_PATH_PNP;
141         path.u.pnp.port = 0;
142         path.u.pnp.device = 0;
143         dummy = alloc_dev(&root->link[link_i], &path);
144         dummy->ops = &dummy_operations;
145
146         return max;
147 }
148
149 static struct device_operations mainboard_operations = {
150         .read_resources         = root_dev_read_resources,
151         .set_resources          = root_dev_set_resources,
152         .enable_resources       = root_dev_enable_resources,
153         .init                   = root_dev_init,
154         .scan_bus               = scan_root_bus,
155 };
156
157 static void enable_dev(struct device *dev)
158 {
159         dev->ops = &mainboard_operations;
160 }
161
162 #if CONFIG_CHIP_NAME == 1
163 struct chip_operations mainboard_tyan_s2881_ops = {
164         CHIP_NAME("Tyan S2881 Mainboard")
165         .enable_dev = enable_dev,
166 };
167 #endif