MT6620: add the new driver JB2 V1.0
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_fm / mt6628 / pub / mt6628_fm_cmd.c
1 #include <linux/kernel.h>
2 #include <linux/types.h>
3
4 #include "fm_typedef.h"
5 #include "fm_dbg.h"
6 #include "fm_err.h"
7 #include "fm_rds.h"
8 #include "fm_config.h"
9 #include "fm_link.h"
10
11 #include "mt6628_fm_reg.h"
12 //#include "mt6628_fm_link.h"
13 #include "mt6628_fm.h"
14 #include "mt6628_fm_cmd.h"
15 #include "mt6628_fm_cust_cfg.h"
16
17 extern fm_cust_cfg mt6628_fm_config;
18
19 static fm_s32 fm_bop_write(fm_u8 addr, fm_u16 value, fm_u8 *buf, fm_s32 size)
20 {
21     if (size < (FM_WRITE_BASIC_OP_SIZE + 2)) {
22         return (-1);
23     }
24
25     if (buf == NULL) {
26         return (-2);
27     }
28
29     buf[0] = FM_WRITE_BASIC_OP;
30     buf[1] = FM_WRITE_BASIC_OP_SIZE;
31     buf[2] = addr;
32     buf[3] = (fm_u8)((value) & 0x00FF);
33     buf[4] = (fm_u8)((value >> 8) & 0x00FF);
34
35     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4]);
36
37     return (FM_WRITE_BASIC_OP_SIZE + 2);
38 }
39
40
41 static fm_s32 fm_bop_udelay(fm_u32 value, fm_u8 *buf, fm_s32 size)
42 {
43     if (size < (FM_UDELAY_BASIC_OP_SIZE + 2)) {
44         return (-1);
45     }
46
47     if (buf == NULL) {
48         return (-2);
49     }
50
51     buf[0] = FM_UDELAY_BASIC_OP;
52     buf[1] = FM_UDELAY_BASIC_OP_SIZE;
53     buf[2] = (fm_u8)((value) & 0x000000FF);
54     buf[3] = (fm_u8)((value >> 8) & 0x000000FF);
55     buf[4] = (fm_u8)((value >> 16) & 0x000000FF);
56     buf[5] = (fm_u8)((value >> 24) & 0x000000FF);
57
58     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
59
60     return (FM_UDELAY_BASIC_OP_SIZE + 2);
61 }
62
63
64 static fm_s32 fm_bop_rd_until(fm_u8 addr, fm_u16 mask, fm_u16 value, fm_u8 *buf, fm_s32 size)
65 {
66     if (size < (FM_RD_UNTIL_BASIC_OP_SIZE + 2)) {
67         return (-1);
68     }
69
70     if (buf == NULL) {
71         return (-2);
72     }
73
74     buf[0] = FM_RD_UNTIL_BASIC_OP;
75     buf[1] = FM_RD_UNTIL_BASIC_OP_SIZE;
76     buf[2] = addr;
77     buf[3] = (fm_u8)((mask) & 0x00FF);
78     buf[4] = (fm_u8)((mask >> 8) & 0x00FF);
79     buf[5] = (fm_u8)((value) & 0x00FF);
80     buf[6] = (fm_u8)((value >> 8) & 0x00FF);
81
82     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
83
84     return (FM_RD_UNTIL_BASIC_OP_SIZE + 2);
85 }
86
87
88 static fm_s32 fm_bop_modify(fm_u8 addr, fm_u16 mask_and, fm_u16 mask_or, fm_u8 *buf, fm_s32 size)
89 {
90     if (size < (FM_MODIFY_BASIC_OP_SIZE + 2)) {
91         return (-1);
92     }
93
94     if (buf == NULL) {
95         return (-2);
96     }
97
98     buf[0] = FM_MODIFY_BASIC_OP;
99     buf[1] = FM_MODIFY_BASIC_OP_SIZE;
100     buf[2] = addr;
101     buf[3] = (fm_u8)((mask_and) & 0x00FF);
102     buf[4] = (fm_u8)((mask_and >> 8) & 0x00FF);
103     buf[5] = (fm_u8)((mask_or) & 0x00FF);
104     buf[6] = (fm_u8)((mask_or >> 8) & 0x00FF);
105
106     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
107
108     return (FM_MODIFY_BASIC_OP_SIZE + 2);
109 }
110
111 #if 0
112 static fm_s32 fm_bop_msleep(fm_u32 value, fm_u8 *buf, fm_s32 size)
113 {
114     if (size < (FM_MSLEEP_BASIC_OP_SIZE + 2)) {
115         return (-1);
116     }
117
118     if (buf == NULL) {
119         return (-2);
120     }
121
122     buf[0] = FM_MSLEEP_BASIC_OP;
123     buf[1] = FM_MSLEEP_BASIC_OP_SIZE;
124     buf[2] = (fm_u8)((value) & 0x000000FF);
125     buf[3] = (fm_u8)((value >> 8) & 0x000000FF);
126     buf[4] = (fm_u8)((value >> 16) & 0x000000FF);
127     buf[5] = (fm_u8)((value >> 24) & 0x000000FF);
128
129     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
130
131     return (FM_MSLEEP_BASIC_OP_SIZE + 2);
132 }
133 #endif
134
135 /*
136 inline fm_s32 fm_get_channel_space(fm_s32 freq)
137 {
138     if ((freq >= 760) && (freq <= 1080)) {
139         return 0;
140     } else if ((freq >= 7600) && (freq <= 10800)) {
141         return 1;
142     } else {
143         return -1;
144     }
145 }
146 */
147
148 fm_s32 mt6628_pwrup_fpga_on(fm_u8 *buf, fm_s32 buf_size)
149 {
150     fm_s32 pkt_size = 0;
151
152     if (buf_size < TX_BUF_SIZE) {
153         return (-1);
154     }
155
156     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
157     buf[1] = FM_ENABLE_OPCODE;
158     pkt_size = 4;
159
160     //Turn on Central Bias + FC
161     pkt_size += fm_bop_write(0x01, 0x4A00, &buf[pkt_size], buf_size - pkt_size);
162     pkt_size += fm_bop_udelay(30000, &buf[pkt_size], buf_size - pkt_size);//delay 30ms
163     pkt_size += fm_bop_write(0x01, 0x6A00, &buf[pkt_size], buf_size - pkt_size);
164     pkt_size += fm_bop_udelay(50000, &buf[pkt_size], buf_size - pkt_size);//delay 50ms
165     pkt_size += fm_bop_write(0x02, 0x099C, &buf[pkt_size], buf_size - pkt_size);
166     pkt_size += fm_bop_write(0x01, 0x6B82, &buf[pkt_size], buf_size - pkt_size);
167     pkt_size += fm_bop_write(0x04, 0x0142, &buf[pkt_size], buf_size - pkt_size);
168     pkt_size += fm_bop_write(0x05, 0x00E7, &buf[pkt_size], buf_size - pkt_size);
169     pkt_size += fm_bop_write(0x0A, 0x0060, &buf[pkt_size], buf_size - pkt_size);
170     pkt_size += fm_bop_write(0x0C, 0xAF8F, &buf[pkt_size], buf_size - pkt_size);
171     pkt_size += fm_bop_write(0x0D, 0x0888, &buf[pkt_size], buf_size - pkt_size);
172     pkt_size += fm_bop_write(0x10, 0x0E8D, &buf[pkt_size], buf_size - pkt_size);
173     pkt_size += fm_bop_write(0x27, 0x0104, &buf[pkt_size], buf_size - pkt_size);
174     pkt_size += fm_bop_write(0x0e, 0x0040, &buf[pkt_size], buf_size - pkt_size);
175     pkt_size += fm_bop_write(0x03, 0x9860, &buf[pkt_size], buf_size - pkt_size);
176     pkt_size += fm_bop_write(0x3F, 0xAD16, &buf[pkt_size], buf_size - pkt_size);
177     pkt_size += fm_bop_write(0x3E, 0x3280, &buf[pkt_size], buf_size - pkt_size);
178     pkt_size += fm_bop_write(0x06, 0x0125, &buf[pkt_size], buf_size - pkt_size);
179     pkt_size += fm_bop_write(0x08, 0x15B8, &buf[pkt_size], buf_size - pkt_size);
180     pkt_size += fm_bop_write(0x28, 0x0000, &buf[pkt_size], buf_size - pkt_size);
181     pkt_size += fm_bop_write(0x00, 0x0167, &buf[pkt_size], buf_size - pkt_size);
182     pkt_size += fm_bop_write(0x3A, 0x0004, &buf[pkt_size], buf_size - pkt_size);
183     pkt_size += fm_bop_write(0x25, 0x0403, &buf[pkt_size], buf_size - pkt_size);
184     pkt_size += fm_bop_write(0x20, 0x2720, &buf[pkt_size], buf_size - pkt_size);
185     pkt_size += fm_bop_write(0x22, 0x9980, &buf[pkt_size], buf_size - pkt_size);
186     pkt_size += fm_bop_write(0x25, 0x0803, &buf[pkt_size], buf_size - pkt_size);
187     pkt_size += fm_bop_write(0x1E, 0x0863, &buf[pkt_size], buf_size - pkt_size);
188     pkt_size += fm_bop_udelay(50000, &buf[pkt_size], buf_size - pkt_size);//delay 50ms
189     pkt_size += fm_bop_write(0x1E, 0x0865, &buf[pkt_size], buf_size - pkt_size);
190     pkt_size += fm_bop_udelay(50000, &buf[pkt_size], buf_size - pkt_size);//delay 50ms
191     pkt_size += fm_bop_write(0x1E, 0x0871, &buf[pkt_size], buf_size - pkt_size);
192     pkt_size += fm_bop_write(0x2A, 0x1020, &buf[pkt_size], buf_size - pkt_size);
193     pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size);//delay 100ms
194     pkt_size += fm_bop_write(0x00, 0x01E7, &buf[pkt_size], buf_size - pkt_size);
195     pkt_size += fm_bop_udelay(1000, &buf[pkt_size], buf_size - pkt_size);//delay 1ms
196     pkt_size += fm_bop_write(0x1B, 0x0094, &buf[pkt_size], buf_size - pkt_size);
197     pkt_size += fm_bop_write(0x1B, 0x0095, &buf[pkt_size], buf_size - pkt_size);
198     pkt_size += fm_bop_udelay(200000, &buf[pkt_size], buf_size - pkt_size);//delay 100ms
199     pkt_size += fm_bop_write(0x1B, 0x0094, &buf[pkt_size], buf_size - pkt_size);
200     pkt_size += fm_bop_write(0x00, 0x0167, &buf[pkt_size], buf_size - pkt_size);
201     pkt_size += fm_bop_write(0x01, 0x6B8A, &buf[pkt_size], buf_size - pkt_size);
202     pkt_size += fm_bop_udelay(1000, &buf[pkt_size], buf_size - pkt_size);//delay 1ms
203     pkt_size += fm_bop_write(0x00, 0xC167, &buf[pkt_size], buf_size - pkt_size);
204     pkt_size += fm_bop_write(0x0C, 0xAF8F, &buf[pkt_size], buf_size - pkt_size);
205     pkt_size += fm_bop_udelay(30000, &buf[pkt_size], buf_size - pkt_size);//delay 1ms
206     pkt_size += fm_bop_write(0x00, 0xF167, &buf[pkt_size], buf_size - pkt_size);
207     pkt_size += fm_bop_write(0x37, 0x2590, &buf[pkt_size], buf_size - pkt_size);
208     pkt_size += fm_bop_write(0x09, 0x2964, &buf[pkt_size], buf_size - pkt_size);
209     pkt_size += fm_bop_write(0x2E, 0x0008, &buf[pkt_size], buf_size - pkt_size);
210     pkt_size += fm_bop_write(0x11, 0x37D4, &buf[pkt_size], buf_size - pkt_size);
211     pkt_size += fm_bop_write(0x2B, 0x0032, &buf[pkt_size], buf_size - pkt_size);
212     pkt_size += fm_bop_write(0x2C, 0x0019, &buf[pkt_size], buf_size - pkt_size);
213     pkt_size += fm_bop_write(0x71, 0x607F, &buf[pkt_size], buf_size - pkt_size);
214     pkt_size += fm_bop_write(0x72, 0x878F, &buf[pkt_size], buf_size - pkt_size);
215     pkt_size += fm_bop_write(0x73, 0x07C3, &buf[pkt_size], buf_size - pkt_size);
216     pkt_size += fm_bop_write(0x28, 0x0000, &buf[pkt_size], buf_size - pkt_size);
217     pkt_size += fm_bop_write(0x64, 0x0001, &buf[pkt_size], buf_size - pkt_size);
218     pkt_size += fm_bop_write(0x6D, 0x1AB2, &buf[pkt_size], buf_size - pkt_size);
219     pkt_size += fm_bop_write(0x9C, 0x0040, &buf[pkt_size], buf_size - pkt_size);
220     pkt_size += fm_bop_write(0x9F, 0x0000, &buf[pkt_size], buf_size - pkt_size);
221     pkt_size += fm_bop_write(0xB4, 0x8810, &buf[pkt_size], buf_size - pkt_size);
222     pkt_size += fm_bop_write(0xB8, 0x006A, &buf[pkt_size], buf_size - pkt_size);
223     pkt_size += fm_bop_write(0xBB, 0x006B, &buf[pkt_size], buf_size - pkt_size);
224     pkt_size += fm_bop_write(0xCB, 0x00B3, &buf[pkt_size], buf_size - pkt_size);
225     pkt_size += fm_bop_write(0xE0, 0xA301, &buf[pkt_size], buf_size - pkt_size);
226     pkt_size += fm_bop_write(0xE4, 0x008F, &buf[pkt_size], buf_size - pkt_size);
227     pkt_size += fm_bop_write(0x9E, 0x2B24, &buf[pkt_size], buf_size - pkt_size);
228     pkt_size += fm_bop_write(0xCC, 0x0886, &buf[pkt_size], buf_size - pkt_size);
229     pkt_size += fm_bop_write(0xDC, 0x036A, &buf[pkt_size], buf_size - pkt_size);
230     pkt_size += fm_bop_write(0xDD, 0x836A, &buf[pkt_size], buf_size - pkt_size);
231     pkt_size += fm_bop_write(0x0F, 0x1AA8, &buf[pkt_size], buf_size - pkt_size);
232     pkt_size += fm_bop_write(0x9F, 0x0000, &buf[pkt_size], buf_size - pkt_size);
233     pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size);//delay 100ms
234     pkt_size += fm_bop_write(0x63, 0x0480, &buf[pkt_size], buf_size - pkt_size);
235     pkt_size += fm_bop_udelay(100000, &buf[pkt_size], buf_size - pkt_size);//delay 100ms
236     pkt_size += fm_bop_write(0x63, 0x0481, &buf[pkt_size], buf_size - pkt_size);
237
238     pkt_size += fm_bop_write(0x6C, 0x0020, &buf[pkt_size], buf_size - pkt_size);
239     pkt_size += fm_bop_write(0x45, 0x1FFF, &buf[pkt_size], buf_size - pkt_size);
240     pkt_size += fm_bop_write(0x25, 0x040F, &buf[pkt_size], buf_size - pkt_size);
241
242     pkt_size += fm_bop_write(0x28, 0x7E57, &buf[pkt_size], buf_size - pkt_size);
243     pkt_size += fm_bop_write(0x11, 0x37DC, &buf[pkt_size], buf_size - pkt_size);
244     pkt_size += fm_bop_write(0x07, 0x1140, &buf[pkt_size], buf_size - pkt_size);
245     pkt_size += fm_bop_write(0x27, 0x005C, &buf[pkt_size], buf_size - pkt_size);
246     pkt_size += fm_bop_write(0x42, 0x0016, &buf[pkt_size], buf_size - pkt_size);
247     pkt_size += fm_bop_write(0x44, 0x006F, &buf[pkt_size], buf_size - pkt_size);
248     pkt_size += fm_bop_write(0x46, 0x1DEF, &buf[pkt_size], buf_size - pkt_size);
249     pkt_size += fm_bop_write(0x47, 0x0210, &buf[pkt_size], buf_size - pkt_size);
250     pkt_size += fm_bop_write(0x55, 0x0001, &buf[pkt_size], buf_size - pkt_size);
251     pkt_size += fm_bop_write(0x54, 0x8001, &buf[pkt_size], buf_size - pkt_size);
252     pkt_size += fm_bop_write(0xA0, 0xD0B2, &buf[pkt_size], buf_size - pkt_size);
253
254     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
255     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
256
257     return pkt_size;
258 }
259
260
261 /*
262  * mt6628_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable
263  * @buf - target buf
264  * @buf_size - buffer size
265  * return package size
266  */
267 fm_s32 mt6628_pwrup_clock_on(fm_u8 *buf, fm_s32 buf_size)
268 {
269     fm_s32 pkt_size = 0;
270     fm_u16 de_emphasis;
271     fm_u16 osc_freq;
272
273     if (buf_size < TX_BUF_SIZE) {
274         return (-1);
275     }
276
277     de_emphasis = mt6628_fm_config.rx_cfg.deemphasis;//MT6628fm_cust_config_fetch(FM_CFG_RX_DEEMPHASIS);
278     de_emphasis &= 0x0001; //rang 0~1
279     osc_freq = mt6628_fm_config.rx_cfg.osc_freq;//MT6628fm_cust_config_fetch(FM_CFG_RX_OSC_FREQ);
280     osc_freq &= 0x0007; //rang 0~5
281
282     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
283     buf[1] = FM_ENABLE_OPCODE;
284     pkt_size = 4;
285
286     //FM Digital Clock enable
287     pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 60 0000
288     pkt_size += fm_bop_write(0x60, 0x0001, &buf[pkt_size], buf_size - pkt_size);//wr 60 0001
289     pkt_size += fm_bop_udelay(3000, &buf[pkt_size], buf_size - pkt_size);//delay 3ms
290     pkt_size += fm_bop_write(0x60, 0x0003, &buf[pkt_size], buf_size - pkt_size);//wr 60 0003
291     pkt_size += fm_bop_write(0x60, 0x0007, &buf[pkt_size], buf_size - pkt_size);//wr 60 0007
292     pkt_size += fm_bop_modify(0x70, 0xFFBF, 0x0040, &buf[pkt_size], buf_size - pkt_size); // wr 70 D6 = 1
293     //no low power mode, analog line in, long antenna
294     pkt_size += fm_bop_modify(0x61, 0xFF63, 0x0000, &buf[pkt_size], buf_size - pkt_size);
295     pkt_size += fm_bop_modify(0x61, ~DE_EMPHASIS, (de_emphasis << 12), &buf[pkt_size], buf_size - pkt_size);
296     pkt_size += fm_bop_modify(0x60, OSC_FREQ_MASK, (osc_freq << 4), &buf[pkt_size], buf_size - pkt_size);
297
298     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
299     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
300
301     return pkt_size;
302 }
303
304
305 /*
306  * mt6628_patch_download - Wholechip FM Power Up: step 3, download patch to f/w,
307  * @buf - target buf
308  * @buf_size - buffer size
309  * @seg_num - total segments that this patch divided into
310  * @seg_id - No. of Segments: segment that will now be sent
311  * @src - patch source buffer
312  * @seg_len - segment size: segment that will now be sent
313  * return package size
314  */
315 fm_s32 mt6628_patch_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id, const fm_u8 *src, fm_s32 seg_len)
316 {
317     fm_s32 pkt_size = 0;
318     fm_u8 *dst = NULL;
319
320     if (buf_size < TX_BUF_SIZE) {
321         return (-1);
322     }
323
324     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
325     buf[1] = FM_PATCH_DOWNLOAD_OPCODE;
326     pkt_size = 4;
327
328     buf[pkt_size++] = seg_num;
329     buf[pkt_size++] = seg_id;
330
331     if (seg_len > (buf_size - pkt_size)) {
332         return -1;
333     }
334
335     dst = &buf[pkt_size];
336     pkt_size += seg_len;
337
338     //copy patch to tx buffer
339     while (seg_len--) {
340         *dst = *src;
341         //printk(KERN_ALERT "%02x ", *dst);
342         src++;
343         dst++;
344     }
345
346     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
347     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
348     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
349
350     return pkt_size;
351 }
352
353
354 /*
355  * mt6628_coeff_download - Wholechip FM Power Up: step 3,download coeff to f/w,
356  * @buf - target buf
357  * @buf_size - buffer size
358  * @seg_num - total segments that this patch divided into
359  * @seg_id - No. of Segments: segment that will now be sent
360  * @src - patch source buffer
361  * @seg_len - segment size: segment that will now be sent
362  * return package size
363  */
364 fm_s32 mt6628_coeff_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id, const fm_u8 *src, fm_s32 seg_len)
365 {
366     fm_s32 pkt_size = 0;
367     fm_u8 *dst = NULL;
368
369     if (buf_size < TX_BUF_SIZE) {
370         return (-1);
371     }
372
373     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
374     buf[1] = FM_COEFF_DOWNLOAD_OPCODE;
375     pkt_size = 4;
376
377     buf[pkt_size++] = seg_num;
378     buf[pkt_size++] = seg_id;
379
380     if (seg_len > (buf_size - pkt_size)) {
381         return -1;
382     }
383
384     dst = &buf[pkt_size];
385     pkt_size += seg_len;
386
387     //copy patch to tx buffer
388     while (seg_len--) {
389         *dst = *src;
390         //printk(KERN_ALERT "%02x ", *dst);
391         src++;
392         dst++;
393     }
394
395     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
396     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
397     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
398
399     return pkt_size;
400 }
401
402
403 /*
404  * mt6628_hwcoeff_download - Wholechip FM Power Up: step 3,download hwcoeff to f/w,
405  * @buf - target buf
406  * @buf_size - buffer size
407  * @seg_num - total segments that this patch divided into
408  * @seg_id - No. of Segments: segment that will now be sent
409  * @src - patch source buffer
410  * @seg_len - segment size: segment that will now be sent
411  * return package size
412  */
413 fm_s32 mt6628_hwcoeff_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id, const fm_u8 *src, fm_s32 seg_len)
414 {
415     fm_s32 pkt_size = 0;
416     fm_u8 *dst = NULL;
417
418     if (buf_size < TX_BUF_SIZE) {
419         return (-1);
420     }
421
422     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
423     buf[1] = FM_HWCOEFF_DOWNLOAD_OPCODE;
424     pkt_size = 4;
425
426     buf[pkt_size++] = seg_num;
427     buf[pkt_size++] = seg_id;
428
429     if (seg_len > (buf_size - pkt_size)) {
430         return -1;
431     }
432
433     dst = &buf[pkt_size];
434     pkt_size += seg_len;
435
436     //copy patch to tx buffer
437     while (seg_len--) {
438         *dst = *src;
439         //printk(KERN_ALERT "%02x ", *dst);
440         src++;
441         dst++;
442     }
443
444     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
445     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
446     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
447
448     return pkt_size;
449 }
450
451
452 /*
453  * mt6628_rom_download - Wholechip FM Power Up: step 3,download rom to f/w,
454  * @buf - target buf
455  * @buf_size - buffer size
456  * @seg_num - total segments that this patch divided into
457  * @seg_id - No. of Segments: segment that will now be sent
458  * @src - patch source buffer
459  * @seg_len - segment size: segment that will now be sent
460  * return package size
461  */
462 fm_s32 mt6628_rom_download(fm_u8 *buf, fm_s32 buf_size, fm_u8 seg_num, fm_u8 seg_id, const fm_u8 *src, fm_s32 seg_len)
463 {
464     fm_s32 pkt_size = 0;
465     fm_u8 *dst = NULL;
466
467     if (buf_size < TX_BUF_SIZE) {
468         return (-1);
469     }
470
471     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
472     buf[1] = FM_ROM_DOWNLOAD_OPCODE;
473     pkt_size = 4;
474
475     buf[pkt_size++] = seg_num;
476     buf[pkt_size++] = seg_id;
477
478     if (seg_len > (buf_size - pkt_size)) {
479         return -1;
480     }
481
482     dst = &buf[pkt_size];
483     pkt_size += seg_len;
484
485     //copy patch to tx buffer
486     while (seg_len--) {
487         *dst = *src;
488         //printk(KERN_ALERT "%02x ", *dst);
489         src++;
490         dst++;
491     }
492
493     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
494     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
495     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
496
497     return pkt_size;
498 }
499
500
501 /*
502  * mt6628_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon
503  * @buf - target buf
504  * @buf_size - buffer size
505  * return package size
506  */
507 fm_s32 mt6628_pwrup_digital_init(fm_u8 *buf, fm_s32 buf_size)
508 {
509     fm_s32 pkt_size = 0;
510
511     if (buf_size < TX_BUF_SIZE) {
512         return (-1);
513     }
514
515     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
516     buf[1] = FM_ENABLE_OPCODE;
517     pkt_size = 4;
518
519     //Wholechip FM Power Up: FM Digital Init: fm_rgf_maincon
520     pkt_size += fm_bop_write(0x6A, 0x2100, &buf[pkt_size], buf_size - pkt_size);//wr 6A 2100
521     pkt_size += fm_bop_write(0x6B, 0x2100, &buf[pkt_size], buf_size - pkt_size);//wr 6B 2100
522     pkt_size += fm_bop_modify(0x60, 0xFFF7, 0x0008, &buf[pkt_size], buf_size - pkt_size);//wr 60 D3=1
523     pkt_size += fm_bop_modify(0x61, 0xFFFD, 0x0002, &buf[pkt_size], buf_size - pkt_size);//wr 61 D1=1
524     pkt_size += fm_bop_modify(0x61, 0xFFFE, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 61 D0=0
525     pkt_size += fm_bop_udelay(200000, &buf[pkt_size], buf_size - pkt_size);//delay 200ms
526     pkt_size += fm_bop_rd_until(0x64, 0x001F, 0x0002, &buf[pkt_size], buf_size - pkt_size);//Poll 64[0~4] = 2
527
528     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
529     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
530
531     return pkt_size;
532 }
533
534
535 /*
536  * mt6628_pwrdown - Wholechip FM Power down: Digital Modem Power Down
537  * @buf - target buf
538  * @buf_size - buffer size
539  * return package size
540  */
541 fm_s32 mt6628_pwrdown(fm_u8 *buf, fm_s32 buf_size)
542 {
543     fm_s32 pkt_size = 0;
544
545     if (buf_size < TX_BUF_SIZE) {
546         return (-1);
547     }
548
549     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
550     buf[1] = FM_ENABLE_OPCODE;
551     pkt_size = 4;
552
553     //Disable HW clock control
554     pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size);//wr 60 330F
555     //Reset ASIP
556     pkt_size += fm_bop_write(0x61, 0x0001, &buf[pkt_size], buf_size - pkt_size);//wr 61 0001
557     //digital core + digital rgf reset
558     pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 6E[0~2] 0
559     pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 6E[0~2] 0
560     pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 6E[0~2] 0
561     pkt_size += fm_bop_modify(0x6E, 0xFFF8, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 6E[0~2] 0
562     //Disable all clock
563     pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 60 0000
564     //Reset rgfrf
565     pkt_size += fm_bop_write(0x60, 0x4000, &buf[pkt_size], buf_size - pkt_size);//wr 60 4000
566     pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 60 0000
567
568     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
569     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
570
571     return pkt_size;
572 }
573
574
575 /*
576  * mt6628_rampdown - f/w will wait for STC_DONE interrupt
577  * @buf - target buf
578  * @buf_size - buffer size
579  * return package size
580  */
581 fm_s32 mt6628_rampdown(fm_u8 *buf, fm_s32 buf_size)
582 {
583     fm_s32 pkt_size = 0;
584
585     if (buf_size < TX_BUF_SIZE) {
586         return (-1);
587     }
588
589     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
590     buf[1] = FM_RAMPDOWN_OPCODE;
591     pkt_size = 4;
592
593     //Clear DSP state
594     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 63[3:0] = 0
595     //Set DSP ramp down state
596     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFFF, RAMP_DOWN, &buf[pkt_size], buf_size - pkt_size);//wr 63[8] = 1
597     //@Wait for STC_DONE interrupt@
598     pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1
599     //Clear DSP ramp down state
600     pkt_size += fm_bop_modify(FM_MAIN_CTRL, (~RAMP_DOWN), 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 63[8] = 0
601     //Write 1 clear the STC_DONE interrupt status flag
602     pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1
603
604     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
605     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
606
607     return pkt_size;
608 }
609
610
611 /*
612  * mt6628_tune - execute tune action,
613  * @buf - target buf
614  * @buf_size - buffer size
615  * @freq - 760 ~ 1080, 100KHz unit
616  * return package size
617  */
618 fm_s32 mt6628_tune(fm_u8 *buf, fm_s32 buf_size, fm_u16 freq, fm_u16 chan_para)
619 {
620     //#define FM_TUNE_USE_POLL
621     fm_s32 pkt_size = 0;
622
623     if (buf_size < TX_BUF_SIZE) {
624         return (-1);
625     }
626
627     if (0 == fm_get_channel_space(freq)) {
628         freq *= 10;
629     }
630     
631     freq = (freq - 6400) * 2 / 10;
632
633     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
634     buf[1] = FM_TUNE_OPCODE;
635     pkt_size = 4;
636
637     //Set desired channel & channel parameter
638 #ifdef FM_TUNE_USE_POLL
639     pkt_size += fm_bop_write(0x6A, 0x0000, &buf[pkt_size], buf_size - pkt_size);
640     pkt_size += fm_bop_write(0x6B, 0x0000, &buf[pkt_size], buf_size - pkt_size);
641 #endif
642     pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0xFC00, freq, &buf[pkt_size], buf_size - pkt_size);// set 0x65[9:0] = 0x029e, => ((97.5 - 64) * 20)
643     //channel para setting, D15~D12, D15: ATJ, D13: HL, D12: FA
644     pkt_size += fm_bop_modify(FM_CHANNEL_SET, 0x0FFF, (chan_para << 12), &buf[pkt_size], buf_size - pkt_size);
645     //Enable hardware controlled tuning sequence
646     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, TUNE, &buf[pkt_size], buf_size - pkt_size);// set 0x63[0] = 1
647     //Wait for STC_DONE interrupt
648 #ifdef FM_TUNE_USE_POLL
649     pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1
650     //Write 1 clear the STC_DONE interrupt status flag
651     pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1
652 #endif
653     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
654     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
655
656     return pkt_size;
657 }
658
659
660 /*
661  * mt6628_full_cqi_req - execute request cqi info action,
662  * @buf - target buf
663  * @buf_size - buffer size
664  * @freq - 7600 ~ 10800, freq array
665  * @cnt - channel count
666  * @type - request type, 1: a single channel; 2: multi channel; 3:multi channel with 100Khz step; 4: multi channel with 50Khz step
667  * 
668  * return package size
669  */
670 fm_s32 mt6628_full_cqi_req(fm_u8 *buf, fm_s32 buf_size, fm_u16 *freq, fm_s32 cnt, fm_s32 type)
671 {
672     fm_s32 pkt_size = 0;
673
674     if (buf_size < TX_BUF_SIZE) {
675         return (-1);
676     }
677
678     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
679     buf[1] = FM_SOFT_MUTE_TUNE_OPCODE;
680     pkt_size = 4;
681
682     switch (type) {
683         case 1:
684             buf[pkt_size] = 0x0001;
685             pkt_size++;
686             buf[pkt_size] = (fm_u8)((*freq) & 0x00FF);
687             pkt_size++;
688             buf[pkt_size] = (fm_u8)((*freq >> 8) & 0x00FF);
689             pkt_size++;
690             break;
691         case 2:
692             buf[pkt_size] = 0x0002;
693             pkt_size++;
694             break;
695         case 3:
696             buf[pkt_size] = 0x0003;
697             pkt_size++;
698             break;
699         case 4:
700             buf[pkt_size] = 0x0004;
701             pkt_size++;
702             break;
703         default:
704             buf[pkt_size] = (fm_u16)type;
705             pkt_size++;
706             break;
707     }
708
709     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
710     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
711
712     return pkt_size;
713 }
714
715
716 /*
717  * mt6628_seek - execute seek action,
718  * @buf - target buf
719  * @buf_size - buffer size
720  * @seekdir - 0=seek up, 1=seek down
721  * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
722  * @max_freq - upper bound
723  * @min_freq - lower bound
724  * return package size
725  */
726 fm_s32 mt6628_seek(fm_u8 *buf, fm_s32 buf_size, fm_u16 seekdir, fm_u16 space, fm_u16 max_freq, fm_u16 min_freq)
727 {
728     fm_s32 pkt_size = 0;
729
730     if (buf_size < TX_BUF_SIZE) {
731         return (-1);
732     }
733
734     if (0 == fm_get_channel_space(max_freq)) {
735         max_freq *= 10;
736     }
737
738     if (0 == fm_get_channel_space(min_freq)) {
739         min_freq *= 10;
740     }
741     
742     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
743     buf[1] = FM_SEEK_OPCODE;
744     pkt_size = 4;
745
746     //Program seek direction
747     if (seekdir == 0) {
748         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 0, seek up
749     } else {
750         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 1, seek down
751     }
752
753     //Program scan channel spacing
754     if (space == 1) {
755         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x1000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=001
756     } else if (space == 2) {
757         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x2000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=010
758     } else if (space == 4) {
759         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=100
760     }
761
762     //enable wrap , if it is not auto scan function, 0x66[11] 0=no wrarp, 1=wrap
763     pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xF7FF, 0x0800, &buf[pkt_size], buf_size - pkt_size);//0x66[11] = 1, wrap
764     //0x66[9:0] freq upper bound
765
766     max_freq = (max_freq - 6400) * 2 / 10;
767
768     pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFC00, max_freq, &buf[pkt_size], buf_size - pkt_size);
769     //0x67[9:0] freq lower bound
770
771     min_freq = (min_freq - 6400) * 2 / 10;
772
773     pkt_size += fm_bop_modify(FM_MAIN_CFG2, 0xFC00, min_freq, &buf[pkt_size], buf_size - pkt_size);
774     //Enable hardware controlled seeking sequence
775     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, SEEK, &buf[pkt_size], buf_size - pkt_size);//0x63[1] = 1
776     //Wait for STC_DONE interrupt
777     //pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1
778     //Write 1 clear the STC_DONE interrupt status flag
779     //pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1
780
781     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
782     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
783
784     return pkt_size;
785 }
786
787
788 /*
789  * mt6628_scan - execute scan action,
790  * @buf - target buf
791  * @buf_size - buffer size
792  * @scandir - 0=seek up, 1=seek down
793  * @space - step, 50KHz:001, 100KHz:010, 200KHz:100
794  * @max_freq - upper bound
795  * @min_freq - lower bound
796  * return package size
797  */
798 fm_s32 mt6628_scan(fm_u8 *buf, fm_s32 buf_size, fm_u16 scandir, fm_u16 space, fm_u16 max_freq, fm_u16 min_freq)
799 {
800     fm_s32 pkt_size = 0;
801
802     if (buf_size < TX_BUF_SIZE) {
803         return (-1);
804     }
805
806     if (0 == fm_get_channel_space(max_freq)) {
807         max_freq *= 10;
808     }
809     if (0 == fm_get_channel_space(min_freq)) {
810         min_freq *= 10;
811     }
812     
813     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
814     buf[1] = FM_SCAN_OPCODE;
815     pkt_size = 4;
816
817     //Program seek direction
818     if (scandir == 0) {
819         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 0, seek up
820     } else {
821         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFFFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 1, seek down
822     }
823
824     //Program scan channel spacing
825     if (space == 1) {
826         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x1000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=001
827     } else if (space == 2) {
828         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x2000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=010
829     } else if (space == 4) {
830         pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0x8FFF, 0x4000, &buf[pkt_size], buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=100
831     }
832
833     //disable wrap , if it is auto scan function, 0x66[11] 0=no wrarp, 1=wrap
834     pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xF7FF, 0x0000, &buf[pkt_size], buf_size - pkt_size);//0x66[11] = 0, no wrap
835     //0x66[9:0] freq upper bound
836
837     max_freq = (max_freq - 6400) * 2 / 10;
838
839     pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFC00, max_freq, &buf[pkt_size], buf_size - pkt_size);
840     //0x67[9:0] freq lower bound
841
842     min_freq = (min_freq - 6400) * 2 / 10;
843
844     pkt_size += fm_bop_modify(FM_MAIN_CFG2, 0xFC00, min_freq, &buf[pkt_size], buf_size - pkt_size);
845     //Enable hardware controlled scanning sequence
846     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF8, SCAN, &buf[pkt_size], buf_size - pkt_size);//0x63[1] = 1
847     //Wait for STC_DONE interrupt
848     //pkt_size += fm_bop_rd_until(FM_MAIN_INTR, FM_INTR_STC_DONE, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//Poll 69[0] = b'1
849     //Write 1 clear the STC_DONE interrupt status flag
850     //pkt_size += fm_bop_modify(FM_MAIN_INTR, 0xFFFF, FM_INTR_STC_DONE, &buf[pkt_size], buf_size - pkt_size);//wr 69[0] = 1
851
852     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
853     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
854
855     return pkt_size;
856 }
857
858
859 fm_s32 mt6628_cqi_get(fm_u8 *buf, fm_s32 buf_size)
860 {
861     fm_s32 pkt_size = 0;
862
863     if (buf_size < TX_BUF_SIZE) {
864         return (-1);
865     }
866
867     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
868     buf[1] = FM_SCAN_OPCODE;
869     pkt_size = 4;
870
871     pkt_size += fm_bop_modify(FM_MAIN_CTRL, 0xFFF0, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 63 bit0~2 0
872     pkt_size += fm_bop_modify(FM_MAIN_CTRL, ~CQI_READ, CQI_READ, &buf[pkt_size], buf_size - pkt_size);//wr 63 bit3 1
873
874     buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
875     buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
876
877     return pkt_size;
878 }
879
880
881 fm_s32 mt6628_get_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr)
882 {
883     if (buf_size < TX_BUF_SIZE) {
884         return (-1);
885     }
886
887     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
888     buf[1] = FSPI_READ_OPCODE;
889     buf[2] = 0x01;
890     buf[3] = 0x00;
891     buf[4] = addr;
892
893     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4]);
894     return 5;
895 }
896
897
898 fm_s32 mt6628_set_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr, fm_u16 value)
899 {
900     if (buf_size < TX_BUF_SIZE) {
901         return (-1);
902     }
903
904     buf[0] = FM_TASK_COMMAND_PKT_TYPE;
905     buf[1] = FSPI_WRITE_OPCODE;
906     buf[2] = 0x03;
907     buf[3] = 0x00;
908     buf[4] = addr;
909     buf[5] = (fm_u8)((value) & 0x00FF);
910     buf[6] = (fm_u8)((value >> 8) & 0x00FF);
911
912     WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
913     return 7;
914 }
915