wm8988.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * wm8988.c -- WM8988 ALSA SoC audio driver
  4. *
  5. * Copyright 2009 Wolfson Microelectronics plc
  6. * Copyright 2005 Openedhand Ltd.
  7. *
  8. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  9. */
  10. #include <linux/module.h>
  11. #include <linux/moduleparam.h>
  12. #include <linux/init.h>
  13. #include <linux/delay.h>
  14. #include <linux/pm.h>
  15. #include <linux/i2c.h>
  16. #include <linux/spi/spi.h>
  17. #include <linux/slab.h>
  18. #include <sound/core.h>
  19. #include <sound/pcm.h>
  20. #include <sound/pcm_params.h>
  21. #include <sound/tlv.h>
  22. #include <sound/soc.h>
  23. #include <sound/initval.h>
  24. #include "wm8988.h"
  25. /*
  26. * wm8988 register cache
  27. * We can't read the WM8988 register space when we
  28. * are using 2 wire for device control, so we cache them instead.
  29. */
  30. static const struct reg_default wm8988_reg_defaults[] = {
  31. { 0, 0x0097 },
  32. { 1, 0x0097 },
  33. { 2, 0x0079 },
  34. { 3, 0x0079 },
  35. { 5, 0x0008 },
  36. { 7, 0x000a },
  37. { 8, 0x0000 },
  38. { 10, 0x00ff },
  39. { 11, 0x00ff },
  40. { 12, 0x000f },
  41. { 13, 0x000f },
  42. { 16, 0x0000 },
  43. { 17, 0x007b },
  44. { 18, 0x0000 },
  45. { 19, 0x0032 },
  46. { 20, 0x0000 },
  47. { 21, 0x00c3 },
  48. { 22, 0x00c3 },
  49. { 23, 0x00c0 },
  50. { 24, 0x0000 },
  51. { 25, 0x0000 },
  52. { 26, 0x0000 },
  53. { 27, 0x0000 },
  54. { 31, 0x0000 },
  55. { 32, 0x0000 },
  56. { 33, 0x0000 },
  57. { 34, 0x0050 },
  58. { 35, 0x0050 },
  59. { 36, 0x0050 },
  60. { 37, 0x0050 },
  61. { 40, 0x0079 },
  62. { 41, 0x0079 },
  63. { 42, 0x0079 },
  64. };
  65. static bool wm8988_writeable(struct device *dev, unsigned int reg)
  66. {
  67. switch (reg) {
  68. case WM8988_LINVOL:
  69. case WM8988_RINVOL:
  70. case WM8988_LOUT1V:
  71. case WM8988_ROUT1V:
  72. case WM8988_ADCDAC:
  73. case WM8988_IFACE:
  74. case WM8988_SRATE:
  75. case WM8988_LDAC:
  76. case WM8988_RDAC:
  77. case WM8988_BASS:
  78. case WM8988_TREBLE:
  79. case WM8988_RESET:
  80. case WM8988_3D:
  81. case WM8988_ALC1:
  82. case WM8988_ALC2:
  83. case WM8988_ALC3:
  84. case WM8988_NGATE:
  85. case WM8988_LADC:
  86. case WM8988_RADC:
  87. case WM8988_ADCTL1:
  88. case WM8988_ADCTL2:
  89. case WM8988_PWR1:
  90. case WM8988_PWR2:
  91. case WM8988_ADCTL3:
  92. case WM8988_ADCIN:
  93. case WM8988_LADCIN:
  94. case WM8988_RADCIN:
  95. case WM8988_LOUTM1:
  96. case WM8988_LOUTM2:
  97. case WM8988_ROUTM1:
  98. case WM8988_ROUTM2:
  99. case WM8988_LOUT2V:
  100. case WM8988_ROUT2V:
  101. case WM8988_LPPB:
  102. return true;
  103. default:
  104. return false;
  105. }
  106. }
  107. /* codec private data */
  108. struct wm8988_priv {
  109. struct regmap *regmap;
  110. unsigned int sysclk;
  111. const struct snd_pcm_hw_constraint_list *sysclk_constraints;
  112. };
  113. #define wm8988_reset(c) snd_soc_component_write(c, WM8988_RESET, 0)
  114. /*
  115. * WM8988 Controls
  116. */
  117. static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"};
  118. static SOC_ENUM_SINGLE_DECL(bass_boost,
  119. WM8988_BASS, 7, bass_boost_txt);
  120. static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
  121. static SOC_ENUM_SINGLE_DECL(bass_filter,
  122. WM8988_BASS, 6, bass_filter_txt);
  123. static const char *treble_txt[] = {"8kHz", "4kHz"};
  124. static SOC_ENUM_SINGLE_DECL(treble,
  125. WM8988_TREBLE, 6, treble_txt);
  126. static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"};
  127. static SOC_ENUM_SINGLE_DECL(stereo_3d_lc,
  128. WM8988_3D, 5, stereo_3d_lc_txt);
  129. static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"};
  130. static SOC_ENUM_SINGLE_DECL(stereo_3d_uc,
  131. WM8988_3D, 6, stereo_3d_uc_txt);
  132. static const char *stereo_3d_func_txt[] = {"Capture", "Playback"};
  133. static SOC_ENUM_SINGLE_DECL(stereo_3d_func,
  134. WM8988_3D, 7, stereo_3d_func_txt);
  135. static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"};
  136. static SOC_ENUM_SINGLE_DECL(alc_func,
  137. WM8988_ALC1, 7, alc_func_txt);
  138. static const char *ng_type_txt[] = {"Constant PGA Gain",
  139. "Mute ADC Output"};
  140. static SOC_ENUM_SINGLE_DECL(ng_type,
  141. WM8988_NGATE, 1, ng_type_txt);
  142. static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"};
  143. static SOC_ENUM_SINGLE_DECL(deemph,
  144. WM8988_ADCDAC, 1, deemph_txt);
  145. static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert",
  146. "L + R Invert"};
  147. static SOC_ENUM_SINGLE_DECL(adcpol,
  148. WM8988_ADCDAC, 5, adcpol_txt);
  149. static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
  150. static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
  151. static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  152. static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
  153. static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
  154. static const struct snd_kcontrol_new wm8988_snd_controls[] = {
  155. SOC_ENUM("Bass Boost", bass_boost),
  156. SOC_ENUM("Bass Filter", bass_filter),
  157. SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1),
  158. SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0),
  159. SOC_ENUM("Treble Cut-off", treble),
  160. SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0),
  161. SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0),
  162. SOC_ENUM("3D Lower Cut-off", stereo_3d_lc),
  163. SOC_ENUM("3D Upper Cut-off", stereo_3d_uc),
  164. SOC_ENUM("3D Mode", stereo_3d_func),
  165. SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0),
  166. SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0),
  167. SOC_ENUM("ALC Capture Function", alc_func),
  168. SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0),
  169. SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0),
  170. SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0),
  171. SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0),
  172. SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0),
  173. SOC_ENUM("ALC Capture NG Type", ng_type),
  174. SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0),
  175. SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0),
  176. SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC,
  177. 0, 255, 0, adc_tlv),
  178. SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL,
  179. 0, 63, 0, pga_tlv),
  180. SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0),
  181. SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1),
  182. SOC_ENUM("Playback De-emphasis", deemph),
  183. SOC_ENUM("Capture Polarity", adcpol),
  184. SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0),
  185. SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0),
  186. SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv),
  187. SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1,
  188. bypass_tlv),
  189. SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1,
  190. bypass_tlv),
  191. SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1,
  192. bypass_tlv),
  193. SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1,
  194. bypass_tlv),
  195. SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V,
  196. WM8988_ROUT1V, 7, 1, 0),
  197. SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V,
  198. 0, 127, 0, out_tlv),
  199. SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V,
  200. WM8988_ROUT2V, 7, 1, 0),
  201. SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
  202. 0, 127, 0, out_tlv),
  203. };
  204. /*
  205. * DAPM Controls
  206. */
  207. static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
  208. struct snd_kcontrol *kcontrol, int event)
  209. {
  210. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  211. u16 adctl2 = snd_soc_component_read(component, WM8988_ADCTL2);
  212. /* Use the DAC to gate LRC if active, otherwise use ADC */
  213. if (snd_soc_component_read(component, WM8988_PWR2) & 0x180)
  214. adctl2 &= ~0x4;
  215. else
  216. adctl2 |= 0x4;
  217. return snd_soc_component_write(component, WM8988_ADCTL2, adctl2);
  218. }
  219. static const char *wm8988_line_texts[] = {
  220. "Line 1", "Line 2", "PGA", "Differential"};
  221. static const unsigned int wm8988_line_values[] = {
  222. 0, 1, 3, 4};
  223. static const struct soc_enum wm8988_lline_enum =
  224. SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7,
  225. ARRAY_SIZE(wm8988_line_texts),
  226. wm8988_line_texts,
  227. wm8988_line_values);
  228. static const struct snd_kcontrol_new wm8988_left_line_controls =
  229. SOC_DAPM_ENUM("Route", wm8988_lline_enum);
  230. static const struct soc_enum wm8988_rline_enum =
  231. SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7,
  232. ARRAY_SIZE(wm8988_line_texts),
  233. wm8988_line_texts,
  234. wm8988_line_values);
  235. static const struct snd_kcontrol_new wm8988_right_line_controls =
  236. SOC_DAPM_ENUM("Route", wm8988_rline_enum);
  237. /* Left Mixer */
  238. static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
  239. SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0),
  240. SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0),
  241. SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0),
  242. SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0),
  243. };
  244. /* Right Mixer */
  245. static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = {
  246. SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0),
  247. SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0),
  248. SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0),
  249. SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0),
  250. };
  251. static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"};
  252. static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
  253. /* Left PGA Mux */
  254. static const struct soc_enum wm8988_lpga_enum =
  255. SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3,
  256. ARRAY_SIZE(wm8988_pga_sel),
  257. wm8988_pga_sel,
  258. wm8988_pga_val);
  259. static const struct snd_kcontrol_new wm8988_left_pga_controls =
  260. SOC_DAPM_ENUM("Route", wm8988_lpga_enum);
  261. /* Right PGA Mux */
  262. static const struct soc_enum wm8988_rpga_enum =
  263. SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3,
  264. ARRAY_SIZE(wm8988_pga_sel),
  265. wm8988_pga_sel,
  266. wm8988_pga_val);
  267. static const struct snd_kcontrol_new wm8988_right_pga_controls =
  268. SOC_DAPM_ENUM("Route", wm8988_rpga_enum);
  269. /* Differential Mux */
  270. static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"};
  271. static SOC_ENUM_SINGLE_DECL(diffmux,
  272. WM8988_ADCIN, 8, wm8988_diff_sel);
  273. static const struct snd_kcontrol_new wm8988_diffmux_controls =
  274. SOC_DAPM_ENUM("Route", diffmux);
  275. /* Mono ADC Mux */
  276. static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)",
  277. "Mono (Right)", "Digital Mono"};
  278. static SOC_ENUM_SINGLE_DECL(monomux,
  279. WM8988_ADCIN, 6, wm8988_mono_mux);
  280. static const struct snd_kcontrol_new wm8988_monomux_controls =
  281. SOC_DAPM_ENUM("Route", monomux);
  282. static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
  283. SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0),
  284. SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
  285. &wm8988_diffmux_controls),
  286. SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
  287. &wm8988_monomux_controls),
  288. SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
  289. &wm8988_monomux_controls),
  290. SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0,
  291. &wm8988_left_pga_controls),
  292. SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0,
  293. &wm8988_right_pga_controls),
  294. SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
  295. &wm8988_left_line_controls),
  296. SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
  297. &wm8988_right_line_controls),
  298. SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
  299. SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
  300. SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
  301. SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
  302. SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
  303. &wm8988_left_mixer_controls[0],
  304. ARRAY_SIZE(wm8988_left_mixer_controls)),
  305. SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
  306. &wm8988_right_mixer_controls[0],
  307. ARRAY_SIZE(wm8988_right_mixer_controls)),
  308. SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0),
  309. SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0),
  310. SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0),
  311. SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0),
  312. SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control),
  313. SND_SOC_DAPM_OUTPUT("LOUT1"),
  314. SND_SOC_DAPM_OUTPUT("ROUT1"),
  315. SND_SOC_DAPM_OUTPUT("LOUT2"),
  316. SND_SOC_DAPM_OUTPUT("ROUT2"),
  317. SND_SOC_DAPM_OUTPUT("VREF"),
  318. SND_SOC_DAPM_INPUT("LINPUT1"),
  319. SND_SOC_DAPM_INPUT("LINPUT2"),
  320. SND_SOC_DAPM_INPUT("RINPUT1"),
  321. SND_SOC_DAPM_INPUT("RINPUT2"),
  322. };
  323. static const struct snd_soc_dapm_route wm8988_dapm_routes[] = {
  324. { "Left Line Mux", "Line 1", "LINPUT1" },
  325. { "Left Line Mux", "Line 2", "LINPUT2" },
  326. { "Left Line Mux", "PGA", "Left PGA Mux" },
  327. { "Left Line Mux", "Differential", "Differential Mux" },
  328. { "Right Line Mux", "Line 1", "RINPUT1" },
  329. { "Right Line Mux", "Line 2", "RINPUT2" },
  330. { "Right Line Mux", "PGA", "Right PGA Mux" },
  331. { "Right Line Mux", "Differential", "Differential Mux" },
  332. { "Left PGA Mux", "Line 1", "LINPUT1" },
  333. { "Left PGA Mux", "Line 2", "LINPUT2" },
  334. { "Left PGA Mux", "Differential", "Differential Mux" },
  335. { "Right PGA Mux", "Line 1", "RINPUT1" },
  336. { "Right PGA Mux", "Line 2", "RINPUT2" },
  337. { "Right PGA Mux", "Differential", "Differential Mux" },
  338. { "Differential Mux", "Line 1", "LINPUT1" },
  339. { "Differential Mux", "Line 1", "RINPUT1" },
  340. { "Differential Mux", "Line 2", "LINPUT2" },
  341. { "Differential Mux", "Line 2", "RINPUT2" },
  342. { "Left ADC Mux", "Stereo", "Left PGA Mux" },
  343. { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },
  344. { "Left ADC Mux", "Digital Mono", "Left PGA Mux" },
  345. { "Right ADC Mux", "Stereo", "Right PGA Mux" },
  346. { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },
  347. { "Right ADC Mux", "Digital Mono", "Right PGA Mux" },
  348. { "Left ADC", NULL, "Left ADC Mux" },
  349. { "Right ADC", NULL, "Right ADC Mux" },
  350. { "Left Line Mux", "Line 1", "LINPUT1" },
  351. { "Left Line Mux", "Line 2", "LINPUT2" },
  352. { "Left Line Mux", "PGA", "Left PGA Mux" },
  353. { "Left Line Mux", "Differential", "Differential Mux" },
  354. { "Right Line Mux", "Line 1", "RINPUT1" },
  355. { "Right Line Mux", "Line 2", "RINPUT2" },
  356. { "Right Line Mux", "PGA", "Right PGA Mux" },
  357. { "Right Line Mux", "Differential", "Differential Mux" },
  358. { "Left Mixer", "Playback Switch", "Left DAC" },
  359. { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
  360. { "Left Mixer", "Right Playback Switch", "Right DAC" },
  361. { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
  362. { "Right Mixer", "Left Playback Switch", "Left DAC" },
  363. { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
  364. { "Right Mixer", "Playback Switch", "Right DAC" },
  365. { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
  366. { "Left Out 1", NULL, "Left Mixer" },
  367. { "LOUT1", NULL, "Left Out 1" },
  368. { "Right Out 1", NULL, "Right Mixer" },
  369. { "ROUT1", NULL, "Right Out 1" },
  370. { "Left Out 2", NULL, "Left Mixer" },
  371. { "LOUT2", NULL, "Left Out 2" },
  372. { "Right Out 2", NULL, "Right Mixer" },
  373. { "ROUT2", NULL, "Right Out 2" },
  374. };
  375. struct _coeff_div {
  376. u32 mclk;
  377. u32 rate;
  378. u16 fs;
  379. u8 sr:5;
  380. u8 usb:1;
  381. };
  382. /* codec hifi mclk clock divider coefficients */
  383. static const struct _coeff_div coeff_div[] = {
  384. /* 8k */
  385. {12288000, 8000, 1536, 0x6, 0x0},
  386. {11289600, 8000, 1408, 0x16, 0x0},
  387. {18432000, 8000, 2304, 0x7, 0x0},
  388. {16934400, 8000, 2112, 0x17, 0x0},
  389. {12000000, 8000, 1500, 0x6, 0x1},
  390. /* 11.025k */
  391. {11289600, 11025, 1024, 0x18, 0x0},
  392. {16934400, 11025, 1536, 0x19, 0x0},
  393. {12000000, 11025, 1088, 0x19, 0x1},
  394. /* 16k */
  395. {12288000, 16000, 768, 0xa, 0x0},
  396. {18432000, 16000, 1152, 0xb, 0x0},
  397. {12000000, 16000, 750, 0xa, 0x1},
  398. /* 22.05k */
  399. {11289600, 22050, 512, 0x1a, 0x0},
  400. {16934400, 22050, 768, 0x1b, 0x0},
  401. {12000000, 22050, 544, 0x1b, 0x1},
  402. /* 32k */
  403. {12288000, 32000, 384, 0xc, 0x0},
  404. {18432000, 32000, 576, 0xd, 0x0},
  405. {12000000, 32000, 375, 0xa, 0x1},
  406. /* 44.1k */
  407. {11289600, 44100, 256, 0x10, 0x0},
  408. {16934400, 44100, 384, 0x11, 0x0},
  409. {12000000, 44100, 272, 0x11, 0x1},
  410. /* 48k */
  411. {12288000, 48000, 256, 0x0, 0x0},
  412. {18432000, 48000, 384, 0x1, 0x0},
  413. {12000000, 48000, 250, 0x0, 0x1},
  414. /* 88.2k */
  415. {11289600, 88200, 128, 0x1e, 0x0},
  416. {16934400, 88200, 192, 0x1f, 0x0},
  417. {12000000, 88200, 136, 0x1f, 0x1},
  418. /* 96k */
  419. {12288000, 96000, 128, 0xe, 0x0},
  420. {18432000, 96000, 192, 0xf, 0x0},
  421. {12000000, 96000, 125, 0xe, 0x1},
  422. };
  423. static inline int get_coeff(int mclk, int rate)
  424. {
  425. int i;
  426. for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
  427. if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
  428. return i;
  429. }
  430. return -EINVAL;
  431. }
  432. /* The set of rates we can generate from the above for each SYSCLK */
  433. static const unsigned int rates_12288[] = {
  434. 8000, 12000, 16000, 24000, 32000, 48000, 96000,
  435. };
  436. static const struct snd_pcm_hw_constraint_list constraints_12288 = {
  437. .count = ARRAY_SIZE(rates_12288),
  438. .list = rates_12288,
  439. };
  440. static const unsigned int rates_112896[] = {
  441. 8000, 11025, 22050, 44100,
  442. };
  443. static const struct snd_pcm_hw_constraint_list constraints_112896 = {
  444. .count = ARRAY_SIZE(rates_112896),
  445. .list = rates_112896,
  446. };
  447. static const unsigned int rates_12[] = {
  448. 8000, 11025, 12000, 16000, 22050, 24000, 32000, 41100, 48000,
  449. 48000, 88235, 96000,
  450. };
  451. static const struct snd_pcm_hw_constraint_list constraints_12 = {
  452. .count = ARRAY_SIZE(rates_12),
  453. .list = rates_12,
  454. };
  455. /*
  456. * Note that this should be called from init rather than from hw_params.
  457. */
  458. static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
  459. int clk_id, unsigned int freq, int dir)
  460. {
  461. struct snd_soc_component *component = codec_dai->component;
  462. struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
  463. switch (freq) {
  464. case 11289600:
  465. case 18432000:
  466. case 22579200:
  467. case 36864000:
  468. wm8988->sysclk_constraints = &constraints_112896;
  469. wm8988->sysclk = freq;
  470. return 0;
  471. case 12288000:
  472. case 16934400:
  473. case 24576000:
  474. case 33868800:
  475. wm8988->sysclk_constraints = &constraints_12288;
  476. wm8988->sysclk = freq;
  477. return 0;
  478. case 12000000:
  479. case 24000000:
  480. wm8988->sysclk_constraints = &constraints_12;
  481. wm8988->sysclk = freq;
  482. return 0;
  483. }
  484. return -EINVAL;
  485. }
  486. static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
  487. unsigned int fmt)
  488. {
  489. struct snd_soc_component *component = codec_dai->component;
  490. u16 iface = 0;
  491. /* set master/slave audio interface */
  492. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  493. case SND_SOC_DAIFMT_CBM_CFM:
  494. iface = 0x0040;
  495. break;
  496. case SND_SOC_DAIFMT_CBS_CFS:
  497. break;
  498. default:
  499. return -EINVAL;
  500. }
  501. /* interface format */
  502. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  503. case SND_SOC_DAIFMT_I2S:
  504. iface |= 0x0002;
  505. break;
  506. case SND_SOC_DAIFMT_RIGHT_J:
  507. break;
  508. case SND_SOC_DAIFMT_LEFT_J:
  509. iface |= 0x0001;
  510. break;
  511. case SND_SOC_DAIFMT_DSP_A:
  512. iface |= 0x0003;
  513. break;
  514. case SND_SOC_DAIFMT_DSP_B:
  515. iface |= 0x0013;
  516. break;
  517. default:
  518. return -EINVAL;
  519. }
  520. /* clock inversion */
  521. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  522. case SND_SOC_DAIFMT_NB_NF:
  523. break;
  524. case SND_SOC_DAIFMT_IB_IF:
  525. iface |= 0x0090;
  526. break;
  527. case SND_SOC_DAIFMT_IB_NF:
  528. iface |= 0x0080;
  529. break;
  530. case SND_SOC_DAIFMT_NB_IF:
  531. iface |= 0x0010;
  532. break;
  533. default:
  534. return -EINVAL;
  535. }
  536. snd_soc_component_write(component, WM8988_IFACE, iface);
  537. return 0;
  538. }
  539. static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
  540. struct snd_soc_dai *dai)
  541. {
  542. struct snd_soc_component *component = dai->component;
  543. struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
  544. /* The set of sample rates that can be supported depends on the
  545. * MCLK supplied to the CODEC - enforce this.
  546. */
  547. if (!wm8988->sysclk) {
  548. dev_err(component->dev,
  549. "No MCLK configured, call set_sysclk() on init\n");
  550. return -EINVAL;
  551. }
  552. snd_pcm_hw_constraint_list(substream->runtime, 0,
  553. SNDRV_PCM_HW_PARAM_RATE,
  554. wm8988->sysclk_constraints);
  555. return 0;
  556. }
  557. static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
  558. struct snd_pcm_hw_params *params,
  559. struct snd_soc_dai *dai)
  560. {
  561. struct snd_soc_component *component = dai->component;
  562. struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
  563. u16 iface = snd_soc_component_read(component, WM8988_IFACE) & 0x1f3;
  564. u16 srate = snd_soc_component_read(component, WM8988_SRATE) & 0x180;
  565. int coeff;
  566. coeff = get_coeff(wm8988->sysclk, params_rate(params));
  567. if (coeff < 0) {
  568. coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
  569. srate |= 0x40;
  570. }
  571. if (coeff < 0) {
  572. dev_err(component->dev,
  573. "Unable to configure sample rate %dHz with %dHz MCLK\n",
  574. params_rate(params), wm8988->sysclk);
  575. return coeff;
  576. }
  577. /* bit size */
  578. switch (params_width(params)) {
  579. case 16:
  580. break;
  581. case 20:
  582. iface |= 0x0004;
  583. break;
  584. case 24:
  585. iface |= 0x0008;
  586. break;
  587. case 32:
  588. iface |= 0x000c;
  589. break;
  590. }
  591. /* set iface & srate */
  592. snd_soc_component_write(component, WM8988_IFACE, iface);
  593. if (coeff >= 0)
  594. snd_soc_component_write(component, WM8988_SRATE, srate |
  595. (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
  596. return 0;
  597. }
  598. static int wm8988_mute(struct snd_soc_dai *dai, int mute, int direction)
  599. {
  600. struct snd_soc_component *component = dai->component;
  601. u16 mute_reg = snd_soc_component_read(component, WM8988_ADCDAC) & 0xfff7;
  602. if (mute)
  603. snd_soc_component_write(component, WM8988_ADCDAC, mute_reg | 0x8);
  604. else
  605. snd_soc_component_write(component, WM8988_ADCDAC, mute_reg);
  606. return 0;
  607. }
  608. static int wm8988_set_bias_level(struct snd_soc_component *component,
  609. enum snd_soc_bias_level level)
  610. {
  611. struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
  612. u16 pwr_reg = snd_soc_component_read(component, WM8988_PWR1) & ~0x1c1;
  613. switch (level) {
  614. case SND_SOC_BIAS_ON:
  615. break;
  616. case SND_SOC_BIAS_PREPARE:
  617. /* VREF, VMID=2x50k, digital enabled */
  618. snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x00c0);
  619. break;
  620. case SND_SOC_BIAS_STANDBY:
  621. if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
  622. regcache_sync(wm8988->regmap);
  623. /* VREF, VMID=2x5k */
  624. snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x1c1);
  625. /* Charge caps */
  626. msleep(100);
  627. }
  628. /* VREF, VMID=2*500k, digital stopped */
  629. snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x0141);
  630. break;
  631. case SND_SOC_BIAS_OFF:
  632. snd_soc_component_write(component, WM8988_PWR1, 0x0000);
  633. break;
  634. }
  635. return 0;
  636. }
  637. #define WM8988_RATES SNDRV_PCM_RATE_8000_96000
  638. #define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  639. SNDRV_PCM_FMTBIT_S24_LE)
  640. static const struct snd_soc_dai_ops wm8988_ops = {
  641. .startup = wm8988_pcm_startup,
  642. .hw_params = wm8988_pcm_hw_params,
  643. .set_fmt = wm8988_set_dai_fmt,
  644. .set_sysclk = wm8988_set_dai_sysclk,
  645. .mute_stream = wm8988_mute,
  646. .no_capture_mute = 1,
  647. };
  648. static struct snd_soc_dai_driver wm8988_dai = {
  649. .name = "wm8988-hifi",
  650. .playback = {
  651. .stream_name = "Playback",
  652. .channels_min = 1,
  653. .channels_max = 2,
  654. .rates = WM8988_RATES,
  655. .formats = WM8988_FORMATS,
  656. },
  657. .capture = {
  658. .stream_name = "Capture",
  659. .channels_min = 1,
  660. .channels_max = 2,
  661. .rates = WM8988_RATES,
  662. .formats = WM8988_FORMATS,
  663. },
  664. .ops = &wm8988_ops,
  665. .symmetric_rates = 1,
  666. };
  667. static int wm8988_probe(struct snd_soc_component *component)
  668. {
  669. int ret = 0;
  670. ret = wm8988_reset(component);
  671. if (ret < 0) {
  672. dev_err(component->dev, "Failed to issue reset\n");
  673. return ret;
  674. }
  675. /* set the update bits (we always update left then right) */
  676. snd_soc_component_update_bits(component, WM8988_RADC, 0x0100, 0x0100);
  677. snd_soc_component_update_bits(component, WM8988_RDAC, 0x0100, 0x0100);
  678. snd_soc_component_update_bits(component, WM8988_ROUT1V, 0x0100, 0x0100);
  679. snd_soc_component_update_bits(component, WM8988_ROUT2V, 0x0100, 0x0100);
  680. snd_soc_component_update_bits(component, WM8988_RINVOL, 0x0100, 0x0100);
  681. return 0;
  682. }
  683. static const struct snd_soc_component_driver soc_component_dev_wm8988 = {
  684. .probe = wm8988_probe,
  685. .set_bias_level = wm8988_set_bias_level,
  686. .controls = wm8988_snd_controls,
  687. .num_controls = ARRAY_SIZE(wm8988_snd_controls),
  688. .dapm_widgets = wm8988_dapm_widgets,
  689. .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets),
  690. .dapm_routes = wm8988_dapm_routes,
  691. .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
  692. .suspend_bias_off = 1,
  693. .idle_bias_on = 1,
  694. .use_pmdown_time = 1,
  695. .endianness = 1,
  696. .non_legacy_dai_naming = 1,
  697. };
  698. static const struct regmap_config wm8988_regmap = {
  699. .reg_bits = 7,
  700. .val_bits = 9,
  701. .max_register = WM8988_LPPB,
  702. .writeable_reg = wm8988_writeable,
  703. .cache_type = REGCACHE_RBTREE,
  704. .reg_defaults = wm8988_reg_defaults,
  705. .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
  706. };
  707. #if defined(CONFIG_SPI_MASTER)
  708. static int wm8988_spi_probe(struct spi_device *spi)
  709. {
  710. struct wm8988_priv *wm8988;
  711. int ret;
  712. wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv),
  713. GFP_KERNEL);
  714. if (wm8988 == NULL)
  715. return -ENOMEM;
  716. wm8988->regmap = devm_regmap_init_spi(spi, &wm8988_regmap);
  717. if (IS_ERR(wm8988->regmap)) {
  718. ret = PTR_ERR(wm8988->regmap);
  719. dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
  720. return ret;
  721. }
  722. spi_set_drvdata(spi, wm8988);
  723. ret = devm_snd_soc_register_component(&spi->dev,
  724. &soc_component_dev_wm8988, &wm8988_dai, 1);
  725. return ret;
  726. }
  727. static struct spi_driver wm8988_spi_driver = {
  728. .driver = {
  729. .name = "wm8988",
  730. },
  731. .probe = wm8988_spi_probe,
  732. };
  733. #endif /* CONFIG_SPI_MASTER */
  734. #if IS_ENABLED(CONFIG_I2C)
  735. static int wm8988_i2c_probe(struct i2c_client *i2c,
  736. const struct i2c_device_id *id)
  737. {
  738. struct wm8988_priv *wm8988;
  739. int ret;
  740. wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv),
  741. GFP_KERNEL);
  742. if (wm8988 == NULL)
  743. return -ENOMEM;
  744. i2c_set_clientdata(i2c, wm8988);
  745. wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap);
  746. if (IS_ERR(wm8988->regmap)) {
  747. ret = PTR_ERR(wm8988->regmap);
  748. dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
  749. return ret;
  750. }
  751. ret = devm_snd_soc_register_component(&i2c->dev,
  752. &soc_component_dev_wm8988, &wm8988_dai, 1);
  753. return ret;
  754. }
  755. static const struct i2c_device_id wm8988_i2c_id[] = {
  756. { "wm8988", 0 },
  757. { }
  758. };
  759. MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
  760. static struct i2c_driver wm8988_i2c_driver = {
  761. .driver = {
  762. .name = "wm8988",
  763. },
  764. .probe = wm8988_i2c_probe,
  765. .id_table = wm8988_i2c_id,
  766. };
  767. #endif
  768. static int __init wm8988_modinit(void)
  769. {
  770. int ret = 0;
  771. #if IS_ENABLED(CONFIG_I2C)
  772. ret = i2c_add_driver(&wm8988_i2c_driver);
  773. if (ret != 0) {
  774. printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
  775. ret);
  776. }
  777. #endif
  778. #if defined(CONFIG_SPI_MASTER)
  779. ret = spi_register_driver(&wm8988_spi_driver);
  780. if (ret != 0) {
  781. printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
  782. ret);
  783. }
  784. #endif
  785. return ret;
  786. }
  787. module_init(wm8988_modinit);
  788. static void __exit wm8988_exit(void)
  789. {
  790. #if IS_ENABLED(CONFIG_I2C)
  791. i2c_del_driver(&wm8988_i2c_driver);
  792. #endif
  793. #if defined(CONFIG_SPI_MASTER)
  794. spi_unregister_driver(&wm8988_spi_driver);
  795. #endif
  796. }
  797. module_exit(wm8988_exit);
  798. MODULE_DESCRIPTION("ASoC WM8988 driver");
  799. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  800. MODULE_LICENSE("GPL");