mt2063.c 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/string.h>
  5. #include <linux/videodev2.h>
  6. #include "mt2063.h"
  7. static unsigned int verbose;
  8. module_param(verbose, int, 0644);
  9. /* positive error codes used internally */
  10. /* Info: Unavoidable LO-related spur may be present in the output */
  11. #define MT2063_SPUR_PRESENT_ERR (0x00800000)
  12. /* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */
  13. #define MT2063_SPUR_CNT_MASK (0x001f0000)
  14. #define MT2063_SPUR_SHIFT (16)
  15. /* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
  16. #define MT2063_UPC_RANGE (0x04000000)
  17. /* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
  18. #define MT2063_DNC_RANGE (0x08000000)
  19. /*
  20. * Constant defining the version of the following structure
  21. * and therefore the API for this code.
  22. *
  23. * When compiling the tuner driver, the preprocessor will
  24. * check against this version number to make sure that
  25. * it matches the version that the tuner driver knows about.
  26. */
  27. /* DECT Frequency Avoidance */
  28. #define MT2063_DECT_AVOID_US_FREQS 0x00000001
  29. #define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
  30. #define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
  31. #define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
  32. enum MT2063_DECT_Avoid_Type {
  33. MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */
  34. MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */
  35. MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */
  36. MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */
  37. };
  38. #define MT2063_MAX_ZONES 48
  39. struct MT2063_ExclZone_t {
  40. u32 min_;
  41. u32 max_;
  42. struct MT2063_ExclZone_t *next_;
  43. };
  44. /*
  45. * Structure of data needed for Spur Avoidance
  46. */
  47. struct MT2063_AvoidSpursData_t {
  48. u32 f_ref;
  49. u32 f_in;
  50. u32 f_LO1;
  51. u32 f_if1_Center;
  52. u32 f_if1_Request;
  53. u32 f_if1_bw;
  54. u32 f_LO2;
  55. u32 f_out;
  56. u32 f_out_bw;
  57. u32 f_LO1_Step;
  58. u32 f_LO2_Step;
  59. u32 f_LO1_FracN_Avoid;
  60. u32 f_LO2_FracN_Avoid;
  61. u32 f_zif_bw;
  62. u32 f_min_LO_Separation;
  63. u32 maxH1;
  64. u32 maxH2;
  65. enum MT2063_DECT_Avoid_Type avoidDECT;
  66. u32 bSpurPresent;
  67. u32 bSpurAvoided;
  68. u32 nSpursFound;
  69. u32 nZones;
  70. struct MT2063_ExclZone_t *freeZones;
  71. struct MT2063_ExclZone_t *usedZones;
  72. struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
  73. };
  74. /*
  75. * Parameter for function MT2063_SetPowerMask that specifies the power down
  76. * of various sections of the MT2063.
  77. */
  78. enum MT2063_Mask_Bits {
  79. MT2063_REG_SD = 0x0040, /* Shutdown regulator */
  80. MT2063_SRO_SD = 0x0020, /* Shutdown SRO */
  81. MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */
  82. MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */
  83. MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */
  84. MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */
  85. MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */
  86. MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */
  87. MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */
  88. MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */
  89. MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */
  90. MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */
  91. MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */
  92. MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */
  93. MT2063_NONE_SD = 0x0000 /* No shutdown bits */
  94. };
  95. /*
  96. * Parameter for selecting tuner mode
  97. */
  98. enum MT2063_RCVR_MODES {
  99. MT2063_CABLE_QAM = 0, /* Digital cable */
  100. MT2063_CABLE_ANALOG, /* Analog cable */
  101. MT2063_OFFAIR_COFDM, /* Digital offair */
  102. MT2063_OFFAIR_COFDM_SAWLESS, /* Digital offair without SAW */
  103. MT2063_OFFAIR_ANALOG, /* Analog offair */
  104. MT2063_OFFAIR_8VSB, /* Analog offair */
  105. MT2063_NUM_RCVR_MODES
  106. };
  107. /*
  108. * Possible values for MT2063_DNC_OUTPUT
  109. */
  110. enum MT2063_DNC_Output_Enable {
  111. MT2063_DNC_NONE = 0,
  112. MT2063_DNC_1,
  113. MT2063_DNC_2,
  114. MT2063_DNC_BOTH
  115. };
  116. /*
  117. ** Two-wire serial bus subaddresses of the tuner registers.
  118. ** Also known as the tuner's register addresses.
  119. */
  120. enum MT2063_Register_Offsets {
  121. MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */
  122. MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */
  123. MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */
  124. MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */
  125. MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */
  126. MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */
  127. MT2063_REG_RSVD_06, /* 0x06: Reserved */
  128. MT2063_REG_LO_STATUS, /* 0x07: LO Status */
  129. MT2063_REG_FIFFC, /* 0x08: FIFF Center */
  130. MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */
  131. MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */
  132. MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */
  133. MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */
  134. MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */
  135. MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */
  136. MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */
  137. MT2063_REG_RSVD_10, /* 0x10: Reserved */
  138. MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */
  139. MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */
  140. MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */
  141. MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */
  142. MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */
  143. MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */
  144. MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */
  145. MT2063_REG_RF_OV, /* 0x18: RF Attn Override */
  146. MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */
  147. MT2063_REG_LNA_TGT, /* 0x1A: Reserved */
  148. MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */
  149. MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */
  150. MT2063_REG_RSVD_1D, /* 0x1D: Reserved */
  151. MT2063_REG_RSVD_1E, /* 0x1E: Reserved */
  152. MT2063_REG_RSVD_1F, /* 0x1F: Reserved */
  153. MT2063_REG_RSVD_20, /* 0x20: Reserved */
  154. MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */
  155. MT2063_REG_RSVD_22, /* 0x22: Reserved */
  156. MT2063_REG_RSVD_23, /* 0x23: Reserved */
  157. MT2063_REG_RSVD_24, /* 0x24: Reserved */
  158. MT2063_REG_RSVD_25, /* 0x25: Reserved */
  159. MT2063_REG_RSVD_26, /* 0x26: Reserved */
  160. MT2063_REG_RSVD_27, /* 0x27: Reserved */
  161. MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */
  162. MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */
  163. MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */
  164. MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */
  165. MT2063_REG_CTRL_2C, /* 0x2C: Reserved */
  166. MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */
  167. MT2063_REG_RSVD_2E, /* 0x2E: Reserved */
  168. MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */
  169. MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */
  170. MT2063_REG_RSVD_31, /* 0x31: Reserved */
  171. MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */
  172. MT2063_REG_RSVD_33, /* 0x33: Reserved */
  173. MT2063_REG_RSVD_34, /* 0x34: Reserved */
  174. MT2063_REG_RSVD_35, /* 0x35: Reserved */
  175. MT2063_REG_RSVD_36, /* 0x36: Reserved */
  176. MT2063_REG_RSVD_37, /* 0x37: Reserved */
  177. MT2063_REG_RSVD_38, /* 0x38: Reserved */
  178. MT2063_REG_RSVD_39, /* 0x39: Reserved */
  179. MT2063_REG_RSVD_3A, /* 0x3A: Reserved */
  180. MT2063_REG_RSVD_3B, /* 0x3B: Reserved */
  181. MT2063_REG_RSVD_3C, /* 0x3C: Reserved */
  182. MT2063_REG_END_REGS
  183. };
  184. struct mt2063_state {
  185. struct i2c_adapter *i2c;
  186. const struct mt2063_config *config;
  187. struct dvb_tuner_ops ops;
  188. struct dvb_frontend *frontend;
  189. struct tuner_state status;
  190. u32 frequency;
  191. u32 srate;
  192. u32 bandwidth;
  193. u32 reference;
  194. u32 tuner_id;
  195. struct MT2063_AvoidSpursData_t AS_Data;
  196. u32 f_IF1_actual;
  197. u32 rcvr_mode;
  198. u32 ctfilt_sw;
  199. u32 CTFiltMax[31];
  200. u32 num_regs;
  201. u8 reg[MT2063_REG_END_REGS];
  202. };
  203. /*
  204. * mt2063_write - Write data into the I2C bus
  205. */
  206. static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
  207. {
  208. struct dvb_frontend *fe = state->frontend;
  209. int ret;
  210. u8 buf[60];
  211. struct i2c_msg msg = {
  212. .addr = state->config->tuner_address,
  213. .flags = 0,
  214. .buf = buf,
  215. .len = len + 1
  216. };
  217. msg.buf[0] = reg;
  218. memcpy(msg.buf + 1, data, len);
  219. if (fe->ops.i2c_gate_ctrl)
  220. fe->ops.i2c_gate_ctrl(fe, 1);
  221. ret = i2c_transfer(state->i2c, &msg, 1);
  222. if (fe->ops.i2c_gate_ctrl)
  223. fe->ops.i2c_gate_ctrl(fe, 0);
  224. if (ret < 0)
  225. printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
  226. return ret;
  227. }
  228. /*
  229. * mt2063_write - Write register data into the I2C bus, caching the value
  230. */
  231. static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
  232. {
  233. u32 status;
  234. if (reg >= MT2063_REG_END_REGS)
  235. return -ERANGE;
  236. status = mt2063_write(state, reg, &val, 1);
  237. if (status < 0)
  238. return status;
  239. state->reg[reg] = val;
  240. return 0;
  241. }
  242. /*
  243. * mt2063_read - Read data from the I2C bus
  244. */
  245. static u32 mt2063_read(struct mt2063_state *state,
  246. u8 subAddress, u8 *pData, u32 cnt)
  247. {
  248. u32 status = 0; /* Status to be returned */
  249. struct dvb_frontend *fe = state->frontend;
  250. u32 i = 0;
  251. if (fe->ops.i2c_gate_ctrl)
  252. fe->ops.i2c_gate_ctrl(fe, 1);
  253. for (i = 0; i < cnt; i++) {
  254. int ret;
  255. u8 b0[] = { subAddress + i };
  256. struct i2c_msg msg[] = {
  257. {
  258. .addr = state->config->tuner_address,
  259. .flags = I2C_M_RD,
  260. .buf = b0,
  261. .len = 1
  262. }, {
  263. .addr = state->config->tuner_address,
  264. .flags = I2C_M_RD,
  265. .buf = pData + 1,
  266. .len = 1
  267. }
  268. };
  269. ret = i2c_transfer(state->i2c, msg, 2);
  270. if (ret < 0)
  271. break;
  272. }
  273. if (fe->ops.i2c_gate_ctrl)
  274. fe->ops.i2c_gate_ctrl(fe, 0);
  275. return status;
  276. }
  277. /*
  278. * FIXME: Is this really needed?
  279. */
  280. static int MT2063_Sleep(struct dvb_frontend *fe)
  281. {
  282. /*
  283. ** ToDo: Add code here to implement a OS blocking
  284. ** for a period of "nMinDelayTime" milliseconds.
  285. */
  286. msleep(10);
  287. return 0;
  288. }
  289. /*
  290. * Microtune spur avoidance
  291. */
  292. /* Implement ceiling, floor functions. */
  293. #define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
  294. #define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
  295. struct MT2063_FIFZone_t {
  296. s32 min_;
  297. s32 max_;
  298. };
  299. static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
  300. *pAS_Info,
  301. struct MT2063_ExclZone_t *pPrevNode)
  302. {
  303. struct MT2063_ExclZone_t *pNode;
  304. /* Check for a node in the free list */
  305. if (pAS_Info->freeZones != NULL) {
  306. /* Use one from the free list */
  307. pNode = pAS_Info->freeZones;
  308. pAS_Info->freeZones = pNode->next_;
  309. } else {
  310. /* Grab a node from the array */
  311. pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
  312. }
  313. if (pPrevNode != NULL) {
  314. pNode->next_ = pPrevNode->next_;
  315. pPrevNode->next_ = pNode;
  316. } else { /* insert at the beginning of the list */
  317. pNode->next_ = pAS_Info->usedZones;
  318. pAS_Info->usedZones = pNode;
  319. }
  320. pAS_Info->nZones++;
  321. return pNode;
  322. }
  323. static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
  324. *pAS_Info,
  325. struct MT2063_ExclZone_t *pPrevNode,
  326. struct MT2063_ExclZone_t
  327. *pNodeToRemove)
  328. {
  329. struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
  330. /* Make previous node point to the subsequent node */
  331. if (pPrevNode != NULL)
  332. pPrevNode->next_ = pNext;
  333. /* Add pNodeToRemove to the beginning of the freeZones */
  334. pNodeToRemove->next_ = pAS_Info->freeZones;
  335. pAS_Info->freeZones = pNodeToRemove;
  336. /* Decrement node count */
  337. pAS_Info->nZones--;
  338. return pNext;
  339. }
  340. /*****************************************************************************
  341. **
  342. ** Name: MT_AddExclZone
  343. **
  344. ** Description: Add (and merge) an exclusion zone into the list.
  345. ** If the range (f_min, f_max) is totally outside the
  346. ** 1st IF BW, ignore the entry.
  347. ** If the range (f_min, f_max) is negative, ignore the entry.
  348. **
  349. ** Revision History:
  350. **
  351. ** SCR Date Author Description
  352. ** -------------------------------------------------------------------------
  353. ** 103 01-31-2005 DAD Ver 1.14: In MT_AddExclZone(), if the range
  354. ** (f_min, f_max) < 0, ignore the entry.
  355. **
  356. *****************************************************************************/
  357. static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
  358. u32 f_min, u32 f_max)
  359. {
  360. struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
  361. struct MT2063_ExclZone_t *pPrev = NULL;
  362. struct MT2063_ExclZone_t *pNext = NULL;
  363. /* Check to see if this overlaps the 1st IF filter */
  364. if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
  365. && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
  366. && (f_min < f_max)) {
  367. /*
  368. ** 1 2 3 4 5 6
  369. **
  370. ** New entry: |---| |--| |--| |-| |---| |--|
  371. ** or or or or or
  372. ** Existing: |--| |--| |--| |---| |-| |--|
  373. */
  374. /* Check for our place in the list */
  375. while ((pNode != NULL) && (pNode->max_ < f_min)) {
  376. pPrev = pNode;
  377. pNode = pNode->next_;
  378. }
  379. if ((pNode != NULL) && (pNode->min_ < f_max)) {
  380. /* Combine me with pNode */
  381. if (f_min < pNode->min_)
  382. pNode->min_ = f_min;
  383. if (f_max > pNode->max_)
  384. pNode->max_ = f_max;
  385. } else {
  386. pNode = InsertNode(pAS_Info, pPrev);
  387. pNode->min_ = f_min;
  388. pNode->max_ = f_max;
  389. }
  390. /* Look for merging possibilities */
  391. pNext = pNode->next_;
  392. while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
  393. if (pNext->max_ > pNode->max_)
  394. pNode->max_ = pNext->max_;
  395. pNext = RemoveNode(pAS_Info, pNode, pNext); /* Remove pNext, return ptr to pNext->next */
  396. }
  397. }
  398. }
  399. /*
  400. ** Reset all exclusion zones.
  401. ** Add zones to protect the PLL FracN regions near zero
  402. **
  403. ** N/A I 06-17-2008 RSK Ver 1.19: Refactoring avoidance of DECT
  404. ** frequencies into MT_ResetExclZones().
  405. */
  406. static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
  407. {
  408. u32 center;
  409. pAS_Info->nZones = 0; /* this clears the used list */
  410. pAS_Info->usedZones = NULL; /* reset ptr */
  411. pAS_Info->freeZones = NULL; /* reset ptr */
  412. center =
  413. pAS_Info->f_ref *
  414. ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
  415. pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
  416. while (center <
  417. pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
  418. pAS_Info->f_LO1_FracN_Avoid) {
  419. /* Exclude LO1 FracN */
  420. MT2063_AddExclZone(pAS_Info,
  421. center - pAS_Info->f_LO1_FracN_Avoid,
  422. center - 1);
  423. MT2063_AddExclZone(pAS_Info, center + 1,
  424. center + pAS_Info->f_LO1_FracN_Avoid);
  425. center += pAS_Info->f_ref;
  426. }
  427. center =
  428. pAS_Info->f_ref *
  429. ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
  430. pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
  431. while (center <
  432. pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
  433. pAS_Info->f_LO2_FracN_Avoid) {
  434. /* Exclude LO2 FracN */
  435. MT2063_AddExclZone(pAS_Info,
  436. center - pAS_Info->f_LO2_FracN_Avoid,
  437. center - 1);
  438. MT2063_AddExclZone(pAS_Info, center + 1,
  439. center + pAS_Info->f_LO2_FracN_Avoid);
  440. center += pAS_Info->f_ref;
  441. }
  442. if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
  443. /* Exclude LO1 values that conflict with DECT channels */
  444. MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
  445. MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
  446. MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
  447. MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
  448. MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
  449. }
  450. if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
  451. MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
  452. MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
  453. MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
  454. MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */
  455. MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
  456. MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
  457. MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
  458. MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
  459. MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */
  460. MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
  461. }
  462. }
  463. /*****************************************************************************
  464. **
  465. ** Name: MT_ChooseFirstIF
  466. **
  467. ** Description: Choose the best available 1st IF
  468. ** If f_Desired is not excluded, choose that first.
  469. ** Otherwise, return the value closest to f_Center that is
  470. ** not excluded
  471. **
  472. ** Revision History:
  473. **
  474. ** SCR Date Author Description
  475. ** -------------------------------------------------------------------------
  476. ** 117 03-29-2007 RSK Ver 1.15: Re-wrote to match search order from
  477. ** tuner DLL.
  478. ** 147 07-27-2007 RSK Ver 1.17: Corrected calculation (-) to (+)
  479. ** Added logic to force f_Center within 1/2 f_Step.
  480. **
  481. *****************************************************************************/
  482. static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
  483. {
  484. /*
  485. ** Update "f_Desired" to be the nearest "combinational-multiple" of "f_LO1_Step".
  486. ** The resulting number, F_LO1 must be a multiple of f_LO1_Step. And F_LO1 is the arithmetic sum
  487. ** of f_in + f_Center. Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
  488. ** However, the sum must be.
  489. */
  490. const u32 f_Desired =
  491. pAS_Info->f_LO1_Step *
  492. ((pAS_Info->f_if1_Request + pAS_Info->f_in +
  493. pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
  494. pAS_Info->f_in;
  495. const u32 f_Step =
  496. (pAS_Info->f_LO1_Step >
  497. pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
  498. f_LO2_Step;
  499. u32 f_Center;
  500. s32 i;
  501. s32 j = 0;
  502. u32 bDesiredExcluded = 0;
  503. u32 bZeroExcluded = 0;
  504. s32 tmpMin, tmpMax;
  505. s32 bestDiff;
  506. struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
  507. struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
  508. if (pAS_Info->nZones == 0)
  509. return f_Desired;
  510. /* f_Center needs to be an integer multiple of f_Step away from f_Desired */
  511. if (pAS_Info->f_if1_Center > f_Desired)
  512. f_Center =
  513. f_Desired +
  514. f_Step *
  515. ((pAS_Info->f_if1_Center - f_Desired +
  516. f_Step / 2) / f_Step);
  517. else
  518. f_Center =
  519. f_Desired -
  520. f_Step *
  521. ((f_Desired - pAS_Info->f_if1_Center +
  522. f_Step / 2) / f_Step);
  523. /* Take MT_ExclZones, center around f_Center and change the resolution to f_Step */
  524. while (pNode != NULL) {
  525. /* floor function */
  526. tmpMin =
  527. floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
  528. /* ceil function */
  529. tmpMax =
  530. ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
  531. if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
  532. bDesiredExcluded = 1;
  533. if ((tmpMin < 0) && (tmpMax > 0))
  534. bZeroExcluded = 1;
  535. /* See if this zone overlaps the previous */
  536. if ((j > 0) && (tmpMin < zones[j - 1].max_))
  537. zones[j - 1].max_ = tmpMax;
  538. else {
  539. /* Add new zone */
  540. zones[j].min_ = tmpMin;
  541. zones[j].max_ = tmpMax;
  542. j++;
  543. }
  544. pNode = pNode->next_;
  545. }
  546. /*
  547. ** If the desired is okay, return with it
  548. */
  549. if (bDesiredExcluded == 0)
  550. return f_Desired;
  551. /*
  552. ** If the desired is excluded and the center is okay, return with it
  553. */
  554. if (bZeroExcluded == 0)
  555. return f_Center;
  556. /* Find the value closest to 0 (f_Center) */
  557. bestDiff = zones[0].min_;
  558. for (i = 0; i < j; i++) {
  559. if (abs(zones[i].min_) < abs(bestDiff))
  560. bestDiff = zones[i].min_;
  561. if (abs(zones[i].max_) < abs(bestDiff))
  562. bestDiff = zones[i].max_;
  563. }
  564. if (bestDiff < 0)
  565. return f_Center - ((u32) (-bestDiff) * f_Step);
  566. return f_Center + (bestDiff * f_Step);
  567. }
  568. /****************************************************************************
  569. **
  570. ** Name: gcd
  571. **
  572. ** Description: Uses Euclid's algorithm
  573. **
  574. ** Parameters: u, v - unsigned values whose GCD is desired.
  575. **
  576. ** Global: None
  577. **
  578. ** Returns: greatest common divisor of u and v, if either value
  579. ** is 0, the other value is returned as the result.
  580. **
  581. ** Dependencies: None.
  582. **
  583. ** Revision History:
  584. **
  585. ** SCR Date Author Description
  586. ** -------------------------------------------------------------------------
  587. ** N/A 06-01-2004 JWS Original
  588. ** N/A 08-03-2004 DAD Changed to Euclid's since it can handle
  589. ** unsigned numbers.
  590. **
  591. ****************************************************************************/
  592. static u32 MT2063_gcd(u32 u, u32 v)
  593. {
  594. u32 r;
  595. while (v != 0) {
  596. r = u % v;
  597. u = v;
  598. v = r;
  599. }
  600. return u;
  601. }
  602. /****************************************************************************
  603. **
  604. ** Name: IsSpurInBand
  605. **
  606. ** Description: Checks to see if a spur will be present within the IF's
  607. ** bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
  608. **
  609. ** ma mb mc md
  610. ** <--+-+-+-------------------+-------------------+-+-+-->
  611. ** | ^ 0 ^ |
  612. ** ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^
  613. ** a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2
  614. **
  615. ** Note that some equations are doubled to prevent round-off
  616. ** problems when calculating fIFBW/2
  617. **
  618. ** Parameters: pAS_Info - Avoid Spurs information block
  619. ** fm - If spur, amount f_IF1 has to move negative
  620. ** fp - If spur, amount f_IF1 has to move positive
  621. **
  622. ** Global: None
  623. **
  624. ** Returns: 1 if an LO spur would be present, otherwise 0.
  625. **
  626. ** Dependencies: None.
  627. **
  628. ** Revision History:
  629. **
  630. ** SCR Date Author Description
  631. ** -------------------------------------------------------------------------
  632. ** N/A 11-28-2002 DAD Implemented algorithm from applied patent
  633. **
  634. ****************************************************************************/
  635. static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
  636. u32 *fm, u32 * fp)
  637. {
  638. /*
  639. ** Calculate LO frequency settings.
  640. */
  641. u32 n, n0;
  642. const u32 f_LO1 = pAS_Info->f_LO1;
  643. const u32 f_LO2 = pAS_Info->f_LO2;
  644. const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
  645. const u32 c = d - pAS_Info->f_out_bw;
  646. const u32 f = pAS_Info->f_zif_bw / 2;
  647. const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
  648. s32 f_nsLO1, f_nsLO2;
  649. s32 f_Spur;
  650. u32 ma, mb, mc, md, me, mf;
  651. u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
  652. *fm = 0;
  653. /*
  654. ** For each edge (d, c & f), calculate a scale, based on the gcd
  655. ** of f_LO1, f_LO2 and the edge value. Use the larger of this
  656. ** gcd-based scale factor or f_Scale.
  657. */
  658. lo_gcd = MT2063_gcd(f_LO1, f_LO2);
  659. gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
  660. hgds = gd_Scale / 2;
  661. gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
  662. hgcs = gc_Scale / 2;
  663. gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
  664. hgfs = gf_Scale / 2;
  665. n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
  666. /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */
  667. for (n = n0; n <= pAS_Info->maxH1; ++n) {
  668. md = (n * ((f_LO1 + hgds) / gd_Scale) -
  669. ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
  670. /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */
  671. if (md >= pAS_Info->maxH1)
  672. break;
  673. ma = (n * ((f_LO1 + hgds) / gd_Scale) +
  674. ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
  675. /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */
  676. if (md == ma)
  677. continue;
  678. mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
  679. ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
  680. if (mc != md) {
  681. f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
  682. f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
  683. f_Spur =
  684. (gc_Scale * (f_nsLO1 - f_nsLO2)) +
  685. n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
  686. *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
  687. *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
  688. return 1;
  689. }
  690. /* Location of Zero-IF-spur to be checked */
  691. me = (n * ((f_LO1 + hgfs) / gf_Scale) +
  692. ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
  693. mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
  694. ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
  695. if (me != mf) {
  696. f_nsLO1 = n * (f_LO1 / gf_Scale);
  697. f_nsLO2 = me * (f_LO2 / gf_Scale);
  698. f_Spur =
  699. (gf_Scale * (f_nsLO1 - f_nsLO2)) +
  700. n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
  701. *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
  702. *fm = (((s32) f - f_Spur) / (me - n)) + 1;
  703. return 1;
  704. }
  705. mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
  706. ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
  707. if (ma != mb) {
  708. f_nsLO1 = n * (f_LO1 / gc_Scale);
  709. f_nsLO2 = ma * (f_LO2 / gc_Scale);
  710. f_Spur =
  711. (gc_Scale * (f_nsLO1 - f_nsLO2)) +
  712. n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
  713. *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
  714. *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
  715. return 1;
  716. }
  717. }
  718. /* No spurs found */
  719. return 0;
  720. }
  721. /*****************************************************************************
  722. **
  723. ** Name: MT_AvoidSpurs
  724. **
  725. ** Description: Main entry point to avoid spurs.
  726. ** Checks for existing spurs in present LO1, LO2 freqs
  727. ** and if present, chooses spur-free LO1, LO2 combination
  728. ** that tunes the same input/output frequencies.
  729. **
  730. ** Revision History:
  731. **
  732. ** SCR Date Author Description
  733. ** -------------------------------------------------------------------------
  734. ** 096 04-06-2005 DAD Ver 1.11: Fix divide by 0 error if maxH==0.
  735. **
  736. *****************************************************************************/
  737. static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
  738. {
  739. u32 status = 0;
  740. u32 fm, fp; /* restricted range on LO's */
  741. pAS_Info->bSpurAvoided = 0;
  742. pAS_Info->nSpursFound = 0;
  743. if (pAS_Info->maxH1 == 0)
  744. return 0;
  745. /*
  746. ** Avoid LO Generated Spurs
  747. **
  748. ** Make sure that have no LO-related spurs within the IF output
  749. ** bandwidth.
  750. **
  751. ** If there is an LO spur in this band, start at the current IF1 frequency
  752. ** and work out until we find a spur-free frequency or run up against the
  753. ** 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they
  754. ** will be unchanged if a spur-free setting is not found.
  755. */
  756. pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
  757. if (pAS_Info->bSpurPresent) {
  758. u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */
  759. u32 zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */
  760. u32 zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */
  761. u32 delta_IF1;
  762. u32 new_IF1;
  763. /*
  764. ** Spur was found, attempt to find a spur-free 1st IF
  765. */
  766. do {
  767. pAS_Info->nSpursFound++;
  768. /* Raise f_IF1_upper, if needed */
  769. MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
  770. /* Choose next IF1 that is closest to f_IF1_CENTER */
  771. new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
  772. if (new_IF1 > zfIF1) {
  773. pAS_Info->f_LO1 += (new_IF1 - zfIF1);
  774. pAS_Info->f_LO2 += (new_IF1 - zfIF1);
  775. } else {
  776. pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
  777. pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
  778. }
  779. zfIF1 = new_IF1;
  780. if (zfIF1 > pAS_Info->f_if1_Center)
  781. delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
  782. else
  783. delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
  784. pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
  785. /*
  786. ** Continue while the new 1st IF is still within the 1st IF bandwidth
  787. ** and there is a spur in the band (again)
  788. */
  789. } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
  790. /*
  791. ** Use the LO-spur free values found. If the search went all the way to
  792. ** the 1st IF band edge and always found spurs, just leave the original
  793. ** choice. It's as "good" as any other.
  794. */
  795. if (pAS_Info->bSpurPresent == 1) {
  796. status |= MT2063_SPUR_PRESENT_ERR;
  797. pAS_Info->f_LO1 = zfLO1;
  798. pAS_Info->f_LO2 = zfLO2;
  799. } else
  800. pAS_Info->bSpurAvoided = 1;
  801. }
  802. status |=
  803. ((pAS_Info->
  804. nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
  805. return status;
  806. }
  807. /*
  808. * Constants used by the tuning algorithm
  809. */
  810. #define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */
  811. #define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */
  812. #define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */
  813. #define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */
  814. #define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */
  815. #define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */
  816. #define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */
  817. #define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */
  818. #define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */
  819. #define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */
  820. #define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */
  821. #define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */
  822. #define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */
  823. #define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */
  824. #define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */
  825. #define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */
  826. #define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */
  827. #define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */
  828. /*
  829. ** Define the supported Part/Rev codes for the MT2063
  830. */
  831. #define MT2063_B0 (0x9B)
  832. #define MT2063_B1 (0x9C)
  833. #define MT2063_B2 (0x9D)
  834. #define MT2063_B3 (0x9E)
  835. /*
  836. ** Constants for setting receiver modes.
  837. ** (6 modes defined at this time, enumerated by MT2063_RCVR_MODES)
  838. ** (DNC1GC & DNC2GC are the values, which are used, when the specific
  839. ** DNC Output is selected, the other is always off)
  840. **
  841. ** If PAL-L or L' is received, set:
  842. ** MT2063_SetParam(hMT2063,MT2063_TAGC,1);
  843. **
  844. ** --------------+----------------------------------------------
  845. ** Mode 0 : | MT2063_CABLE_QAM
  846. ** Mode 1 : | MT2063_CABLE_ANALOG
  847. ** Mode 2 : | MT2063_OFFAIR_COFDM
  848. ** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
  849. ** Mode 4 : | MT2063_OFFAIR_ANALOG
  850. ** Mode 5 : | MT2063_OFFAIR_8VSB
  851. ** --------------+----+----+----+----+-----+-----+--------------
  852. ** Mode | 0 | 1 | 2 | 3 | 4 | 5 |
  853. ** --------------+----+----+----+----+-----+-----+
  854. **
  855. **
  856. */
  857. static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
  858. static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
  859. static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
  860. static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
  861. static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
  862. static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
  863. static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
  864. static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
  865. static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
  866. static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
  867. static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
  868. static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
  869. static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
  870. static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
  871. /**
  872. * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
  873. *
  874. * @state: struct mt2063_state pointer
  875. *
  876. * This function returns 0, if no lock, 1 if locked and a value < 1 if error
  877. */
  878. static unsigned int mt2063_lockStatus(struct mt2063_state *state)
  879. {
  880. const u32 nMaxWait = 100; /* wait a maximum of 100 msec */
  881. const u32 nPollRate = 2; /* poll status bits every 2 ms */
  882. const u32 nMaxLoops = nMaxWait / nPollRate;
  883. const u8 LO1LK = 0x80;
  884. u8 LO2LK = 0x08;
  885. u32 status;
  886. u32 nDelays = 0;
  887. /* LO2 Lock bit was in a different place for B0 version */
  888. if (state->tuner_id == MT2063_B0)
  889. LO2LK = 0x40;
  890. do {
  891. status = mt2063_read(state, MT2063_REG_LO_STATUS,
  892. &state->reg[MT2063_REG_LO_STATUS], 1);
  893. if (status < 0)
  894. return status;
  895. if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
  896. (LO1LK | LO2LK)) {
  897. return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
  898. }
  899. msleep(nPollRate); /* Wait between retries */
  900. } while (++nDelays < nMaxLoops);
  901. /*
  902. * Got no lock or partial lock
  903. */
  904. return 0;
  905. }
  906. /*
  907. * mt2063_set_dnc_output_enable()
  908. */
  909. static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
  910. enum MT2063_DNC_Output_Enable *pValue)
  911. {
  912. if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
  913. if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
  914. *pValue = MT2063_DNC_NONE;
  915. else
  916. *pValue = MT2063_DNC_2;
  917. } else { /* DNC1 is on */
  918. if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
  919. *pValue = MT2063_DNC_1;
  920. else
  921. *pValue = MT2063_DNC_BOTH;
  922. }
  923. return 0;
  924. }
  925. /*
  926. * mt2063_set_dnc_output_enable()
  927. */
  928. static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
  929. enum MT2063_DNC_Output_Enable nValue)
  930. {
  931. u32 status = 0; /* Status to be returned */
  932. u8 val = 0;
  933. /* selects, which DNC output is used */
  934. switch (nValue) {
  935. case MT2063_DNC_NONE:
  936. {
  937. val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
  938. if (state->reg[MT2063_REG_DNC_GAIN] !=
  939. val)
  940. status |=
  941. mt2063_setreg(state,
  942. MT2063_REG_DNC_GAIN,
  943. val);
  944. val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
  945. if (state->reg[MT2063_REG_VGA_GAIN] !=
  946. val)
  947. status |=
  948. mt2063_setreg(state,
  949. MT2063_REG_VGA_GAIN,
  950. val);
  951. val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
  952. if (state->reg[MT2063_REG_RSVD_20] !=
  953. val)
  954. status |=
  955. mt2063_setreg(state,
  956. MT2063_REG_RSVD_20,
  957. val);
  958. break;
  959. }
  960. case MT2063_DNC_1:
  961. {
  962. val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
  963. if (state->reg[MT2063_REG_DNC_GAIN] !=
  964. val)
  965. status |=
  966. mt2063_setreg(state,
  967. MT2063_REG_DNC_GAIN,
  968. val);
  969. val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
  970. if (state->reg[MT2063_REG_VGA_GAIN] !=
  971. val)
  972. status |=
  973. mt2063_setreg(state,
  974. MT2063_REG_VGA_GAIN,
  975. val);
  976. val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
  977. if (state->reg[MT2063_REG_RSVD_20] !=
  978. val)
  979. status |=
  980. mt2063_setreg(state,
  981. MT2063_REG_RSVD_20,
  982. val);
  983. break;
  984. }
  985. case MT2063_DNC_2:
  986. {
  987. val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
  988. if (state->reg[MT2063_REG_DNC_GAIN] !=
  989. val)
  990. status |=
  991. mt2063_setreg(state,
  992. MT2063_REG_DNC_GAIN,
  993. val);
  994. val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
  995. if (state->reg[MT2063_REG_VGA_GAIN] !=
  996. val)
  997. status |=
  998. mt2063_setreg(state,
  999. MT2063_REG_VGA_GAIN,
  1000. val);
  1001. val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
  1002. if (state->reg[MT2063_REG_RSVD_20] !=
  1003. val)
  1004. status |=
  1005. mt2063_setreg(state,
  1006. MT2063_REG_RSVD_20,
  1007. val);
  1008. break;
  1009. }
  1010. case MT2063_DNC_BOTH:
  1011. {
  1012. val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
  1013. if (state->reg[MT2063_REG_DNC_GAIN] !=
  1014. val)
  1015. status |=
  1016. mt2063_setreg(state,
  1017. MT2063_REG_DNC_GAIN,
  1018. val);
  1019. val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
  1020. if (state->reg[MT2063_REG_VGA_GAIN] !=
  1021. val)
  1022. status |=
  1023. mt2063_setreg(state,
  1024. MT2063_REG_VGA_GAIN,
  1025. val);
  1026. val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
  1027. if (state->reg[MT2063_REG_RSVD_20] !=
  1028. val)
  1029. status |=
  1030. mt2063_setreg(state,
  1031. MT2063_REG_RSVD_20,
  1032. val);
  1033. break;
  1034. }
  1035. default:
  1036. break;
  1037. }
  1038. return status;
  1039. }
  1040. /******************************************************************************
  1041. **
  1042. ** Name: MT2063_SetReceiverMode
  1043. **
  1044. ** Description: Set the MT2063 receiver mode
  1045. **
  1046. ** --------------+----------------------------------------------
  1047. ** Mode 0 : | MT2063_CABLE_QAM
  1048. ** Mode 1 : | MT2063_CABLE_ANALOG
  1049. ** Mode 2 : | MT2063_OFFAIR_COFDM
  1050. ** Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
  1051. ** Mode 4 : | MT2063_OFFAIR_ANALOG
  1052. ** Mode 5 : | MT2063_OFFAIR_8VSB
  1053. ** --------------+----+----+----+----+-----+--------------------
  1054. ** (DNC1GC & DNC2GC are the values, which are used, when the specific
  1055. ** DNC Output is selected, the other is always off)
  1056. **
  1057. ** |<---------- Mode -------------->|
  1058. ** Reg Field | 0 | 1 | 2 | 3 | 4 | 5 |
  1059. ** ------------+-----+-----+-----+-----+-----+-----+
  1060. ** RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF
  1061. ** LNARin | 0 | 0 | 3 | 3 | 3 | 3
  1062. ** FIFFQen | 1 | 1 | 1 | 1 | 1 | 1
  1063. ** FIFFq | 0 | 0 | 0 | 0 | 0 | 0
  1064. ** DNC1gc | 0 | 0 | 0 | 0 | 0 | 0
  1065. ** DNC2gc | 0 | 0 | 0 | 0 | 0 | 0
  1066. ** GCU Auto | 1 | 1 | 1 | 1 | 1 | 1
  1067. ** LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31
  1068. ** LNA Target | 44 | 43 | 43 | 43 | 43 | 43
  1069. ** ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0
  1070. ** RF max Atn | 31 | 31 | 31 | 31 | 31 | 31
  1071. ** PD1 Target | 36 | 36 | 38 | 38 | 36 | 38
  1072. ** ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0
  1073. ** FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5
  1074. ** PD2 Target | 40 | 33 | 42 | 42 | 33 | 42
  1075. **
  1076. **
  1077. ** Parameters: state - ptr to mt2063_state structure
  1078. ** Mode - desired reciever mode
  1079. **
  1080. ** Usage: status = MT2063_SetReceiverMode(hMT2063, Mode);
  1081. **
  1082. ** Returns: status:
  1083. ** MT_OK - No errors
  1084. ** MT_COMM_ERR - Serial bus communications error
  1085. **
  1086. ** Dependencies: mt2063_setreg - Write a byte of data to a HW register.
  1087. ** Assumes that the tuner cache is valid.
  1088. **
  1089. ** Revision History:
  1090. **
  1091. ** SCR Date Author Description
  1092. ** -------------------------------------------------------------------------
  1093. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1094. ** N/A 01-10-2007 PINZ Added additional GCU Settings, FIFF Calib will be triggered
  1095. ** 155 10-01-2007 DAD Ver 1.06: Add receiver mode for SECAM positive
  1096. ** modulation
  1097. ** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
  1098. ** N/A 10-22-2007 PINZ Ver 1.07: Changed some Registers at init to have
  1099. ** the same settings as with MT Launcher
  1100. ** N/A 10-30-2007 PINZ Add SetParam VGAGC & VGAOI
  1101. ** Add SetParam DNC_OUTPUT_ENABLE
  1102. ** Removed VGAGC from receiver mode,
  1103. ** default now 1
  1104. ** N/A 10-31-2007 PINZ Ver 1.08: Add SetParam TAGC, removed from rcvr-mode
  1105. ** Add SetParam AMPGC, removed from rcvr-mode
  1106. ** Corrected names of GCU values
  1107. ** reorganized receiver modes, removed,
  1108. ** (MT2063_ANALOG_TV_POS_NO_RFAGC_MODE)
  1109. ** Actualized Receiver-Mode values
  1110. ** N/A 11-12-2007 PINZ Ver 1.09: Actualized Receiver-Mode values
  1111. ** N/A 11-27-2007 PINZ Improved buffered writing
  1112. ** 01-03-2008 PINZ Ver 1.10: Added a trigger of BYPATNUP for
  1113. ** correct wakeup of the LNA after shutdown
  1114. ** Set AFCsd = 1 as default
  1115. ** Changed CAP1sel default
  1116. ** 01-14-2008 PINZ Ver 1.11: Updated gain settings
  1117. ** 04-18-2008 PINZ Ver 1.15: Add SetParam LNARIN & PDxTGT
  1118. ** Split SetParam up to ACLNA / ACLNA_MAX
  1119. ** removed ACLNA_INRC/DECR (+RF & FIF)
  1120. ** removed GCUAUTO / BYPATNDN/UP
  1121. **
  1122. ******************************************************************************/
  1123. static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
  1124. enum MT2063_RCVR_MODES Mode)
  1125. {
  1126. u32 status = 0; /* Status to be returned */
  1127. u8 val;
  1128. u32 longval;
  1129. if (Mode >= MT2063_NUM_RCVR_MODES)
  1130. status = -ERANGE;
  1131. /* RFAGCen */
  1132. if (status >= 0) {
  1133. val =
  1134. (state->
  1135. reg[MT2063_REG_PD1_TGT] & (u8) ~0x40) | (RFAGCEN[Mode]
  1136. ? 0x40 :
  1137. 0x00);
  1138. if (state->reg[MT2063_REG_PD1_TGT] != val)
  1139. status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
  1140. }
  1141. /* LNARin */
  1142. if (status >= 0) {
  1143. u8 val = (state->reg[MT2063_REG_CTRL_2C] & (u8) ~0x03) |
  1144. (LNARIN[Mode] & 0x03);
  1145. if (state->reg[MT2063_REG_CTRL_2C] != val)
  1146. status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
  1147. }
  1148. /* FIFFQEN and FIFFQ */
  1149. if (status >= 0) {
  1150. val =
  1151. (state->
  1152. reg[MT2063_REG_FIFF_CTRL2] & (u8) ~0xF0) |
  1153. (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
  1154. if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
  1155. status |=
  1156. mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
  1157. /* trigger FIFF calibration, needed after changing FIFFQ */
  1158. val =
  1159. (state->reg[MT2063_REG_FIFF_CTRL] | (u8) 0x01);
  1160. status |=
  1161. mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
  1162. val =
  1163. (state->
  1164. reg[MT2063_REG_FIFF_CTRL] & (u8) ~0x01);
  1165. status |=
  1166. mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
  1167. }
  1168. }
  1169. /* DNC1GC & DNC2GC */
  1170. status |= mt2063_get_dnc_output_enable(state, &longval);
  1171. status |= mt2063_set_dnc_output_enable(state, longval);
  1172. /* acLNAmax */
  1173. if (status >= 0) {
  1174. u8 val = (state->reg[MT2063_REG_LNA_OV] & (u8) ~0x1F) |
  1175. (ACLNAMAX[Mode] & 0x1F);
  1176. if (state->reg[MT2063_REG_LNA_OV] != val)
  1177. status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
  1178. }
  1179. /* LNATGT */
  1180. if (status >= 0) {
  1181. u8 val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x3F) |
  1182. (LNATGT[Mode] & 0x3F);
  1183. if (state->reg[MT2063_REG_LNA_TGT] != val)
  1184. status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
  1185. }
  1186. /* ACRF */
  1187. if (status >= 0) {
  1188. u8 val = (state->reg[MT2063_REG_RF_OV] & (u8) ~0x1F) |
  1189. (ACRFMAX[Mode] & 0x1F);
  1190. if (state->reg[MT2063_REG_RF_OV] != val)
  1191. status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
  1192. }
  1193. /* PD1TGT */
  1194. if (status >= 0) {
  1195. u8 val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x3F) |
  1196. (PD1TGT[Mode] & 0x3F);
  1197. if (state->reg[MT2063_REG_PD1_TGT] != val)
  1198. status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
  1199. }
  1200. /* FIFATN */
  1201. if (status >= 0) {
  1202. u8 val = ACFIFMAX[Mode];
  1203. if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
  1204. val = 5;
  1205. val = (state->reg[MT2063_REG_FIF_OV] & (u8) ~0x1F) |
  1206. (val & 0x1F);
  1207. if (state->reg[MT2063_REG_FIF_OV] != val)
  1208. status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
  1209. }
  1210. /* PD2TGT */
  1211. if (status >= 0) {
  1212. u8 val = (state->reg[MT2063_REG_PD2_TGT] & (u8) ~0x3F) |
  1213. (PD2TGT[Mode] & 0x3F);
  1214. if (state->reg[MT2063_REG_PD2_TGT] != val)
  1215. status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
  1216. }
  1217. /* Ignore ATN Overload */
  1218. if (status >= 0) {
  1219. val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x80) |
  1220. (RFOVDIS[Mode] ? 0x80 : 0x00);
  1221. if (state->reg[MT2063_REG_LNA_TGT] != val)
  1222. status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
  1223. }
  1224. /* Ignore FIF Overload */
  1225. if (status >= 0) {
  1226. val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x80) |
  1227. (FIFOVDIS[Mode] ? 0x80 : 0x00);
  1228. if (state->reg[MT2063_REG_PD1_TGT] != val)
  1229. status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
  1230. }
  1231. if (status >= 0)
  1232. state->rcvr_mode = Mode;
  1233. return status;
  1234. }
  1235. /****************************************************************************
  1236. **
  1237. ** Name: MT2063_ClearPowerMaskBits
  1238. **
  1239. ** Description: Clears the power-down mask bits for various sections of
  1240. ** the MT2063
  1241. **
  1242. ** Parameters: h - Tuner handle (returned by MT2063_Open)
  1243. ** Bits - Mask bits to be cleared.
  1244. **
  1245. ** See definition of MT2063_Mask_Bits type for description
  1246. ** of each of the power bits.
  1247. **
  1248. ** Returns: status:
  1249. ** MT_OK - No errors
  1250. ** MT_INV_HANDLE - Invalid tuner handle
  1251. ** MT_COMM_ERR - Serial bus communications error
  1252. **
  1253. ** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
  1254. **
  1255. ** Revision History:
  1256. **
  1257. ** SCR Date Author Description
  1258. ** -------------------------------------------------------------------------
  1259. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1260. **
  1261. ****************************************************************************/
  1262. static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
  1263. enum MT2063_Mask_Bits Bits)
  1264. {
  1265. u32 status = 0; /* Status to be returned */
  1266. Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
  1267. if ((Bits & 0xFF00) != 0) {
  1268. state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
  1269. status |=
  1270. mt2063_write(state,
  1271. MT2063_REG_PWR_2,
  1272. &state->reg[MT2063_REG_PWR_2], 1);
  1273. }
  1274. if ((Bits & 0xFF) != 0) {
  1275. state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
  1276. status |=
  1277. mt2063_write(state,
  1278. MT2063_REG_PWR_1,
  1279. &state->reg[MT2063_REG_PWR_1], 1);
  1280. }
  1281. return status;
  1282. }
  1283. /****************************************************************************
  1284. **
  1285. ** Name: MT2063_SoftwareShutdown
  1286. **
  1287. ** Description: Enables or disables software shutdown function. When
  1288. ** Shutdown==1, any section whose power mask is set will be
  1289. ** shutdown.
  1290. **
  1291. ** Parameters: h - Tuner handle (returned by MT2063_Open)
  1292. ** Shutdown - 1 = shutdown the masked sections, otherwise
  1293. ** power all sections on
  1294. **
  1295. ** Returns: status:
  1296. ** MT_OK - No errors
  1297. ** MT_INV_HANDLE - Invalid tuner handle
  1298. ** MT_COMM_ERR - Serial bus communications error
  1299. **
  1300. ** Dependencies: USERS MUST CALL MT2063_Open() FIRST!
  1301. **
  1302. ** Revision History:
  1303. **
  1304. ** SCR Date Author Description
  1305. ** -------------------------------------------------------------------------
  1306. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1307. ** 01-03-2008 PINZ Ver 1.xx: Added a trigger of BYPATNUP for
  1308. ** correct wakeup of the LNA
  1309. **
  1310. ****************************************************************************/
  1311. static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
  1312. {
  1313. u32 status; /* Status to be returned */
  1314. if (Shutdown == 1)
  1315. state->reg[MT2063_REG_PWR_1] |= 0x04; /* Turn the bit on */
  1316. else
  1317. state->reg[MT2063_REG_PWR_1] &= ~0x04; /* Turn off the bit */
  1318. status = mt2063_write(state,
  1319. MT2063_REG_PWR_1,
  1320. &state->reg[MT2063_REG_PWR_1], 1);
  1321. if (Shutdown != 1) {
  1322. state->reg[MT2063_REG_BYP_CTRL] =
  1323. (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
  1324. status |=
  1325. mt2063_write(state,
  1326. MT2063_REG_BYP_CTRL,
  1327. &state->reg[MT2063_REG_BYP_CTRL],
  1328. 1);
  1329. state->reg[MT2063_REG_BYP_CTRL] =
  1330. (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
  1331. status |=
  1332. mt2063_write(state,
  1333. MT2063_REG_BYP_CTRL,
  1334. &state->reg[MT2063_REG_BYP_CTRL],
  1335. 1);
  1336. }
  1337. return status;
  1338. }
  1339. static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
  1340. {
  1341. return f_ref * (f_LO / f_ref)
  1342. + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
  1343. }
  1344. /****************************************************************************
  1345. **
  1346. ** Name: fLO_FractionalTerm
  1347. **
  1348. ** Description: Calculates the portion contributed by FracN / denom.
  1349. **
  1350. ** This function preserves maximum precision without
  1351. ** risk of overflow. It accurately calculates
  1352. ** f_ref * num / denom to within 1 HZ with fixed math.
  1353. **
  1354. ** Parameters: num - Fractional portion of the multiplier
  1355. ** denom - denominator portion of the ratio
  1356. ** This routine successfully handles denom values
  1357. ** up to and including 2^18.
  1358. ** f_Ref - SRO frequency. This calculation handles
  1359. ** f_ref as two separate 14-bit fields.
  1360. ** Therefore, a maximum value of 2^28-1
  1361. ** may safely be used for f_ref. This is
  1362. ** the genesis of the magic number "14" and the
  1363. ** magic mask value of 0x03FFF.
  1364. **
  1365. ** Returns: f_ref * num / denom
  1366. **
  1367. ** Revision History:
  1368. **
  1369. ** SCR Date Author Description
  1370. ** -------------------------------------------------------------------------
  1371. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1372. **
  1373. ****************************************************************************/
  1374. static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
  1375. {
  1376. u32 t1 = (f_ref >> 14) * num;
  1377. u32 term1 = t1 / denom;
  1378. u32 loss = t1 % denom;
  1379. u32 term2 =
  1380. (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
  1381. return (term1 << 14) + term2;
  1382. }
  1383. /****************************************************************************
  1384. **
  1385. ** Name: CalcLO1Mult
  1386. **
  1387. ** Description: Calculates Integer divider value and the numerator
  1388. ** value for a FracN PLL.
  1389. **
  1390. ** This function assumes that the f_LO and f_Ref are
  1391. ** evenly divisible by f_LO_Step.
  1392. **
  1393. ** Parameters: Div - OUTPUT: Whole number portion of the multiplier
  1394. ** FracN - OUTPUT: Fractional portion of the multiplier
  1395. ** f_LO - desired LO frequency.
  1396. ** f_LO_Step - Minimum step size for the LO (in Hz).
  1397. ** f_Ref - SRO frequency.
  1398. ** f_Avoid - Range of PLL frequencies to avoid near
  1399. ** integer multiples of f_Ref (in Hz).
  1400. **
  1401. ** Returns: Recalculated LO frequency.
  1402. **
  1403. ** Revision History:
  1404. **
  1405. ** SCR Date Author Description
  1406. ** -------------------------------------------------------------------------
  1407. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1408. **
  1409. ****************************************************************************/
  1410. static u32 MT2063_CalcLO1Mult(u32 *Div,
  1411. u32 *FracN,
  1412. u32 f_LO,
  1413. u32 f_LO_Step, u32 f_Ref)
  1414. {
  1415. /* Calculate the whole number portion of the divider */
  1416. *Div = f_LO / f_Ref;
  1417. /* Calculate the numerator value (round to nearest f_LO_Step) */
  1418. *FracN =
  1419. (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
  1420. (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
  1421. return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
  1422. }
  1423. /****************************************************************************
  1424. **
  1425. ** Name: CalcLO2Mult
  1426. **
  1427. ** Description: Calculates Integer divider value and the numerator
  1428. ** value for a FracN PLL.
  1429. **
  1430. ** This function assumes that the f_LO and f_Ref are
  1431. ** evenly divisible by f_LO_Step.
  1432. **
  1433. ** Parameters: Div - OUTPUT: Whole number portion of the multiplier
  1434. ** FracN - OUTPUT: Fractional portion of the multiplier
  1435. ** f_LO - desired LO frequency.
  1436. ** f_LO_Step - Minimum step size for the LO (in Hz).
  1437. ** f_Ref - SRO frequency.
  1438. ** f_Avoid - Range of PLL frequencies to avoid near
  1439. ** integer multiples of f_Ref (in Hz).
  1440. **
  1441. ** Returns: Recalculated LO frequency.
  1442. **
  1443. ** Revision History:
  1444. **
  1445. ** SCR Date Author Description
  1446. ** -------------------------------------------------------------------------
  1447. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1448. **
  1449. ****************************************************************************/
  1450. static u32 MT2063_CalcLO2Mult(u32 *Div,
  1451. u32 *FracN,
  1452. u32 f_LO,
  1453. u32 f_LO_Step, u32 f_Ref)
  1454. {
  1455. /* Calculate the whole number portion of the divider */
  1456. *Div = f_LO / f_Ref;
  1457. /* Calculate the numerator value (round to nearest f_LO_Step) */
  1458. *FracN =
  1459. (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
  1460. (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
  1461. return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
  1462. 8191);
  1463. }
  1464. /****************************************************************************
  1465. **
  1466. ** Name: FindClearTuneFilter
  1467. **
  1468. ** Description: Calculate the corrrect ClearTune filter to be used for
  1469. ** a given input frequency.
  1470. **
  1471. ** Parameters: state - ptr to tuner data structure
  1472. ** f_in - RF input center frequency (in Hz).
  1473. **
  1474. ** Returns: ClearTune filter number (0-31)
  1475. **
  1476. ** Dependencies: MUST CALL MT2064_Open BEFORE FindClearTuneFilter!
  1477. **
  1478. ** Revision History:
  1479. **
  1480. ** SCR Date Author Description
  1481. ** -------------------------------------------------------------------------
  1482. ** 04-10-2008 PINZ Ver 1.14: Use software-controlled ClearTune
  1483. ** cross-over frequency values.
  1484. **
  1485. ****************************************************************************/
  1486. static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
  1487. {
  1488. u32 RFBand;
  1489. u32 idx; /* index loop */
  1490. /*
  1491. ** Find RF Band setting
  1492. */
  1493. RFBand = 31; /* def when f_in > all */
  1494. for (idx = 0; idx < 31; ++idx) {
  1495. if (state->CTFiltMax[idx] >= f_in) {
  1496. RFBand = idx;
  1497. break;
  1498. }
  1499. }
  1500. return RFBand;
  1501. }
  1502. /****************************************************************************
  1503. **
  1504. ** Name: MT2063_Tune
  1505. **
  1506. ** Description: Change the tuner's tuned frequency to RFin.
  1507. **
  1508. ** Parameters: h - Open handle to the tuner (from MT2063_Open).
  1509. ** f_in - RF input center frequency (in Hz).
  1510. **
  1511. ** Returns: status:
  1512. ** MT_OK - No errors
  1513. ** MT_INV_HANDLE - Invalid tuner handle
  1514. ** MT_UPC_UNLOCK - Upconverter PLL unlocked
  1515. ** MT_DNC_UNLOCK - Downconverter PLL unlocked
  1516. ** MT_COMM_ERR - Serial bus communications error
  1517. ** MT_SPUR_CNT_MASK - Count of avoided LO spurs
  1518. ** MT_SPUR_PRESENT - LO spur possible in output
  1519. ** MT_FIN_RANGE - Input freq out of range
  1520. ** MT_FOUT_RANGE - Output freq out of range
  1521. ** MT_UPC_RANGE - Upconverter freq out of range
  1522. ** MT_DNC_RANGE - Downconverter freq out of range
  1523. **
  1524. ** Dependencies: MUST CALL MT2063_Open BEFORE MT2063_Tune!
  1525. **
  1526. ** MT_ReadSub - Read data from the two-wire serial bus
  1527. ** MT_WriteSub - Write data to the two-wire serial bus
  1528. ** MT_Sleep - Delay execution for x milliseconds
  1529. ** MT2063_GetLocked - Checks to see if LO1 and LO2 are locked
  1530. **
  1531. ** Revision History:
  1532. **
  1533. ** SCR Date Author Description
  1534. ** -------------------------------------------------------------------------
  1535. ** 138 06-19-2007 DAD Ver 1.00: Initial, derived from mt2067_b.
  1536. ** 04-10-2008 PINZ Ver 1.05: Use software-controlled ClearTune
  1537. ** cross-over frequency values.
  1538. ** 175 I 16-06-2008 PINZ Ver 1.16: Add control to avoid US DECT freqs.
  1539. ** 175 I 06-19-2008 RSK Ver 1.17: Refactor DECT control to SpurAvoid.
  1540. ** 06-24-2008 PINZ Ver 1.18: Add Get/SetParam CTFILT_SW
  1541. **
  1542. ****************************************************************************/
  1543. static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
  1544. { /* RF input center frequency */
  1545. u32 status = 0; /* status of operation */
  1546. u32 LO1; /* 1st LO register value */
  1547. u32 Num1; /* Numerator for LO1 reg. value */
  1548. u32 f_IF1; /* 1st IF requested */
  1549. u32 LO2; /* 2nd LO register value */
  1550. u32 Num2; /* Numerator for LO2 reg. value */
  1551. u32 ofLO1, ofLO2; /* last time's LO frequencies */
  1552. u32 ofin, ofout; /* last time's I/O frequencies */
  1553. u8 fiffc = 0x80; /* FIFF center freq from tuner */
  1554. u32 fiffof; /* Offset from FIFF center freq */
  1555. const u8 LO1LK = 0x80; /* Mask for LO1 Lock bit */
  1556. u8 LO2LK = 0x08; /* Mask for LO2 Lock bit */
  1557. u8 val;
  1558. u32 RFBand;
  1559. /* Check the input and output frequency ranges */
  1560. if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
  1561. return -EINVAL;
  1562. if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
  1563. || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
  1564. return -EINVAL;
  1565. /*
  1566. ** Save original LO1 and LO2 register values
  1567. */
  1568. ofLO1 = state->AS_Data.f_LO1;
  1569. ofLO2 = state->AS_Data.f_LO2;
  1570. ofin = state->AS_Data.f_in;
  1571. ofout = state->AS_Data.f_out;
  1572. /*
  1573. ** Find and set RF Band setting
  1574. */
  1575. if (state->ctfilt_sw == 1) {
  1576. val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
  1577. if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
  1578. status |=
  1579. mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
  1580. }
  1581. val = state->reg[MT2063_REG_CTUNE_OV];
  1582. RFBand = FindClearTuneFilter(state, f_in);
  1583. state->reg[MT2063_REG_CTUNE_OV] =
  1584. (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
  1585. | RFBand);
  1586. if (state->reg[MT2063_REG_CTUNE_OV] != val) {
  1587. status |=
  1588. mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
  1589. }
  1590. }
  1591. /*
  1592. ** Read the FIFF Center Frequency from the tuner
  1593. */
  1594. if (status >= 0) {
  1595. status |=
  1596. mt2063_read(state,
  1597. MT2063_REG_FIFFC,
  1598. &state->reg[MT2063_REG_FIFFC], 1);
  1599. fiffc = state->reg[MT2063_REG_FIFFC];
  1600. }
  1601. /*
  1602. ** Assign in the requested values
  1603. */
  1604. state->AS_Data.f_in = f_in;
  1605. /* Request a 1st IF such that LO1 is on a step size */
  1606. state->AS_Data.f_if1_Request =
  1607. MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
  1608. state->AS_Data.f_LO1_Step,
  1609. state->AS_Data.f_ref) - f_in;
  1610. /*
  1611. ** Calculate frequency settings. f_IF1_FREQ + f_in is the
  1612. ** desired LO1 frequency
  1613. */
  1614. MT2063_ResetExclZones(&state->AS_Data);
  1615. f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
  1616. state->AS_Data.f_LO1 =
  1617. MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
  1618. state->AS_Data.f_ref);
  1619. state->AS_Data.f_LO2 =
  1620. MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
  1621. state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
  1622. /*
  1623. ** Check for any LO spurs in the output bandwidth and adjust
  1624. ** the LO settings to avoid them if needed
  1625. */
  1626. status |= MT2063_AvoidSpurs(&state->AS_Data);
  1627. /*
  1628. ** MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
  1629. ** Recalculate the LO frequencies and the values to be placed
  1630. ** in the tuning registers.
  1631. */
  1632. state->AS_Data.f_LO1 =
  1633. MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
  1634. state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
  1635. state->AS_Data.f_LO2 =
  1636. MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
  1637. state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
  1638. state->AS_Data.f_LO2 =
  1639. MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
  1640. state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
  1641. /*
  1642. ** Check the upconverter and downconverter frequency ranges
  1643. */
  1644. if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
  1645. || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
  1646. status |= MT2063_UPC_RANGE;
  1647. if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
  1648. || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
  1649. status |= MT2063_DNC_RANGE;
  1650. /* LO2 Lock bit was in a different place for B0 version */
  1651. if (state->tuner_id == MT2063_B0)
  1652. LO2LK = 0x40;
  1653. /*
  1654. ** If we have the same LO frequencies and we're already locked,
  1655. ** then skip re-programming the LO registers.
  1656. */
  1657. if ((ofLO1 != state->AS_Data.f_LO1)
  1658. || (ofLO2 != state->AS_Data.f_LO2)
  1659. || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
  1660. (LO1LK | LO2LK))) {
  1661. /*
  1662. ** Calculate the FIFFOF register value
  1663. **
  1664. ** IF1_Actual
  1665. ** FIFFOF = ------------ - 8 * FIFFC - 4992
  1666. ** f_ref/64
  1667. */
  1668. fiffof =
  1669. (state->AS_Data.f_LO1 -
  1670. f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
  1671. 4992;
  1672. if (fiffof > 0xFF)
  1673. fiffof = 0xFF;
  1674. /*
  1675. ** Place all of the calculated values into the local tuner
  1676. ** register fields.
  1677. */
  1678. if (status >= 0) {
  1679. state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF); /* DIV1q */
  1680. state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F); /* NUM1q */
  1681. state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1) /* DIV2q */
  1682. |(Num2 >> 12)); /* NUM2q (hi) */
  1683. state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */
  1684. state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
  1685. /*
  1686. ** Now write out the computed register values
  1687. ** IMPORTANT: There is a required order for writing
  1688. ** (0x05 must follow all the others).
  1689. */
  1690. status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */
  1691. if (state->tuner_id == MT2063_B0) {
  1692. /* Re-write the one-shot bits to trigger the tune operation */
  1693. status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */
  1694. }
  1695. /* Write out the FIFF offset only if it's changing */
  1696. if (state->reg[MT2063_REG_FIFF_OFFSET] !=
  1697. (u8) fiffof) {
  1698. state->reg[MT2063_REG_FIFF_OFFSET] =
  1699. (u8) fiffof;
  1700. status |=
  1701. mt2063_write(state,
  1702. MT2063_REG_FIFF_OFFSET,
  1703. &state->
  1704. reg[MT2063_REG_FIFF_OFFSET],
  1705. 1);
  1706. }
  1707. }
  1708. /*
  1709. ** Check for LO's locking
  1710. */
  1711. if (status < 0)
  1712. return status;
  1713. status = mt2063_lockStatus(state);
  1714. if (status < 0)
  1715. return status;
  1716. if (!status)
  1717. return -EINVAL; /* Couldn't lock */
  1718. /*
  1719. * If we locked OK, assign calculated data to mt2063_state structure
  1720. */
  1721. state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
  1722. }
  1723. return status;
  1724. }
  1725. static const u8 MT2063B0_defaults[] = {
  1726. /* Reg, Value */
  1727. 0x19, 0x05,
  1728. 0x1B, 0x1D,
  1729. 0x1C, 0x1F,
  1730. 0x1D, 0x0F,
  1731. 0x1E, 0x3F,
  1732. 0x1F, 0x0F,
  1733. 0x20, 0x3F,
  1734. 0x22, 0x21,
  1735. 0x23, 0x3F,
  1736. 0x24, 0x20,
  1737. 0x25, 0x3F,
  1738. 0x27, 0xEE,
  1739. 0x2C, 0x27, /* bit at 0x20 is cleared below */
  1740. 0x30, 0x03,
  1741. 0x2C, 0x07, /* bit at 0x20 is cleared here */
  1742. 0x2D, 0x87,
  1743. 0x2E, 0xAA,
  1744. 0x28, 0xE1, /* Set the FIFCrst bit here */
  1745. 0x28, 0xE0, /* Clear the FIFCrst bit here */
  1746. 0x00
  1747. };
  1748. /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
  1749. static const u8 MT2063B1_defaults[] = {
  1750. /* Reg, Value */
  1751. 0x05, 0xF0,
  1752. 0x11, 0x10, /* New Enable AFCsd */
  1753. 0x19, 0x05,
  1754. 0x1A, 0x6C,
  1755. 0x1B, 0x24,
  1756. 0x1C, 0x28,
  1757. 0x1D, 0x8F,
  1758. 0x1E, 0x14,
  1759. 0x1F, 0x8F,
  1760. 0x20, 0x57,
  1761. 0x22, 0x21, /* New - ver 1.03 */
  1762. 0x23, 0x3C, /* New - ver 1.10 */
  1763. 0x24, 0x20, /* New - ver 1.03 */
  1764. 0x2C, 0x24, /* bit at 0x20 is cleared below */
  1765. 0x2D, 0x87, /* FIFFQ=0 */
  1766. 0x2F, 0xF3,
  1767. 0x30, 0x0C, /* New - ver 1.11 */
  1768. 0x31, 0x1B, /* New - ver 1.11 */
  1769. 0x2C, 0x04, /* bit at 0x20 is cleared here */
  1770. 0x28, 0xE1, /* Set the FIFCrst bit here */
  1771. 0x28, 0xE0, /* Clear the FIFCrst bit here */
  1772. 0x00
  1773. };
  1774. /* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
  1775. static const u8 MT2063B3_defaults[] = {
  1776. /* Reg, Value */
  1777. 0x05, 0xF0,
  1778. 0x19, 0x3D,
  1779. 0x2C, 0x24, /* bit at 0x20 is cleared below */
  1780. 0x2C, 0x04, /* bit at 0x20 is cleared here */
  1781. 0x28, 0xE1, /* Set the FIFCrst bit here */
  1782. 0x28, 0xE0, /* Clear the FIFCrst bit here */
  1783. 0x00
  1784. };
  1785. static int mt2063_init(struct dvb_frontend *fe)
  1786. {
  1787. u32 status;
  1788. struct mt2063_state *state = fe->tuner_priv;
  1789. u8 all_resets = 0xF0; /* reset/load bits */
  1790. const u8 *def = NULL;
  1791. u32 FCRUN;
  1792. s32 maxReads;
  1793. u32 fcu_osc;
  1794. u32 i;
  1795. state->rcvr_mode = MT2063_CABLE_QAM;
  1796. /* Read the Part/Rev code from the tuner */
  1797. status = mt2063_read(state, MT2063_REG_PART_REV, state->reg, 1);
  1798. if (status < 0)
  1799. return status;
  1800. /* Check the part/rev code */
  1801. if (((state->reg[MT2063_REG_PART_REV] != MT2063_B0) /* MT2063 B0 */
  1802. && (state->reg[MT2063_REG_PART_REV] != MT2063_B1) /* MT2063 B1 */
  1803. && (state->reg[MT2063_REG_PART_REV] != MT2063_B3))) /* MT2063 B3 */
  1804. return -ENODEV; /* Wrong tuner Part/Rev code */
  1805. /* Check the 2nd byte of the Part/Rev code from the tuner */
  1806. status = mt2063_read(state, MT2063_REG_RSVD_3B,
  1807. &state->reg[MT2063_REG_RSVD_3B], 1);
  1808. /* b7 != 0 ==> NOT MT2063 */
  1809. if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00))
  1810. return -ENODEV; /* Wrong tuner Part/Rev code */
  1811. /* Reset the tuner */
  1812. status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
  1813. if (status < 0)
  1814. return status;
  1815. /* change all of the default values that vary from the HW reset values */
  1816. /* def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
  1817. switch (state->reg[MT2063_REG_PART_REV]) {
  1818. case MT2063_B3:
  1819. def = MT2063B3_defaults;
  1820. break;
  1821. case MT2063_B1:
  1822. def = MT2063B1_defaults;
  1823. break;
  1824. case MT2063_B0:
  1825. def = MT2063B0_defaults;
  1826. break;
  1827. default:
  1828. return -ENODEV;
  1829. break;
  1830. }
  1831. while (status >= 0 && *def) {
  1832. u8 reg = *def++;
  1833. u8 val = *def++;
  1834. status = mt2063_write(state, reg, &val, 1);
  1835. }
  1836. if (status < 0)
  1837. return status;
  1838. /* Wait for FIFF location to complete. */
  1839. FCRUN = 1;
  1840. maxReads = 10;
  1841. while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
  1842. msleep(2);
  1843. status = mt2063_read(state,
  1844. MT2063_REG_XO_STATUS,
  1845. &state->
  1846. reg[MT2063_REG_XO_STATUS], 1);
  1847. FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
  1848. }
  1849. if (FCRUN != 0 || status < 0)
  1850. return -ENODEV;
  1851. status = mt2063_read(state,
  1852. MT2063_REG_FIFFC,
  1853. &state->reg[MT2063_REG_FIFFC], 1);
  1854. if (status < 0)
  1855. return status;
  1856. /* Read back all the registers from the tuner */
  1857. status = mt2063_read(state,
  1858. MT2063_REG_PART_REV,
  1859. state->reg, MT2063_REG_END_REGS);
  1860. if (status < 0)
  1861. return status;
  1862. /* Initialize the tuner state. */
  1863. state->tuner_id = state->reg[MT2063_REG_PART_REV];
  1864. state->AS_Data.f_ref = MT2063_REF_FREQ;
  1865. state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
  1866. ((u32) state->reg[MT2063_REG_FIFFC] + 640);
  1867. state->AS_Data.f_if1_bw = MT2063_IF1_BW;
  1868. state->AS_Data.f_out = 43750000UL;
  1869. state->AS_Data.f_out_bw = 6750000UL;
  1870. state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
  1871. state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
  1872. state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
  1873. state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
  1874. state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
  1875. state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
  1876. state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
  1877. state->AS_Data.f_LO1 = 2181000000UL;
  1878. state->AS_Data.f_LO2 = 1486249786UL;
  1879. state->f_IF1_actual = state->AS_Data.f_if1_Center;
  1880. state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
  1881. state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
  1882. state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
  1883. state->num_regs = MT2063_REG_END_REGS;
  1884. state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
  1885. state->ctfilt_sw = 0;
  1886. state->CTFiltMax[0] = 69230000;
  1887. state->CTFiltMax[1] = 105770000;
  1888. state->CTFiltMax[2] = 140350000;
  1889. state->CTFiltMax[3] = 177110000;
  1890. state->CTFiltMax[4] = 212860000;
  1891. state->CTFiltMax[5] = 241130000;
  1892. state->CTFiltMax[6] = 274370000;
  1893. state->CTFiltMax[7] = 309820000;
  1894. state->CTFiltMax[8] = 342450000;
  1895. state->CTFiltMax[9] = 378870000;
  1896. state->CTFiltMax[10] = 416210000;
  1897. state->CTFiltMax[11] = 456500000;
  1898. state->CTFiltMax[12] = 495790000;
  1899. state->CTFiltMax[13] = 534530000;
  1900. state->CTFiltMax[14] = 572610000;
  1901. state->CTFiltMax[15] = 598970000;
  1902. state->CTFiltMax[16] = 635910000;
  1903. state->CTFiltMax[17] = 672130000;
  1904. state->CTFiltMax[18] = 714840000;
  1905. state->CTFiltMax[19] = 739660000;
  1906. state->CTFiltMax[20] = 770410000;
  1907. state->CTFiltMax[21] = 814660000;
  1908. state->CTFiltMax[22] = 846950000;
  1909. state->CTFiltMax[23] = 867820000;
  1910. state->CTFiltMax[24] = 915980000;
  1911. state->CTFiltMax[25] = 947450000;
  1912. state->CTFiltMax[26] = 983110000;
  1913. state->CTFiltMax[27] = 1021630000;
  1914. state->CTFiltMax[28] = 1061870000;
  1915. state->CTFiltMax[29] = 1098330000;
  1916. state->CTFiltMax[30] = 1138990000;
  1917. /*
  1918. ** Fetch the FCU osc value and use it and the fRef value to
  1919. ** scale all of the Band Max values
  1920. */
  1921. state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
  1922. status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
  1923. &state->reg[MT2063_REG_CTUNE_CTRL], 1);
  1924. if (status < 0)
  1925. return status;
  1926. /* Read the ClearTune filter calibration value */
  1927. status = mt2063_read(state, MT2063_REG_FIFFC,
  1928. &state->reg[MT2063_REG_FIFFC], 1);
  1929. if (status < 0)
  1930. return status;
  1931. fcu_osc = state->reg[MT2063_REG_FIFFC];
  1932. state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
  1933. status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
  1934. &state->reg[MT2063_REG_CTUNE_CTRL], 1);
  1935. if (status < 0)
  1936. return status;
  1937. /* Adjust each of the values in the ClearTune filter cross-over table */
  1938. for (i = 0; i < 31; i++)
  1939. state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
  1940. status = MT2063_SoftwareShutdown(state, 1);
  1941. if (status < 0)
  1942. return status;
  1943. status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
  1944. if (status < 0)
  1945. return status;
  1946. return 0;
  1947. }
  1948. static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
  1949. {
  1950. struct mt2063_state *state = fe->tuner_priv;
  1951. int status;
  1952. *tuner_status = 0;
  1953. status = mt2063_lockStatus(state);
  1954. if (status < 0)
  1955. return status;
  1956. if (status)
  1957. *tuner_status = TUNER_STATUS_LOCKED;
  1958. return 0;
  1959. }
  1960. static int mt2063_release(struct dvb_frontend *fe)
  1961. {
  1962. struct mt2063_state *state = fe->tuner_priv;
  1963. fe->tuner_priv = NULL;
  1964. kfree(state);
  1965. return 0;
  1966. }
  1967. static int mt2063_set_analog_params(struct dvb_frontend *fe,
  1968. struct analog_parameters *params)
  1969. {
  1970. struct mt2063_state *state = fe->tuner_priv;
  1971. s32 pict_car = 0;
  1972. s32 pict2chanb_vsb = 0;
  1973. s32 pict2chanb_snd = 0;
  1974. s32 pict2snd1 = 0;
  1975. s32 pict2snd2 = 0;
  1976. s32 ch_bw = 0;
  1977. s32 if_mid = 0;
  1978. s32 rcvr_mode = 0;
  1979. int status;
  1980. switch (params->mode) {
  1981. case V4L2_TUNER_RADIO:
  1982. pict_car = 38900000;
  1983. ch_bw = 8000000;
  1984. pict2chanb_vsb = -(ch_bw / 2);
  1985. pict2snd1 = 0;
  1986. pict2snd2 = 0;
  1987. rcvr_mode = MT2063_OFFAIR_ANALOG;
  1988. break;
  1989. case V4L2_TUNER_ANALOG_TV:
  1990. rcvr_mode = MT2063_CABLE_ANALOG;
  1991. if (params->std & ~V4L2_STD_MN) {
  1992. pict_car = 38900000;
  1993. ch_bw = 6000000;
  1994. pict2chanb_vsb = -1250000;
  1995. pict2snd1 = 4500000;
  1996. pict2snd2 = 0;
  1997. } else if (params->std & V4L2_STD_PAL_I) {
  1998. pict_car = 38900000;
  1999. ch_bw = 8000000;
  2000. pict2chanb_vsb = -1250000;
  2001. pict2snd1 = 6000000;
  2002. pict2snd2 = 0;
  2003. } else if (params->std & V4L2_STD_PAL_B) {
  2004. pict_car = 38900000;
  2005. ch_bw = 8000000;
  2006. pict2chanb_vsb = -1250000;
  2007. pict2snd1 = 5500000;
  2008. pict2snd2 = 5742000;
  2009. } else if (params->std & V4L2_STD_PAL_G) {
  2010. pict_car = 38900000;
  2011. ch_bw = 7000000;
  2012. pict2chanb_vsb = -1250000;
  2013. pict2snd1 = 5500000;
  2014. pict2snd2 = 0;
  2015. } else if (params->std & V4L2_STD_PAL_DK) {
  2016. pict_car = 38900000;
  2017. ch_bw = 8000000;
  2018. pict2chanb_vsb = -1250000;
  2019. pict2snd1 = 6500000;
  2020. pict2snd2 = 0;
  2021. } else { /* PAL-L */
  2022. pict_car = 38900000;
  2023. ch_bw = 8000000;
  2024. pict2chanb_vsb = -1250000;
  2025. pict2snd1 = 6500000;
  2026. pict2snd2 = 0;
  2027. }
  2028. break;
  2029. }
  2030. pict2chanb_snd = pict2chanb_vsb - ch_bw;
  2031. if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
  2032. state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
  2033. state->AS_Data.f_out = if_mid;
  2034. state->AS_Data.f_out_bw = ch_bw + 750000;
  2035. status = MT2063_SetReceiverMode(state, rcvr_mode);
  2036. if (status < 0)
  2037. return status;
  2038. status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
  2039. if (status < 0)
  2040. return status;
  2041. state->frequency = params->frequency;
  2042. return 0;
  2043. }
  2044. /*
  2045. * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
  2046. * So, the amount of the needed bandwith is given by:
  2047. * Bw = Symbol_rate * (1 + 0.15)
  2048. * As such, the maximum symbol rate supported by 6 MHz is given by:
  2049. * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
  2050. */
  2051. #define MAX_SYMBOL_RATE_6MHz 5217391
  2052. static int mt2063_set_params(struct dvb_frontend *fe,
  2053. struct dvb_frontend_parameters *params)
  2054. {
  2055. struct mt2063_state *state = fe->tuner_priv;
  2056. int status;
  2057. s32 pict_car = 0;
  2058. s32 pict2chanb_vsb = 0;
  2059. s32 pict2chanb_snd = 0;
  2060. s32 pict2snd1 = 0;
  2061. s32 pict2snd2 = 0;
  2062. s32 ch_bw = 0;
  2063. s32 if_mid = 0;
  2064. s32 rcvr_mode = 0;
  2065. switch (fe->ops.info.type) {
  2066. case FE_OFDM:
  2067. switch (params->u.ofdm.bandwidth) {
  2068. case BANDWIDTH_6_MHZ:
  2069. ch_bw = 6000000;
  2070. break;
  2071. case BANDWIDTH_7_MHZ:
  2072. ch_bw = 7000000;
  2073. break;
  2074. case BANDWIDTH_8_MHZ:
  2075. ch_bw = 8000000;
  2076. break;
  2077. default:
  2078. return -EINVAL;
  2079. }
  2080. rcvr_mode = MT2063_OFFAIR_COFDM;
  2081. pict_car = 36125000;
  2082. pict2chanb_vsb = -(ch_bw / 2);
  2083. pict2snd1 = 0;
  2084. pict2snd2 = 0;
  2085. break;
  2086. case FE_QAM:
  2087. /*
  2088. * Using a 8MHz bandwidth sometimes fail
  2089. * with 6MHz-spaced channels, due to inter-carrier
  2090. * interference. So, it is better to narrow-down the filter
  2091. */
  2092. if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz)
  2093. ch_bw = 6000000;
  2094. else
  2095. ch_bw = 8000000;
  2096. rcvr_mode = MT2063_CABLE_QAM;
  2097. pict_car = 36125000;
  2098. pict2snd1 = 0;
  2099. pict2snd2 = 0;
  2100. pict2chanb_vsb = -(ch_bw / 2);
  2101. break;
  2102. default:
  2103. return -EINVAL;
  2104. }
  2105. pict2chanb_snd = pict2chanb_vsb - ch_bw;
  2106. if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
  2107. state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
  2108. state->AS_Data.f_out = if_mid;
  2109. state->AS_Data.f_out_bw = ch_bw + 750000;
  2110. status = MT2063_SetReceiverMode(state, rcvr_mode);
  2111. if (status < 0)
  2112. return status;
  2113. status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
  2114. if (status < 0)
  2115. return status;
  2116. state->frequency = params->frequency;
  2117. return 0;
  2118. }
  2119. static int mt2063_get_frequency(struct dvb_frontend *fe, u32 *freq)
  2120. {
  2121. struct mt2063_state *state = fe->tuner_priv;
  2122. *freq = state->frequency;
  2123. return 0;
  2124. }
  2125. static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
  2126. {
  2127. struct mt2063_state *state = fe->tuner_priv;
  2128. *bw = state->AS_Data.f_out_bw - 750000;
  2129. return 0;
  2130. }
  2131. static struct dvb_tuner_ops mt2063_ops = {
  2132. .info = {
  2133. .name = "MT2063 Silicon Tuner",
  2134. .frequency_min = 45000000,
  2135. .frequency_max = 850000000,
  2136. .frequency_step = 0,
  2137. },
  2138. .init = mt2063_init,
  2139. .sleep = MT2063_Sleep,
  2140. .get_status = mt2063_get_status,
  2141. .set_analog_params = mt2063_set_analog_params,
  2142. .set_params = mt2063_set_params,
  2143. .get_frequency = mt2063_get_frequency,
  2144. .get_bandwidth = mt2063_get_bandwidth,
  2145. .release = mt2063_release,
  2146. };
  2147. struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
  2148. struct mt2063_config *config,
  2149. struct i2c_adapter *i2c)
  2150. {
  2151. struct mt2063_state *state = NULL;
  2152. state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
  2153. if (state == NULL)
  2154. goto error;
  2155. state->config = config;
  2156. state->i2c = i2c;
  2157. state->frontend = fe;
  2158. state->reference = config->refclock / 1000; /* kHz */
  2159. fe->tuner_priv = state;
  2160. fe->ops.tuner_ops = mt2063_ops;
  2161. printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
  2162. return fe;
  2163. error:
  2164. kfree(state);
  2165. return NULL;
  2166. }
  2167. EXPORT_SYMBOL_GPL(mt2063_attach);
  2168. /*
  2169. * Ancillary routines visible outside mt2063
  2170. * FIXME: Remove them in favor of using standard tuner callbacks
  2171. */
  2172. unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
  2173. {
  2174. struct mt2063_state *state = fe->tuner_priv;
  2175. int err = 0;
  2176. err = MT2063_SoftwareShutdown(state, 1);
  2177. if (err < 0)
  2178. printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
  2179. return err;
  2180. }
  2181. EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown);
  2182. unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
  2183. {
  2184. struct mt2063_state *state = fe->tuner_priv;
  2185. int err = 0;
  2186. err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
  2187. if (err < 0)
  2188. printk(KERN_ERR "%s: Invalid parameter\n", __func__);
  2189. return err;
  2190. }
  2191. EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits);
  2192. MODULE_PARM_DESC(verbose, "Set Verbosity level");
  2193. MODULE_AUTHOR("Henry");
  2194. MODULE_DESCRIPTION("MT2063 Silicon tuner");
  2195. MODULE_LICENSE("GPL");