adau1761.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. /*
  2. * Driver for ADAU1361/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 "/*(DEBLOBBED)*/"
  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 snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
  226. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  227. /* After any power changes have been made the dejitter circuit
  228. * has to be reinitialized. */
  229. regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
  230. if (!adau->master)
  231. regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
  232. return 0;
  233. }
  234. static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
  235. SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
  236. NULL, 0),
  237. SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
  238. NULL, 0),
  239. SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
  240. 0, 0, adau1761_left_mixer_controls),
  241. SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
  242. 0, 0, adau1761_right_mixer_controls),
  243. SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
  244. 0, 0, adau1761_left_lr_mixer_controls),
  245. SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
  246. 0, 0, adau1761_right_lr_mixer_controls),
  247. SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
  248. 0, 0, NULL, 0),
  249. SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
  250. SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
  251. SND_SOC_DAPM_INPUT("LAUX"),
  252. SND_SOC_DAPM_INPUT("RAUX"),
  253. SND_SOC_DAPM_INPUT("LINP"),
  254. SND_SOC_DAPM_INPUT("LINN"),
  255. SND_SOC_DAPM_INPUT("RINP"),
  256. SND_SOC_DAPM_INPUT("RINN"),
  257. SND_SOC_DAPM_OUTPUT("LOUT"),
  258. SND_SOC_DAPM_OUTPUT("ROUT"),
  259. SND_SOC_DAPM_OUTPUT("LHP"),
  260. SND_SOC_DAPM_OUTPUT("RHP"),
  261. };
  262. static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
  263. SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
  264. 0, 0, NULL, 0),
  265. SND_SOC_DAPM_OUTPUT("MONOOUT"),
  266. };
  267. static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
  268. SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
  269. 0, 0, NULL, 0),
  270. };
  271. static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
  272. { "Left Input Mixer", NULL, "LINP" },
  273. { "Left Input Mixer", NULL, "LINN" },
  274. { "Left Input Mixer", NULL, "LAUX" },
  275. { "Right Input Mixer", NULL, "RINP" },
  276. { "Right Input Mixer", NULL, "RINN" },
  277. { "Right Input Mixer", NULL, "RAUX" },
  278. { "Left Playback Mixer", NULL, "Left Playback Enable"},
  279. { "Right Playback Mixer", NULL, "Right Playback Enable"},
  280. { "Left LR Playback Mixer", NULL, "Left Playback Enable"},
  281. { "Right LR Playback Mixer", NULL, "Right Playback Enable"},
  282. { "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
  283. { "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
  284. { "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
  285. { "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
  286. { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
  287. { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
  288. { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
  289. { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
  290. { "LHP", NULL, "Left Playback Mixer" },
  291. { "RHP", NULL, "Right Playback Mixer" },
  292. { "LHP", NULL, "Headphone" },
  293. { "RHP", NULL, "Headphone" },
  294. { "LOUT", NULL, "Left LR Playback Mixer" },
  295. { "ROUT", NULL, "Right LR Playback Mixer" },
  296. { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
  297. { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
  298. { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
  299. { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
  300. { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
  301. { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
  302. };
  303. static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
  304. { "Mono Playback Mixer", NULL, "Left Playback Mixer" },
  305. { "Mono Playback Mixer", NULL, "Right Playback Mixer" },
  306. { "MONOOUT", NULL, "Mono Playback Mixer" },
  307. };
  308. static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
  309. { "Headphone", NULL, "Headphone VGND" },
  310. };
  311. static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
  312. SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
  313. &adau1761_input_mux_control),
  314. SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
  315. &adau1761_input_mux_control),
  316. SND_SOC_DAPM_INPUT("DMIC"),
  317. };
  318. static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
  319. { "Left Decimator Mux", "ADC", "Left Input Mixer" },
  320. { "Left Decimator Mux", "DMIC", "DMIC" },
  321. { "Right Decimator Mux", "ADC", "Right Input Mixer" },
  322. { "Right Decimator Mux", "DMIC", "DMIC" },
  323. { "Left Decimator", NULL, "Left Decimator Mux" },
  324. { "Right Decimator", NULL, "Right Decimator Mux" },
  325. };
  326. static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
  327. { "Left Decimator", NULL, "Left Input Mixer" },
  328. { "Right Decimator", NULL, "Right Input Mixer" },
  329. };
  330. static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
  331. SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
  332. 0, 0, NULL, 0),
  333. SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
  334. 1, 0, NULL, 0),
  335. SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
  336. 3, 0, NULL, 0),
  337. SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
  338. 4, 0, NULL, 0),
  339. SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
  340. 2, 0, NULL, 0),
  341. SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
  342. SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
  343. SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
  344. 0, 0, NULL, 0),
  345. SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
  346. 1, 0, NULL, 0),
  347. };
  348. static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
  349. { "Left Decimator", NULL, "Digital Clock 0", },
  350. { "Right Decimator", NULL, "Digital Clock 0", },
  351. { "Left DAC", NULL, "Digital Clock 0", },
  352. { "Right DAC", NULL, "Digital Clock 0", },
  353. { "AIFCLK", NULL, "Digital Clock 1" },
  354. { "Playback", NULL, "Serial Port Clock" },
  355. { "Capture", NULL, "Serial Port Clock" },
  356. { "Playback", NULL, "Serial Input Routing Clock" },
  357. { "Capture", NULL, "Serial Output Routing Clock" },
  358. { "Left Decimator", NULL, "Decimator Resync Clock" },
  359. { "Right Decimator", NULL, "Decimator Resync Clock" },
  360. { "Left DAC", NULL, "Interpolator Resync Clock" },
  361. { "Right DAC", NULL, "Interpolator Resync Clock" },
  362. { "DSP", NULL, "Digital Clock 0" },
  363. { "Slew Clock", NULL, "Digital Clock 0" },
  364. { "Right Playback Mixer", NULL, "Slew Clock" },
  365. { "Left Playback Mixer", NULL, "Slew Clock" },
  366. { "Left Input Mixer", NULL, "ALC Clock" },
  367. { "Right Input Mixer", NULL, "ALC Clock" },
  368. { "Digital Clock 0", NULL, "SYSCLK" },
  369. { "Digital Clock 1", NULL, "SYSCLK" },
  370. };
  371. static int adau1761_set_bias_level(struct snd_soc_codec *codec,
  372. enum snd_soc_bias_level level)
  373. {
  374. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  375. switch (level) {
  376. case SND_SOC_BIAS_ON:
  377. break;
  378. case SND_SOC_BIAS_PREPARE:
  379. break;
  380. case SND_SOC_BIAS_STANDBY:
  381. regcache_cache_only(adau->regmap, false);
  382. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  383. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
  384. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
  385. if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
  386. regcache_sync(adau->regmap);
  387. break;
  388. case SND_SOC_BIAS_OFF:
  389. regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
  390. ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
  391. regcache_cache_only(adau->regmap, true);
  392. break;
  393. }
  394. return 0;
  395. }
  396. static enum adau1761_output_mode adau1761_get_lineout_mode(
  397. struct snd_soc_codec *codec)
  398. {
  399. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  400. if (pdata)
  401. return pdata->lineout_mode;
  402. return ADAU1761_OUTPUT_MODE_LINE;
  403. }
  404. static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
  405. {
  406. struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
  407. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  408. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  409. enum adau1761_digmic_jackdet_pin_mode mode;
  410. unsigned int val = 0;
  411. int ret;
  412. if (pdata)
  413. mode = pdata->digmic_jackdetect_pin_mode;
  414. else
  415. mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
  416. switch (mode) {
  417. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
  418. switch (pdata->jackdetect_debounce_time) {
  419. case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
  420. case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
  421. case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
  422. case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
  423. val |= pdata->jackdetect_debounce_time << 6;
  424. break;
  425. default:
  426. return -EINVAL;
  427. }
  428. if (pdata->jackdetect_active_low)
  429. val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
  430. ret = snd_soc_add_codec_controls(codec,
  431. adau1761_jack_detect_controls,
  432. ARRAY_SIZE(adau1761_jack_detect_controls));
  433. if (ret)
  434. return ret;
  435. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
  436. ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
  437. ARRAY_SIZE(adau1761_no_dmic_routes));
  438. if (ret)
  439. return ret;
  440. break;
  441. case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
  442. ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
  443. ARRAY_SIZE(adau1761_dmic_widgets));
  444. if (ret)
  445. return ret;
  446. ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
  447. ARRAY_SIZE(adau1761_dmic_routes));
  448. if (ret)
  449. return ret;
  450. val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
  451. break;
  452. default:
  453. return -EINVAL;
  454. }
  455. regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
  456. return 0;
  457. }
  458. static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
  459. {
  460. struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
  461. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  462. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  463. enum adau1761_output_mode mode;
  464. int ret;
  465. if (pdata)
  466. mode = pdata->headphone_mode;
  467. else
  468. mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
  469. switch (mode) {
  470. case ADAU1761_OUTPUT_MODE_LINE:
  471. break;
  472. case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
  473. regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
  474. ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
  475. ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
  476. ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
  477. ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
  478. /* fallthrough */
  479. case ADAU1761_OUTPUT_MODE_HEADPHONE:
  480. regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
  481. ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
  482. ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
  483. break;
  484. default:
  485. return -EINVAL;
  486. }
  487. if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
  488. ret = snd_soc_dapm_new_controls(dapm,
  489. adau1761_capless_dapm_widgets,
  490. ARRAY_SIZE(adau1761_capless_dapm_widgets));
  491. if (ret)
  492. return ret;
  493. ret = snd_soc_dapm_add_routes(dapm,
  494. adau1761_capless_dapm_routes,
  495. ARRAY_SIZE(adau1761_capless_dapm_routes));
  496. } else {
  497. ret = snd_soc_add_codec_controls(codec, adau1761_mono_controls,
  498. ARRAY_SIZE(adau1761_mono_controls));
  499. if (ret)
  500. return ret;
  501. ret = snd_soc_dapm_new_controls(dapm,
  502. adau1761_mono_dapm_widgets,
  503. ARRAY_SIZE(adau1761_mono_dapm_widgets));
  504. if (ret)
  505. return ret;
  506. ret = snd_soc_dapm_add_routes(dapm,
  507. adau1761_mono_dapm_routes,
  508. ARRAY_SIZE(adau1761_mono_dapm_routes));
  509. }
  510. return ret;
  511. }
  512. static bool adau1761_readable_register(struct device *dev, unsigned int reg)
  513. {
  514. switch (reg) {
  515. case ADAU1761_DIGMIC_JACKDETECT:
  516. case ADAU1761_REC_MIXER_LEFT0:
  517. case ADAU1761_REC_MIXER_LEFT1:
  518. case ADAU1761_REC_MIXER_RIGHT0:
  519. case ADAU1761_REC_MIXER_RIGHT1:
  520. case ADAU1761_LEFT_DIFF_INPUT_VOL:
  521. case ADAU1761_RIGHT_DIFF_INPUT_VOL:
  522. case ADAU1761_PLAY_LR_MIXER_LEFT:
  523. case ADAU1761_PLAY_MIXER_LEFT0:
  524. case ADAU1761_PLAY_MIXER_LEFT1:
  525. case ADAU1761_PLAY_MIXER_RIGHT0:
  526. case ADAU1761_PLAY_MIXER_RIGHT1:
  527. case ADAU1761_PLAY_LR_MIXER_RIGHT:
  528. case ADAU1761_PLAY_MIXER_MONO:
  529. case ADAU1761_PLAY_HP_LEFT_VOL:
  530. case ADAU1761_PLAY_HP_RIGHT_VOL:
  531. case ADAU1761_PLAY_LINE_LEFT_VOL:
  532. case ADAU1761_PLAY_LINE_RIGHT_VOL:
  533. case ADAU1761_PLAY_MONO_OUTPUT_VOL:
  534. case ADAU1761_POP_CLICK_SUPPRESS:
  535. case ADAU1761_JACK_DETECT_PIN:
  536. case ADAU1761_DEJITTER:
  537. case ADAU1761_CLK_ENABLE0:
  538. case ADAU1761_CLK_ENABLE1:
  539. return true;
  540. default:
  541. break;
  542. }
  543. return adau17x1_readable_register(dev, reg);
  544. }
  545. static int adau1761_codec_probe(struct snd_soc_codec *codec)
  546. {
  547. struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
  548. struct adau1761_platform_data *pdata = codec->dev->platform_data;
  549. struct adau *adau = snd_soc_codec_get_drvdata(codec);
  550. int ret;
  551. ret = adau17x1_add_widgets(codec);
  552. if (ret < 0)
  553. return ret;
  554. if (pdata && pdata->input_differential) {
  555. regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
  556. ADAU1761_DIFF_INPUT_VOL_LDEN,
  557. ADAU1761_DIFF_INPUT_VOL_LDEN);
  558. regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
  559. ADAU1761_DIFF_INPUT_VOL_LDEN,
  560. ADAU1761_DIFF_INPUT_VOL_LDEN);
  561. ret = snd_soc_add_codec_controls(codec,
  562. adau1761_differential_mode_controls,
  563. ARRAY_SIZE(adau1761_differential_mode_controls));
  564. if (ret)
  565. return ret;
  566. } else {
  567. ret = snd_soc_add_codec_controls(codec,
  568. adau1761_single_mode_controls,
  569. ARRAY_SIZE(adau1761_single_mode_controls));
  570. if (ret)
  571. return ret;
  572. }
  573. switch (adau1761_get_lineout_mode(codec)) {
  574. case ADAU1761_OUTPUT_MODE_LINE:
  575. break;
  576. case ADAU1761_OUTPUT_MODE_HEADPHONE:
  577. regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
  578. ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
  579. ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
  580. regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
  581. ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
  582. ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
  583. break;
  584. default:
  585. return -EINVAL;
  586. }
  587. ret = adau1761_setup_headphone_mode(codec);
  588. if (ret)
  589. return ret;
  590. ret = adau1761_setup_digmic_jackdetect(codec);
  591. if (ret)
  592. return ret;
  593. if (adau->type == ADAU1761) {
  594. ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
  595. ARRAY_SIZE(adau1761_dapm_widgets));
  596. if (ret)
  597. return ret;
  598. ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
  599. ARRAY_SIZE(adau1761_dapm_routes));
  600. if (ret)
  601. return ret;
  602. }
  603. ret = adau17x1_add_routes(codec);
  604. if (ret < 0)
  605. return ret;
  606. return 0;
  607. }
  608. static const struct snd_soc_codec_driver adau1761_codec_driver = {
  609. .probe = adau1761_codec_probe,
  610. .resume = adau17x1_resume,
  611. .set_bias_level = adau1761_set_bias_level,
  612. .suspend_bias_off = true,
  613. .component_driver = {
  614. .controls = adau1761_controls,
  615. .num_controls = ARRAY_SIZE(adau1761_controls),
  616. .dapm_widgets = adau1x61_dapm_widgets,
  617. .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
  618. .dapm_routes = adau1x61_dapm_routes,
  619. .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
  620. },
  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. const char *firmware_name;
  665. int ret;
  666. if (type == ADAU1361) {
  667. dai_drv = &adau1361_dai_driver;
  668. firmware_name = NULL;
  669. } else {
  670. dai_drv = &adau1761_dai_driver;
  671. firmware_name = ADAU1761_FIRMWARE;
  672. }
  673. ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
  674. if (ret)
  675. return ret;
  676. /* Enable cache only mode as we could miss writes before bias level
  677. * reaches standby and the core clock is enabled */
  678. regcache_cache_only(regmap, true);
  679. return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
  680. }
  681. EXPORT_SYMBOL_GPL(adau1761_probe);
  682. const struct regmap_config adau1761_regmap_config = {
  683. .val_bits = 8,
  684. .reg_bits = 16,
  685. .max_register = 0x40fa,
  686. .reg_defaults = adau1761_reg_defaults,
  687. .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
  688. .readable_reg = adau1761_readable_register,
  689. .volatile_reg = adau17x1_volatile_register,
  690. .precious_reg = adau17x1_precious_register,
  691. .cache_type = REGCACHE_RBTREE,
  692. };
  693. EXPORT_SYMBOL_GPL(adau1761_regmap_config);
  694. MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
  695. MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
  696. MODULE_LICENSE("GPL");