cros_ec: Support reading EC features
The EC can support a variety of features and provides a way to find out what is available. Add support for this. Also update the feature list to the lastest available while we are here. This is at: https://chromium.googlesource.com/chromiumos/platform/ec/+/refs/heads/master/include/ec_commands.h Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
7791df576c
commit
8aec32f6ab
@ -94,6 +94,74 @@ static int do_read_write(struct udevice *dev, int is_write, int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const feat_name[64] = {
|
||||
"limited",
|
||||
"flash",
|
||||
"pwm_fan",
|
||||
"pwm_keyb",
|
||||
"lightbar",
|
||||
"led",
|
||||
"motion_sense",
|
||||
"keyb",
|
||||
"pstore",
|
||||
"port80",
|
||||
"thermal",
|
||||
"bklight_switch",
|
||||
"wifi_switch",
|
||||
"host_events",
|
||||
"gpio",
|
||||
"i2c",
|
||||
"charger",
|
||||
"battery",
|
||||
"smart_battery",
|
||||
"hang_detect",
|
||||
"pmu",
|
||||
"sub_mcu",
|
||||
"usb_pd",
|
||||
"usb_mux",
|
||||
"motion_sense_fifo",
|
||||
"vstore",
|
||||
"usbc_ss_mux_virtual",
|
||||
"rtc",
|
||||
"fingerprint",
|
||||
"touchpad",
|
||||
"rwsig",
|
||||
"device_event",
|
||||
"unified_wake_masks",
|
||||
"host_event64",
|
||||
"exec_in_ram",
|
||||
"cec",
|
||||
"motion_sense_tight_timestamps",
|
||||
"refined_tablet_mode_hysteresis",
|
||||
"efs2",
|
||||
"scp",
|
||||
"ish",
|
||||
"typec_cmd",
|
||||
"typec_require_ap_mode_entry",
|
||||
"typec_mux_require_ap_ack",
|
||||
};
|
||||
|
||||
static int do_show_features(struct udevice *dev)
|
||||
{
|
||||
u64 feat;
|
||||
int ret;
|
||||
uint i;
|
||||
|
||||
ret = cros_ec_get_features(dev, &feat);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (i = 0; i < ARRAY_SIZE(feat_name); i++) {
|
||||
if (feat & (1ULL << i)) {
|
||||
if (feat_name[i])
|
||||
printf("%s\n", feat_name[i]);
|
||||
else
|
||||
printf("unknown %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
@ -140,6 +208,11 @@ static int do_cros_ec(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
}
|
||||
printf("rows = %u\n", info.rows);
|
||||
printf("cols = %u\n", info.cols);
|
||||
} else if (!strcmp("features", cmd)) {
|
||||
ret = do_show_features(dev);
|
||||
|
||||
if (ret)
|
||||
printf("Error: %d\n", ret);
|
||||
} else if (0 == strcmp("curimage", cmd)) {
|
||||
enum ec_current_image image;
|
||||
|
||||
@ -379,6 +452,7 @@ U_BOOT_CMD(
|
||||
"init Re-init CROS-EC (done on startup automatically)\n"
|
||||
"crosec id Read CROS-EC ID\n"
|
||||
"crosec info Read CROS-EC info\n"
|
||||
"crosec features Read CROS-EC features\n"
|
||||
"crosec curimage Read CROS-EC current image\n"
|
||||
"crosec hash Read CROS-EC hash\n"
|
||||
"crosec reboot [rw | ro | cold] Reboot CROS-EC\n"
|
||||
|
@ -1344,19 +1344,33 @@ int cros_ec_i2c_tunnel(struct udevice *dev, int port, struct i2c_msg *in,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_check_feature(struct udevice *dev, int feature)
|
||||
int cros_ec_get_features(struct udevice *dev, u64 *featuresp)
|
||||
{
|
||||
struct ec_response_get_features r;
|
||||
int rv;
|
||||
|
||||
rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, &r, sizeof(r), NULL, 0);
|
||||
if (rv)
|
||||
return rv;
|
||||
rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
|
||||
if (rv != sizeof(r))
|
||||
return -EIO;
|
||||
*featuresp = r.flags[0] | (u64)r.flags[1] << 32;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cros_ec_check_feature(struct udevice *dev, uint feature)
|
||||
{
|
||||
struct ec_response_get_features r;
|
||||
int rv;
|
||||
|
||||
rv = ec_command(dev, EC_CMD_GET_FEATURES, 0, NULL, 0, &r, sizeof(r));
|
||||
if (rv != sizeof(r))
|
||||
return -EIO;
|
||||
|
||||
if (feature >= 8 * sizeof(r.flags))
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
|
||||
return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature);
|
||||
return r.flags[feature / 32] & EC_FEATURE_MASK_0(feature) ? true :
|
||||
false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -480,6 +480,17 @@ static int process_cmd(struct ec_state *ec,
|
||||
len = sizeof(*resp);
|
||||
break;
|
||||
}
|
||||
case EC_CMD_GET_FEATURES: {
|
||||
struct ec_response_get_features *resp = resp_data;
|
||||
|
||||
resp->flags[0] = EC_FEATURE_MASK_0(EC_FEATURE_FLASH) |
|
||||
EC_FEATURE_MASK_0(EC_FEATURE_I2C);
|
||||
resp->flags[1] =
|
||||
EC_FEATURE_MASK_1(EC_FEATURE_UNIFIED_WAKE_MASKS) |
|
||||
EC_FEATURE_MASK_1(EC_FEATURE_ISH);
|
||||
len = sizeof(*resp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf(" ** Unknown EC command %#02x\n", req_hdr->command);
|
||||
return -1;
|
||||
|
@ -516,4 +516,25 @@ int cros_ec_set_lid_shutdown_mask(struct udevice *dev, int enable);
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_hello(struct udevice *dev, uint *handshakep);
|
||||
|
||||
/**
|
||||
* cros_ec_get_features() - Get the set of features provided by the EC
|
||||
*
|
||||
* See enum ec_feature_code for the list of available features
|
||||
*
|
||||
* @dev: CROS-EC device
|
||||
* @featuresp: Returns a bitmask of supported features
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int cros_ec_get_features(struct udevice *dev, u64 *featuresp);
|
||||
|
||||
/**
|
||||
* cros_ec_check_feature() - Check if a feature is supported
|
||||
*
|
||||
* @dev: CROS-EC device
|
||||
* @feature: Feature number to check (enum ec_feature_code)
|
||||
* @return true if supported, false if not, -ve on error
|
||||
*/
|
||||
int cros_ec_check_feature(struct udevice *dev, uint feature);
|
||||
|
||||
#endif
|
||||
|
@ -1101,13 +1101,50 @@ enum ec_feature_code {
|
||||
EC_FEATURE_DEVICE_EVENT = 31,
|
||||
/* EC supports the unified wake masks for LPC/eSPI systems */
|
||||
EC_FEATURE_UNIFIED_WAKE_MASKS = 32,
|
||||
/* EC supports 64-bit host events */
|
||||
EC_FEATURE_HOST_EVENT64 = 33,
|
||||
/* EC runs code in RAM (not in place, a.k.a. XIP) */
|
||||
EC_FEATURE_EXEC_IN_RAM = 34,
|
||||
/* EC supports CEC commands */
|
||||
EC_FEATURE_CEC = 35,
|
||||
/* EC supports tight sensor timestamping. */
|
||||
EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS = 36,
|
||||
/*
|
||||
* EC supports tablet mode detection aligned to Chrome and allows
|
||||
* setting of threshold by host command using
|
||||
* MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE.
|
||||
*/
|
||||
EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37,
|
||||
/*
|
||||
* Early Firmware Selection ver.2. Enabled by CONFIG_VBOOT_EFS2.
|
||||
* Note this is a RO feature. So, a query (EC_CMD_GET_FEATURES) should
|
||||
* be sent to RO to be precise.
|
||||
*/
|
||||
EC_FEATURE_EFS2 = 38,
|
||||
/* The MCU is a System Companion Processor (SCP). */
|
||||
EC_FEATURE_SCP = 39,
|
||||
/* The MCU is an Integrated Sensor Hub */
|
||||
EC_FEATURE_ISH = 40,
|
||||
/* New TCPMv2 TYPEC_ prefaced commands supported */
|
||||
EC_FEATURE_TYPEC_CMD = 41,
|
||||
/*
|
||||
* The EC will wait for direction from the AP to enter Type-C alternate
|
||||
* modes or USB4.
|
||||
*/
|
||||
EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY = 42,
|
||||
/*
|
||||
* The EC will wait for an acknowledge from the AP after setting the
|
||||
* mux.
|
||||
*/
|
||||
EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43,
|
||||
};
|
||||
|
||||
#define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32))
|
||||
#define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32))
|
||||
struct __ec_align4 ec_response_get_features {
|
||||
#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
|
||||
#define EC_FEATURE_MASK_1(event_code) BIT(event_code - 32)
|
||||
|
||||
struct ec_response_get_features {
|
||||
uint32_t flags[2];
|
||||
};
|
||||
} __ec_align4;
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Get the board's SKU ID from EC */
|
||||
|
@ -47,3 +47,31 @@ static int dm_test_cros_ec_sku_id(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_cros_ec_sku_id, UT_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_cros_ec_features(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
u64 feat;
|
||||
|
||||
ut_assertok(uclass_first_device_err(UCLASS_CROS_EC, &dev));
|
||||
ut_assertok(cros_ec_get_features(dev, &feat));
|
||||
ut_asserteq_64(1U << EC_FEATURE_FLASH | 1U << EC_FEATURE_I2C |
|
||||
1ULL << EC_FEATURE_UNIFIED_WAKE_MASKS | 1ULL << EC_FEATURE_ISH,
|
||||
feat);
|
||||
|
||||
ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_I2C));
|
||||
ut_asserteq(false, cros_ec_check_feature(dev, EC_FEATURE_MOTION_SENSE));
|
||||
ut_asserteq(true, cros_ec_check_feature(dev, EC_FEATURE_ISH));
|
||||
|
||||
/* try the command */
|
||||
console_record_reset();
|
||||
ut_assertok(run_command("crosec features", 0));
|
||||
ut_assert_nextline("flash");
|
||||
ut_assert_nextline("i2c");
|
||||
ut_assert_nextline("unified_wake_masks");
|
||||
ut_assert_nextline("ish");
|
||||
ut_assert_console_end();
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_cros_ec_features, UT_TESTF_SCAN_FDT);
|
||||
|
Loading…
Reference in New Issue
Block a user