drivers: usb: usb_dc_it82xx2: optimize the basic/extend endpoints control
This commit refactors the basic and extended endpoint control functions to enhance readability. Signed-off-by: Ren Chen <Ren.Chen@ite.com.tw>
This commit is contained in:
parent
40fa61213e
commit
5762d022dc
2 changed files with 276 additions and 292 deletions
|
@ -65,12 +65,6 @@ enum it82xx2_transaction_types {
|
|||
/* Bit definitions of the register Port0/Port1 MISC Control: 0XE4/0xE8 */
|
||||
#define PULL_DOWN_EN BIT(4)
|
||||
|
||||
/* Bit definitions of the register EPN0N1_EXTEND_CONTROL_REG: 0X98 ~ 0X9D */
|
||||
#define EPN1_OUTDATA_SEQ BIT(4)
|
||||
#define EPN0_ISO_ENABLE BIT(2)
|
||||
#define EPN0_SEND_STALL BIT(1)
|
||||
#define EPN0_OUTDATA_SEQ BIT(0)
|
||||
|
||||
/* ENDPOINT[3..0]_STATUS_REG */
|
||||
#define DC_STALL_SENT BIT(5)
|
||||
|
||||
|
@ -92,10 +86,7 @@ enum it82xx2_transaction_types {
|
|||
/* ENDPOINT[3..0]_CONTROL_REG */
|
||||
#define ENDPOINT_EN BIT(0)
|
||||
#define ENDPOINT_RDY BIT(1)
|
||||
#define EP_OUTDATA_SEQ BIT(2)
|
||||
#define EP_SEND_STALL BIT(3)
|
||||
#define EP_ISO_ENABLE BIT(4)
|
||||
#define EP_DIRECTION BIT(5)
|
||||
|
||||
enum it82xx2_ep_status {
|
||||
EP_INIT = 0,
|
||||
|
@ -120,23 +111,15 @@ enum it82xx2_setup_stage {
|
|||
STALL_SEND,
|
||||
};
|
||||
|
||||
enum it82xx2_extend_ep_ctrl {
|
||||
/* EPN0N1_EXTEND_CONTROL_REG */
|
||||
EXT_EP_ISO_DISABLE,
|
||||
EXT_EP_ISO_ENABLE,
|
||||
EXT_EP_SEND_STALL,
|
||||
EXT_EP_CLEAR_STALL,
|
||||
EXT_EP_CHECK_STALL,
|
||||
EXT_EP_DATA_SEQ_1,
|
||||
EXT_EP_DATA_SEQ_0,
|
||||
EXT_EP_DATA_SEQ_INV,
|
||||
/* EPN_EXTEND_CONTROL1_REG */
|
||||
EXT_EP_DIR_IN,
|
||||
EXT_EP_DIR_OUT,
|
||||
EXT_EP_ENABLE,
|
||||
EXT_EP_DISABLE,
|
||||
/* EPN_EXTEND_CONTROL2_REG */
|
||||
EXT_EP_READY,
|
||||
enum it82xx2_ep_ctrl {
|
||||
EP_IN_DIRECTION_SET,
|
||||
EP_STALL_SEND,
|
||||
EP_STALL_CHECK,
|
||||
EP_IOS_ENABLE,
|
||||
EP_ENABLE,
|
||||
EP_DATA_SEQ_1,
|
||||
EP_DATA_SEQ_TOGGLE,
|
||||
EP_READY_ENABLE,
|
||||
};
|
||||
|
||||
struct usb_it8xxx2_wuc {
|
||||
|
@ -197,36 +180,11 @@ struct usb_it82xx2_data {
|
|||
struct k_work_delayable check_suspended_work;
|
||||
};
|
||||
|
||||
/* Mapped to the bit definitions in the EPN_EXTEND_CONTROL1 Register
|
||||
* (D6h to DDh) for configuring the FIFO direction and for enabling/disabling
|
||||
* the endpoints.
|
||||
*/
|
||||
static uint8_t ext_ep_bit_shift[12] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};
|
||||
|
||||
/* The ep_fifo_res[ep_idx % FIFO_NUM] where the FIFO_NUM is 3 represents the
|
||||
* EP mapping because when (ep_idx % FIFO_NUM) is 3, it actually means the EP0.
|
||||
*/
|
||||
static const uint8_t ep_fifo_res[3] = {3, 1, 2};
|
||||
|
||||
/* Mapping the enum it82xx2_extend_ep_ctrl code to their corresponding bit in
|
||||
* the EP45/67/89/1011/1213/1415 Extended Control Registers.
|
||||
*/
|
||||
static const uint8_t ext_ctrl_tbl[8] = {
|
||||
EPN0_ISO_ENABLE,
|
||||
EPN0_ISO_ENABLE,
|
||||
EPN0_SEND_STALL,
|
||||
EPN0_SEND_STALL,
|
||||
EPN0_SEND_STALL,
|
||||
EPN0_OUTDATA_SEQ,
|
||||
EPN0_OUTDATA_SEQ,
|
||||
EPN0_OUTDATA_SEQ,
|
||||
};
|
||||
|
||||
/* Indexing of the following control codes:
|
||||
* EXT_EP_DIR_IN, EXT_EP_DIR_OUT, EXT_EP_ENABLE, EXT_EP_DISABLE
|
||||
*/
|
||||
static const uint8_t epn_ext_ctrl_tbl[4] = {1, 0, 1, 0};
|
||||
|
||||
static struct usb_it82xx2_data udata0;
|
||||
|
||||
static struct usb_it82xx2_regs *it82xx2_get_usb_regs(void)
|
||||
|
@ -338,158 +296,196 @@ static int it82xx2_usb_fifo_ctrl(uint8_t ep)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions it82xx2_epn0n1_ext_ctrl_cfg() and epn0n1_ext_ctrl_cfg_seq_inv()
|
||||
* provide the entrance of configuring the EPN0N1 Extended Ctrl Registers.
|
||||
*
|
||||
* The variable set_clr determines if we set/clear the corresponding bit.
|
||||
*/
|
||||
static void it82xx2_epn0n1_ext_ctrl_cfg(uint8_t reg_idx, uint8_t bit_mask,
|
||||
bool set_clr)
|
||||
static volatile void *it82xx2_get_ext_ctrl(int ep_idx, enum it82xx2_ep_ctrl ctrl)
|
||||
{
|
||||
uint8_t idx;
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
volatile uint8_t *epn0n1_ext_ctrl =
|
||||
union epn0n1_extend_ctrl_reg *epn0n1_ext_ctrl =
|
||||
usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
|
||||
|
||||
(set_clr) ? (epn0n1_ext_ctrl[reg_idx] |= bit_mask) :
|
||||
(epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask));
|
||||
}
|
||||
|
||||
static void it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(uint8_t reg_idx,
|
||||
uint8_t bit_mask, bool set_clr)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
volatile uint8_t *epn0n1_ext_ctrl =
|
||||
usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
|
||||
|
||||
bool check = (set_clr) ? (epn0n1_ext_ctrl[reg_idx] & EPN1_OUTDATA_SEQ)
|
||||
: (epn0n1_ext_ctrl[reg_idx] & EPN0_OUTDATA_SEQ);
|
||||
|
||||
(check) ? (epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask)) :
|
||||
(epn0n1_ext_ctrl[reg_idx] |= bit_mask);
|
||||
}
|
||||
|
||||
/* Return the status of STALL bit in the EPN0N1 Extend Control Registers */
|
||||
static bool it82xx2_epn01n1_check_stall(uint8_t reg_idx, uint8_t bit_mask)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
volatile uint8_t *epn0n1_ext_ctrl =
|
||||
usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;
|
||||
|
||||
return !!(epn0n1_ext_ctrl[reg_idx] & bit_mask);
|
||||
}
|
||||
|
||||
/* Configuring the EPN Extended Ctrl Registers. */
|
||||
static void it82xx2_epn_ext_ctrl_cfg1(uint8_t reg_idx, uint8_t bit_mask,
|
||||
bool set_clr)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct epn_ext_ctrl_regs *epn_ext_ctrl =
|
||||
struct epn_ext_ctrl_regs *ext_ctrl =
|
||||
usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
|
||||
|
||||
(set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl1 |= bit_mask) :
|
||||
(epn_ext_ctrl[reg_idx].epn_ext_ctrl1 &= ~(bit_mask));
|
||||
if ((ctrl == EP_IN_DIRECTION_SET) || (ctrl == EP_ENABLE)) {
|
||||
idx = ((ep_idx - 4) % 3) + 1;
|
||||
return &ext_ctrl[idx].epn_ext_ctrl1;
|
||||
}
|
||||
|
||||
idx = (ep_idx - 4) / 2;
|
||||
return &epn0n1_ext_ctrl[idx];
|
||||
}
|
||||
|
||||
static void it82xx2_epn_ext_ctrl_cfg2(uint8_t reg_idx, uint8_t bit_mask,
|
||||
bool set_clr)
|
||||
static int it82xx2_usb_extend_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enable)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct epn_ext_ctrl_regs *epn_ext_ctrl =
|
||||
struct usb_it82xx2_regs *const usb_regs = (struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct epn_ext_ctrl_regs *ext_ctrl =
|
||||
usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;
|
||||
|
||||
(set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl2 |= bit_mask) :
|
||||
(epn_ext_ctrl[reg_idx].epn_ext_ctrl2 &= ~(bit_mask));
|
||||
}
|
||||
|
||||
/* From 98h to 9Dh, the EP45/67/89/1011/1213/1415 Extended Control Registers
|
||||
* are defined, and their bits definitions are as follows:
|
||||
*
|
||||
* Bit Description
|
||||
* 7 Reserved
|
||||
* 6 EPPOINT5_ISO_ENABLE
|
||||
* 5 EPPOINT5_SEND_STALL
|
||||
* 4 EPPOINT5_OUT_DATA_SEQUENCE
|
||||
* 3 Reserved
|
||||
* 2 EPPOINT4_ISO_ENABLE
|
||||
* 1 EPPOINT4_SEND_STALL
|
||||
* 0 EPPOINT4_OUT_DATA_SEQUENCE
|
||||
*
|
||||
* Apparently, we can tell that the EP4 and EP5 share the same register, and
|
||||
* the EP6 and EP7 share the same one, and the other EPs are defined in the
|
||||
* same way.
|
||||
*
|
||||
* In the function it82xx2_usb_extend_ep_ctrl() we will obtain the mask/flag
|
||||
* according to the bits definitions mentioned above. As for the control code,
|
||||
* please refer to the definition of enum it82xx2_extend_ep_ctrl.
|
||||
*/
|
||||
static int it82xx2_usb_extend_ep_ctrl(uint8_t ep_idx,
|
||||
enum it82xx2_extend_ep_ctrl ctrl)
|
||||
{
|
||||
uint8_t reg_idx, mask;
|
||||
bool flag;
|
||||
union epn_extend_ctrl1_reg *epn_ext_ctrl1 = NULL;
|
||||
union epn0n1_extend_ctrl_reg *epn0n1_ext_ctrl = NULL;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ctrl >= EXT_EP_DIR_IN) && (ctrl < EXT_EP_READY)) {
|
||||
/* From EXT_EP_DIR_IN to EXT_EP_DISABLE */
|
||||
reg_idx = ep_fifo_res[ep_idx % FIFO_NUM];
|
||||
if (ctrl == EXT_EP_DIR_IN || ctrl == EXT_EP_DIR_OUT) {
|
||||
mask = BIT(ext_ep_bit_shift[ep_idx - 4] * 2 + 1);
|
||||
} else {
|
||||
mask = BIT(ext_ep_bit_shift[ep_idx - 4] * 2);
|
||||
}
|
||||
flag = epn_ext_ctrl_tbl[ctrl - EXT_EP_DIR_IN];
|
||||
it82xx2_epn_ext_ctrl_cfg1(reg_idx, mask, flag);
|
||||
|
||||
} else if ((ctrl >= EXT_EP_ISO_DISABLE) && (ctrl < EXT_EP_DIR_IN)) {
|
||||
/* From EXT_EP_ISO_DISABLE to EXT_EP_DATA_SEQ_0 */
|
||||
reg_idx = (ep_idx - 4) >> 1;
|
||||
flag = !!(ep_idx & 1);
|
||||
mask = flag ? (ext_ctrl_tbl[ctrl] << 4) : (ext_ctrl_tbl[ctrl]);
|
||||
|
||||
switch (ctrl) {
|
||||
case EXT_EP_CHECK_STALL:
|
||||
return it82xx2_epn01n1_check_stall(reg_idx, mask);
|
||||
case EXT_EP_DATA_SEQ_INV:
|
||||
it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(reg_idx, mask, flag);
|
||||
break;
|
||||
case EXT_EP_ISO_DISABLE:
|
||||
__fallthrough;
|
||||
case EXT_EP_CLEAR_STALL:
|
||||
__fallthrough;
|
||||
case EXT_EP_DATA_SEQ_0:
|
||||
it82xx2_epn0n1_ext_ctrl_cfg(reg_idx, mask, false);
|
||||
break;
|
||||
case EXT_EP_ISO_ENABLE:
|
||||
__fallthrough;
|
||||
case EXT_EP_SEND_STALL:
|
||||
__fallthrough;
|
||||
case EXT_EP_DATA_SEQ_1:
|
||||
it82xx2_epn0n1_ext_ctrl_cfg(reg_idx, mask, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (ctrl == EXT_EP_READY) {
|
||||
reg_idx = (ep_idx - 4) >> 1;
|
||||
mask = 1 << (ext_ep_bit_shift[ep_idx - 4]);
|
||||
it82xx2_epn_ext_ctrl_cfg2(reg_idx, mask, true);
|
||||
if ((ctrl == EP_IN_DIRECTION_SET) || (ctrl == EP_ENABLE)) {
|
||||
epn_ext_ctrl1 = (union epn_extend_ctrl1_reg *)it82xx2_get_ext_ctrl(ep_idx, ctrl);
|
||||
} else {
|
||||
LOG_ERR("Invalid Control Code of Endpoint");
|
||||
epn0n1_ext_ctrl =
|
||||
(union epn0n1_extend_ctrl_reg *)it82xx2_get_ext_ctrl(ep_idx, ctrl);
|
||||
}
|
||||
|
||||
switch (ctrl) {
|
||||
case EP_STALL_SEND:
|
||||
if (ep_idx % 2) {
|
||||
epn0n1_ext_ctrl->fields.epn1_send_stall_bit = enable;
|
||||
} else {
|
||||
epn0n1_ext_ctrl->fields.epn0_send_stall_bit = enable;
|
||||
}
|
||||
break;
|
||||
case EP_STALL_CHECK:
|
||||
if (ep_idx % 2) {
|
||||
return epn0n1_ext_ctrl->fields.epn1_send_stall_bit;
|
||||
} else {
|
||||
return epn0n1_ext_ctrl->fields.epn0_send_stall_bit;
|
||||
}
|
||||
break;
|
||||
case EP_IOS_ENABLE:
|
||||
if (ep_idx % 2) {
|
||||
epn0n1_ext_ctrl->fields.epn1_iso_enable_bit = enable;
|
||||
} else {
|
||||
epn0n1_ext_ctrl->fields.epn0_iso_enable_bit = enable;
|
||||
}
|
||||
break;
|
||||
case EP_DATA_SEQ_1:
|
||||
if (ep_idx % 2) {
|
||||
epn0n1_ext_ctrl->fields.epn1_outdata_sequence_bit = enable;
|
||||
} else {
|
||||
epn0n1_ext_ctrl->fields.epn0_outdata_sequence_bit = enable;
|
||||
}
|
||||
break;
|
||||
case EP_DATA_SEQ_TOGGLE:
|
||||
if (!enable) {
|
||||
break;
|
||||
}
|
||||
if (ep_idx % 2) {
|
||||
if (epn0n1_ext_ctrl->fields.epn1_outdata_sequence_bit) {
|
||||
epn0n1_ext_ctrl->fields.epn1_outdata_sequence_bit = 0;
|
||||
} else {
|
||||
epn0n1_ext_ctrl->fields.epn1_outdata_sequence_bit = 1;
|
||||
}
|
||||
} else {
|
||||
if (epn0n1_ext_ctrl->fields.epn0_outdata_sequence_bit) {
|
||||
epn0n1_ext_ctrl->fields.epn0_outdata_sequence_bit = 0;
|
||||
} else {
|
||||
epn0n1_ext_ctrl->fields.epn0_outdata_sequence_bit = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EP_IN_DIRECTION_SET:
|
||||
if (((ep_idx - 4) / 3 == 0)) {
|
||||
epn_ext_ctrl1->fields.epn0_direction_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 1)) {
|
||||
epn_ext_ctrl1->fields.epn3_direction_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 2)) {
|
||||
epn_ext_ctrl1->fields.epn6_direction_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 3)) {
|
||||
epn_ext_ctrl1->fields.epn9_direction_bit = enable;
|
||||
} else {
|
||||
LOG_ERR("Invalid endpoint 0x%x for control type 0x%x", ep, ctrl);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case EP_ENABLE:
|
||||
if (((ep_idx - 4) / 3 == 0)) {
|
||||
epn_ext_ctrl1->fields.epn0_enable_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 1)) {
|
||||
epn_ext_ctrl1->fields.epn3_enable_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 2)) {
|
||||
epn_ext_ctrl1->fields.epn6_enable_bit = enable;
|
||||
} else if (((ep_idx - 4) / 3 == 3)) {
|
||||
epn_ext_ctrl1->fields.epn9_enable_bit = enable;
|
||||
} else {
|
||||
LOG_ERR("Invalid endpoint 0x%x for control type 0x%x", ep, ctrl);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case EP_READY_ENABLE:
|
||||
int idx = ((ep_idx - 4) % 3) + 1;
|
||||
|
||||
(enable) ? (ext_ctrl[idx].epn_ext_ctrl2 |= BIT((ep_idx - 4) / 3))
|
||||
: (ext_ctrl[idx].epn_ext_ctrl2 &= ~BIT((ep_idx - 4) / 3));
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unknown control type 0x%x", ctrl);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it82xx2_usb_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enable)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (ctrl) {
|
||||
case EP_IN_DIRECTION_SET:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.direction_bit = enable;
|
||||
break;
|
||||
case EP_STALL_SEND:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.send_stall_bit = enable;
|
||||
break;
|
||||
case EP_STALL_CHECK:
|
||||
return ep_regs[ep_idx].ep_ctrl.fields.send_stall_bit;
|
||||
case EP_IOS_ENABLE:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.iso_enable_bit = enable;
|
||||
break;
|
||||
case EP_ENABLE:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.enable_bit = enable;
|
||||
break;
|
||||
case EP_READY_ENABLE:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.ready_bit = enable;
|
||||
break;
|
||||
case EP_DATA_SEQ_1:
|
||||
ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit = enable;
|
||||
break;
|
||||
case EP_DATA_SEQ_TOGGLE:
|
||||
if (!enable) {
|
||||
break;
|
||||
}
|
||||
if (ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit) {
|
||||
ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit = 0;
|
||||
} else {
|
||||
ep_regs[ep_idx].ep_ctrl.fields.outdata_sequence_bit = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unknown control type 0x%x", ctrl);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int it82xx2_usb_set_ep_ctrl(uint8_t ep, enum it82xx2_ep_ctrl ctrl, bool enable)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
int ret = 0;
|
||||
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ret = it82xx2_usb_extend_ep_ctrl(ep, ctrl, enable);
|
||||
} else {
|
||||
ret = it82xx2_usb_ep_ctrl(ep, ctrl, enable);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int it82xx2_usb_dc_ip_init(void)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
|
@ -551,7 +547,7 @@ static inline void it82xx2_handler_setup(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
|
||||
/* wrong trans */
|
||||
if (ep_ctrl & EP_SEND_STALL) {
|
||||
ep_regs[fifo_idx].ep_ctrl &= ~EP_SEND_STALL;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.send_stall_bit = 0;
|
||||
udata0.st_state = STALL_SEND;
|
||||
ff_regs[fifo_idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
|
||||
LOG_DBG("Clear Stall Bit & RX FIFO");
|
||||
|
@ -580,12 +576,12 @@ static inline void it82xx2_handler_setup(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
udata0.now_token = SETUP_TOKEN;
|
||||
udata0.st_state = SETUP_ST;
|
||||
|
||||
ep_regs[fifo_idx].ep_ctrl |= EP_OUTDATA_SEQ;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.outdata_sequence_bit = 1;
|
||||
udata0.ep_data[ep_idx].cb_out(ep_idx | USB_EP_DIR_OUT, USB_DC_EP_SETUP);
|
||||
|
||||
/* Set ready bit to no-data control in */
|
||||
if (udata0.no_data_ctrl) {
|
||||
ep_regs[fifo_idx].ep_ctrl |= ENDPOINT_RDY;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1;
|
||||
udata0.no_data_ctrl = false;
|
||||
}
|
||||
}
|
||||
|
@ -612,7 +608,7 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
} else {
|
||||
ep_idx = 0;
|
||||
if (ep_ctrl & EP_SEND_STALL) {
|
||||
ep_regs[0].ep_ctrl &= ~EP_SEND_STALL;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.send_stall_bit = 0;
|
||||
udata0.st_state = STALL_SEND;
|
||||
LOG_DBG("Clear Stall Bit");
|
||||
return;
|
||||
|
@ -625,7 +621,8 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
udata0.last_token = udata0.now_token;
|
||||
udata0.now_token = IN_TOKEN;
|
||||
|
||||
if (udata0.addr != DC_ADDR_NULL && udata0.addr != usb_regs->dc_address) {
|
||||
if (udata0.addr != DC_ADDR_NULL &&
|
||||
udata0.addr != usb_regs->dc_address) {
|
||||
usb_regs->dc_address = udata0.addr;
|
||||
LOG_DBG("Address Is Set Successfully");
|
||||
}
|
||||
|
@ -633,7 +630,9 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
if (udata0.st_state == DOUT_ST) {
|
||||
/* setup -> out(data) -> in(status) */
|
||||
udata0.st_state = STATUS_ST;
|
||||
} else if (udata0.ep_data[0].remaining == 0 && udata0.st_state == SETUP_ST) {
|
||||
|
||||
} else if (udata0.ep_data[ep_idx].remaining == 0 &&
|
||||
udata0.st_state == SETUP_ST) {
|
||||
/* setup -> in(status) */
|
||||
udata0.st_state = STATUS_ST;
|
||||
} else {
|
||||
|
@ -642,11 +641,7 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
}
|
||||
}
|
||||
|
||||
if (!!(ep_regs[fifo_idx].ep_ctrl & EP_OUTDATA_SEQ)) {
|
||||
ep_regs[fifo_idx].ep_ctrl &= ~EP_OUTDATA_SEQ;
|
||||
} else {
|
||||
ep_regs[fifo_idx].ep_ctrl |= EP_OUTDATA_SEQ;
|
||||
}
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_DATA_SEQ_TOGGLE, true);
|
||||
|
||||
if (udata0.ep_data[ep_idx].cb_in) {
|
||||
udata0.ep_data[ep_idx].cb_in(ep_idx | USB_EP_DIR_IN, USB_DC_EP_DATA_IN);
|
||||
|
@ -656,7 +651,7 @@ static inline void it82xx2_handler_in(uint8_t fifo_idx, uint8_t ep_ctrl)
|
|||
k_sem_give(&udata0.fifo_sem[fifo_idx - 1]);
|
||||
} else {
|
||||
if (udata0.st_state == DIN_ST && udata0.ep_data[ep_idx].remaining == 0) {
|
||||
ep_regs[fifo_idx].ep_ctrl |= ENDPOINT_RDY;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -709,11 +704,11 @@ static inline void it82xx2_handler_out(uint8_t fifo_idx)
|
|||
udata0.last_token = udata0.now_token;
|
||||
udata0.now_token = SETUP_TOKEN;
|
||||
udata0.st_state = SETUP_ST;
|
||||
ep_regs[fifo_idx].ep_ctrl |= EP_OUTDATA_SEQ;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.outdata_sequence_bit = 1;
|
||||
udata0.ep_data[ep_idx].cb_out(ep_idx | USB_EP_DIR_OUT, USB_DC_EP_SETUP);
|
||||
|
||||
if (udata0.no_data_ctrl) {
|
||||
ep_regs[fifo_idx].ep_ctrl |= ENDPOINT_RDY;
|
||||
ep_regs[fifo_idx].ep_ctrl.fields.ready_bit = 1;
|
||||
udata0.no_data_ctrl = false;
|
||||
}
|
||||
}
|
||||
|
@ -727,7 +722,7 @@ static void it82xx2_usb_dc_trans_done(void)
|
|||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
for (uint8_t fifo_idx = 0; fifo_idx < 4; fifo_idx++) {
|
||||
uint8_t ep_ctrl = ep_regs[fifo_idx].ep_ctrl;
|
||||
uint8_t ep_ctrl = ep_regs[fifo_idx].ep_ctrl.value;
|
||||
|
||||
/* check ready bit ,will be 0 when trans done */
|
||||
if ((ep_ctrl & ENDPOINT_EN) && !(ep_ctrl & ENDPOINT_RDY)) {
|
||||
|
@ -912,7 +907,7 @@ int usb_dc_reset(void)
|
|||
}
|
||||
}
|
||||
|
||||
ep_regs[EP0].ep_ctrl = ENDPOINT_EN;
|
||||
ep_regs[0].ep_ctrl.value = ENDPOINT_EN;
|
||||
usb_regs->dc_address = DC_ADDR_NULL;
|
||||
udata0.addr = DC_ADDR_NULL;
|
||||
usb_regs->dc_interrupt_status = DC_NAK_SENT_INT | DC_SOF_RECEIVED;
|
||||
|
@ -978,10 +973,6 @@ int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
|
|||
|
||||
int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
|
||||
bool in = USB_EP_DIR_IS_IN(cfg->ep_addr);
|
||||
|
||||
|
@ -1005,56 +996,31 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
(in) ? (ep_regs[ep_idx].ep_ctrl |= EP_DIRECTION) :
|
||||
(ep_regs[ep_idx].ep_ctrl &= ~EP_DIRECTION);
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_IN_DIRECTION_SET, in);
|
||||
|
||||
} else {
|
||||
|
||||
(in) ? (it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_IN)) :
|
||||
(it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_OUT));
|
||||
|
||||
if (in) {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DATA_SEQ_0);
|
||||
if (in) {
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EP_DATA_SEQ_1, false);
|
||||
}
|
||||
|
||||
LOG_DBG("ep_status %d", udata0.ep_data[ep_idx].ep_status);
|
||||
}
|
||||
|
||||
(in) ? (udata0.ep_data[ep_idx].ep_status = EP_CONFIG_IN) :
|
||||
(udata0.ep_data[ep_idx].ep_status = EP_CONFIG_OUT);
|
||||
|
||||
if (!in) {
|
||||
udata0.ep_data[ep_idx].ep_status = EP_CONFIG_IN;
|
||||
} else {
|
||||
udata0.ep_data[ep_idx].ep_status = EP_CONFIG_OUT;
|
||||
it82xx2_usb_fifo_ctrl(cfg->ep_addr);
|
||||
}
|
||||
|
||||
switch (cfg->ep_type) {
|
||||
|
||||
case USB_DC_EP_CONTROL:
|
||||
return -EINVAL;
|
||||
|
||||
case USB_DC_EP_ISOCHRONOUS:
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ep_regs[ep_idx].ep_ctrl |= EP_ISO_ENABLE;
|
||||
} else {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_ENABLE);
|
||||
}
|
||||
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_IOS_ENABLE, true);
|
||||
break;
|
||||
|
||||
case USB_DC_EP_BULK:
|
||||
__fallthrough;
|
||||
case USB_DC_EP_INTERRUPT:
|
||||
__fallthrough;
|
||||
default:
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ep_regs[ep_idx].ep_ctrl &= ~EP_ISO_ENABLE;
|
||||
} else {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_DISABLE);
|
||||
}
|
||||
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_IOS_ENABLE, false);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
udata0.ep_data[ep_idx].ep_type = cfg->ep_type;
|
||||
|
@ -1091,24 +1057,23 @@ int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
|
|||
|
||||
int usb_dc_ep_enable(const uint8_t ep)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
int ret = 0;
|
||||
|
||||
if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
|
||||
LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ep_regs[ep_idx].ep_ctrl |= ENDPOINT_EN;
|
||||
} else {
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
uint8_t ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
|
||||
|
||||
ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_EN;
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ENABLE);
|
||||
it82xx2_usb_set_ep_ctrl(ep_fifo, EP_ENABLE, true);
|
||||
}
|
||||
|
||||
ret = it82xx2_usb_set_ep_ctrl(ep_idx, EP_ENABLE, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_DBG("Endpoint 0x%02x is enabled", ep);
|
||||
|
@ -1118,10 +1083,6 @@ int usb_dc_ep_enable(const uint8_t ep)
|
|||
|
||||
int usb_dc_ep_disable(uint8_t ep)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
|
||||
|
@ -1129,13 +1090,7 @@ int usb_dc_ep_disable(uint8_t ep)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ep_regs[ep_idx].ep_ctrl &= ~ENDPOINT_EN;
|
||||
} else {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DISABLE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return it82xx2_usb_set_ep_ctrl(ep_idx, EP_ENABLE, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1152,32 +1107,29 @@ int usb_dc_ep_set_stall(const uint8_t ep)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
ep_regs[ep_idx].ep_ctrl |= EP_SEND_STALL;
|
||||
} else {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_SEND_STALL);
|
||||
}
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_STALL_SEND, true);
|
||||
|
||||
if (ep_idx == EP0) {
|
||||
ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
|
||||
if (ep_idx == 0) {
|
||||
uint32_t idx = 0;
|
||||
|
||||
ep_regs[ep_idx].ep_ctrl.fields.ready_bit = 1;
|
||||
/* polling if stall send for 3ms */
|
||||
while (idx < 198 &&
|
||||
!(ep_regs[EP0].ep_status & DC_STALL_SENT)) {
|
||||
!(ep_regs[ep_idx].ep_status & DC_STALL_SENT)) {
|
||||
/* wait 15.15us */
|
||||
gctrl_regs->GCTRL_WNCKR = 0;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (idx < 198) {
|
||||
ep_regs[EP0].ep_ctrl &= ~EP_SEND_STALL;
|
||||
ep_regs[ep_idx].ep_ctrl.fields.send_stall_bit = 0;
|
||||
}
|
||||
|
||||
udata0.no_data_ctrl = false;
|
||||
udata0.st_state = STALL_SEND;
|
||||
}
|
||||
|
||||
LOG_DBG("EP(%d) ctrl: 0x%02x", ep_idx, ep_regs[ep_idx].ep_ctrl);
|
||||
LOG_DBG("EP(%d) ctrl: 0x%02x", ep_idx, ep_regs[ep_idx].ep_ctrl.value);
|
||||
LOG_DBG("EP(%d) Set Stall", ep_idx);
|
||||
|
||||
return 0;
|
||||
|
@ -1185,17 +1137,13 @@ int usb_dc_ep_set_stall(const uint8_t ep)
|
|||
|
||||
int usb_dc_ep_clear_stall(const uint8_t ep)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (ep_idx >= MAX_NUM_ENDPOINTS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ep_regs[ep_idx].ep_ctrl &= ~EP_SEND_STALL;
|
||||
it82xx2_usb_set_ep_ctrl(ep_idx, EP_STALL_SEND, false);
|
||||
LOG_DBG("EP(%d) clear stall", ep_idx);
|
||||
|
||||
return 0;
|
||||
|
@ -1203,23 +1151,13 @@ int usb_dc_ep_clear_stall(const uint8_t ep)
|
|||
|
||||
int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
struct usb_it82xx2_regs *const usb_regs =
|
||||
(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
|
||||
struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
|
||||
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if ((!stalled) || (ep_idx >= MAX_NUM_ENDPOINTS)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
*stalled =
|
||||
(0 != (ep_regs[ep_idx].ep_ctrl & EP_SEND_STALL));
|
||||
} else {
|
||||
*stalled = it82xx2_usb_extend_ep_ctrl(ep_idx,
|
||||
EXT_EP_CHECK_STALL);
|
||||
}
|
||||
*stalled = it82xx2_usb_set_ep_ctrl(ep_idx, EP_STALL_CHECK, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1304,10 +1242,10 @@ int usb_dc_ep_write(uint8_t ep, const uint8_t *buf,
|
|||
}
|
||||
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true);
|
||||
}
|
||||
|
||||
ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
|
||||
ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1;
|
||||
|
||||
if (ep_fifo > EP0) {
|
||||
udata0.fifo_ready[ep_fifo - 1] = true;
|
||||
|
@ -1344,7 +1282,7 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
|
|||
*read_bytes = 0;
|
||||
|
||||
if (ep_idx > 0) {
|
||||
ep_regs[ep_idx].ep_ctrl |= ENDPOINT_RDY;
|
||||
ep_regs[ep_idx].ep_ctrl.fields.ready_bit = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1396,8 +1334,10 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
|
|||
}
|
||||
|
||||
if (ep_fifo > EP0) {
|
||||
ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
|
||||
ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1;
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true);
|
||||
}
|
||||
udata0.fifo_ready[ep_fifo - 1] = true;
|
||||
} else if (udata0.now_token == SETUP_TOKEN) {
|
||||
if (!(buf[0] & USB_EP_DIR_MASK)) {
|
||||
|
@ -1405,7 +1345,8 @@ int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
|
|||
ff_regs[0].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
|
||||
if (buf[6] != 0 || buf[7] != 0) {
|
||||
/* set status IN after data OUT */
|
||||
ep_regs[0].ep_ctrl |= ENDPOINT_RDY | EP_OUTDATA_SEQ;
|
||||
ep_regs[0].ep_ctrl.fields.outdata_sequence_bit = 1;
|
||||
ep_regs[0].ep_ctrl.fields.ready_bit = 1;
|
||||
} else {
|
||||
/* no_data_ctrl status */
|
||||
udata0.no_data_ctrl = true;
|
||||
|
@ -1479,8 +1420,10 @@ int usb_dc_ep_read_continue(uint8_t ep)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
|
||||
ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
|
||||
if (IT8XXX2_IS_EXTEND_ENDPOINT(ep_idx)) {
|
||||
it82xx2_usb_extend_ep_ctrl(ep_idx, EP_READY_ENABLE, true);
|
||||
}
|
||||
ep_regs[ep_fifo].ep_ctrl.fields.ready_bit = 1;
|
||||
udata0.fifo_ready[ep_fifo - 1] = true;
|
||||
LOG_DBG("EP(%d) Read Continue", ep_idx);
|
||||
return 0;
|
||||
|
|
|
@ -481,8 +481,21 @@ enum usb_dc_endpoints {
|
|||
MAX_NUM_ENDPOINTS
|
||||
};
|
||||
|
||||
union ep_ctrl_reg {
|
||||
volatile uint8_t value;
|
||||
struct {
|
||||
volatile uint8_t enable_bit: 1;
|
||||
volatile uint8_t ready_bit: 1;
|
||||
volatile uint8_t outdata_sequence_bit: 1;
|
||||
volatile uint8_t send_stall_bit: 1;
|
||||
volatile uint8_t iso_enable_bit: 1;
|
||||
volatile uint8_t direction_bit: 1;
|
||||
volatile uint8_t reserved: 2;
|
||||
} __packed fields;
|
||||
} __packed;
|
||||
|
||||
struct it82xx2_usb_ep_regs {
|
||||
volatile uint8_t ep_ctrl;
|
||||
union ep_ctrl_reg ep_ctrl;
|
||||
volatile uint8_t ep_status;
|
||||
volatile uint8_t ep_transtype_sts;
|
||||
volatile uint8_t ep_nak_transtype_sts;
|
||||
|
@ -531,6 +544,20 @@ struct ep_ext_regs_7x {
|
|||
* the EP6 and EP7 share the same one, and the rest EPs are defined in the
|
||||
* same way.
|
||||
*/
|
||||
union epn0n1_extend_ctrl_reg {
|
||||
volatile uint8_t value;
|
||||
struct {
|
||||
volatile uint8_t epn0_outdata_sequence_bit: 1;
|
||||
volatile uint8_t epn0_send_stall_bit: 1;
|
||||
volatile uint8_t epn0_iso_enable_bit: 1;
|
||||
volatile uint8_t reserved0: 1;
|
||||
volatile uint8_t epn1_outdata_sequence_bit: 1;
|
||||
volatile uint8_t epn1_send_stall_bit: 1;
|
||||
volatile uint8_t epn1_iso_enable_bit: 1;
|
||||
volatile uint8_t reserved1: 1;
|
||||
} __packed fields;
|
||||
} __packed;
|
||||
|
||||
struct ep_ext_regs_9x {
|
||||
/* 0x95 Reserved */
|
||||
volatile uint8_t ep_ext_ctrl_95;
|
||||
|
@ -539,7 +566,7 @@ struct ep_ext_regs_9x {
|
|||
/* 0x97 Reserved */
|
||||
volatile uint8_t ep_ext_ctrl_97;
|
||||
/* 0x98 ~ 0x9D EP45/67/89/1011/1213/1415 Extended Control Registers */
|
||||
volatile uint8_t epn0n1_ext_ctrl[6];
|
||||
union epn0n1_extend_ctrl_reg epn0n1_ext_ctrl[6];
|
||||
/* 0x9E Reserved */
|
||||
volatile uint8_t ep_ext_ctrl_9e;
|
||||
/* 0x9F Reserved */
|
||||
|
@ -602,9 +629,23 @@ struct ep_ext_regs_bx {
|
|||
* We classify them into 4 groups which each of them contains Control 1 and 2
|
||||
* according to the EP number as follows:
|
||||
*/
|
||||
union epn_extend_ctrl1_reg {
|
||||
volatile uint8_t value;
|
||||
struct {
|
||||
volatile uint8_t epn0_enable_bit: 1;
|
||||
volatile uint8_t epn0_direction_bit: 1;
|
||||
volatile uint8_t epn3_enable_bit: 1;
|
||||
volatile uint8_t epn3_direction_bit: 1;
|
||||
volatile uint8_t epn6_enable_bit: 1;
|
||||
volatile uint8_t epn6_direction_bit: 1;
|
||||
volatile uint8_t epn9_enable_bit: 1;
|
||||
volatile uint8_t epn9_direction_bit: 1;
|
||||
} __packed fields;
|
||||
} __packed;
|
||||
|
||||
struct epn_ext_ctrl_regs {
|
||||
/* 0xD6/0xD8/0xDA/0xDC EPN Extended Control1 Register */
|
||||
volatile uint8_t epn_ext_ctrl1;
|
||||
union epn_extend_ctrl1_reg epn_ext_ctrl1;
|
||||
/* 0xD7/0xD9/0xDB/0xDD EPB Extended Control2 Register */
|
||||
volatile uint8_t epn_ext_ctrl2;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue