dmbdrv_wrap_fc8050.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*
  2. * Copyright(c) 2008 SEC Corp. All Rights Reserved
  3. *
  4. * File name : DMBDrv_wrap_FC8050.c
  5. *
  6. * Description : fc8050 tuner control driver
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * History :
  22. * ----------------------------------------------------------------------
  23. * 2009/01/19 changsul.park initial
  24. * 2009/09/23 jason porting QSC6270
  25. */
  26. #include "dmbdrv_wrap_fc8050.h"
  27. #include "fci_types.h"
  28. #include "bbm.h"
  29. #include "fci_oal.h"
  30. #include "fc8050_regs.h"
  31. #include "fic.h"
  32. #include "fci_tun.h"
  33. #include "tdmb.h"
  34. struct sub_channel_info_type dmb_subchannel_info;
  35. struct sub_channel_info_type dab_subchannel_info;
  36. static u32 saved_ber = 3000;
  37. static u32 dmb_initialize;
  38. unsigned char current_service_type = 0x18;
  39. unsigned char current_subchannel_id;
  40. int tdmb_interrupt_fic_callback(u32 userdata, u8 *data, int length)
  41. {
  42. fic_decoder_put((struct fic *)data, length);
  43. return 0;
  44. }
  45. #ifdef FEATURE_FC8050_DEBUG
  46. #define FC8050_DMB 0x01
  47. #define FC8050_DATA 0x04
  48. #define FC8050_DAB 0x08
  49. u16 dmb_mode = FC8050_DMB;
  50. #endif
  51. int tdmb_interrupt_msc_callback(
  52. u32 userdata, u8 subchannel_id, u8 *data, int length)
  53. {
  54. tdmb_store_data(&data[0], length);
  55. return 0;
  56. }
  57. static int viterbi_rt_ber_read(unsigned int *ber)
  58. {
  59. u32 frame, error;
  60. u8 control = 0;
  61. int res = BBM_OK;
  62. bbm_com_read(NULL, BBM_VT_CONTROL, &control);
  63. control |= 0x10;
  64. bbm_com_write(NULL, BBM_VT_CONTROL, control);
  65. bbm_com_long_read(NULL, BBM_VT_RT_BER_PERIOD, &frame);
  66. bbm_com_long_read(NULL, BBM_VT_RT_ERROR_SUM, &error);
  67. control &= ~0x10;
  68. bbm_com_write(NULL, BBM_VT_CONTROL, control);
  69. if (frame == 0) {
  70. *ber = 0;
  71. return BBM_NOK;
  72. }
  73. *ber = (error * 10000 / frame);
  74. return res;
  75. }
  76. static int get_signal_level(u32 ber, u8 *level)
  77. {
  78. if (ber >= 900)
  79. *level = 0;
  80. else if ((ber >= 800) && (ber < 900))
  81. *level = 1;
  82. else if ((ber >= 700) && (ber < 800))
  83. *level = 2;
  84. else if ((ber >= 600) && (ber < 700))
  85. *level = 3;
  86. else if ((ber >= 500) && (ber < 600))
  87. *level = 4;
  88. else if ((ber >= 400) && (ber < 500))
  89. *level = 5;
  90. else if (ber < 400)
  91. *level = 6;
  92. return BBM_OK;
  93. }
  94. void dmb_drv_isr()
  95. {
  96. bbm_com_isr(NULL);
  97. }
  98. unsigned char dmb_drv_init(unsigned long param)
  99. {
  100. #ifdef FEATURE_INTERFACE_TEST_MODE
  101. int i;
  102. u8 data;
  103. u16 wdata;
  104. u32 ldata;
  105. u8 temp = 0x1e;
  106. #endif
  107. #ifdef CONFIG_TDMB_SPI
  108. if (bbm_com_hostif_select(NULL, BBM_SPI, param))
  109. return TDMB_FAIL;
  110. #elif defined(CONFIG_TDMB_EBI)
  111. if (bbm_com_hostif_select(NULL, BBM_PPI, param))
  112. return TDMB_FAIL;
  113. #endif
  114. /* check for factory chip interface test */
  115. if (bbm_com_probe(NULL) != BBM_OK) {
  116. DPRINTK("%s : BBM_PROBE fail\n", __func__);
  117. return TDMB_FAIL;
  118. }
  119. bbm_com_fic_callback_register(0, tdmb_interrupt_fic_callback);
  120. bbm_com_msc_callback_register(0, tdmb_interrupt_msc_callback);
  121. bbm_com_init(NULL);
  122. bbm_com_tuner_select(NULL, FC8050_TUNER, BAND3_TYPE);
  123. #ifdef FEATURE_INTERFACE_TEST_MODE
  124. for (i = 0; i < 1000; i++) {
  125. bbm_com_write(NULL, 0x05, i & 0xff);
  126. bbm_com_read(NULL, 0x05, &data);
  127. if ((i & 0xff) != data)
  128. DPRINTK("FC8000 byte test (0x%x,0x%x)\r\n"
  129. , i & 0xff, data);
  130. }
  131. for (i = 0; i < 1000; i++) {
  132. bbm_com_word_write(NULL, 0x0210, i & 0xffff);
  133. bbm_com_word_read(NULL, 0x0210, &wdata);
  134. if ((i & 0xffff) != wdata)
  135. DPRINTK("FC8000 word test (0x%x,0x%x)\r\n"
  136. , i & 0xffff, wdata);
  137. }
  138. for (i = 0; i < 1000; i++) {
  139. bbm_com_long_write(NULL, 0x0210, i & 0xffffffff);
  140. bbm_com_long_read(NULL, 0x0210, &ldata);
  141. if ((i & 0xffffffff) != ldata)
  142. DPRINTK("FC8000 long test (0x%x,0x%x)\r\n"
  143. , i & 0xffffffff, ldata);
  144. }
  145. for (i = 0; i < 1000; i++) {
  146. temp = i&0xff;
  147. bbm_com_tuner_write(NULL, 0x12, 0x01, &temp, 0x01);
  148. bbm_com_tuner_read(NULL, 0x12, 0x01, &data, 0x01);
  149. if ((i & 0xff) != data)
  150. DPRINTK("FC8000 tuner test (0x%x,0x%x)\r\n"
  151. , i & 0xff, data);
  152. }
  153. temp = 0x51;
  154. bbm_com_tuner_write(NULL, 0x12, 0x01, &temp, 0x01);
  155. #endif
  156. saved_ber = 3000;
  157. dmb_initialize = 1;
  158. return TDMB_SUCCESS;
  159. }
  160. unsigned char dmb_drv_deinit(void)
  161. {
  162. dmb_initialize = 0;
  163. bbm_com_video_deselect(NULL, 0, 0, 0);
  164. bbm_com_audio_deselect(NULL, 0, 3);
  165. bbm_com_data_deselect(NULL, 0, 2);
  166. bbm_com_write(NULL, BBM_COM_STATUS_ENABLE, 0x00);
  167. ms_wait(100);
  168. bbm_com_deinit(NULL);
  169. bbm_com_fic_callback_deregister(NULL);
  170. bbm_com_msc_callback_deregister(NULL);
  171. bbm_com_hostif_deselect(NULL);
  172. return TDMB_SUCCESS;
  173. }
  174. unsigned char dmb_drv_scan_ch(unsigned long frequency)
  175. {
  176. struct esbinfo_t *esb;
  177. if (!dmb_initialize)
  178. return TDMB_FAIL;
  179. if (bbm_com_tuner_set_freq(NULL, frequency)) {
  180. bbm_com_word_write(NULL, BBM_BUF_INT, 0x00ff);
  181. return TDMB_FAIL;
  182. }
  183. fic_decoder_subchannel_info_clean();
  184. bbm_com_word_write(NULL, BBM_BUF_INT, 0x01ff);
  185. if (bbm_com_scan_status(NULL)) {
  186. bbm_com_word_write(NULL, BBM_BUF_INT, 0x00ff);
  187. return TDMB_FAIL;
  188. }
  189. /* wait 1.2 sec for gathering fic information */
  190. ms_wait(1200);
  191. bbm_com_word_write(NULL, BBM_BUF_INT, 0x00ff);
  192. esb = fic_decoder_get_ensemble_info(0);
  193. if (esb->flag != 99) {
  194. fic_decoder_subchannel_info_clean();
  195. return TDMB_FAIL;
  196. }
  197. if (strnlen(esb->label, sizeof(esb->label)) <= 0) {
  198. fic_decoder_subchannel_info_clean();
  199. return TDMB_FAIL;
  200. }
  201. return TDMB_SUCCESS;
  202. }
  203. int dmb_drv_get_dmb_sub_ch_cnt()
  204. {
  205. struct service_info_t *svc_info;
  206. int i, n;
  207. if (!dmb_initialize)
  208. return 0;
  209. n = 0;
  210. for (i = 0; i < MAX_SVC_NUM; i++) {
  211. svc_info = fic_decoder_get_service_info_list(i);
  212. if ((svc_info->flag & 0x07) == 0x07) {
  213. if ((svc_info->tmid == 0x01)
  214. && (svc_info->dscty == 0x18))
  215. n++;
  216. }
  217. }
  218. return n;
  219. }
  220. int dmb_drv_get_dab_sub_ch_cnt()
  221. {
  222. struct service_info_t *svc_info;
  223. int i, n;
  224. if (!dmb_initialize)
  225. return 0;
  226. n = 0;
  227. for (i = 0; i < MAX_SVC_NUM; i++) {
  228. svc_info = fic_decoder_get_service_info_list(i);
  229. if ((svc_info->flag & 0x07) == 0x07) {
  230. if ((svc_info->tmid == 0x00)
  231. && (svc_info->ascty == 0x00))
  232. n++;
  233. }
  234. }
  235. return n;
  236. }
  237. char *dmb_drv_get_ensemble_label()
  238. {
  239. struct esbinfo_t *esb;
  240. if (!dmb_initialize)
  241. return NULL;
  242. esb = fic_decoder_get_ensemble_info(0);
  243. if (esb->flag == 99)
  244. return (char *)esb->label;
  245. return NULL;
  246. }
  247. char *dmb_drv_get_sub_ch_dmb_label(int subchannel_count)
  248. {
  249. int i, n;
  250. struct service_info_t *svc_info;
  251. char *label = NULL;
  252. if (!dmb_initialize)
  253. return NULL;
  254. n = 0;
  255. for (i = 0; i < MAX_SVC_NUM; i++) {
  256. svc_info = fic_decoder_get_service_info_list(i);
  257. if ((svc_info->flag & 0x07) == 0x07) {
  258. if ((svc_info->tmid == 0x01)
  259. && (svc_info->dscty == 0x18)) {
  260. if (n == subchannel_count) {
  261. label = (char *) svc_info->label;
  262. break;
  263. }
  264. n++;
  265. }
  266. }
  267. }
  268. return label;
  269. }
  270. char *dmb_drv_get_sub_ch_dab_label(int subchannel_count)
  271. {
  272. int i, n;
  273. struct service_info_t *svc_info;
  274. char *label = NULL;
  275. if (!dmb_initialize)
  276. return NULL;
  277. n = 0;
  278. for (i = 0; i < MAX_SVC_NUM; i++) {
  279. svc_info = fic_decoder_get_service_info_list(i);
  280. if ((svc_info->flag & 0x07) == 0x07) {
  281. if ((svc_info->tmid == 0x00)
  282. && (svc_info->ascty == 0x00)) {
  283. if (n == subchannel_count) {
  284. label = (char *) svc_info->label;
  285. break;
  286. }
  287. n++;
  288. }
  289. }
  290. }
  291. return label;
  292. }
  293. struct sub_channel_info_type *dmb_drv_get_fic_dmb(int subchannel_count)
  294. {
  295. int i, n, j;
  296. struct esbinfo_t *esb;
  297. struct service_info_t *svc_info;
  298. u8 num_of_user_appl;
  299. if (!dmb_initialize)
  300. return NULL;
  301. memset((void *)&dmb_subchannel_info, 0, sizeof(dmb_subchannel_info));
  302. n = 0;
  303. for (i = 0; i < MAX_SVC_NUM; i++) {
  304. svc_info = fic_decoder_get_service_info_list(i);
  305. if ((svc_info->flag & 0x07) == 0x07) {
  306. if ((svc_info->tmid == 0x01)
  307. && (svc_info->dscty == 0x18)) {
  308. if (n == subchannel_count) {
  309. dmb_subchannel_info.ucSubchID
  310. = svc_info->sub_channel_id;
  311. dmb_subchannel_info.uiStartAddress
  312. = 0;
  313. dmb_subchannel_info.ucTMId
  314. = svc_info->tmid;
  315. dmb_subchannel_info.ucServiceType
  316. = svc_info->dscty;
  317. dmb_subchannel_info.ulServiceID
  318. = svc_info->sid;
  319. dmb_subchannel_info.scids
  320. = svc_info->scids;
  321. num_of_user_appl =
  322. svc_info->num_of_user_appl;
  323. dmb_subchannel_info.num_of_user_appl
  324. = num_of_user_appl;
  325. for (j = 0; j < num_of_user_appl; j++) {
  326. dmb_subchannel_info.
  327. user_appl_type[j]
  328. = svc_info->user_appl_type[j];
  329. dmb_subchannel_info.
  330. user_appl_length[j]
  331. = svc_info->user_appl_length[j];
  332. memcpy(
  333. &dmb_subchannel_info.
  334. user_appl_data[j][0]
  335. , &svc_info->
  336. user_appl_data[j][0]
  337. , dmb_subchannel_info.
  338. user_appl_length[j]);
  339. }
  340. esb = fic_decoder_get_ensemble_info(0);
  341. if (esb->flag == 99)
  342. dmb_subchannel_info.uiEnsembleID
  343. = esb->eid;
  344. else
  345. dmb_subchannel_info.uiEnsembleID
  346. = 0;
  347. dmb_subchannel_info.ecc = esb->ecc;
  348. break;
  349. }
  350. n++;
  351. }
  352. }
  353. }
  354. return &dmb_subchannel_info;
  355. }
  356. struct sub_channel_info_type *dmb_drv_get_fic_dab(int subchannel_count)
  357. {
  358. int i, n;
  359. struct esbinfo_t *esb;
  360. struct service_info_t *svc_info;
  361. if (!dmb_initialize)
  362. return NULL;
  363. memset((void *)&dab_subchannel_info, 0, sizeof(dab_subchannel_info));
  364. n = 0;
  365. for (i = 0; i < MAX_SVC_NUM; i++) {
  366. svc_info = fic_decoder_get_service_info_list(i);
  367. if ((svc_info->flag & 0x07) == 0x07) {
  368. if ((svc_info->tmid == 0x00)
  369. && (svc_info->ascty == 0x00)) {
  370. if (n == subchannel_count) {
  371. dab_subchannel_info.ucSubchID =
  372. svc_info->sub_channel_id;
  373. dab_subchannel_info.uiStartAddress = 0;
  374. dab_subchannel_info.ucTMId
  375. = svc_info->tmid;
  376. dab_subchannel_info.ucServiceType =
  377. svc_info->ascty;
  378. dab_subchannel_info.ulServiceID =
  379. svc_info->sid;
  380. dab_subchannel_info.scids =
  381. svc_info->scids;
  382. esb = fic_decoder_get_ensemble_info(0);
  383. if (esb->flag == 99)
  384. dmb_subchannel_info.uiEnsembleID
  385. = esb->eid;
  386. else
  387. dmb_subchannel_info.uiEnsembleID
  388. = 0;
  389. dab_subchannel_info.ecc = esb->ecc;
  390. break;
  391. }
  392. n++;
  393. }
  394. }
  395. }
  396. return &dab_subchannel_info;
  397. }
  398. #ifdef FEATURE_FC8050_DEBUG
  399. void fc8050_isr_interruptclear(void)
  400. {
  401. u8 status = 0;
  402. bbm_com_read(NULL, BBM_COM_INT_STATUS, &status);
  403. bbm_com_write(NULL, BBM_COM_INT_STATUS, status);
  404. bbm_com_write(NULL, BBM_COM_INT_STATUS, 0x00);
  405. }
  406. void dmb_drv_check_overrun(u8 reset)
  407. {
  408. u16 overrun;
  409. u16 temp = 0;
  410. bbm_com_word_read(NULL, BBM_BUF_OVERRUN, &overrun);
  411. if (overrun & dmb_mode) {
  412. /* overrun clear */
  413. bbm_com_word_write(NULL, BBM_BUF_OVERRUN, overrun);
  414. bbm_com_word_write(NULL, BBM_BUF_OVERRUN, 0x0000);
  415. if (reset) {
  416. /* buffer restore */
  417. bbm_com_word_read(NULL, BBM_BUF_ENABLE, &temp);
  418. temp &= ~dmb_mode;
  419. bbm_com_word_write(NULL, BBM_BUF_ENABLE, temp);
  420. temp |= dmb_mode;
  421. bbm_com_word_write(NULL, BBM_BUF_ENABLE, temp);
  422. /* external interrupt restore */
  423. fc8050_isr_interruptclear();
  424. }
  425. DPRINTK("FC8050 Overrun occured\n");
  426. }
  427. }
  428. #endif
  429. unsigned char dmb_drv_set_ch(
  430. unsigned long frequency
  431. , unsigned char subchannel
  432. , unsigned char sevice_type)
  433. {
  434. if (!dmb_initialize)
  435. return TDMB_FAIL;
  436. current_service_type = sevice_type;
  437. current_subchannel_id = subchannel;
  438. bbm_com_video_deselect(NULL, 0, 0, 0);
  439. bbm_com_audio_deselect(NULL, 0, 3);
  440. bbm_com_data_deselect(NULL, 0, 2);
  441. bbm_com_word_write(NULL, BBM_BUF_INT, 0x00ff);
  442. if (bbm_com_tuner_set_freq(NULL, frequency) != BBM_OK)
  443. return TDMB_FAIL;
  444. if (sevice_type == 0x18)
  445. bbm_com_video_select(NULL, subchannel, 0, 0);
  446. else if (sevice_type == 0x00)
  447. bbm_com_audio_select(NULL, subchannel, 3);
  448. else
  449. bbm_com_data_select(NULL, subchannel, 2);
  450. #ifdef FEATURE_FC8050_DEBUG
  451. if (sevice_type == 0x18)
  452. dmb_mode = FC8050_DMB;
  453. else if (sevice_type == 0x00)
  454. dmb_mode = FC8050_DAB;
  455. else
  456. dmb_mode = FC8050_DATA;
  457. #endif
  458. return TDMB_SUCCESS;
  459. }
  460. unsigned char dmb_drv_set_ch_factory(
  461. unsigned long frequency
  462. , unsigned char subchannel
  463. , unsigned char sevice_type)
  464. {
  465. if (!dmb_initialize)
  466. return TDMB_FAIL;
  467. current_service_type = sevice_type;
  468. current_subchannel_id = subchannel;
  469. bbm_com_video_deselect(NULL, 0, 0, 0);
  470. bbm_com_audio_deselect(NULL, 0, 3);
  471. bbm_com_data_deselect(NULL, 0, 2);
  472. bbm_com_word_write(NULL, BBM_BUF_INT, 0x00ff);
  473. if (bbm_com_tuner_set_freq(NULL, frequency) != BBM_OK)
  474. return TDMB_FAIL;
  475. if (bbm_com_scan_status(NULL)) {
  476. DPRINTK("%s scan fail\n", __func__);
  477. return TDMB_FAIL;
  478. }
  479. if (sevice_type == 0x18)
  480. bbm_com_video_select(NULL, subchannel, 0, 0);
  481. else if (sevice_type == 0x00)
  482. bbm_com_audio_select(NULL, subchannel, 3);
  483. else
  484. bbm_com_data_select(NULL, subchannel, 2);
  485. #ifdef FEATURE_FC8050_DEBUG
  486. if (sevice_type == 0x18)
  487. dmb_mode = FC8050_DMB;
  488. else if (sevice_type == 0x00)
  489. dmb_mode = FC8050_DAB;
  490. else
  491. dmb_mode = FC8050_DATA;
  492. #endif
  493. return TDMB_SUCCESS;
  494. }
  495. unsigned short dmb_drv_get_ber()
  496. {
  497. return saved_ber;
  498. }
  499. unsigned char dmb_drv_get_ant(void)
  500. {
  501. u8 level = 0;
  502. unsigned int ber;
  503. if (!dmb_initialize) {
  504. saved_ber = 3000;
  505. return 0;
  506. }
  507. if (viterbi_rt_ber_read(&ber)) {
  508. saved_ber = 3000;
  509. return 0;
  510. }
  511. if (ber <= 20)
  512. ber = 0;
  513. saved_ber = ber;
  514. if (get_signal_level(ber, &level))
  515. return 0;
  516. #ifdef FEATURE_FC8050_DEBUG
  517. dmb_drv_check_overrun(1);
  518. #endif
  519. return level;
  520. }
  521. signed short dmb_drv_get_rssi()
  522. {
  523. s32 rssi;
  524. if (!dmb_initialize) {
  525. rssi = -110;
  526. return rssi;
  527. }
  528. bbm_com_tuner_get_rssi(NULL, &rssi);
  529. return (signed short)rssi;
  530. }