blob: 5324af24c81b0438271976f576c30c4565ceaecc [file] [log] [blame]
// Copyright 2020 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_MCU_DRIVERS_VIM3_MCU_VIM3_MCU_H_
#define SRC_DEVICES_MCU_DRIVERS_VIM3_MCU_VIM3_MCU_H_
#include <fidl/fuchsia.hardware.fan/cpp/fidl.h>
#include <lib/ddk/device.h>
#include <lib/inspect/cpp/inspect.h>
#include <threads.h>
#include <optional>
#include <ddktl/device.h>
#include <ddktl/protocol/empty-protocol.h>
#include <fbl/mutex.h>
#include "src/devices/i2c/lib/i2c-channel-legacy/i2c-channel.h"
// STM8S003 MCU specific reg definitions
// dl.khadas.com/Hardware/VIM3/MCU/VIM3_MCU_REG_EN.pdf for reg details
#if 0
#define STM_MCU_CHIP_ADDR 0x18
// RO
#define STM_MCU_REG_PASSWD_VEN 0x00
#define STM_MCU_REG_MAC 0x06
#define STM_MCU_REG_USID 0x0c
#define STM_MCU_REG_VERSION 0x12
#define STM_MCU_REG_SHUTDOWN_NORMAL_STATUS_REG 0x86
// RW
#define STM_MCU_REG_BOOT_MODE 0x20
#define STM_MCU_REG_BOOT_EN_RTC 0x22
#define STM_MCU_REG_BOOT_EN_EXP 0x23
#define STM_MCU_REG_BOOT_EN_IR 0x24
#define STM_MCU_REG_BOOT_EN_DCIN 0x25
#define STM_MCU_REG_BOOT_EN_KEY 0x26
#define STM_MCU_REG_LED_SYSTEM_ON_MODE 0x28
#define STM_MCU_REG_LED_SYSTEM_OFF_MODE 0x29
#define STM_MCU_REG_MAC_SWITCH 0x2d
// WO
#define STM_MCU_REG_PWR_OFF_CMD_REG 0x80
#define STM_MCU_REG_PASSWD_START_REG 0x81
#define STM_MCU_REG_CHECK_VEN_PASSWD_REG 0x82
#define STM_MCU_REG_CHECK_USER_PASSWD_REG 0x83
#define STM_MCU_REG_WOL_INIT_START_REG 0x87
#endif
#define STM_MCU_REG_BOOT_EN_WOL 0x21
#define STM_MCU_REG_CMD_FAN_STATUS_CTRL_REG 0x88
#define STM_MCU_REG_EN_WOL_RESET_ENABLE 0x03
#define STM_MCU_USB_PCIE_SWITCH_REG 0x33
// Vim3MCU is an external MCU made by STM used in vim3 for
// fan control and WoL
//
// For now this only sets the fan level on boot
namespace stm {
enum FanLevel {
FL0,
FL1,
FL2,
FL3,
MAX,
};
class StmMcu;
using DeviceType = ddk::Device<StmMcu, ddk::Unbindable>;
class StmMcu : public DeviceType, public fidl::WireServer<fuchsia_hardware_fan::Device> {
public:
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(StmMcu);
StmMcu(zx_device_t* parent, ddk::I2cChannel i2c) : DeviceType(parent), i2c_(std::move(i2c)) {}
~StmMcu() {}
static zx_status_t Create(void* ctx, zx_device_t* parent);
void Init(); // Visible for testing.
void DdkUnbind(ddk::UnbindTxn txn);
void DdkRelease();
// fuchsia_hardware_fan.Device protocol implementation.
void GetFanLevel(GetFanLevelCompleter::Sync& completer) override {
if (fan_level_ >= FanLevel::MAX) {
completer.Reply(ZX_ERR_INTERNAL, fan_level_);
return;
}
completer.Reply(ZX_OK, fan_level_);
}
void SetFanLevel(SetFanLevelRequestView request, SetFanLevelCompleter::Sync& completer) override {
if (request->fan_level >= FanLevel::MAX) {
completer.Reply(ZX_ERR_OUT_OF_RANGE);
return;
}
completer.Reply(SetFanLevel(static_cast<FanLevel>(request->fan_level)));
}
void GetClientType(GetClientTypeCompleter::Sync& completer) override { completer.Reply("fan"); }
zx::vmo inspect_vmo() const { return inspect_.DuplicateVmo(); }
private:
zx_status_t SetFanLevel(FanLevel level);
ddk::I2cChannel i2c_;
void ShutDown();
fbl::Mutex i2c_lock_;
inspect::Inspector inspect_;
fidl::ServerBindingGroup<fuchsia_hardware_fan::Device> bindings_;
FanLevel fan_level_ = FanLevel::MAX;
};
} // namespace stm
#endif // SRC_DEVICES_MCU_DRIVERS_VIM3_MCU_VIM3_MCU_H_