adau1761.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. /*
  2. * Driver for ADAU1761/ADAU1461/ADAU1761/ADAU1961 codec
  3. *
  4. * Copyright 2011-2013 Analog Devices Inc.
  5. * Author: Lars-Peter Clausen <lars@metafoo.de>
  6. *
  7. * Licensed under the GPL-2 or later.
  8. */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/i2c.h>
  12. #include <linux/spi/spi.h>
  13. #include <linux/slab.h>
  14. #include <sound/core.h>
  15. #include <sound/pcm.h>
  16. #include <sound/pcm_params.h>
  17. #include <sound/soc.h>
  18. #include <sound/tlv.h>
  19. #include <linux/platform_data/adau17x1.h>
  20. #include "adau17x1.h"
  21. #include "adau1761.h"
  22. #define ADAU1761_DIGMIC_JACKDETECT 0x4008
  23. #define ADAU1761_REC_MIXER_LEFT0 0x400a
  24. #define ADAU1761_REC_MIXER_LEFT1 0x400b
  25. #define ADAU1761_REC_MIXER_RIGHT0 0x400c
  26. #define ADAU1761_REC_MIXER_RIGHT1 0x400d
  27. #define ADAU1761_LEFT_DIFF_INPUT_VOL 0x400e
  28. #define ADAU1761_RIGHT_DIFF_INPUT_VOL 0x400f
  29. #define ADAU1761_PLAY_LR_MIXER_LEFT 0x4020
  30. #define ADAU1761_PLAY_MIXER_LEFT0 0x401c
  31. #define ADAU1761_PLAY_MIXER_LEFT1 0x401d
  32. #define ADAU1761_PLAY_MIXER_RIGHT0 0x401e
  33. #define ADAU1761_PLAY_MIXER_RIGHT1 0x401f
  34. #define ADAU1761_PLAY_LR_MIXER_RIGHT 0x4021
  35. #define ADAU1761_PLAY_MIXER_MONO 0x4022
  36. #define ADAU1761_PLAY_HP_LEFT_VOL 0x4023
  37. #define ADAU1761_PLAY_HP_RIGHT_VOL 0x4024
  38. #define ADAU1761_PLAY_LINE_LEFT_VOL 0x4025
  39. #define ADAU1761_PLAY_LINE_RIGHT_VOL 0x4026
  40. #define ADAU1761_PLAY_MONO_OUTPUT_VOL 0x4027
  41. #define ADAU1761_POP_CLICK_SUPPRESS 0x4028
  42. #define ADAU1761_JACK_DETECT_PIN 0x4031
  43. #define ADAU1761_DEJITTER 0x4036
  44. #define ADAU1761_CLK_ENABLE0 0x40f9
  45. #define ADAU1761_CLK_ENABLE1 0x40fa
  46. #define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW BIT(0)
  47. #define ADAU1761_DIGMIC_JACKDETECT_DIGMIC BIT(5)
  48. #define ADAU1761_DIFF_INPUT_VOL_LDEN BIT(0)
  49. #define ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP BIT(0)
  50. #define ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE BIT(1)
  51. #define ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP BIT(0)
  52. #define ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP BIT(0)
  53. #define ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP BIT(0)
  54. #define ADAU1761_FIRMWARE "adau1761.bin"
  55. static const struct reg_default adau1761_reg_defaults[] = {
  56. { ADAU1761_DEJITTER, 0x03 },
  57. { ADAU1761_DIGMIC_JACKDETECT, 0x00 },
  58. { ADAU1761_REC_MIXER_LEFT0, 0x00 },
  59. { ADAU1761_REC_MIXER_LEFT1, 0x00 },
  60. { ADAU1761_REC_MIXER_RIGHT0, 0x00 },
  61. { ADAU1761_REC_MIXER_RIGHT1, 0x00 },
  62. { ADAU1761_LEFT_DIFF_INPUT_VOL, 0x00 },
  63. { ADAU1761_RIGHT_DIFF_INPUT_VOL, 0x00 },
  64. { ADAU1761_PLAY_LR_MIXER_LEFT, 0x00 },
  65. { ADAU1761_PLAY_MIXER_LEFT0, 0x00 },
  66. { ADAU1761_PLAY_MIXER_LEFT1, 0x00 },
  67. { ADAU1761_PLAY_MIXER_RIGHT0, 0x00 },
  68. { ADAU1761_PLAY_MIXER_RIGHT1, 0x00 },
  69. { ADAU1761_PLAY_LR_MIXER_RIGHT, 0x00 },
  70. { ADAU1761_PLAY_MIXER_MONO, 0x00 },
  71. { ADAU1761_PLAY_HP_LEFT_VOL, 0x00 },
  72. { ADAU1761_PLAY_HP_RIGHT_VOL, 0x00 },
  73. { ADAU1761_PLAY_LINE_LEFT_VOL, 0x00 },
  74. { ADAU1761_PLAY_LINE_RIGHT_VOL, 0x00 },
  75. { ADAU1761_PLAY_MONO_OUTPUT_VOL, 0x00 },
  76. { ADAU1761_POP_CLICK_SUPPRESS, 0x00 },
  77. { ADAU1761_JACK_DETECT_PIN, 0x00 },
  78. { ADAU1761_CLK_ENABLE0, 0x00 },
  79. { ADAU1761_CLK_ENABLE1, 0x00 },
  80. { ADAU17X1_CLOCK_CONTROL, 0x00 },
  81. { ADAU17X1_PLL_CONTROL, 0x00 },
  82. { ADAU17X1_REC_POWER_MGMT, 0x00 },
  83. { ADAU17X1_MICBIAS, 0x00 },
  84. { ADAU17X1_SERIAL_PORT0, 0x00 },
  85. { ADAU17X1_SERIAL_PORT1, 0x00 },
  86. { ADAU17X1_CONVERTER0, 0x00 },
  87. { ADAU17X1_CONVERTER1, 0x00 },
  88. { ADAU17X1_LEFT_INPUT_DIGITAL_VOL, 0x00 },
  89. { ADAU17X1_RIGHT_INPUT_DIGITAL_VOL, 0x00 },
  90. { ADAU17X1_ADC_CONTROL, 0x00 },
  91. { ADAU17X1_PLAY_POWER_MGMT, 0x00 },
  92. { ADAU17X1_DAC_CONTROL0, 0x00 },
  93. { ADAU17X1_DAC_CONTROL1, 0x00 },
  94. { ADAU17X1_DAC_CONTROL2, 0x00 },
  95. { ADAU17X1_SERIAL_PORT_PAD, 0xaa },
  96. { ADAU17X1_CONTROL_PORT_PAD0, 0xaa },
  97. { ADAU17X1_CONTROL_PORT_PAD1, 0x00 },
  98. { ADAU17X1_DSP_SAMPLING_RATE, 0x01 },
  99. { ADAU17X1_SERIAL_INPUT_ROUTE, 0x00 },
  100. { ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x00 },
  101. { ADAU17X1_DSP_ENABLE, 0x00 },
  102. { ADAU17X1_DSP_RUN, 0x00 },
  103. { ADAU17X1_SERIAL_SAMPLING_RATE, 0x00 },
  104. };
  105. static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
  106. static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
  107. static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
  108. static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
  109. static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
  110. static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
  111. static const unsigned int adau1761_bias_select_values[] = {
  112. 0, 2, 3,
  113. };
  114. static const char * const adau1761_bias_select_text[] = {
  115. "Normal operation", "Enhanced performance", "Power saving",
  116. };
  117. static const char * const adau1761_bias_select_extreme_text[] = {
  118. "Normal operation", "Extreme power saving", "Enhanced performance",
  119. "Power saving",
  120. };
  121. static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
  122. ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
  123. static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
  124. ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
  125. static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
  126. ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
  127. static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum,
  128. ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text,
  129. adau1761_bias_select_values);
  130. static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum,
  131. ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text,
  132. adau1761_bias_select_values);
  133. static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = {
  134. SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT,
  135. 4, 1, 0),
  136. };
  137. static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = {
  138. SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL,
  139. ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0,
  140. adau1761_diff_in_tlv),
  141. SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL,
  142. ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0),
  143. SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1,
  144. ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv),
  145. };
  146. static const struct snd_kcontrol_new adau1761_single_mode_controls[] = {
  147. SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
  148. 4, 7, 0, adau1761_sing_in_tlv),
  149. SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
  150. 1, 7, 0, adau1761_sing_in_tlv),
  151. SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
  152. 4, 7, 0, adau1761_sing_in_tlv),
  153. SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
  154. 1, 7, 0, adau1761_sing_in_tlv),
  155. };
  156. static const struct snd_kcontrol_new adau1761_controls[] = {
  157. SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1,
  158. ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv),
  159. SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL,
  160. ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
  161. SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL,
  162. ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0),
  163. SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL,
  164. ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
  165. SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL,
  166. ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0),
  167. SOC_ENUM("ADC Bias", adau1761_adc_bias_enum),
  168. SOC_ENUM("DAC Bias", adau1761_dac_bias_enum),
  169. SOC_ENUM("Capture Bias", adau1761_capture_bias_enum),
  170. SOC_ENUM("Playback Bias", adau1761_playback_bias_enum),
  171. SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum),
  172. };
  173. static const struct snd_kcontrol_new adau1761_mono_controls[] = {
  174. SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL,
  175. 2, 0x3f, 0, adau1761_out_tlv),
  176. SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL,
  177. 1, 1, 0),
  178. };
  179. static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = {
  180. SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
  181. ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0),
  182. SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
  183. ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0),
  184. SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
  185. ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv),
  186. SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
  187. ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv),
  188. SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
  189. ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv),
  190. };
  191. static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = {
  192. SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
  193. ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0),
  194. SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
  195. ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0),
  196. SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
  197. ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv),
  198. SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
  199. ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv),
  200. SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
  201. ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv),
  202. };
  203. static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = {
  204. SOC_DAPM_SINGLE_TLV("Left Volume",
  205. ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv),
  206. SOC_DAPM_SINGLE_TLV("Right Volume",
  207. ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv),
  208. };
  209. static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = {
  210. SOC_DAPM_SINGLE_TLV("Left Volume",
  211. ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv),
  212. SOC_DAPM_SINGLE_TLV("Right Volume",
  213. ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv),
  214. };
  215. static const char * const adau1761_input_mux_text[] = {
  216. "ADC", "DMIC",
  217. };
  218. static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
  219. ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
  220. static const struct snd_kcontrol_new adau1761_input_mux_control =
  221. SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
  222. static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
  223. struct snd_kcontrol *kcontrol, int event)
  224. {
  225. struct adau *adau = snd_soc_codec_get_drvdata(w->codec);
  226. /* After any power changes have been made the dejitter circuit
  227. * has to be reinitialized. */
  228. regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
  229. if (!adau->master)
  230. regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
  231. return 0;
  232. }
  233. static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
  234. SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
  235. NULL, 0),
  236. SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
  237. NULL, 0),
  238. SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
  239. 0, 0, adau1761_left_mixer_controls),
  240. SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
  241. 0, 0, adau1761_right_mixer_controls),
  242. SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
  243. 0, 0, adau1761_left_lr_mixer_controls),
  244. SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
  245. 0, 0, adau1761_right_lr_mixer_controls),
  246. SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
  247. 0, 0, NULL, 0),
  248. SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
  249. SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
  250. SND_SOC_DAPM_INPUT("LAUX"),
  251. SND_SOC_DAPM_INPUT("RAUX"),
  252. SND_SOC_DAPM_INPUT("LINP"),
  253. SND_SOC_DAPM_INPUT("LINN"),
  254. SND_SOC_DAPM_INPUT("RINP"),
  255. SND_SOC_DAPM_INPUT("RINN"),
  256. SND_SOC_DAPM_OUTPUT("LOUT"),
  257. SND_SOC_DAPM_OUTPUT("ROUT"),
  258. SND_SOC_DAPM_OUTPUT("LHP"),
  259. SND_SOC_DAPM_OUTPUT("RHP"),
  260. };
  261. static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
  262. SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
  263. 0, 0, NULL, 0),
  264. SND_SOC_DAPM_OUTPUT("MONOOUT"),
  265. };
  266. static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
  267. SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
  268. 0, 0, NULL, 0),
  269. };
  270. static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
  271. { "Left Input Mixer", NULL, "LINP" },
  272. { "Left Input Mixer", NULL, "LINN" },
  273. { "Left Input Mixer", NULL, "LAUX" },
  274. { "Right Input Mixer", NULL, "RINP" },
  275. { "Right Input Mixer", NULL, "RINN" },
  276. { "Right Input Mixer", NULL, "RAUX" },
  277. { "Left Playback Mixer", NULL, "Left Playback Enable"},
  278. { "Right Playback Mixer", NULL, "Right Playback Enable"},
  279. { "Left LR Playback Mixer", NULL, "Left Playback Enable"},
  280. { "Right LR Playback Mixer", NULL, "Right Playback Enable"},
  281. { "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
  282. { "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
  283. { "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
  284. { "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
  285. { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
  286. { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
  287. { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
  288. { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
  289. { "LHP", NULL, "Left Playback Mixer" },
  290. { "RHP", NULL, "Right Playback Mixer" },
  291. { "LHP", NULL, "Headphone" },
  292. { "RHP", NULL, "Headphone" },
  293. { "LOUT", NULL, "Left LR Playback Mixer" },
  294. { "ROUT", NULL, "Right LR Playback Mixer" },
  295. { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
  296. { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
  297. { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
  298. { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
  299. { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
  300. { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
  301. };
  302. static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
  303. { "Mono Playback Mixer", NULL, "Left Playback Mixer" },
  304. { "Mono Playback Mixer", NULL, "Right Playback Mixer" },
  305. { "MONOOUT", NULL, "Mono Playback Mixer" },
  306. };
  307. static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
  308. { "Headphone", NULL, "Headphone VGND" },
  309. };
  310. static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
  311. SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
  312. &adau1761_input_mux_control),
  313. SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
  314. &adau1761_input_mux_control),
  315. SND_SOC_DAPM_INPUT("DMIC"),
  316. };
  317. static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
  318. { "Left Decimator Mux", "ADC", "Left Input Mixer" },
  319. { "Left Decimator Mux", "DMIC", "DMIC" },
  320. { "Right Decimator Mux", "ADC", "Right Input Mixer" },
  321. { "Right Decimator Mux", "DMIC", "DMIC" },
  322. { "Left Decimator", NULL, "Left Decimator Mux" },
  323. { "Right Decimator", NULL, "Right Decimator Mux" },
  324. };
  325. static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
  326. { "Left Decimator", NULL, "Left Input Mixer" },
  327. { "Right Decimator", NULL, "Right Input Mixer" },
  328. };
  329. static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
  330. SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
  331. 0, 0, NULL, 0),
  332. SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
  333. 1, 0, NULL, 0),
  334. SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
  335. 3, 0, NULL, 0),
  336. SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
  337. 4, 0, NULL, 0),
  338. SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
  339. 2, 0, NULL, 0),
  340. SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
  341. SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
  342. SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
  343. 0, 0, NULL, 0),
  344. SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
  345. 1, 0, NULL, 0),
  346. };
  347. static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
  348. { "Left Decimator", NULL, "Digital Clock 0", },
  349. { "Right Decimator", NULL, "Digital Clock 0", },
  350. { "Left DAC", NULL, "Digital Clock 0", },
  351. { "Right DAC", NULL, "Digital Clock 0", },
  352. { "AIFCLK", NULL, "Digital Clock 1" },
  353. { "Playback", NULL, "Serial Port Clock" },
  354. { "Capture", NULL, "Serial Port Clock" },
  355. { "Playback", NULL, "Serial Input Routing Clock" },
  356. { "Capture", NULL, "Serial Output Routing Clock" },
  357. { "Left Decimator", NULL, "Decimator Resync Clock" },
  358. { "Right Decimator", NULL, "Decimator Resync Clock" },
  359. { "Left DAC", NULL, "Interpolator Resync Clock" },
  360. { "Right DAC", NULL, "Interpolator Resync Clock" },
  361. { "DSP", NULL, "Digital Clock 0" },
  362. { "Slew Clock", NULL, "Digital Clock 0" },
  363. { "Right Playback Mixer", NULL, "Slew Clock" },
  364. { "Left Playback Mixer", NULL, "Slew Clock" },
  365. { "Left Input Mixer", NULL, "ALC Clock" },
  366. { "Right Input Mixer", NULL, "ALC Clock" },
  367. { "Digital Clock 0", NULL, "SYSCLK" },
  368. { "Digital Clock 1", NULL, "SYSCLK" },
  369. };
  370. static int adau1761_set_bias_level(struct snd_soc_codec *codec,
  371. enum snd_soc_bias_level level)
  372. {
  373. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  374. switch (level) {
  375. case SND_SOC_BIAS_ON:
  376. break;
  377. case SND_SOC_BIAS_PREPARE:
  378. break;
  379. case SND_SOC_BIAS_STANDBY:
  380. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  381. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
  382. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
  383. break;
  384. case SND_SOC_BIAS_OFF:
  385. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  386. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
  387. break;
  388. }
  389. codec->dapm.bias_level = level;
  390. return 0;
  391. }
  392. static enum adau1761_output_mode adau1761_get_lineout_mode(
  393. struct snd_soc_codec *codec)
  394. {
  395. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  396. if (pdata)
  397. return pdata->lineout_mode;
  398. return ADAU1761_OUTPUT_MODE_LINE;
  399. }
  400. static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
  401. {
  402. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  403. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  404. enum adau1761_digmic_jackdet_pin_mode mode;
  405. unsigned int val = 0;
  406. int ret;
  407. if (pdata)
  408. mode = pdata->digmic_jackdetect_pin_mode;
  409. else
  410. mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
  411. switch (mode) {
  412. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
  413. switch (pdata->jackdetect_debounce_time) {
  414. case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
  415. case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
  416. case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
  417. case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
  418. val |= pdata->jackdetect_debounce_time << 6;
  419. break;
  420. default:
  421. return -EINVAL;
  422. }
  423. if (pdata->jackdetect_active_low)
  424. val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
  425. ret = snd_soc_add_codec_controls(codec,
  426. adau1761_jack_detect_controls,
  427. ARRAY_SIZE(adau1761_jack_detect_controls));
  428. if (ret)
  429. return ret;
  430. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
  431. ret = snd_soc_dapm_add_routes(&codec->dapm,
  432. adau1761_no_dmic_routes,
  433. ARRAY_SIZE(adau1761_no_dmic_routes));
  434. if (ret)
  435. return ret;
  436. break;
  437. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
  438. ret = snd_soc_dapm_new_controls(&codec->dapm,
  439. adau1761_dmic_widgets,
  440. ARRAY_SIZE(adau1761_dmic_widgets));
  441. if (ret)
  442. return ret;
  443. ret = snd_soc_dapm_add_routes(&codec->dapm,
  444. adau1761_dmic_routes,
  445. ARRAY_SIZE(adau1761_dmic_routes));
  446. if (ret)
  447. return ret;
  448. val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
  449. break;
  450. default:
  451. return -EINVAL;
  452. }
  453. regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
  454. return 0;
  455. }
  456. static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
  457. {
  458. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  459. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  460. enum adau1761_output_mode mode;
  461. int ret;
  462. if (pdata)
  463. mode = pdata->headphone_mode;
  464. else
  465. mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
  466. switch (mode) {
  467. case ADAU1761_OUTPUT_MODE_LINE:
  468. break;
  469. case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
  470. regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
  471. ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
  472. ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
  473. ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
  474. ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
  475. /* fallthrough */
  476. case ADAU1761_OUTPUT_MODE_HEADPHONE:
  477. regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
  478. ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
  479. ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
  480. break;
  481. default:
  482. return -EINVAL;
  483. }
  484. if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
  485. ret = snd_soc_dapm_new_controls(&codec->dapm,
  486. adau1761_capless_dapm_widgets,
  487. ARRAY_SIZE(adau1761_capless_dapm_widgets));
  488. if (ret)
  489. return ret;
  490. ret = snd_soc_dapm_add_routes(&codec->dapm,
  491. adau1761_capless_dapm_routes,
  492. ARRAY_SIZE(adau1761_capless_dapm_routes));
  493. } else {
  494. ret = snd_soc_add_codec_controls(codec, adau1761_mono_controls,
  495. ARRAY_SIZE(adau1761_mono_controls));
  496. if (ret)
  497. return ret;
  498. ret = snd_soc_dapm_new_controls(&codec->dapm,
  499. adau1761_mono_dapm_widgets,
  500. ARRAY_SIZE(adau1761_mono_dapm_widgets));
  501. if (ret)
  502. return ret;
  503. ret = snd_soc_dapm_add_routes(&codec->dapm,
  504. adau1761_mono_dapm_routes,
  505. ARRAY_SIZE(adau1761_mono_dapm_routes));
  506. }
  507. return ret;
  508. }
  509. static bool adau1761_readable_register(struct device *dev, unsigned int reg)
  510. {
  511. switch (reg) {
  512. case ADAU1761_DIGMIC_JACKDETECT:
  513. case ADAU1761_REC_MIXER_LEFT0:
  514. case ADAU1761_REC_MIXER_LEFT1:
  515. case ADAU1761_REC_MIXER_RIGHT0:
  516. case ADAU1761_REC_MIXER_RIGHT1:
  517. case ADAU1761_LEFT_DIFF_INPUT_VOL:
  518. case ADAU1761_RIGHT_DIFF_INPUT_VOL:
  519. case ADAU1761_PLAY_LR_MIXER_LEFT:
  520. case ADAU1761_PLAY_MIXER_LEFT0:
  521. case ADAU1761_PLAY_MIXER_LEFT1:
  522. case ADAU1761_PLAY_MIXER_RIGHT0:
  523. case ADAU1761_PLAY_MIXER_RIGHT1:
  524. case ADAU1761_PLAY_LR_MIXER_RIGHT:
  525. case ADAU1761_PLAY_MIXER_MONO:
  526. case ADAU1761_PLAY_HP_LEFT_VOL:
  527. case ADAU1761_PLAY_HP_RIGHT_VOL:
  528. case ADAU1761_PLAY_LINE_LEFT_VOL:
  529. case ADAU1761_PLAY_LINE_RIGHT_VOL:
  530. case ADAU1761_PLAY_MONO_OUTPUT_VOL:
  531. case ADAU1761_POP_CLICK_SUPPRESS:
  532. case ADAU1761_JACK_DETECT_PIN:
  533. case ADAU1761_DEJITTER:
  534. case ADAU1761_CLK_ENABLE0:
  535. case ADAU1761_CLK_ENABLE1:
  536. return true;
  537. default:
  538. break;
  539. }
  540. return adau17x1_readable_register(dev, reg);
  541. }
  542. static int adau1761_codec_probe(struct snd_soc_codec *codec)
  543. {
  544. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  545. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  546. int ret;
  547. ret = adau17x1_add_widgets(codec);
  548. if (ret < 0)
  549. return ret;
  550. if (pdata && pdata->input_differential) {
  551. regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
  552. ADAU1761_DIFF_INPUT_VOL_LDEN,
  553. ADAU1761_DIFF_INPUT_VOL_LDEN);
  554. regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
  555. ADAU1761_DIFF_INPUT_VOL_LDEN,
  556. ADAU1761_DIFF_INPUT_VOL_LDEN);
  557. ret = snd_soc_add_codec_controls(codec,
  558. adau1761_differential_mode_controls,
  559. ARRAY_SIZE(adau1761_differential_mode_controls));
  560. if (ret)
  561. return ret;
  562. } else {
  563. ret = snd_soc_add_codec_controls(codec,
  564. adau1761_single_mode_controls,
  565. ARRAY_SIZE(adau1761_single_mode_controls));
  566. if (ret)
  567. return ret;
  568. }
  569. switch (adau1761_get_lineout_mode(codec)) {
  570. case ADAU1761_OUTPUT_MODE_LINE:
  571. break;
  572. case ADAU1761_OUTPUT_MODE_HEADPHONE:
  573. regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
  574. ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
  575. ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
  576. regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
  577. ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
  578. ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
  579. break;
  580. default:
  581. return -EINVAL;
  582. }
  583. ret = adau1761_setup_headphone_mode(codec);
  584. if (ret)
  585. return ret;
  586. ret = adau1761_setup_digmic_jackdetect(codec);
  587. if (ret)
  588. return ret;
  589. if (adau->type == ADAU1761) {
  590. ret = snd_soc_dapm_new_controls(&codec->dapm,
  591. adau1761_dapm_widgets,
  592. ARRAY_SIZE(adau1761_dapm_widgets));
  593. if (ret)
  594. return ret;
  595. ret = snd_soc_dapm_add_routes(&codec->dapm,
  596. adau1761_dapm_routes,
  597. ARRAY_SIZE(adau1761_dapm_routes));
  598. if (ret)
  599. return ret;
  600. ret = adau17x1_load_firmware(adau, codec->dev,
  601. ADAU1761_FIRMWARE);
  602. if (ret)
  603. dev_warn(codec->dev, "Failed to firmware\n");
  604. }
  605. ret = adau17x1_add_routes(codec);
  606. if (ret < 0)
  607. return ret;
  608. return 0;
  609. }
  610. static const struct snd_soc_codec_driver adau1761_codec_driver = {
  611. .probe = adau1761_codec_probe,
  612. .resume = adau17x1_resume,
  613. .set_bias_level = adau1761_set_bias_level,
  614. .suspend_bias_off = true,
  615. .controls = adau1761_controls,
  616. .num_controls = ARRAY_SIZE(adau1761_controls),
  617. .dapm_widgets = adau1x61_dapm_widgets,
  618. .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
  619. .dapm_routes = adau1x61_dapm_routes,
  620. .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
  621. };
  622. #define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
  623. SNDRV_PCM_FMTBIT_S32_LE)
  624. static struct snd_soc_dai_driver adau1361_dai_driver = {
  625. .name = "adau-hifi",
  626. .playback = {
  627. .stream_name = "Playback",
  628. .channels_min = 2,
  629. .channels_max = 4,
  630. .rates = SNDRV_PCM_RATE_8000_96000,
  631. .formats = ADAU1761_FORMATS,
  632. },
  633. .capture = {
  634. .stream_name = "Capture",
  635. .channels_min = 2,
  636. .channels_max = 4,
  637. .rates = SNDRV_PCM_RATE_8000_96000,
  638. .formats = ADAU1761_FORMATS,
  639. },
  640. .ops = &adau17x1_dai_ops,
  641. };
  642. static struct snd_soc_dai_driver adau1761_dai_driver = {
  643. .name = "adau-hifi",
  644. .playback = {
  645. .stream_name = "Playback",
  646. .channels_min = 2,
  647. .channels_max = 8,
  648. .rates = SNDRV_PCM_RATE_8000_96000,
  649. .formats = ADAU1761_FORMATS,
  650. },
  651. .capture = {
  652. .stream_name = "Capture",
  653. .channels_min = 2,
  654. .channels_max = 8,
  655. .rates = SNDRV_PCM_RATE_8000_96000,
  656. .formats = ADAU1761_FORMATS,
  657. },
  658. .ops = &adau17x1_dai_ops,
  659. };
  660. int adau1761_probe(struct device *dev, struct regmap *regmap,
  661. enum adau17x1_type type, void (*switch_mode)(struct device *dev))
  662. {
  663. struct snd_soc_dai_driver *dai_drv;
  664. int ret;
  665. ret = adau17x1_probe(dev, regmap, type, switch_mode);
  666. if (ret)
  667. return ret;
  668. if (type == ADAU1361)
  669. dai_drv = &adau1361_dai_driver;
  670. else
  671. dai_drv = &adau1761_dai_driver;
  672. return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
  673. }
  674. EXPORT_SYMBOL_GPL(adau1761_probe);
  675. const struct regmap_config adau1761_regmap_config = {
  676. .val_bits = 8,
  677. .reg_bits = 16,
  678. .max_register = 0x40fa,
  679. .reg_defaults = adau1761_reg_defaults,
  680. .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
  681. .readable_reg = adau1761_readable_register,
  682. .volatile_reg = adau17x1_volatile_register,
  683. .cache_type = REGCACHE_RBTREE,
  684. };
  685. EXPORT_SYMBOL_GPL(adau1761_regmap_config);
  686. MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
  687. MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
  688. MODULE_LICENSE("GPL");