xonar_dg.c 8.4 KB

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