blob: ec7d05d393f4a8b65a61a585dc1915e78b5165c8 [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0+
/*
* GPIO flag: read from the EC to determine a flag value
*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#define LOG_CATEGORY UCLASS_CROS_VBOOT_FLAG
#include <common.h>
#include <cros_ec.h>
#include <dm.h>
#include <log.h>
#include <cros/vboot_flag.h>
static int flag_cros_ec_read(struct udevice *dev)
{
struct vboot_flag_uc_priv *uc_priv = dev_get_uclass_priv(dev);
struct udevice *cros_ec = dev_get_parent(dev);
int ret;
switch (uc_priv->flag) {
case VBOOT_FLAG_LID_OPEN:
ret = cros_ec_get_switches(cros_ec);
if (ret < 0)
return log_msg_ret("lid", ret);
return !!(ret & EC_SWITCH_LID_OPEN);
case VBOOT_FLAG_RECOVERY: {
u32 events;
ret = cros_ec_get_host_events(cros_ec, &events);
if (ret)
return log_msg_ret("rec", ret);
return !!(events &
EC_HOST_EVENT_MASK(EC_HOST_EVENT_KEYBOARD_RECOVERY));
}
default:
return -EINVAL;
}
return 0;
}
static int flag_cros_ec_probe(struct udevice *dev)
{
struct vboot_flag_uc_priv *uc_priv = dev_get_uclass_priv(dev);
struct udevice *cros_ec = dev_get_parent(dev);
if (device_get_uclass_id(cros_ec) != UCLASS_CROS_EC)
return log_msg_ret("uc", -EPROTOTYPE);
if (uc_priv->flag != VBOOT_FLAG_LID_OPEN &&
uc_priv->flag != VBOOT_FLAG_RECOVERY)
return log_msg_ret("uc", -ENOTSUPP);
return 0;
}
static const struct vboot_flag_ops flag_cros_ec_ops = {
.read = flag_cros_ec_read,
};
static const struct udevice_id flag_cros_ec_ids[] = {
{ .compatible = "google,cros-ec-flag" },
{ }
};
U_BOOT_DRIVER(google_cros_ec_flag) = {
.name = "google_cros_ec_flag",
.id = UCLASS_CROS_VBOOT_FLAG,
.of_match = flag_cros_ec_ids,
.probe = flag_cros_ec_probe,
.ops = &flag_cros_ec_ops,
};