1 #include <linux/kernel.h>
2 #include <linux/types.h>
4 #include "fm_typedef.h"
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"
17 extern fm_cust_cfg mt6628_fm_config;
19 static fm_s32 fm_bop_write(fm_u8 addr, fm_u16 value, fm_u8 *buf, fm_s32 size)
21 if (size < (FM_WRITE_BASIC_OP_SIZE + 2)) {
29 buf[0] = FM_WRITE_BASIC_OP;
30 buf[1] = FM_WRITE_BASIC_OP_SIZE;
32 buf[3] = (fm_u8)((value) & 0x00FF);
33 buf[4] = (fm_u8)((value >> 8) & 0x00FF);
35 WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4]);
37 return (FM_WRITE_BASIC_OP_SIZE + 2);
41 static fm_s32 fm_bop_udelay(fm_u32 value, fm_u8 *buf, fm_s32 size)
43 if (size < (FM_UDELAY_BASIC_OP_SIZE + 2)) {
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);
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]);
60 return (FM_UDELAY_BASIC_OP_SIZE + 2);
64 static fm_s32 fm_bop_rd_until(fm_u8 addr, fm_u16 mask, fm_u16 value, fm_u8 *buf, fm_s32 size)
66 if (size < (FM_RD_UNTIL_BASIC_OP_SIZE + 2)) {
74 buf[0] = FM_RD_UNTIL_BASIC_OP;
75 buf[1] = FM_RD_UNTIL_BASIC_OP_SIZE;
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);
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]);
84 return (FM_RD_UNTIL_BASIC_OP_SIZE + 2);
88 static fm_s32 fm_bop_modify(fm_u8 addr, fm_u16 mask_and, fm_u16 mask_or, fm_u8 *buf, fm_s32 size)
90 if (size < (FM_MODIFY_BASIC_OP_SIZE + 2)) {
98 buf[0] = FM_MODIFY_BASIC_OP;
99 buf[1] = FM_MODIFY_BASIC_OP_SIZE;
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);
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]);
108 return (FM_MODIFY_BASIC_OP_SIZE + 2);
112 static fm_s32 fm_bop_msleep(fm_u32 value, fm_u8 *buf, fm_s32 size)
114 if (size < (FM_MSLEEP_BASIC_OP_SIZE + 2)) {
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);
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]);
131 return (FM_MSLEEP_BASIC_OP_SIZE + 2);
136 inline fm_s32 fm_get_channel_space(fm_s32 freq)
138 if ((freq >= 760) && (freq <= 1080)) {
140 } else if ((freq >= 7600) && (freq <= 10800)) {
148 fm_s32 mt6628_pwrup_fpga_on(fm_u8 *buf, fm_s32 buf_size)
152 if (buf_size < TX_BUF_SIZE) {
156 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
157 buf[1] = FM_ENABLE_OPCODE;
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);
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);
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);
254 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
255 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
262 * mt6628_pwrup_clock_on - Wholechip FM Power Up: step 1, FM Digital Clock enable
264 * @buf_size - buffer size
265 * return package size
267 fm_s32 mt6628_pwrup_clock_on(fm_u8 *buf, fm_s32 buf_size)
273 if (buf_size < TX_BUF_SIZE) {
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
282 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
283 buf[1] = FM_ENABLE_OPCODE;
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);
298 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
299 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
306 * mt6628_patch_download - Wholechip FM Power Up: step 3, download patch to f/w,
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
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)
320 if (buf_size < TX_BUF_SIZE) {
324 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
325 buf[1] = FM_PATCH_DOWNLOAD_OPCODE;
328 buf[pkt_size++] = seg_num;
329 buf[pkt_size++] = seg_id;
331 if (seg_len > (buf_size - pkt_size)) {
335 dst = &buf[pkt_size];
338 //copy patch to tx buffer
341 //printk(KERN_ALERT "%02x ", *dst);
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]);
355 * mt6628_coeff_download - Wholechip FM Power Up: step 3,download coeff to f/w,
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
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)
369 if (buf_size < TX_BUF_SIZE) {
373 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
374 buf[1] = FM_COEFF_DOWNLOAD_OPCODE;
377 buf[pkt_size++] = seg_num;
378 buf[pkt_size++] = seg_id;
380 if (seg_len > (buf_size - pkt_size)) {
384 dst = &buf[pkt_size];
387 //copy patch to tx buffer
390 //printk(KERN_ALERT "%02x ", *dst);
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]);
404 * mt6628_hwcoeff_download - Wholechip FM Power Up: step 3,download hwcoeff to f/w,
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
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)
418 if (buf_size < TX_BUF_SIZE) {
422 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
423 buf[1] = FM_HWCOEFF_DOWNLOAD_OPCODE;
426 buf[pkt_size++] = seg_num;
427 buf[pkt_size++] = seg_id;
429 if (seg_len > (buf_size - pkt_size)) {
433 dst = &buf[pkt_size];
436 //copy patch to tx buffer
439 //printk(KERN_ALERT "%02x ", *dst);
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]);
453 * mt6628_rom_download - Wholechip FM Power Up: step 3,download rom to f/w,
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
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)
467 if (buf_size < TX_BUF_SIZE) {
471 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
472 buf[1] = FM_ROM_DOWNLOAD_OPCODE;
475 buf[pkt_size++] = seg_num;
476 buf[pkt_size++] = seg_id;
478 if (seg_len > (buf_size - pkt_size)) {
482 dst = &buf[pkt_size];
485 //copy patch to tx buffer
488 //printk(KERN_ALERT "%02x ", *dst);
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]);
502 * mt6628_pwrup_digital_init - Wholechip FM Power Up: step 4, FM Digital Init: fm_rgf_maincon
504 * @buf_size - buffer size
505 * return package size
507 fm_s32 mt6628_pwrup_digital_init(fm_u8 *buf, fm_s32 buf_size)
511 if (buf_size < TX_BUF_SIZE) {
515 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
516 buf[1] = FM_ENABLE_OPCODE;
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
528 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
529 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
536 * mt6628_pwrdown - Wholechip FM Power down: Digital Modem Power Down
538 * @buf_size - buffer size
539 * return package size
541 fm_s32 mt6628_pwrdown(fm_u8 *buf, fm_s32 buf_size)
545 if (buf_size < TX_BUF_SIZE) {
549 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
550 buf[1] = FM_ENABLE_OPCODE;
553 //Disable HW clock control
554 pkt_size += fm_bop_write(0x60, 0x330F, &buf[pkt_size], buf_size - pkt_size);//wr 60 330F
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
563 pkt_size += fm_bop_write(0x60, 0x0000, &buf[pkt_size], buf_size - pkt_size);//wr 60 0000
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
568 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
569 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
576 * mt6628_rampdown - f/w will wait for STC_DONE interrupt
578 * @buf_size - buffer size
579 * return package size
581 fm_s32 mt6628_rampdown(fm_u8 *buf, fm_s32 buf_size)
585 if (buf_size < TX_BUF_SIZE) {
589 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
590 buf[1] = FM_RAMPDOWN_OPCODE;
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
604 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
605 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
612 * mt6628_tune - execute tune action,
614 * @buf_size - buffer size
615 * @freq - 760 ~ 1080, 100KHz unit
616 * return package size
618 fm_s32 mt6628_tune(fm_u8 *buf, fm_s32 buf_size, fm_u16 freq, fm_u16 chan_para)
620 //#define FM_TUNE_USE_POLL
623 if (buf_size < TX_BUF_SIZE) {
627 if (0 == fm_get_channel_space(freq)) {
631 freq = (freq - 6400) * 2 / 10;
633 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
634 buf[1] = FM_TUNE_OPCODE;
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);
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
653 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
654 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
661 * mt6628_full_cqi_req - execute request cqi info action,
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
668 * return package size
670 fm_s32 mt6628_full_cqi_req(fm_u8 *buf, fm_s32 buf_size, fm_u16 *freq, fm_s32 cnt, fm_s32 type)
674 if (buf_size < TX_BUF_SIZE) {
678 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
679 buf[1] = FM_SOFT_MUTE_TUNE_OPCODE;
684 buf[pkt_size] = 0x0001;
686 buf[pkt_size] = (fm_u8)((*freq) & 0x00FF);
688 buf[pkt_size] = (fm_u8)((*freq >> 8) & 0x00FF);
692 buf[pkt_size] = 0x0002;
696 buf[pkt_size] = 0x0003;
700 buf[pkt_size] = 0x0004;
704 buf[pkt_size] = (fm_u16)type;
709 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
710 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
717 * mt6628_seek - execute seek action,
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
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)
730 if (buf_size < TX_BUF_SIZE) {
734 if (0 == fm_get_channel_space(max_freq)) {
738 if (0 == fm_get_channel_space(min_freq)) {
742 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
743 buf[1] = FM_SEEK_OPCODE;
746 //Program seek direction
748 pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 0, seek up
750 pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 1, seek down
753 //Program scan channel spacing
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
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
766 max_freq = (max_freq - 6400) * 2 / 10;
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
771 min_freq = (min_freq - 6400) * 2 / 10;
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
781 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
782 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
789 * mt6628_scan - execute scan action,
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
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)
802 if (buf_size < TX_BUF_SIZE) {
806 if (0 == fm_get_channel_space(max_freq)) {
809 if (0 == fm_get_channel_space(min_freq)) {
813 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
814 buf[1] = FM_SCAN_OPCODE;
817 //Program seek direction
819 pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFBFF, 0x0000, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 0, seek up
821 pkt_size += fm_bop_modify(FM_MAIN_CFG1, 0xFFFF, 0x0400, &buf[pkt_size], buf_size - pkt_size);//0x66[10] = 1, seek down
824 //Program scan channel spacing
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
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
837 max_freq = (max_freq - 6400) * 2 / 10;
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
842 min_freq = (min_freq - 6400) * 2 / 10;
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
852 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
853 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
859 fm_s32 mt6628_cqi_get(fm_u8 *buf, fm_s32 buf_size)
863 if (buf_size < TX_BUF_SIZE) {
867 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
868 buf[1] = FM_SCAN_OPCODE;
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
874 buf[2] = (fm_u8)((pkt_size - 4) & 0x00FF);
875 buf[3] = (fm_u8)(((pkt_size - 4) >> 8) & 0x00FF);
881 fm_s32 mt6628_get_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr)
883 if (buf_size < TX_BUF_SIZE) {
887 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
888 buf[1] = FSPI_READ_OPCODE;
893 WCN_DBG(FM_DBG | CHIP, "%02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4]);
898 fm_s32 mt6628_set_reg(fm_u8 *buf, fm_s32 buf_size, fm_u8 addr, fm_u16 value)
900 if (buf_size < TX_BUF_SIZE) {
904 buf[0] = FM_TASK_COMMAND_PKT_TYPE;
905 buf[1] = FSPI_WRITE_OPCODE;
909 buf[5] = (fm_u8)((value) & 0x00FF);
910 buf[6] = (fm_u8)((value >> 8) & 0x00FF);
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]);