xref: /aosp_15_r20/external/coreboot/src/ec/smsc/mec1308/ec.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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