coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ec_acpi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_device.h>
5 #include <acpi/acpi_pld.h>
6 #include <acpi/acpigen.h>
8 #include <acpi/acpigen_usb.h>
9 #include <console/console.h>
10 #include <drivers/usb/acpi/chip.h>
12 #include <ec/google/common/dptf.h>
13 
14 #include "chip.h"
15 #include "ec.h"
16 #include "ec_commands.h"
17 
18 #define GOOGLE_CHROMEEC_USBC_DEVICE_HID "GOOG0014"
19 #define GOOGLE_CHROMEEC_USBC_DEVICE_NAME "USBC"
20 
21 const char *google_chromeec_acpi_name(const struct device *dev)
22 {
23  /*
24  * Chrome EC device (CREC - GOOG0004) is really a child of EC device (EC - PNP0C09) in
25  * ACPI tables. However, in coreboot device tree, there is no separate chip/device for
26  * EC0. Thus, Chrome EC device needs to return "EC0.CREC" as the ACPI name so that the
27  * callers can get the correct acpi device path/scope for this device.
28  *
29  * If we ever enable a separate driver for generating AML for EC0 device, then this
30  * function needs to be updated to return "CREC".
31  */
32  return "EC0.CREC";
33 }
34 
35 /*
36  * Helper for fill_ssdt_generator. This adds references to the USB
37  * port objects so that the consumer of this information can know
38  * whether the port supports USB2 and/or USB3.
39  */
40 static void get_usb_port_references(int port_number, struct device **usb2_port,
41  struct device **usb3_port, struct device **usb4_port)
42 {
44  struct device *port = NULL;
45 
46  /* Search through the devicetree for matching USB Type-C ports */
47  while ((port = dev_find_path(port, DEVICE_PATH_USB)) != NULL) {
48  if (!port->enabled || port->path.type != DEVICE_PATH_USB)
49  continue;
50 
51  config = port->chip_info;
52 
53  /* Look at only USB Type-C ports */
54  if ((config->type != UPC_TYPE_C_USB2_ONLY) &&
55  (config->type != UPC_TYPE_C_USB2_SS_SWITCH) &&
56  (config->type != UPC_TYPE_C_USB2_SS))
57  continue;
58 
59  /*
60  * Check for a matching port number (the 'token' field in 'group'). Note that
61  * 'port_number' is 0-based, whereas the 'token' field is 1-based.
62  */
63  int group_token;
64  if (config->use_custom_pld)
65  group_token = config->custom_pld.group.token;
66  else
67  group_token = config->group.token;
68  if (group_token != (port_number + 1))
69  continue;
70 
71  switch (port->path.usb.port_type) {
72  case 2:
73  *usb2_port = port;
74  break;
75  case 3:
76  *usb3_port = port;
77  break;
78  case 4:
79  *usb4_port = port;
80  break;
81  default:
82  break;
83  }
84  }
85 }
86 
87 /*
88  * Apparently these are supposed to be uppercase, in contrast to the other
89  * lowercase fields.
90  */
91 static const char *port_location_to_str(enum ec_pd_port_location port_location)
92 {
93  switch (port_location) {
95  return "LEFT";
97  return "RIGHT";
99  return "BACK";
101  return "FRONT";
103  return "LEFT_FRONT";
105  return "LEFT_BACK";
107  return "RIGHT_FRONT";
109  return "RIGHT_BACK";
111  return "BACK_LEFT";
113  return "BACK_RIGHT";
116  default:
117  return "UNKNOWN";
118  }
119 }
120 
121 static struct usb_pd_port_caps port_caps;
122 static void add_port_location(struct acpi_dp *dsd, int port_number)
123 {
125 }
126 
127 static void get_pld_from_usb_ports(struct acpi_pld *pld,
128  struct device *usb2_port, struct device *usb3_port,
129  struct device *usb4_port)
130 {
132 
133  if (usb4_port)
134  config = usb4_port->chip_info;
135  else if (usb3_port)
136  config = usb3_port->chip_info;
137  else if (usb2_port)
138  config = usb2_port->chip_info;
139 
140  if (config) {
141  if (config->use_custom_pld)
142  *pld = config->custom_pld;
143  else
144  acpi_pld_fill_usb(pld, config->type, &config->group);
145  }
146 }
147 
148 static void fill_ssdt_typec_device(const struct device *dev)
149 {
151  int rv;
152  int i;
153  unsigned int num_ports = 0;
154  struct device *usb2_port;
155  struct device *usb3_port;
156  struct device *usb4_port;
157  struct acpi_pld pld = {0};
158  uint32_t pcap_mask = 0;
159 
160  rv = google_chromeec_get_num_pd_ports(&num_ports);
161  if (rv || num_ports == 0)
162  return;
163 
164  /* If we can't get port caps, we shouldn't bother creating a device. */
166  if (rv || pcap_mask == 0)
167  return;
168 
172  acpigen_write_name_string("_DDN", "ChromeOS EC Embedded Controller "
173  "USB Type-C Control");
174 
175  for (i = 0; i < num_ports; ++i) {
177  if (rv)
178  continue;
179 
180  usb2_port = NULL;
181  usb3_port = NULL;
182  usb4_port = NULL;
183  get_usb_port_references(i, &usb2_port, &usb3_port, &usb4_port);
184 
185  get_pld_from_usb_ports(&pld, usb2_port, usb3_port, usb4_port);
186 
187  struct typec_connector_class_config typec_config = {
189  .try_power_role =
191  .data_role = (enum usb_typec_data_role)port_caps.data_role_cap,
192  .usb2_port = usb2_port,
193  .usb3_port = usb3_port,
194  .usb4_port = usb4_port,
195  .orientation_switch = config->mux_conn[i],
196  .usb_role_switch = config->mux_conn[i],
197  .mode_switch = config->mux_conn[i],
198  .pld = &pld,
199  };
200 
202  }
203 
204  acpigen_pop_len(); /* Device GOOGLE_CHROMEEC_USBC_DEVICE_NAME */
205  acpigen_pop_len(); /* Scope */
206 }
207 
208 static const enum ps2_action_key ps2_enum_val[] = {
210  [TK_BACK] = PS2_KEY_BACK,
229  [TK_MENU] = PS2_KEY_MENU,
230 };
231 
232 static void fill_ssdt_ps2_keyboard(const struct device *dev)
233 {
234  uint8_t i;
235  struct ec_response_keybd_config keybd = {};
236  enum ps2_action_key ps2_action_keys[MAX_TOP_ROW_KEYS] = {};
237 
238  if (google_chromeec_get_keybd_config(&keybd) ||
239  !keybd.num_top_row_keys ||
241  printk(BIOS_ERR, "PS2K: Bad resp from EC. Vivaldi disabled!\n");
242  return;
243  }
244 
245  /* Convert enum action_key values to enum ps2_action_key values */
246  for (i = 0; i < keybd.num_top_row_keys; i++)
247  ps2_action_keys[i] = ps2_enum_val[keybd.action_keys[i]];
248 
249  acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", keybd.num_top_row_keys,
250  ps2_action_keys,
254 }
255 
256 static const char *ec_acpi_name(const struct device *dev)
257 {
258  return "EC0";
259 }
260 
261 static struct device_operations ec_ops = {
262  .acpi_name = ec_acpi_name,
263 };
264 
266 {
267  struct device_path path;
268  struct device *ec;
269 
270  /* Set up a minimal EC0 device to pass to the DPTF helpers */
272  path.generic.id = 0;
273  path.generic.subid = 0;
274  ec = alloc_find_dev(dev->bus, &path);
275  ec->ops = &ec_ops;
276 
277  if (CONFIG(DRIVERS_INTEL_DPTF))
279 
282 }
283 
284 const char *ec_retimer_fw_update_path(void)
285 {
286  return "\\_SB_.PCI0.LPCB.EC0_.RFWU";
287 }
288 
290 {
291  const char *RFWU = ec_retimer_fw_update_path();
292 
293  /*
294  * Write the EC RAM for Retimer Upgrade
295  * RFWU = data
296  */
298  acpigen_write_byte(data);
300 }
const char * acpi_device_path(const struct device *dev)
Definition: device.c:144
struct acpi_dp * acpi_dp_add_string(struct acpi_dp *dp, const char *name, const char *string)
Definition: device.c:991
void acpigen_emit_namestring(const char *namepath)
Definition: acpigen.c:275
void acpigen_write_store(void)
Definition: acpigen.c:1333
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_byte(unsigned int data)
Definition: acpigen.c:96
void acpigen_write_device(const char *name)
Definition: acpigen.c:769
void acpigen_write_name_string(const char *name, const char *string)
Definition: acpigen.c:176
void acpigen_ps2_keyboard_dsd(const char *scope, uint8_t num_top_row_keys, enum ps2_action_key action_keys[], bool can_send_function_keys, bool has_numeric_keypad, bool has_scrnlock_key)
ps2_action_key
@ PS2_KEY_REFRESH
@ PS2_KEY_PRIVACY_SCRN_TOGGLE
@ PS2_KEY_KBD_BKLIGHT_TOGGLE
@ PS2_KEY_PREV_TRACK
@ PS2_KEY_SNAPSHOT
@ PS2_KEY_MICMUTE
@ PS2_KEY_VOL_MUTE
@ PS2_KEY_KBD_BKLIGHT_DOWN
@ PS2_KEY_OVERVIEW
@ PS2_KEY_VOL_UP
@ PS2_KEY_MENU
@ PS2_KEY_BRIGHTNESS_DOWN
@ PS2_KEY_KBD_BKLIGHT_UP
@ PS2_KEY_BACK
@ PS2_KEY_FORWARD
@ PS2_KEY_VOL_DOWN
@ PS2_KEY_ABSENT
@ PS2_KEY_FULLSCREEN
@ PS2_KEY_BRIGHTNESS_UP
@ PS2_KEY_PLAY_PAUSE
@ PS2_KEY_NEXT_TRACK
void acpigen_write_typec_connector(const struct typec_connector_class_config *config, int port_number, add_custom_dsd_property_cb add_custom_dsd_property)
Definition: acpigen_usb.c:111
usb_typec_data_role
Definition: acpigen_usb.h:20
usb_typec_power_role
Definition: acpigen_usb.h:8
usb_typec_try_power_role
Definition: acpigen_usb.h:14
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
struct device * alloc_find_dev(struct bus *parent, struct device_path *path)
See if a device structure already exists and if not allocate it.
Definition: device.c:138
DEVTREE_CONST struct device * dev_find_path(DEVTREE_CONST struct device *prev_match, enum device_path_type path_type)
Given a Device Path Type, find the device structure.
Definition: device_const.c:53
@ CONFIG
Definition: dsi_common.h:201
int google_chromeec_get_pd_port_caps(int port, struct usb_pd_port_caps *port_caps)
Get role-based capabilities for a USB-PD port.
Definition: ec.c:1440
int google_chromeec_get_cmd_versions(int command, uint32_t *pmask)
Get available versions of the specified command.
Definition: ec.c:464
int google_chromeec_get_num_pd_ports(unsigned int *num_ports)
Get number of PD-capable USB ports from EC.
Definition: ec.c:1419
int google_chromeec_get_keybd_config(struct ec_response_keybd_config *keybd)
Get the keyboard configuration / layout information from EC.
Definition: ec.c:1718
void ec_retimer_fw_update(uint8_t data)
Definition: ec_acpi.c:289
#define GOOGLE_CHROMEEC_USBC_DEVICE_NAME
Definition: ec_acpi.c:19
static const char * port_location_to_str(enum ec_pd_port_location port_location)
Definition: ec_acpi.c:91
static struct device_operations ec_ops
Definition: ec_acpi.c:261
static void fill_ssdt_typec_device(const struct device *dev)
Definition: ec_acpi.c:148
static const char * ec_acpi_name(const struct device *dev)
Definition: ec_acpi.c:256
const char * ec_retimer_fw_update_path(void)
Definition: ec_acpi.c:284
static void fill_ssdt_ps2_keyboard(const struct device *dev)
Definition: ec_acpi.c:232
static void add_port_location(struct acpi_dp *dsd, int port_number)
Definition: ec_acpi.c:122
void google_chromeec_fill_ssdt_generator(const struct device *dev)
Definition: ec_acpi.c:265
const char * google_chromeec_acpi_name(const struct device *dev)
Definition: ec_acpi.c:21
static void get_pld_from_usb_ports(struct acpi_pld *pld, struct device *usb2_port, struct device *usb3_port, struct device *usb4_port)
Definition: ec_acpi.c:127
#define GOOGLE_CHROMEEC_USBC_DEVICE_HID
Definition: ec_acpi.c:18
static void get_usb_port_references(int port_number, struct device **usb2_port, struct device **usb3_port, struct device **usb4_port)
Definition: ec_acpi.c:40
static struct usb_pd_port_caps port_caps
Definition: ec_acpi.c:121
static enum ps2_action_key ps2_enum_val[]
Definition: ec_acpi.c:208
#define KEYBD_CAP_NUMERIC_KEYPAD
Definition: ec_commands.h:6439
#define EC_CMD_GET_PD_PORT_CAPS
Definition: ec_commands.h:6292
#define MAX_TOP_ROW_KEYS
Definition: ec_commands.h:6427
@ TK_KBD_BKLIGHT_DOWN
Definition: ec_commands.h:6413
@ TK_PRIVACY_SCRN_TOGGLE
Definition: ec_commands.h:6412
@ TK_KBD_BKLIGHT_TOGGLE
Definition: ec_commands.h:6418
@ TK_VOL_UP
Definition: ec_commands.h:6410
@ TK_MICMUTE
Definition: ec_commands.h:6419
@ TK_VOL_MUTE
Definition: ec_commands.h:6408
@ TK_REFRESH
Definition: ec_commands.h:6403
@ TK_BRIGHTNESS_UP
Definition: ec_commands.h:6407
@ TK_PLAY_PAUSE
Definition: ec_commands.h:6415
@ TK_NEXT_TRACK
Definition: ec_commands.h:6416
@ TK_MENU
Definition: ec_commands.h:6420
@ TK_OVERVIEW
Definition: ec_commands.h:6405
@ TK_FORWARD
Definition: ec_commands.h:6402
@ TK_BACK
Definition: ec_commands.h:6401
@ TK_ABSENT
Definition: ec_commands.h:6400
@ TK_BRIGHTNESS_DOWN
Definition: ec_commands.h:6406
@ TK_SNAPSHOT
Definition: ec_commands.h:6411
@ TK_KBD_BKLIGHT_UP
Definition: ec_commands.h:6414
@ TK_VOL_DOWN
Definition: ec_commands.h:6409
@ TK_FULLSCREEN
Definition: ec_commands.h:6404
@ TK_PREV_TRACK
Definition: ec_commands.h:6417
#define KEYBD_CAP_SCRNLOCK_KEY
Definition: ec_commands.h:6443
ec_pd_port_location
Definition: ec_commands.h:6313
@ EC_PD_PORT_LOCATION_FRONT
Definition: ec_commands.h:6327
@ EC_PD_PORT_LOCATION_RIGHT
Definition: ec_commands.h:6325
@ EC_PD_PORT_LOCATION_UNKNOWN
Definition: ec_commands.h:6315
@ EC_PD_PORT_LOCATION_RIGHT_BACK
Definition: ec_commands.h:6331
@ EC_PD_PORT_LOCATION_BACK_RIGHT
Definition: ec_commands.h:6333
@ EC_PD_PORT_LOCATION_LEFT
Definition: ec_commands.h:6324
@ EC_PD_PORT_LOCATION_LEFT_BACK
Definition: ec_commands.h:6329
@ EC_PD_PORT_LOCATION_LEFT_FRONT
Definition: ec_commands.h:6328
@ EC_PD_PORT_LOCATION_BACK
Definition: ec_commands.h:6326
@ EC_PD_PORT_LOCATION_BACK_LEFT
Definition: ec_commands.h:6332
@ EC_PD_PORT_LOCATION_RIGHT_FRONT
Definition: ec_commands.h:6330
#define KEYBD_CAP_FUNCTION_KEYS
Definition: ec_commands.h:6435
void ec_fill_dptf_helpers(const struct device *ec)
port
Definition: i915.h:29
@ UPC_TYPE_C_USB2_SS
Definition: acpi.h:1049
@ UPC_TYPE_C_USB2_ONLY
Definition: acpi.h:1047
@ UPC_TYPE_C_USB2_SS_SWITCH
Definition: acpi.h:1048
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
enum board_config config
Definition: memory.c:448
@ DEVICE_PATH_USB
Definition: path.h:20
@ DEVICE_PATH_GENERIC
Definition: path.h:18
int acpi_pld_fill_usb(struct acpi_pld *pld, enum acpi_upc_type type, struct acpi_pld_group *group)
Definition: pld.c:8
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
struct generic_path generic
Definition: path.h:125
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
DEVTREE_CONST struct bus * bus
Definition: device.h:108
DEVTREE_CONST void * chip_info
Definition: device.h:164
uint8_t action_keys[MAX_TOP_ROW_KEYS]
Definition: ec_commands.h:6458
unsigned int subid
Definition: path.h:97
unsigned int id
Definition: path.h:96
Configuration required to write out a Type-C Connector ACPI object.
Definition: acpigen_usb.h:46
const struct acpi_pld * pld
Definition: acpigen_usb.h:56
const struct device * usb2_port
Definition: acpigen_usb.h:50
const struct device * usb3_port
Definition: acpigen_usb.h:51
const struct device * usb4_port
Definition: acpigen_usb.h:52
enum usb_typec_power_role power_role
Definition: acpigen_usb.h:47
enum ec_pd_power_role_caps power_role_cap
Definition: ec.h:339
enum ec_pd_try_power_role_caps try_power_role_cap
Definition: ec.h:340
enum ec_pd_port_location port_location
Definition: ec.h:342
enum ec_pd_data_role_caps data_role_cap
Definition: ec.h:341