12ee67178SXianjun Jiao /*
22ee67178SXianjun Jiao * axi lite register access driver
38598124eSJiao Xianjun * Author: Xianjun Jiao, Michael Mehari, Wei Liu
48598124eSJiao Xianjun * SPDX-FileCopyrightText: 2019 UGent
5a6085186SLina Ceballos * SPDX-License-Identifier: AGPL-3.0-or-later
62ee67178SXianjun Jiao */
72ee67178SXianjun Jiao
82ee67178SXianjun Jiao #include <linux/bitops.h>
92ee67178SXianjun Jiao #include <linux/dmapool.h>
102ee67178SXianjun Jiao #include <linux/dma/xilinx_dma.h>
112ee67178SXianjun Jiao #include <linux/init.h>
122ee67178SXianjun Jiao #include <linux/interrupt.h>
132ee67178SXianjun Jiao #include <linux/io.h>
142ee67178SXianjun Jiao #include <linux/iopoll.h>
152ee67178SXianjun Jiao #include <linux/module.h>
162ee67178SXianjun Jiao #include <linux/of_address.h>
172ee67178SXianjun Jiao #include <linux/of_dma.h>
182ee67178SXianjun Jiao #include <linux/of_platform.h>
192ee67178SXianjun Jiao #include <linux/of_irq.h>
202ee67178SXianjun Jiao #include <linux/slab.h>
212ee67178SXianjun Jiao #include <linux/clk.h>
222ee67178SXianjun Jiao #include <linux/io-64-nonatomic-lo-hi.h>
232ee67178SXianjun Jiao
242ee67178SXianjun Jiao #include "../hw_def.h"
252ee67178SXianjun Jiao
262ee67178SXianjun 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
272ee67178SXianjun Jiao
282ee67178SXianjun Jiao /* IO accessors */
reg_read(u32 reg)292ee67178SXianjun Jiao static inline u32 reg_read(u32 reg)
302ee67178SXianjun Jiao {
312ee67178SXianjun Jiao return ioread32(base_addr + reg);
322ee67178SXianjun Jiao }
332ee67178SXianjun Jiao
reg_write(u32 reg,u32 value)342ee67178SXianjun Jiao static inline void reg_write(u32 reg, u32 value)
352ee67178SXianjun Jiao {
362ee67178SXianjun Jiao iowrite32(value, base_addr + reg);
372ee67178SXianjun Jiao }
382ee67178SXianjun Jiao
RX_INTF_REG_MULTI_RST_read(void)392ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MULTI_RST_read(void){
402ee67178SXianjun Jiao return reg_read(RX_INTF_REG_MULTI_RST_ADDR);
412ee67178SXianjun Jiao }
422ee67178SXianjun Jiao
RX_INTF_REG_MIXER_CFG_read(void)432ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MIXER_CFG_read(void){
442ee67178SXianjun Jiao return reg_read(RX_INTF_REG_MIXER_CFG_ADDR);
452ee67178SXianjun Jiao }
462ee67178SXianjun Jiao
RX_INTF_REG_IQ_SRC_SEL_read(void)472ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_SRC_SEL_read(void){
482ee67178SXianjun Jiao return reg_read(RX_INTF_REG_IQ_SRC_SEL_ADDR);
492ee67178SXianjun Jiao }
502ee67178SXianjun Jiao
RX_INTF_REG_IQ_CTRL_read(void)512ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_CTRL_read(void){
522ee67178SXianjun Jiao return reg_read(RX_INTF_REG_IQ_CTRL_ADDR);
532ee67178SXianjun Jiao }
542ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_MODE_read(void)552ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_MODE_read(void){
562ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR);
572ee67178SXianjun Jiao }
582ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_read(void)592ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_read(void){
602ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_ADDR);
612ee67178SXianjun Jiao }
622ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read(void)632ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read(void){
642ee67178SXianjun Jiao return reg_read(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR);
652ee67178SXianjun Jiao }
662ee67178SXianjun Jiao
RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read(void)672ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read(void){
682ee67178SXianjun Jiao return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR);
692ee67178SXianjun Jiao }
702ee67178SXianjun Jiao
RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read(void)712ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read(void){
722ee67178SXianjun Jiao return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR);
732ee67178SXianjun Jiao }
742ee67178SXianjun Jiao
RX_INTF_REG_CFG_DATA_TO_ANT_read(void)752ee67178SXianjun Jiao static inline u32 RX_INTF_REG_CFG_DATA_TO_ANT_read(void){
762ee67178SXianjun Jiao return reg_read(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR);
772ee67178SXianjun Jiao }
782ee67178SXianjun Jiao
RX_INTF_REG_ANT_SEL_read(void)792ee67178SXianjun Jiao static inline u32 RX_INTF_REG_ANT_SEL_read(void){
802ee67178SXianjun Jiao return reg_read(RX_INTF_REG_ANT_SEL_ADDR);
812ee67178SXianjun Jiao }
822ee67178SXianjun Jiao
RX_INTF_REG_INTERRUPT_TEST_read(void)832ee67178SXianjun Jiao static inline u32 RX_INTF_REG_INTERRUPT_TEST_read(void) {
842ee67178SXianjun Jiao return reg_read(RX_INTF_REG_INTERRUPT_TEST_ADDR);
852ee67178SXianjun Jiao }
862ee67178SXianjun Jiao
RX_INTF_REG_MULTI_RST_write(u32 value)872ee67178SXianjun Jiao static inline void RX_INTF_REG_MULTI_RST_write(u32 value){
882ee67178SXianjun Jiao reg_write(RX_INTF_REG_MULTI_RST_ADDR, value);
892ee67178SXianjun Jiao }
902ee67178SXianjun Jiao
RX_INTF_REG_M_AXIS_RST_write(u32 value)912ee67178SXianjun Jiao static inline void RX_INTF_REG_M_AXIS_RST_write(u32 value){
922ee67178SXianjun Jiao u32 reg_val;
932ee67178SXianjun Jiao
942ee67178SXianjun Jiao if (value==0) {
952ee67178SXianjun Jiao reg_val = RX_INTF_REG_MULTI_RST_read();
962ee67178SXianjun Jiao reg_val = ( reg_val&(~(1<<4)) );
972ee67178SXianjun Jiao RX_INTF_REG_MULTI_RST_write(reg_val);
982ee67178SXianjun Jiao } else {
992ee67178SXianjun Jiao reg_val = RX_INTF_REG_MULTI_RST_read();
1002ee67178SXianjun Jiao reg_val = ( reg_val|(1<<4) );
1012ee67178SXianjun Jiao RX_INTF_REG_MULTI_RST_write(reg_val);
1022ee67178SXianjun Jiao }
1032ee67178SXianjun Jiao }
1042ee67178SXianjun Jiao
RX_INTF_REG_MIXER_CFG_write(u32 value)1052ee67178SXianjun Jiao static inline void RX_INTF_REG_MIXER_CFG_write(u32 value){
1062ee67178SXianjun Jiao reg_write(RX_INTF_REG_MIXER_CFG_ADDR, value);
1072ee67178SXianjun Jiao }
1082ee67178SXianjun Jiao
RX_INTF_REG_IQ_SRC_SEL_write(u32 value)1092ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_SRC_SEL_write(u32 value){
1102ee67178SXianjun Jiao reg_write(RX_INTF_REG_IQ_SRC_SEL_ADDR, value);
1112ee67178SXianjun Jiao }
1122ee67178SXianjun Jiao
RX_INTF_REG_IQ_CTRL_write(u32 value)1132ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_CTRL_write(u32 value){
1142ee67178SXianjun Jiao reg_write(RX_INTF_REG_IQ_CTRL_ADDR, value);
1152ee67178SXianjun Jiao }
1162ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_MODE_write(u32 value)1172ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_MODE_write(u32 value){
1182ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR, value);
1192ee67178SXianjun Jiao }
1202ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_write(u32 value)1212ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_write(u32 value){
1222ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_ADDR, value);
1232ee67178SXianjun Jiao }
1242ee67178SXianjun Jiao
RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(u32 value)1252ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(u32 value){
1262ee67178SXianjun Jiao reg_write(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR, value);
1272ee67178SXianjun Jiao }
1282ee67178SXianjun Jiao
RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(u32 value)1292ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(u32 value){
1302ee67178SXianjun Jiao reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR, value);
1312ee67178SXianjun Jiao }
1322ee67178SXianjun Jiao
RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(u32 value)1332ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(u32 value){
1342ee67178SXianjun Jiao reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR, value);
1352ee67178SXianjun Jiao }
1362ee67178SXianjun Jiao
RX_INTF_REG_CFG_DATA_TO_ANT_write(u32 value)1372ee67178SXianjun Jiao static inline void RX_INTF_REG_CFG_DATA_TO_ANT_write(u32 value){
1382ee67178SXianjun Jiao reg_write(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR, value);
1392ee67178SXianjun Jiao }
1402ee67178SXianjun Jiao
RX_INTF_REG_BB_GAIN_write(u32 value)141b73660adSXianjun Jiao static inline void RX_INTF_REG_BB_GAIN_write(u32 value) {
142b73660adSXianjun Jiao reg_write(RX_INTF_REG_BB_GAIN_ADDR, value);
143b73660adSXianjun Jiao }
144b73660adSXianjun Jiao
RX_INTF_REG_ANT_SEL_write(u32 value)1452ee67178SXianjun Jiao static inline void RX_INTF_REG_ANT_SEL_write(u32 value){
1462ee67178SXianjun Jiao reg_write(RX_INTF_REG_ANT_SEL_ADDR, value);
1472ee67178SXianjun Jiao }
1482ee67178SXianjun Jiao
RX_INTF_REG_INTERRUPT_TEST_write(u32 value)1492ee67178SXianjun Jiao static inline void RX_INTF_REG_INTERRUPT_TEST_write(u32 value) {
1502ee67178SXianjun Jiao reg_write(RX_INTF_REG_INTERRUPT_TEST_ADDR, value);
1512ee67178SXianjun Jiao }
1522ee67178SXianjun Jiao
RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(u32 value)1532ee67178SXianjun Jiao static inline void RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(u32 value) {
1542ee67178SXianjun Jiao reg_write(RX_INTF_REG_S2MM_INTR_DELAY_COUNT_ADDR, value);
1552ee67178SXianjun Jiao }
1562ee67178SXianjun Jiao
RX_INTF_REG_TLAST_TIMEOUT_TOP_write(u32 value)1572ee67178SXianjun Jiao static inline void RX_INTF_REG_TLAST_TIMEOUT_TOP_write(u32 value) {
1582ee67178SXianjun Jiao reg_write(RX_INTF_REG_TLAST_TIMEOUT_TOP_ADDR, value);
1592ee67178SXianjun Jiao }
1602ee67178SXianjun Jiao
1612ee67178SXianjun Jiao static const struct of_device_id dev_of_ids[] = {
1622ee67178SXianjun Jiao { .compatible = "sdr,rx_intf", },
1632ee67178SXianjun Jiao {}
1642ee67178SXianjun Jiao };
1652ee67178SXianjun Jiao MODULE_DEVICE_TABLE(of, dev_of_ids);
1662ee67178SXianjun Jiao
1672ee67178SXianjun Jiao static struct rx_intf_driver_api rx_intf_driver_api_inst;
168*db8c69b6Srobgar2001 struct rx_intf_driver_api *rx_intf_api = &rx_intf_driver_api_inst;
1692ee67178SXianjun Jiao EXPORT_SYMBOL(rx_intf_api);
1702ee67178SXianjun Jiao
hw_init(enum rx_intf_mode mode,u32 num_dma_symbol_to_pl,u32 num_dma_symbol_to_ps)1712ee67178SXianjun Jiao static inline u32 hw_init(enum rx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 num_dma_symbol_to_ps){
1724ecf49bbSJiao Xianjun int err=0, i;
1732ee67178SXianjun Jiao u32 reg_val, mixer_cfg=0, ant_sel=0;
1742ee67178SXianjun Jiao
1752ee67178SXianjun Jiao printk("%s hw_init mode %d\n", rx_intf_compatible_str, mode);
1762ee67178SXianjun Jiao
1772ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write(7000);
1784ecf49bbSJiao Xianjun
1794ecf49bbSJiao Xianjun //rst
1804ecf49bbSJiao Xianjun for (i=0;i<8;i++)
1812ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
1824ecf49bbSJiao Xianjun for (i=0;i<32;i++)
1834ecf49bbSJiao Xianjun rx_intf_api->RX_INTF_REG_MULTI_RST_write(0xFFFFFFFF);
1844ecf49bbSJiao Xianjun for (i=0;i<8;i++)
1854ecf49bbSJiao Xianjun rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
1864ecf49bbSJiao Xianjun
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) {
271febc5adfSXianjun Jiao // rx_intf_api->RX_INTF_REG_MIXER_CFG_write(mixer_cfg); --now rx doesn't have mixer anymore
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);
292b1dd94e3Sluz paz //0x000-normal; 0x100-sig and fcs valid are controlled 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
295febc5adfSXianjun Jiao rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(30*10); // delayed interrupt, counter clock 10MHz is assumed
2962ee67178SXianjun Jiao
2972ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_write(0);
2982ee67178SXianjun 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
2992ee67178SXianjun Jiao //rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x00025); //bit16 enable_m_axis_auto_rst
3002ee67178SXianjun Jiao //bit2-0: source of M AXIS transfer trigger
3012ee67178SXianjun Jiao // -0 fcs_valid_from_acc
3022ee67178SXianjun Jiao // -1 sig_valid_from_acc
3032ee67178SXianjun Jiao // -2 sig_invalid_from_acc
3042ee67178SXianjun Jiao // -3 start_1trans_s_axis_tlast_trigger
3052ee67178SXianjun Jiao // -4 start_1trans_s_axis_tready_trigger
3062ee67178SXianjun Jiao // -5 internal state machine together with bit5 1. By parsing signal field, num_dma_symbol_to_ps can be decided automatically
3072ee67178SXianjun Jiao // -6 start_1trans_monitor_dma_to_ps_start_trigger
3082ee67178SXianjun Jiao // -7 start_1trans_ext_trigger
3092ee67178SXianjun Jiao //bit3: 1-fcs valid and invalid both connected; 0-only fcs valid connected (fcs_invalid_mode)
3102ee67178SXianjun Jiao //bit4: 1-num_dma_symbol_to_pl from monitor; 0-num_dma_symbol_to_pl from slv_reg8
3112ee67178SXianjun Jiao //bit5: 1-num_dma_symbol_to_ps from monitor; 0-num_dma_symbol_to_ps from slv_reg9
3122ee67178SXianjun Jiao //bit6: 1-pl_to_m_axis_intf will try to send both ht and non-ht; 0-only send non-ht
3132ee67178SXianjun Jiao //bit8: 1-endless S AXIS; 0-normal
3142ee67178SXianjun Jiao //bit9: 1-endless M AXIS; 0-normal
3152ee67178SXianjun Jiao //bit12: 1-direct loop back; 0-normal
3162ee67178SXianjun 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
3172ee67178SXianjun Jiao //bit24: 1-disable m_axis fifo_rst_by_fcs_invalid; 0-enable
3182ee67178SXianjun Jiao //bit29,28: sig_valid_mode. 0- non-ht sig valid; 1- ht sig valid other- both
319585a5601SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(OPENWIFI_MAX_SIGNAL_LEN_TH<<16); //bit31~16 max pkt length threshold
3202ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(0);
3212ee67178SXianjun Jiao // 0-wifi_rx packet out; 1-loopback from input of wifi_rx
3222ee67178SXianjun Jiao
3232ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(num_dma_symbol_to_pl);
3242ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps);
3252ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(1<<8);
326b73660adSXianjun Jiao rx_intf_api->RX_INTF_REG_BB_GAIN_write(4);
3272ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_write(ant_sel);
3282ee67178SXianjun Jiao
3292ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0x14);//rst m/s axis
3302ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
3312ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start
3322ee67178SXianjun Jiao }
3332ee67178SXianjun Jiao
3342ee67178SXianjun Jiao if (mode==RX_INTF_BYPASS) {
3352ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(0x10); //bit4 bypass enable
3362ee67178SXianjun Jiao }
3372ee67178SXianjun Jiao
3382ee67178SXianjun Jiao printk("%s hw_init err %d\n", rx_intf_compatible_str, err);
3392ee67178SXianjun Jiao return(err);
3402ee67178SXianjun Jiao }
3412ee67178SXianjun Jiao
dev_probe(struct platform_device * pdev)3422ee67178SXianjun Jiao static int dev_probe(struct platform_device *pdev)
3432ee67178SXianjun Jiao {
3442ee67178SXianjun Jiao struct device_node *np = pdev->dev.of_node;
3452ee67178SXianjun Jiao struct resource *io;
3462ee67178SXianjun Jiao int err=1;
3472ee67178SXianjun Jiao
3482ee67178SXianjun Jiao printk("\n");
3492ee67178SXianjun Jiao
3502ee67178SXianjun Jiao if (np) {
3512ee67178SXianjun Jiao const struct of_device_id *match;
3522ee67178SXianjun Jiao
3532ee67178SXianjun Jiao match = of_match_node(dev_of_ids, np);
3542ee67178SXianjun Jiao if (match) {
3552ee67178SXianjun Jiao printk("%s dev_probe match!\n", rx_intf_compatible_str);
3562ee67178SXianjun Jiao err = 0;
3572ee67178SXianjun Jiao }
3582ee67178SXianjun Jiao }
3592ee67178SXianjun Jiao
3602ee67178SXianjun Jiao if (err)
3612ee67178SXianjun Jiao return err;
3622ee67178SXianjun Jiao
3632ee67178SXianjun Jiao rx_intf_api->hw_init=hw_init;
3642ee67178SXianjun Jiao
3652ee67178SXianjun Jiao rx_intf_api->reg_read=reg_read;
3662ee67178SXianjun Jiao rx_intf_api->reg_write=reg_write;
3672ee67178SXianjun Jiao
3682ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_read=RX_INTF_REG_MULTI_RST_read;
3692ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MIXER_CFG_read=RX_INTF_REG_MIXER_CFG_read;
3702ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_read=RX_INTF_REG_IQ_SRC_SEL_read;
3712ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_read=RX_INTF_REG_IQ_CTRL_read;
3722ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_read=RX_INTF_REG_START_TRANS_TO_PS_MODE_read;
3732ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_read=RX_INTF_REG_START_TRANS_TO_PS_read;
3742ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read;
3752ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read;
3762ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read;
3772ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_read=RX_INTF_REG_CFG_DATA_TO_ANT_read;
3782ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_read=RX_INTF_REG_ANT_SEL_read;
3792ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_read=RX_INTF_REG_INTERRUPT_TEST_read;
3802ee67178SXianjun Jiao
3812ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MULTI_RST_write=RX_INTF_REG_MULTI_RST_write;
3822ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_M_AXIS_RST_write=RX_INTF_REG_M_AXIS_RST_write;
3832ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_MIXER_CFG_write=RX_INTF_REG_MIXER_CFG_write;
3842ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write=RX_INTF_REG_IQ_SRC_SEL_write;
3852ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_IQ_CTRL_write=RX_INTF_REG_IQ_CTRL_write;
3862ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write=RX_INTF_REG_START_TRANS_TO_PS_MODE_write;
3872ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write=RX_INTF_REG_START_TRANS_TO_PS_write;
3882ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write;
3892ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write;
3902ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write;
3912ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write=RX_INTF_REG_CFG_DATA_TO_ANT_write;
392b73660adSXianjun Jiao rx_intf_api->RX_INTF_REG_BB_GAIN_write=RX_INTF_REG_BB_GAIN_write;
3932ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_ANT_SEL_write=RX_INTF_REG_ANT_SEL_write;
3942ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write=RX_INTF_REG_INTERRUPT_TEST_write;
3952ee67178SXianjun Jiao
3962ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write=RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write;
3972ee67178SXianjun Jiao rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write=RX_INTF_REG_TLAST_TIMEOUT_TOP_write;
3982ee67178SXianjun Jiao
3992ee67178SXianjun Jiao /* Request and map I/O memory */
4002ee67178SXianjun Jiao io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4012ee67178SXianjun Jiao base_addr = devm_ioremap_resource(&pdev->dev, io);
4022ee67178SXianjun Jiao if (IS_ERR(base_addr))
4032ee67178SXianjun Jiao return PTR_ERR(base_addr);
4042ee67178SXianjun Jiao
4052ee67178SXianjun Jiao rx_intf_api->io_start = io->start;
4062ee67178SXianjun Jiao rx_intf_api->base_addr = (u32)base_addr;
4072ee67178SXianjun Jiao
4082ee67178SXianjun 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);
4092ee67178SXianjun Jiao printk("%s dev_probe base_addr 0x%08x\n", rx_intf_compatible_str,(u32)base_addr);
4102ee67178SXianjun Jiao printk("%s dev_probe rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) );
4112ee67178SXianjun Jiao printk("%s dev_probe rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api);
4122ee67178SXianjun Jiao
4132ee67178SXianjun Jiao printk("%s dev_probe succeed!\n", rx_intf_compatible_str);
4142ee67178SXianjun Jiao
4152ee67178SXianjun Jiao //err = hw_init(DDC_CURRENT_CH_OFFSET_CFG,8,8);
4162ee67178SXianjun Jiao err = hw_init(RX_INTF_BW_20MHZ_AT_0MHZ_ANT0,8,8);
4172ee67178SXianjun Jiao
4182ee67178SXianjun Jiao return err;
4192ee67178SXianjun Jiao }
4202ee67178SXianjun Jiao
dev_remove(struct platform_device * pdev)4212ee67178SXianjun Jiao static int dev_remove(struct platform_device *pdev)
4222ee67178SXianjun Jiao {
4232ee67178SXianjun Jiao printk("\n");
4242ee67178SXianjun Jiao
4252ee67178SXianjun Jiao printk("%s dev_remove base_addr 0x%08x\n", rx_intf_compatible_str, (u32)base_addr);
4262ee67178SXianjun Jiao printk("%s dev_remove rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) );
4272ee67178SXianjun Jiao printk("%s dev_remove rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api);
4282ee67178SXianjun Jiao
4292ee67178SXianjun Jiao printk("%s dev_remove succeed!\n", rx_intf_compatible_str);
4302ee67178SXianjun Jiao return 0;
4312ee67178SXianjun Jiao }
4322ee67178SXianjun Jiao
4332ee67178SXianjun Jiao static struct platform_driver dev_driver = {
4342ee67178SXianjun Jiao .driver = {
4352ee67178SXianjun Jiao .name = "sdr,rx_intf",
4362ee67178SXianjun Jiao .owner = THIS_MODULE,
4372ee67178SXianjun Jiao .of_match_table = dev_of_ids,
4382ee67178SXianjun Jiao },
4392ee67178SXianjun Jiao .probe = dev_probe,
4402ee67178SXianjun Jiao .remove = dev_remove,
4412ee67178SXianjun Jiao };
4422ee67178SXianjun Jiao
4432ee67178SXianjun Jiao module_platform_driver(dev_driver);
4442ee67178SXianjun Jiao
4452ee67178SXianjun Jiao MODULE_AUTHOR("Xianjun Jiao");
4462ee67178SXianjun Jiao MODULE_DESCRIPTION("sdr,rx_intf");
4472ee67178SXianjun Jiao MODULE_LICENSE("GPL v2");
448