coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ec.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/io.h>
4 #include <ec/acpi/ec.h>
5 #include "include/ec.h"
6 
7 /*
8  * Notes:
9  * - ACPI "CMDB": Writing to this offset is equivalent to sending commands.
10  * The CMDx bytes contain the command parameters.
11  *
12  * TODO - Implement:
13  * - Commands: 0x58, 0xE1 and 0xE2
14  * - 0x51, 0x52: EC flash write?
15  * - ACPI CMDB: 0x63 and 0x64, 0xC7
16  * - 0x0B: Flash lock/write (Set offset 0x0B?)
17  * - Key/recovery detection?
18  *
19  * Vendor's protocols:
20  * - Only read and write are used.
21  * - Query, ACPI "CMDB" processing and command 58 are unused.
22  * - Equivalent KbcPeim is an unused PPI.
23  *
24  * NB: Also look for potential EC library
25  */
26 
27 #define EC_INDEX_IO_PORT 0x1200
28 #define EC_INDEX_IO_HIGH_ADDR_PORT (EC_INDEX_IO_PORT + 1)
29 #define EC_INDEX_IO_LOW_ADDR_PORT (EC_INDEX_IO_PORT + 2)
30 #define EC_INDEX_IO_DATA_PORT (EC_INDEX_IO_PORT + 3)
31 
33 {
34  /* EC ports: 0x62/0x66 */
35  send_ec_command(0x90);
37  return recv_ec_data();
38 }
39 
41 {
42  /* EC ports: 0x62/0x66 */
43  send_ec_command(0x91);
45  send_ec_data(data);
46 }
47 
49 {
50  send_ec_command(0x94);
51  return recv_ec_data();
52 }
53 
55 {
58  return inb(EC_INDEX_IO_DATA_PORT);
59 }
60 
62 {
66 }
67 
68 /* TODO: Check if ADC is valid. Are there 4, or actually 8 ADCs? */
70 {
71  uint8_t adc_converters_enabled; // Contains some ADCs and some DACs
72  uint8_t idx_data;
73  uint16_t adc_data;
74 
75  /* Backup enabled ADCs */
76  adc_converters_enabled = ec_idx_read(0xff15); // ADDAEN
77 
78  /* Enable desired ADC in bitmask (not enabled by EC FW, not used by vendor FW) */
79  ec_idx_write(0xff15, adc_converters_enabled | ((1 << adc) & 0xf)); // ADDAEN
80 
81  /* Sample the desired ADC in binary field; OR the start bit */
82  ec_idx_write(0xff18, ((adc << 1) & 0xf) | 1); // ADCTRL
83 
84  /* Read the desired ADC */
85  idx_data = ec_idx_read(0xff19); // ADCDAT
86  adc_data = (idx_data << 2);
87  /* Lower 2-bits of 10-bit ADC are in high bits of next register */
88  idx_data = ec_idx_read(0xff1a); // ECIF
89  adc_data |= ((idx_data & 0xc0) >> 6);
90 
91  /* Restore enabled ADCs */
92  ec_idx_write(0xff15, adc_converters_enabled); // ADDAEN
93 
94  return adc_data;
95 }
static u32 addr
Definition: cirrus.c:14
u8 inb(u16 port)
void outb(u8 val, u16 port)
int send_ec_command(u8 command)
Definition: ec.c:13
u8 recv_ec_data(void)
Definition: ec.c:65
int send_ec_data(u8 data)
Definition: ec.c:35
#define EC_INDEX_IO_DATA_PORT
Definition: ec.c:30
#define EC_INDEX_IO_HIGH_ADDR_PORT
Definition: ec.c:28
void ec_cmd_91_write(uint8_t addr, uint8_t data)
Definition: ec.c:40
#define EC_INDEX_IO_LOW_ADDR_PORT
Definition: ec.c:29
uint8_t ec_cmd_90_read(uint8_t addr)
Definition: ec.c:32
uint16_t read_ec_adc_converter(uint8_t adc)
Definition: ec.c:69
uint8_t ec_cmd_94_query(void)
Definition: ec.c:48
void ec_idx_write(uint16_t addr, uint8_t data)
Definition: ec.c:61
uint8_t ec_idx_read(uint16_t addr)
Definition: ec.c:54
unsigned short uint16_t
Definition: stdint.h:11
unsigned char uint8_t
Definition: stdint.h:8