fm_main.c 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372
  1. #include <linux/kernel.h>
  2. #include <asm/uaccess.h>
  3. #include <linux/slab.h>
  4. #include <mtk_wcn_cmb_stub.h>
  5. #include "fm_main.h"
  6. #include "fm_config.h"
  7. #include "fm_err.h"
  8. /* #include "fm_cust_cfg.h" */
  9. #include "osal_typedef.h"
  10. #include "wmt_exp.h"
  11. /* fm main data structure */
  12. static struct fm *g_fm_struct;
  13. /* we must get low level interface first, when add a new chip, the main effort is this interface */
  14. static struct fm_lowlevel_ops fm_low_ops;
  15. #ifdef MT6620_FM
  16. static struct fm_lowlevel_ops MT6620fm_low_ops;
  17. #endif
  18. #ifdef MT6628_FM
  19. static struct fm_lowlevel_ops MT6628fm_low_ops;
  20. #endif
  21. #ifdef MT6627_FM
  22. static struct fm_lowlevel_ops MT6627fm_low_ops;
  23. #endif
  24. #ifdef MT6580_FM
  25. static struct fm_lowlevel_ops MT6580fm_low_ops;
  26. #endif
  27. #ifdef MT6630_FM
  28. static struct fm_lowlevel_ops MT6630fm_low_ops;
  29. #endif
  30. /* MTK FM Radio private advanced features */
  31. #if 0 /* (!defined(MT6620_FM)&&!defined(MT6628_FM)) */
  32. static struct fm_priv priv_adv;
  33. #endif
  34. /* mutex for char device ops */
  35. static struct fm_lock *fm_ops_lock;
  36. /* mutex for RDS parsing and read result */
  37. static struct fm_lock *fm_read_lock;
  38. /* for get rds block counter */
  39. static struct fm_lock *fm_rds_cnt;
  40. /* mutex for fm timer, RDS reset */
  41. static struct fm_lock *fm_timer_lock;
  42. static struct fm_lock *fm_rxtx_lock; /* protect FM RX TX mode switch */
  43. static struct fm_lock *fm_rtc_mutex; /* protect FM GPS RTC drift info */
  44. static struct fm_timer *fm_timer_sys;
  45. static fm_bool scan_stop_flag = fm_false;
  46. static struct fm_gps_rtc_info gps_rtc_info;
  47. static volatile bool g_fm_stat[3] = {
  48. fm_false, /* RX power */
  49. fm_false, /* TX power */
  50. fm_false, /* TX scan */
  51. };
  52. /* RDS reset related functions */
  53. static fm_u16 fm_cur_freq_get(void);
  54. static fm_s32 fm_cur_freq_set(fm_u16 new_freq);
  55. static enum fm_op_state fm_op_state_get(struct fm *fmp);
  56. static enum fm_op_state fm_op_state_set(struct fm *fmp, enum fm_op_state sta);
  57. static void fm_timer_func(unsigned long data);
  58. #ifdef MT6620_FM
  59. static void fmtx_timer_func(unsigned long data);
  60. #endif
  61. static void fm_enable_rds_BlerCheck(struct fm *fm);
  62. static void fm_disable_rds_BlerCheck(void);
  63. static void fm_rds_reset_work_func(unsigned long data);
  64. /* when interrupt be triggered by FM chip, fm_eint_handler will first be executed */
  65. /* then fm_eint_handler will schedule fm_eint_work_func to run */
  66. static void fm_eint_handler(void);
  67. static void fm_eint_work_func(unsigned long data);
  68. static fm_s32 fm_rds_parser(struct rds_rx_t *rds_raw, fm_s32 rds_size);
  69. static fm_s32 fm_callback_register(struct fm_lowlevel_ops *ops);
  70. static fm_s32 fm_callback_unregister(struct fm_lowlevel_ops *ops);
  71. static fm_s32 pwrdown_flow(struct fm *fm);
  72. static fm_u16 fm_cur_freq_get(void)
  73. {
  74. return g_fm_struct ? g_fm_struct->cur_freq : 0;
  75. }
  76. static fm_s32 fm_cur_freq_set(fm_u16 new_freq)
  77. {
  78. if (g_fm_struct)
  79. g_fm_struct->cur_freq = new_freq;
  80. return 0;
  81. }
  82. static enum fm_op_state fm_op_state_get(struct fm *fmp)
  83. {
  84. if (fmp) {
  85. WCN_DBG(FM_DBG | MAIN, "op state get %d\n", fmp->op_sta);
  86. return fmp->op_sta;
  87. }
  88. WCN_DBG(FM_ERR | MAIN, "op state get para error\n");
  89. return FM_STA_UNKNOWN;
  90. }
  91. static enum fm_op_state fm_op_state_set(struct fm *fmp, enum fm_op_state sta)
  92. {
  93. if (fmp && (sta < FM_STA_MAX)) {
  94. fmp->op_sta = sta;
  95. WCN_DBG(FM_DBG | MAIN, "op state set to %d\n", sta);
  96. return fmp->op_sta;
  97. }
  98. WCN_DBG(FM_ERR | MAIN, "op state set para error, %d\n", sta);
  99. return FM_STA_UNKNOWN;
  100. }
  101. enum fm_pwr_state fm_pwr_state_get(struct fm *fmp)
  102. {
  103. if (fmp) {
  104. WCN_DBG(FM_DBG | MAIN, "pwr state get %d\n", fmp->pwr_sta);
  105. return fmp->pwr_sta;
  106. }
  107. WCN_DBG(FM_ERR | MAIN, "pwr state get para error\n");
  108. return FM_PWR_MAX;
  109. }
  110. enum fm_pwr_state fm_pwr_state_set(struct fm *fmp, enum fm_pwr_state sta)
  111. {
  112. if (fmp && (sta < FM_PWR_MAX)) {
  113. fmp->pwr_sta = sta;
  114. WCN_DBG(FM_DBG | MAIN, "pwr state set to %d\n", sta);
  115. return fmp->pwr_sta;
  116. }
  117. WCN_DBG(FM_ERR | MAIN, "pwr state set para error, %d\n", sta);
  118. return FM_PWR_MAX;
  119. }
  120. fm_s32 fm_set_stat(struct fm *fmp, int which, bool stat)
  121. {
  122. fm_s32 ret = 0;
  123. if (fmp == NULL) {
  124. pr_err("%s,invalid pointer\n", __func__);
  125. return -FM_EPARA;
  126. }
  127. if (FM_LOCK(fm_ops_lock))
  128. return -FM_ELOCK;
  129. if (which < (sizeof(g_fm_stat) / sizeof(g_fm_stat[0]))) {
  130. g_fm_stat[which] = stat;
  131. WCN_DBG(FM_DBG | MAIN, "fm set stat object=%d, stat=%d\n", which, stat);
  132. } else {
  133. ret = -1;
  134. WCN_DBG(FM_ERR | MAIN, "fm set stat error, object=%d, stat=%d\n", which, stat);
  135. }
  136. FM_UNLOCK(fm_ops_lock);
  137. return ret;
  138. }
  139. fm_s32 fm_get_stat(struct fm *fmp, int which, bool *stat)
  140. {
  141. fm_s32 ret = 0;
  142. if (fmp == NULL) {
  143. pr_err("%s,invalid pointer\n", __func__);
  144. return -FM_EPARA;
  145. }
  146. if (stat == NULL) {
  147. pr_err("%s,invalid pointer\n", __func__);
  148. return -FM_EPARA;
  149. }
  150. if (FM_LOCK(fm_ops_lock))
  151. return -FM_ELOCK;
  152. if (which < (sizeof(g_fm_stat) / sizeof(g_fm_stat[0]))) {
  153. *stat = g_fm_stat[which];
  154. WCN_DBG(FM_DBG | MAIN, "fm get stat object=%d, stat=%d\n", which, *stat);
  155. } else {
  156. ret = -1;
  157. WCN_DBG(FM_ERR | MAIN, "fm get stat error, object=%d\n", which);
  158. }
  159. FM_UNLOCK(fm_ops_lock);
  160. return ret;
  161. }
  162. static volatile fm_s32 subsys_rst_state = FM_SUBSYS_RST_OFF;
  163. fm_s32 fm_sys_state_get(struct fm *fmp)
  164. {
  165. return subsys_rst_state;
  166. }
  167. fm_s32 fm_sys_state_set(struct fm *fmp, fm_s32 sta)
  168. {
  169. if ((sta >= FM_SUBSYS_RST_OFF) && (sta < FM_SUBSYS_RST_MAX)) {
  170. WCN_DBG(FM_NTC | MAIN, "sys state set from %d to %d\n", subsys_rst_state, sta);
  171. subsys_rst_state = sta;
  172. } else {
  173. WCN_DBG(FM_ERR | MAIN, "sys state set para error, %d\n", sta);
  174. }
  175. return subsys_rst_state;
  176. }
  177. fm_s32 fm_subsys_reset(struct fm *fm)
  178. {
  179. /* check if we are resetting */
  180. if (fm_sys_state_get(fm) != FM_SUBSYS_RST_OFF) {
  181. WCN_DBG(FM_NTC | MAIN, "subsys reset is ongoing\n");
  182. goto out;
  183. }
  184. if (fm == NULL) {
  185. pr_err("%s,invalid pointer\n", __func__);
  186. return -FM_EPARA;
  187. }
  188. fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rst_wk);
  189. out:
  190. return 0;
  191. }
  192. fm_s32 fm_wholechip_rst_cb(fm_s32 sta)
  193. {
  194. struct fm *fm = g_fm_struct;
  195. if (!fm)
  196. return 0;
  197. if (sta == 1) {
  198. if (fm_sys_state_get(fm) == FM_SUBSYS_RST_OFF)
  199. fm_sys_state_set(fm, FM_SUBSYS_RST_START);
  200. } else {
  201. fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rst_wk);
  202. }
  203. return 0;
  204. }
  205. fm_s32 fm_open(struct fm *fmp)
  206. {
  207. fm_s32 ret = 0;
  208. fm_s32 chipid;
  209. if (fmp == NULL) {
  210. pr_err("%s,invalid pointer\n", __func__);
  211. return -FM_EPARA;
  212. }
  213. if (FM_LOCK(fm_ops_lock))
  214. return -FM_ELOCK;
  215. /* makesure fmp->ref >= 0 */
  216. /* fmp->ref = (fmp->ref < 0) ? 0 : fmp->ref; */
  217. /* fmp->ref++; */
  218. /* if ((fmp->ref > 0) && (fmp->chipon == fm_false)) */
  219. if (fmp->chipon == fm_false) {
  220. chipid = mtk_wcn_wmt_chipid_query();
  221. WCN_DBG(FM_NTC | MAIN, "wmt chip id=0x%x\n", chipid);
  222. if (chipid == 0x6628) { /* get WCN chip ID */
  223. #ifdef MT6628_FM
  224. fm_low_ops = MT6628fm_low_ops;
  225. fmp->chip_id = 0x6628;
  226. #endif
  227. } else if (chipid == 0x6620) {
  228. #ifdef MT6620_FM
  229. fm_low_ops = MT6620fm_low_ops;
  230. fmp->chip_id = 0x6620;
  231. #endif
  232. } else if ((chipid == 0x6572) || (chipid == 0x6582) || (chipid == 0x6592)
  233. || (chipid == 0x8127) || (chipid == 0x6571) || (chipid == 0x6752)
  234. || (chipid == 0x0321) || (chipid == 0x0335) || (chipid == 0x0337)
  235. || (chipid == 0x6735) || (chipid == 0x8163) || (chipid == 0x6755)
  236. || (chipid == 0x0326)) {
  237. #ifdef MT6627_FM
  238. fm_low_ops = MT6627fm_low_ops;
  239. fmp->chip_id = 0x6627;
  240. #endif
  241. } else if (chipid == 0x6580) {
  242. #ifdef MT6580_FM
  243. fm_low_ops = MT6580fm_low_ops;
  244. fmp->chip_id = 0x6580;
  245. #endif
  246. } else if (chipid == 0x6630) {
  247. #ifdef MT6630_FM
  248. fm_low_ops = MT6630fm_low_ops;
  249. fmp->chip_id = 0x6630;
  250. #endif
  251. }
  252. /*
  253. if(fm_low_ops.bi.pwron == NULL)
  254. {
  255. WCN_DBG(FM_NTC | MAIN, "get fm_low_ops fail\n");
  256. fmp->ref--;
  257. ret = -ENODEV;
  258. goto out;
  259. }
  260. ret = fm_low_ops.bi.pwron(0);
  261. if (ret) {
  262. fmp->ref--;
  263. ret = -ENODEV;
  264. goto out;
  265. }
  266. fmp->chipon = fm_true;
  267. */
  268. fm_eint_pin_cfg(FM_EINT_PIN_EINT_MODE);
  269. fm_request_eint(fm_eint_handler);
  270. }
  271. /* out: */
  272. /* WCN_DBG(FM_NTC | MAIN, "fm->ref:%d\n", fmp->ref); */
  273. FM_UNLOCK(fm_ops_lock);
  274. return ret;
  275. }
  276. fm_s32 fm_close(struct fm *fmp)
  277. {
  278. fm_s32 ret = 0;
  279. if (fmp == NULL) {
  280. pr_err("%s,invalid pointer\n", __func__);
  281. return -FM_EPARA;
  282. }
  283. if (FM_LOCK(fm_ops_lock))
  284. return -FM_ELOCK;
  285. /*
  286. fmp->ref--;
  287. if (fmp->ref == 0) {
  288. pwrdown_flow(fmp);
  289. if (fmp->chipon == fm_true) {
  290. fm_eint_pin_cfg(FM_EINT_PIN_GPIO_MODE);
  291. fm_low_ops.bi.pwroff(0);
  292. fmp->chipon = fm_false;
  293. }
  294. }
  295. //makesure fm->ref >= 0
  296. fmp->ref = (fmp->ref < 0) ? 0 : fmp->ref;
  297. WCN_DBG(FM_NTC | MAIN, "fmp->ref:%d\n", fmp->ref);
  298. */
  299. fm_eint_pin_cfg(FM_EINT_PIN_GPIO_MODE);
  300. FM_UNLOCK(fm_ops_lock);
  301. return ret;
  302. }
  303. /*
  304. fm_s32 fm_flush(struct fm *fmp)
  305. {
  306. fm_s32 ret = 0;
  307. if (fmp == NULL) {
  308. pr_err("%s,invalid pointer\n", __func__);
  309. return -FM_EPARA;
  310. }
  311. if (FM_LOCK(fm_ops_lock)) return (-FM_ELOCK);
  312. if (FM_PWR_OFF == fm_pwr_state_get(fmp))
  313. {
  314. WCN_DBG(FM_NTC | MAIN, "should power off combo!\n");
  315. if (fmp->chipon == fm_true)
  316. {
  317. fm_low_ops.bi.pwroff(0);
  318. fmp->chipon = fm_false;
  319. }
  320. }
  321. WCN_DBG(FM_NTC | MAIN, "fm_flush done\n");
  322. FM_UNLOCK(fm_ops_lock);
  323. return ret;
  324. }
  325. */
  326. fm_s32 fm_rds_read(struct fm *fmp, fm_s8 *dst, fm_s32 len)
  327. {
  328. fm_s32 copy_len = 0, left = 0;
  329. copy_len = sizeof(rds_t);
  330. if (FM_EVENT_GET(fmp->rds_event) == FM_RDS_DATA_READY) {
  331. if (FM_LOCK(fm_read_lock))
  332. return -FM_ELOCK;
  333. left = copy_to_user((void *)dst, fmp->pstRDSData, (unsigned long)copy_len);
  334. if (left)
  335. WCN_DBG(FM_ALT | MAIN, "fm_read copy failed\n");
  336. else
  337. fmp->pstRDSData->event_status = 0x0000;
  338. WCN_DBG(FM_DBG | MAIN, "fm_read copy len:%d\n", (copy_len - left));
  339. FM_EVENT_RESET(fmp->rds_event);
  340. FM_UNLOCK(fm_read_lock);
  341. } else {
  342. /*if (FM_EVENT_WAIT(fmp->rds_event, FM_RDS_DATA_READY) == 0) {
  343. WCN_DBG(FM_DBG | MAIN, "fm_read wait ok\n");
  344. goto RESTART;
  345. } else {
  346. WCN_DBG(FM_ALT | MAIN, "fm_read wait err\n");
  347. return 0;
  348. } *//*event wait caused AP stop RDS thread and re-read RDS, which caused issue ALPS00595367 */
  349. WCN_DBG(FM_DBG | MAIN, "fm_read no event now\n");
  350. return 0;
  351. }
  352. return copy_len - left;
  353. }
  354. fm_s32 fm_powerup(struct fm *fm, struct fm_tune_parm *parm)
  355. {
  356. fm_s32 ret = 0;
  357. fm_u8 tmp_vol;
  358. if (fm_low_ops.bi.pwron == NULL) {
  359. pr_err("%s,invalid pointer\n", __func__);
  360. return -FM_EPARA;
  361. }
  362. if (fm_low_ops.bi.pwrupseq == NULL) {
  363. pr_err("%s,invalid pointer\n", __func__);
  364. return -FM_EPARA;
  365. }
  366. if (FM_LOCK(fm_ops_lock))
  367. return -FM_ELOCK;
  368. /* for normal case */
  369. if (fm_low_ops.bi.pwron == NULL) {
  370. WCN_DBG(FM_NTC | MAIN, "get fm_low_ops fail\n");
  371. ret = -ENODEV;
  372. goto out;
  373. }
  374. if (fm->chipon == fm_false) {
  375. ret = fm_low_ops.bi.pwron(0);
  376. if (ret) {
  377. ret = -ENODEV;
  378. goto out;
  379. }
  380. fm->chipon = fm_true;
  381. }
  382. if (FM_PWR_RX_ON == fm_pwr_state_get(fm)) {
  383. WCN_DBG(FM_NTC | MAIN, "already pwron!\n");
  384. goto out;
  385. } else if (FM_PWR_TX_ON == fm_pwr_state_get(fm)) {
  386. /* if Tx is on, we need pwr down TX first */
  387. WCN_DBG(FM_NTC | MAIN, "power down TX first!\n");
  388. ret = fm_powerdowntx(fm);
  389. if (ret) {
  390. WCN_DBG(FM_ERR | MAIN, "FM pwr down Tx fail!\n");
  391. return ret;
  392. }
  393. }
  394. fm_pwr_state_set(fm, FM_PWR_RX_ON);
  395. /* execute power on sequence */
  396. ret = fm_low_ops.bi.pwrupseq(&fm->chip_id, &fm->device_id);
  397. if (ret)
  398. goto out;
  399. fm_enable_eint();
  400. fm_cur_freq_set(parm->freq);
  401. parm->err = FM_SUCCESS;
  402. if (fm_low_ops.bi.low_pwr_wa)
  403. fm_low_ops.bi.low_pwr_wa(1);
  404. fm_low_ops.bi.volget(&tmp_vol);
  405. WCN_DBG(FM_DBG | MAIN, "vol=%d!!!\n", tmp_vol);
  406. /* fm_low_ops.bi.volset(0); */
  407. fm->vol = 15;
  408. if (fm_low_ops.ri.rds_bci_get) {
  409. fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct,
  410. fm_low_ops.ri.rds_bci_get(), 0);
  411. fm_timer_sys->start(fm_timer_sys);
  412. } else {
  413. WCN_DBG(FM_NTC | MAIN, "start timer fail!!!\n");
  414. }
  415. out:
  416. FM_UNLOCK(fm_ops_lock);
  417. return ret;
  418. }
  419. /*
  420. * fm_powerup_tx
  421. */
  422. fm_s32 fm_powerup_tx(struct fm *fm, struct fm_tune_parm *parm)
  423. {
  424. fm_s32 ret = 0;
  425. if (fm_low_ops.bi.pwron == NULL) {
  426. pr_err("%s,invalid pointer\n", __func__);
  427. return -FM_EPARA;
  428. }
  429. if (fm_low_ops.bi.pwrupseq_tx == NULL) {
  430. pr_err("%s,invalid pointer\n", __func__);
  431. return -FM_EPARA;
  432. }
  433. if (FM_PWR_TX_ON == fm_pwr_state_get(fm)) {
  434. WCN_DBG(FM_NTC | MAIN, "already pwron!\n");
  435. parm->err = FM_BADSTATUS;
  436. goto out;
  437. } else if (FM_PWR_RX_ON == fm_pwr_state_get(fm)) {
  438. /* if Rx is on, we need pwr down first */
  439. ret = fm_powerdown(fm, 0);
  440. if (ret) {
  441. WCN_DBG(FM_ERR | MAIN, "FM pwr down Rx fail!\n");
  442. goto out;
  443. }
  444. }
  445. if (FM_LOCK(fm_ops_lock))
  446. return -FM_ELOCK;
  447. /* for normal case */
  448. if (fm->chipon == fm_false) {
  449. fm_low_ops.bi.pwron(0);
  450. fm->chipon = fm_true;
  451. }
  452. fm_pwr_state_set(fm, FM_PWR_TX_ON);
  453. ret = fm_low_ops.bi.pwrupseq_tx();
  454. if (ret) {
  455. parm->err = FM_FAILED;
  456. fm_pwr_state_set(fm, FM_PWR_OFF);
  457. WCN_DBG(FM_ERR | MAIN, "FM pwr up Tx fail!\n");
  458. } else {
  459. parm->err = FM_SUCCESS;
  460. }
  461. fm_cur_freq_set(parm->freq);
  462. #ifdef MT6620_FM
  463. /* if(fm_low_ops.ri.rds_bci_get) */
  464. {
  465. fm_timer_sys->count = 0;
  466. fm_timer_sys->tx_pwr_ctrl_en = FM_TX_PWR_CTRL_ENABLE;
  467. fm_timer_sys->tx_rtc_ctrl_en = FM_TX_RTC_CTRL_ENABLE;
  468. fm_timer_sys->tx_desense_en = FM_TX_DESENSE_ENABLE;
  469. fm_timer_sys->init(fm_timer_sys, fmtx_timer_func, (unsigned long)g_fm_struct, FM_TIMER_TIMEOUT_MIN, 0);
  470. fm_timer_sys->start(fm_timer_sys);
  471. WCN_DBG(FM_NTC | MAIN, "start timer ok\n");
  472. }
  473. #endif
  474. out:
  475. FM_UNLOCK(fm_ops_lock);
  476. return ret;
  477. }
  478. static fm_s32 pwrdown_flow(struct fm *fm)
  479. {
  480. fm_s32 ret = 0;
  481. if (fm_low_ops.ri.rds_onoff == NULL) {
  482. pr_err("%s,invalid pointer\n", __func__);
  483. return -FM_EPARA;
  484. }
  485. if (fm_low_ops.bi.pwrdownseq == NULL) {
  486. pr_err("%s,invalid pointer\n", __func__);
  487. return -FM_EPARA;
  488. }
  489. if (FM_PWR_OFF == fm_pwr_state_get(fm)) {
  490. WCN_DBG(FM_NTC | MAIN, "FMSYS already pwroff!\n");
  491. goto out;
  492. }
  493. if (FM_PWR_RX_ON == fm_pwr_state_get(fm)) {
  494. /* Disable all interrupt */
  495. fm_disable_rds_BlerCheck();
  496. fm_low_ops.ri.rds_onoff(fm->pstRDSData, fm_false);
  497. fm_disable_eint();
  498. fm_pwr_state_set(fm, FM_PWR_OFF);
  499. /* execute power down sequence */
  500. ret = fm_low_ops.bi.pwrdownseq();
  501. if (fm_low_ops.bi.low_pwr_wa)
  502. fm_low_ops.bi.low_pwr_wa(0);
  503. WCN_DBG(FM_ALT | MAIN, "pwrdown_flow exit\n");
  504. }
  505. out:
  506. return ret;
  507. }
  508. fm_s32 fm_powerdown(struct fm *fm, int type)
  509. {
  510. fm_s32 ret = 0;
  511. if (1 == type) { /* 0: RX 1: TX */
  512. ret = fm_powerdowntx(fm);
  513. } else {
  514. if (FM_LOCK(fm_ops_lock))
  515. return -FM_ELOCK;
  516. if (FM_LOCK(fm_rxtx_lock))
  517. return -FM_ELOCK;
  518. ret = pwrdown_flow(fm);
  519. FM_UNLOCK(fm_rxtx_lock);
  520. FM_UNLOCK(fm_ops_lock);
  521. }
  522. if ((FM_PWR_OFF == fm_pwr_state_get(fm)) && (fm->chipon == fm_true)) {
  523. fm_low_ops.bi.pwroff(0);
  524. fm->chipon = fm_false;
  525. }
  526. return ret;
  527. }
  528. fm_s32 fm_powerdowntx(struct fm *fm)
  529. {
  530. fm_s32 ret = 0;
  531. if (fm_low_ops.bi.pwrdownseq_tx == NULL) {
  532. pr_err("%s,invalid pointer\n", __func__);
  533. return -FM_EPARA;
  534. }
  535. if (FM_LOCK(fm_rxtx_lock))
  536. return -FM_ELOCK;
  537. if (FM_PWR_TX_ON == fm_pwr_state_get(fm)) {
  538. #ifdef MT6620_FM
  539. if (FM_LOCK(fm_timer_lock))
  540. return -FM_ELOCK;
  541. fm_timer_sys->stop(fm_timer_sys);
  542. FM_UNLOCK(fm_timer_lock);
  543. fm_timer_sys->count = 0;
  544. fm_timer_sys->tx_pwr_ctrl_en = FM_TX_PWR_CTRL_DISABLE;
  545. fm_timer_sys->tx_rtc_ctrl_en = FM_TX_RTC_CTRL_DISABLE;
  546. fm_timer_sys->tx_desense_en = FM_TX_DESENSE_DISABLE;
  547. #endif
  548. /* fm_low_ops.ri.rds_onoff(fm->pstRDSData, fm_false); */
  549. /* execute power down sequence */
  550. ret = fm_low_ops.bi.pwrdownseq_tx();
  551. if (ret)
  552. WCN_DBG(FM_ERR | MAIN, "pwrdown tx fail\n");
  553. fm_pwr_state_set(fm, FM_PWR_OFF);
  554. WCN_DBG(FM_NTC | MAIN, "pwrdown tx ok\n");
  555. }
  556. FM_UNLOCK(fm_rxtx_lock);
  557. /* FM_UNLOCK(fm_ops_lock); */
  558. return ret;
  559. }
  560. fm_s32 fm_seek(struct fm *fm, struct fm_seek_parm *parm)
  561. {
  562. fm_s32 ret = 0;
  563. fm_u16 seekdir, space;
  564. if (fm_low_ops.bi.seek == NULL) {
  565. pr_err("%s,invalid pointer\n", __func__);
  566. return -FM_EPARA;
  567. }
  568. if (FM_LOCK(fm_ops_lock))
  569. return -FM_ELOCK;
  570. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  571. parm->err = FM_BADSTATUS;
  572. ret = -EPERM;
  573. goto out;
  574. }
  575. if (parm->space == FM_SPACE_100K) {
  576. space = 0x0002;
  577. } else if (parm->space == FM_SPACE_50K) {
  578. space = 0x0001;
  579. } else if (parm->space == FM_SPACE_200K) {
  580. space = 0x0004;
  581. } else {
  582. /* default */
  583. space = 0x0002;
  584. }
  585. if (parm->band == FM_BAND_UE) {
  586. fm->min_freq = FM_UE_FREQ_MIN;
  587. fm->max_freq = FM_UE_FREQ_MAX;
  588. } else if (parm->band == FM_BAND_JAPANW) {
  589. fm->min_freq = FM_JP_FREQ_MIN;
  590. fm->max_freq = FM_JP_FREQ_MAX;
  591. } else if (parm->band == FM_BAND_SPECIAL) {
  592. fm->min_freq = FM_RX_BAND_FREQ_L;
  593. fm->max_freq = FM_RX_BAND_FREQ_H;
  594. } else {
  595. WCN_DBG(FM_ALT | MAIN, "band:%d out of range\n", parm->band);
  596. parm->err = FM_EPARM;
  597. ret = -EPERM;
  598. goto out;
  599. }
  600. if (parm->freq < fm->min_freq || parm->freq > fm->max_freq) {
  601. WCN_DBG(FM_ALT | MAIN, "freq:%d out of range\n", parm->freq);
  602. parm->err = FM_EPARM;
  603. ret = -EPERM;
  604. goto out;
  605. }
  606. if (parm->seekdir == FM_SEEK_UP)
  607. seekdir = FM_SEEK_UP;
  608. else
  609. seekdir = FM_SEEK_DOWN;
  610. fm_op_state_set(fm, FM_STA_SEEK);
  611. /* seek successfully */
  612. if (fm_true == fm_low_ops.bi.seek(fm->min_freq, fm->max_freq, &(parm->freq), seekdir, space)) {
  613. parm->err = FM_SUCCESS;
  614. } else {
  615. parm->err = FM_SEEK_FAILED;
  616. ret = -EPERM;
  617. }
  618. if ((parm->space != FM_SPACE_50K) && (1 == fm_get_channel_space(parm->freq)))
  619. parm->freq /= 10; /* (8750 / 10) = 875 */
  620. fm_op_state_set(fm, FM_STA_PLAY);
  621. out:
  622. FM_UNLOCK(fm_ops_lock);
  623. return ret;
  624. }
  625. /***********************************************************
  626. Function: fm_tx_scan()
  627. Description: get the valid channels for fm tx function
  628. Para: fm--->fm driver global info
  629. parm--->input/output parameter
  630. Return: 0, if success; error code, if failed
  631. ***********************************************************/
  632. fm_s32 fm_tx_scan(struct fm *fm, struct fm_tx_scan_parm *parm)
  633. {
  634. fm_s32 ret = 0;
  635. fm_u16 scandir = 0;
  636. fm_u16 space = parm->space;
  637. if (fm_low_ops.bi.tx_scan == NULL) {
  638. pr_err("%s,invalid pointer\n", __func__);
  639. return -FM_EPARA;
  640. }
  641. if (FM_LOCK(fm_ops_lock))
  642. return -FM_ELOCK;
  643. if (fm->chipon != fm_true) {
  644. parm->err = FM_BADSTATUS;
  645. ret = -EPERM;
  646. WCN_DBG(FM_ERR | MAIN, "tx scan chip not on\n");
  647. goto out;
  648. }
  649. switch (parm->scandir) {
  650. case FM_TX_SCAN_UP:
  651. scandir = 0;
  652. break;
  653. case FM_TX_SCAN_DOWN:
  654. scandir = 1;
  655. break;
  656. default:
  657. scandir = 0;
  658. break;
  659. }
  660. if (parm->band == FM_BAND_UE) {
  661. fm->min_freq = FM_UE_FREQ_MIN;
  662. fm->max_freq = FM_UE_FREQ_MAX;
  663. } else if (parm->band == FM_BAND_JAPANW) {
  664. fm->min_freq = FM_JP_FREQ_MIN;
  665. fm->max_freq = FM_JP_FREQ_MAX;
  666. } else if (parm->band == FM_BAND_SPECIAL) {
  667. fm->min_freq = FM_FREQ_MIN;
  668. fm->max_freq = FM_FREQ_MAX;
  669. } else {
  670. WCN_DBG(FM_ERR | MAIN, "band:%d out of range\n", parm->band);
  671. parm->err = FM_EPARM;
  672. ret = -EPERM;
  673. goto out;
  674. }
  675. if (unlikely((parm->freq < fm->min_freq) || (parm->freq > fm->max_freq))) {
  676. parm->err = FM_EPARM;
  677. ret = -EPERM;
  678. WCN_DBG(FM_ERR | MAIN, "%s parm->freq:%d fm->min_freq: %d fm->max_freq:%d\n",
  679. __func__, parm->freq, fm->min_freq, fm->max_freq);
  680. goto out;
  681. }
  682. if (unlikely(parm->ScanTBLSize < TX_SCAN_MIN || parm->ScanTBLSize > TX_SCAN_MAX)) {
  683. parm->err = FM_EPARM;
  684. ret = -EPERM;
  685. WCN_DBG(FM_ERR | MAIN, "%s parm->ScanTBLSize:%d TX_SCAN_MIN:%d TX_SCAN_MAX:%d\n",
  686. __func__, parm->ScanTBLSize, TX_SCAN_MIN, TX_SCAN_MAX);
  687. goto out;
  688. }
  689. ret = fm_low_ops.bi.anaswitch(FM_ANA_SHORT);
  690. if (ret) {
  691. WCN_DBG(FM_ERR | MAIN, "switch to short ana failed\n");
  692. goto out;
  693. }
  694. /* do tx scan */
  695. ret = fm_low_ops.bi.tx_scan(fm->min_freq, fm->max_freq, &(parm->freq),
  696. parm->ScanTBL, &(parm->ScanTBLSize), scandir, space);
  697. if (!ret) {
  698. parm->err = FM_SUCCESS;
  699. } else {
  700. WCN_DBG(FM_ERR | MAIN, "fm_tx_scan failed\n");
  701. parm->err = FM_SCAN_FAILED;
  702. }
  703. out:
  704. FM_UNLOCK(fm_ops_lock);
  705. return ret;
  706. }
  707. fm_s32 fm_scan(struct fm *fm, struct fm_scan_parm *parm)
  708. {
  709. fm_s32 ret = 0;
  710. fm_u16 scandir = FM_SEEK_UP, space;
  711. if (fm_low_ops.bi.scan == NULL) {
  712. pr_err("%s,invalid pointer\n", __func__);
  713. return -FM_EPARA;
  714. }
  715. WCN_DBG(FM_NTC | MAIN, "fm_scan:start\n");
  716. if (FM_LOCK(fm_ops_lock))
  717. return -FM_ELOCK;
  718. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  719. parm->err = FM_BADSTATUS;
  720. ret = -EPERM;
  721. goto out;
  722. }
  723. if (parm->space == FM_SPACE_100K) {
  724. space = 0x0002;
  725. } else if (parm->space == FM_SPACE_50K) {
  726. space = 0x0001;
  727. } else if (parm->space == FM_SPACE_200K) {
  728. space = 0x0004;
  729. } else {
  730. /* default */
  731. space = 0x0002;
  732. }
  733. if (parm->band == FM_BAND_UE) {
  734. fm->min_freq = FM_UE_FREQ_MIN;
  735. fm->max_freq = FM_UE_FREQ_MAX;
  736. } else if (parm->band == FM_BAND_JAPANW) {
  737. fm->min_freq = FM_JP_FREQ_MIN;
  738. fm->max_freq = FM_JP_FREQ_MAX;
  739. } else if (parm->band == FM_BAND_SPECIAL) {
  740. fm->min_freq = FM_RX_BAND_FREQ_L;
  741. fm->max_freq = FM_RX_BAND_FREQ_H;
  742. } else {
  743. WCN_DBG(FM_ALT | MAIN, "band:%d out of range\n", parm->band);
  744. parm->err = FM_EPARM;
  745. ret = -EPERM;
  746. goto out;
  747. }
  748. fm_op_state_set(fm, FM_STA_SCAN);
  749. scan_stop_flag = fm_false;
  750. if (fm_true ==
  751. fm_low_ops.bi.scan(fm->min_freq, fm->max_freq, &(parm->freq), parm->ScanTBL,
  752. &(parm->ScanTBLSize), scandir, space)) {
  753. parm->err = FM_SUCCESS;
  754. } else {
  755. WCN_DBG(FM_ALT | MAIN, "fm_scan failed\n");
  756. parm->err = FM_SEEK_FAILED;
  757. ret = -EPERM;
  758. }
  759. fm_op_state_set(fm, FM_STA_STOP);
  760. out:
  761. FM_UNLOCK(fm_ops_lock);
  762. WCN_DBG(FM_NTC | MAIN, "fm_scan:done\n");
  763. return ret;
  764. }
  765. #define SCAN_SEG_LEN 250
  766. static struct fm_cqi cqi_buf[SCAN_SEG_LEN];
  767. fm_s32 fm_scan_new(struct fm *fm, struct fm_scan_t *parm)
  768. {
  769. fm_s32 ret = 0;
  770. fm_s32 tmp;
  771. fm_s32 cnt, seg;
  772. fm_s32 i, j;
  773. fm_s32 start_freq, end_freq;
  774. fm_u16 scan_tbl[FM_SCANTBL_SIZE]; /* need no less than the chip */
  775. fm_u16 tbl_size = FM_SCANTBL_SIZE;
  776. fm_u16 tmp_freq = 0;
  777. fm_s32 chl_cnt;
  778. fm_s32 ch_offset, step, tmp_val;
  779. fm_u16 space_idx = 0x0002;
  780. fm_s32 cqi_cnt, cqi_idx;
  781. fm_s8 *buf = (fm_s8 *) cqi_buf;
  782. if (fm_low_ops.bi.scan == NULL) {
  783. pr_err("%s,invalid pointer\n", __func__);
  784. return -FM_EPARA;
  785. }
  786. if (fm_low_ops.bi.cqi_get == NULL) {
  787. pr_err("%s,invalid pointer\n", __func__);
  788. return -FM_EPARA;
  789. }
  790. if (FM_LOCK(fm_ops_lock))
  791. return -FM_ELOCK;
  792. /* caculate channel number, get segment count */
  793. cnt = (parm->upper - parm->lower) / parm->space + 1; /* Eg, (10800 - 8750) / 5 = 411 */
  794. /* Eg, (411 / 200) + ((411 % 200) ? 1 : 0) = 2 + 1 = 3 */
  795. seg = (cnt / SCAN_SEG_LEN) + ((cnt % SCAN_SEG_LEN) ? 1 : 0);
  796. WCN_DBG(FM_NTC | MAIN, "total ch %d, seg %d\n", cnt, seg);
  797. /* alloc memory */
  798. tmp = cnt * sizeof(struct fm_ch_rssi *);
  799. if (parm->sr_size < tmp) {
  800. if (parm->sr.ch_rssi_buf) {
  801. fm_free(parm->sr.ch_rssi_buf);
  802. parm->sr.ch_rssi_buf = NULL;
  803. }
  804. parm->sr_size = tmp;
  805. }
  806. if (!parm->sr.ch_rssi_buf) {
  807. parm->sr.ch_rssi_buf = (struct fm_ch_rssi *)fm_zalloc(parm->sr_size);
  808. if (!parm->sr.ch_rssi_buf) {
  809. WCN_DBG(FM_ERR | MAIN, "scan alloc mem failed\n");
  810. parm->sr_size = 0;
  811. return -2;
  812. }
  813. }
  814. if (parm->space == 5)
  815. space_idx = 0x0001; /* 50Khz */
  816. else if (parm->space == 10)
  817. space_idx = 0x0002; /* 100Khz */
  818. else if (parm->space == 20)
  819. space_idx = 0x0004; /* 200Khz */
  820. fm_op_state_set(fm, FM_STA_SCAN);
  821. /* do scan */
  822. chl_cnt = 0;
  823. for (i = 0; (i < seg) && (fm_false == scan_stop_flag); i++) {
  824. cqi_cnt = 0;
  825. cqi_idx = 0;
  826. start_freq = parm->lower + SCAN_SEG_LEN * parm->space * i;
  827. end_freq = parm->lower + SCAN_SEG_LEN * parm->space * (i + 1) - parm->space;
  828. end_freq = (end_freq > parm->upper) ? parm->upper : end_freq;
  829. WCN_DBG(FM_NTC | MAIN, "seg %d, start %d, end %d\n", i, start_freq, end_freq);
  830. if (fm_false ==
  831. fm_low_ops.bi.scan(start_freq, end_freq, &tmp_freq, scan_tbl, &tbl_size, FM_SEEK_UP, space_idx)) {
  832. ret = -1;
  833. goto out;
  834. }
  835. /* get channel count */
  836. for (ch_offset = 0; ch_offset < FM_SCANTBL_SIZE; ch_offset++) {
  837. if (scan_tbl[ch_offset] == 0)
  838. continue;
  839. for (step = 0; step < 16; step++) {
  840. if (scan_tbl[ch_offset] & (1 << step)) {
  841. tmp_val = start_freq + (ch_offset * 16 + step) * parm->space;
  842. if (tmp_val <= end_freq) {
  843. /* record valid result channel */
  844. WCN_DBG(FM_NTC | MAIN, "freq %d\n", tmp_val);
  845. parm->sr.ch_rssi_buf[chl_cnt].freq = tmp_val;
  846. chl_cnt++;
  847. cqi_cnt++;
  848. }
  849. }
  850. }
  851. }
  852. /* get cqi */
  853. if (fm_low_ops.bi.cqi_get) {
  854. tmp = cqi_cnt;
  855. while ((cqi_cnt > 0) && (fm_false == scan_stop_flag)) {
  856. ret =
  857. fm_low_ops.bi.cqi_get(buf +
  858. (16 * sizeof(struct fm_cqi) * cqi_idx),
  859. sizeof(cqi_buf) - (16 * sizeof(struct fm_cqi) * cqi_idx));
  860. if (ret)
  861. goto out;
  862. cqi_cnt -= 16;
  863. cqi_idx++;
  864. }
  865. cqi_cnt = tmp;
  866. /* fill cqi to result buffer */
  867. for (j = 0; j < cqi_cnt; j++) {
  868. tmp = chl_cnt - cqi_cnt + j; /* target pos */
  869. parm->sr.ch_rssi_buf[tmp].freq = (fm_u16) cqi_buf[j].ch;
  870. parm->sr.ch_rssi_buf[tmp].rssi = cqi_buf[j].rssi;
  871. WCN_DBG(FM_NTC | MAIN, "idx %d, freq %d, rssi %d\n", tmp,
  872. parm->sr.ch_rssi_buf[tmp].freq, parm->sr.ch_rssi_buf[tmp].rssi);
  873. }
  874. }
  875. /* 6620 won't get rssi in scan new */
  876. /* else if(fm_low_ops.bi.rssiget) */
  877. }
  878. fm_op_state_set(fm, FM_STA_STOP);
  879. out:
  880. scan_stop_flag = fm_false;
  881. FM_UNLOCK(fm_ops_lock);
  882. parm->num = chl_cnt;
  883. return ret;
  884. }
  885. fm_s32 fm_seek_new(struct fm *fm, struct fm_seek_t *parm)
  886. {
  887. fm_s32 ret = 0;
  888. fm_s32 space_idx = 0x0002;
  889. if (fm_low_ops.bi.setfreq == NULL) {
  890. pr_err("%s,invalid pointer\n", __func__);
  891. return -FM_EPARA;
  892. }
  893. if (fm_low_ops.bi.rssiget == NULL) {
  894. pr_err("%s,invalid pointer\n", __func__);
  895. return -FM_EPARA;
  896. }
  897. if (fm_low_ops.bi.rampdown == NULL) {
  898. pr_err("%s,invalid pointer\n", __func__);
  899. return -FM_EPARA;
  900. }
  901. if (fm_low_ops.bi.seek == NULL) {
  902. pr_err("%s,invalid pointer\n", __func__);
  903. return -FM_EPARA;
  904. }
  905. if (FM_LOCK(fm_ops_lock))
  906. return -FM_ELOCK;
  907. if (parm->freq < parm->lower || parm->freq > parm->upper) {
  908. WCN_DBG(FM_ERR | MAIN, "seek start freq:%d out of range\n", parm->freq);
  909. ret = -EPERM;
  910. goto out;
  911. }
  912. /* tune to start freq */
  913. fm_low_ops.bi.rampdown();
  914. fm_low_ops.bi.setfreq(parm->freq);
  915. if (parm->space == 5)
  916. space_idx = 0x0001;
  917. else if (parm->space == 10)
  918. space_idx = 0x0002;
  919. else if (parm->space == 20)
  920. space_idx = 0x0004;
  921. fm_op_state_set(fm, FM_STA_SEEK);
  922. if (fm_false == fm_low_ops.bi.seek(parm->lower, parm->upper, &(parm->freq), parm->dir, space_idx)) {
  923. ret = -1;
  924. goto out;
  925. }
  926. /* tune to new channel */
  927. fm_low_ops.bi.setfreq(parm->freq);
  928. fm_low_ops.bi.rssiget(&parm->th);
  929. out:
  930. FM_UNLOCK(fm_ops_lock);
  931. return ret;
  932. }
  933. fm_s32 fm_tune_new(struct fm *fm, struct fm_tune_t *parm)
  934. {
  935. fm_s32 ret = 0;
  936. if (fm_low_ops.bi.mute == NULL) {
  937. pr_err("%s,invalid pointer\n", __func__);
  938. return -FM_EPARA;
  939. }
  940. if (fm_low_ops.bi.rampdown == NULL) {
  941. pr_err("%s,invalid pointer\n", __func__);
  942. return -FM_EPARA;
  943. }
  944. if (fm_low_ops.bi.setfreq == NULL) {
  945. pr_err("%s,invalid pointer\n", __func__);
  946. return -FM_EPARA;
  947. }
  948. if (FM_LOCK(fm_ops_lock))
  949. return -FM_ELOCK;
  950. WCN_DBG(FM_DBG | MAIN, "%s\n", __func__);
  951. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  952. ret = -EPERM;
  953. goto out;
  954. }
  955. if (parm->freq < parm->lower || parm->freq > parm->upper) {
  956. WCN_DBG(FM_ERR | MAIN, "tune freq:%d out of range\n", parm->freq);
  957. ret = -EPERM;
  958. goto out;
  959. }
  960. /* fm_low_ops.bi.mute(fm_true); */
  961. fm_low_ops.bi.rampdown();
  962. if (fm_cur_freq_get() != parm->freq)
  963. fm_memset(fm->pstRDSData, 0, sizeof(rds_t));
  964. fm_op_state_set(fm, FM_STA_TUNE);
  965. WCN_DBG(FM_ALT | MAIN, "tuning to %d\n", parm->freq);
  966. if (fm_false == fm_low_ops.bi.setfreq(parm->freq)) {
  967. WCN_DBG(FM_ALT | MAIN, "FM tune failed\n");
  968. ret = -EPERM;
  969. goto out;
  970. }
  971. /* fm_low_ops.bi.mute(fm_false); */
  972. fm_op_state_set(fm, FM_STA_PLAY);
  973. out:
  974. FM_UNLOCK(fm_ops_lock);
  975. return ret;
  976. }
  977. fm_s32 fm_cqi_get(struct fm *fm, fm_s32 ch_num, fm_s8 *buf, fm_s32 buf_size)
  978. {
  979. fm_s32 ret = 0;
  980. fm_s32 idx = 0;
  981. if (fm_low_ops.bi.cqi_get == NULL) {
  982. pr_err("%s,invalid pointer\n", __func__);
  983. return -FM_EPARA;
  984. }
  985. if (FM_LOCK(fm_ops_lock))
  986. return -FM_ELOCK;
  987. if (fm_true == scan_stop_flag) {
  988. WCN_DBG(FM_NTC | MAIN, "scan flow aborted, do not get CQI\n");
  989. ret = -1;
  990. goto out;
  991. }
  992. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  993. ret = -EPERM;
  994. goto out;
  995. }
  996. if (ch_num * sizeof(struct fm_cqi) > buf_size) {
  997. ret = -EPERM;
  998. goto out;
  999. }
  1000. fm_op_state_set(fm, FM_STA_SCAN);
  1001. idx = 0;
  1002. WCN_DBG(FM_NTC | MAIN, "cqi num %d\n", ch_num);
  1003. while (ch_num > 0) {
  1004. ret =
  1005. fm_low_ops.bi.cqi_get(buf + 16 * sizeof(struct fm_cqi) * idx,
  1006. buf_size - 16 * sizeof(struct fm_cqi) * idx);
  1007. if (ret)
  1008. goto out;
  1009. ch_num -= 16;
  1010. idx++;
  1011. }
  1012. fm_op_state_set(fm, FM_STA_STOP);
  1013. out:
  1014. FM_UNLOCK(fm_ops_lock);
  1015. return ret;
  1016. }
  1017. /* fm_is_dese_chan -- check if gived channel is a de-sense channel or not
  1018. * @pfm - fm driver global DS
  1019. * @freq - gived channel
  1020. * return value: 0, not a dese chan; 1, a dese chan; else error NO.
  1021. */
  1022. fm_s32 fm_is_dese_chan(struct fm *pfm, fm_u16 freq)
  1023. {
  1024. fm_s32 ret = 0;
  1025. if (pfm == NULL) {
  1026. pr_err("%s,invalid pointer\n", __func__);
  1027. return -FM_EPARA;
  1028. }
  1029. if (fm_low_ops.bi.is_dese_chan) {
  1030. if (FM_LOCK(fm_ops_lock))
  1031. return -FM_ELOCK;
  1032. ret = fm_low_ops.bi.is_dese_chan(freq);
  1033. FM_UNLOCK(fm_ops_lock);
  1034. }
  1035. return ret;
  1036. }
  1037. /* fm_is_dese_chan -- check if gived channel is a de-sense channel or not
  1038. * @pfm - fm driver global DS
  1039. * @freq - gived channel
  1040. * return value: 0, not a dese chan; 1, a dese chan; else error NO.
  1041. */
  1042. fm_s32 fm_desense_check(struct fm *pfm, fm_u16 freq, fm_s32 rssi)
  1043. {
  1044. fm_s32 ret = 0;
  1045. if (pfm == NULL) {
  1046. pr_err("%s,invalid pointer\n", __func__);
  1047. return -FM_EPARA;
  1048. }
  1049. if (fm_low_ops.bi.desense_check) {
  1050. if (FM_LOCK(fm_ops_lock))
  1051. return -FM_ELOCK;
  1052. ret = fm_low_ops.bi.desense_check(freq, rssi);
  1053. FM_UNLOCK(fm_ops_lock);
  1054. }
  1055. return ret;
  1056. }
  1057. fm_s32 fm_dump_reg(void)
  1058. {
  1059. fm_s32 ret = 0;
  1060. if (fm_low_ops.bi.dumpreg) {
  1061. if (FM_LOCK(fm_ops_lock))
  1062. return -FM_ELOCK;
  1063. ret = fm_low_ops.bi.dumpreg();
  1064. FM_UNLOCK(fm_ops_lock);
  1065. }
  1066. return ret;
  1067. }
  1068. /* fm_get_hw_info -- hw info: chip id, ECO version, DSP ROM version, Patch version
  1069. * @pfm - fm driver global DS
  1070. * @freq - target buffer
  1071. * return value: 0, success; else error NO.
  1072. */
  1073. fm_s32 fm_get_hw_info(struct fm *pfm, struct fm_hw_info *req)
  1074. {
  1075. fm_s32 ret = 0;
  1076. if (req == NULL) {
  1077. pr_err("%s,invalid pointer\n", __func__);
  1078. return -FM_EPARA;
  1079. }
  1080. /* default value for all chips */
  1081. req->chip_id = 0x000066FF;
  1082. req->eco_ver = 0x00000000;
  1083. req->rom_ver = 0x00000001;
  1084. req->patch_ver = 0x00000100;
  1085. req->reserve = 0x00000000;
  1086. /* get actual chip hw info */
  1087. if (fm_low_ops.bi.hwinfo_get) {
  1088. if (FM_LOCK(fm_ops_lock))
  1089. return -FM_ELOCK;
  1090. ret = fm_low_ops.bi.hwinfo_get(req);
  1091. FM_UNLOCK(fm_ops_lock);
  1092. }
  1093. return ret;
  1094. }
  1095. fm_s32 fm_get_aud_info(fm_audio_info_t *data)
  1096. {
  1097. if (fm_low_ops.bi.get_aud_info)
  1098. return fm_low_ops.bi.get_aud_info(data);
  1099. data->aud_path = FM_AUD_ERR;
  1100. data->i2s_info.mode = FM_I2S_MODE_ERR;
  1101. data->i2s_info.status = FM_I2S_STATE_ERR;
  1102. data->i2s_info.rate = FM_I2S_SR_ERR;
  1103. return 0;
  1104. }
  1105. /* fm_get_i2s_info -- i2s info: on/off, master/slave, sample rate
  1106. * @pfm - fm driver global DS
  1107. * @req - target buffer
  1108. * return value: 0, success; else error NO.
  1109. */
  1110. fm_s32 fm_get_i2s_info(struct fm *pfm, struct fm_i2s_info *req)
  1111. {
  1112. if (fm_low_ops.bi.i2s_get == NULL) {
  1113. pr_err("%s,invalid pointer\n", __func__);
  1114. return -FM_EPARA;
  1115. }
  1116. return fm_low_ops.bi.i2s_get(&req->status, &req->mode, &req->rate);
  1117. }
  1118. fm_s32 fm_hwscan_stop(struct fm *fm)
  1119. {
  1120. fm_s32 ret = 0;
  1121. if ((FM_STA_SCAN != fm_op_state_get(fm)) && (FM_STA_SEEK != fm_op_state_get(fm))) {
  1122. WCN_DBG(FM_WAR | MAIN, "fm isn't on scan, no need stop\n");
  1123. return ret;
  1124. }
  1125. if (fm_low_ops.bi.scanstop == NULL) {
  1126. pr_err("%s,invalid pointer\n", __func__);
  1127. return -FM_EPARA;
  1128. }
  1129. fm_low_ops.bi.scanstop();
  1130. fm_low_ops.bi.seekstop();
  1131. scan_stop_flag = fm_true;
  1132. WCN_DBG(FM_DBG | MAIN, "fm will stop scan\n");
  1133. if (FM_LOCK(fm_ops_lock))
  1134. return -FM_ELOCK;
  1135. fm_low_ops.bi.rampdown();
  1136. fm_low_ops.bi.setfreq(fm_cur_freq_get());
  1137. FM_UNLOCK(fm_ops_lock);
  1138. return ret;
  1139. }
  1140. /* fm_ana_switch -- switch antenna to long/short
  1141. * @fm - fm driver main data structure
  1142. * @antenna - 0, long; 1, short
  1143. * If success, return 0; else error code
  1144. */
  1145. fm_s32 fm_ana_switch(struct fm *fm, fm_s32 antenna)
  1146. {
  1147. fm_s32 ret = 0;
  1148. if (fm_low_ops.bi.anaswitch == NULL) {
  1149. pr_err("%s,invalid pointer\n", __func__);
  1150. return -FM_EPARA;
  1151. }
  1152. if (FM_LOCK(fm_ops_lock))
  1153. return -FM_ELOCK;
  1154. WCN_DBG(FM_DBG | MAIN, "Switching ana to %s\n", antenna ? "short" : "long");
  1155. fm->ana_type = antenna;
  1156. if ((FM_PWR_RX_ON == fm_pwr_state_get(fm)) || (FM_PWR_TX_ON == fm_pwr_state_get(fm)))
  1157. ret = fm_low_ops.bi.anaswitch(antenna);
  1158. if (ret)
  1159. WCN_DBG(FM_ALT | MAIN, "Switch ana Failed\n");
  1160. else
  1161. WCN_DBG(FM_DBG | MAIN, "Switch ana OK!\n");
  1162. FM_UNLOCK(fm_ops_lock);
  1163. return ret;
  1164. }
  1165. /* volume?[0~15] */
  1166. fm_s32 fm_setvol(struct fm *fm, fm_u32 vol)
  1167. {
  1168. fm_u8 tmp_vol;
  1169. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON)
  1170. return -EPERM;
  1171. if (fm_low_ops.bi.volset == NULL) {
  1172. pr_err("%s,invalid pointer\n", __func__);
  1173. return -FM_EPARA;
  1174. }
  1175. if (FM_LOCK(fm_ops_lock))
  1176. return -FM_ELOCK;
  1177. tmp_vol = (vol > 15) ? 15 : vol;
  1178. fm_low_ops.bi.volset(tmp_vol);
  1179. fm->vol = (fm_s32) tmp_vol;
  1180. FM_UNLOCK(fm_ops_lock);
  1181. return 0;
  1182. }
  1183. fm_s32 fm_getvol(struct fm *fm, fm_u32 *vol)
  1184. {
  1185. fm_u8 tmp_vol;
  1186. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON)
  1187. return -EPERM;
  1188. if (fm_low_ops.bi.volget == NULL) {
  1189. pr_err("%s,invalid pointer\n", __func__);
  1190. return -FM_EPARA;
  1191. }
  1192. if (FM_LOCK(fm_ops_lock))
  1193. return -FM_ELOCK;
  1194. fm_low_ops.bi.volget(&tmp_vol);
  1195. *vol = (fm_u32) tmp_vol;
  1196. FM_UNLOCK(fm_ops_lock);
  1197. return 0;
  1198. }
  1199. fm_s32 fm_mute(struct fm *fm, fm_u32 bmute)
  1200. {
  1201. fm_s32 ret = 0;
  1202. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  1203. ret = -EPERM;
  1204. return ret;
  1205. }
  1206. if (fm_low_ops.bi.mute == NULL) {
  1207. pr_err("%s,invalid pointer\n", __func__);
  1208. return -FM_EPARA;
  1209. }
  1210. if (FM_LOCK(fm_ops_lock))
  1211. return -FM_ELOCK;
  1212. if (bmute) {
  1213. ret = fm_low_ops.bi.mute(fm_true);
  1214. fm->mute = fm_true;
  1215. } else {
  1216. ret = fm_low_ops.bi.mute(fm_false);
  1217. fm->mute = fm_false;
  1218. }
  1219. FM_UNLOCK(fm_ops_lock);
  1220. return ret;
  1221. }
  1222. fm_s32 fm_getrssi(struct fm *fm, fm_s32 *rssi)
  1223. {
  1224. fm_s32 ret = 0;
  1225. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  1226. ret = -EPERM;
  1227. return ret;
  1228. }
  1229. if (fm_low_ops.bi.rssiget == NULL) {
  1230. pr_err("%s,invalid pointer\n", __func__);
  1231. return -FM_EPARA;
  1232. }
  1233. if (FM_LOCK(fm_ops_lock))
  1234. return -FM_ELOCK;
  1235. ret = fm_low_ops.bi.rssiget(rssi);
  1236. FM_UNLOCK(fm_ops_lock);
  1237. return ret;
  1238. }
  1239. fm_s32 fm_reg_read(struct fm *fm, fm_u8 addr, fm_u16 *val)
  1240. {
  1241. fm_s32 ret = 0;
  1242. if (fm_low_ops.bi.read == NULL) {
  1243. pr_err("%s,invalid pointer\n", __func__);
  1244. return -FM_EPARA;
  1245. }
  1246. if (FM_LOCK(fm_ops_lock))
  1247. return -FM_ELOCK;
  1248. ret = fm_low_ops.bi.read(addr, val);
  1249. FM_UNLOCK(fm_ops_lock);
  1250. return ret;
  1251. }
  1252. fm_s32 fm_reg_write(struct fm *fm, fm_u8 addr, fm_u16 val)
  1253. {
  1254. fm_s32 ret = 0;
  1255. if (fm_low_ops.bi.write == NULL) {
  1256. pr_err("%s,invalid pointer\n", __func__);
  1257. return -FM_EPARA;
  1258. }
  1259. if (FM_LOCK(fm_ops_lock))
  1260. return -FM_ELOCK;
  1261. ret = fm_low_ops.bi.write(addr, val);
  1262. FM_UNLOCK(fm_ops_lock);
  1263. return ret;
  1264. }
  1265. fm_s32 fm_top_read(struct fm *fm, fm_u16 addr, fm_u32 *val)
  1266. {
  1267. fm_s32 ret = 0;
  1268. if (fm_low_ops.bi.top_read == NULL) {
  1269. pr_err("%s,invalid pointer\n", __func__);
  1270. return -FM_EPARA;
  1271. }
  1272. if (FM_LOCK(fm_ops_lock))
  1273. return -FM_ELOCK;
  1274. ret = fm_low_ops.bi.top_read(addr, val);
  1275. FM_UNLOCK(fm_ops_lock);
  1276. return ret;
  1277. }
  1278. fm_s32 fm_top_write(struct fm *fm, fm_u16 addr, fm_u32 val)
  1279. {
  1280. fm_s32 ret = 0;
  1281. if (fm_low_ops.bi.top_write == NULL) {
  1282. pr_err("%s,invalid pointer\n", __func__);
  1283. return -FM_EPARA;
  1284. }
  1285. if (FM_LOCK(fm_ops_lock))
  1286. return -FM_ELOCK;
  1287. ret = fm_low_ops.bi.top_write(addr, val);
  1288. FM_UNLOCK(fm_ops_lock);
  1289. return ret;
  1290. }
  1291. fm_s32 fm_host_read(struct fm *fm, fm_u32 addr, fm_u32 *val)
  1292. {
  1293. fm_s32 ret = 0;
  1294. if (fm_low_ops.bi.host_read == NULL) {
  1295. pr_err("%s,invalid pointer\n", __func__);
  1296. return -FM_EPARA;
  1297. }
  1298. if (FM_LOCK(fm_ops_lock))
  1299. return -FM_ELOCK;
  1300. ret = fm_low_ops.bi.host_read(addr, val);
  1301. FM_UNLOCK(fm_ops_lock);
  1302. return ret;
  1303. }
  1304. fm_s32 fm_host_write(struct fm *fm, fm_u32 addr, fm_u32 val)
  1305. {
  1306. fm_s32 ret = 0;
  1307. if (fm_low_ops.bi.host_write == NULL) {
  1308. pr_err("%s,invalid pointer\n", __func__);
  1309. return -FM_EPARA;
  1310. }
  1311. if (FM_LOCK(fm_ops_lock))
  1312. return -FM_ELOCK;
  1313. ret = fm_low_ops.bi.host_write(addr, val);
  1314. FM_UNLOCK(fm_ops_lock);
  1315. return ret;
  1316. }
  1317. fm_s32 fm_chipid_get(struct fm *fm, fm_u16 *chipid)
  1318. {
  1319. if (chipid == NULL) {
  1320. pr_err("%s,invalid pointer\n", __func__);
  1321. return -FM_EPARA;
  1322. }
  1323. if (FM_LOCK(fm_ops_lock))
  1324. return -FM_ELOCK;
  1325. *chipid = fm->chip_id;
  1326. FM_UNLOCK(fm_ops_lock);
  1327. return 0;
  1328. }
  1329. fm_s32 fm_monostereo_get(struct fm *fm, fm_u16 *ms)
  1330. {
  1331. fm_s32 ret = 0;
  1332. if (fm_low_ops.bi.msget == NULL) {
  1333. pr_err("%s,invalid pointer\n", __func__);
  1334. return -FM_EPARA;
  1335. }
  1336. if (ms == NULL) {
  1337. pr_err("%s,invalid pointer\n", __func__);
  1338. return -FM_EPARA;
  1339. }
  1340. if (FM_LOCK(fm_ops_lock))
  1341. return -FM_ELOCK;
  1342. if (fm_low_ops.bi.msget(ms) == fm_false)
  1343. ret = -FM_EPARA;
  1344. FM_UNLOCK(fm_ops_lock);
  1345. return ret;
  1346. }
  1347. /*
  1348. * Force set to stero/mono mode
  1349. * @MonoStereo -- 0, auto; 1, mono
  1350. * If success, return 0; else error code
  1351. */
  1352. fm_s32 fm_monostereo_set(struct fm *fm, fm_s32 ms)
  1353. {
  1354. fm_s32 ret = 0;
  1355. if (fm_low_ops.bi.msset == NULL) {
  1356. pr_err("%s,invalid pointer\n", __func__);
  1357. return -FM_EPARA;
  1358. }
  1359. if (FM_LOCK(fm_ops_lock))
  1360. return -FM_ELOCK;
  1361. ret = fm_low_ops.bi.msset(ms);
  1362. FM_UNLOCK(fm_ops_lock);
  1363. return ret;
  1364. }
  1365. fm_s32 fm_pamd_get(struct fm *fm, fm_u16 *pamd)
  1366. {
  1367. fm_s32 ret = 0;
  1368. if (fm_low_ops.bi.pamdget == NULL) {
  1369. pr_err("%s,invalid pointer\n", __func__);
  1370. return -FM_EPARA;
  1371. }
  1372. if (pamd == NULL) {
  1373. pr_err("%s,invalid pointer\n", __func__);
  1374. return -FM_EPARA;
  1375. }
  1376. if (FM_LOCK(fm_ops_lock))
  1377. return -FM_ELOCK;
  1378. if (fm_low_ops.bi.pamdget(pamd) == fm_false)
  1379. ret = -FM_EPARA;
  1380. FM_UNLOCK(fm_ops_lock);
  1381. return ret;
  1382. }
  1383. fm_s32 fm_caparray_get(struct fm *fm, fm_s32 *ca)
  1384. {
  1385. fm_s32 ret = 0;
  1386. if (fm_low_ops.bi.caparray_get == NULL) {
  1387. pr_err("%s,invalid pointer\n", __func__);
  1388. return -FM_EPARA;
  1389. }
  1390. if (ca == NULL) {
  1391. pr_err("%s,invalid pointer\n", __func__);
  1392. return -FM_EPARA;
  1393. }
  1394. if (FM_LOCK(fm_ops_lock))
  1395. return -FM_ELOCK;
  1396. ret = fm_low_ops.bi.caparray_get(ca);
  1397. FM_UNLOCK(fm_ops_lock);
  1398. return ret;
  1399. }
  1400. fm_s32 fm_em_test(struct fm *fm, fm_u16 group, fm_u16 item, fm_u32 val)
  1401. {
  1402. fm_s32 ret = 0;
  1403. if (fm_low_ops.bi.em == NULL) {
  1404. pr_err("%s,invalid pointer\n", __func__);
  1405. return -FM_EPARA;
  1406. }
  1407. if (FM_LOCK(fm_ops_lock))
  1408. return -FM_ELOCK;
  1409. if (fm_false == fm_low_ops.bi.em(group, item, val))
  1410. ret = -FM_EPARA;
  1411. FM_UNLOCK(fm_ops_lock);
  1412. return ret;
  1413. }
  1414. fm_s32 fm_set_search_th(struct fm *fm, struct fm_search_threshold_t parm)
  1415. {
  1416. fm_s32 ret = 0;
  1417. if (fm_low_ops.bi.set_search_th == NULL) {
  1418. pr_err("%s,invalid pointer\n", __func__);
  1419. return -FM_EPARA;
  1420. }
  1421. if (FM_LOCK(fm_ops_lock))
  1422. return -FM_ELOCK;
  1423. ret = fm_low_ops.bi.set_search_th(parm.th_type, parm.th_val, parm.reserve);
  1424. FM_UNLOCK(fm_ops_lock);
  1425. return ret;
  1426. }
  1427. fm_s32 fm_rds_tx(struct fm *fm, struct fm_rds_tx_parm *parm)
  1428. {
  1429. fm_s32 ret = 0;
  1430. if (fm_low_ops.ri.rds_tx == NULL) {
  1431. pr_err("%s,invalid pointer\n", __func__);
  1432. return -FM_EPARA;
  1433. }
  1434. if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) {
  1435. parm->err = FM_BADSTATUS;
  1436. ret = -FM_EPARA;
  1437. goto out;
  1438. }
  1439. if (parm->other_rds_cnt > 29) {
  1440. parm->err = FM_EPARM;
  1441. WCN_DBG(FM_ERR | MAIN, "other_rds_cnt=%d\n", parm->other_rds_cnt);
  1442. ret = -FM_EPARA;
  1443. goto out;
  1444. }
  1445. ret = fm_low_ops.ri.rds_tx(parm->pi, parm->ps, parm->other_rds, parm->other_rds_cnt);
  1446. if (ret) {
  1447. WCN_DBG(FM_ERR | MAIN, "Rds_Tx failed!\n");
  1448. goto out;
  1449. }
  1450. /* fm_cxt->txcxt.rdsTxOn = true; */
  1451. /* fm_cxt->txcxt.pi = parm->pi; */
  1452. /* memcpy(fm_cxt->txcxt.ps, parm->ps,sizeof(parm->ps)); */
  1453. /* memcpy(fm_cxt->txcxt.other_rds, parm->other_rds,sizeof(parm->other_rds)); */
  1454. /* fm_cxt->txcxt.other_rds_cnt = parm->other_rds_cnt; */
  1455. out:
  1456. return ret;
  1457. }
  1458. fm_s32 fm_rds_onoff(struct fm *fm, fm_u16 rdson_off)
  1459. {
  1460. fm_s32 ret = 0;
  1461. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  1462. ret = -EPERM;
  1463. goto out;
  1464. }
  1465. if (fm_low_ops.ri.rds_onoff == NULL) {
  1466. pr_err("%s,invalid pointer\n", __func__);
  1467. return -FM_EPARA;
  1468. }
  1469. if (FM_LOCK(fm_ops_lock))
  1470. return -FM_ELOCK;
  1471. if (rdson_off) {
  1472. fm->rds_on = fm_true;
  1473. if (fm_low_ops.ri.rds_onoff(fm->pstRDSData, fm_true) == fm_false) {
  1474. WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_RDS_ONOFF on faield\n");
  1475. ret = -EPERM;
  1476. goto out;
  1477. }
  1478. fm_enable_rds_BlerCheck(fm);
  1479. } else {
  1480. fm->rds_on = fm_false;
  1481. fm_disable_rds_BlerCheck();
  1482. if (fm_low_ops.ri.rds_onoff(fm->pstRDSData, fm_false) == fm_false) {
  1483. WCN_DBG(FM_ALT | MAIN, "FM_IOCTL_RDS_ONOFF off faield\n");
  1484. ret = -EPERM;
  1485. };
  1486. }
  1487. out:
  1488. FM_UNLOCK(fm_ops_lock);
  1489. return ret;
  1490. }
  1491. fm_s32 fm_rds_good_bc_get(struct fm *fm, fm_u16 *gbc)
  1492. {
  1493. fm_s32 ret = 0;
  1494. if (fm_low_ops.ri.rds_gbc_get == NULL) {
  1495. pr_err("%s,invalid pointer\n", __func__);
  1496. return -FM_EPARA;
  1497. }
  1498. if (gbc == NULL) {
  1499. pr_err("%s,invalid pointer\n", __func__);
  1500. return -FM_EPARA;
  1501. }
  1502. if (FM_LOCK(fm_ops_lock))
  1503. return -FM_ELOCK;
  1504. *gbc = fm_low_ops.ri.rds_gbc_get();
  1505. FM_UNLOCK(fm_ops_lock);
  1506. return ret;
  1507. }
  1508. fm_s32 fm_rds_bad_bc_get(struct fm *fm, fm_u16 *bbc)
  1509. {
  1510. fm_s32 ret = 0;
  1511. if (fm_low_ops.ri.rds_gbc_get == NULL) {
  1512. pr_err("%s,invalid pointer\n", __func__);
  1513. return -FM_EPARA;
  1514. }
  1515. if (bbc == NULL) {
  1516. pr_err("%s,invalid pointer\n", __func__);
  1517. return -FM_EPARA;
  1518. }
  1519. if (FM_LOCK(fm_ops_lock))
  1520. return -FM_ELOCK;
  1521. *bbc = fm_low_ops.ri.rds_bbc_get();
  1522. FM_UNLOCK(fm_ops_lock);
  1523. return ret;
  1524. }
  1525. fm_s32 fm_rds_bler_ratio_get(struct fm *fm, fm_u16 *bbr)
  1526. {
  1527. fm_s32 ret = 0;
  1528. if (fm_low_ops.ri.rds_bbr_get == NULL) {
  1529. pr_err("%s,invalid pointer\n", __func__);
  1530. return -FM_EPARA;
  1531. }
  1532. if (bbr == NULL) {
  1533. pr_err("%s,invalid pointer\n", __func__);
  1534. return -FM_EPARA;
  1535. }
  1536. if (FM_LOCK(fm_ops_lock))
  1537. return -FM_ELOCK;
  1538. *bbr = (fm_u16) fm_low_ops.ri.rds_bbr_get();
  1539. FM_UNLOCK(fm_ops_lock);
  1540. return ret;
  1541. }
  1542. fm_s32 fm_rds_group_cnt_get(struct fm *fm, struct rds_group_cnt_t *dst)
  1543. {
  1544. fm_s32 ret = 0;
  1545. if (fm_low_ops.ri.rds_gc_get == NULL) {
  1546. pr_err("%s,invalid pointer\n", __func__);
  1547. return -FM_EPARA;
  1548. }
  1549. if (dst == NULL) {
  1550. pr_err("%s,invalid pointer\n", __func__);
  1551. return -FM_EPARA;
  1552. }
  1553. if (FM_LOCK(fm_rds_cnt))
  1554. return -FM_ELOCK;
  1555. ret = fm_low_ops.ri.rds_gc_get(dst, fm->pstRDSData);
  1556. FM_UNLOCK(fm_rds_cnt);
  1557. return ret;
  1558. }
  1559. fm_s32 fm_rds_group_cnt_reset(struct fm *fm)
  1560. {
  1561. fm_s32 ret = 0;
  1562. if (fm_low_ops.ri.rds_gc_reset == NULL) {
  1563. pr_err("%s,invalid pointer\n", __func__);
  1564. return -FM_EPARA;
  1565. }
  1566. if (FM_LOCK(fm_rds_cnt))
  1567. return -FM_ELOCK;
  1568. ret = fm_low_ops.ri.rds_gc_reset(fm->pstRDSData);
  1569. FM_UNLOCK(fm_rds_cnt);
  1570. return ret;
  1571. }
  1572. fm_s32 fm_rds_log_get(struct fm *fm, struct rds_rx_t *dst, fm_s32 *dst_len)
  1573. {
  1574. fm_s32 ret = 0;
  1575. if (fm_low_ops.ri.rds_log_get == NULL) {
  1576. pr_err("%s,invalid pointer\n", __func__);
  1577. return -FM_EPARA;
  1578. }
  1579. if (dst == NULL) {
  1580. pr_err("%s,invalid pointer\n", __func__);
  1581. return -FM_EPARA;
  1582. }
  1583. if (dst_len == NULL) {
  1584. pr_err("%s,invalid pointer\n", __func__);
  1585. return -FM_EPARA;
  1586. }
  1587. if (FM_LOCK(fm_read_lock))
  1588. return -FM_ELOCK;
  1589. ret = fm_low_ops.ri.rds_log_get(dst, dst_len);
  1590. FM_UNLOCK(fm_read_lock);
  1591. return ret;
  1592. }
  1593. fm_s32 fm_rds_block_cnt_reset(struct fm *fm)
  1594. {
  1595. fm_s32 ret = 0;
  1596. if (fm_low_ops.ri.rds_bc_reset == NULL) {
  1597. pr_err("%s,invalid pointer\n", __func__);
  1598. return -FM_EPARA;
  1599. }
  1600. if (FM_LOCK(fm_ops_lock))
  1601. return -FM_ELOCK;
  1602. ret = fm_low_ops.ri.rds_bc_reset();
  1603. FM_UNLOCK(fm_ops_lock);
  1604. return ret;
  1605. }
  1606. fm_s32 fm_i2s_set(struct fm *fm, fm_s32 onoff, fm_s32 mode, fm_s32 sample)
  1607. {
  1608. fm_s32 ret = 0;
  1609. if (fm_low_ops.bi.i2s_set == NULL) {
  1610. pr_err("%s,invalid pointer\n", __func__);
  1611. return -FM_EPARA;
  1612. }
  1613. if ((onoff != 0) || (onoff != 1))
  1614. onoff = 0; /* default on. */
  1615. if (FM_LOCK(fm_ops_lock))
  1616. return -FM_ELOCK;
  1617. if ((FM_PWR_RX_ON == fm_pwr_state_get(fm)) || (FM_PWR_TX_ON == fm_pwr_state_get(fm)))
  1618. ret = fm_low_ops.bi.i2s_set(onoff, mode, sample);
  1619. if (ret)
  1620. WCN_DBG(FM_ALT | MAIN, "i2s setting Failed\n");
  1621. else
  1622. WCN_DBG(FM_DBG | MAIN, "i2s setting OK!\n");
  1623. FM_UNLOCK(fm_ops_lock);
  1624. return ret;
  1625. }
  1626. /*
  1627. * fm_tune_tx
  1628. */
  1629. fm_s32 fm_tune_tx(struct fm *fm, struct fm_tune_parm *parm)
  1630. {
  1631. fm_s32 ret = 0;
  1632. if (fm_low_ops.bi.tune_tx == NULL) {
  1633. pr_err("%s,invalid pointer\n", __func__);
  1634. return -FM_EPARA;
  1635. }
  1636. if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) {
  1637. parm->err = FM_BADSTATUS;
  1638. return -EPERM;
  1639. }
  1640. if (FM_LOCK(fm_ops_lock))
  1641. return -FM_ELOCK;
  1642. WCN_DBG(FM_DBG | MAIN, "%s\n", __func__);
  1643. fm_op_state_set(fm, FM_STA_TUNE);
  1644. WCN_DBG(FM_NTC | MAIN, "Tx tune to %d\n", parm->freq);
  1645. /* tune to desired channel */
  1646. if (fm_true != fm_low_ops.bi.tune_tx(parm->freq)) {
  1647. parm->err = FM_TUNE_FAILED;
  1648. WCN_DBG(FM_ALT | MAIN, "Tx tune failed\n");
  1649. ret = -EPERM;
  1650. }
  1651. fm_op_state_set(fm, FM_STA_PLAY);
  1652. FM_UNLOCK(fm_ops_lock);
  1653. return ret;
  1654. }
  1655. /*
  1656. * fm_tune
  1657. */
  1658. fm_s32 fm_tune(struct fm *fm, struct fm_tune_parm *parm)
  1659. {
  1660. fm_s32 ret = 0;
  1661. if (fm_low_ops.bi.mute == NULL) {
  1662. pr_err("%s,invalid pointer\n", __func__);
  1663. return -FM_EPARA;
  1664. }
  1665. if (fm_low_ops.bi.rampdown == NULL) {
  1666. pr_err("%s,invalid pointer\n", __func__);
  1667. return -FM_EPARA;
  1668. }
  1669. if (fm_low_ops.bi.setfreq == NULL) {
  1670. pr_err("%s,invalid pointer\n", __func__);
  1671. return -FM_EPARA;
  1672. }
  1673. if (FM_LOCK(fm_ops_lock))
  1674. return -FM_ELOCK;
  1675. WCN_DBG(FM_DBG | MAIN, "%s\n", __func__);
  1676. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  1677. parm->err = FM_BADSTATUS;
  1678. ret = -EPERM;
  1679. goto out;
  1680. }
  1681. /* fm_low_ops.bi.mute(fm_true); */
  1682. ret = fm_low_ops.bi.rampdown();
  1683. if (ret) {
  1684. WCN_DBG(FM_ALT | MAIN, "FM ramp down failed\n");
  1685. goto out;
  1686. }
  1687. if (fm_cur_freq_get() != parm->freq)
  1688. fm_memset(fm->pstRDSData, 0, sizeof(rds_t));
  1689. #if 0 /* (!defined(MT6620_FM)&&!defined(MT6628_FM)) */
  1690. /* HILO side adjust if need */
  1691. if (priv_adv.priv_tbl.hl_dese) {
  1692. ret = priv_adv.priv_tbl.hl_dese(parm->freq, NULL);
  1693. if (ret < 0)
  1694. goto out;
  1695. WCN_DBG(FM_INF | MAIN, "HILO side %d\n", ret);
  1696. }
  1697. /* Frequency avoid adjust if need */
  1698. if (priv_adv.priv_tbl.fa_dese) {
  1699. ret = priv_adv.priv_tbl.fa_dese(parm->freq, NULL);
  1700. if (ret < 0)
  1701. goto out;
  1702. WCN_DBG(FM_INF | MAIN, "FA %d\n", ret);
  1703. }
  1704. /* MCU clock adjust if need */
  1705. if (priv_adv.priv_tbl.mcu_dese) {
  1706. ret = priv_adv.priv_tbl.mcu_dese(parm->freq, NULL);
  1707. if (ret < 0)
  1708. goto out;
  1709. WCN_DBG(FM_INF | MAIN, "MCU %d\n", ret);
  1710. }
  1711. /* GPS clock adjust if need */
  1712. if (priv_adv.priv_tbl.gps_dese) {
  1713. ret = priv_adv.priv_tbl.gps_dese(parm->freq, NULL);
  1714. if (ret < 0)
  1715. goto out;
  1716. WCN_DBG(FM_INF | MAIN, "GPS %d\n", ret);
  1717. }
  1718. #endif
  1719. fm_op_state_set(fm, FM_STA_TUNE);
  1720. WCN_DBG(FM_ALT | MAIN, "tuning to %d\n", parm->freq);
  1721. if (fm_true != fm_low_ops.bi.setfreq(parm->freq)) {
  1722. parm->err = FM_TUNE_FAILED;
  1723. WCN_DBG(FM_ALT | MAIN, "FM tune failed\n");
  1724. ret = -FM_EFW;
  1725. }
  1726. /* fm_low_ops.bi.mute(fm_false);//open for dbg */
  1727. fm_op_state_set(fm, FM_STA_PLAY);
  1728. out:
  1729. FM_UNLOCK(fm_ops_lock);
  1730. return ret;
  1731. }
  1732. /* cqi log tool entry */
  1733. fm_s32 fm_cqi_log(void)
  1734. {
  1735. fm_s32 ret = 0;
  1736. fm_u16 freq;
  1737. if (fm_low_ops.bi.cqi_log == NULL) {
  1738. pr_err("%s,invalid pointer\n", __func__);
  1739. return -FM_EPARA;
  1740. }
  1741. freq = fm_cur_freq_get();
  1742. if (0 == fm_get_channel_space(freq))
  1743. freq *= 10;
  1744. if ((freq != 10000) && (0xffffffff != g_dbg_level))
  1745. return -FM_EPARA;
  1746. if (FM_LOCK(fm_ops_lock))
  1747. return -FM_ELOCK;
  1748. ret = fm_low_ops.bi.cqi_log(8750, 10800, 2, 5);
  1749. FM_UNLOCK(fm_ops_lock);
  1750. return ret;
  1751. }
  1752. fm_s32 fm_pre_search(struct fm *fm)
  1753. {
  1754. fm_s32 ret = 0;
  1755. if (fm_low_ops.bi.pre_search == NULL) {
  1756. pr_err("%s,invalid pointer\n", __func__);
  1757. return -FM_EPARA;
  1758. }
  1759. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON)
  1760. return -FM_EPARA;
  1761. if (FM_LOCK(fm_ops_lock))
  1762. return -FM_ELOCK;
  1763. ret = fm_low_ops.bi.pre_search();
  1764. FM_UNLOCK(fm_ops_lock);
  1765. return ret;
  1766. }
  1767. fm_s32 fm_restore_search(struct fm *fm)
  1768. {
  1769. fm_s32 ret = 0;
  1770. if (fm_low_ops.bi.restore_search == NULL) {
  1771. pr_err("%s,invalid pointer\n", __func__);
  1772. return -FM_EPARA;
  1773. }
  1774. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON)
  1775. return -FM_EPARA;
  1776. if (FM_LOCK(fm_ops_lock))
  1777. return -FM_ELOCK;
  1778. ret = fm_low_ops.bi.restore_search();
  1779. FM_UNLOCK(fm_ops_lock);
  1780. return ret;
  1781. }
  1782. /*fm soft mute tune function*/
  1783. fm_s32 fm_soft_mute_tune(struct fm *fm, struct fm_softmute_tune_t *parm)
  1784. {
  1785. fm_s32 ret = 0;
  1786. if (fm_low_ops.bi.softmute_tune == NULL) {
  1787. pr_err("%s,invalid pointer\n", __func__);
  1788. return -FM_EPARA;
  1789. }
  1790. if (FM_LOCK(fm_ops_lock))
  1791. return -FM_ELOCK;
  1792. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON) {
  1793. parm->valid = fm_false;
  1794. ret = -EPERM;
  1795. goto out;
  1796. }
  1797. /* fm_low_ops.bi.mute(fm_true); */
  1798. /* fm_op_state_set(fm, FM_STA_TUNE); */
  1799. if (fm_false == fm_low_ops.bi.softmute_tune(parm->freq, &parm->rssi, &parm->valid)) {
  1800. parm->valid = fm_false;
  1801. WCN_DBG(FM_ALT | MAIN, "sm tune failed\n");
  1802. ret = -EPERM;
  1803. }
  1804. /* fm_low_ops.bi.mute(fm_false); */
  1805. out:
  1806. FM_UNLOCK(fm_ops_lock);
  1807. return ret;
  1808. }
  1809. fm_s32 fm_over_bt(struct fm *fm, fm_s32 flag)
  1810. {
  1811. fm_s32 ret = 0;
  1812. if (fm_low_ops.bi.fm_via_bt == NULL) {
  1813. pr_err("%s,invalid pointer\n", __func__);
  1814. return -FM_EPARA;
  1815. }
  1816. if (fm_pwr_state_get(fm) != FM_PWR_RX_ON)
  1817. return -EPERM;
  1818. if (FM_LOCK(fm_ops_lock))
  1819. return -FM_ELOCK;
  1820. ret = fm_low_ops.bi.fm_via_bt(flag);
  1821. if (ret)
  1822. WCN_DBG(FM_ALT | MAIN, "%s(),failed!\n", __func__);
  1823. else
  1824. fm->via_bt = flag;
  1825. WCN_DBG(FM_NTC | MAIN, "%s(),[ret=%d]!\n", __func__, ret);
  1826. FM_UNLOCK(fm_ops_lock);
  1827. return ret;
  1828. }
  1829. fm_s32 fm_tx_support(struct fm *fm, fm_s32 *support)
  1830. {
  1831. if (FM_LOCK(fm_ops_lock))
  1832. return -FM_ELOCK;
  1833. if (fm_low_ops.bi.tx_support)
  1834. fm_low_ops.bi.tx_support(support);
  1835. else
  1836. *support = 0;
  1837. WCN_DBG(FM_NTC | MAIN, "%s(),[%d]!\n", __func__, *support);
  1838. FM_UNLOCK(fm_ops_lock);
  1839. return 0;
  1840. }
  1841. fm_s32 fm_rdstx_support(struct fm *fm, fm_s32 *support)
  1842. {
  1843. if (FM_LOCK(fm_ops_lock))
  1844. return -FM_ELOCK;
  1845. if (fm_low_ops.ri.rdstx_support)
  1846. fm_low_ops.ri.rdstx_support(support);
  1847. else
  1848. *support = 0;
  1849. WCN_DBG(FM_NTC | MAIN, "support=[%d]!\n", *support);
  1850. FM_UNLOCK(fm_ops_lock);
  1851. return 0;
  1852. }
  1853. /*1:on,0:off*/
  1854. fm_s32 fm_rdstx_enable(struct fm *fm, fm_s32 enable)
  1855. {
  1856. fm_s32 ret = -1;
  1857. if (fm_low_ops.ri.rds_tx_enable == NULL) {
  1858. pr_err("%s,invalid pointer\n", __func__);
  1859. return -FM_EPARA;
  1860. }
  1861. if (fm_low_ops.ri.rds_tx_disable == NULL) {
  1862. pr_err("%s,invalid pointer\n", __func__);
  1863. return -FM_EPARA;
  1864. }
  1865. if (fm_pwr_state_get(fm) != FM_PWR_TX_ON)
  1866. return -FM_EPARA;
  1867. if (FM_LOCK(fm_ops_lock))
  1868. return -FM_ELOCK;
  1869. if (enable == 1) {
  1870. ret = fm_low_ops.ri.rds_tx_enable();
  1871. if (ret)
  1872. FM_LOG_ERR(MAIN, "rds_tx_enable fail=[%d]!\n", ret);
  1873. fm->rdstx_on = fm_true;
  1874. } else {
  1875. ret = fm_low_ops.ri.rds_tx_disable();
  1876. if (ret)
  1877. FM_LOG_ERR(MAIN, "rds_tx_disable fail=[%d]!\n", ret);
  1878. fm->rdstx_on = fm_false;
  1879. }
  1880. FM_LOG_NTC(MAIN, "rds tx enable=[%d]!\n", enable);
  1881. FM_UNLOCK(fm_ops_lock);
  1882. return 0;
  1883. }
  1884. static void fm_timer_func(unsigned long data)
  1885. {
  1886. struct fm *fm = g_fm_struct;
  1887. if (FM_LOCK(fm_timer_lock))
  1888. return;
  1889. if (fm_timer_sys->update(fm_timer_sys)) {
  1890. WCN_DBG(FM_NTC | MAIN, "timer skip\n");
  1891. goto out; /* fm timer is stopped before timeout */
  1892. }
  1893. if (fm != NULL) {
  1894. WCN_DBG(FM_NTC | MAIN, "timer:rds_wk\n");
  1895. fm->timer_wkthd->add_work(fm->timer_wkthd, fm->rds_wk);
  1896. }
  1897. out:
  1898. FM_UNLOCK(fm_timer_lock);
  1899. }
  1900. #ifdef MT6620_FM
  1901. static void fmtx_timer_func(unsigned long data)
  1902. {
  1903. struct fm *fm = g_fm_struct;
  1904. fm_s32 vco_cycle = 1;
  1905. if (FM_LOCK(fm_timer_lock))
  1906. return;
  1907. fm_timer_sys->count++;
  1908. if (fm != NULL) {
  1909. /* schedule tx pwr ctrl work if need */
  1910. if (fm->txpwrctl < 1) {
  1911. WCN_DBG(FM_WAR | MAIN, "tx power ctl time err\n");
  1912. fm->txpwrctl = FM_TX_PWR_CTRL_INVAL_MIN;
  1913. }
  1914. if ((fm_timer_sys->tx_pwr_ctrl_en == FM_TX_PWR_CTRL_ENABLE)
  1915. && (fm_timer_sys->count % fm->txpwrctl == 0)) {
  1916. WCN_DBG(FM_NTC | MAIN, "Tx timer:fm_tx_power_ctrl_work\n");
  1917. fm->timer_wkthd->add_work(fm->timer_wkthd, fm->fm_tx_power_ctrl_work);
  1918. }
  1919. /*
  1920. //schedule tx RTC ctrl work if need
  1921. if((timer->tx_rtc_ctrl_en == FM_TX_RTC_CTRL_ENABLE)&& (timer->count%FM_TX_RTC_CTRL_INTERVAL == 0)){
  1922. FM_LOG_DBG(D_TIMER,"fm_tx_rtc_ctrl_work, ticks:%d\n", jiffies_to_msecs(jiffies));
  1923. queue_work(fm->fm_timer_workqueue, &fm->fm_tx_rtc_ctrl_work);
  1924. } */
  1925. /* schedule tx desense with wifi/bt work if need */
  1926. if (fm->vcooff < 1) {
  1927. WCN_DBG(FM_WAR | MAIN, "tx vco tracking time err\n");
  1928. fm->vcooff = FM_TX_VCO_OFF_MIN;
  1929. }
  1930. vco_cycle = fm->vcooff + fm->vcoon / 1000;
  1931. if ((fm_timer_sys->tx_desense_en == FM_TX_DESENSE_ENABLE)
  1932. && (fm_timer_sys->count % vco_cycle == 0)) {
  1933. WCN_DBG(FM_NTC | MAIN, "Tx timer:fm_tx_desense_wifi_work\n");
  1934. fm->timer_wkthd->add_work(fm->timer_wkthd, fm->fm_tx_desense_wifi_work);
  1935. }
  1936. }
  1937. if (fm_timer_sys->update(fm_timer_sys)) {
  1938. WCN_DBG(FM_NTC | MAIN, "timer skip\n");
  1939. goto out; /* fm timer is stopped before timeout */
  1940. }
  1941. out:
  1942. FM_UNLOCK(fm_timer_lock);
  1943. }
  1944. #endif
  1945. static void fm_tx_power_ctrl_worker_func(unsigned long data)
  1946. {
  1947. fm_s32 ctrl = 0, ret = 0;
  1948. struct fm *fm = g_fm_struct;
  1949. WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__);
  1950. if (fm_low_ops.bi.tx_pwr_ctrl == NULL)
  1951. return;
  1952. if (FM_LOCK(fm_rxtx_lock))
  1953. return;
  1954. if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) {
  1955. WCN_DBG(FM_ERR | MAIN, "FM is not on TX mode\n");
  1956. goto out;
  1957. }
  1958. ctrl = fm->tx_pwr;
  1959. WCN_DBG(FM_NTC | MAIN, "tx pwr %ddb\n", ctrl);
  1960. ret = fm_low_ops.bi.tx_pwr_ctrl(fm_cur_freq_get(), &ctrl);
  1961. if (ret)
  1962. WCN_DBG(FM_ERR | MAIN, "tx_pwr_ctrl fail\n");
  1963. out:
  1964. FM_UNLOCK(fm_rxtx_lock);
  1965. WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__);
  1966. }
  1967. static void fm_tx_rtc_ctrl_worker_func(unsigned long data)
  1968. {
  1969. fm_s32 ret = 0;
  1970. fm_s32 ctrl = 0;
  1971. struct fm_gps_rtc_info rtcInfo;
  1972. /* struct timeval curTime; */
  1973. /* struct fm *fm = (struct fm*)fm_cb; */
  1974. unsigned long curTime = 0;
  1975. WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__);
  1976. if (FM_LOCK(fm_rtc_mutex))
  1977. return;
  1978. if (gps_rtc_info.flag == FM_GPS_RTC_INFO_NEW) {
  1979. memcpy(&rtcInfo, &gps_rtc_info, sizeof(struct fm_gps_rtc_info));
  1980. gps_rtc_info.flag = FM_GPS_RTC_INFO_OLD;
  1981. FM_UNLOCK(fm_rtc_mutex);
  1982. } else {
  1983. WCN_DBG(FM_NTC | MAIN, "there's no new rtc drift info\n");
  1984. FM_UNLOCK(fm_rtc_mutex);
  1985. goto out;
  1986. }
  1987. if (rtcInfo.age > rtcInfo.ageThd) {
  1988. WCN_DBG(FM_WAR | MAIN, "age over it's threshlod\n");
  1989. goto out;
  1990. }
  1991. if ((rtcInfo.drift <= rtcInfo.driftThd) && (rtcInfo.drift >= -rtcInfo.driftThd)) {
  1992. WCN_DBG(FM_WAR | MAIN, "drift over it's MIN threshlod\n");
  1993. goto out;
  1994. }
  1995. if (rtcInfo.drift > FM_GPS_RTC_DRIFT_MAX) {
  1996. WCN_DBG(FM_WAR | MAIN, "drift over it's +MAX threshlod\n");
  1997. rtcInfo.drift = FM_GPS_RTC_DRIFT_MAX;
  1998. goto out;
  1999. } else if (rtcInfo.drift < -FM_GPS_RTC_DRIFT_MAX) {
  2000. WCN_DBG(FM_WAR | MAIN, "drift over it's -MAX threshlod\n");
  2001. rtcInfo.drift = -FM_GPS_RTC_DRIFT_MAX;
  2002. goto out;
  2003. }
  2004. /*
  2005. //get current time
  2006. do_gettimeofday(&curTime);
  2007. if((curTime.tv_sec - rtcInfo.tv.tv_sec) > rtcInfo.tvThd.tv_sec){
  2008. FM_LOG_WAR(D_MAIN,"time diff over it's threshlod\n");
  2009. goto out;
  2010. } */
  2011. curTime = jiffies;
  2012. if (((long)curTime - (long)rtcInfo.stamp) / HZ > rtcInfo.tvThd.tv_sec) {
  2013. WCN_DBG(FM_WAR | MAIN, "time diff over it's threshlod\n");
  2014. goto out;
  2015. }
  2016. if (fm_low_ops.bi.rtc_drift_ctrl != NULL) {
  2017. ctrl = rtcInfo.drift;
  2018. WCN_DBG(FM_NTC | MAIN, "RTC_drift_ctrl[0x%08x]\n", ctrl);
  2019. ret = fm_low_ops.bi.rtc_drift_ctrl(fm_cur_freq_get(), &ctrl);
  2020. if (ret)
  2021. goto out;
  2022. }
  2023. out:
  2024. WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__);
  2025. }
  2026. static void fm_tx_desense_wifi_worker_func(unsigned long data)
  2027. {
  2028. fm_s32 ret = 0;
  2029. fm_s32 ctrl = 0;
  2030. struct fm *fm = g_fm_struct;
  2031. WCN_DBG(FM_NTC | MAIN, "+%s():\n", __func__);
  2032. if (FM_LOCK(fm_rxtx_lock))
  2033. return;
  2034. if (fm_pwr_state_get(fm) != FM_PWR_TX_ON) {
  2035. WCN_DBG(FM_ERR | MAIN, "FM is not on TX mode\n");
  2036. goto out;
  2037. }
  2038. fm_tx_rtc_ctrl_worker_func(0);
  2039. ctrl = fm->vcoon;
  2040. if (fm_low_ops.bi.tx_desense_wifi) {
  2041. WCN_DBG(FM_NTC | MAIN, "tx_desense_wifi[%d]\n", ctrl);
  2042. ret = fm_low_ops.bi.tx_desense_wifi(fm_cur_freq_get(), &ctrl);
  2043. if (ret)
  2044. WCN_DBG(FM_ERR | MAIN, "tx_desense_wifi fail\n");
  2045. }
  2046. out:
  2047. FM_UNLOCK(fm_rxtx_lock);
  2048. WCN_DBG(FM_NTC | MAIN, "-%s()\n", __func__);
  2049. }
  2050. /*
  2051. ************************************************************************************
  2052. Function: fm_get_gps_rtc_info()
  2053. Description: get GPS RTC drift info, and this function should not block
  2054. Date: 2011/04/10
  2055. Return Value: success:0, failed: error coe
  2056. ************************************************************************************
  2057. */
  2058. fm_s32 fm_get_gps_rtc_info(struct fm_gps_rtc_info *src)
  2059. {
  2060. fm_s32 ret = 0;
  2061. /* fm_s32 retry_cnt = 0; */
  2062. struct fm_gps_rtc_info *dst = &gps_rtc_info;
  2063. if (src == NULL) {
  2064. pr_err("%s,invalid pointer\n", __func__);
  2065. return -FM_EPARA;
  2066. }
  2067. if (dst == NULL) {
  2068. pr_err("%s,invalid pointer\n", __func__);
  2069. return -FM_EPARA;
  2070. }
  2071. if (src->retryCnt > 0) {
  2072. dst->retryCnt = src->retryCnt;
  2073. WCN_DBG(FM_NTC | MAIN, "%s, new [retryCnt=%d]\n", __func__, dst->retryCnt);
  2074. }
  2075. if (src->ageThd > 0) {
  2076. dst->ageThd = src->ageThd;
  2077. WCN_DBG(FM_NTC | MAIN, "%s, new [ageThd=%d]\n", __func__, dst->ageThd);
  2078. }
  2079. if (src->driftThd > 0) {
  2080. dst->driftThd = src->driftThd;
  2081. WCN_DBG(FM_NTC | MAIN, "%s, new [driftThd=%d]\n", __func__, dst->driftThd);
  2082. }
  2083. if (src->tvThd.tv_sec > 0) {
  2084. dst->tvThd.tv_sec = src->tvThd.tv_sec;
  2085. WCN_DBG(FM_NTC | MAIN, "%s, new [tvThd=%d]\n", __func__, (fm_s32) dst->tvThd.tv_sec);
  2086. }
  2087. ret = fm_rtc_mutex->trylock(fm_rtc_mutex, dst->retryCnt);
  2088. if (ret)
  2089. goto out;
  2090. dst->age = src->age;
  2091. dst->drift = src->drift;
  2092. dst->stamp = jiffies; /* get curren time stamp */
  2093. dst->flag = FM_GPS_RTC_INFO_NEW;
  2094. FM_UNLOCK(fm_rtc_mutex);
  2095. /*
  2096. //send event to info fm_tx_rtc_ctrl_work
  2097. if(timer_sys.tx_rtc_ctrl_en == FM_TX_RTC_CTRL_ENABLE){
  2098. FM_LOG_DBG(D_TIMER,"fm_tx_rtc_ctrl_work, ticks:%d\n", jiffies_to_msecs(jiffies));
  2099. queue_work(fm->fm_timer_workqueue, &fm->fm_tx_rtc_ctrl_work);
  2100. }
  2101. */
  2102. out:
  2103. return ret;
  2104. }
  2105. static void fm_enable_rds_BlerCheck(struct fm *fm)
  2106. {
  2107. if (FM_LOCK(fm_timer_lock))
  2108. return;
  2109. fm_timer_sys->start(fm_timer_sys);
  2110. FM_UNLOCK(fm_timer_lock);
  2111. FM_LOG_NTC(MAIN, "enable rds timer ok\n");
  2112. }
  2113. static void fm_disable_rds_BlerCheck(void)
  2114. {
  2115. if (FM_LOCK(fm_timer_lock))
  2116. return;
  2117. fm_timer_sys->stop(fm_timer_sys);
  2118. FM_UNLOCK(fm_timer_lock);
  2119. FM_LOG_NTC(MAIN, "stop rds timer ok\n");
  2120. }
  2121. void fm_rds_reset_work_func(unsigned long data)
  2122. {
  2123. fm_s32 ret = 0;
  2124. if (!fm_low_ops.ri.rds_blercheck)
  2125. return;
  2126. if (FM_LOCK(fm_rxtx_lock))
  2127. return;
  2128. if (FM_LOCK(fm_rds_cnt))
  2129. return;
  2130. ret = fm_low_ops.ri.rds_blercheck(g_fm_struct->pstRDSData);
  2131. WCN_DBG(FM_NTC | MAIN, "Addr_Cnt=%x\n", g_fm_struct->pstRDSData->AF_Data.Addr_Cnt);
  2132. /* check af list get,can't use event==af_list because event will clear after read rds every time */
  2133. if (g_fm_struct->pstRDSData->AF_Data.Addr_Cnt == 0xFF)
  2134. g_fm_struct->pstRDSData->event_status |= RDS_EVENT_AF;
  2135. if (!ret && g_fm_struct->pstRDSData->event_status)
  2136. FM_EVENT_SEND(g_fm_struct->rds_event, FM_RDS_DATA_READY);
  2137. WCN_DBG(FM_NTC | MAIN, "rds event check=%x\n", g_fm_struct->pstRDSData->event_status);
  2138. FM_UNLOCK(fm_rds_cnt);
  2139. FM_UNLOCK(fm_rxtx_lock);
  2140. }
  2141. void fm_subsys_reset_work_func(unsigned long data)
  2142. {
  2143. g_dbg_level = 0xffffffff;
  2144. if (FM_LOCK(fm_ops_lock))
  2145. return;
  2146. fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_START);
  2147. if (g_fm_struct->chipon == fm_false) {
  2148. WCN_DBG(FM_ALT | MAIN, "chip off no need do recover\n");
  2149. goto out;
  2150. }
  2151. /* if whole chip reset, wmt will clear fm-on-flag, and firmware turn fm to off status,
  2152. so no need turn fm off again */
  2153. if (g_fm_struct->wholechiprst == fm_false) {
  2154. fm_low_ops.bi.pwrdownseq();
  2155. /* subsystem power off */
  2156. if (fm_low_ops.bi.pwroff(0)) {
  2157. WCN_DBG(FM_ALT | MAIN, "chip off fail\n");
  2158. goto out;
  2159. }
  2160. }
  2161. /* prepare to reset */
  2162. /* wait 3s */
  2163. /* fm_low_ops.bi.msdelay(2000); */
  2164. /* subsystem power on */
  2165. if (fm_low_ops.bi.pwron(0)) {
  2166. WCN_DBG(FM_ALT | MAIN, "chip on fail\n");
  2167. goto out;
  2168. }
  2169. /* recover context */
  2170. if (g_fm_struct->chipon == fm_false) {
  2171. fm_low_ops.bi.pwroff(0);
  2172. WCN_DBG(FM_ALT | MAIN, "no need do recover\n");
  2173. goto out;
  2174. }
  2175. if (FM_PWR_RX_ON == fm_pwr_state_get(g_fm_struct)) {
  2176. fm_low_ops.bi.pwrupseq(&g_fm_struct->chip_id, &g_fm_struct->device_id);
  2177. } else {
  2178. WCN_DBG(FM_ALT | MAIN, "no need do re-powerup\n");
  2179. goto out;
  2180. }
  2181. fm_low_ops.bi.anaswitch(g_fm_struct->ana_type);
  2182. fm_low_ops.bi.setfreq(fm_cur_freq_get());
  2183. fm_low_ops.bi.volset((fm_u8) g_fm_struct->vol);
  2184. g_fm_struct->mute = 0;
  2185. fm_low_ops.bi.mute(g_fm_struct->mute);
  2186. if (fm_low_ops.ri.rds_bci_get) {
  2187. fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct, fm_low_ops.ri.rds_bci_get(),
  2188. 0);
  2189. WCN_DBG(FM_NTC | MAIN, "initial timer ok\n");
  2190. } else {
  2191. WCN_DBG(FM_NTC | MAIN, "initial timer fail!!!\n");
  2192. }
  2193. g_fm_struct->rds_on = 1;
  2194. fm_low_ops.ri.rds_onoff(g_fm_struct->pstRDSData, g_fm_struct->rds_on);
  2195. WCN_DBG(FM_ALT | MAIN, "recover done\n");
  2196. out:
  2197. fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_END);
  2198. fm_sys_state_set(g_fm_struct, FM_SUBSYS_RST_OFF);
  2199. g_fm_struct->wholechiprst = fm_true;
  2200. FM_UNLOCK(fm_ops_lock);
  2201. g_dbg_level = 0xfffffff5;
  2202. }
  2203. static void fm_eint_handler(void)
  2204. {
  2205. struct fm *fm = g_fm_struct;
  2206. WCN_DBG(FM_DBG | MAIN, "intr occur, ticks:%d\n", jiffies_to_msecs(jiffies));
  2207. if (fm != NULL)
  2208. fm->eint_wkthd->add_work(fm->eint_wkthd, fm->eint_wk);
  2209. }
  2210. static fm_s32 fm_rds_parser(struct rds_rx_t *rds_raw, fm_s32 rds_size)
  2211. {
  2212. struct fm *fm = g_fm_struct; /* (struct fm *)work->data; */
  2213. rds_t *pstRDSData = fm->pstRDSData;
  2214. if (FM_LOCK(fm_read_lock))
  2215. return -FM_ELOCK;
  2216. /* parsing RDS data */
  2217. fm_low_ops.ri.rds_parser(pstRDSData, rds_raw, rds_size, fm_cur_freq_get);
  2218. FM_UNLOCK(fm_read_lock);
  2219. if ((pstRDSData->event_status != 0x0000) && (pstRDSData->event_status != RDS_EVENT_AF_LIST)) {
  2220. WCN_DBG(FM_NTC | MAIN, "Notify user to read, [event:%04x]\n", pstRDSData->event_status);
  2221. FM_EVENT_SEND(fm->rds_event, FM_RDS_DATA_READY);
  2222. }
  2223. return 0;
  2224. }
  2225. static void fm_eint_work_func(unsigned long data)
  2226. {
  2227. fm_event_parser(fm_rds_parser);
  2228. /* re-enable eint if need */
  2229. fm_enable_eint();
  2230. }
  2231. static fm_s32 fm_callback_register(struct fm_lowlevel_ops *ops)
  2232. {
  2233. if (ops == NULL) {
  2234. pr_err("%s,invalid pointer\n", __func__);
  2235. return -FM_EPARA;
  2236. }
  2237. ops->cb.cur_freq_get = fm_cur_freq_get;
  2238. ops->cb.cur_freq_set = fm_cur_freq_set;
  2239. return 0;
  2240. }
  2241. static fm_s32 fm_callback_unregister(struct fm_lowlevel_ops *ops)
  2242. {
  2243. if (ops == NULL) {
  2244. pr_err("%s,invalid pointer\n", __func__);
  2245. return -FM_EPARA;
  2246. }
  2247. fm_memset(&ops->cb, 0, sizeof(struct fm_callback));
  2248. return 0;
  2249. }
  2250. static fm_s32 fm_para_init(struct fm *fmp)
  2251. {
  2252. if (fmp == NULL) {
  2253. pr_err("%s,invalid pointer\n", __func__);
  2254. return -FM_EPARA;
  2255. }
  2256. fmp->band = FM_BAND_SPECIAL;
  2257. fmp->min_freq = FM_RX_BAND_FREQ_L;
  2258. fmp->max_freq = FM_RX_BAND_FREQ_H;
  2259. fmp->cur_freq = 0;
  2260. return 0;
  2261. }
  2262. fm_s32 fm_cust_config_setup(fm_s8 *filename)
  2263. {
  2264. fm_s32 ret;
  2265. #if (defined(MT6620_FM) || defined(MT6628_FM) || defined(MT6627_FM) || defined(MT6630_FM) || defined(MT6580_FM))
  2266. #ifdef MT6628_FM
  2267. ret = MT6628fm_cust_config_setup(filename);
  2268. if (ret < 0)
  2269. WCN_DBG(FM_ERR | MAIN, "MT6628fm_cust_config_setup failed\n");
  2270. #endif
  2271. #ifdef MT6620_FM
  2272. ret = MT6620fm_cust_config_setup(filename);
  2273. if (ret < 0)
  2274. WCN_DBG(FM_ERR | MAIN, "MT6620fm_cust_config_setup failed\n");
  2275. #endif
  2276. #ifdef MT6627_FM
  2277. ret = MT6627fm_cust_config_setup(filename);
  2278. if (ret < 0)
  2279. WCN_DBG(FM_ERR | MAIN, "MT6627fm_cust_config_setup failed\n");
  2280. #endif
  2281. #ifdef MT6580_FM
  2282. ret = MT6580fm_cust_config_setup(filename);
  2283. if (ret < 0)
  2284. WCN_DBG(FM_ERR | MAIN, "MT6580fm_cust_config_setup failed\n");
  2285. #endif
  2286. #ifdef MT6630_FM
  2287. ret = MT6630fm_cust_config_setup(filename);
  2288. if (ret < 0)
  2289. WCN_DBG(FM_ERR | MAIN, "MT6630fm_cust_config_setup failed\n");
  2290. #endif
  2291. #else
  2292. ret = fm_cust_config(filename);
  2293. if (ret < 0)
  2294. WCN_DBG(FM_ERR | MAIN, "fm_cust_config failed\n");
  2295. #endif
  2296. return ret;
  2297. }
  2298. struct fm *fm_dev_init(fm_u32 arg)
  2299. {
  2300. fm_s32 ret = 0;
  2301. struct fm *fm = NULL;
  2302. /* if (!fm_low_ops.ri.rds_bci_get) */
  2303. /* return NULL; */
  2304. /* if (!fm_low_ops.bi.chipid_get) */
  2305. /* return NULL; */
  2306. /* alloc fm main data structure */
  2307. fm = fm_zalloc(sizeof(struct fm));
  2308. if (!fm) {
  2309. WCN_DBG(FM_ALT | MAIN, "-ENOMEM\n");
  2310. ret = -ENOMEM;
  2311. return NULL;
  2312. }
  2313. fm->ref = 0;
  2314. fm->chipon = fm_false;
  2315. fm_pwr_state_set(fm, FM_PWR_OFF);
  2316. /* fm->chip_id = fm_low_ops.bi.chipid_get(); */
  2317. /* FM Tx */
  2318. fm->vcoon = FM_TX_VCO_ON_DEFAULT;
  2319. fm->vcooff = FM_TX_VCO_OFF_DEFAULT;
  2320. fm->txpwrctl = FM_TX_PWR_CTRL_INVAL_DEFAULT;
  2321. fm->tx_pwr = FM_TX_PWR_LEVEL_MAX;
  2322. fm->wholechiprst = fm_true;
  2323. gps_rtc_info.err = 0;
  2324. gps_rtc_info.age = 0;
  2325. gps_rtc_info.drift = 0;
  2326. gps_rtc_info.tv.tv_sec = 0;
  2327. gps_rtc_info.tv.tv_usec = 0;
  2328. gps_rtc_info.ageThd = FM_GPS_RTC_AGE_TH;
  2329. gps_rtc_info.driftThd = FM_GPS_RTC_DRIFT_TH;
  2330. gps_rtc_info.tvThd.tv_sec = FM_GPS_RTC_TIME_DIFF_TH;
  2331. gps_rtc_info.retryCnt = FM_GPS_RTC_RETRY_CNT;
  2332. gps_rtc_info.flag = FM_GPS_RTC_INFO_OLD;
  2333. fm->rds_event = fm_flag_event_create("fm_rds_event");
  2334. if (!fm->rds_event) {
  2335. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for RDS event\n");
  2336. ret = -ENOMEM;
  2337. goto ERR_EXIT;
  2338. }
  2339. fm_flag_event_get(fm->rds_event);
  2340. /* alloc fm rds data structure */
  2341. fm->pstRDSData = fm_zalloc(sizeof(rds_t));
  2342. if (!fm->pstRDSData) {
  2343. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for RDS\n");
  2344. ret = -ENOMEM;
  2345. goto ERR_EXIT;
  2346. }
  2347. g_fm_struct = fm;
  2348. fm->timer_wkthd = fm_workthread_create("fm_timer_wq");
  2349. if (!fm->timer_wkthd) {
  2350. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for fm_timer_wq\n");
  2351. ret = -ENOMEM;
  2352. goto ERR_EXIT;
  2353. }
  2354. fm_workthread_get(fm->timer_wkthd);
  2355. fm->eint_wkthd = fm_workthread_create("fm_eint_wq");
  2356. if (!fm->eint_wkthd) {
  2357. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for fm_eint_wq\n");
  2358. ret = -ENOMEM;
  2359. goto ERR_EXIT;
  2360. }
  2361. fm_workthread_get(fm->eint_wkthd);
  2362. fm->eint_wk = fm_work_create("fm_eint_work");
  2363. if (!fm->eint_wk) {
  2364. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for eint_wk\n");
  2365. ret = -ENOMEM;
  2366. goto ERR_EXIT;
  2367. } else {
  2368. fm_work_get(fm->eint_wk);
  2369. fm->eint_wk->init(fm->eint_wk, fm_eint_work_func, (unsigned long)fm);
  2370. }
  2371. /* create reset work */
  2372. fm->rst_wk = fm_work_create("fm_rst_work");
  2373. if (!fm->rst_wk) {
  2374. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for rst_wk\n");
  2375. ret = -ENOMEM;
  2376. goto ERR_EXIT;
  2377. } else {
  2378. fm_work_get(fm->rst_wk);
  2379. fm->rst_wk->init(fm->rst_wk, fm_subsys_reset_work_func, (unsigned long)fm);
  2380. }
  2381. fm->rds_wk = fm_work_create("fm_rds_work");
  2382. if (!fm->rds_wk) {
  2383. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for rds_wk\n");
  2384. ret = -ENOMEM;
  2385. goto ERR_EXIT;
  2386. } else {
  2387. fm_work_get(fm->rds_wk);
  2388. fm->rds_wk->init(fm->rds_wk, fm_rds_reset_work_func, (unsigned long)fm);
  2389. }
  2390. fm->fm_tx_power_ctrl_work = fm_work_create("tx_pwr_ctl_work");
  2391. if (!fm->fm_tx_power_ctrl_work) {
  2392. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for tx_pwr_ctl_work\n");
  2393. ret = -ENOMEM;
  2394. goto ERR_EXIT;
  2395. } else {
  2396. fm_work_get(fm->fm_tx_power_ctrl_work);
  2397. fm->fm_tx_power_ctrl_work->init(fm->fm_tx_power_ctrl_work,
  2398. fm_tx_power_ctrl_worker_func, (unsigned long)fm);
  2399. }
  2400. fm->fm_tx_desense_wifi_work = fm_work_create("tx_desen_wifi_work");
  2401. if (!fm->fm_tx_desense_wifi_work) {
  2402. WCN_DBG(FM_ALT | MAIN, "-ENOMEM for tx_desen_wifi_work\n");
  2403. ret = -ENOMEM;
  2404. goto ERR_EXIT;
  2405. } else {
  2406. fm_work_get(fm->fm_tx_desense_wifi_work);
  2407. fm->fm_tx_desense_wifi_work->init(fm->fm_tx_desense_wifi_work,
  2408. fm_tx_desense_wifi_worker_func, (unsigned long)fm);
  2409. }
  2410. /* fm timer was created in fm_env_setp() */
  2411. /* fm_timer_sys->init(fm_timer_sys, fm_timer_func, (unsigned long)g_fm_struct, fm_low_ops.ri.rds_bci_get(), 0); */
  2412. /* fm_timer_sys->start(fm_timer_sys); */
  2413. /* init customer config parameter */
  2414. fm_cust_config_setup(NULL);
  2415. fm_para_init(fm);
  2416. return g_fm_struct;
  2417. ERR_EXIT:
  2418. if (fm->eint_wkthd) {
  2419. ret = fm_workthread_put(fm->eint_wkthd);
  2420. if (!ret)
  2421. fm->eint_wkthd = NULL;
  2422. }
  2423. if (fm->timer_wkthd) {
  2424. ret = fm_workthread_put(fm->timer_wkthd);
  2425. if (!ret)
  2426. fm->timer_wkthd = NULL;
  2427. }
  2428. if (fm->eint_wk) {
  2429. ret = fm_work_put(fm->eint_wk);
  2430. if (!ret)
  2431. fm->eint_wk = NULL;
  2432. }
  2433. if (fm->rds_wk) {
  2434. ret = fm_work_put(fm->rds_wk);
  2435. if (!ret)
  2436. fm->rds_wk = NULL;
  2437. }
  2438. if (fm->rst_wk) {
  2439. ret = fm_work_put(fm->rst_wk);
  2440. if (!ret)
  2441. fm->rst_wk = NULL;
  2442. }
  2443. if (fm->fm_tx_desense_wifi_work) {
  2444. ret = fm_work_put(fm->fm_tx_desense_wifi_work);
  2445. if (!ret)
  2446. fm->fm_tx_desense_wifi_work = NULL;
  2447. }
  2448. if (fm->fm_tx_power_ctrl_work) {
  2449. ret = fm_work_put(fm->fm_tx_power_ctrl_work);
  2450. if (!ret)
  2451. fm->fm_tx_power_ctrl_work = NULL;
  2452. }
  2453. if (fm->pstRDSData) {
  2454. fm_free(fm->pstRDSData);
  2455. fm->pstRDSData = NULL;
  2456. }
  2457. fm_free(fm);
  2458. g_fm_struct = NULL;
  2459. return NULL;
  2460. }
  2461. fm_s32 fm_dev_destroy(struct fm *fm)
  2462. {
  2463. fm_s32 ret = 0;
  2464. WCN_DBG(FM_DBG | MAIN, "%s\n", __func__);
  2465. fm_timer_sys->stop(fm_timer_sys);
  2466. if (!fm) {
  2467. WCN_DBG(FM_NTC | MAIN, "fm is null\n");
  2468. return -1;
  2469. }
  2470. if (fm->eint_wkthd) {
  2471. ret = fm_workthread_put(fm->eint_wkthd);
  2472. if (!ret)
  2473. fm->eint_wkthd = NULL;
  2474. }
  2475. if (fm->timer_wkthd) {
  2476. ret = fm_workthread_put(fm->timer_wkthd);
  2477. if (!ret)
  2478. fm->timer_wkthd = NULL;
  2479. }
  2480. if (fm->eint_wk) {
  2481. ret = fm_work_put(fm->eint_wk);
  2482. if (!ret)
  2483. fm->eint_wk = NULL;
  2484. }
  2485. if (fm->rds_wk) {
  2486. ret = fm_work_put(fm->rds_wk);
  2487. if (!ret)
  2488. fm->rds_wk = NULL;
  2489. }
  2490. if (fm->rst_wk) {
  2491. ret = fm_work_put(fm->rst_wk);
  2492. if (!ret)
  2493. fm->rst_wk = NULL;
  2494. }
  2495. if (fm->pstRDSData) {
  2496. fm_free(fm->pstRDSData);
  2497. fm->pstRDSData = NULL;
  2498. }
  2499. if (fm->pstRDSData) {
  2500. fm_free(fm->pstRDSData);
  2501. fm->pstRDSData = NULL;
  2502. }
  2503. fm_flag_event_put(fm->rds_event);
  2504. /* free all memory */
  2505. if (fm) {
  2506. fm_free(fm);
  2507. fm = NULL;
  2508. g_fm_struct = NULL;
  2509. }
  2510. return ret;
  2511. }
  2512. fm_s32 fm_env_setup(void)
  2513. {
  2514. fm_s32 ret = 0;
  2515. WCN_DBG(FM_NTC | MAIN, "%s\n", __func__);
  2516. #if (defined(MT6620_FM) || defined(MT6628_FM) || defined(MT6627_FM) || defined(MT6580_FM) || defined(MT6630_FM))
  2517. #ifdef MT6620_FM
  2518. /* register call back functions */
  2519. ret = fm_callback_register(&MT6620fm_low_ops);
  2520. if (ret)
  2521. return ret;
  2522. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2523. /* get low level functions */
  2524. ret = MT6620fm_low_ops_register(&MT6620fm_low_ops);
  2525. if (ret)
  2526. return ret;
  2527. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2528. /* get rds level functions */
  2529. ret = MT6620fm_rds_ops_register(&MT6620fm_low_ops);
  2530. if (ret)
  2531. return ret;
  2532. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2533. #endif
  2534. #ifdef MT6628_FM
  2535. /* register call back functions */
  2536. ret = fm_callback_register(&MT6628fm_low_ops);
  2537. if (ret)
  2538. return ret;
  2539. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2540. /* get low level functions */
  2541. ret = MT6628fm_low_ops_register(&MT6628fm_low_ops);
  2542. if (ret)
  2543. return ret;
  2544. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2545. /* get rds level functions */
  2546. ret = MT6628fm_rds_ops_register(&MT6628fm_low_ops);
  2547. if (ret)
  2548. return ret;
  2549. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2550. #endif
  2551. #ifdef MT6627_FM
  2552. /* register call back functions */
  2553. ret = fm_callback_register(&MT6627fm_low_ops);
  2554. if (ret)
  2555. return ret;
  2556. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2557. /* get low level functions */
  2558. ret = MT6627fm_low_ops_register(&MT6627fm_low_ops);
  2559. if (ret)
  2560. return ret;
  2561. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2562. /* get rds level functions */
  2563. ret = MT6627fm_rds_ops_register(&MT6627fm_low_ops);
  2564. if (ret)
  2565. return ret;
  2566. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2567. #endif
  2568. #ifdef MT6580_FM
  2569. /* register call back functions */
  2570. ret = fm_callback_register(&MT6580fm_low_ops);
  2571. if (ret)
  2572. return ret;
  2573. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2574. /* get low level functions */
  2575. ret = MT6580fm_low_ops_register(&MT6580fm_low_ops);
  2576. if (ret)
  2577. return ret;
  2578. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2579. /* get rds level functions */
  2580. ret = MT6580fm_rds_ops_register(&MT6580fm_low_ops);
  2581. if (ret)
  2582. return ret;
  2583. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2584. #endif
  2585. #ifdef MT6630_FM
  2586. /* register call back functions */
  2587. ret = fm_callback_register(&MT6630fm_low_ops);
  2588. if (ret)
  2589. return ret;
  2590. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2591. /* get low level functions */
  2592. ret = MT6630fm_low_ops_register(&MT6630fm_low_ops);
  2593. if (ret)
  2594. return ret;
  2595. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2596. /* get rds level functions */
  2597. ret = MT6630fm_rds_ops_register(&MT6630fm_low_ops);
  2598. if (ret)
  2599. return ret;
  2600. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2601. #endif
  2602. #else
  2603. /* register call back functions */
  2604. ret = fm_callback_register(&fm_low_ops);
  2605. if (ret)
  2606. return ret;
  2607. WCN_DBG(FM_NTC | MAIN, "1. fm callback registered\n");
  2608. /* get low level functions */
  2609. ret = fm_low_ops_register(&fm_low_ops);
  2610. if (ret)
  2611. return ret;
  2612. WCN_DBG(FM_NTC | MAIN, "2. fm low ops registered\n");
  2613. /* get rds level functions */
  2614. ret = fm_rds_ops_register(&fm_low_ops);
  2615. if (ret)
  2616. return ret;
  2617. WCN_DBG(FM_NTC | MAIN, "3. fm rds ops registered\n");
  2618. #endif
  2619. fm_ops_lock = fm_lock_create("ops_lock");
  2620. if (!fm_ops_lock)
  2621. return -1;
  2622. fm_read_lock = fm_lock_create("rds_read");
  2623. if (!fm_read_lock)
  2624. return -1;
  2625. fm_rds_cnt = fm_lock_create("rds_cnt");
  2626. if (!fm_rds_cnt)
  2627. return -1;
  2628. fm_timer_lock = fm_spin_lock_create("timer_lock");
  2629. if (!fm_timer_lock)
  2630. return -1;
  2631. fm_rxtx_lock = fm_lock_create("rxtx_lock");
  2632. if (!fm_rxtx_lock)
  2633. return -1;
  2634. fm_rtc_mutex = fm_lock_create("rxtx_lock");
  2635. if (!fm_rxtx_lock)
  2636. return -1;
  2637. fm_lock_get(fm_ops_lock);
  2638. fm_lock_get(fm_read_lock);
  2639. fm_lock_get(fm_rds_cnt);
  2640. fm_spin_lock_get(fm_timer_lock);
  2641. fm_lock_get(fm_rxtx_lock);
  2642. WCN_DBG(FM_NTC | MAIN, "4. fm locks created\n");
  2643. fm_timer_sys = fm_timer_create("fm_sys_timer");
  2644. if (!fm_timer_sys)
  2645. return -1;
  2646. fm_timer_get(fm_timer_sys);
  2647. WCN_DBG(FM_NTC | MAIN, "5. fm timer created\n");
  2648. ret = fm_link_setup((void *)fm_wholechip_rst_cb);
  2649. if (ret) {
  2650. WCN_DBG(FM_ERR | MAIN, "fm link setup Failed\n");
  2651. return -1;
  2652. }
  2653. return ret;
  2654. }
  2655. fm_s32 fm_env_destroy(void)
  2656. {
  2657. fm_s32 ret = 0;
  2658. WCN_DBG(FM_NTC | MAIN, "%s\n", __func__);
  2659. fm_link_release();
  2660. #if (defined(MT6620_FM) || defined(MT6628_FM) || defined(MT6627_FM) || defined(MT6580_FM) || defined(MT6630_FM))
  2661. #if defined(MT6620_FM)
  2662. /* register call back functions */
  2663. ret = fm_callback_unregister(&MT6620fm_low_ops);
  2664. if (ret)
  2665. return -1;
  2666. /* put low level functions */
  2667. ret = MT6620fm_low_ops_unregister(&MT6620fm_low_ops);
  2668. if (ret)
  2669. return -1;
  2670. /* put rds func */
  2671. ret = MT6620fm_rds_ops_unregister(&MT6620fm_low_ops);
  2672. if (ret)
  2673. return -1;
  2674. #endif
  2675. #if defined(MT6628_FM)
  2676. /* register call back functions */
  2677. ret = fm_callback_unregister(&MT6628fm_low_ops);
  2678. if (ret)
  2679. return -1;
  2680. /* put low level functions */
  2681. ret = MT6628fm_low_ops_unregister(&MT6628fm_low_ops);
  2682. if (ret)
  2683. return -1;
  2684. /* put rds func */
  2685. ret = MT6628fm_rds_ops_unregister(&MT6628fm_low_ops);
  2686. if (ret)
  2687. return -1;
  2688. #endif
  2689. #if defined(MT6627_FM)
  2690. /* register call back functions */
  2691. ret = fm_callback_unregister(&MT6627fm_low_ops);
  2692. if (ret)
  2693. return -1;
  2694. /* put low level functions */
  2695. ret = MT6627fm_low_ops_unregister(&MT6627fm_low_ops);
  2696. if (ret)
  2697. return -1;
  2698. /* put rds func */
  2699. ret = MT6627fm_rds_ops_unregister(&MT6627fm_low_ops);
  2700. if (ret)
  2701. return -1;
  2702. #endif
  2703. #if defined(MT6580_FM)
  2704. /* register call back functions */
  2705. ret = fm_callback_unregister(&MT6580fm_low_ops);
  2706. if (ret)
  2707. return -1;
  2708. /* put low level functions */
  2709. ret = MT6580fm_low_ops_unregister(&MT6580fm_low_ops);
  2710. if (ret)
  2711. return -1;
  2712. /* put rds func */
  2713. ret = MT6580fm_rds_ops_unregister(&MT6580fm_low_ops);
  2714. if (ret)
  2715. return -1;
  2716. #endif
  2717. #if defined(MT6630_FM)
  2718. /* register call back functions */
  2719. ret = fm_callback_unregister(&MT6630fm_low_ops);
  2720. if (ret)
  2721. return -1;
  2722. /* put low level functions */
  2723. ret = MT6630fm_low_ops_unregister(&MT6630fm_low_ops);
  2724. if (ret)
  2725. return -1;
  2726. /* put rds func */
  2727. ret = MT6630fm_rds_ops_unregister(&MT6630fm_low_ops);
  2728. if (ret)
  2729. return -1;
  2730. #endif
  2731. #else
  2732. /* register call back functions */
  2733. ret = fm_callback_unregister(&fm_low_ops);
  2734. if (ret)
  2735. return -1;
  2736. /* put low level functions */
  2737. ret = fm_low_ops_unregister(&fm_low_ops);
  2738. if (ret)
  2739. return -1;
  2740. /* put rds func */
  2741. ret = fm_rds_ops_unregister(&fm_low_ops);
  2742. if (ret)
  2743. return -1;
  2744. #endif
  2745. ret = fm_lock_put(fm_ops_lock);
  2746. if (!ret)
  2747. fm_ops_lock = NULL;
  2748. ret = fm_lock_put(fm_read_lock);
  2749. if (!ret)
  2750. fm_read_lock = NULL;
  2751. ret = fm_lock_put(fm_rds_cnt);
  2752. if (!ret)
  2753. fm_rds_cnt = NULL;
  2754. ret = fm_spin_lock_put(fm_timer_lock);
  2755. if (!ret)
  2756. fm_timer_lock = NULL;
  2757. ret = fm_timer_put(fm_timer_sys);
  2758. if (!ret)
  2759. fm_timer_sys = NULL;
  2760. return ret;
  2761. }
  2762. /*
  2763. * GetChannelSpace - get the spcace of gived channel
  2764. * @freq - value in 760~1080 or 7600~10800
  2765. *
  2766. * Return 0, if 760~1080; return 1, if 7600 ~ 10800, else err code < 0
  2767. */
  2768. fm_s32 fm_get_channel_space(fm_s32 freq)
  2769. {
  2770. if ((freq >= 640) && (freq <= 1080))
  2771. return 0;
  2772. else if ((freq >= 6400) && (freq <= 10800))
  2773. return 1;
  2774. else
  2775. return -1;
  2776. }