blob: 1c645a4729ce33df4c55baaf87ac437638c94f10 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVICES_BOARD_DRIVERS_X86_ACPI_DEV_DEV_CROS_EC_DEV_H_
#define SRC_DEVICES_BOARD_DRIVERS_X86_ACPI_DEV_DEV_CROS_EC_DEV_H_
#include <fuchsia/hardware/hidbus/cpp/banjo.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <memory>
#include <acpica/acpi.h>
#include <chromiumos-platform-ec/ec_commands.h>
#include <ddktl/device.h>
#include <fbl/array.h>
#include <fbl/macros.h>
#include <fbl/mutex.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
#include <fbl/span.h>
#include <fbl/vector.h>
namespace cros_ec {
class EmbeddedController : public fbl::RefCounted<EmbeddedController> {
public:
virtual ~EmbeddedController() {}
// Issue a command to the EC.
virtual zx_status_t IssueCommand(uint16_t command, uint8_t command_version, const void* input,
size_t input_size, void* result, size_t result_buff_size,
size_t* actual) = 0;
// Return true if the platform supports the given feature.
virtual bool SupportsFeature(enum ec_feature_code feature) const = 0;
// Send a fixed-sized command to the EC with a fixed-size output.
//
// These call into the raw "IssueCommand" method above.
template <typename Input, typename Output>
zx_status_t IssueCommand(uint16_t command, uint8_t command_version, const Input& input,
Output* output);
template <typename Output>
zx_status_t IssueCommand(uint16_t command, uint8_t command_version, Output* output);
};
// Initialise detected devices in the DDK. Exposed for testing.
zx_status_t InitDevices(fbl::RefPtr<EmbeddedController> controller, zx_device_t* parent,
ACPI_HANDLE acpi_handle);
//
// Implementation details follow.
//
// Send a fixed-sized command to the EC with a fixed-size output.
template <typename Input, typename Output>
zx_status_t EmbeddedController::IssueCommand(uint16_t command, uint8_t command_version,
const Input& input, Output* output) {
static_assert(!std::is_pointer<Input>::value, "Input type should be a reference, not pointer.");
static_assert(std::is_pod<Input>::value, "Input type should be POD.");
static_assert(std::is_pod<Output>::value, "Output type should be POD.");
size_t actual;
zx_status_t status = this->IssueCommand(command, command_version, &input, sizeof(Input), output,
sizeof(Output), &actual);
if (status != ZX_OK) {
return status;
}
if (actual != sizeof(Output)) {
return ZX_ERR_IO;
}
return ZX_OK;
}
// Send a command with no input to the EC with a fixed-size output.
template <typename Output>
zx_status_t EmbeddedController::IssueCommand(uint16_t command, uint8_t command_version,
Output* output) {
static_assert(std::is_pod<Output>::value, "Output type should be POD.");
size_t actual;
zx_status_t status =
this->IssueCommand(command, command_version, nullptr, 0, output, sizeof(Output), &actual);
if (status != ZX_OK) {
return status;
}
if (actual != sizeof(Output)) {
return ZX_ERR_IO;
}
return ZX_OK;
}
} // namespace cros_ec
#endif // SRC_DEVICES_BOARD_DRIVERS_X86_ACPI_DEV_DEV_CROS_EC_DEV_H_