wm8580.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * wm8580.c -- WM8580 ALSA Soc Audio driver
  3. *
  4. * Copyright 2008, 2009 Wolfson Microelectronics PLC.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * Notes:
  12. * The WM8580 is a multichannel codec with S/PDIF support, featuring six
  13. * DAC channels and two ADC channels.
  14. *
  15. * Currently only the primary audio interface is supported - S/PDIF and
  16. * the secondary audio interfaces are not.
  17. */
  18. #include <linux/module.h>
  19. #include <linux/moduleparam.h>
  20. #include <linux/kernel.h>
  21. #include <linux/init.h>
  22. #include <linux/delay.h>
  23. #include <linux/pm.h>
  24. #include <linux/i2c.h>
  25. #include <linux/platform_device.h>
  26. #include <sound/core.h>
  27. #include <sound/pcm.h>
  28. #include <sound/pcm_params.h>
  29. #include <sound/soc.h>
  30. #include <sound/soc-dapm.h>
  31. #include <sound/tlv.h>
  32. #include <sound/initval.h>
  33. #include <asm/div64.h>
  34. #include "wm8580.h"
  35. /* WM8580 register space */
  36. #define WM8580_PLLA1 0x00
  37. #define WM8580_PLLA2 0x01
  38. #define WM8580_PLLA3 0x02
  39. #define WM8580_PLLA4 0x03
  40. #define WM8580_PLLB1 0x04
  41. #define WM8580_PLLB2 0x05
  42. #define WM8580_PLLB3 0x06
  43. #define WM8580_PLLB4 0x07
  44. #define WM8580_CLKSEL 0x08
  45. #define WM8580_PAIF1 0x09
  46. #define WM8580_PAIF2 0x0A
  47. #define WM8580_SAIF1 0x0B
  48. #define WM8580_PAIF3 0x0C
  49. #define WM8580_PAIF4 0x0D
  50. #define WM8580_SAIF2 0x0E
  51. #define WM8580_DAC_CONTROL1 0x0F
  52. #define WM8580_DAC_CONTROL2 0x10
  53. #define WM8580_DAC_CONTROL3 0x11
  54. #define WM8580_DAC_CONTROL4 0x12
  55. #define WM8580_DAC_CONTROL5 0x13
  56. #define WM8580_DIGITAL_ATTENUATION_DACL1 0x14
  57. #define WM8580_DIGITAL_ATTENUATION_DACR1 0x15
  58. #define WM8580_DIGITAL_ATTENUATION_DACL2 0x16
  59. #define WM8580_DIGITAL_ATTENUATION_DACR2 0x17
  60. #define WM8580_DIGITAL_ATTENUATION_DACL3 0x18
  61. #define WM8580_DIGITAL_ATTENUATION_DACR3 0x19
  62. #define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C
  63. #define WM8580_ADC_CONTROL1 0x1D
  64. #define WM8580_SPDTXCHAN0 0x1E
  65. #define WM8580_SPDTXCHAN1 0x1F
  66. #define WM8580_SPDTXCHAN2 0x20
  67. #define WM8580_SPDTXCHAN3 0x21
  68. #define WM8580_SPDTXCHAN4 0x22
  69. #define WM8580_SPDTXCHAN5 0x23
  70. #define WM8580_SPDMODE 0x24
  71. #define WM8580_INTMASK 0x25
  72. #define WM8580_GPO1 0x26
  73. #define WM8580_GPO2 0x27
  74. #define WM8580_GPO3 0x28
  75. #define WM8580_GPO4 0x29
  76. #define WM8580_GPO5 0x2A
  77. #define WM8580_INTSTAT 0x2B
  78. #define WM8580_SPDRXCHAN1 0x2C
  79. #define WM8580_SPDRXCHAN2 0x2D
  80. #define WM8580_SPDRXCHAN3 0x2E
  81. #define WM8580_SPDRXCHAN4 0x2F
  82. #define WM8580_SPDRXCHAN5 0x30
  83. #define WM8580_SPDSTAT 0x31
  84. #define WM8580_PWRDN1 0x32
  85. #define WM8580_PWRDN2 0x33
  86. #define WM8580_READBACK 0x34
  87. #define WM8580_RESET 0x35
  88. #define WM8580_MAX_REGISTER 0x35
  89. /* PLLB4 (register 7h) */
  90. #define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
  91. #define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
  92. #define WM8580_PLLB4_MCLKOUTSRC_PLLB 0x40
  93. #define WM8580_PLLB4_MCLKOUTSRC_OSC 0x60
  94. #define WM8580_PLLB4_CLKOUTSRC_MASK 0x180
  95. #define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080
  96. #define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100
  97. #define WM8580_PLLB4_CLKOUTSRC_OSCCLK 0x180
  98. /* CLKSEL (register 8h) */
  99. #define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03
  100. #define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01
  101. #define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02
  102. /* AIF control 1 (registers 9h-bh) */
  103. #define WM8580_AIF_RATE_MASK 0x7
  104. #define WM8580_AIF_RATE_128 0x0
  105. #define WM8580_AIF_RATE_192 0x1
  106. #define WM8580_AIF_RATE_256 0x2
  107. #define WM8580_AIF_RATE_384 0x3
  108. #define WM8580_AIF_RATE_512 0x4
  109. #define WM8580_AIF_RATE_768 0x5
  110. #define WM8580_AIF_RATE_1152 0x6
  111. #define WM8580_AIF_BCLKSEL_MASK 0x18
  112. #define WM8580_AIF_BCLKSEL_64 0x00
  113. #define WM8580_AIF_BCLKSEL_128 0x08
  114. #define WM8580_AIF_BCLKSEL_256 0x10
  115. #define WM8580_AIF_BCLKSEL_SYSCLK 0x18
  116. #define WM8580_AIF_MS 0x20
  117. #define WM8580_AIF_CLKSRC_MASK 0xc0
  118. #define WM8580_AIF_CLKSRC_PLLA 0x40
  119. #define WM8580_AIF_CLKSRC_PLLB 0x40
  120. #define WM8580_AIF_CLKSRC_MCLK 0xc0
  121. /* AIF control 2 (registers ch-eh) */
  122. #define WM8580_AIF_FMT_MASK 0x03
  123. #define WM8580_AIF_FMT_RIGHTJ 0x00
  124. #define WM8580_AIF_FMT_LEFTJ 0x01
  125. #define WM8580_AIF_FMT_I2S 0x02
  126. #define WM8580_AIF_FMT_DSP 0x03
  127. #define WM8580_AIF_LENGTH_MASK 0x0c
  128. #define WM8580_AIF_LENGTH_16 0x00
  129. #define WM8580_AIF_LENGTH_20 0x04
  130. #define WM8580_AIF_LENGTH_24 0x08
  131. #define WM8580_AIF_LENGTH_32 0x0c
  132. #define WM8580_AIF_LRP 0x10
  133. #define WM8580_AIF_BCP 0x20
  134. /* Powerdown Register 1 (register 32h) */
  135. #define WM8580_PWRDN1_PWDN 0x001
  136. #define WM8580_PWRDN1_ALLDACPD 0x040
  137. /* Powerdown Register 2 (register 33h) */
  138. #define WM8580_PWRDN2_OSSCPD 0x001
  139. #define WM8580_PWRDN2_PLLAPD 0x002
  140. #define WM8580_PWRDN2_PLLBPD 0x004
  141. #define WM8580_PWRDN2_SPDIFPD 0x008
  142. #define WM8580_PWRDN2_SPDIFTXD 0x010
  143. #define WM8580_PWRDN2_SPDIFRXD 0x020
  144. #define WM8580_DAC_CONTROL5_MUTEALL 0x10
  145. /*
  146. * wm8580 register cache
  147. * We can't read the WM8580 register space when we
  148. * are using 2 wire for device control, so we cache them instead.
  149. */
  150. static const u16 wm8580_reg[] = {
  151. 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
  152. 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
  153. 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
  154. 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
  155. 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
  156. 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
  157. 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
  158. 0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
  159. 0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
  160. 0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
  161. 0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
  162. 0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
  163. 0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
  164. 0x0000, 0x0000 /*R53*/
  165. };
  166. struct pll_state {
  167. unsigned int in;
  168. unsigned int out;
  169. };
  170. /* codec private data */
  171. struct wm8580_priv {
  172. struct snd_soc_codec codec;
  173. u16 reg_cache[WM8580_MAX_REGISTER + 1];
  174. struct pll_state a;
  175. struct pll_state b;
  176. };
  177. /*
  178. * read wm8580 register cache
  179. */
  180. static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
  181. unsigned int reg)
  182. {
  183. u16 *cache = codec->reg_cache;
  184. BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
  185. return cache[reg];
  186. }
  187. /*
  188. * write wm8580 register cache
  189. */
  190. static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
  191. unsigned int reg, unsigned int value)
  192. {
  193. u16 *cache = codec->reg_cache;
  194. cache[reg] = value;
  195. }
  196. /*
  197. * write to the WM8580 register space
  198. */
  199. static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
  200. unsigned int value)
  201. {
  202. u8 data[2];
  203. BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
  204. /* Registers are 9 bits wide */
  205. value &= 0x1ff;
  206. switch (reg) {
  207. case WM8580_RESET:
  208. /* Uncached */
  209. break;
  210. default:
  211. if (value == wm8580_read_reg_cache(codec, reg))
  212. return 0;
  213. }
  214. /* data is
  215. * D15..D9 WM8580 register offset
  216. * D8...D0 register data
  217. */
  218. data[0] = (reg << 1) | ((value >> 8) & 0x0001);
  219. data[1] = value & 0x00ff;
  220. wm8580_write_reg_cache(codec, reg, value);
  221. if (codec->hw_write(codec->control_data, data, 2) == 2)
  222. return 0;
  223. else
  224. return -EIO;
  225. }
  226. static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
  227. unsigned int reg)
  228. {
  229. switch (reg) {
  230. default:
  231. return wm8580_read_reg_cache(codec, reg);
  232. }
  233. }
  234. static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
  235. static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
  236. struct snd_ctl_elem_value *ucontrol)
  237. {
  238. struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
  239. int reg = kcontrol->private_value & 0xff;
  240. int reg2 = (kcontrol->private_value >> 24) & 0xff;
  241. int ret;
  242. u16 val;
  243. /* Clear the register cache so we write without VU set */
  244. wm8580_write_reg_cache(codec, reg, 0);
  245. wm8580_write_reg_cache(codec, reg2, 0);
  246. ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
  247. if (ret < 0)
  248. return ret;
  249. /* Now write again with the volume update bit set */
  250. val = wm8580_read_reg_cache(codec, reg);
  251. wm8580_write(codec, reg, val | 0x0100);
  252. val = wm8580_read_reg_cache(codec, reg2);
  253. wm8580_write(codec, reg2, val | 0x0100);
  254. return 0;
  255. }
  256. #define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, shift, max, invert, tlv_array) \
  257. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
  258. .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
  259. SNDRV_CTL_ELEM_ACCESS_READWRITE, \
  260. .tlv.p = (tlv_array), \
  261. .info = snd_soc_info_volsw_2r, \
  262. .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
  263. .private_value = (reg_left) | ((shift) << 8) | \
  264. ((max) << 12) | ((invert) << 20) | ((reg_right) << 24) }
  265. static const struct snd_kcontrol_new wm8580_snd_controls[] = {
  266. SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume",
  267. WM8580_DIGITAL_ATTENUATION_DACL1,
  268. WM8580_DIGITAL_ATTENUATION_DACR1,
  269. 0, 0xff, 0, dac_tlv),
  270. SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume",
  271. WM8580_DIGITAL_ATTENUATION_DACL2,
  272. WM8580_DIGITAL_ATTENUATION_DACR2,
  273. 0, 0xff, 0, dac_tlv),
  274. SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume",
  275. WM8580_DIGITAL_ATTENUATION_DACL3,
  276. WM8580_DIGITAL_ATTENUATION_DACR3,
  277. 0, 0xff, 0, dac_tlv),
  278. SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
  279. SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
  280. SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),
  281. SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4, 0, 1, 1, 0),
  282. SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4, 2, 3, 1, 0),
  283. SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4, 4, 5, 1, 0),
  284. SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),
  285. SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 0),
  286. SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 0),
  287. SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 0),
  288. SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0),
  289. SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
  290. };
  291. static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
  292. SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),
  293. SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),
  294. SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),
  295. SND_SOC_DAPM_OUTPUT("VOUT1L"),
  296. SND_SOC_DAPM_OUTPUT("VOUT1R"),
  297. SND_SOC_DAPM_OUTPUT("VOUT2L"),
  298. SND_SOC_DAPM_OUTPUT("VOUT2R"),
  299. SND_SOC_DAPM_OUTPUT("VOUT3L"),
  300. SND_SOC_DAPM_OUTPUT("VOUT3R"),
  301. SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),
  302. SND_SOC_DAPM_INPUT("AINL"),
  303. SND_SOC_DAPM_INPUT("AINR"),
  304. };
  305. static const struct snd_soc_dapm_route audio_map[] = {
  306. { "VOUT1L", NULL, "DAC1" },
  307. { "VOUT1R", NULL, "DAC1" },
  308. { "VOUT2L", NULL, "DAC2" },
  309. { "VOUT2R", NULL, "DAC2" },
  310. { "VOUT3L", NULL, "DAC3" },
  311. { "VOUT3R", NULL, "DAC3" },
  312. { "ADC", NULL, "AINL" },
  313. { "ADC", NULL, "AINR" },
  314. };
  315. static int wm8580_add_widgets(struct snd_soc_codec *codec)
  316. {
  317. snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets,
  318. ARRAY_SIZE(wm8580_dapm_widgets));
  319. snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
  320. snd_soc_dapm_new_widgets(codec);
  321. return 0;
  322. }
  323. /* PLL divisors */
  324. struct _pll_div {
  325. u32 prescale:1;
  326. u32 postscale:1;
  327. u32 freqmode:2;
  328. u32 n:4;
  329. u32 k:24;
  330. };
  331. /* The size in bits of the pll divide */
  332. #define FIXED_PLL_SIZE (1 << 22)
  333. /* PLL rate to output rate divisions */
  334. static struct {
  335. unsigned int div;
  336. unsigned int freqmode;
  337. unsigned int postscale;
  338. } post_table[] = {
  339. { 2, 0, 0 },
  340. { 4, 0, 1 },
  341. { 4, 1, 0 },
  342. { 8, 1, 1 },
  343. { 8, 2, 0 },
  344. { 16, 2, 1 },
  345. { 12, 3, 0 },
  346. { 24, 3, 1 }
  347. };
  348. static int pll_factors(struct _pll_div *pll_div, unsigned int target,
  349. unsigned int source)
  350. {
  351. u64 Kpart;
  352. unsigned int K, Ndiv, Nmod;
  353. int i;
  354. pr_debug("wm8580: PLL %dHz->%dHz\n", source, target);
  355. /* Scale the output frequency up; the PLL should run in the
  356. * region of 90-100MHz.
  357. */
  358. for (i = 0; i < ARRAY_SIZE(post_table); i++) {
  359. if (target * post_table[i].div >= 90000000 &&
  360. target * post_table[i].div <= 100000000) {
  361. pll_div->freqmode = post_table[i].freqmode;
  362. pll_div->postscale = post_table[i].postscale;
  363. target *= post_table[i].div;
  364. break;
  365. }
  366. }
  367. if (i == ARRAY_SIZE(post_table)) {
  368. printk(KERN_ERR "wm8580: Unable to scale output frequency "
  369. "%u\n", target);
  370. return -EINVAL;
  371. }
  372. Ndiv = target / source;
  373. if (Ndiv < 5) {
  374. source /= 2;
  375. pll_div->prescale = 1;
  376. Ndiv = target / source;
  377. } else
  378. pll_div->prescale = 0;
  379. if ((Ndiv < 5) || (Ndiv > 13)) {
  380. printk(KERN_ERR
  381. "WM8580 N=%d outside supported range\n", Ndiv);
  382. return -EINVAL;
  383. }
  384. pll_div->n = Ndiv;
  385. Nmod = target % source;
  386. Kpart = FIXED_PLL_SIZE * (long long)Nmod;
  387. do_div(Kpart, source);
  388. K = Kpart & 0xFFFFFFFF;
  389. pll_div->k = K;
  390. pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",
  391. pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,
  392. pll_div->postscale);
  393. return 0;
  394. }
  395. static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
  396. int pll_id, unsigned int freq_in, unsigned int freq_out)
  397. {
  398. int offset;
  399. struct snd_soc_codec *codec = codec_dai->codec;
  400. struct wm8580_priv *wm8580 = codec->private_data;
  401. struct pll_state *state;
  402. struct _pll_div pll_div;
  403. unsigned int reg;
  404. unsigned int pwr_mask;
  405. int ret;
  406. /* GCC isn't able to work out the ifs below for initialising/using
  407. * pll_div so suppress warnings.
  408. */
  409. memset(&pll_div, 0, sizeof(pll_div));
  410. switch (pll_id) {
  411. case WM8580_PLLA:
  412. state = &wm8580->a;
  413. offset = 0;
  414. pwr_mask = WM8580_PWRDN2_PLLAPD;
  415. break;
  416. case WM8580_PLLB:
  417. state = &wm8580->b;
  418. offset = 4;
  419. pwr_mask = WM8580_PWRDN2_PLLBPD;
  420. break;
  421. default:
  422. return -ENODEV;
  423. }
  424. if (freq_in && freq_out) {
  425. ret = pll_factors(&pll_div, freq_out, freq_in);
  426. if (ret != 0)
  427. return ret;
  428. }
  429. state->in = freq_in;
  430. state->out = freq_out;
  431. /* Always disable the PLL - it is not safe to leave it running
  432. * while reprogramming it.
  433. */
  434. reg = wm8580_read(codec, WM8580_PWRDN2);
  435. wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask);
  436. if (!freq_in || !freq_out)
  437. return 0;
  438. wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
  439. wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff);
  440. wm8580_write(codec, WM8580_PLLA3 + offset,
  441. (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
  442. reg = wm8580_read(codec, WM8580_PLLA4 + offset);
  443. reg &= ~0x3f;
  444. reg |= pll_div.prescale | pll_div.postscale << 1 |
  445. pll_div.freqmode << 4;
  446. wm8580_write(codec, WM8580_PLLA4 + offset, reg);
  447. /* All done, turn it on */
  448. reg = wm8580_read(codec, WM8580_PWRDN2);
  449. wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
  450. return 0;
  451. }
  452. /*
  453. * Set PCM DAI bit size and sample rate.
  454. */
  455. static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
  456. struct snd_pcm_hw_params *params,
  457. struct snd_soc_dai *dai)
  458. {
  459. struct snd_soc_pcm_runtime *rtd = substream->private_data;
  460. struct snd_soc_device *socdev = rtd->socdev;
  461. struct snd_soc_codec *codec = socdev->card->codec;
  462. u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
  463. paifb &= ~WM8580_AIF_LENGTH_MASK;
  464. /* bit size */
  465. switch (params_format(params)) {
  466. case SNDRV_PCM_FORMAT_S16_LE:
  467. break;
  468. case SNDRV_PCM_FORMAT_S20_3LE:
  469. paifb |= WM8580_AIF_LENGTH_20;
  470. break;
  471. case SNDRV_PCM_FORMAT_S24_LE:
  472. paifb |= WM8580_AIF_LENGTH_24;
  473. break;
  474. case SNDRV_PCM_FORMAT_S32_LE:
  475. paifb |= WM8580_AIF_LENGTH_24;
  476. break;
  477. default:
  478. return -EINVAL;
  479. }
  480. wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
  481. return 0;
  482. }
  483. static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
  484. unsigned int fmt)
  485. {
  486. struct snd_soc_codec *codec = codec_dai->codec;
  487. unsigned int aifa;
  488. unsigned int aifb;
  489. int can_invert_lrclk;
  490. aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id);
  491. aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id);
  492. aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
  493. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  494. case SND_SOC_DAIFMT_CBS_CFS:
  495. aifa &= ~WM8580_AIF_MS;
  496. break;
  497. case SND_SOC_DAIFMT_CBM_CFM:
  498. aifa |= WM8580_AIF_MS;
  499. break;
  500. default:
  501. return -EINVAL;
  502. }
  503. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  504. case SND_SOC_DAIFMT_I2S:
  505. can_invert_lrclk = 1;
  506. aifb |= WM8580_AIF_FMT_I2S;
  507. break;
  508. case SND_SOC_DAIFMT_RIGHT_J:
  509. can_invert_lrclk = 1;
  510. aifb |= WM8580_AIF_FMT_RIGHTJ;
  511. break;
  512. case SND_SOC_DAIFMT_LEFT_J:
  513. can_invert_lrclk = 1;
  514. aifb |= WM8580_AIF_FMT_LEFTJ;
  515. break;
  516. case SND_SOC_DAIFMT_DSP_A:
  517. can_invert_lrclk = 0;
  518. aifb |= WM8580_AIF_FMT_DSP;
  519. break;
  520. case SND_SOC_DAIFMT_DSP_B:
  521. can_invert_lrclk = 0;
  522. aifb |= WM8580_AIF_FMT_DSP;
  523. aifb |= WM8580_AIF_LRP;
  524. break;
  525. default:
  526. return -EINVAL;
  527. }
  528. switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  529. case SND_SOC_DAIFMT_NB_NF:
  530. break;
  531. case SND_SOC_DAIFMT_IB_IF:
  532. if (!can_invert_lrclk)
  533. return -EINVAL;
  534. aifb |= WM8580_AIF_BCP;
  535. aifb |= WM8580_AIF_LRP;
  536. break;
  537. case SND_SOC_DAIFMT_IB_NF:
  538. aifb |= WM8580_AIF_BCP;
  539. break;
  540. case SND_SOC_DAIFMT_NB_IF:
  541. if (!can_invert_lrclk)
  542. return -EINVAL;
  543. aifb |= WM8580_AIF_LRP;
  544. break;
  545. default:
  546. return -EINVAL;
  547. }
  548. wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
  549. wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
  550. return 0;
  551. }
  552. static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
  553. int div_id, int div)
  554. {
  555. struct snd_soc_codec *codec = codec_dai->codec;
  556. unsigned int reg;
  557. switch (div_id) {
  558. case WM8580_MCLK:
  559. reg = wm8580_read(codec, WM8580_PLLB4);
  560. reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
  561. switch (div) {
  562. case WM8580_CLKSRC_MCLK:
  563. /* Input */
  564. break;
  565. case WM8580_CLKSRC_PLLA:
  566. reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;
  567. break;
  568. case WM8580_CLKSRC_PLLB:
  569. reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;
  570. break;
  571. case WM8580_CLKSRC_OSC:
  572. reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;
  573. break;
  574. default:
  575. return -EINVAL;
  576. }
  577. wm8580_write(codec, WM8580_PLLB4, reg);
  578. break;
  579. case WM8580_DAC_CLKSEL:
  580. reg = wm8580_read(codec, WM8580_CLKSEL);
  581. reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
  582. switch (div) {
  583. case WM8580_CLKSRC_MCLK:
  584. break;
  585. case WM8580_CLKSRC_PLLA:
  586. reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
  587. break;
  588. case WM8580_CLKSRC_PLLB:
  589. reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
  590. break;
  591. default:
  592. return -EINVAL;
  593. }
  594. wm8580_write(codec, WM8580_CLKSEL, reg);
  595. break;
  596. case WM8580_CLKOUTSRC:
  597. reg = wm8580_read(codec, WM8580_PLLB4);
  598. reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
  599. switch (div) {
  600. case WM8580_CLKSRC_NONE:
  601. break;
  602. case WM8580_CLKSRC_PLLA:
  603. reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;
  604. break;
  605. case WM8580_CLKSRC_PLLB:
  606. reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;
  607. break;
  608. case WM8580_CLKSRC_OSC:
  609. reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;
  610. break;
  611. default:
  612. return -EINVAL;
  613. }
  614. wm8580_write(codec, WM8580_PLLB4, reg);
  615. break;
  616. default:
  617. return -EINVAL;
  618. }
  619. return 0;
  620. }
  621. static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
  622. {
  623. struct snd_soc_codec *codec = codec_dai->codec;
  624. unsigned int reg;
  625. reg = wm8580_read(codec, WM8580_DAC_CONTROL5);
  626. if (mute)
  627. reg |= WM8580_DAC_CONTROL5_MUTEALL;
  628. else
  629. reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
  630. wm8580_write(codec, WM8580_DAC_CONTROL5, reg);
  631. return 0;
  632. }
  633. static int wm8580_set_bias_level(struct snd_soc_codec *codec,
  634. enum snd_soc_bias_level level)
  635. {
  636. u16 reg;
  637. switch (level) {
  638. case SND_SOC_BIAS_ON:
  639. case SND_SOC_BIAS_PREPARE:
  640. break;
  641. case SND_SOC_BIAS_STANDBY:
  642. if (codec->bias_level == SND_SOC_BIAS_OFF) {
  643. /* Power up and get individual control of the DACs */
  644. reg = wm8580_read(codec, WM8580_PWRDN1);
  645. reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
  646. wm8580_write(codec, WM8580_PWRDN1, reg);
  647. /* Make VMID high impedence */
  648. reg = wm8580_read(codec, WM8580_ADC_CONTROL1);
  649. reg &= ~0x100;
  650. wm8580_write(codec, WM8580_ADC_CONTROL1, reg);
  651. }
  652. break;
  653. case SND_SOC_BIAS_OFF:
  654. reg = wm8580_read(codec, WM8580_PWRDN1);
  655. wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
  656. break;
  657. }
  658. codec->bias_level = level;
  659. return 0;
  660. }
  661. #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
  662. SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
  663. static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
  664. .hw_params = wm8580_paif_hw_params,
  665. .set_fmt = wm8580_set_paif_dai_fmt,
  666. .set_clkdiv = wm8580_set_dai_clkdiv,
  667. .set_pll = wm8580_set_dai_pll,
  668. .digital_mute = wm8580_digital_mute,
  669. };
  670. static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
  671. .hw_params = wm8580_paif_hw_params,
  672. .set_fmt = wm8580_set_paif_dai_fmt,
  673. .set_clkdiv = wm8580_set_dai_clkdiv,
  674. .set_pll = wm8580_set_dai_pll,
  675. };
  676. struct snd_soc_dai wm8580_dai[] = {
  677. {
  678. .name = "WM8580 PAIFRX",
  679. .id = 0,
  680. .playback = {
  681. .stream_name = "Playback",
  682. .channels_min = 1,
  683. .channels_max = 6,
  684. .rates = SNDRV_PCM_RATE_8000_192000,
  685. .formats = WM8580_FORMATS,
  686. },
  687. .ops = &wm8580_dai_ops_playback,
  688. },
  689. {
  690. .name = "WM8580 PAIFTX",
  691. .id = 1,
  692. .capture = {
  693. .stream_name = "Capture",
  694. .channels_min = 2,
  695. .channels_max = 2,
  696. .rates = SNDRV_PCM_RATE_8000_192000,
  697. .formats = WM8580_FORMATS,
  698. },
  699. .ops = &wm8580_dai_ops_capture,
  700. },
  701. };
  702. EXPORT_SYMBOL_GPL(wm8580_dai);
  703. static struct snd_soc_codec *wm8580_codec;
  704. static int wm8580_probe(struct platform_device *pdev)
  705. {
  706. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  707. struct snd_soc_codec *codec;
  708. int ret = 0;
  709. if (wm8580_codec == NULL) {
  710. dev_err(&pdev->dev, "Codec device not registered\n");
  711. return -ENODEV;
  712. }
  713. socdev->card->codec = wm8580_codec;
  714. codec = wm8580_codec;
  715. /* register pcms */
  716. ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
  717. if (ret < 0) {
  718. dev_err(codec->dev, "failed to create pcms: %d\n", ret);
  719. goto pcm_err;
  720. }
  721. snd_soc_add_controls(codec, wm8580_snd_controls,
  722. ARRAY_SIZE(wm8580_snd_controls));
  723. wm8580_add_widgets(codec);
  724. ret = snd_soc_init_card(socdev);
  725. if (ret < 0) {
  726. dev_err(codec->dev, "failed to register card: %d\n", ret);
  727. goto card_err;
  728. }
  729. return ret;
  730. card_err:
  731. snd_soc_free_pcms(socdev);
  732. snd_soc_dapm_free(socdev);
  733. pcm_err:
  734. return ret;
  735. }
  736. /* power down chip */
  737. static int wm8580_remove(struct platform_device *pdev)
  738. {
  739. struct snd_soc_device *socdev = platform_get_drvdata(pdev);
  740. snd_soc_free_pcms(socdev);
  741. snd_soc_dapm_free(socdev);
  742. return 0;
  743. }
  744. struct snd_soc_codec_device soc_codec_dev_wm8580 = {
  745. .probe = wm8580_probe,
  746. .remove = wm8580_remove,
  747. };
  748. EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
  749. static int wm8580_register(struct wm8580_priv *wm8580)
  750. {
  751. int ret, i;
  752. struct snd_soc_codec *codec = &wm8580->codec;
  753. if (wm8580_codec) {
  754. dev_err(codec->dev, "Another WM8580 is registered\n");
  755. ret = -EINVAL;
  756. goto err;
  757. }
  758. mutex_init(&codec->mutex);
  759. INIT_LIST_HEAD(&codec->dapm_widgets);
  760. INIT_LIST_HEAD(&codec->dapm_paths);
  761. codec->private_data = wm8580;
  762. codec->name = "WM8580";
  763. codec->owner = THIS_MODULE;
  764. codec->read = wm8580_read_reg_cache;
  765. codec->write = wm8580_write;
  766. codec->bias_level = SND_SOC_BIAS_OFF;
  767. codec->set_bias_level = wm8580_set_bias_level;
  768. codec->dai = wm8580_dai;
  769. codec->num_dai = ARRAY_SIZE(wm8580_dai);
  770. codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
  771. codec->reg_cache = &wm8580->reg_cache;
  772. memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
  773. /* Get the codec into a known state */
  774. ret = wm8580_write(codec, WM8580_RESET, 0);
  775. if (ret != 0) {
  776. dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
  777. goto err;
  778. }
  779. for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
  780. wm8580_dai[i].dev = codec->dev;
  781. wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
  782. wm8580_codec = codec;
  783. ret = snd_soc_register_codec(codec);
  784. if (ret != 0) {
  785. dev_err(codec->dev, "Failed to register codec: %d\n", ret);
  786. goto err;
  787. }
  788. ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
  789. if (ret != 0) {
  790. dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
  791. goto err_codec;
  792. }
  793. return 0;
  794. err_codec:
  795. snd_soc_unregister_codec(codec);
  796. err:
  797. kfree(wm8580);
  798. return ret;
  799. }
  800. static void wm8580_unregister(struct wm8580_priv *wm8580)
  801. {
  802. wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
  803. snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
  804. snd_soc_unregister_codec(&wm8580->codec);
  805. kfree(wm8580);
  806. wm8580_codec = NULL;
  807. }
  808. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  809. static int wm8580_i2c_probe(struct i2c_client *i2c,
  810. const struct i2c_device_id *id)
  811. {
  812. struct wm8580_priv *wm8580;
  813. struct snd_soc_codec *codec;
  814. wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
  815. if (wm8580 == NULL)
  816. return -ENOMEM;
  817. codec = &wm8580->codec;
  818. codec->hw_write = (hw_write_t)i2c_master_send;
  819. i2c_set_clientdata(i2c, wm8580);
  820. codec->control_data = i2c;
  821. codec->dev = &i2c->dev;
  822. return wm8580_register(wm8580);
  823. }
  824. static int wm8580_i2c_remove(struct i2c_client *client)
  825. {
  826. struct wm8580_priv *wm8580 = i2c_get_clientdata(client);
  827. wm8580_unregister(wm8580);
  828. return 0;
  829. }
  830. static const struct i2c_device_id wm8580_i2c_id[] = {
  831. { "wm8580", 0 },
  832. { }
  833. };
  834. MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
  835. static struct i2c_driver wm8580_i2c_driver = {
  836. .driver = {
  837. .name = "wm8580",
  838. .owner = THIS_MODULE,
  839. },
  840. .probe = wm8580_i2c_probe,
  841. .remove = wm8580_i2c_remove,
  842. .id_table = wm8580_i2c_id,
  843. };
  844. #endif
  845. static int __init wm8580_modinit(void)
  846. {
  847. int ret;
  848. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  849. ret = i2c_add_driver(&wm8580_i2c_driver);
  850. if (ret != 0) {
  851. pr_err("Failed to register WM8580 I2C driver: %d\n", ret);
  852. }
  853. #endif
  854. return 0;
  855. }
  856. module_init(wm8580_modinit);
  857. static void __exit wm8580_exit(void)
  858. {
  859. #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
  860. i2c_del_driver(&wm8580_i2c_driver);
  861. #endif
  862. }
  863. module_exit(wm8580_exit);
  864. MODULE_DESCRIPTION("ASoC WM8580 driver");
  865. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  866. MODULE_LICENSE("GPL");