xonar_dg.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * card driver for the Xonar DG/DGX
  4. *
  5. * Copyright (c) Clemens Ladisch <[email protected]>
  6. * Copyright (c) Roman Volkov <[email protected]>
  7. */
  8. /*
  9. * Xonar DG/DGX
  10. * ------------
  11. *
  12. * CS4245 and CS4361 both will mute all outputs if any clock ratio
  13. * is invalid.
  14. *
  15. * CMI8788:
  16. *
  17. * SPI 0 -> CS4245
  18. *
  19. * Playback:
  20. * I²S 1 -> CS4245
  21. * I²S 2 -> CS4361 (center/LFE)
  22. * I²S 3 -> CS4361 (surround)
  23. * I²S 4 -> CS4361 (front)
  24. * Capture:
  25. * I²S ADC 1 <- CS4245
  26. *
  27. * GPIO 3 <- ?
  28. * GPIO 4 <- headphone detect
  29. * GPIO 5 -> enable ADC analog circuit for the left channel
  30. * GPIO 6 -> enable ADC analog circuit for the right channel
  31. * GPIO 7 -> switch green rear output jack between CS4245 and the first
  32. * channel of CS4361 (mechanical relay)
  33. * GPIO 8 -> enable output to speakers
  34. *
  35. * CS4245:
  36. *
  37. * input 0 <- mic
  38. * input 1 <- aux
  39. * input 2 <- front mic
  40. * input 4 <- line
  41. * DAC out -> headphones
  42. * aux out -> front panel headphones
  43. */
  44. #include <linux/pci.h>
  45. #include <linux/delay.h>
  46. #include <sound/control.h>
  47. #include <sound/core.h>
  48. #include <sound/info.h>
  49. #include <sound/pcm.h>
  50. #include <sound/tlv.h>
  51. #include "oxygen.h"
  52. #include "xonar_dg.h"
  53. #include "cs4245.h"
  54. int cs4245_write_spi(struct oxygen *chip, u8 reg)
  55. {
  56. struct dg *data = chip->model_data;
  57. unsigned int packet;
  58. packet = reg << 8;
  59. packet |= (CS4245_SPI_ADDRESS | CS4245_SPI_WRITE) << 16;
  60. packet |= data->cs4245_shadow[reg];
  61. return oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
  62. OXYGEN_SPI_DATA_LENGTH_3 |
  63. OXYGEN_SPI_CLOCK_1280 |
  64. (0 << OXYGEN_SPI_CODEC_SHIFT) |
  65. OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
  66. packet);
  67. }
  68. int cs4245_read_spi(struct oxygen *chip, u8 addr)
  69. {
  70. struct dg *data = chip->model_data;
  71. int ret;
  72. ret = oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
  73. OXYGEN_SPI_DATA_LENGTH_2 |
  74. OXYGEN_SPI_CEN_LATCH_CLOCK_HI |
  75. OXYGEN_SPI_CLOCK_1280 | (0 << OXYGEN_SPI_CODEC_SHIFT),
  76. ((CS4245_SPI_ADDRESS | CS4245_SPI_WRITE) << 8) | addr);
  77. if (ret < 0)
  78. return ret;
  79. ret = oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
  80. OXYGEN_SPI_DATA_LENGTH_2 |
  81. OXYGEN_SPI_CEN_LATCH_CLOCK_HI |
  82. OXYGEN_SPI_CLOCK_1280 | (0 << OXYGEN_SPI_CODEC_SHIFT),
  83. (CS4245_SPI_ADDRESS | CS4245_SPI_READ) << 8);
  84. if (ret < 0)
  85. return ret;
  86. data->cs4245_shadow[addr] = oxygen_read8(chip, OXYGEN_SPI_DATA1);
  87. return 0;
  88. }
  89. int cs4245_shadow_control(struct oxygen *chip, enum cs4245_shadow_operation op)
  90. {
  91. struct dg *data = chip->model_data;
  92. unsigned char addr;
  93. int ret;
  94. for (addr = 1; addr < ARRAY_SIZE(data->cs4245_shadow); addr++) {
  95. ret = (op == CS4245_SAVE_TO_SHADOW ?
  96. cs4245_read_spi(chip, addr) :
  97. cs4245_write_spi(chip, addr));
  98. if (ret < 0)
  99. return ret;
  100. }
  101. return 0;
  102. }
  103. static void cs4245_init(struct oxygen *chip)
  104. {
  105. struct dg *data = chip->model_data;
  106. /* save the initial state: codec version, registers */
  107. cs4245_shadow_control(chip, CS4245_SAVE_TO_SHADOW);
  108. /*
  109. * Power up the CODEC internals, enable soft ramp & zero cross, work in
  110. * async. mode, enable aux output from DAC. Invert DAC output as in the
  111. * Windows driver.
  112. */
  113. data->cs4245_shadow[CS4245_POWER_CTRL] = 0;
  114. data->cs4245_shadow[CS4245_SIGNAL_SEL] =
  115. CS4245_A_OUT_SEL_DAC | CS4245_ASYNCH;
  116. data->cs4245_shadow[CS4245_DAC_CTRL_1] =
  117. CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
  118. data->cs4245_shadow[CS4245_DAC_CTRL_2] =
  119. CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC;
  120. data->cs4245_shadow[CS4245_ADC_CTRL] =
  121. CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
  122. data->cs4245_shadow[CS4245_ANALOG_IN] =
  123. CS4245_PGA_SOFT | CS4245_PGA_ZERO;
  124. data->cs4245_shadow[CS4245_PGA_B_CTRL] = 0;
  125. data->cs4245_shadow[CS4245_PGA_A_CTRL] = 0;
  126. data->cs4245_shadow[CS4245_DAC_A_CTRL] = 8;
  127. data->cs4245_shadow[CS4245_DAC_B_CTRL] = 8;
  128. cs4245_shadow_control(chip, CS4245_LOAD_FROM_SHADOW);
  129. snd_component_add(chip->card, "CS4245");
  130. }
  131. void dg_init(struct oxygen *chip)
  132. {
  133. struct dg *data = chip->model_data;
  134. data->output_sel = PLAYBACK_DST_HP_FP;
  135. data->input_sel = CAPTURE_SRC_MIC;
  136. cs4245_init(chip);
  137. oxygen_write16(chip, OXYGEN_GPIO_CONTROL,
  138. GPIO_OUTPUT_ENABLE | GPIO_HP_REAR | GPIO_INPUT_ROUTE);
  139. /* anti-pop delay, wait some time before enabling the output */
  140. msleep(2500);
  141. oxygen_write16(chip, OXYGEN_GPIO_DATA,
  142. GPIO_OUTPUT_ENABLE | GPIO_INPUT_ROUTE);
  143. }
  144. void dg_cleanup(struct oxygen *chip)
  145. {
  146. oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
  147. }
  148. void dg_suspend(struct oxygen *chip)
  149. {
  150. dg_cleanup(chip);
  151. }
  152. void dg_resume(struct oxygen *chip)
  153. {
  154. cs4245_shadow_control(chip, CS4245_LOAD_FROM_SHADOW);
  155. msleep(2500);
  156. oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
  157. }
  158. void set_cs4245_dac_params(struct oxygen *chip,
  159. struct snd_pcm_hw_params *params)
  160. {
  161. struct dg *data = chip->model_data;
  162. unsigned char dac_ctrl;
  163. unsigned char mclk_freq;
  164. dac_ctrl = data->cs4245_shadow[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
  165. mclk_freq = data->cs4245_shadow[CS4245_MCLK_FREQ] & ~CS4245_MCLK1_MASK;
  166. if (params_rate(params) <= 50000) {
  167. dac_ctrl |= CS4245_DAC_FM_SINGLE;
  168. mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK1_SHIFT;
  169. } else if (params_rate(params) <= 100000) {
  170. dac_ctrl |= CS4245_DAC_FM_DOUBLE;
  171. mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK1_SHIFT;
  172. } else {
  173. dac_ctrl |= CS4245_DAC_FM_QUAD;
  174. mclk_freq |= CS4245_MCLK_2 << CS4245_MCLK1_SHIFT;
  175. }
  176. data->cs4245_shadow[CS4245_DAC_CTRL_1] = dac_ctrl;
  177. data->cs4245_shadow[CS4245_MCLK_FREQ] = mclk_freq;
  178. cs4245_write_spi(chip, CS4245_DAC_CTRL_1);
  179. cs4245_write_spi(chip, CS4245_MCLK_FREQ);
  180. }
  181. void set_cs4245_adc_params(struct oxygen *chip,
  182. struct snd_pcm_hw_params *params)
  183. {
  184. struct dg *data = chip->model_data;
  185. unsigned char adc_ctrl;
  186. unsigned char mclk_freq;
  187. adc_ctrl = data->cs4245_shadow[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
  188. mclk_freq = data->cs4245_shadow[CS4245_MCLK_FREQ] & ~CS4245_MCLK2_MASK;
  189. if (params_rate(params) <= 50000) {
  190. adc_ctrl |= CS4245_ADC_FM_SINGLE;
  191. mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK2_SHIFT;
  192. } else if (params_rate(params) <= 100000) {
  193. adc_ctrl |= CS4245_ADC_FM_DOUBLE;
  194. mclk_freq |= CS4245_MCLK_1 << CS4245_MCLK2_SHIFT;
  195. } else {
  196. adc_ctrl |= CS4245_ADC_FM_QUAD;
  197. mclk_freq |= CS4245_MCLK_2 << CS4245_MCLK2_SHIFT;
  198. }
  199. data->cs4245_shadow[CS4245_ADC_CTRL] = adc_ctrl;
  200. data->cs4245_shadow[CS4245_MCLK_FREQ] = mclk_freq;
  201. cs4245_write_spi(chip, CS4245_ADC_CTRL);
  202. cs4245_write_spi(chip, CS4245_MCLK_FREQ);
  203. }
  204. static inline unsigned int shift_bits(unsigned int value,
  205. unsigned int shift_from,
  206. unsigned int shift_to,
  207. unsigned int mask)
  208. {
  209. if (shift_from < shift_to)
  210. return (value << (shift_to - shift_from)) & mask;
  211. else
  212. return (value >> (shift_from - shift_to)) & mask;
  213. }
  214. unsigned int adjust_dg_dac_routing(struct oxygen *chip,
  215. unsigned int play_routing)
  216. {
  217. struct dg *data = chip->model_data;
  218. switch (data->output_sel) {
  219. case PLAYBACK_DST_HP:
  220. case PLAYBACK_DST_HP_FP:
  221. oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING,
  222. OXYGEN_PLAY_MUTE23 | OXYGEN_PLAY_MUTE45 |
  223. OXYGEN_PLAY_MUTE67, OXYGEN_PLAY_MUTE_MASK);
  224. break;
  225. case PLAYBACK_DST_MULTICH:
  226. oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING,
  227. OXYGEN_PLAY_MUTE01, OXYGEN_PLAY_MUTE_MASK);
  228. break;
  229. }
  230. return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
  231. shift_bits(play_routing,
  232. OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
  233. OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
  234. OXYGEN_PLAY_DAC1_SOURCE_MASK) |
  235. shift_bits(play_routing,
  236. OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
  237. OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
  238. OXYGEN_PLAY_DAC2_SOURCE_MASK) |
  239. shift_bits(play_routing,
  240. OXYGEN_PLAY_DAC0_SOURCE_SHIFT,
  241. OXYGEN_PLAY_DAC3_SOURCE_SHIFT,
  242. OXYGEN_PLAY_DAC3_SOURCE_MASK);
  243. }
  244. void dump_cs4245_registers(struct oxygen *chip,
  245. struct snd_info_buffer *buffer)
  246. {
  247. struct dg *data = chip->model_data;
  248. unsigned int addr;
  249. snd_iprintf(buffer, "\nCS4245:");
  250. cs4245_read_spi(chip, CS4245_INT_STATUS);
  251. for (addr = 1; addr < ARRAY_SIZE(data->cs4245_shadow); addr++)
  252. snd_iprintf(buffer, " %02x", data->cs4245_shadow[addr]);
  253. snd_iprintf(buffer, "\n");
  254. }