xref: /openwifi/driver/rx_intf/rx_intf.c (revision 2ee67178825ee52f380c2f72b7135d15ddadca60)
1*2ee67178SXianjun Jiao /*
2*2ee67178SXianjun Jiao  * axi lite register access driver
3*2ee67178SXianjun Jiao  * Xianjun jiao. [email protected]; [email protected]
4*2ee67178SXianjun Jiao  */
5*2ee67178SXianjun Jiao 
6*2ee67178SXianjun Jiao #include <linux/bitops.h>
7*2ee67178SXianjun Jiao #include <linux/dmapool.h>
8*2ee67178SXianjun Jiao #include <linux/dma/xilinx_dma.h>
9*2ee67178SXianjun Jiao #include <linux/init.h>
10*2ee67178SXianjun Jiao #include <linux/interrupt.h>
11*2ee67178SXianjun Jiao #include <linux/io.h>
12*2ee67178SXianjun Jiao #include <linux/iopoll.h>
13*2ee67178SXianjun Jiao #include <linux/module.h>
14*2ee67178SXianjun Jiao #include <linux/of_address.h>
15*2ee67178SXianjun Jiao #include <linux/of_dma.h>
16*2ee67178SXianjun Jiao #include <linux/of_platform.h>
17*2ee67178SXianjun Jiao #include <linux/of_irq.h>
18*2ee67178SXianjun Jiao #include <linux/slab.h>
19*2ee67178SXianjun Jiao #include <linux/clk.h>
20*2ee67178SXianjun Jiao #include <linux/io-64-nonatomic-lo-hi.h>
21*2ee67178SXianjun Jiao 
22*2ee67178SXianjun Jiao #include "../hw_def.h"
23*2ee67178SXianjun Jiao 
24*2ee67178SXianjun 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
25*2ee67178SXianjun Jiao 
26*2ee67178SXianjun Jiao /* IO accessors */
27*2ee67178SXianjun Jiao static inline u32 reg_read(u32 reg)
28*2ee67178SXianjun Jiao {
29*2ee67178SXianjun Jiao 	return ioread32(base_addr + reg);
30*2ee67178SXianjun Jiao }
31*2ee67178SXianjun Jiao 
32*2ee67178SXianjun Jiao static inline void reg_write(u32 reg, u32 value)
33*2ee67178SXianjun Jiao {
34*2ee67178SXianjun Jiao 	iowrite32(value, base_addr + reg);
35*2ee67178SXianjun Jiao }
36*2ee67178SXianjun Jiao 
37*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MULTI_RST_read(void){
38*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_MULTI_RST_ADDR);
39*2ee67178SXianjun Jiao }
40*2ee67178SXianjun Jiao 
41*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_MIXER_CFG_read(void){
42*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_MIXER_CFG_ADDR);
43*2ee67178SXianjun Jiao }
44*2ee67178SXianjun Jiao 
45*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_SRC_SEL_read(void){
46*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_IQ_SRC_SEL_ADDR);
47*2ee67178SXianjun Jiao }
48*2ee67178SXianjun Jiao 
49*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_IQ_CTRL_read(void){
50*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_IQ_CTRL_ADDR);
51*2ee67178SXianjun Jiao }
52*2ee67178SXianjun Jiao 
53*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_MODE_read(void){
54*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR);
55*2ee67178SXianjun Jiao }
56*2ee67178SXianjun Jiao 
57*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_read(void){
58*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_START_TRANS_TO_PS_ADDR);
59*2ee67178SXianjun Jiao }
60*2ee67178SXianjun Jiao 
61*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read(void){
62*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR);
63*2ee67178SXianjun Jiao }
64*2ee67178SXianjun Jiao 
65*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read(void){
66*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR);
67*2ee67178SXianjun Jiao }
68*2ee67178SXianjun Jiao 
69*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read(void){
70*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR);
71*2ee67178SXianjun Jiao }
72*2ee67178SXianjun Jiao 
73*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_CFG_DATA_TO_ANT_read(void){
74*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR);
75*2ee67178SXianjun Jiao }
76*2ee67178SXianjun Jiao 
77*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_ANT_SEL_read(void){
78*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_ANT_SEL_ADDR);
79*2ee67178SXianjun Jiao }
80*2ee67178SXianjun Jiao 
81*2ee67178SXianjun Jiao static inline u32 RX_INTF_REG_INTERRUPT_TEST_read(void) {
82*2ee67178SXianjun Jiao 	return reg_read(RX_INTF_REG_INTERRUPT_TEST_ADDR);
83*2ee67178SXianjun Jiao }
84*2ee67178SXianjun Jiao 
85*2ee67178SXianjun Jiao static inline void RX_INTF_REG_MULTI_RST_write(u32 value){
86*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_MULTI_RST_ADDR, value);
87*2ee67178SXianjun Jiao }
88*2ee67178SXianjun Jiao 
89*2ee67178SXianjun Jiao static inline void RX_INTF_REG_M_AXIS_RST_write(u32 value){
90*2ee67178SXianjun Jiao 	u32 reg_val;
91*2ee67178SXianjun Jiao 
92*2ee67178SXianjun Jiao 	if (value==0) {
93*2ee67178SXianjun Jiao 		reg_val = RX_INTF_REG_MULTI_RST_read();
94*2ee67178SXianjun Jiao 		reg_val = ( reg_val&(~(1<<4)) );
95*2ee67178SXianjun Jiao 		RX_INTF_REG_MULTI_RST_write(reg_val);
96*2ee67178SXianjun Jiao 	} else {
97*2ee67178SXianjun Jiao 		reg_val = RX_INTF_REG_MULTI_RST_read();
98*2ee67178SXianjun Jiao 		reg_val = ( reg_val|(1<<4) );
99*2ee67178SXianjun Jiao 		RX_INTF_REG_MULTI_RST_write(reg_val);
100*2ee67178SXianjun Jiao 	}
101*2ee67178SXianjun Jiao }
102*2ee67178SXianjun Jiao 
103*2ee67178SXianjun Jiao static inline void RX_INTF_REG_MIXER_CFG_write(u32 value){
104*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_MIXER_CFG_ADDR, value);
105*2ee67178SXianjun Jiao }
106*2ee67178SXianjun Jiao 
107*2ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_SRC_SEL_write(u32 value){
108*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_IQ_SRC_SEL_ADDR, value);
109*2ee67178SXianjun Jiao }
110*2ee67178SXianjun Jiao 
111*2ee67178SXianjun Jiao static inline void RX_INTF_REG_IQ_CTRL_write(u32 value){
112*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_IQ_CTRL_ADDR, value);
113*2ee67178SXianjun Jiao }
114*2ee67178SXianjun Jiao 
115*2ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_MODE_write(u32 value){
116*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_START_TRANS_TO_PS_MODE_ADDR, value);
117*2ee67178SXianjun Jiao }
118*2ee67178SXianjun Jiao 
119*2ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_write(u32 value){
120*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_START_TRANS_TO_PS_ADDR, value);
121*2ee67178SXianjun Jiao }
122*2ee67178SXianjun Jiao 
123*2ee67178SXianjun Jiao static inline void RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(u32 value){
124*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_ADDR, value);
125*2ee67178SXianjun Jiao }
126*2ee67178SXianjun Jiao 
127*2ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(u32 value){
128*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_ADDR, value);
129*2ee67178SXianjun Jiao }
130*2ee67178SXianjun Jiao 
131*2ee67178SXianjun Jiao static inline void RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(u32 value){
132*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_ADDR, value);
133*2ee67178SXianjun Jiao }
134*2ee67178SXianjun Jiao 
135*2ee67178SXianjun Jiao static inline void RX_INTF_REG_CFG_DATA_TO_ANT_write(u32 value){
136*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_CFG_DATA_TO_ANT_ADDR, value);
137*2ee67178SXianjun Jiao }
138*2ee67178SXianjun Jiao 
139*2ee67178SXianjun Jiao static inline void RX_INTF_REG_ANT_SEL_write(u32 value){
140*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_ANT_SEL_ADDR, value);
141*2ee67178SXianjun Jiao }
142*2ee67178SXianjun Jiao 
143*2ee67178SXianjun Jiao static inline void RX_INTF_REG_INTERRUPT_TEST_write(u32 value) {
144*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_INTERRUPT_TEST_ADDR, value);
145*2ee67178SXianjun Jiao }
146*2ee67178SXianjun Jiao 
147*2ee67178SXianjun Jiao static inline void RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(u32 value) {
148*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_S2MM_INTR_DELAY_COUNT_ADDR, value);
149*2ee67178SXianjun Jiao }
150*2ee67178SXianjun Jiao 
151*2ee67178SXianjun Jiao static inline void RX_INTF_REG_TLAST_TIMEOUT_TOP_write(u32 value) {
152*2ee67178SXianjun Jiao 	reg_write(RX_INTF_REG_TLAST_TIMEOUT_TOP_ADDR, value);
153*2ee67178SXianjun Jiao }
154*2ee67178SXianjun Jiao 
155*2ee67178SXianjun Jiao static const struct of_device_id dev_of_ids[] = {
156*2ee67178SXianjun Jiao 	{ .compatible = "sdr,rx_intf", },
157*2ee67178SXianjun Jiao 	{}
158*2ee67178SXianjun Jiao };
159*2ee67178SXianjun Jiao MODULE_DEVICE_TABLE(of, dev_of_ids);
160*2ee67178SXianjun Jiao 
161*2ee67178SXianjun Jiao static struct rx_intf_driver_api rx_intf_driver_api_inst;
162*2ee67178SXianjun Jiao //EXPORT_SYMBOL(rx_intf_driver_api_inst);
163*2ee67178SXianjun Jiao static struct rx_intf_driver_api *rx_intf_api = &rx_intf_driver_api_inst;
164*2ee67178SXianjun Jiao EXPORT_SYMBOL(rx_intf_api);
165*2ee67178SXianjun Jiao 
166*2ee67178SXianjun Jiao static inline u32 hw_init(enum rx_intf_mode mode, u32 num_dma_symbol_to_pl, u32 num_dma_symbol_to_ps){
167*2ee67178SXianjun Jiao 	int err=0;
168*2ee67178SXianjun Jiao 	u32 reg_val, mixer_cfg=0, ant_sel=0;
169*2ee67178SXianjun Jiao 
170*2ee67178SXianjun Jiao 	printk("%s hw_init mode %d\n", rx_intf_compatible_str, mode);
171*2ee67178SXianjun Jiao 
172*2ee67178SXianjun Jiao 	////rst wifi rx -- slv_reg11[2] is actual rx reset. slv_reg11[0] only reset axi lite of rx
173*2ee67178SXianjun Jiao 	//printk("%s hw_init reset wifi rx\n", rx_intf_compatible_str);
174*2ee67178SXianjun Jiao 	//rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0);
175*2ee67178SXianjun Jiao 	//rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(4);
176*2ee67178SXianjun Jiao 	//rx_intf_api->RX_INTF_REG_RST_START_TO_EXT_write(0);
177*2ee67178SXianjun Jiao 
178*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write(7000);
179*2ee67178SXianjun Jiao 	//rst ddc internal module
180*2ee67178SXianjun Jiao 	for (reg_val=0;reg_val<32;reg_val++)
181*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_MULTI_RST_write(0xFFFFFFFF);
182*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
183*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start
184*2ee67178SXianjun Jiao 
185*2ee67178SXianjun Jiao 	switch(mode)
186*2ee67178SXianjun Jiao 	{
187*2ee67178SXianjun Jiao 		case RX_INTF_AXIS_LOOP_BACK:
188*2ee67178SXianjun Jiao 			printk("%s hw_init mode RX_INTF_AXIS_LOOP_BACK\n", rx_intf_compatible_str);
189*2ee67178SXianjun Jiao 			//setting the path and mode. This must be done before our dma end reset
190*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write(0x15);
191*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(1);
192*2ee67178SXianjun 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
193*2ee67178SXianjun Jiao 
194*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(num_dma_symbol_to_pl);
195*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps);
196*2ee67178SXianjun Jiao 
197*2ee67178SXianjun Jiao 			// put bb_en to constant 1
198*2ee67178SXianjun Jiao 			reg_val = rx_intf_api->RX_INTF_REG_IQ_CTRL_read();
199*2ee67178SXianjun Jiao 			reg_val = (reg_val|0x8);
200*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_IQ_CTRL_write(reg_val);
201*2ee67178SXianjun Jiao 
202*2ee67178SXianjun Jiao 			// connect axis slave and master directly for loopback
203*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x1037);
204*2ee67178SXianjun Jiao 
205*2ee67178SXianjun Jiao 			// reset dma end point in our design
206*2ee67178SXianjun Jiao 			reg_val = rx_intf_api->RX_INTF_REG_MULTI_RST_read();
207*2ee67178SXianjun Jiao 			reg_val = (reg_val&(~0x14) );
208*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val);
209*2ee67178SXianjun Jiao 			reg_val = reg_val|(0x14);
210*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val);
211*2ee67178SXianjun Jiao 			reg_val = reg_val&(~0x14);
212*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_MULTI_RST_write(reg_val);
213*2ee67178SXianjun Jiao 
214*2ee67178SXianjun Jiao 			//start 1 trans now from our m_axis to ps dma
215*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0);
216*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(1);
217*2ee67178SXianjun Jiao 			rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0);
218*2ee67178SXianjun Jiao 			break;
219*2ee67178SXianjun Jiao 
220*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_0MHZ_ANT0:
221*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_0MHZ\n", rx_intf_compatible_str);
222*2ee67178SXianjun Jiao 			mixer_cfg = 0x300200F4;
223*2ee67178SXianjun Jiao 			ant_sel=0;
224*2ee67178SXianjun Jiao 			break;
225*2ee67178SXianjun Jiao 
226*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_0MHZ_ANT1:
227*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_0MHZ\n", rx_intf_compatible_str);
228*2ee67178SXianjun Jiao 			mixer_cfg = 0x300200F4;
229*2ee67178SXianjun Jiao 			ant_sel=1;
230*2ee67178SXianjun Jiao 			break;
231*2ee67178SXianjun Jiao 
232*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0:
233*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_N_10MHZ\n", rx_intf_compatible_str);
234*2ee67178SXianjun Jiao 			mixer_cfg = 0x300202F6;
235*2ee67178SXianjun Jiao 			ant_sel=0;
236*2ee67178SXianjun Jiao 			break;
237*2ee67178SXianjun Jiao 
238*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_N_10MHZ_ANT1:
239*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_N_10MHZ\n", rx_intf_compatible_str);
240*2ee67178SXianjun Jiao 			mixer_cfg = 0x300202F6;
241*2ee67178SXianjun Jiao 			ant_sel=1;
242*2ee67178SXianjun Jiao 			break;
243*2ee67178SXianjun Jiao 
244*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_P_10MHZ_ANT0:
245*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_P_10MHZ\n", rx_intf_compatible_str);
246*2ee67178SXianjun Jiao 			mixer_cfg = 0x3001F602;
247*2ee67178SXianjun Jiao 			ant_sel=0;
248*2ee67178SXianjun Jiao 			break;
249*2ee67178SXianjun Jiao 
250*2ee67178SXianjun Jiao 		case RX_INTF_BW_20MHZ_AT_P_10MHZ_ANT1:
251*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BW_20MHZ_AT_P_10MHZ\n", rx_intf_compatible_str);
252*2ee67178SXianjun Jiao 			mixer_cfg = 0x3001F602;
253*2ee67178SXianjun Jiao 			ant_sel=1;
254*2ee67178SXianjun Jiao 			break;
255*2ee67178SXianjun Jiao 
256*2ee67178SXianjun Jiao 		case RX_INTF_BYPASS:
257*2ee67178SXianjun Jiao 			printk("%s hw_init mode DDC_BYPASS\n", rx_intf_compatible_str);
258*2ee67178SXianjun Jiao 			mixer_cfg = 0x3001F602;
259*2ee67178SXianjun Jiao 			break;
260*2ee67178SXianjun Jiao 
261*2ee67178SXianjun Jiao 		default:
262*2ee67178SXianjun Jiao 			printk("%s hw_init mode %d is wrong!\n", rx_intf_compatible_str, mode);
263*2ee67178SXianjun Jiao 			err=1;
264*2ee67178SXianjun Jiao 	}
265*2ee67178SXianjun Jiao 
266*2ee67178SXianjun Jiao 	if (mode!=RX_INTF_AXIS_LOOP_BACK) {
267*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_MIXER_CFG_write(mixer_cfg);
268*2ee67178SXianjun 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
269*2ee67178SXianjun 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
270*2ee67178SXianjun 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
271*2ee67178SXianjun Jiao 		// 0x2101F602 for: wifi gain 4;   zigbee gain 2
272*2ee67178SXianjun Jiao 		// 0xFE01F602 for: wifi gain 1/2; zigbee gain 1/4
273*2ee67178SXianjun Jiao 		// bits definitions:
274*2ee67178SXianjun Jiao 		// wifi ch selection:     ant0 bit1~0; ant1 bit 9~8; ch offset: 0-0MHz; 1-5MHz; 2-10MHz; 3-15MHz(severe distortion)
275*2ee67178SXianjun Jiao 		// wifi ch +/- selection: ant0 bit2; ant1 bit 10; 0-positive; 1-negative
276*2ee67178SXianjun Jiao 		// zigbee 2M mixer +/- selection:        ant0   bit3; ant1    bit 11; 0-positive; 1-negative
277*2ee67178SXianjun Jiao 		// zigbee secondary mixer +/- selection: ant0 bit4~7; ant1 bit 12~15; 0-positive; 1-negative
278*2ee67178SXianjun 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
279*2ee67178SXianjun Jiao 		// wifi gain: bit31~28; number of bits shifted to left in 2'complement code
280*2ee67178SXianjun Jiao 		// zigb gain: bit27~24; number of bits shifted to left in 2'complement code
281*2ee67178SXianjun 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
282*2ee67178SXianjun Jiao 
283*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
284*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start
285*2ee67178SXianjun Jiao 
286*2ee67178SXianjun Jiao 		//rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x000);
287*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write(0x100);
288*2ee67178SXianjun Jiao 		//0x000-normal; 0x100-sig and fcs valid are controled by bit4 and bit0;
289*2ee67178SXianjun Jiao 		//0x111-sig and fcs high; 0x110-sig high fcs low; 0x101-sig low fcs high; 0x100-sig and fcs low
290*2ee67178SXianjun Jiao 
291*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write(0);
292*2ee67178SXianjun Jiao 		// 0-bw20-ch0; 1-bw2-ch0;  2-bw2-ch2;  3-bw2-ch4;  4-bw2-ch6;  5-s_axis-ch0
293*2ee67178SXianjun Jiao 		// 8-bw20-ch1; 9-bw2-ch1; 10-bw2-ch3; 11-bw2-ch5; 12-bw2-ch7; 13-s_axis-ch1
294*2ee67178SXianjun Jiao 
295*2ee67178SXianjun Jiao 		//rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(1000|0x80000000); //0x80000000 to enable tsft and rssi gpio test magic value
296*2ee67178SXianjun Jiao 		//rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(200*10); //0x80000000 to enable tsft and rssi gpio test magic value
297*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write(30*200); // delayed interrupt
298*2ee67178SXianjun Jiao 
299*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_IQ_CTRL_write(0);
300*2ee67178SXianjun 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
301*2ee67178SXianjun Jiao 		//rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write(0x00025); //bit16 enable_m_axis_auto_rst
302*2ee67178SXianjun Jiao 		//bit2-0: source of M AXIS transfer trigger
303*2ee67178SXianjun Jiao 		//		 -0 fcs_valid_from_acc
304*2ee67178SXianjun Jiao 		//		 -1 sig_valid_from_acc
305*2ee67178SXianjun Jiao 		//		 -2 sig_invalid_from_acc
306*2ee67178SXianjun Jiao 		//		 -3 start_1trans_s_axis_tlast_trigger
307*2ee67178SXianjun Jiao 		//		 -4 start_1trans_s_axis_tready_trigger
308*2ee67178SXianjun Jiao 		//		 -5 internal state machine together with bit5 1. By parsing signal field, num_dma_symbol_to_ps can be decided automatically
309*2ee67178SXianjun Jiao 		//		 -6 start_1trans_monitor_dma_to_ps_start_trigger
310*2ee67178SXianjun Jiao 		//		 -7 start_1trans_ext_trigger
311*2ee67178SXianjun Jiao 		//bit3:  1-fcs valid and invalid both connected; 0-only fcs valid connected (fcs_invalid_mode)
312*2ee67178SXianjun Jiao 		//bit4:  1-num_dma_symbol_to_pl from monitor; 0-num_dma_symbol_to_pl from slv_reg8
313*2ee67178SXianjun Jiao 		//bit5:  1-num_dma_symbol_to_ps from monitor; 0-num_dma_symbol_to_ps from slv_reg9
314*2ee67178SXianjun Jiao 		//bit6:  1-pl_to_m_axis_intf will try to send both ht and non-ht; 0-only send non-ht
315*2ee67178SXianjun Jiao 		//bit8:  1-endless S AXIS; 0-normal
316*2ee67178SXianjun Jiao 		//bit9:  1-endless M AXIS; 0-normal
317*2ee67178SXianjun Jiao 		//bit12: 1-direct loop back; 0-normal
318*2ee67178SXianjun 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
319*2ee67178SXianjun Jiao 		//bit24: 1-disable m_axis fifo_rst_by_fcs_invalid; 0-enable
320*2ee67178SXianjun Jiao 		//bit29,28: sig_valid_mode. 0- non-ht sig valid; 1- ht sig valid other- both
321*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write(0);
322*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write(0);
323*2ee67178SXianjun Jiao 		// 0-wifi_rx packet out; 1-loopback from input of wifi_rx
324*2ee67178SXianjun Jiao 
325*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write(num_dma_symbol_to_pl);
326*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write(num_dma_symbol_to_ps);
327*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(1<<8);
328*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_ANT_SEL_write(ant_sel);
329*2ee67178SXianjun Jiao 
330*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_MULTI_RST_write(0x14);//rst m/s axis
331*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_MULTI_RST_write(0);
332*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_M_AXIS_RST_write(1); // hold M AXIS in reset status. will be released when openwifi_start
333*2ee67178SXianjun Jiao 	}
334*2ee67178SXianjun Jiao 
335*2ee67178SXianjun Jiao 	if (mode==RX_INTF_BYPASS) {
336*2ee67178SXianjun Jiao 		rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write(0x10); //bit4 bypass enable
337*2ee67178SXianjun Jiao 	}
338*2ee67178SXianjun Jiao 
339*2ee67178SXianjun Jiao 	printk("%s hw_init err %d\n", rx_intf_compatible_str, err);
340*2ee67178SXianjun Jiao 	return(err);
341*2ee67178SXianjun Jiao }
342*2ee67178SXianjun Jiao 
343*2ee67178SXianjun Jiao static int dev_probe(struct platform_device *pdev)
344*2ee67178SXianjun Jiao {
345*2ee67178SXianjun Jiao 	struct device_node *np = pdev->dev.of_node;
346*2ee67178SXianjun Jiao 	struct resource *io;
347*2ee67178SXianjun Jiao 	int err=1;
348*2ee67178SXianjun Jiao 
349*2ee67178SXianjun Jiao 	printk("\n");
350*2ee67178SXianjun Jiao 
351*2ee67178SXianjun Jiao 	if (np) {
352*2ee67178SXianjun Jiao 		const struct of_device_id *match;
353*2ee67178SXianjun Jiao 
354*2ee67178SXianjun Jiao 		match = of_match_node(dev_of_ids, np);
355*2ee67178SXianjun Jiao 		if (match) {
356*2ee67178SXianjun Jiao 			printk("%s dev_probe match!\n", rx_intf_compatible_str);
357*2ee67178SXianjun Jiao 			err = 0;
358*2ee67178SXianjun Jiao 		}
359*2ee67178SXianjun Jiao 	}
360*2ee67178SXianjun Jiao 
361*2ee67178SXianjun Jiao 	if (err)
362*2ee67178SXianjun Jiao 		return err;
363*2ee67178SXianjun Jiao 
364*2ee67178SXianjun Jiao 	rx_intf_api->hw_init=hw_init;
365*2ee67178SXianjun Jiao 
366*2ee67178SXianjun Jiao 	rx_intf_api->reg_read=reg_read;
367*2ee67178SXianjun Jiao 	rx_intf_api->reg_write=reg_write;
368*2ee67178SXianjun Jiao 
369*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_MULTI_RST_read=RX_INTF_REG_MULTI_RST_read;
370*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_MIXER_CFG_read=RX_INTF_REG_MIXER_CFG_read;
371*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_read=RX_INTF_REG_IQ_SRC_SEL_read;
372*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_IQ_CTRL_read=RX_INTF_REG_IQ_CTRL_read;
373*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_read=RX_INTF_REG_START_TRANS_TO_PS_MODE_read;
374*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_read=RX_INTF_REG_START_TRANS_TO_PS_read;
375*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_read;
376*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_read;
377*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_read;
378*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_read=RX_INTF_REG_CFG_DATA_TO_ANT_read;
379*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_ANT_SEL_read=RX_INTF_REG_ANT_SEL_read;
380*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_read=RX_INTF_REG_INTERRUPT_TEST_read;
381*2ee67178SXianjun Jiao 
382*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_MULTI_RST_write=RX_INTF_REG_MULTI_RST_write;
383*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_M_AXIS_RST_write=RX_INTF_REG_M_AXIS_RST_write;
384*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_MIXER_CFG_write=RX_INTF_REG_MIXER_CFG_write;
385*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_IQ_SRC_SEL_write=RX_INTF_REG_IQ_SRC_SEL_write;
386*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_IQ_CTRL_write=RX_INTF_REG_IQ_CTRL_write;
387*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_MODE_write=RX_INTF_REG_START_TRANS_TO_PS_MODE_write;
388*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_write=RX_INTF_REG_START_TRANS_TO_PS_write;
389*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write=RX_INTF_REG_START_TRANS_TO_PS_SRC_SEL_write;
390*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PL_write;
391*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write=RX_INTF_REG_NUM_DMA_SYMBOL_TO_PS_write;
392*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_CFG_DATA_TO_ANT_write=RX_INTF_REG_CFG_DATA_TO_ANT_write;
393*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_ANT_SEL_write=RX_INTF_REG_ANT_SEL_write;
394*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_INTERRUPT_TEST_write=RX_INTF_REG_INTERRUPT_TEST_write;
395*2ee67178SXianjun Jiao 
396*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write=RX_INTF_REG_S2MM_INTR_DELAY_COUNT_write;
397*2ee67178SXianjun Jiao 	rx_intf_api->RX_INTF_REG_TLAST_TIMEOUT_TOP_write=RX_INTF_REG_TLAST_TIMEOUT_TOP_write;
398*2ee67178SXianjun Jiao 
399*2ee67178SXianjun Jiao 	/* Request and map I/O memory */
400*2ee67178SXianjun Jiao 	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
401*2ee67178SXianjun Jiao 	base_addr = devm_ioremap_resource(&pdev->dev, io);
402*2ee67178SXianjun Jiao 	if (IS_ERR(base_addr))
403*2ee67178SXianjun Jiao 		return PTR_ERR(base_addr);
404*2ee67178SXianjun Jiao 
405*2ee67178SXianjun Jiao 	rx_intf_api->io_start = io->start;
406*2ee67178SXianjun Jiao 	rx_intf_api->base_addr = (u32)base_addr;
407*2ee67178SXianjun Jiao 
408*2ee67178SXianjun 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);
409*2ee67178SXianjun Jiao 	printk("%s dev_probe base_addr 0x%08x\n", rx_intf_compatible_str,(u32)base_addr);
410*2ee67178SXianjun Jiao 	printk("%s dev_probe rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) );
411*2ee67178SXianjun Jiao 	printk("%s dev_probe             rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api);
412*2ee67178SXianjun Jiao 
413*2ee67178SXianjun Jiao 	printk("%s dev_probe succeed!\n", rx_intf_compatible_str);
414*2ee67178SXianjun Jiao 
415*2ee67178SXianjun Jiao 	//err = hw_init(DDC_CURRENT_CH_OFFSET_CFG,8,8);
416*2ee67178SXianjun Jiao 	err = hw_init(RX_INTF_BW_20MHZ_AT_0MHZ_ANT0,8,8);
417*2ee67178SXianjun Jiao 
418*2ee67178SXianjun Jiao 	return err;
419*2ee67178SXianjun Jiao }
420*2ee67178SXianjun Jiao 
421*2ee67178SXianjun Jiao static int dev_remove(struct platform_device *pdev)
422*2ee67178SXianjun Jiao {
423*2ee67178SXianjun Jiao 	printk("\n");
424*2ee67178SXianjun Jiao 
425*2ee67178SXianjun Jiao 	printk("%s dev_remove base_addr 0x%08x\n", rx_intf_compatible_str, (u32)base_addr);
426*2ee67178SXianjun Jiao 	printk("%s dev_remove rx_intf_driver_api_inst 0x%08x\n", rx_intf_compatible_str, (u32)(&rx_intf_driver_api_inst) );
427*2ee67178SXianjun Jiao 	printk("%s dev_remove             rx_intf_api 0x%08x\n", rx_intf_compatible_str, (u32)rx_intf_api);
428*2ee67178SXianjun Jiao 
429*2ee67178SXianjun Jiao 	printk("%s dev_remove succeed!\n", rx_intf_compatible_str);
430*2ee67178SXianjun Jiao 	return 0;
431*2ee67178SXianjun Jiao }
432*2ee67178SXianjun Jiao 
433*2ee67178SXianjun Jiao static struct platform_driver dev_driver = {
434*2ee67178SXianjun Jiao 	.driver = {
435*2ee67178SXianjun Jiao 		.name = "sdr,rx_intf",
436*2ee67178SXianjun Jiao 		.owner = THIS_MODULE,
437*2ee67178SXianjun Jiao 		.of_match_table = dev_of_ids,
438*2ee67178SXianjun Jiao 	},
439*2ee67178SXianjun Jiao 	.probe = dev_probe,
440*2ee67178SXianjun Jiao 	.remove = dev_remove,
441*2ee67178SXianjun Jiao };
442*2ee67178SXianjun Jiao 
443*2ee67178SXianjun Jiao module_platform_driver(dev_driver);
444*2ee67178SXianjun Jiao 
445*2ee67178SXianjun Jiao MODULE_AUTHOR("Xianjun Jiao");
446*2ee67178SXianjun Jiao MODULE_DESCRIPTION("sdr,rx_intf");
447*2ee67178SXianjun Jiao MODULE_LICENSE("GPL v2");
448