// Copyright 2019 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_UI_INPUT_DRIVERS_I2C_HID_I2C_HID_H_
#define SRC_UI_INPUT_DRIVERS_I2C_HID_I2C_HID_H_

#include <fidl/fuchsia.hardware.acpi/cpp/wire.h>
#include <fuchsia/hardware/hidbus/cpp/banjo.h>
#include <lib/device-protocol/i2c-channel.h>
#include <threads.h>

#include <memory>
#include <optional>

#include <ddktl/device.h>
#include <fbl/condition_variable.h>
#include <fbl/mutex.h>

#include "src/devices/lib/acpi/client.h"

namespace i2c_hid {

// The I2c Hid Command codes.
constexpr uint8_t kResetCommand = 0x01;
constexpr uint8_t kGetReportCommand = 0x02;
constexpr uint8_t kSetReportCommand = 0x03;

// The i2c descriptor that describes the i2c's registers Ids.
// This is populated directly from an I2cRead call, so all
// of the values are in little endian.
struct I2cHidDesc {
  uint16_t wHIDDescLength;
  uint16_t bcdVersion;
  uint16_t wReportDescLength;
  uint16_t wReportDescRegister;
  uint16_t wInputRegister;
  uint16_t wMaxInputLength;
  uint16_t wOutputRegister;
  uint16_t wMaxOutputLength;
  uint16_t wCommandRegister;
  uint16_t wDataRegister;
  uint16_t wVendorID;
  uint16_t wProductID;
  uint16_t wVersionID;
  uint8_t RESERVED[4];
} __PACKED;

class I2cHidbus;
using DeviceType = ddk::Device<I2cHidbus, ddk::Initializable, ddk::Unbindable>;

class I2cHidbus : public DeviceType, public ddk::HidbusProtocol<I2cHidbus, ddk::base_protocol> {
 public:
  explicit I2cHidbus(zx_device_t* device, acpi::Client client)
      : DeviceType(device), acpi_client_(std::move(client)) {}
  ~I2cHidbus() = default;

  // Methods required by the ddk mixins.
  zx_status_t HidbusStart(const hidbus_ifc_protocol_t* ifc);
  zx_status_t HidbusQuery(uint32_t options, hid_info_t* info);
  void HidbusStop();
  zx_status_t HidbusGetDescriptor(hid_description_type_t desc_type, uint8_t* out_data_buffer,
                                  size_t data_size, size_t* out_data_actual);
  zx_status_t HidbusGetReport(uint8_t rpt_type, uint8_t rpt_id, uint8_t* data, size_t len,
                              size_t* out_len);
  zx_status_t HidbusSetReport(uint8_t rpt_type, uint8_t rpt_id, const uint8_t* data, size_t len);

  // TODO(https://fxbug.dev/42109818): implement the rest of the HID protocol
  zx_status_t HidbusGetIdle(uint8_t rpt_id, uint8_t* duration) { return ZX_ERR_NOT_SUPPORTED; }
  zx_status_t HidbusSetIdle(uint8_t rpt_id, uint8_t duration) { return ZX_ERR_NOT_SUPPORTED; }
  zx_status_t HidbusGetProtocol(uint8_t* protocol) { return ZX_ERR_NOT_SUPPORTED; }
  zx_status_t HidbusSetProtocol(uint8_t protocol) { return ZX_OK; }

  void DdkInit(ddk::InitTxn txn);
  void DdkUnbind(ddk::UnbindTxn txn);
  void DdkRelease();
  zx_status_t Bind(ddk::I2cChannel i2c);

  zx_status_t ReadI2cHidDesc(I2cHidDesc* hiddesc);

  // Must be called with i2c_lock held.
  void WaitForReadyLocked() __TA_REQUIRES(i2c_lock_);

  zx_status_t Reset(bool force) __TA_EXCLUDES(i2c_lock_);

 private:
  void Shutdown();

  I2cHidDesc hiddesc_ = {};

  // Signaled when reset received.
  fbl::ConditionVariable i2c_reset_cnd_;

  std::optional<ddk::InitTxn> init_txn_;

  std::atomic_bool worker_thread_started_ = false;
  std::atomic_bool stop_worker_thread_ = false;
  thrd_t worker_thread_;
  zx::interrupt irq_;
  // The functions to be run in the worker thread. They are responsible for initializing the
  // driver and then reading Reports. If the I2c parent driver supports interrupts,
  // then |WorkerThreadIrq| will be used. Otherwise |WorkerThreadNoIrq| will be used and the
  // driver will poll periodically.
  int WorkerThreadIrq();
  int WorkerThreadNoIrq();

  fbl::Mutex ifc_lock_;
  ddk::HidbusIfcProtocolClient ifc_ __TA_GUARDED(ifc_lock_);

  fbl::Mutex i2c_lock_;
  ddk::I2cChannel i2c_ __TA_GUARDED(i2c_lock_);
  // True if reset-in-progress. Initalize as true so no work gets done until this is cleared.
  bool i2c_pending_reset_ __TA_GUARDED(i2c_lock_) = true;

  acpi::Client acpi_client_;
};

}  // namespace i2c_hid

#endif  // SRC_UI_INPUT_DRIVERS_I2C_HID_I2C_HID_H_
