/*
 * SPDX-FileCopyrightText: Copyright (c) 2019 Ha Thach (tinyusb.org)
 * SPDX-License-Identifier: MIT
 *
 * This file is part of the TinyUSB stack.
 */

#ifndef TUSB_HUB_H_
#define TUSB_HUB_H_

#include "common/tusb_common.h"

#ifdef __cplusplus
 extern "C" {
#endif

//--------------------------------------------------------------------+
// Configuration
//--------------------------------------------------------------------+

#ifndef CFG_TUH_HUB_BUFSIZE
  #define CFG_TUH_HUB_BUFSIZE 12
#endif

//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
enum {
  HUB_REQUEST_GET_STATUS      = 0  ,
  HUB_REQUEST_CLEAR_FEATURE   = 1  ,
  // 2 is reserved
  HUB_REQUEST_SET_FEATURE     = 3  ,
  // 4-5 are reserved
  HUB_REQUEST_GET_DESCRIPTOR  = 6  ,
  HUB_REQUEST_SET_DESCRIPTOR  = 7  ,
  HUB_REQUEST_CLEAR_TT_BUFFER = 8  ,
  HUB_REQUEST_RESET_TT        = 9  ,
  HUB_REQUEST_GET_TT_STATE    = 10 ,
  HUB_REQUEST_STOP_TT         = 11
};

enum {
  HUB_FEATURE_HUB_LOCAL_POWER_CHANGE = 0,
  HUB_FEATURE_HUB_OVER_CURRENT_CHANGE
};

enum{
  HUB_FEATURE_PORT_CONNECTION          = 0,
  HUB_FEATURE_PORT_ENABLE              = 1,
  HUB_FEATURE_PORT_SUSPEND             = 2,
  HUB_FEATURE_PORT_OVER_CURRENT        = 3,
  HUB_FEATURE_PORT_RESET               = 4,
  // 5-7 are reserved
  HUB_FEATURE_PORT_POWER               = 8,
  HUB_FEATURE_PORT_LOW_SPEED           = 9,
  // 10-15 are reserved
  HUB_FEATURE_PORT_CONNECTION_CHANGE   = 16,
  HUB_FEATURE_PORT_ENABLE_CHANGE       = 17,
  HUB_FEATURE_PORT_SUSPEND_CHANGE      = 18,
  HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19,
  HUB_FEATURE_PORT_RESET_CHANGE        = 20,
  HUB_FEATURE_PORT_TEST                = 21,
  HUB_FEATURE_PORT_INDICATOR           = 22
};

enum {
  HUB_CHARS_POWER_GANGED_SWITCHING = 0,
  HUB_CHARS_POWER_INDIVIDUAL_SWITCHING = 1,
};

enum {
  HUB_CHARS_OVER_CURRENT_GLOBAL = 0,
  HUB_CHARS_OVER_CURRENT_INDIVIDUAL = 1,
};

// Hub Interface Protocol (USB 2.0 spec Table 11-16)
typedef enum {
  HUB_PROTOCOL_FULL_SPEED     = 0, // Full speed hub
  HUB_PROTOCOL_HIGH_SPEED_STT = 1, // Hi-speed hub with single TT
  HUB_PROTOCOL_HIGH_SPEED_MTT = 2, // Hi-speed hub with multiple TTs
} hub_protocol_t;

typedef struct TU_ATTR_PACKED{
  uint8_t  bLength           ; ///< Size of descriptor
  uint8_t  bDescriptorType   ; ///< Other_speed_Configuration Type
  uint8_t  bNbrPorts;
  uint16_t wHubCharacteristics;
  uint8_t  bPwrOn2PwrGood;
  uint8_t  bHubContrCurrent;
  uint8_t  DeviceRemovable; // bitmap each bit for a port (from bit1)
  uint8_t  PortPwrCtrlMask; // just for compatibility, should be 0xff
} hub_desc_cs_t;
TU_VERIFY_STATIC(sizeof(hub_desc_cs_t) == 9, "size is not correct");
TU_VERIFY_STATIC(CFG_TUH_HUB_BUFSIZE >= sizeof(hub_desc_cs_t), "buffer is not big enough");

typedef struct TU_ATTR_PACKED {
  struct TU_ATTR_PACKED {
    uint8_t logical_power_switching_mode : 2; // [0..1] gannged or individual power switching
    uint8_t compound_device              : 1; // [2] hub is part of compound device
    uint8_t over_current_protect_mode    : 2; // [3..4] global or individual port over-current protection
    uint8_t tt_think_time                : 2; // [5..6] TT think time
    uint8_t port_indicator_supported     : 1; // [7] port indicator supported
  };
  uint8_t rsv1;
} hub_characteristics_t;
TU_VERIFY_STATIC(sizeof(hub_characteristics_t) == 2, "size is not correct");

// data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub)
typedef struct {
  union{
    struct TU_ATTR_PACKED {
      uint16_t local_power_source : 1;
      uint16_t over_current       : 1;
      uint16_t : 14;
    };

    uint16_t value;
  } status, change;
} hub_status_response_t;
TU_VERIFY_STATIC( sizeof(hub_status_response_t) == 4, "size is not correct");

// data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num
typedef struct {
  union TU_ATTR_PACKED {
    struct TU_ATTR_PACKED {
      // Bit 0-4 are for change & status
      uint16_t connection             : 1; // [0] 0 = no device, 1 = device connected
      uint16_t port_enable            : 1; // [1] port is enabled
      uint16_t suspend                : 1; // [2]
      uint16_t over_current           : 1; // [3] over-current exists
      uint16_t reset                  : 1; // [4] 0 = no reset, 1 = resetting

      // From Bit 5 are for status only
      uint16_t rsv5_7                 : 3; // [5..7] reserved
      uint16_t port_power             : 1; // [8] 0 = port is off, 1 = port is on
      uint16_t low_speed              : 1; // [9] low speed device attached
      uint16_t high_speed             : 1; // [10] high speed device attached
      uint16_t port_test_mode         : 1; // [11] port in test mode
      uint16_t port_indicator_control : 1; // [12] 0: default color, 1: indicator is software controlled
      uint16_t TU_RESERVED            : 3; // [13..15] reserved
    };

    uint16_t value;
  } status, change;
} hub_port_status_response_t;
TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct");

//--------------------------------------------------------------------+
// HUB API
//--------------------------------------------------------------------+

// Clear port feature
bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
                            tuh_xfer_cb_t complete_cb, uintptr_t user_data);

// Set port feature
bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
                          tuh_xfer_cb_t complete_cb, uintptr_t user_data);

// Get port status
// If hub_port != 0, resp is ignored. hub_port_get_status_local() can be used to retrieve the status
bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void *resp,
                         tuh_xfer_cb_t complete_cb, uintptr_t user_data);

// Get port status from local cache. This does not send a request to the device
bool hub_port_get_status_local(uint8_t hub_addr, uint8_t hub_port, hub_port_status_response_t* resp);

// Get status from Interrupt endpoint
bool hub_edpt_status_xfer(uint8_t daddr);

// Reset a port
TU_ATTR_ALWAYS_INLINE static inline
bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data);
}

// Clear Port Reset Change
TU_ATTR_ALWAYS_INLINE static inline
bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data);
}

// Get Hub status (port = 0)
TU_ATTR_ALWAYS_INLINE static inline
bool hub_get_status(uint8_t hub_addr, void* resp, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return hub_port_get_status(hub_addr, 0, resp, complete_cb, user_data);
}

// Clear Hub feature
TU_ATTR_ALWAYS_INLINE static inline
bool hub_clear_feature(uint8_t hub_addr, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
  return hub_port_clear_feature(hub_addr, 0, feature, complete_cb, user_data);
}
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
bool     hub_init(void);
bool     hub_deinit(void);
uint16_t hub_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface_t *itf_desc, uint16_t max_len);
bool     hub_set_config(uint8_t daddr, uint8_t itf_num);
bool     hub_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void     hub_close(uint8_t dev_addr);

#ifdef __cplusplus
 }
#endif

#endif
