wm9090.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * ALSA SoC WM9090 driver
  4. *
  5. * Copyright 2009-12 Wolfson Microelectronics
  6. *
  7. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/errno.h>
  11. #include <linux/device.h>
  12. #include <linux/i2c.h>
  13. #include <linux/delay.h>
  14. #include <linux/regmap.h>
  15. #include <linux/slab.h>
  16. #include <sound/initval.h>
  17. #include <sound/soc.h>
  18. #include <sound/tlv.h>
  19. #include <sound/wm9090.h>
  20. #include "wm9090.h"
  21. static const struct reg_default wm9090_reg_defaults[] = {
  22. { 1, 0x0006 }, /* R1 - Power Management (1) */
  23. { 2, 0x6000 }, /* R2 - Power Management (2) */
  24. { 3, 0x0000 }, /* R3 - Power Management (3) */
  25. { 6, 0x01C0 }, /* R6 - Clocking 1 */
  26. { 22, 0x0003 }, /* R22 - IN1 Line Control */
  27. { 23, 0x0003 }, /* R23 - IN2 Line Control */
  28. { 24, 0x0083 }, /* R24 - IN1 Line Input A Volume */
  29. { 25, 0x0083 }, /* R25 - IN1 Line Input B Volume */
  30. { 26, 0x0083 }, /* R26 - IN2 Line Input A Volume */
  31. { 27, 0x0083 }, /* R27 - IN2 Line Input B Volume */
  32. { 28, 0x002D }, /* R28 - Left Output Volume */
  33. { 29, 0x002D }, /* R29 - Right Output Volume */
  34. { 34, 0x0100 }, /* R34 - SPKMIXL Attenuation */
  35. { 35, 0x0010 }, /* R36 - SPKOUT Mixers */
  36. { 37, 0x0140 }, /* R37 - ClassD3 */
  37. { 38, 0x0039 }, /* R38 - Speaker Volume Left */
  38. { 45, 0x0000 }, /* R45 - Output Mixer1 */
  39. { 46, 0x0000 }, /* R46 - Output Mixer2 */
  40. { 47, 0x0100 }, /* R47 - Output Mixer3 */
  41. { 48, 0x0100 }, /* R48 - Output Mixer4 */
  42. { 54, 0x0000 }, /* R54 - Speaker Mixer */
  43. { 57, 0x000D }, /* R57 - AntiPOP2 */
  44. { 70, 0x0000 }, /* R70 - Write Sequencer 0 */
  45. { 71, 0x0000 }, /* R71 - Write Sequencer 1 */
  46. { 72, 0x0000 }, /* R72 - Write Sequencer 2 */
  47. { 73, 0x0000 }, /* R73 - Write Sequencer 3 */
  48. { 74, 0x0000 }, /* R74 - Write Sequencer 4 */
  49. { 75, 0x0000 }, /* R75 - Write Sequencer 5 */
  50. { 76, 0x1F25 }, /* R76 - Charge Pump 1 */
  51. { 85, 0x054A }, /* R85 - DC Servo 1 */
  52. { 87, 0x0000 }, /* R87 - DC Servo 3 */
  53. { 96, 0x0100 }, /* R96 - Analogue HP 0 */
  54. { 98, 0x8640 }, /* R98 - AGC Control 0 */
  55. { 99, 0xC000 }, /* R99 - AGC Control 1 */
  56. { 100, 0x0200 }, /* R100 - AGC Control 2 */
  57. };
  58. /* This struct is used to save the context */
  59. struct wm9090_priv {
  60. struct wm9090_platform_data pdata;
  61. struct regmap *regmap;
  62. };
  63. static bool wm9090_volatile(struct device *dev, unsigned int reg)
  64. {
  65. switch (reg) {
  66. case WM9090_SOFTWARE_RESET:
  67. case WM9090_DC_SERVO_0:
  68. case WM9090_DC_SERVO_READBACK_0:
  69. case WM9090_DC_SERVO_READBACK_1:
  70. case WM9090_DC_SERVO_READBACK_2:
  71. return true;
  72. default:
  73. return false;
  74. }
  75. }
  76. static bool wm9090_readable(struct device *dev, unsigned int reg)
  77. {
  78. switch (reg) {
  79. case WM9090_SOFTWARE_RESET:
  80. case WM9090_POWER_MANAGEMENT_1:
  81. case WM9090_POWER_MANAGEMENT_2:
  82. case WM9090_POWER_MANAGEMENT_3:
  83. case WM9090_CLOCKING_1:
  84. case WM9090_IN1_LINE_CONTROL:
  85. case WM9090_IN2_LINE_CONTROL:
  86. case WM9090_IN1_LINE_INPUT_A_VOLUME:
  87. case WM9090_IN1_LINE_INPUT_B_VOLUME:
  88. case WM9090_IN2_LINE_INPUT_A_VOLUME:
  89. case WM9090_IN2_LINE_INPUT_B_VOLUME:
  90. case WM9090_LEFT_OUTPUT_VOLUME:
  91. case WM9090_RIGHT_OUTPUT_VOLUME:
  92. case WM9090_SPKMIXL_ATTENUATION:
  93. case WM9090_SPKOUT_MIXERS:
  94. case WM9090_CLASSD3:
  95. case WM9090_SPEAKER_VOLUME_LEFT:
  96. case WM9090_OUTPUT_MIXER1:
  97. case WM9090_OUTPUT_MIXER2:
  98. case WM9090_OUTPUT_MIXER3:
  99. case WM9090_OUTPUT_MIXER4:
  100. case WM9090_SPEAKER_MIXER:
  101. case WM9090_ANTIPOP2:
  102. case WM9090_WRITE_SEQUENCER_0:
  103. case WM9090_WRITE_SEQUENCER_1:
  104. case WM9090_WRITE_SEQUENCER_2:
  105. case WM9090_WRITE_SEQUENCER_3:
  106. case WM9090_WRITE_SEQUENCER_4:
  107. case WM9090_WRITE_SEQUENCER_5:
  108. case WM9090_CHARGE_PUMP_1:
  109. case WM9090_DC_SERVO_0:
  110. case WM9090_DC_SERVO_1:
  111. case WM9090_DC_SERVO_3:
  112. case WM9090_DC_SERVO_READBACK_0:
  113. case WM9090_DC_SERVO_READBACK_1:
  114. case WM9090_DC_SERVO_READBACK_2:
  115. case WM9090_ANALOGUE_HP_0:
  116. case WM9090_AGC_CONTROL_0:
  117. case WM9090_AGC_CONTROL_1:
  118. case WM9090_AGC_CONTROL_2:
  119. return true;
  120. default:
  121. return false;
  122. }
  123. }
  124. static void wait_for_dc_servo(struct snd_soc_component *component)
  125. {
  126. unsigned int reg;
  127. int count = 0;
  128. dev_dbg(component->dev, "Waiting for DC servo...\n");
  129. do {
  130. count++;
  131. msleep(1);
  132. reg = snd_soc_component_read(component, WM9090_DC_SERVO_READBACK_0);
  133. dev_dbg(component->dev, "DC servo status: %x\n", reg);
  134. } while ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
  135. != WM9090_DCS_CAL_COMPLETE_MASK && count < 1000);
  136. if ((reg & WM9090_DCS_CAL_COMPLETE_MASK)
  137. != WM9090_DCS_CAL_COMPLETE_MASK)
  138. dev_err(component->dev, "Timed out waiting for DC Servo\n");
  139. }
  140. static const DECLARE_TLV_DB_RANGE(in_tlv,
  141. 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
  142. 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0),
  143. 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0)
  144. );
  145. static const DECLARE_TLV_DB_RANGE(mix_tlv,
  146. 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0),
  147. 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0)
  148. );
  149. static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
  150. static const DECLARE_TLV_DB_RANGE(spkboost_tlv,
  151. 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
  152. 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0)
  153. );
  154. static const struct snd_kcontrol_new wm9090_controls[] = {
  155. SOC_SINGLE_TLV("IN1A Volume", WM9090_IN1_LINE_INPUT_A_VOLUME, 0, 6, 0,
  156. in_tlv),
  157. SOC_SINGLE("IN1A Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 7, 1, 1),
  158. SOC_SINGLE("IN1A ZC Switch", WM9090_IN1_LINE_INPUT_A_VOLUME, 6, 1, 0),
  159. SOC_SINGLE_TLV("IN2A Volume", WM9090_IN2_LINE_INPUT_A_VOLUME, 0, 6, 0,
  160. in_tlv),
  161. SOC_SINGLE("IN2A Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 7, 1, 1),
  162. SOC_SINGLE("IN2A ZC Switch", WM9090_IN2_LINE_INPUT_A_VOLUME, 6, 1, 0),
  163. SOC_SINGLE("MIXOUTL Switch", WM9090_OUTPUT_MIXER3, 8, 1, 1),
  164. SOC_SINGLE_TLV("MIXOUTL IN1A Volume", WM9090_OUTPUT_MIXER3, 6, 3, 1,
  165. mix_tlv),
  166. SOC_SINGLE_TLV("MIXOUTL IN2A Volume", WM9090_OUTPUT_MIXER3, 2, 3, 1,
  167. mix_tlv),
  168. SOC_SINGLE("MIXOUTR Switch", WM9090_OUTPUT_MIXER4, 8, 1, 1),
  169. SOC_SINGLE_TLV("MIXOUTR IN1A Volume", WM9090_OUTPUT_MIXER4, 6, 3, 1,
  170. mix_tlv),
  171. SOC_SINGLE_TLV("MIXOUTR IN2A Volume", WM9090_OUTPUT_MIXER4, 2, 3, 1,
  172. mix_tlv),
  173. SOC_SINGLE("SPKMIX Switch", WM9090_SPKMIXL_ATTENUATION, 8, 1, 1),
  174. SOC_SINGLE_TLV("SPKMIX IN1A Volume", WM9090_SPKMIXL_ATTENUATION, 6, 3, 1,
  175. mix_tlv),
  176. SOC_SINGLE_TLV("SPKMIX IN2A Volume", WM9090_SPKMIXL_ATTENUATION, 2, 3, 1,
  177. mix_tlv),
  178. SOC_DOUBLE_R_TLV("Headphone Volume", WM9090_LEFT_OUTPUT_VOLUME,
  179. WM9090_RIGHT_OUTPUT_VOLUME, 0, 63, 0, out_tlv),
  180. SOC_DOUBLE_R("Headphone Switch", WM9090_LEFT_OUTPUT_VOLUME,
  181. WM9090_RIGHT_OUTPUT_VOLUME, 6, 1, 1),
  182. SOC_DOUBLE_R("Headphone ZC Switch", WM9090_LEFT_OUTPUT_VOLUME,
  183. WM9090_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
  184. SOC_SINGLE_TLV("Speaker Volume", WM9090_SPEAKER_VOLUME_LEFT, 0, 63, 0,
  185. out_tlv),
  186. SOC_SINGLE("Speaker Switch", WM9090_SPEAKER_VOLUME_LEFT, 6, 1, 1),
  187. SOC_SINGLE("Speaker ZC Switch", WM9090_SPEAKER_VOLUME_LEFT, 7, 1, 0),
  188. SOC_SINGLE_TLV("Speaker Boost Volume", WM9090_CLASSD3, 3, 7, 0, spkboost_tlv),
  189. };
  190. static const struct snd_kcontrol_new wm9090_in1_se_controls[] = {
  191. SOC_SINGLE_TLV("IN1B Volume", WM9090_IN1_LINE_INPUT_B_VOLUME, 0, 6, 0,
  192. in_tlv),
  193. SOC_SINGLE("IN1B Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 7, 1, 1),
  194. SOC_SINGLE("IN1B ZC Switch", WM9090_IN1_LINE_INPUT_B_VOLUME, 6, 1, 0),
  195. SOC_SINGLE_TLV("SPKMIX IN1B Volume", WM9090_SPKMIXL_ATTENUATION, 4, 3, 1,
  196. mix_tlv),
  197. SOC_SINGLE_TLV("MIXOUTL IN1B Volume", WM9090_OUTPUT_MIXER3, 4, 3, 1,
  198. mix_tlv),
  199. SOC_SINGLE_TLV("MIXOUTR IN1B Volume", WM9090_OUTPUT_MIXER4, 4, 3, 1,
  200. mix_tlv),
  201. };
  202. static const struct snd_kcontrol_new wm9090_in2_se_controls[] = {
  203. SOC_SINGLE_TLV("IN2B Volume", WM9090_IN2_LINE_INPUT_B_VOLUME, 0, 6, 0,
  204. in_tlv),
  205. SOC_SINGLE("IN2B Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 7, 1, 1),
  206. SOC_SINGLE("IN2B ZC Switch", WM9090_IN2_LINE_INPUT_B_VOLUME, 6, 1, 0),
  207. SOC_SINGLE_TLV("SPKMIX IN2B Volume", WM9090_SPKMIXL_ATTENUATION, 0, 3, 1,
  208. mix_tlv),
  209. SOC_SINGLE_TLV("MIXOUTL IN2B Volume", WM9090_OUTPUT_MIXER3, 0, 3, 1,
  210. mix_tlv),
  211. SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
  212. mix_tlv),
  213. };
  214. static int hp_ev(struct snd_soc_dapm_widget *w,
  215. struct snd_kcontrol *kcontrol, int event)
  216. {
  217. struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
  218. unsigned int reg = snd_soc_component_read(component, WM9090_ANALOGUE_HP_0);
  219. switch (event) {
  220. case SND_SOC_DAPM_POST_PMU:
  221. snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
  222. WM9090_CP_ENA, WM9090_CP_ENA);
  223. msleep(5);
  224. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
  225. WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
  226. WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA);
  227. reg |= WM9090_HPOUT1L_DLY | WM9090_HPOUT1R_DLY;
  228. snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
  229. /* Start the DC servo. We don't currently use the
  230. * ability to save the state since we don't have full
  231. * control of the analogue paths and they can change
  232. * DC offsets; see the WM8904 driver for an example of
  233. * doing so.
  234. */
  235. snd_soc_component_write(component, WM9090_DC_SERVO_0,
  236. WM9090_DCS_ENA_CHAN_0 |
  237. WM9090_DCS_ENA_CHAN_1 |
  238. WM9090_DCS_TRIG_STARTUP_1 |
  239. WM9090_DCS_TRIG_STARTUP_0);
  240. wait_for_dc_servo(component);
  241. reg |= WM9090_HPOUT1R_OUTP | WM9090_HPOUT1R_RMV_SHORT |
  242. WM9090_HPOUT1L_OUTP | WM9090_HPOUT1L_RMV_SHORT;
  243. snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
  244. break;
  245. case SND_SOC_DAPM_PRE_PMD:
  246. reg &= ~(WM9090_HPOUT1L_RMV_SHORT |
  247. WM9090_HPOUT1L_DLY |
  248. WM9090_HPOUT1L_OUTP |
  249. WM9090_HPOUT1R_RMV_SHORT |
  250. WM9090_HPOUT1R_DLY |
  251. WM9090_HPOUT1R_OUTP);
  252. snd_soc_component_write(component, WM9090_ANALOGUE_HP_0, reg);
  253. snd_soc_component_write(component, WM9090_DC_SERVO_0, 0);
  254. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
  255. WM9090_HPOUT1L_ENA | WM9090_HPOUT1R_ENA,
  256. 0);
  257. snd_soc_component_update_bits(component, WM9090_CHARGE_PUMP_1,
  258. WM9090_CP_ENA, 0);
  259. break;
  260. }
  261. return 0;
  262. }
  263. static const struct snd_kcontrol_new spkmix[] = {
  264. SOC_DAPM_SINGLE("IN1A Switch", WM9090_SPEAKER_MIXER, 6, 1, 0),
  265. SOC_DAPM_SINGLE("IN1B Switch", WM9090_SPEAKER_MIXER, 4, 1, 0),
  266. SOC_DAPM_SINGLE("IN2A Switch", WM9090_SPEAKER_MIXER, 2, 1, 0),
  267. SOC_DAPM_SINGLE("IN2B Switch", WM9090_SPEAKER_MIXER, 0, 1, 0),
  268. };
  269. static const struct snd_kcontrol_new spkout[] = {
  270. SOC_DAPM_SINGLE("Mixer Switch", WM9090_SPKOUT_MIXERS, 4, 1, 0),
  271. };
  272. static const struct snd_kcontrol_new mixoutl[] = {
  273. SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER1, 6, 1, 0),
  274. SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER1, 4, 1, 0),
  275. SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER1, 2, 1, 0),
  276. SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER1, 0, 1, 0),
  277. };
  278. static const struct snd_kcontrol_new mixoutr[] = {
  279. SOC_DAPM_SINGLE("IN1A Switch", WM9090_OUTPUT_MIXER2, 6, 1, 0),
  280. SOC_DAPM_SINGLE("IN1B Switch", WM9090_OUTPUT_MIXER2, 4, 1, 0),
  281. SOC_DAPM_SINGLE("IN2A Switch", WM9090_OUTPUT_MIXER2, 2, 1, 0),
  282. SOC_DAPM_SINGLE("IN2B Switch", WM9090_OUTPUT_MIXER2, 0, 1, 0),
  283. };
  284. static const struct snd_soc_dapm_widget wm9090_dapm_widgets[] = {
  285. SND_SOC_DAPM_INPUT("IN1+"),
  286. SND_SOC_DAPM_INPUT("IN1-"),
  287. SND_SOC_DAPM_INPUT("IN2+"),
  288. SND_SOC_DAPM_INPUT("IN2-"),
  289. SND_SOC_DAPM_SUPPLY("OSC", WM9090_POWER_MANAGEMENT_1, 3, 0, NULL, 0),
  290. SND_SOC_DAPM_PGA("IN1A PGA", WM9090_POWER_MANAGEMENT_2, 7, 0, NULL, 0),
  291. SND_SOC_DAPM_PGA("IN1B PGA", WM9090_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
  292. SND_SOC_DAPM_PGA("IN2A PGA", WM9090_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
  293. SND_SOC_DAPM_PGA("IN2B PGA", WM9090_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
  294. SND_SOC_DAPM_MIXER("SPKMIX", WM9090_POWER_MANAGEMENT_3, 3, 0,
  295. spkmix, ARRAY_SIZE(spkmix)),
  296. SND_SOC_DAPM_MIXER("MIXOUTL", WM9090_POWER_MANAGEMENT_3, 5, 0,
  297. mixoutl, ARRAY_SIZE(mixoutl)),
  298. SND_SOC_DAPM_MIXER("MIXOUTR", WM9090_POWER_MANAGEMENT_3, 4, 0,
  299. mixoutr, ARRAY_SIZE(mixoutr)),
  300. SND_SOC_DAPM_PGA_E("HP PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
  301. hp_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
  302. SND_SOC_DAPM_PGA("SPKPGA", WM9090_POWER_MANAGEMENT_3, 8, 0, NULL, 0),
  303. SND_SOC_DAPM_MIXER("SPKOUT", WM9090_POWER_MANAGEMENT_1, 12, 0,
  304. spkout, ARRAY_SIZE(spkout)),
  305. SND_SOC_DAPM_OUTPUT("HPR"),
  306. SND_SOC_DAPM_OUTPUT("HPL"),
  307. SND_SOC_DAPM_OUTPUT("Speaker"),
  308. };
  309. static const struct snd_soc_dapm_route audio_map[] = {
  310. { "IN1A PGA", NULL, "IN1+" },
  311. { "IN2A PGA", NULL, "IN2+" },
  312. { "SPKMIX", "IN1A Switch", "IN1A PGA" },
  313. { "SPKMIX", "IN2A Switch", "IN2A PGA" },
  314. { "MIXOUTL", "IN1A Switch", "IN1A PGA" },
  315. { "MIXOUTL", "IN2A Switch", "IN2A PGA" },
  316. { "MIXOUTR", "IN1A Switch", "IN1A PGA" },
  317. { "MIXOUTR", "IN2A Switch", "IN2A PGA" },
  318. { "HP PGA", NULL, "OSC" },
  319. { "HP PGA", NULL, "MIXOUTL" },
  320. { "HP PGA", NULL, "MIXOUTR" },
  321. { "HPL", NULL, "HP PGA" },
  322. { "HPR", NULL, "HP PGA" },
  323. { "SPKPGA", NULL, "OSC" },
  324. { "SPKPGA", NULL, "SPKMIX" },
  325. { "SPKOUT", "Mixer Switch", "SPKPGA" },
  326. { "Speaker", NULL, "SPKOUT" },
  327. };
  328. static const struct snd_soc_dapm_route audio_map_in1_se[] = {
  329. { "IN1B PGA", NULL, "IN1-" },
  330. { "SPKMIX", "IN1B Switch", "IN1B PGA" },
  331. { "MIXOUTL", "IN1B Switch", "IN1B PGA" },
  332. { "MIXOUTR", "IN1B Switch", "IN1B PGA" },
  333. };
  334. static const struct snd_soc_dapm_route audio_map_in1_diff[] = {
  335. { "IN1A PGA", NULL, "IN1-" },
  336. };
  337. static const struct snd_soc_dapm_route audio_map_in2_se[] = {
  338. { "IN2B PGA", NULL, "IN2-" },
  339. { "SPKMIX", "IN2B Switch", "IN2B PGA" },
  340. { "MIXOUTL", "IN2B Switch", "IN2B PGA" },
  341. { "MIXOUTR", "IN2B Switch", "IN2B PGA" },
  342. };
  343. static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
  344. { "IN2A PGA", NULL, "IN2-" },
  345. };
  346. static int wm9090_add_controls(struct snd_soc_component *component)
  347. {
  348. struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
  349. struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
  350. int i;
  351. snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
  352. ARRAY_SIZE(wm9090_dapm_widgets));
  353. snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
  354. snd_soc_add_component_controls(component, wm9090_controls,
  355. ARRAY_SIZE(wm9090_controls));
  356. if (wm9090->pdata.lin1_diff) {
  357. snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
  358. ARRAY_SIZE(audio_map_in1_diff));
  359. } else {
  360. snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
  361. ARRAY_SIZE(audio_map_in1_se));
  362. snd_soc_add_component_controls(component, wm9090_in1_se_controls,
  363. ARRAY_SIZE(wm9090_in1_se_controls));
  364. }
  365. if (wm9090->pdata.lin2_diff) {
  366. snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
  367. ARRAY_SIZE(audio_map_in2_diff));
  368. } else {
  369. snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
  370. ARRAY_SIZE(audio_map_in2_se));
  371. snd_soc_add_component_controls(component, wm9090_in2_se_controls,
  372. ARRAY_SIZE(wm9090_in2_se_controls));
  373. }
  374. if (wm9090->pdata.agc_ena) {
  375. for (i = 0; i < ARRAY_SIZE(wm9090->pdata.agc); i++)
  376. snd_soc_component_write(component, WM9090_AGC_CONTROL_0 + i,
  377. wm9090->pdata.agc[i]);
  378. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
  379. WM9090_AGC_ENA, WM9090_AGC_ENA);
  380. } else {
  381. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_3,
  382. WM9090_AGC_ENA, 0);
  383. }
  384. return 0;
  385. }
  386. /*
  387. * The machine driver should call this from their set_bias_level; if there
  388. * isn't one then this can just be set as the set_bias_level function.
  389. */
  390. static int wm9090_set_bias_level(struct snd_soc_component *component,
  391. enum snd_soc_bias_level level)
  392. {
  393. struct wm9090_priv *wm9090 = snd_soc_component_get_drvdata(component);
  394. switch (level) {
  395. case SND_SOC_BIAS_ON:
  396. break;
  397. case SND_SOC_BIAS_PREPARE:
  398. snd_soc_component_update_bits(component, WM9090_ANTIPOP2, WM9090_VMID_ENA,
  399. WM9090_VMID_ENA);
  400. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
  401. WM9090_BIAS_ENA |
  402. WM9090_VMID_RES_MASK,
  403. WM9090_BIAS_ENA |
  404. 1 << WM9090_VMID_RES_SHIFT);
  405. msleep(1); /* Probably an overestimate */
  406. break;
  407. case SND_SOC_BIAS_STANDBY:
  408. if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
  409. /* Restore the register cache */
  410. regcache_sync(wm9090->regmap);
  411. }
  412. /* We keep VMID off during standby since the combination of
  413. * ground referenced outputs and class D speaker mean that
  414. * latency is not an issue.
  415. */
  416. snd_soc_component_update_bits(component, WM9090_POWER_MANAGEMENT_1,
  417. WM9090_BIAS_ENA | WM9090_VMID_RES_MASK, 0);
  418. snd_soc_component_update_bits(component, WM9090_ANTIPOP2,
  419. WM9090_VMID_ENA, 0);
  420. break;
  421. case SND_SOC_BIAS_OFF:
  422. break;
  423. }
  424. return 0;
  425. }
  426. static int wm9090_probe(struct snd_soc_component *component)
  427. {
  428. /* Configure some defaults; they will be written out when we
  429. * bring the bias up.
  430. */
  431. snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_A_VOLUME,
  432. WM9090_IN1_VU | WM9090_IN1A_ZC,
  433. WM9090_IN1_VU | WM9090_IN1A_ZC);
  434. snd_soc_component_update_bits(component, WM9090_IN1_LINE_INPUT_B_VOLUME,
  435. WM9090_IN1_VU | WM9090_IN1B_ZC,
  436. WM9090_IN1_VU | WM9090_IN1B_ZC);
  437. snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_A_VOLUME,
  438. WM9090_IN2_VU | WM9090_IN2A_ZC,
  439. WM9090_IN2_VU | WM9090_IN2A_ZC);
  440. snd_soc_component_update_bits(component, WM9090_IN2_LINE_INPUT_B_VOLUME,
  441. WM9090_IN2_VU | WM9090_IN2B_ZC,
  442. WM9090_IN2_VU | WM9090_IN2B_ZC);
  443. snd_soc_component_update_bits(component, WM9090_SPEAKER_VOLUME_LEFT,
  444. WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC,
  445. WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC);
  446. snd_soc_component_update_bits(component, WM9090_LEFT_OUTPUT_VOLUME,
  447. WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC,
  448. WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC);
  449. snd_soc_component_update_bits(component, WM9090_RIGHT_OUTPUT_VOLUME,
  450. WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC,
  451. WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC);
  452. snd_soc_component_update_bits(component, WM9090_CLOCKING_1,
  453. WM9090_TOCLK_ENA, WM9090_TOCLK_ENA);
  454. wm9090_add_controls(component);
  455. return 0;
  456. }
  457. static const struct snd_soc_component_driver soc_component_dev_wm9090 = {
  458. .probe = wm9090_probe,
  459. .set_bias_level = wm9090_set_bias_level,
  460. .suspend_bias_off = 1,
  461. .idle_bias_on = 1,
  462. .use_pmdown_time = 1,
  463. .endianness = 1,
  464. .non_legacy_dai_naming = 1,
  465. };
  466. static const struct regmap_config wm9090_regmap = {
  467. .reg_bits = 8,
  468. .val_bits = 16,
  469. .max_register = WM9090_MAX_REGISTER,
  470. .volatile_reg = wm9090_volatile,
  471. .readable_reg = wm9090_readable,
  472. .cache_type = REGCACHE_RBTREE,
  473. .reg_defaults = wm9090_reg_defaults,
  474. .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults),
  475. };
  476. static int wm9090_i2c_probe(struct i2c_client *i2c,
  477. const struct i2c_device_id *id)
  478. {
  479. struct wm9090_priv *wm9090;
  480. unsigned int reg;
  481. int ret;
  482. wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL);
  483. if (!wm9090)
  484. return -ENOMEM;
  485. wm9090->regmap = devm_regmap_init_i2c(i2c, &wm9090_regmap);
  486. if (IS_ERR(wm9090->regmap)) {
  487. ret = PTR_ERR(wm9090->regmap);
  488. dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
  489. return ret;
  490. }
  491. ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, &reg);
  492. if (ret < 0)
  493. return ret;
  494. if (reg != 0x9093) {
  495. dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg);
  496. return -ENODEV;
  497. }
  498. ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0);
  499. if (ret < 0)
  500. return ret;
  501. if (i2c->dev.platform_data)
  502. memcpy(&wm9090->pdata, i2c->dev.platform_data,
  503. sizeof(wm9090->pdata));
  504. i2c_set_clientdata(i2c, wm9090);
  505. ret = devm_snd_soc_register_component(&i2c->dev,
  506. &soc_component_dev_wm9090, NULL, 0);
  507. if (ret != 0) {
  508. dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
  509. return ret;
  510. }
  511. return 0;
  512. }
  513. static const struct i2c_device_id wm9090_id[] = {
  514. { "wm9090", 0 },
  515. { "wm9093", 0 },
  516. { }
  517. };
  518. MODULE_DEVICE_TABLE(i2c, wm9090_id);
  519. static struct i2c_driver wm9090_i2c_driver = {
  520. .driver = {
  521. .name = "wm9090",
  522. },
  523. .probe = wm9090_i2c_probe,
  524. .id_table = wm9090_id,
  525. };
  526. module_i2c_driver(wm9090_i2c_driver);
  527. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  528. MODULE_DESCRIPTION("WM9090 ASoC driver");
  529. MODULE_LICENSE("GPL");