/** * @file wm_io.c * * @brief IO Driver Module * * @author lilm * * Copyright (c) 2015 Winner Microelectronics Co., Ltd. */ #include "wm_regs.h" #include "wm_osal.h" #include "wm_io.h" #include "wm_dbg.h" #include "tls_common.h" static void io_cfg_option1(enum tls_io_name name) { u8 pin; u16 offset; if ( (WM_IO_PB_25 == name) || (WM_IO_PB_26 == name) || (WM_IO_PB_29 == name) ) { TLS_DBGPRT_IO_ERR("io %u have no option1.\r\n", name); return; } if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */ tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin))); tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin))); return; } static void io_cfg_option2(enum tls_io_name name) { u8 pin; u16 offset; if ( (WM_IO_PB_13 == name) || (WM_IO_PB_27 == name) || (WM_IO_PB_31 == name) ) { TLS_DBGPRT_IO_ERR("io %u have no option2.\r\n", name); return; } if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */ tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) & (~BIT(pin))); tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin)); return; } static void io_cfg_option3(enum tls_io_name name) { u8 pin; u16 offset; if ( (name == WM_IO_PB_19) || (name == WM_IO_PB_20) || (name >= WM_IO_PB_23) || (name == WM_IO_PA_00) || (name == WM_IO_PA_07) || ((name >= WM_IO_PA_13) && (name <= WM_IO_PA_15)) ) { TLS_DBGPRT_IO_ERR("io %u have no option3.\r\n", name); return; } if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */ tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin)); tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) & (~BIT(pin))); return; } static void io_cfg_option4(enum tls_io_name name) { u8 pin; u16 offset; if( (name == WM_IO_PA_00) || (name == WM_IO_PA_01) || (name == WM_IO_PA_06) || ((name >= WM_IO_PA_13) && (name <= WM_IO_PA_15)) || ((name >= WM_IO_PB_00) && (name <= WM_IO_PB_02)) || (name >= WM_IO_PB_19) ) { TLS_DBGPRT_IO_ERR("io %u have no option4.\r\n", name); return; } if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) | BIT(pin)); /* gpio function */ tls_reg_write32(HR_GPIO_AF_S1 + offset, tls_reg_read32(HR_GPIO_AF_S1 + offset) | BIT(pin)); tls_reg_write32(HR_GPIO_AF_S0 + offset, tls_reg_read32(HR_GPIO_AF_S0 + offset) | BIT(pin)); return; } static void io_cfg_option5(enum tls_io_name name) { u8 pin; u16 offset; if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin))); /* disable gpio function */ return; } static void io_cfg_option6(enum tls_io_name name) { u8 pin; u16 offset; if( ((name >= WM_IO_PB_06)&&(name <= WM_IO_PB_18)) || ((name >= WM_IO_PB_29)&&(name <= WM_IO_PB_31))) { TLS_DBGPRT_IO_ERR("io %u have no option6.\r\n", name); return; } if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } tls_reg_write32(HR_GPIO_AF_SEL + offset, tls_reg_read32(HR_GPIO_AF_SEL + offset) & (~BIT(pin))); /* disable gpio function */ tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin))); tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) & (~BIT(pin))); return; } /** * @brief This function is used to config io function * * @param[in] name io name * @param[in] option io function option, value is WM_IO_OPT*_*, also is WM_IO_OPTION1-6 * * @return None * * @note None */ void tls_io_cfg_set(enum tls_io_name name, u8 option) { if (WM_IO_OPTION1 == option) io_cfg_option1(name); else if (WM_IO_OPTION2 == option) io_cfg_option2(name); else if (WM_IO_OPTION3 == option) io_cfg_option3(name); else if (WM_IO_OPTION4 == option) io_cfg_option4(name); else if (WM_IO_OPTION5 == option) io_cfg_option5(name); else if (WM_IO_OPTION6 == option) io_cfg_option6(name); else TLS_DBGPRT_IO_ERR("invalid io option.\r\n"); return; } /** * @brief This function is used to get io function config * * @param[in] name io name * * @retval WM_IO_OPTION1~6 Mapping io function * * @note None */ int tls_io_cfg_get(enum tls_io_name name) { u8 pin; u16 offset; u32 afsel,afs1,afs0,dir,pullen; if (name >= WM_IO_PB_00) { pin = name - WM_IO_PB_00; offset = TLS_IO_AB_OFFSET; } else { pin = name; offset = 0; } afsel = tls_reg_read32(HR_GPIO_AF_SEL + offset); afs1 = tls_reg_read32(HR_GPIO_AF_S1 + offset); afs0 = tls_reg_read32(HR_GPIO_AF_S0 + offset); dir = tls_reg_read32(HR_GPIO_DIR + offset); pullen = tls_reg_read32(HR_GPIO_PULL_EN + offset); if(afsel&BIT(pin)) { if((0==(afs1&BIT(pin))) && (0==(afs0&BIT(pin)))) return WM_IO_OPTION1; else if((0==(afs1&BIT(pin))) && (afs0&BIT(pin))) return WM_IO_OPTION2; else if((afs1&BIT(pin)) && (0==(afs0&BIT(pin)))) return WM_IO_OPTION3; else if((afs1&BIT(pin)) && (afs0&BIT(pin))) return WM_IO_OPTION4; } else { if((!(dir&BIT(pin))) && (pullen&BIT(pin))) return WM_IO_OPTION6; else return WM_IO_OPTION5; } return 0; }