SI4703API.c
上传用户:ledjyj
上传日期:2014-08-27
资源大小:2639k
文件大小:36k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1. /***************************************************************************
  2.  * 
  3.  *                         QCI GSM/GPRS Phase 2 Software       
  4.  *                                                             
  5.  *                    Copyright (c) 2005 Quanta Computer Inc.
  6.  *
  7.  *****************************************************************************
  8.  * 
  9.  *  $Workfile:   l1alfmradio.c
  10.  *  $Revision:   1.0
  11.  *  $Author  :   Eric Yang
  12.  *  $Date    :   2005.08.19
  13.  *
  14.  *****************************************************************************
  15.  *
  16.  *  File Description : This file includes all the function about silicon FM module FM_SI47XX/01 
  17.  *
  18.  *  Definition by project
  19.  *
  20.  *****************************************************************************
  21.  *
  22.  * Revision Details
  23.  * ----------------
  24.  *   $Log: l1alfmradio.c,v $
  25.  *   Revision 1.5  2005/12/08 08:29:31  05063078
  26.  *   1.       add power down function in file dlau6535.c ,l1alfmradio.c
  27.  *   2.       when powering on FM, MMI will set a default frequency, but  FM Module can’t tune successfully
  28.  *   3.       Wolfson change path fail by using Wolfson Power on Req
  29.  *
  30.  *   Revision 1.4  2005/12/01 01:24:22  05063078
  31.  *   the way set band change and return channel change when seek complete
  32.  *
  33.  *   Revision 1.3  2005/11/11 03:43:09  QUANTA92101320
  34.  *   1.Modify DlAu6535OutputSelect() and L1FrSendPowerOnWolfsonCommand() to play soft midi
  35.  *   2.Add signal-base control of WM8976 I2S audio path
  36.  *   3.Open default audio path(Headphone) for FM
  37.  *   4.Add ReadST(),WaitSTC(),ReadRDS(),ReadRDSR(),ReadRDSE(),ReadRDS_Block(), FM_SI47XX_ReadRSSI(), FM_SI47XX_OpenRDS(), FM_SI47XX_SetSeekDepth() and FM_SI47XX_CloseRDS() for FM RDS/RBDS function
  38.  *   5.Add signal-base control of power down WM8976
  39.  *
  40.  *   Revision 1.2  2005/11/02 06:37:36  QUANTA92101320
  41.  *   Update I2S and DAC
  42.  *
  43.  *   Revision 1.1  2005/09/29 02:49:32  QUANTA91080103
  44.  *   no message
  45.  *
  46.  *
  47.  ***************************************************************************/
  48. /* This file is created and include in the serial number 20050922-00000100-01962-G80 */
  49. //#if defined (QCI_L1_UPGRADE_SILICON_FM_MODULE) 
  50. /***************************************************************************
  51.  * Include Files
  52.  ***************************************************************************/
  53. //#include <system.h>
  54. //#include <kernel.h>
  55. #include <linux/wait.h>
  56. #include <linux/delay.h>
  57. #include <asm/hardware.h>
  58. #include <asm/arch/pxa-regs.h>
  59. #include <asm/irq.h>
  60. #include "SI4703API.h"
  61. //#include <dlmmicfg.h>
  62. //#include <l1debug.h>
  63. /* Quanta modify by Beck.He 20051206-00001100-02083-G80 */ 
  64. //#include <l1al_typ.h>
  65. /* End of modification by Beck.He 20051129-00000100-*****-G80 */
  66. /* Quanta modify by Beck.He 20051129-00000100-*****-G80 */ 
  67. //#include <bbcfg.h>
  68. /* End of modification by Beck.He 20051206-00001100-02083-G80 */
  69. /***************************************************************************
  70.  * Manifest Constants
  71.  ***************************************************************************/
  72. /***************************************************************************
  73.  * Type Definitions
  74.  ***************************************************************************/
  75. /***************************************************************************
  76.  * Variables
  77.  ***************************************************************************/
  78. /* Quanta modify by Beck.He 20051206-00001100-02083-G80   */
  79. /*move the define to bbcfg.h*/
  80. /* End of modification by Beck.He 20051206-00001100-02083-G80 */
  81. /***************************************************************************
  82.  * Macros
  83.  ***************************************************************************/
  84. /***************************************************************************
  85.  * Variables
  86.  ***************************************************************************/
  87. const __u16 FM_SI47XX_DEVICE_ADDR=0x20;
  88. const __u16 FM_SI47XX_WRITE=0x00;
  89. const __u16 FM_SI47XX_READ=0x01;
  90. /*** For writing ***/
  91. /*** REG 0x02 POWERCFG ***/
  92. const __u16 SI_DMUTE =0x4000;
  93. const __u16 SI_MUTE  =0x0000;
  94. const __u16 SI_MONO =0x2000;
  95. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  96. const __u16 SI_SKMODE=0x0400;
  97. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  98. const __u16 SI_SEEKUP=0x0200;
  99. const __u16 SI_SEEKDOWN=0x0000;
  100. const __u16 SI_SEEK =0x0100;
  101. const __u16 SI_DISABLE=0x0040;
  102. const __u16 SI_ENABLE=0x0001;
  103. /*** REG 0x03 CHANNEL ***/
  104. const __u16 SI_TUNE=0x8000;
  105. /*** REG 0x04 SYSCONFIG1 ***/
  106. const __u16 SI_RDSIEN=0x8000;
  107. const __u16 SI_STCIEN=0x4000;
  108. const __u16 SI_RDS=0x1000;
  109. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  110. const __u16 SI_DE_50US=0x0800; // 50us for Europe and Australia
  111. const __u16 SI_GPIO3_INTERRUPT=0x0010;
  112. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  113. const __u16 SI_AGCD_DIS=0x0400;
  114. const __u16 SI_GPIO2_INTERRUPT=0x0004;
  115. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  116. const __u16 SI_GPIO2_HIGH=0x000B;
  117. const __u16 SI_GPIO2_LOW =0x0008;
  118. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  119. /*** REG 0x05 SYSCONFIG2 ***/
  120. const __u16 SI_RECOMMENDED_SEEKTH=0x1900;
  121. /* Quanta modify by Beck.He 20051129-00001100-02083-G80 */
  122. const __u16 SI_BAND =0x00C0; 
  123. /* End of modification by Beck.He 20051129-00001100-02083-G80 */
  124. const __u16 SI_BAND_US =0x0000; //87.5-108MHz
  125. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  126. const __u16 SI_WIDEBAND_JAPAN=0x0040;//76-108MHZ
  127. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  128. const __u16 SI_BAND_JAPAN =0x0080; //76-90MHz
  129. const __u16 SI_SPACE =0x0030;
  130. const __u16 SI_SPACE_200KHZ=0x0000;
  131. const __u16 SI_SPACE_100KHZ=0x0010;
  132. const __u16 SI_SPACE_50KHZ =0x0020;
  133. const __u16 SI_VOLUME =0x000F;
  134. /*** For reading ***/
  135. /*** REG 0x0A STATUSRSSI ***/
  136. const __u16 SI_RDSR=0x8000;
  137. const __u16 SI_STC=0x4000;
  138. const __u16 SI_SF=0x2000;
  139. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  140. const __u16 SI_AFCRL=0x1000;
  141. const __u16 SI_RDSE=0x0E00;
  142. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  143. const __u16 SI_ST=0x0100;
  144. const __u16 SI_RSSI=0x00FF;
  145. /*** REG 0x0B READCHAN ***/
  146. const __u16 SI_READCHAN=0x03FF;
  147. /*** REG 0x00 DEVICEID ***/
  148. const __u16 SI_PN=0xF000;
  149. const __u16 SI_MFGID=0x0FFF;
  150. /*** REG 0x01 CHIPID ***/
  151. const __u16 REV=0xFC00;
  152. const __u16 DEV=0x0200;
  153. const __u16 FIRMWARE=0x01FF;
  154. /*** User defined Variables ***/
  155. static __u16 AUTOSEEK=FALSE;
  156. static __u8 WriteRegArray[9];
  157. static __u8 ReadRegArray[25];
  158. const __u16 SI_BottomOfChannel=0x0000;
  159. __u8 VolumeCtrl;
  160. const __u8 NORVOL=0x08;
  161. const __u8 MAXVOL=0x0F;
  162. const __u8 MINVOL=0x00;
  163. static __u16 SeekedChannels[40];
  164. static __u8 MaxSeekedChannels=40;
  165. //static Boolean AUTOSEEK=FALSE;
  166. static __u8 MaxTuneIndex=0;
  167. static __u8 TuneIndex=0;
  168. static __u16 BandSelect;
  169. static __u16 SpacingSelect;
  170. const __u8 SEEKTH_TO_VALUE_LIST[]=
  171. {
  172. 0x19, 0x1A, 0x1B, 0x1C, 
  173. 0x1D, 0x1E, 0x1F, 0x20
  174. };
  175. /***************************************************************************
  176.  * Declarations & Prototypes
  177.  ***************************************************************************/
  178. #define si4703_debug 1
  179. /***************************************************************************
  180.  * Local Functions
  181.  ***************************************************************************/
  182. /***************************************************************************
  183.  * Global Functions
  184.  ***************************************************************************/
  185. /*******************************************************************************
  186.  * Function:      FM_SI47XX_WriteReg
  187.  *
  188.  * Parameters:    RegAddr, representing address of register of FM_SI47XX from 02h to 05h
  189.  * 
  190.  *    __u16 InputData, content of register for writing in FM_SI47XX
  191.  *
  192.  * Returns:       none
  193.  *
  194.  * Description:   Routine to write content into registers in FM_SI47XX
  195.  ******************************************************************************/
  196. void
  197. FM_SI47XX_WriteReg(
  198. WRITE_REG_ADDR RegAddr,
  199. __u16 InputData
  200. )
  201. {
  202. __u8 NumOfBytesToWrite;
  203.    
  204. NumOfBytesToWrite=RegAddr*2;
  205. WriteRegArray[RegAddr*2-1]=(InputData & 0xFF00)>>8;
  206. WriteRegArray[RegAddr*2]=InputData & 0x00FF;
  207.             SI4703_I2C_Write(&WriteRegArray[1],NumOfBytesToWrite);
  208. //I2C_2Wire_Operation(WRITE,WriteRegArray,NumOfBytesToWrite+1);
  209. }
  210. /*******************************************************************************
  211.  * Function:      FM_SI47XX_ReadReg
  212.  *
  213.  * Parameters:    RegAddr, representing address of register of FM_SI47XX from 00h to 0Ah
  214.  *
  215.  * Returns:       none
  216.  *
  217.  * Description:  Routine to read content into registers in FM_SI47XX
  218.  ******************************************************************************/
  219. __u16
  220. FM_SI47XX_ReadReg(
  221. READ_REG_ADDR RegAddr 
  222. )
  223. {
  224. __u8 NumOfBytesToRead;
  225. NumOfBytesToRead=RegAddr*2;   SI4703_I2C_Read(&ReadRegArray[1],NumOfBytesToRead);
  226. //I2C_2Wire_Operation(READ,ReadRegArray,NumOfBytesToRead+1);
  227. return ((ReadRegArray[NumOfBytesToRead-1]<<8) | ReadRegArray[NumOfBytesToRead]);
  228. }
  229. /*******************************************************************************
  230.  * Function:      ReadSTC
  231.  *
  232.  * Parameters:    none
  233.  *    
  234.  * Returns:       __u8
  235.  *
  236.  * Description:  Routine to return STC bit in FM_SI47XX
  237.  ******************************************************************************/
  238. __u8
  239. ReadSTC(
  240. void
  241. )
  242. {
  243. if(FM_SI47XX_ReadReg(R0Ah) & SI_STC)
  244. return 1;
  245. else
  246. return 0;
  247. }
  248. /*******************************************************************************
  249.  * Function:      ReadSF
  250.  *
  251.  * Parameters:    none
  252.  *    
  253.  * Returns:       __u8
  254.  *
  255.  * Description:  Routine to return SF bit in FM_SI47XX
  256.  ******************************************************************************/
  257. __u8
  258. ReadSF(
  259. void
  260. )
  261. {
  262. if(FM_SI47XX_ReadReg(R0Ah) & SI_SF)
  263. return 1;
  264. else
  265. return 0;
  266. }
  267. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  268. /*******************************************************************************
  269.  * Function:      ReadST
  270.  *
  271.  * Parameters:    none
  272.  *    
  273.  * Returns:       __u8
  274.  *
  275.  * Description:  Routine to return ST(stereo) bit in FM_SI47XX/01
  276.  ******************************************************************************/
  277. __u8 
  278. ReadST(
  279. void
  280. )
  281. {
  282. if(FM_SI47XX_ReadReg(R0Ah) & SI_ST){
  283. return 1;
  284. }
  285. else{
  286. return 0;
  287. }
  288. }
  289. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  290. /*******************************************************************************
  291.  * Function:      ReadGpio2
  292.  *
  293.  * Parameters:    none
  294.  *    
  295.  * Returns:       __u8
  296.  *
  297.  * Description:  Routine to return status of interrupt pin GPIO2 in FM_SI47XX
  298.  ******************************************************************************/
  299. __u8
  300. ReadGpio2(
  301. void
  302. )
  303. {
  304. return 0;
  305. }
  306. /*******************************************************************************
  307.  * Function:      WaitGpio2
  308.  *
  309.  * Parameters:    none
  310.  *    
  311.  * Returns:       none
  312.  *
  313.  * Description:  Routine to wait interrupt pin GPIO2 on FM_SI47XX until its value is 0
  314.  ******************************************************************************/
  315. void 
  316. WaitGpio2(
  317. void
  318. )
  319. {
  320. while(ReadGpio2() !=0);
  321. return;
  322. }
  323. /*******************************************************************************
  324.  * Function:      CfgFM_SI47XXRstAsOutput
  325.  *
  326.  * Parameters:    none
  327.  *    
  328.  * Returns:       none
  329.  *
  330.  * Description:  Routine to configure GPIO53 on AD6527
  331.  ******************************************************************************/
  332. void
  333. CfgFM_SI47XXRstAsOutput(
  334. void
  335. )
  336. {
  337. //DlGpioConfigure(FM_RST); // pull to high
  338. }
  339. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  340. /*******************************************************************************
  341.  * Function:      WaitSTC
  342.  *
  343.  * Parameters:    none
  344.  *    
  345.  * Returns:       none
  346.  *
  347.  * Description:  Routine to wait until STC bit =1 on FM_SI47XX/01
  348.  ******************************************************************************/
  349. void
  350. WaitSTC(
  351. void
  352. )
  353. {
  354. //StartOfFrame=l1FrameNumber;
  355. while( (ReadSTC() !=1) ); //&& ((l1FrameNumber-StartOfFrame)<20) );
  356. //StopOfFrame=l1FrameNumber;
  357. //gplog4(2212,StartOfFrame,StopOfFrame,StopOfFrame-StartOfFrame,FM_SI47XX_ReadReg(R05h) & SI_SPACE);
  358. return;
  359. }
  360. /*******************************************************************************
  361.  * Function:      ReadRDS
  362.  *
  363.  * Parameters:    none
  364.  *    
  365.  * Returns:       none
  366.  *
  367.  * Description:  Routine to read RDS bit on FM_SI47XX/01
  368.  ******************************************************************************/
  369. __u8
  370. ReadRDS(
  371. void
  372. )
  373. {
  374. if(FM_SI47XX_ReadReg(R04h) & SI_RDS){
  375. return 1;
  376. }
  377. else{
  378. return 0;
  379. }
  380. }
  381. /*******************************************************************************
  382.  * Function:      ReadRDSR
  383.  *
  384.  * Parameters:    none
  385.  *    
  386.  * Returns:       none
  387.  *
  388.  * Description:  Routine to read RDSR bit on FM_SI47XX/01
  389.  ******************************************************************************/
  390. __u8
  391. ReadRDSR(
  392. void
  393. )
  394. {
  395. if(FM_SI47XX_ReadReg(R0Ah) & SI_RDSR){
  396. return 1;
  397. }
  398. else{
  399. return 0;
  400. }
  401. }
  402. /*******************************************************************************
  403.  * Function:      ReadRDSE
  404.  *
  405.  * Parameters:    none
  406.  *    
  407.  * Returns:       none
  408.  *
  409.  * Description:  Routine to read RDSE bits on FM_SI47XX/01
  410.  ******************************************************************************/
  411. __u8
  412. ReadRDSE(
  413. void
  414. )
  415. {
  416. return ( (FM_SI47XX_ReadReg(R0Ah) & SI_RDSE)>>9 );
  417. }
  418. /*******************************************************************************
  419.  * Function:      ReadRDS_BLOCK
  420.  *
  421.  * Parameters:    none
  422.  *    
  423.  * Returns:       none
  424.  *
  425.  * Description:  Routine to read RDSA, RDSB, RDSC and RDSD on FM_SI47XX/01
  426.  ******************************************************************************/
  427. __u16
  428. ReadRDS_BLOCK(
  429. RDS_STATUS RDS_ID
  430. )
  431. {
  432. switch(RDS_ID)
  433. {
  434. case RDSA:
  435. return FM_SI47XX_ReadReg(R0Ch);
  436. break;
  437. case RDSB:
  438. return FM_SI47XX_ReadReg(R0Dh);
  439. break;
  440. case RDSC:
  441. return FM_SI47XX_ReadReg(R0Eh);
  442. break;
  443. case RDSD:
  444. return FM_SI47XX_ReadReg(R0Fh);
  445. break;
  446. default:
  447.     /* Quanta modify by BECK.HE 20051129-00001100-02083-G80 */     
  448.   return 0;   
  449.   /* End of modification by BECK.HE 20051129-00001100-02083-G80 */  
  450.   break;
  451. }                                                       
  452. }    
  453. /*******************************************************************************
  454.  * Function:      FM_SI47XX_ReadRSSI
  455.  *
  456.  * Parameters:    none
  457.  *    
  458.  * Returns:       none
  459.  *
  460.  * Description:  Routine to read RSSI bits on FM_SI47XX/01
  461.  ******************************************************************************/
  462. __u8
  463. FM_SI47XX_ReadRSSI(
  464. void
  465. )
  466. {
  467. return ( (FM_SI47XX_ReadReg(R0Ah) & SI_RSSI) );
  468. }
  469. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  470. /*******************************************************************************
  471.  * Function:      FM_SI47XX_RST_LOW
  472.  *
  473.  * Parameters:    none
  474.  *    
  475.  * Returns:       none
  476.  *
  477.  * Description:  Routine to set GPIO53 on AD6527 as low voltage
  478.  ******************************************************************************/
  479. void
  480. FM_SI47XX_RST_LOW(
  481. void
  482. )
  483. {
  484. //M_DLGpioAssertLine(M_DLGpioLine(FM_RST));
  485. }
  486. /*******************************************************************************
  487.  * Function:      FM_SI47XX_RST_HIGH
  488.  *
  489.  * Parameters:    none
  490.  *    
  491.  * Returns:       none
  492.  *
  493.  * Description:  Routine to set GPIO53 on AD6527 as high voltage
  494.  ******************************************************************************/
  495. void
  496. FM_SI47XX_RST_HIGH(
  497. void
  498. )
  499. {
  500. //M_DLGpioDeassertLine(M_DLGpioLine(FM_RST));
  501. }
  502. /*******************************************************************************
  503.  * Function:      FM_SI47XX_2Wire
  504.  *
  505.  * Parameters:    none
  506.  *    
  507.  * Returns:       none
  508.  *
  509.  * Description:  Routine to configure FM_SI47XX to operate in 2-wire mode
  510.  ******************************************************************************/
  511. void 
  512. FM_SI47XX_2Wire(
  513. void
  514. )
  515. {
  516. //DlGpioConfigure(FM_SEN); // pull to high
  517. //M_DLGpioDeassertLine(M_DLGpioLine(FM_SEN)); // pull to high
  518. }
  519. /*******************************************************************************
  520.  * Function:      FM_SI47XX_Reset
  521.  *
  522.  * Parameters:    none
  523.  *    
  524.  * Returns:       none
  525.  *
  526.  * Description:  Routine to reset FM_SI47XX 
  527.  ******************************************************************************/
  528. void
  529. FM_SI47XX_Reset(
  530. void
  531. )
  532. {
  533. //CfgFM_SI47XXRstAsOutput(); //pull to high
  534. //TWS_TransmitData (TWS_TC_START, 0);
  535. //TWS_TransmitData (TWS_TC_DATA, (TWS_DATA)0x00);
  536. //TWS_TransmitData (TWS_TC_DATA, (TWS_DATA)0x00);
  537. //TWS_TransmitData (TWS_TC_DATA, (TWS_DATA)0x00);
  538. // FM_SI47XX_RST_LOW();
  539. // FM_SI47XX_RST_HIGH();
  540. // TWS_TransmitData (TWS_TC_STOP, 0);
  541. }
  542. /*******************************************************************************
  543.  * Function:      FM_SI47XX_Init
  544.  *
  545.  * Parameters:    none
  546.  *    
  547.  * Returns:       none
  548.  *
  549.  * Description:  Routine to initialize FM_SI47XX 
  550.  ******************************************************************************/
  551. /*** Initialization of FM_SI47XX module ***/
  552. void FM_SI47XX_Init(void)
  553. {
  554. //WM8976_LDO_POWERON();
  555. //CfgGpio6As32KHZ();
  556. //CfgFM_SI47XXGpio2AsInput(); //pull to high
  557.     #ifdef si4703_debug
  558.     printk(KERN_ERR "radio-si4703: Init,n");
  559.     #endif
  560.   #define TOUT_EN  1<<2
  561.    OSCC |= TOUT_EN;          //clk
  562.     pxa_gpio_mode(123 |GPIO_OUT | GPIO_DFLT_LOW);//reset
  563.     udelay(200);
  564.     pxa_gpio_mode(123 |GPIO_OUT | GPIO_DFLT_HIGH);
  565.     pxa_gpio_mode(122 | GPIO_IN); // irq setting
  566.     set_irq_type(IRQ_GPIO(122), IRQT_FALLING);
  567. WriteRegArray[0]=FM_SI47XX_DEVICE_ADDR | FM_SI47XX_WRITE;
  568. ReadRegArray[0] =FM_SI47XX_DEVICE_ADDR | FM_SI47XX_READ;
  569. VolumeCtrl=MAXVOL;
  570. BandSelect=SI_BAND_US;
  571. SpacingSelect=SI_SPACE_100KHZ;
  572. }
  573. /* Quanta modify by Jacky.Sun 20051202-00000100-*****-G80 */
  574. /*******************************************************************************
  575.  * Function:      FM_SI47XX_PowerUp
  576.  *
  577.  * Parameters:    Boolean  bRDSEnable, enable RDS function
  578.  *    
  579.  * Returns:       none
  580.  *
  581.  * Description:  Routine to turn on FM_SI47XX 
  582.  ******************************************************************************/
  583. void FM_SI47XX_PowerUp()
  584. {
  585.  /* Quanta modify by Beck.He 20051206-00001100-02083-G80 */ 
  586. //M_DLGpioAssertLine(M_DLGpioLine(FM_PWR_ON)); // pull to high
  587.  /* End of modification by Beck.He 20051206-00001100-02083-G80 */
  588. //FM_SI47XX_Init();
  589. //FM_SI47XX_2Wire(); /* 2wire setting must be done before reset operation */
  590. //FM_SI47XX_Reset();
  591.     #ifdef si4703_debug
  592.     printk(KERN_ERR "radio-si4703: power up,n");
  593.     #endif
  594. FM_SI47XX_WriteReg(W02h,SI_DMUTE | SI_ENABLE);
  595. FM_SI47XX_WriteReg(W03h,SI_BottomOfChannel);
  596. //FM_SI47XX_WriteReg(W04h,SI_RDSIEN | SI_STCIEN | SI_GPIO2_INTERRUPT);
  597.        
  598.     FM_SI47XX_WriteReg(W04h,SI_RDSIEN | SI_STCIEN | SI_RDS | SI_GPIO2_INTERRUPT);
  599. FM_SI47XX_WriteReg(W05h,SI_RECOMMENDED_SEEKTH | BandSelect | SpacingSelect | VolumeCtrl);
  600. /* Quanta modify by Beck.He 20051206-00001100-02083-G80 */  
  601. while(ReadSTC() !=1);
  602. /* End of modification by Beck.He 20051206-00001100-02083-G80 */
  603. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  604. FM_SI47XX_WriteReg(W03h,FM_SI47XX_ReadChannel());
  605. /* End of modification by Brian 20051111-00001100-02083-G80 */
  606. }
  607. /* End of modification by Jacky.Sun 20051202-00000100-*****-G80 */
  608. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  609. /*******************************************************************************
  610.  * Function:      FM_SI47XX_OpenRDS
  611.  *
  612.  * Parameters:    none
  613.  *    
  614.  * Returns:       none
  615.  *
  616.  * Description:  Routine to turn on RDS function of SI4701
  617.  ******************************************************************************/
  618. void
  619. FM_SI47XX_OpenRDS(
  620. void
  621. )
  622. {
  623. FM_SI47XX_WriteReg(W04h,FM_SI47XX_ReadReg(R04h) | SI_RDS);
  624. }
  625. /*******************************************************************************
  626.  * Function:      FM_SI47XX_CloseRDS
  627.  *
  628.  * Parameters:    none
  629.  *    
  630.  * Returns:       none
  631.  *
  632.  * Description:  Routine to turn off RDS function of SI4701 
  633.  ******************************************************************************/
  634. void 
  635. FM_SI47XX_CloseRDS(
  636. void
  637. )
  638. {
  639. FM_SI47XX_WriteReg(W04h,FM_SI47XX_ReadReg(R04h) & 0xCC3F);
  640. }
  641. /* End of modification by Brian 20051111-00001100-02083-G80 */
  642. /*******************************************************************************
  643.  * Function:      FM_SI47XX_SetBand
  644.  *
  645.  * Parameters:    band- set 0 for changing band to USA,EUROPE
  646.  *
  647.  *    set 1 for changing band to JAPAN
  648.  *    
  649.  * Returns:       none
  650.  *
  651.  * Description:  Routine to set FM band
  652.  ******************************************************************************/
  653. void
  654. FM_SI47XX_SetBand(
  655. __u8 band
  656. )
  657. {
  658. if(band==1)
  659. BandSelect=SI_BAND_US;
  660. else
  661. BandSelect=SI_BAND_JAPAN;
  662. FM_SI47XX_WriteReg(W05h,SI_RECOMMENDED_SEEKTH | BandSelect | SpacingSelect | VolumeCtrl);
  663. }
  664. /*******************************************************************************
  665.  * Function:      FM_SI47XX_SetSpacing
  666.  *
  667.  * Parameters:    spacing- set 0 for changing channel spacing to 200KHZ
  668.  *
  669.  *       set 1 for changing channel spacing to 100KHZ
  670.  *
  671.  *       set 2 for changing channel spacing to 50KHZ
  672.  *    
  673.  * Returns:       none
  674.  *
  675.  * Description:  Routine to set FM band
  676.  ******************************************************************************/
  677. void
  678. FM_SI47XX_SetSpacing(
  679. __u8 spacing
  680. )
  681. {
  682. switch(spacing){
  683. case 0:
  684. SpacingSelect=SI_SPACE_200KHZ;
  685. break;
  686. case 1:
  687. SpacingSelect=SI_SPACE_100KHZ;
  688. break;
  689. case 2:
  690. SpacingSelect=SI_SPACE_50KHZ;
  691. break;
  692. default:
  693. break;
  694. }
  695. FM_SI47XX_WriteReg(W05h,SI_RECOMMENDED_SEEKTH | BandSelect | SpacingSelect | VolumeCtrl);
  696. }
  697. /* Quanta modify by Brian 20051111-00001100-02083-G80 */
  698. /*******************************************************************************
  699.  * Function:      FM_SI47XX_SetSeekDepth
  700.  *
  701.  * Parameters:    SeekDepth
  702.  *
  703.  *    set 1 for changing band to JAPAN
  704.  *    
  705.  * Returns:       none
  706.  *
  707.  * Description:  Routine to set seeking depth of FM channel
  708.  ******************************************************************************/
  709. void 
  710. FM_SI47XX_SetSeekDepth(
  711. __u8 SeekDepth
  712. )
  713. {
  714. FM_SI47XX_WriteReg(W05h,(SeekDepth<<8) | BandSelect | SpacingSelect | VolumeCtrl);
  715. }
  716. /* End of modification by Brian 20051111-00001100-02083-G80 */ 
  717. /*******************************************************************************
  718.  * Function:      FM_SI47XX_PowerDown
  719.  *
  720.  * Parameters:    none
  721.  *    
  722.  * Returns:       none
  723.  *
  724.  * Description:  Routine to turn off FM_SI47XX 
  725.  ******************************************************************************/
  726. void
  727. FM_SI47XX_PowerDown(
  728. void
  729. )
  730. {
  731.     #ifdef si4703_debug
  732.     printk(KERN_ERR "radio-si4703: power down,n");
  733.     #endif
  734.     /*** Set DISABLE bit=1, perform internal power-down sequence and set ENABLE bit=0 later by device itself ***/
  735. FM_SI47XX_WriteReg(W02h,SI_ENABLE | SI_DISABLE);
  736. }
  737. /*******************************************************************************
  738.  * Function:      FM_SI47XX_Tune
  739.  *
  740.  * Parameters:    Channel- channel on FM radio, its unit value is 100Khz such as
  741.  *
  742.  *    if we want to tune 101.5Mhz radio, we must set variable Channel
  743.  *
  744.  *    =1015
  745.  *    
  746.  * Returns:       none
  747.  *
  748.  * Description:  Routine to turn off FM_SI47XX 
  749.  ******************************************************************************/
  750. void 
  751. FM_SI47XX_Tune(
  752. __u16 Freq
  753. )
  754. {
  755.     #ifdef si4703_debug
  756.     printk(KERN_ERR "radio-si4703: tune ,n");
  757.     #endif
  758.     /* Write address 0x03 to set channel and TUNE bit */
  759. FM_SI47XX_WriteReg(W03h,FM_SI47XX_FreqToChan(Freq) | SI_TUNE);
  760. /*** Wait for STC interrupt ***/
  761. WaitGpio2();
  762. /*** Write address 0x03 to clear TUNE bit ***/
  763. while(ReadSTC() !=1);
  764. FM_SI47XX_WriteReg(W03h,FM_SI47XX_ReadChannel());
  765. }
  766. /*******************************************************************************
  767.  * Function:      FM_SI47XX_TuneNextChan
  768.  *
  769.  * Parameters:    none
  770.  *    
  771.  * Returns:       none
  772.  *
  773.  * Description:  Routine to tune next channel from current channel
  774.  ******************************************************************************/
  775. void
  776. FM_SI47XX_TuneNextChan(
  777. void
  778. )
  779. {
  780. /* Write address 0x03 to set channel and TUNE bit */
  781. FM_SI47XX_WriteReg(W03h, SI_TUNE | ((FM_SI47XX_ReadChannel()+0x0001) &0x03FF));
  782. /*** Wait for STC interrupt ***/
  783. WaitGpio2();
  784. /*** Write address 0x03 to clear TUNE bit ***/
  785. while(ReadSTC() !=1);
  786. FM_SI47XX_WriteReg(W03h,FM_SI47XX_ReadChannel());
  787. }
  788. /*******************************************************************************
  789.  * Function:      FM_SI47XX_TunePrevChan
  790.  *
  791.  * Parameters:    none
  792.  *    
  793.  * Returns:       none
  794.  *
  795.  * Description:  Routine to tune previous channel from current channel
  796.  ******************************************************************************/
  797. void
  798. FM_SI47XX_TunePrevChan(
  799. void
  800. )
  801. {
  802. /* Write address 0x03 to set channel and TUNE bit */
  803. FM_SI47XX_WriteReg(W03h, SI_TUNE | ((FM_SI47XX_ReadChannel()-0x0001) &0x03FF));
  804. /*** Wait for STC interrupt ***/
  805. WaitGpio2();
  806. /*** Write address 0x03 to clear TUNE bit ***/
  807. while(ReadSTC() !=1);
  808. FM_SI47XX_WriteReg(W03h,FM_SI47XX_ReadChannel());
  809. }
  810. /*******************************************************************************
  811.  * Function:      FM_SI47XX_Seek
  812.  *
  813.  * Parameters:    SeekDirection, determine the direction of seeking on FM radio module
  814.  *    
  815.  * Returns:       SEEK_STATUS
  816.  *
  817.  * Description:  Routine to seek available channel on FM_SI47XX
  818.  ******************************************************************************/
  819. void
  820. FM_SI47XX_Seek(
  821. __u16 SeekDirection, __u16 *channel, __u16 *scanok
  822. )
  823. {
  824.     #ifdef si4703_debug
  825.     printk(KERN_ERR "radio-si4703: seek,n");
  826.     #endif
  827.     /*** Write address 0x02 to set SEEK and SEEKUP bit ***/
  828. if(SeekDirection==SEEKUP)
  829. FM_SI47XX_WriteReg(W02h,SI_DMUTE | SI_SEEK | SI_SEEKUP | SI_ENABLE);
  830. else
  831. FM_SI47XX_WriteReg(W02h,SI_DMUTE | SI_SEEK | SI_SEEKDOWN | SI_ENABLE);
  832. /*** Wait for STC interrupt ***/
  833. WaitGpio2();
  834. /*** Read channel status after seeking at address 0x0B and clear ***/
  835. while(ReadSTC()!=1);
  836. /*** Read SF status after seeking at address 0x0A ***/
  837. if(ReadSF()==1){
  838. *scanok = FALSE;
  839. }
  840. else{
  841. /*** Clear STC and SF bit by setting SEEK bit to low ***/
  842. *scanok = TRUE;
  843. }
  844.     *channel = FM_SI47XX_ReadChannel();
  845. FM_SI47XX_WriteReg(W02h,SI_DMUTE | SI_ENABLE);
  846. }
  847. /*******************************************************************************
  848.  * Function:      FM_SI47XX_SeekUp
  849.  *
  850.  * Parameters:    none
  851.  *    
  852.  * Returns:       SEEK_STATUS
  853.  *
  854.  * Description:  Routine to seek up available channel on FM_SI47XX
  855.  ******************************************************************************/
  856. SEEK_STATUS
  857. FM_SI47XX_SeekUp(
  858. void
  859. )
  860. {
  861.     return 0;
  862.     //return FM_SI47XX_Seek(SEEKUP);
  863. }
  864. /*******************************************************************************
  865.  * Function:      FM_SI47XX_SeekDown
  866.  *
  867.  * Parameters:    none
  868.  *    
  869.  * Returns:       SEEK_STATUS
  870.  *
  871.  * Description:  Routine to seek down available channel on FM_SI47XX
  872.  ******************************************************************************/
  873. SEEK_STATUS
  874. FM_SI47XX_SeekDown(
  875. void
  876. )
  877. {
  878.     return 0;
  879.     
  880.     //return FM_SI47XX_Seek(SEEKDOWN);
  881. }
  882. /*******************************************************************************
  883.  * Function:      FM_SI47XX_AutoSeek
  884.  *
  885.  * Parameters:    none
  886.  *    
  887.  * Returns:       __u8
  888.  *
  889.  * Description:  Routine to seek all channels on full band automatically and return 
  890.  *
  891.  *   the number of channels seeked before
  892.  ******************************************************************************/
  893. __u8
  894. FM_SI47XX_AutoSeek(
  895. void
  896. )
  897. {
  898. __u8 ChannelIndex=0;
  899. __u16 DoneSeeking=FALSE;
  900. FM_SI47XX_EraseAllSeekedChannels();
  901. /*** Seek through all FM band automatically ***/
  902. while((DoneSeeking !=TRUE)){
  903. /* DoneSeeking if SF=1 */
  904. if(FM_SI47XX_SeekUp()==SEEKFAILURE) {
  905. DoneSeeking=TRUE;
  906. }
  907. else if( (ChannelIndex !=0) && (SeekedChannels[ChannelIndex-1]>FM_SI47XX_ReadChannel()) ){
  908. /* at least one channel in SeekedChannels list and current seeked channel is lower than previous seeked channel */
  909. DoneSeeking=TRUE;
  910. }
  911. else{
  912. /* Store channel and keep seeking */
  913. SeekedChannels[ChannelIndex]=FM_SI47XX_ReadChannel();
  914. FM_SI47XX_WriteReg(W03h,SeekedChannels[ChannelIndex]);
  915. ChannelIndex++;
  916. if(ChannelIndex==MaxSeekedChannels)
  917. DoneSeeking=TRUE;
  918. }
  919. }
  920. if(ChannelIndex>0){
  921. AUTOSEEK=TRUE;
  922. TuneIndex=0;
  923. MaxTuneIndex=ChannelIndex;
  924. /** Set default frequency after seeking automatically **/
  925. FM_SI47XX_Tune(FM_SI47XX_ChanToFreq(SeekedChannels[0]));
  926. }
  927. return ChannelIndex; /* Return NumOfChannels seeked by AutoSeek function */
  928. }
  929. /*******************************************************************************
  930.  * Function:      FM_SI47XX_TuneUp
  931.  *
  932.  * Parameters:    none
  933.  *    
  934.  * Returns:       none
  935.  *
  936.  * Description:  Routine to tune next seeked channel after seeking automatically
  937.  ******************************************************************************/
  938. void 
  939. FM_SI47XX_TuneUp(
  940. void
  941. )
  942. {
  943. if(AUTOSEEK == TRUE){
  944. if(TuneIndex==(MaxTuneIndex-1))
  945. TuneIndex=0;
  946. else
  947. TuneIndex++;
  948. FM_SI47XX_Tune(FM_SI47XX_ChanToFreq(SeekedChannels[TuneIndex]));
  949. }
  950. }
  951. /*******************************************************************************
  952.  * Function:      FM_SI47XX_TuneDown
  953.  *
  954.  * Parameters:    none
  955.  *    
  956.  * Returns:       none
  957.  *
  958.  * Description:  Routine to tune previous seeked channel after seeking automatically
  959.  ******************************************************************************/
  960. void 
  961. FM_SI47XX_TuneDown(
  962. void
  963. )
  964. {
  965. if(AUTOSEEK == TRUE){
  966. if(TuneIndex==0)
  967. TuneIndex=MaxTuneIndex-1;
  968. else
  969. TuneIndex--;
  970. FM_SI47XX_Tune(FM_SI47XX_ChanToFreq(SeekedChannels[TuneIndex]));
  971. }
  972. }
  973. /*******************************************************************************
  974.  * Function:      FM_SI47XX_EraseAllSeekedChannels
  975.  *
  976.  * Parameters:    none
  977.  *    
  978.  * Returns:       none
  979.  *
  980.  * Description:  Routine to erase all seeked channels after seeking automatically
  981.  ******************************************************************************/
  982. void 
  983. FM_SI47XX_EraseAllSeekedChannels(
  984. void
  985. )
  986. {
  987. __u8 ChannelIndex;
  988. for(ChannelIndex=0;ChannelIndex<MaxSeekedChannels;ChannelIndex++)
  989. SeekedChannels[ChannelIndex]=0x0000;
  990. AUTOSEEK=FALSE;
  991. MaxTuneIndex=0;
  992. TuneIndex=0;
  993. /*** Tune to the bottom of FM band ***/
  994. FM_SI47XX_Tune(FM_SI47XX_ChanToFreq(SI_BottomOfChannel));
  995. }
  996. /*******************************************************************************
  997.  * Function:      FM_SI47XX_ReadChannel
  998.  *
  999.  * Parameters:    none
  1000.  *    
  1001.  * Returns:       __u16
  1002.  *
  1003.  * Description:  Routine to return current available channel on FM_SI47XX
  1004.  ******************************************************************************/
  1005. __u16
  1006. FM_SI47XX_ReadChannel(
  1007. void
  1008. )
  1009. {
  1010. return FM_SI47XX_ReadReg(R0Bh);
  1011. }
  1012. /*******************************************************************************
  1013.  * Function:      FM_SI47XX_ChanToFreq
  1014.  *
  1015.  * Parameters:    Channel- channel on FM radio, its  value starts at 0x0000
  1016.  *
  1017.  * Returns:       __u16
  1018.  *
  1019.  * Description:  Routine to translate channel to frequency value
  1020.  ******************************************************************************/
  1021. __u16
  1022. FM_SI47XX_ChanToFreq(
  1023. __u16 Channel
  1024. )
  1025. {
  1026. __u16 Info;
  1027. __u16 BottomOfFreq;
  1028. Info=WriteRegArray[W05h*2];
  1029. /* 100KHZ as one unit */
  1030.  /* Quanta modify by Beck.He 20051129-00001100-02083-G80 */
  1031. if((Info & SI_BAND)==SI_BAND_US)
  1032. {
  1033. BottomOfFreq=875;         
  1034.         }
  1035. else
  1036. {
  1037. BottomOfFreq=760;  
  1038. }
  1039.  /* End of modification by Beck.He 20051129-00001100-02083-G80 */
  1040. if((Info & SI_SPACE)==SI_SPACE_200KHZ){
  1041. return (BottomOfFreq + (Channel <<1 ) );
  1042. }
  1043. else if((Info & SI_SPACE)==SI_SPACE_100KHZ){
  1044. return (BottomOfFreq + Channel);
  1045. }
  1046. else{
  1047. return (BottomOfFreq + ( Channel >>1 ) );
  1048. }
  1049. }
  1050. /*******************************************************************************
  1051.  * Function:      FM_SI47XX_FreqToChan
  1052.  *
  1053.  * Parameters:    Frequency- operating frequency of FM radio
  1054.  *
  1055.  * Returns:       __u16
  1056.  *
  1057.  * Description:  Routine to translate frequency to channel value
  1058.  ******************************************************************************/
  1059. __u16 
  1060. FM_SI47XX_FreqToChan(
  1061. __u16 Frequency
  1062. )
  1063. {
  1064. __u16 Info;
  1065. __u16 BottomOfFreq;
  1066. Info=WriteRegArray[W05h*2];
  1067.  
  1068.    /* Quanta modify by Beck.He 20051129-00001100-02083-G80 */      
  1069.    if((Info & SI_BAND)==SI_BAND_US)                              
  1070.  {                                                             
  1071. BottomOfFreq=875;                                            
  1072.  }                                                             
  1073. else                                                          
  1074.  {                                                             
  1075. BottomOfFreq=760;                                           
  1076.    }                                                              
  1077.    /* End of modification by Beck.He 20051129-00001100-02083-G80 */
  1078.     
  1079. if((Info & SI_SPACE)==SI_SPACE_200KHZ){
  1080. return ((Frequency - BottomOfFreq) >>1); 
  1081. }
  1082. else if((Info & SI_SPACE)==SI_SPACE_100KHZ){
  1083. return (Frequency - BottomOfFreq) ; 
  1084. }
  1085. else{
  1086. return ((Frequency - BottomOfFreq) <<1) ; 
  1087. }
  1088. }
  1089. /*******************************************************************************
  1090.  * Function:      FM_SI47XX_Volume
  1091.  *
  1092.  * Parameters:    Direction- determine to increase volume(TURNUP) or to decrease volume(TURNDOWN)
  1093.  *    
  1094.  * Returns:       none
  1095.  *
  1096.  * Description:  Routine to control volume of FM_SI47XX
  1097.  ******************************************************************************/
  1098. void 
  1099. FM_SI47XX_Volume(
  1100. __u8 vol
  1101. )
  1102. {
  1103.     #ifdef si4703_debug
  1104.     printk(KERN_ERR "radio-si4703: set volume,n");
  1105.     #endif
  1106.     VolumeCtrl = vol/10+5;
  1107. FM_SI47XX_WriteReg(W05h,SI_RECOMMENDED_SEEKTH | BandSelect | SpacingSelect | VolumeCtrl);
  1108. }
  1109. /*******************************************************************************
  1110.  * Function:      FM_SI47XX_IncVolume
  1111.  *
  1112.  * Parameters:    none
  1113.  *    
  1114.  * Returns:       none
  1115.  *
  1116.  * Description:  Routine to increase volume of FM_SI47XX
  1117.  ******************************************************************************/
  1118. void
  1119. FM_SI47XX_IncVolume(
  1120. void
  1121. )
  1122. {
  1123. FM_SI47XX_Volume(TURNUP);
  1124. }
  1125. /*******************************************************************************
  1126.  * Function:      FM_SI47XX_DecVolume
  1127.  *
  1128.  * Parameters:    none
  1129.  *    
  1130.  * Returns:       none
  1131.  *
  1132.  * Description:  Routine to decrease volume of FM_SI47XX
  1133.  ******************************************************************************/
  1134. void
  1135. FM_SI47XX_DecVolume(
  1136. void
  1137. )
  1138. {
  1139. FM_SI47XX_Volume(TURNDOWN);
  1140. }
  1141. /*******************************************************************************
  1142.  * Function:      FM_SI47XX_MuteVolume
  1143.  *
  1144.  * Parameters:    none
  1145.  *    
  1146.  * Returns:       none
  1147.  *
  1148.  * Description:  Routine to mute volume of FM_SI47XX
  1149.  ******************************************************************************/
  1150. void
  1151. FM_SI47XX_MuteVolume(
  1152. void
  1153. )
  1154. {
  1155.     #ifdef si4703_debug
  1156.     printk(KERN_ERR "radio-si4703: mute,n");
  1157.     #endif
  1158.     FM_SI47XX_WriteReg(W02h,SI_MUTE | SI_ENABLE);
  1159. }
  1160. /*******************************************************************************
  1161.  * Function:      FM_SI47XX_DMuteVolume
  1162.  *
  1163.  * Parameters:    none
  1164.  *    
  1165.  * Returns:       none
  1166.  *
  1167.  * Description:  Routine to unmute volume of FM_SI47XX
  1168.  ******************************************************************************/
  1169. void 
  1170. FM_SI47XX_DMuteVolume(
  1171. void
  1172. )
  1173. {
  1174.     #ifdef si4703_debug
  1175.     printk(KERN_ERR "radio-si4703: unmute,n");
  1176.     #endif
  1177.     FM_SI47XX_WriteReg(W02h,SI_DMUTE | SI_ENABLE);
  1178. }