blob: 2680aa34e4aa7f23e18255d064f23ec28c988b83 [file] [log] [blame]
Stefan Reinauer838c5a52010-01-17 14:08:17 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22#include <console/console.h>
Sven Schnelle7592e8b2011-01-27 11:43:03 +000023#include <device/device.h>
Stefan Reinauer838c5a52010-01-17 14:08:17 +000024#include <arch/io.h>
25#include <delay.h>
26#include "ec.h"
27
Sven Schnelle0238a9c2011-03-14 08:18:27 +000028static int ec_cmd_reg = EC_SC;
29static int ec_data_reg = EC_DATA;
30
Stefan Reinauer838c5a52010-01-17 14:08:17 +000031int send_ec_command(u8 command)
32{
33 int timeout;
34
35 timeout = 0x7ff;
Sven Schnelle0238a9c2011-03-14 08:18:27 +000036 while ((inb(ec_cmd_reg) & EC_IBF) && --timeout) {
Stefan Reinauer838c5a52010-01-17 14:08:17 +000037 udelay(10);
38 if ((timeout & 0xff) == 0)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000039 printk(BIOS_SPEW, ".");
Stefan Reinauer838c5a52010-01-17 14:08:17 +000040 }
41 if (!timeout) {
Stefan Reinauer14e22772010-04-27 06:56:47 +000042 printk(BIOS_DEBUG, "Timeout while sending command 0x%02x to EC!\n",
Stefan Reinauer838c5a52010-01-17 14:08:17 +000043 command);
44 // return -1;
45 }
46
Sven Schnelle0238a9c2011-03-14 08:18:27 +000047 outb(command, ec_cmd_reg);
Stefan Reinauer838c5a52010-01-17 14:08:17 +000048 return 0;
49}
50
51int send_ec_data(u8 data)
52{
53 int timeout;
54
55 timeout = 0x7ff;
Sven Schnelle0238a9c2011-03-14 08:18:27 +000056 while ((inb(ec_cmd_reg) & EC_IBF) && --timeout) { // wait for IBF = 0
Stefan Reinauer838c5a52010-01-17 14:08:17 +000057 udelay(10);
58 if ((timeout & 0xff) == 0)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000059 printk(BIOS_SPEW, ".");
Stefan Reinauer838c5a52010-01-17 14:08:17 +000060 }
61 if (!timeout) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000062 printk(BIOS_DEBUG, "Timeout while sending data 0x%02x to EC!\n",
Stefan Reinauer838c5a52010-01-17 14:08:17 +000063 data);
64 // return -1;
65 }
66
Sven Schnelle0238a9c2011-03-14 08:18:27 +000067 outb(data, ec_data_reg);
Stefan Reinauer838c5a52010-01-17 14:08:17 +000068
69 return 0;
70}
71
72int send_ec_data_nowait(u8 data)
73{
Sven Schnelle0238a9c2011-03-14 08:18:27 +000074 outb(data, ec_data_reg);
Stefan Reinauer838c5a52010-01-17 14:08:17 +000075
76 return 0;
77}
78
79u8 recv_ec_data(void)
80{
81 int timeout;
82 u8 data;
83
84 timeout = 0x7fff;
85 while (--timeout) { // Wait for OBF = 1
Sven Schnelle0238a9c2011-03-14 08:18:27 +000086 if (inb(ec_cmd_reg) & EC_OBF) {
Stefan Reinauer838c5a52010-01-17 14:08:17 +000087 break;
88 }
89 udelay(10);
90 if ((timeout & 0xff) == 0)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000091 printk(BIOS_SPEW, ".");
Stefan Reinauer838c5a52010-01-17 14:08:17 +000092 }
93 if (!timeout) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000094 printk(BIOS_DEBUG, "\nTimeout while receiving data from EC!\n");
Stefan Reinauer838c5a52010-01-17 14:08:17 +000095 // return -1;
96 }
97
Sven Schnelle0238a9c2011-03-14 08:18:27 +000098 data = inb(ec_data_reg);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000099 printk(BIOS_DEBUG, "recv_ec_data: 0x%02x\n", data);
Stefan Reinauer838c5a52010-01-17 14:08:17 +0000100
101 return data;
102}
103
104u8 ec_read(u8 addr)
105{
106 send_ec_command(0x80);
107 send_ec_data(addr);
108
109 return recv_ec_data();
110}
111
112int ec_write(u8 addr, u8 data)
113{
114 send_ec_command(0x81);
115 send_ec_data(addr);
116 return send_ec_data(data);
117}
118
Sven Schnellef9a0b922011-03-15 09:52:07 +0000119u8 ec_query(void)
120{
121 send_ec_command(0x84);
122 return recv_ec_data();
123}
124
Sven Schnelle8d94d7c2011-03-14 08:18:17 +0000125void ec_set_bit(u8 addr, u8 bit)
126{
127 ec_write(addr, ec_read(addr) | (1 << bit));
128}
129
130void ec_clr_bit(u8 addr, u8 bit)
131{
132 ec_write(addr, ec_read(addr) & ~(1 << bit));
133}
134
Sven Schnelle0238a9c2011-03-14 08:18:27 +0000135void ec_set_ports(u16 cmd_reg, u16 data_reg)
136{
137 ec_cmd_reg = cmd_reg;
138 ec_data_reg = data_reg;
139}
140
Sven Schnelle7592e8b2011-01-27 11:43:03 +0000141struct chip_operations ec_acpi_ops = {
142 CHIP_NAME("ACPI Embedded Controller")
143};