blob: 406cc41ae789c6c222d81a04a5cc9c858c6ef610 [file] [log] [blame]
Stefan Reinauerb5ab3232009-04-22 07:23:00 +00001/*
2 * This file is part of the ectool 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
Uwe Hermann257ae3f2009-04-22 12:28:14 +00008 * published by the Free Software Foundation; version 2 of the License.
Stefan Reinauerb5ab3232009-04-22 07:23:00 +00009 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000014 */
15
16#include <stdio.h>
Stefan Reinauer2dd1ded2010-09-27 18:48:15 +000017#include <stdint.h>
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000018#include <stdlib.h>
19#include <unistd.h>
20#include <sys/io.h>
21#include "ec.h"
22
23extern int verbose;
24
25#define debug(x...) if (verbose) printf(x)
26
27int send_ec_command(uint8_t command)
28{
29 int timeout;
30
31 timeout = 0x7ff;
32 while ((inb(EC_SC) & EC_IBF) && --timeout) {
33 usleep(10);
34 if ((timeout & 0xff) == 0)
35 debug(".");
36 }
37 if (!timeout) {
Anton Kochkov7e59f7692010-06-29 21:13:20 +000038 debug("Timeout while sending command 0x%02x to EC!\n",
Uwe Hermann257ae3f2009-04-22 12:28:14 +000039 command);
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000040 // return -1;
41 }
42
43 outb(command, EC_SC);
44 return 0;
45}
46
47int send_ec_data(uint8_t data)
48{
49 int timeout;
50
51 timeout = 0x7ff;
Uwe Hermann257ae3f2009-04-22 12:28:14 +000052 while ((inb(EC_SC) & EC_IBF) && --timeout) { // wait for IBF = 0
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000053 usleep(10);
54 if ((timeout & 0xff) == 0)
55 debug(".");
56 }
Anton Kochkov7e59f7692010-06-29 21:13:20 +000057 if (timeout) {
58 debug("Timeout while sending data 0x%02x to EC!\n", data);
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000059 // return -1;
60 }
61
62 outb(data, EC_DATA);
63
64 return 0;
65}
66
67int send_ec_data_nowait(uint8_t data)
68{
69 outb(data, EC_DATA);
70
71 return 0;
72}
73
74uint8_t recv_ec_data(void)
75{
76 int timeout;
77 uint8_t data;
78
79 timeout = 0x7fff;
Uwe Hermann257ae3f2009-04-22 12:28:14 +000080 while (--timeout) { // Wait for OBF = 1
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000081 if (inb(EC_SC) & EC_OBF) {
82 break;
83 }
84 usleep(10);
85 if ((timeout & 0xff) == 0)
86 debug(".");
87 }
88 if (!timeout) {
Anton Kochkov7e59f7692010-06-29 21:13:20 +000089 debug("\nTimeout while receiving data from EC!\n");
Stefan Reinauerb5ab3232009-04-22 07:23:00 +000090 // return -1;
91 }
92
93 data = inb(EC_DATA);
94 debug("recv_ec_data: 0x%02x\n", data);
95
96 return data;
97}
98
99uint8_t ec_read(uint8_t addr)
100{
Anton Kochkov7e59f7692010-06-29 21:13:20 +0000101 send_ec_command(RD_EC);
Stefan Reinauerb5ab3232009-04-22 07:23:00 +0000102 send_ec_data(addr);
103
104 return recv_ec_data();
105}
106
Anton Kochkov7e59f7692010-06-29 21:13:20 +0000107uint8_t ec_ext_read(uint16_t addr)
108{
109 send_ec_command(WR_EC);
110 send_ec_data(0x02);
111 send_ec_data(addr & 0xff);
112 send_ec_command(RX_EC);
113 send_ec_data(addr >> 8);
114
115 return recv_ec_data();
116}
117
118int ec_ext_write(uint16_t addr, uint8_t data)
119{
120 send_ec_command(WR_EC);
121 send_ec_data(0x02);
122 send_ec_data(addr & 0xff);
123 send_ec_command(WX_EC);
124 send_ec_data(addr >> 8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700125
Anton Kochkov7e59f7692010-06-29 21:13:20 +0000126 return send_ec_data(data);
127}
128
Stefan Reinauerb5ab3232009-04-22 07:23:00 +0000129int ec_write(uint8_t addr, uint8_t data)
130{
Anton Kochkov7e59f7692010-06-29 21:13:20 +0000131 send_ec_command(WR_EC);
Stefan Reinauerb5ab3232009-04-22 07:23:00 +0000132 send_ec_data(addr);
Uwe Hermann257ae3f2009-04-22 12:28:14 +0000133
Stefan Reinauerb5ab3232009-04-22 07:23:00 +0000134 return send_ec_data(data);
135}
Stefan Reinauer984e0f32010-01-16 17:50:55 +0000136
137uint8_t ec_idx_read(uint16_t addr)
138{
139 uint16_t lpc_idx = 0x380;
140
141 outb(addr & 0xff, lpc_idx + 2);
142 outb(addr >> 8, lpc_idx + 1);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000143
Stefan Reinauer984e0f32010-01-16 17:50:55 +0000144 return inb(lpc_idx + 3);
145}
Alexander Couzens0edf4192015-02-06 22:27:33 +0100146
147uint8_t ec_query(void)
148{
149 send_ec_command(QR_EC);
150 return recv_ec_data();
151}