mxl111sf-phy.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * mxl111sf-phy.c - driver for the MaxLinear MXL111SF
  3. *
  4. * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include "mxl111sf-phy.h"
  17. #include "mxl111sf-reg.h"
  18. int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
  19. {
  20. struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
  21. {0x07, 0xff, 0x0c},
  22. {0x58, 0xff, 0x9d},
  23. {0x09, 0xff, 0x00},
  24. {0x06, 0xff, 0x06},
  25. {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
  26. {0x8d, 0x01, 0x01}, /* NEGATE_Q */
  27. {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
  28. {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
  29. {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
  30. {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
  31. {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
  32. {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
  33. {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
  34. {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
  35. {0x00, 0xff, 0x01}, /* Change to page 1 */
  36. {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
  37. {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
  38. {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
  39. {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
  40. {0x00, 0xff, 0x00}, /* Change to page 0 */
  41. {0, 0, 0}
  42. };
  43. mxl_debug("()");
  44. return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
  45. }
  46. int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
  47. {
  48. int ret;
  49. mxl_debug("()");
  50. ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
  51. if (mxl_fail(ret))
  52. goto fail;
  53. ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
  54. mxl_fail(ret);
  55. fail:
  56. return ret;
  57. }
  58. int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
  59. {
  60. int ret;
  61. mxl_debug("(%s)", MXL_SOC_MODE == mode ?
  62. "MXL_SOC_MODE" : "MXL_TUNER_MODE");
  63. /* set device mode */
  64. ret = mxl111sf_write_reg(state, 0x03,
  65. MXL_SOC_MODE == mode ? 0x01 : 0x00);
  66. if (mxl_fail(ret))
  67. goto fail;
  68. ret = mxl111sf_write_reg_mask(state,
  69. 0x7d, 0x40, MXL_SOC_MODE == mode ?
  70. 0x00 : /* enable impulse noise filter,
  71. INF_BYP = 0 */
  72. 0x40); /* disable impulse noise filter,
  73. INF_BYP = 1 */
  74. if (mxl_fail(ret))
  75. goto fail;
  76. state->device_mode = mode;
  77. fail:
  78. return ret;
  79. }
  80. /* power up tuner */
  81. int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
  82. {
  83. mxl_debug("(%d)", onoff);
  84. return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
  85. }
  86. int mxl111sf_disable_656_port(struct mxl111sf_state *state)
  87. {
  88. mxl_debug("()");
  89. return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
  90. }
  91. int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
  92. {
  93. mxl_debug("()");
  94. return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
  95. }
  96. /* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
  97. int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
  98. unsigned int parallel_serial,
  99. unsigned int msb_lsb_1st,
  100. unsigned int clock_phase,
  101. unsigned int mpeg_valid_pol,
  102. unsigned int mpeg_sync_pol)
  103. {
  104. int ret;
  105. u8 mode, tmp;
  106. mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
  107. clock_phase, mpeg_valid_pol, mpeg_sync_pol);
  108. /* Enable PIN MUX */
  109. ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
  110. mxl_fail(ret);
  111. /* Configure MPEG Clock phase */
  112. mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
  113. if (clock_phase == TSIF_NORMAL)
  114. mode &= ~V6_INVERTED_CLK_PHASE;
  115. else
  116. mode |= V6_INVERTED_CLK_PHASE;
  117. ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
  118. mxl_fail(ret);
  119. /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
  120. * Get current configuration */
  121. ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
  122. mxl_fail(ret);
  123. /* Data Input mode */
  124. if (parallel_serial == TSIF_INPUT_PARALLEL) {
  125. /* Disable serial mode */
  126. mode &= ~V6_MPEG_IN_DATA_SERIAL;
  127. /* Enable Parallel mode */
  128. mode |= V6_MPEG_IN_DATA_PARALLEL;
  129. } else {
  130. /* Disable Parallel mode */
  131. mode &= ~V6_MPEG_IN_DATA_PARALLEL;
  132. /* Enable Serial Mode */
  133. mode |= V6_MPEG_IN_DATA_SERIAL;
  134. /* If serial interface is chosen, configure
  135. MSB or LSB order in transmission */
  136. ret = mxl111sf_read_reg(state,
  137. V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
  138. &tmp);
  139. mxl_fail(ret);
  140. if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
  141. tmp |= V6_MPEG_SER_MSB_FIRST;
  142. else
  143. tmp &= ~V6_MPEG_SER_MSB_FIRST;
  144. ret = mxl111sf_write_reg(state,
  145. V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
  146. tmp);
  147. mxl_fail(ret);
  148. }
  149. /* MPEG Sync polarity */
  150. if (mpeg_sync_pol == TSIF_NORMAL)
  151. mode &= ~V6_INVERTED_MPEG_SYNC;
  152. else
  153. mode |= V6_INVERTED_MPEG_SYNC;
  154. /* MPEG Valid polarity */
  155. if (mpeg_valid_pol == 0)
  156. mode &= ~V6_INVERTED_MPEG_VALID;
  157. else
  158. mode |= V6_INVERTED_MPEG_VALID;
  159. ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
  160. mxl_fail(ret);
  161. return ret;
  162. }
  163. int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
  164. {
  165. static struct mxl111sf_reg_ctrl_info init_i2s[] = {
  166. {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
  167. {0x15, 0x60, 0x60}, /* Enable I2S */
  168. {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
  169. Inverted 656 Clock, I2S_SOFT_RESET,
  170. 0 : Normal operation, 1 : Reset State */
  171. #if 0
  172. {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
  173. #endif
  174. {0x00, 0xff, 0x02}, /* Change to Control Page */
  175. {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
  176. {0x00, 0xff, 0x00},
  177. {0, 0, 0}
  178. };
  179. int ret;
  180. mxl_debug("(0x%02x)", sample_size);
  181. ret = mxl111sf_ctrl_program_regs(state, init_i2s);
  182. if (mxl_fail(ret))
  183. goto fail;
  184. ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
  185. mxl_fail(ret);
  186. fail:
  187. return ret;
  188. }
  189. int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
  190. {
  191. static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
  192. {0x15, 0x40, 0x00},
  193. {0, 0, 0}
  194. };
  195. mxl_debug("()");
  196. return mxl111sf_ctrl_program_regs(state, disable_i2s);
  197. }
  198. int mxl111sf_config_i2s(struct mxl111sf_state *state,
  199. u8 msb_start_pos, u8 data_width)
  200. {
  201. int ret;
  202. u8 tmp;
  203. mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
  204. ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
  205. if (mxl_fail(ret))
  206. goto fail;
  207. tmp &= 0xe0;
  208. tmp |= msb_start_pos;
  209. ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
  210. if (mxl_fail(ret))
  211. goto fail;
  212. ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
  213. if (mxl_fail(ret))
  214. goto fail;
  215. tmp &= 0xe0;
  216. tmp |= data_width;
  217. ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
  218. mxl_fail(ret);
  219. fail:
  220. return ret;
  221. }
  222. int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
  223. {
  224. u8 val;
  225. int ret;
  226. mxl_debug("(%d)", onoff);
  227. ret = mxl111sf_write_reg(state, 0x00, 0x02);
  228. if (mxl_fail(ret))
  229. goto fail;
  230. ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
  231. if (mxl_fail(ret))
  232. goto fail;
  233. if (onoff)
  234. val |= 0x04;
  235. else
  236. val &= ~0x04;
  237. ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
  238. if (mxl_fail(ret))
  239. goto fail;
  240. ret = mxl111sf_write_reg(state, 0x00, 0x00);
  241. mxl_fail(ret);
  242. fail:
  243. return ret;
  244. }
  245. int mxl111sf_idac_config(struct mxl111sf_state *state,
  246. u8 control_mode, u8 current_setting,
  247. u8 current_value, u8 hysteresis_value)
  248. {
  249. int ret;
  250. u8 val;
  251. /* current value will be set for both automatic & manual IDAC control */
  252. val = current_value;
  253. if (control_mode == IDAC_MANUAL_CONTROL) {
  254. /* enable manual control of IDAC */
  255. val |= IDAC_MANUAL_CONTROL_BIT_MASK;
  256. if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
  257. /* enable current sinking in manual mode */
  258. val |= IDAC_CURRENT_SINKING_BIT_MASK;
  259. else
  260. /* disable current sinking in manual mode */
  261. val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
  262. } else {
  263. /* disable manual control of IDAC */
  264. val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
  265. /* set hysteresis value reg: 0x0B<5:0> */
  266. ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
  267. (hysteresis_value & 0x3F));
  268. mxl_fail(ret);
  269. }
  270. ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
  271. mxl_fail(ret);
  272. return ret;
  273. }