12ee67178SXianjun Jiao /* 22ee67178SXianjun Jiao * axi lite register access driver 32ee67178SXianjun Jiao * Xianjun jiao. [email protected]; [email protected] 42ee67178SXianjun Jiao */ 52ee67178SXianjun Jiao 62ee67178SXianjun Jiao #include <linux/bitops.h> 72ee67178SXianjun Jiao #include <linux/dmapool.h> 82ee67178SXianjun Jiao #include <linux/dma/xilinx_dma.h> 92ee67178SXianjun Jiao #include <linux/init.h> 102ee67178SXianjun Jiao #include <linux/interrupt.h> 112ee67178SXianjun Jiao #include <linux/io.h> 122ee67178SXianjun Jiao #include <linux/iopoll.h> 132ee67178SXianjun Jiao #include <linux/module.h> 142ee67178SXianjun Jiao #include <linux/of_address.h> 152ee67178SXianjun Jiao #include <linux/of_dma.h> 162ee67178SXianjun Jiao #include <linux/of_platform.h> 172ee67178SXianjun Jiao #include <linux/of_irq.h> 182ee67178SXianjun Jiao #include <linux/slab.h> 192ee67178SXianjun Jiao #include <linux/clk.h> 202ee67178SXianjun Jiao #include <linux/io-64-nonatomic-lo-hi.h> 212ee67178SXianjun Jiao 222ee67178SXianjun Jiao #include "../hw_def.h" 232ee67178SXianjun Jiao 242ee67178SXianjun Jiao static void __iomem *base_addr; // to store driver specific base address needed for mmu to translate virtual address to physical address in our FPGA design 252ee67178SXianjun Jiao 262ee67178SXianjun Jiao /* IO accessors */ 272ee67178SXianjun Jiao static inline u32 reg_read(u32 reg) 282ee67178SXianjun Jiao { 292ee67178SXianjun Jiao return ioread32(base_addr + reg); 302ee67178SXianjun Jiao } 312ee67178SXianjun Jiao 322ee67178SXianjun Jiao static inline void reg_write(u32 reg, u32 value) 332ee67178SXianjun Jiao { 342ee67178SXianjun Jiao iowrite32(value, base_addr + reg); 352ee67178SXianjun Jiao } 362ee67178SXianjun Jiao 372ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MULTI_RST_read(void){ 382ee67178SXianjun Jiao return reg_read(RX_INTF_REG_MULTI_RST_ADDR); 392ee67178SXianjun Jiao } 402ee67178SXianjun Jiao 412ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MIXER_CFG_read(void){ 422ee67178SXianjun Jiao return reg_read(RX_INTF_REG_MIXER_CFG_ADDR); 432ee67178SXianjun Jiao } 442ee67178SXianjun Jiao 452ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_SRC_SEL_read(void){ 462ee67178SXianjun Jiao return reg_read(RX_INTF_REG_IQ_SRC_SEL_ADDR); 472ee67178SXianjun Jiao } 482ee67178SXianjun Jiao 492ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_CTRL_read(void){ 502ee67178SXianjun Jiao return reg_read(RX_INTF_REG_IQ_CTRL_ADDR); 512ee67178SXianjun Jiao } 522ee67178SXianjun Jiao 532ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_MODE_read(void){ 542ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR); 552ee67178SXianjun Jiao } 562ee67178SXianjun Jiao 572ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_read(void){ 582ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_ADDR); 592ee67178SXianjun Jiao } 602ee67178SXianjun Jiao 612ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read(void){ 622ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR); 632ee67178SXianjun Jiao } 642ee67178SXianjun Jiao 652ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read(void){ 662ee67178SXianjun Jiao return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR); 672ee67178SXianjun Jiao } 682ee67178SXianjun Jiao 692ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read(void){ 702ee67178SXianjun Jiao return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR); 712ee67178SXianjun Jiao } 722ee67178SXianjun Jiao 732ee67178SXianjun Jiao static inline u32 RX_INTF_REG_CFG_DATA_TO_ANT_read(void){ 742ee67178SXianjun Jiao return reg_read(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR); 752ee67178SXianjun Jiao } 762ee67178SXianjun Jiao 772ee67178SXianjun Jiao static inline u32 RX_INTF_REG_ANT_SEL_read(void){ 782ee67178SXianjun Jiao return reg_read(RX_INTF_REG_ANT_SEL_ADDR); 792ee67178SXianjun Jiao } 802ee67178SXianjun Jiao 812ee67178SXianjun Jiao static inline u32 RX_INTF_REG_INTERRUPT_TEST_read(void) { 822ee67178SXianjun Jiao return reg_read(RX_INTF_REG_INTERRUPT_TEST_ADDR); 832ee67178SXianjun Jiao } 842ee67178SXianjun Jiao 852ee67178SXianjun Jiao static inline void RX_INTF_REG_MULTI_RST_write(u32 value){ 862ee67178SXianjun Jiao reg_write(RX_INTF_REG_MULTI_RST_ADDR, value); 872ee67178SXianjun Jiao } 882ee67178SXianjun Jiao 892ee67178SXianjun Jiao static inline void RX_INTF_REG_M_AXIS_RST_write(u32 value){ 902ee67178SXianjun Jiao u32 reg_val; 912ee67178SXianjun Jiao 922ee67178SXianjun Jiao if (value==0) { 932ee67178SXianjun Jiao reg_val = RX_INTF_REG_MULTI_RST_read(); 942ee67178SXianjun Jiao reg_val = ( reg_val&(~(1<<4)) ); 952ee67178SXianjun Jiao RX_INTF_REG_MULTI_RST_write(reg_val); 962ee67178SXianjun Jiao } else { 972ee67178SXianjun Jiao reg_val = RX_INTF_REG_MULTI_RST_read(); 982ee67178SXianjun Jiao reg_val = ( reg_val|(1<<4) ); 992ee67178SXianjun Jiao RX_INTF_REG_MULTI_RST_write(reg_val); 1002ee67178SXianjun Jiao } 1012ee67178SXianjun Jiao } 1022ee67178SXianjun Jiao 1032ee67178SXianjun Jiao static inline void RX_INTF_REG_MIXER_CFG_write(u32 value){ 1042ee67178SXianjun Jiao reg_write(RX_INTF_REG_MIXER_CFG_ADDR, value); 1052ee67178SXianjun Jiao } 1062ee67178SXianjun Jiao 1072ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_SRC_SEL_write(u32 value){ 1082ee67178SXianjun Jiao reg_write(RX_INTF_REG_IQ_SRC_SEL_ADDR, value); 1092ee67178SXianjun Jiao } 1102ee67178SXianjun Jiao 1112ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_CTRL_write(u32 value){ 1122ee67178SXianjun Jiao reg_write(RX_INTF_REG_IQ_CTRL_ADDR, value); 1132ee67178SXianjun Jiao } 1142ee67178SXianjun Jiao 1152ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_MODE_write(u32 value){ 1162ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR, value); 1172ee67178SXianjun Jiao } 1182ee67178SXianjun Jiao 1192ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_write(u32 value){ 1202ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_ADDR, value); 1212ee67178SXianjun Jiao } 1222ee67178SXianjun Jiao 1232ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(u32 value){ 1242ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR, value); 1252ee67178SXianjun Jiao } 1262ee67178SXianjun Jiao 1272ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(u32 value){ 1282ee67178SXianjun Jiao reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR, value); 1292ee67178SXianjun Jiao } 1302ee67178SXianjun Jiao 1312ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(u32 value){ 1322ee67178SXianjun Jiao reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR, value); 1332ee67178SXianjun Jiao } 1342ee67178SXianjun Jiao 1352ee67178SXianjun Jiao static inline void RX_INTF_REG_CFG_DATA_TO_ANT_write(u32 value){ 1362ee67178SXianjun Jiao reg_write(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR, value); 1372ee67178SXianjun Jiao } 1382ee67178SXianjun Jiao 139*b73660adSXianjun Jiao static inline void RX_INTF_REG_BB_GAIN_write(u32 value) { 140*b73660adSXianjun Jiao reg_write(RX_INTF_REG_BB_GAIN_ADDR, value); 141*b73660adSXianjun Jiao } 142*b73660adSXianjun Jiao 1432ee67178SXianjun Jiao static inline void RX_INTF_REG_ANT_SEL_write(u32 value){ 1442ee67178SXianjun Jiao reg_write(RX_INTF_REG_ANT_SEL_ADDR, value); 1452ee67178SXianjun Jiao } 1462ee67178SXianjun Jiao 1472ee67178SXianjun Jiao static inline void RX_INTF_REG_INTERRUPT_TEST_write(u32 value) { 1482ee67178SXianjun Jiao reg_write(RX_INTF_REG_INTERRUPT_TEST_ADDR, value); 1492ee67178SXianjun Jiao } 1502ee67178SXianjun Jiao 1512ee67178SXianjun Jiao static inline void RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(u32 value) { 1522ee67178SXianjun Jiao reg_write(RX_INTF_REG_S2MM_INTR_DELAY_COUNT_ADDR, value); 1532ee67178SXianjun Jiao } 1542ee67178SXianjun Jiao 1552ee67178SXianjun Jiao static inline void RX_INTF_REG_TLAST_TIMEOUT_TOP_write(u32 value) { 1562ee67178SXianjun Jiao reg_write(RX_INTF_REG_TLAST_TIMEOUT_TOP_ADDR, value); 1572ee67178SXianjun Jiao } 1582ee67178SXianjun Jiao 1592ee67178SXianjun Jiao static const struct of_device_id dev_of_ids[] = { 1602ee67178SXianjun Jiao { .compatible = "sdr,rx_intf", }, 1612ee67178SXianjun Jiao {} 1622ee67178SXianjun Jiao }; 1632ee67178SXianjun Jiao MODULE_DEVICE_TABLE(of, dev_of_ids); 1642ee67178SXianjun Jiao 1652ee67178SXianjun Jiao static struct rx_intf_driver_api rx_intf_driver_api_inst; 1662ee67178SXianjun Jiao //EXPORT_SYMBOL(rx_intf_driver_api_inst); 1672ee67178SXianjun Jiao static struct rx_intf_driver_api *rx_intf_api = &rx_intf_driver_api_inst; 1682ee67178SXianjun Jiao EXPORT_SYMBOL(rx_intf_api); 1692ee67178SXianjun Jiao 1702ee67178SXianjun Jiao static inline u32 hw_init(enum rx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 num_dma_symbol_to_ps){ 1712ee67178SXianjun Jiao int err=0; 1722ee67178SXianjun Jiao u32 reg_val, mixer_cfg=0, ant_sel=0; 1732ee67178SXianjun Jiao 1742ee67178SXianjun Jiao printk("%s hw_init mode %d\n", rx_intf_compatible_str, mode); 1752ee67178SXianjun Jiao 1762ee67178SXianjun Jiao ////rst wifi rx -- slv_reg11[2] is actual rx reset. slv_reg11[0] only reset axi lite of rx 1772ee67178SXianjun Jiao //printk("%s hw_init reset wifi rx\n", rx_intf_compatible_str); 1782ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0); 1792ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(4); 1802ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0); 1812ee67178SXianjun Jiao 1822ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write(7000); 1832ee67178SXianjun Jiao //rst ddc internal module 1842ee67178SXianjun Jiao for (reg_val=0;reg_val<32;reg_val++) 1852ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0xFFFFFFFF); 1862ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); 1872ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start 1882ee67178SXianjun Jiao 1892ee67178SXianjun Jiao switch(mode) 1902ee67178SXianjun Jiao { 1912ee67178SXianjun Jiao case RX_INTF_AXIS_LOOP_BACK: 1922ee67178SXianjun Jiao printk("%s hw_init mode RX_INTF_AXIS_LOOP_BACK\n", rx_intf_compatible_str); 1932ee67178SXianjun Jiao //setting the path and mode. This must be done before our dma end reset 1942ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write(0x15); 1952ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(1); 1962ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x37);// endless mode to support sg DMA loop back, start 1 trans from sw trigger 1972ee67178SXianjun Jiao 1982ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(num_dma_symbol_to_pl); 1992ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps); 2002ee67178SXianjun Jiao 2012ee67178SXianjun Jiao // put bb_en to constant 1 2022ee67178SXianjun Jiao reg_val = rx_intf_api->RX_INTF_REG_IQ_CTRL_read(); 2032ee67178SXianjun Jiao reg_val = (reg_val|0x8); 2042ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_write(reg_val); 2052ee67178SXianjun Jiao 2062ee67178SXianjun Jiao // connect axis slave and master directly for loopback 2072ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x1037); 2082ee67178SXianjun Jiao 2092ee67178SXianjun Jiao // reset dma end point in our design 2102ee67178SXianjun Jiao reg_val = rx_intf_api->RX_INTF_REG_MULTI_RST_read(); 2112ee67178SXianjun Jiao reg_val = (reg_val&(~0x14) ); 2122ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val); 2132ee67178SXianjun Jiao reg_val = reg_val|(0x14); 2142ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val); 2152ee67178SXianjun Jiao reg_val = reg_val&(~0x14); 2162ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val); 2172ee67178SXianjun Jiao 2182ee67178SXianjun Jiao //start 1 trans now from our m_axis to ps dma 2192ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0); 2202ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(1); 2212ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0); 2222ee67178SXianjun Jiao break; 2232ee67178SXianjun Jiao 2242ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_0MHZ_ANT0: 2252ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_0MHZ\n", rx_intf_compatible_str); 2262ee67178SXianjun Jiao mixer_cfg = 0x300200F4; 2272ee67178SXianjun Jiao ant_sel=0; 2282ee67178SXianjun Jiao break; 2292ee67178SXianjun Jiao 2302ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_0MHZ_ANT1: 2312ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_0MHZ\n", rx_intf_compatible_str); 2322ee67178SXianjun Jiao mixer_cfg = 0x300200F4; 2332ee67178SXianjun Jiao ant_sel=1; 2342ee67178SXianjun Jiao break; 2352ee67178SXianjun Jiao 2362ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0: 2372ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_N_10MHZ\n", rx_intf_compatible_str); 2382ee67178SXianjun Jiao mixer_cfg = 0x300202F6; 2392ee67178SXianjun Jiao ant_sel=0; 2402ee67178SXianjun Jiao break; 2412ee67178SXianjun Jiao 2422ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1: 2432ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_N_10MHZ\n", rx_intf_compatible_str); 2442ee67178SXianjun Jiao mixer_cfg = 0x300202F6; 2452ee67178SXianjun Jiao ant_sel=1; 2462ee67178SXianjun Jiao break; 2472ee67178SXianjun Jiao 2482ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_P_10MHZ_ANT0: 2492ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_P_10MHZ\n", rx_intf_compatible_str); 2502ee67178SXianjun Jiao mixer_cfg = 0x3001F602; 2512ee67178SXianjun Jiao ant_sel=0; 2522ee67178SXianjun Jiao break; 2532ee67178SXianjun Jiao 2542ee67178SXianjun Jiao case RX_INTF_BW_20MHZ_AT_P_10MHZ_ANT1: 2552ee67178SXianjun Jiao printk("%s hw_init mode DDC_BW_20MHZ_AT_P_10MHZ\n", rx_intf_compatible_str); 2562ee67178SXianjun Jiao mixer_cfg = 0x3001F602; 2572ee67178SXianjun Jiao ant_sel=1; 2582ee67178SXianjun Jiao break; 2592ee67178SXianjun Jiao 2602ee67178SXianjun Jiao case RX_INTF_BYPASS: 2612ee67178SXianjun Jiao printk("%s hw_init mode DDC_BYPASS\n", rx_intf_compatible_str); 2622ee67178SXianjun Jiao mixer_cfg = 0x3001F602; 2632ee67178SXianjun Jiao break; 2642ee67178SXianjun Jiao 2652ee67178SXianjun Jiao default: 2662ee67178SXianjun Jiao printk("%s hw_init mode %d is wrong!\n", rx_intf_compatible_str, mode); 2672ee67178SXianjun Jiao err=1; 2682ee67178SXianjun Jiao } 2692ee67178SXianjun Jiao 2702ee67178SXianjun Jiao if (mode!=RX_INTF_AXIS_LOOP_BACK) { 2712ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MIXER_CFG_write(mixer_cfg); 2722ee67178SXianjun Jiao // 0x000202F6 for: wifi ant0: -10MHz; wifi ant1: +10MHz; zigbee 4 ch ant0: -2, -7, -12, -17MHz; zigbee 4 ch ant1: +3, +8, +13, +18MHz 2732ee67178SXianjun Jiao // 0x0001F602 for: wifi ant0: +10MHz; wifi ant1: -10MHz; zigbee 4 ch ant0: +3, +8, +13, +18MHz; zigbee 4 ch ant1: -2, -7, -12, -17MHz 2742ee67178SXianjun Jiao // 0x0001F206 for: wifi ant0: -10MHz; wifi ant1: +10MHz; zigbee 4 ch ant0: +3, +8, +13, +18MHz; zigbee 4 ch ant1: -2, -7, -12, -17MHz 2752ee67178SXianjun Jiao // 0x2101F602 for: wifi gain 4; zigbee gain 2 2762ee67178SXianjun Jiao // 0xFE01F602 for: wifi gain 1/2; zigbee gain 1/4 2772ee67178SXianjun Jiao // bits definitions: 2782ee67178SXianjun Jiao // wifi ch selection: ant0 bit1~0; ant1 bit 9~8; ch offset: 0-0MHz; 1-5MHz; 2-10MHz; 3-15MHz(severe distortion) 2792ee67178SXianjun Jiao // wifi ch +/- selection: ant0 bit2; ant1 bit 10; 0-positive; 1-negative 2802ee67178SXianjun Jiao // zigbee 2M mixer +/- selection: ant0 bit3; ant1 bit 11; 0-positive; 1-negative 2812ee67178SXianjun Jiao // zigbee secondary mixer +/- selection: ant0 bit4~7; ant1 bit 12~15; 0-positive; 1-negative 2822ee67178SXianjun Jiao // zigbee ch slip offset: ant0 bit16; ant1 bit17; 0-select ch offset 0, 5, 10, 15; 1-select ch offset 5 10 15 20 2832ee67178SXianjun Jiao // wifi gain: bit31~28; number of bits shifted to left in 2'complement code 2842ee67178SXianjun Jiao // zigb gain: bit27~24; number of bits shifted to left in 2'complement code 2852ee67178SXianjun Jiao // max amplitude calibration info (agc low, ddc w/o gain adj 0x0001F602): 5GHz, max amplitude 1.26e4. According to simulation, schr shrink 1bit should be enough 2862ee67178SXianjun Jiao 2872ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); 2882ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start 2892ee67178SXianjun Jiao 2902ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x000); 2912ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100); 2922ee67178SXianjun Jiao //0x000-normal; 0x100-sig and fcs valid are controled by bit4 and bit0; 2932ee67178SXianjun Jiao //0x111-sig and fcs high; 0x110-sig high fcs low; 0x101-sig low fcs high; 0x100-sig and fcs low 2942ee67178SXianjun Jiao 2952ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write(0); 2962ee67178SXianjun Jiao // 0-bw20-ch0; 1-bw2-ch0; 2-bw2-ch2; 3-bw2-ch4; 4-bw2-ch6; 5-s_axis-ch0 2972ee67178SXianjun Jiao // 8-bw20-ch1; 9-bw2-ch1; 10-bw2-ch3; 11-bw2-ch5; 12-bw2-ch7; 13-s_axis-ch1 2982ee67178SXianjun Jiao 2992ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(1000|0x80000000); //0x80000000 to enable tsft and rssi gpio test magic value 3002ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(200*10); //0x80000000 to enable tsft and rssi gpio test magic value 3012ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(30*200); // delayed interrupt 3022ee67178SXianjun Jiao 3032ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_write(0); 3042ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x10025); //now bit 5 should be 1 to let pl_to_m_axis_intf decide num_dma_symbol_to_ps automatically 3052ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x00025); //bit16 enable_m_axis_auto_rst 3062ee67178SXianjun Jiao //bit2-0: source of M AXIS transfer trigger 3072ee67178SXianjun Jiao // -0 fcs_valid_from_acc 3082ee67178SXianjun Jiao // -1 sig_valid_from_acc 3092ee67178SXianjun Jiao // -2 sig_invalid_from_acc 3102ee67178SXianjun Jiao // -3 start_1trans_s_axis_tlast_trigger 3112ee67178SXianjun Jiao // -4 start_1trans_s_axis_tready_trigger 3122ee67178SXianjun Jiao // -5 internal state machine together with bit5 1. By parsing signal field, num_dma_symbol_to_ps can be decided automatically 3132ee67178SXianjun Jiao // -6 start_1trans_monitor_dma_to_ps_start_trigger 3142ee67178SXianjun Jiao // -7 start_1trans_ext_trigger 3152ee67178SXianjun Jiao //bit3: 1-fcs valid and invalid both connected; 0-only fcs valid connected (fcs_invalid_mode) 3162ee67178SXianjun Jiao //bit4: 1-num_dma_symbol_to_pl from monitor; 0-num_dma_symbol_to_pl from slv_reg8 3172ee67178SXianjun Jiao //bit5: 1-num_dma_symbol_to_ps from monitor; 0-num_dma_symbol_to_ps from slv_reg9 3182ee67178SXianjun Jiao //bit6: 1-pl_to_m_axis_intf will try to send both ht and non-ht; 0-only send non-ht 3192ee67178SXianjun Jiao //bit8: 1-endless S AXIS; 0-normal 3202ee67178SXianjun Jiao //bit9: 1-endless M AXIS; 0-normal 3212ee67178SXianjun Jiao //bit12: 1-direct loop back; 0-normal 3222ee67178SXianjun Jiao //bit16: 1-auto m_axis rst (sig_valid_from_acc|sig_invalid_from_acc|ht_sig_valid|ht_sig_invalid|ht_unsupported); 0-normal 3232ee67178SXianjun Jiao //bit24: 1-disable m_axis fifo_rst_by_fcs_invalid; 0-enable 3242ee67178SXianjun Jiao //bit29,28: sig_valid_mode. 0- non-ht sig valid; 1- ht sig valid other- both 3252ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0); 3262ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(0); 3272ee67178SXianjun Jiao // 0-wifi_rx packet out; 1-loopback from input of wifi_rx 3282ee67178SXianjun Jiao 3292ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(num_dma_symbol_to_pl); 3302ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps); 3312ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(1<<8); 332*b73660adSXianjun Jiao rx_intf_api->RX_INTF_REG_BB_GAIN_write(4); 3332ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_write(ant_sel); 3342ee67178SXianjun Jiao 3352ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0x14);//rst m/s axis 3362ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0); 3372ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start 3382ee67178SXianjun Jiao } 3392ee67178SXianjun Jiao 3402ee67178SXianjun Jiao if (mode==RX_INTF_BYPASS) { 3412ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(0x10); //bit4 bypass enable 3422ee67178SXianjun Jiao } 3432ee67178SXianjun Jiao 3442ee67178SXianjun Jiao printk("%s hw_init err %d\n", rx_intf_compatible_str, err); 3452ee67178SXianjun Jiao return(err); 3462ee67178SXianjun Jiao } 3472ee67178SXianjun Jiao 3482ee67178SXianjun Jiao static int dev_probe(struct platform_device *pdev) 3492ee67178SXianjun Jiao { 3502ee67178SXianjun Jiao struct device_node *np = pdev->dev.of_node; 3512ee67178SXianjun Jiao struct resource *io; 3522ee67178SXianjun Jiao int err=1; 3532ee67178SXianjun Jiao 3542ee67178SXianjun Jiao printk("\n"); 3552ee67178SXianjun Jiao 3562ee67178SXianjun Jiao if (np) { 3572ee67178SXianjun Jiao const struct of_device_id *match; 3582ee67178SXianjun Jiao 3592ee67178SXianjun Jiao match = of_match_node(dev_of_ids, np); 3602ee67178SXianjun Jiao if (match) { 3612ee67178SXianjun Jiao printk("%s dev_probe match!\n", rx_intf_compatible_str); 3622ee67178SXianjun Jiao err = 0; 3632ee67178SXianjun Jiao } 3642ee67178SXianjun Jiao } 3652ee67178SXianjun Jiao 3662ee67178SXianjun Jiao if (err) 3672ee67178SXianjun Jiao return err; 3682ee67178SXianjun Jiao 3692ee67178SXianjun Jiao rx_intf_api->hw_init=hw_init; 3702ee67178SXianjun Jiao 3712ee67178SXianjun Jiao rx_intf_api->reg_read=reg_read; 3722ee67178SXianjun Jiao rx_intf_api->reg_write=reg_write; 3732ee67178SXianjun Jiao 3742ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_read=RX_INTF_REG_MULTI_RST_read; 3752ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MIXER_CFG_read=RX_INTF_REG_MIXER_CFG_read; 3762ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_read=RX_INTF_REG_IQ_SRC_SEL_read; 3772ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_read=RX_INTF_REG_IQ_CTRL_read; 3782ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_read=RX_INTF_REG_START_TRANS_TO_PS_MODE_read; 3792ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_read=RX_INTF_REG_START_TRANS_TO_PS_read; 3802ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read; 3812ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read; 3822ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read; 3832ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_read=RX_INTF_REG_CFG_DATA_TO_ANT_read; 3842ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_read=RX_INTF_REG_ANT_SEL_read; 3852ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_read=RX_INTF_REG_INTERRUPT_TEST_read; 3862ee67178SXianjun Jiao 3872ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write=RX_INTF_REG_MULTI_RST_write; 3882ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write=RX_INTF_REG_M_AXIS_RST_write; 3892ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MIXER_CFG_write=RX_INTF_REG_MIXER_CFG_write; 3902ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write=RX_INTF_REG_IQ_SRC_SEL_write; 3912ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_write=RX_INTF_REG_IQ_CTRL_write; 3922ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write=RX_INTF_REG_START_TRANS_TO_PS_MODE_write; 3932ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write=RX_INTF_REG_START_TRANS_TO_PS_write; 3942ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write; 3952ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write; 3962ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write; 3972ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write=RX_INTF_REG_CFG_DATA_TO_ANT_write; 398*b73660adSXianjun Jiao rx_intf_api->RX_INTF_REG_BB_GAIN_write=RX_INTF_REG_BB_GAIN_write; 3992ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_write=RX_INTF_REG_ANT_SEL_write; 4002ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write=RX_INTF_REG_INTERRUPT_TEST_write; 4012ee67178SXianjun Jiao 4022ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write=RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write; 4032ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write=RX_INTF_REG_TLAST_TIMEOUT_TOP_write; 4042ee67178SXianjun Jiao 4052ee67178SXianjun Jiao /* Request and map I/O memory */ 4062ee67178SXianjun Jiao io = platform_get_resource(pdev, IORESOURCE_MEM, 0); 4072ee67178SXianjun Jiao base_addr = devm_ioremap_resource(&pdev->dev, io); 4082ee67178SXianjun Jiao if (IS_ERR(base_addr)) 4092ee67178SXianjun Jiao return PTR_ERR(base_addr); 4102ee67178SXianjun Jiao 4112ee67178SXianjun Jiao rx_intf_api->io_start = io->start; 4122ee67178SXianjun Jiao rx_intf_api->base_addr = (u32)base_addr; 4132ee67178SXianjun Jiao 4142ee67178SXianjun Jiao printk("%s dev_probe io start 0x%08x end 0x%08x name %s flags 0x%08x desc 0x%08x\n", rx_intf_compatible_str,io->start,io->end,io->name,(u32)io->flags,(u32)io->desc); 4152ee67178SXianjun Jiao printk("%s dev_probe base_addr 0x%08x\n", rx_intf_compatible_str,(u32)base_addr); 4162ee67178SXianjun Jiao printk("%s dev_probe rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) ); 4172ee67178SXianjun Jiao printk("%s dev_probe rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api); 4182ee67178SXianjun Jiao 4192ee67178SXianjun Jiao printk("%s dev_probe succeed!\n", rx_intf_compatible_str); 4202ee67178SXianjun Jiao 4212ee67178SXianjun Jiao //err = hw_init(DDC_CURRENT_CH_OFFSET_CFG,8,8); 4222ee67178SXianjun Jiao err = hw_init(RX_INTF_BW_20MHZ_AT_0MHZ_ANT0,8,8); 4232ee67178SXianjun Jiao 4242ee67178SXianjun Jiao return err; 4252ee67178SXianjun Jiao } 4262ee67178SXianjun Jiao 4272ee67178SXianjun Jiao static int dev_remove(struct platform_device *pdev) 4282ee67178SXianjun Jiao { 4292ee67178SXianjun Jiao printk("\n"); 4302ee67178SXianjun Jiao 4312ee67178SXianjun Jiao printk("%s dev_remove base_addr 0x%08x\n", rx_intf_compatible_str, (u32)base_addr); 4322ee67178SXianjun Jiao printk("%s dev_remove rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) ); 4332ee67178SXianjun Jiao printk("%s dev_remove rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api); 4342ee67178SXianjun Jiao 4352ee67178SXianjun Jiao printk("%s dev_remove succeed!\n", rx_intf_compatible_str); 4362ee67178SXianjun Jiao return 0; 4372ee67178SXianjun Jiao } 4382ee67178SXianjun Jiao 4392ee67178SXianjun Jiao static struct platform_driver dev_driver = { 4402ee67178SXianjun Jiao .driver = { 4412ee67178SXianjun Jiao .name = "sdr,rx_intf", 4422ee67178SXianjun Jiao .owner = THIS_MODULE, 4432ee67178SXianjun Jiao .of_match_table = dev_of_ids, 4442ee67178SXianjun Jiao }, 4452ee67178SXianjun Jiao .probe = dev_probe, 4462ee67178SXianjun Jiao .remove = dev_remove, 4472ee67178SXianjun Jiao }; 4482ee67178SXianjun Jiao 4492ee67178SXianjun Jiao module_platform_driver(dev_driver); 4502ee67178SXianjun Jiao 4512ee67178SXianjun Jiao MODULE_AUTHOR("Xianjun Jiao"); 4522ee67178SXianjun Jiao MODULE_DESCRIPTION("sdr,rx_intf"); 4532ee67178SXianjun Jiao MODULE_LICENSE("GPL v2"); 454