1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <arch/io.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <delay.h>
7
8 #include "ec.h"
9 #include "chip.h"
10
11 static u16 ec_cmd_reg = 0;
12 static u16 ec_data_reg = 0;
13
__ec_read(u8 addr)14 static inline u8 __ec_read(u8 addr)
15 {
16 outb(addr, ec_cmd_reg);
17 return inb(ec_data_reg);
18 }
19
__ec_write(u8 addr,u8 data)20 static inline void __ec_write(u8 addr, u8 data)
21 {
22 outb(addr, ec_cmd_reg);
23 outb(data, ec_data_reg);
24 }
25
ec_ready(void)26 static int ec_ready(void)
27 {
28 u16 timeout = EC_TIMEOUT;
29
30 if (!ec_cmd_reg || !ec_data_reg) {
31 printk(BIOS_DEBUG, "Invalid ports: cmd=0x%x data=0x%x\n",
32 ec_cmd_reg, ec_data_reg);
33 return -1;
34 }
35
36 while (__ec_read(EC_MAILBOX_COMMAND) != 0 && --timeout) {
37 udelay(10);
38 if ((timeout & 0xff) == 0)
39 printk(BIOS_SPEW, ".");
40 }
41 if (!timeout) {
42 printk(BIOS_DEBUG, "Timeout waiting for EC to be ready.\n");
43 return -1;
44 }
45 return 0;
46 }
47
send_ec_command(u8 command)48 int send_ec_command(u8 command)
49 {
50 if (ec_ready() < 0)
51 return -1;
52 __ec_write(EC_MAILBOX_COMMAND, command);
53 return ec_ready();
54 }
55
send_ec_command_data(u8 command,u8 data)56 int send_ec_command_data(u8 command, u8 data)
57 {
58 if (ec_ready() < 0)
59 return -1;
60 __ec_write(EC_MAILBOX_DATA, data);
61 __ec_write(EC_MAILBOX_COMMAND, command);
62 return ec_ready();
63 }
64
read_ec_command_byte(u8 command)65 u8 read_ec_command_byte(u8 command)
66 {
67 send_ec_command(command);
68 return __ec_read(EC_MAILBOX_DATA);
69 }
70
ec_read(u8 addr)71 u8 ec_read(u8 addr)
72 {
73 if (send_ec_command_data(EC_RAM_READ, addr) < 0)
74 return 0;
75 return __ec_read(EC_MAILBOX_DATA);
76 }
77
ec_write(u8 addr,u8 data)78 int ec_write(u8 addr, u8 data)
79 {
80 if (ec_ready() < 0)
81 return -1;
82 __ec_write(EC_MAILBOX_DATA, addr);
83 __ec_write(EC_MAILBOX_DATA_H, data);
84 __ec_write(EC_MAILBOX_COMMAND, EC_RAM_WRITE);
85 return ec_ready();
86 }
87
ec_set_bit(u8 addr,u8 bit)88 void ec_set_bit(u8 addr, u8 bit)
89 {
90 ec_write(addr, ec_read(addr) | (1 << bit));
91 }
92
ec_clr_bit(u8 addr,u8 bit)93 void ec_clr_bit(u8 addr, u8 bit)
94 {
95 ec_write(addr, ec_read(addr) & ~(1 << bit));
96 }
97
ec_set_ports(u16 cmd_reg,u16 data_reg)98 void ec_set_ports(u16 cmd_reg, u16 data_reg)
99 {
100 ec_cmd_reg = cmd_reg;
101 ec_data_reg = data_reg;
102 }
103
mec1308_enable(struct device * dev)104 static void mec1308_enable(struct device *dev)
105 {
106 DEVTREE_CONST struct ec_smsc_mec1308_config *conf = dev->chip_info;
107
108 if (conf->mailbox_port) {
109 ec_cmd_reg = conf->mailbox_port;
110 ec_data_reg = conf->mailbox_port + 1;
111 }
112 }
113
114 struct chip_operations ec_smsc_mec1308_ops = {
115 .name = "SMSC MEC1308 EC Mailbox Interface",
116 .enable_dev = mec1308_enable
117 };
118