brintos

brintos / linux-shallow public Read only

0
0
Text · 27.3 KiB · 73a8edc Raw
1056 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm8580.c  --  WM8580 and WM8581 ALSA Soc Audio driver4 *5 * Copyright 2008-12 Wolfson Microelectronics PLC.6 *7 * Notes:8 *  The WM8580 is a multichannel codec with S/PDIF support, featuring six9 *  DAC channels and two ADC channels.10 *11 *  The WM8581 is a multichannel codec with S/PDIF support, featuring eight12 *  DAC channels and two ADC channels.13 *14 *  Currently only the primary audio interface is supported - S/PDIF and15 *  the secondary audio interfaces are not.16 */17 18#include <linux/mod_devicetable.h>19#include <linux/module.h>20#include <linux/moduleparam.h>21#include <linux/kernel.h>22#include <linux/init.h>23#include <linux/delay.h>24#include <linux/pm.h>25#include <linux/i2c.h>26#include <linux/regmap.h>27#include <linux/regulator/consumer.h>28#include <linux/slab.h>29 30#include <sound/core.h>31#include <sound/pcm.h>32#include <sound/pcm_params.h>33#include <sound/soc.h>34#include <sound/tlv.h>35#include <sound/initval.h>36#include <asm/div64.h>37 38#include "wm8580.h"39 40/* WM8580 register space */41#define WM8580_PLLA1                         0x0042#define WM8580_PLLA2                         0x0143#define WM8580_PLLA3                         0x0244#define WM8580_PLLA4                         0x0345#define WM8580_PLLB1                         0x0446#define WM8580_PLLB2                         0x0547#define WM8580_PLLB3                         0x0648#define WM8580_PLLB4                         0x0749#define WM8580_CLKSEL                        0x0850#define WM8580_PAIF1                         0x0951#define WM8580_PAIF2                         0x0A52#define WM8580_SAIF1                         0x0B53#define WM8580_PAIF3                         0x0C54#define WM8580_PAIF4                         0x0D55#define WM8580_SAIF2                         0x0E56#define WM8580_DAC_CONTROL1                  0x0F57#define WM8580_DAC_CONTROL2                  0x1058#define WM8580_DAC_CONTROL3                  0x1159#define WM8580_DAC_CONTROL4                  0x1260#define WM8580_DAC_CONTROL5                  0x1361#define WM8580_DIGITAL_ATTENUATION_DACL1     0x1462#define WM8580_DIGITAL_ATTENUATION_DACR1     0x1563#define WM8580_DIGITAL_ATTENUATION_DACL2     0x1664#define WM8580_DIGITAL_ATTENUATION_DACR2     0x1765#define WM8580_DIGITAL_ATTENUATION_DACL3     0x1866#define WM8580_DIGITAL_ATTENUATION_DACR3     0x1967#define WM8581_DIGITAL_ATTENUATION_DACL4     0x1A68#define WM8581_DIGITAL_ATTENUATION_DACR4     0x1B69#define WM8580_MASTER_DIGITAL_ATTENUATION    0x1C70#define WM8580_ADC_CONTROL1                  0x1D71#define WM8580_SPDTXCHAN0                    0x1E72#define WM8580_SPDTXCHAN1                    0x1F73#define WM8580_SPDTXCHAN2                    0x2074#define WM8580_SPDTXCHAN3                    0x2175#define WM8580_SPDTXCHAN4                    0x2276#define WM8580_SPDTXCHAN5                    0x2377#define WM8580_SPDMODE                       0x2478#define WM8580_INTMASK                       0x2579#define WM8580_GPO1                          0x2680#define WM8580_GPO2                          0x2781#define WM8580_GPO3                          0x2882#define WM8580_GPO4                          0x2983#define WM8580_GPO5                          0x2A84#define WM8580_INTSTAT                       0x2B85#define WM8580_SPDRXCHAN1                    0x2C86#define WM8580_SPDRXCHAN2                    0x2D87#define WM8580_SPDRXCHAN3                    0x2E88#define WM8580_SPDRXCHAN4                    0x2F89#define WM8580_SPDRXCHAN5                    0x3090#define WM8580_SPDSTAT                       0x3191#define WM8580_PWRDN1                        0x3292#define WM8580_PWRDN2                        0x3393#define WM8580_READBACK                      0x3494#define WM8580_RESET                         0x3595 96#define WM8580_MAX_REGISTER                  0x3597 98#define WM8580_DACOSR 0x4099 100/* PLLB4 (register 7h) */101#define WM8580_PLLB4_MCLKOUTSRC_MASK   0x60102#define WM8580_PLLB4_MCLKOUTSRC_PLLA   0x20103#define WM8580_PLLB4_MCLKOUTSRC_PLLB   0x40104#define WM8580_PLLB4_MCLKOUTSRC_OSC    0x60105 106#define WM8580_PLLB4_CLKOUTSRC_MASK    0x180107#define WM8580_PLLB4_CLKOUTSRC_PLLACLK 0x080108#define WM8580_PLLB4_CLKOUTSRC_PLLBCLK 0x100109#define WM8580_PLLB4_CLKOUTSRC_OSCCLK  0x180110 111/* CLKSEL (register 8h) */112#define WM8580_CLKSEL_DAC_CLKSEL_MASK 0x03113#define WM8580_CLKSEL_DAC_CLKSEL_PLLA 0x01114#define WM8580_CLKSEL_DAC_CLKSEL_PLLB 0x02115 116/* AIF control 1 (registers 9h-bh) */117#define WM8580_AIF_RATE_MASK       0x7118#define WM8580_AIF_BCLKSEL_MASK   0x18119 120#define WM8580_AIF_MS             0x20121 122#define WM8580_AIF_CLKSRC_MASK    0xc0123#define WM8580_AIF_CLKSRC_PLLA    0x40124#define WM8580_AIF_CLKSRC_PLLB    0x40125#define WM8580_AIF_CLKSRC_MCLK    0xc0126 127/* AIF control 2 (registers ch-eh) */128#define WM8580_AIF_FMT_MASK    0x03129#define WM8580_AIF_FMT_RIGHTJ  0x00130#define WM8580_AIF_FMT_LEFTJ   0x01131#define WM8580_AIF_FMT_I2S     0x02132#define WM8580_AIF_FMT_DSP     0x03133 134#define WM8580_AIF_LENGTH_MASK   0x0c135#define WM8580_AIF_LENGTH_16     0x00136#define WM8580_AIF_LENGTH_20     0x04137#define WM8580_AIF_LENGTH_24     0x08138#define WM8580_AIF_LENGTH_32     0x0c139 140#define WM8580_AIF_LRP         0x10141#define WM8580_AIF_BCP         0x20142 143/* Powerdown Register 1 (register 32h) */144#define WM8580_PWRDN1_PWDN     0x001145#define WM8580_PWRDN1_ALLDACPD 0x040146 147/* Powerdown Register 2 (register 33h) */148#define WM8580_PWRDN2_OSSCPD   0x001149#define WM8580_PWRDN2_PLLAPD   0x002150#define WM8580_PWRDN2_PLLBPD   0x004151#define WM8580_PWRDN2_SPDIFPD  0x008152#define WM8580_PWRDN2_SPDIFTXD 0x010153#define WM8580_PWRDN2_SPDIFRXD 0x020154 155#define WM8580_DAC_CONTROL5_MUTEALL 0x10156 157/*158 * wm8580 register cache159 * We can't read the WM8580 register space when we160 * are using 2 wire for device control, so we cache them instead.161 */162static const struct reg_default wm8580_reg_defaults[] = {163	{  0, 0x0121 },164	{  1, 0x017e },165	{  2, 0x007d },166	{  3, 0x0014 },167	{  4, 0x0121 },168	{  5, 0x017e },169	{  6, 0x007d },170	{  7, 0x0194 },171	{  8, 0x0010 },172	{  9, 0x0002 },173	{ 10, 0x0002 },174	{ 11, 0x00c2 },175	{ 12, 0x0182 },176	{ 13, 0x0082 },177	{ 14, 0x000a },178	{ 15, 0x0024 },179	{ 16, 0x0009 },180	{ 17, 0x0000 },181	{ 18, 0x00ff },182	{ 19, 0x0000 },183	{ 20, 0x00ff },184	{ 21, 0x00ff },185	{ 22, 0x00ff },186	{ 23, 0x00ff },187	{ 24, 0x00ff },188	{ 25, 0x00ff },189	{ 26, 0x00ff },190	{ 27, 0x00ff },191	{ 28, 0x01f0 },192	{ 29, 0x0040 },193	{ 30, 0x0000 },194	{ 31, 0x0000 },195	{ 32, 0x0000 },196	{ 33, 0x0000 },197	{ 34, 0x0031 },198	{ 35, 0x000b },199	{ 36, 0x0039 },200	{ 37, 0x0000 },201	{ 38, 0x0010 },202	{ 39, 0x0032 },203	{ 40, 0x0054 },204	{ 41, 0x0076 },205	{ 42, 0x0098 },206	{ 43, 0x0000 },207	{ 44, 0x0000 },208	{ 45, 0x0000 },209	{ 46, 0x0000 },210	{ 47, 0x0000 },211	{ 48, 0x0000 },212	{ 49, 0x0000 },213	{ 50, 0x005e },214	{ 51, 0x003e },215	{ 52, 0x0000 },216};217 218static bool wm8580_volatile(struct device *dev, unsigned int reg)219{220	switch (reg) {221	case WM8580_RESET:222		return true;223	default:224		return false;225	}226}227 228struct pll_state {229	unsigned int in;230	unsigned int out;231};232 233#define WM8580_NUM_SUPPLIES 3234static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {235	"AVDD",236	"DVDD",237	"PVDD",238};239 240struct wm8580_driver_data {241	int num_dacs;242};243 244/* codec private data */245struct wm8580_priv {246	struct regmap *regmap;247	struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];248	struct pll_state a;249	struct pll_state b;250	const struct wm8580_driver_data *drvdata;251	int sysclk[2];252};253 254static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);255 256static int wm8580_out_vu(struct snd_kcontrol *kcontrol,257			 struct snd_ctl_elem_value *ucontrol)258{259	struct soc_mixer_control *mc =260		(struct soc_mixer_control *)kcontrol->private_value;261	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);262	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);263	unsigned int reg = mc->reg;264	unsigned int reg2 = mc->rreg;265	int ret;266 267	/* Clear the register cache VU so we write without VU set */268	regcache_cache_only(wm8580->regmap, true);269	regmap_update_bits(wm8580->regmap, reg, 0x100, 0x000);270	regmap_update_bits(wm8580->regmap, reg2, 0x100, 0x000);271	regcache_cache_only(wm8580->regmap, false);272 273	ret = snd_soc_put_volsw(kcontrol, ucontrol);274	if (ret < 0)275		return ret;276 277	/* Now write again with the volume update bit set */278	snd_soc_component_update_bits(component, reg, 0x100, 0x100);279	snd_soc_component_update_bits(component, reg2, 0x100, 0x100);280 281	return 0;282}283 284static const struct snd_kcontrol_new wm8580_snd_controls[] = {285SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume",286		     WM8580_DIGITAL_ATTENUATION_DACL1,287		     WM8580_DIGITAL_ATTENUATION_DACR1,288		     0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),289SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume",290		     WM8580_DIGITAL_ATTENUATION_DACL2,291		     WM8580_DIGITAL_ATTENUATION_DACR2,292		     0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),293SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume",294		     WM8580_DIGITAL_ATTENUATION_DACL3,295		     WM8580_DIGITAL_ATTENUATION_DACR3,296		     0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),297 298SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),299SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),300SOC_SINGLE("DAC3 Deemphasis Switch", WM8580_DAC_CONTROL3, 2, 1, 0),301 302SOC_DOUBLE("DAC1 Invert Switch", WM8580_DAC_CONTROL4,  0, 1, 1, 0),303SOC_DOUBLE("DAC2 Invert Switch", WM8580_DAC_CONTROL4,  2, 3, 1, 0),304SOC_DOUBLE("DAC3 Invert Switch", WM8580_DAC_CONTROL4,  4, 5, 1, 0),305 306SOC_SINGLE("DAC ZC Switch", WM8580_DAC_CONTROL5, 5, 1, 0),307SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),308SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),309SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),310 311SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1),312SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),313};314 315static const struct snd_kcontrol_new wm8581_snd_controls[] = {316SOC_DOUBLE_R_EXT_TLV("DAC4 Playback Volume",317		     WM8581_DIGITAL_ATTENUATION_DACL4,318		     WM8581_DIGITAL_ATTENUATION_DACR4,319		     0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),320 321SOC_SINGLE("DAC4 Deemphasis Switch", WM8580_DAC_CONTROL3, 3, 1, 0),322 323SOC_DOUBLE("DAC4 Invert Switch", WM8580_DAC_CONTROL4,  8, 7, 1, 0),324 325SOC_SINGLE("DAC4 Switch", WM8580_DAC_CONTROL5, 3, 1, 1),326};327 328static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {329SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1),330SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1),331SND_SOC_DAPM_DAC("DAC3", "Playback", WM8580_PWRDN1, 4, 1),332 333SND_SOC_DAPM_OUTPUT("VOUT1L"),334SND_SOC_DAPM_OUTPUT("VOUT1R"),335SND_SOC_DAPM_OUTPUT("VOUT2L"),336SND_SOC_DAPM_OUTPUT("VOUT2R"),337SND_SOC_DAPM_OUTPUT("VOUT3L"),338SND_SOC_DAPM_OUTPUT("VOUT3R"),339 340SND_SOC_DAPM_ADC("ADC", "Capture", WM8580_PWRDN1, 1, 1),341 342SND_SOC_DAPM_INPUT("AINL"),343SND_SOC_DAPM_INPUT("AINR"),344};345 346static const struct snd_soc_dapm_widget wm8581_dapm_widgets[] = {347SND_SOC_DAPM_DAC("DAC4", "Playback", WM8580_PWRDN1, 5, 1),348 349SND_SOC_DAPM_OUTPUT("VOUT4L"),350SND_SOC_DAPM_OUTPUT("VOUT4R"),351};352 353static const struct snd_soc_dapm_route wm8580_dapm_routes[] = {354	{ "VOUT1L", NULL, "DAC1" },355	{ "VOUT1R", NULL, "DAC1" },356 357	{ "VOUT2L", NULL, "DAC2" },358	{ "VOUT2R", NULL, "DAC2" },359 360	{ "VOUT3L", NULL, "DAC3" },361	{ "VOUT3R", NULL, "DAC3" },362 363	{ "ADC", NULL, "AINL" },364	{ "ADC", NULL, "AINR" },365};366 367static const struct snd_soc_dapm_route wm8581_dapm_routes[] = {368	{ "VOUT4L", NULL, "DAC4" },369	{ "VOUT4R", NULL, "DAC4" },370};371 372/* PLL divisors */373struct _pll_div {374	u32 prescale:1;375	u32 postscale:1;376	u32 freqmode:2;377	u32 n:4;378	u32 k:24;379};380 381/* The size in bits of the pll divide */382#define FIXED_PLL_SIZE (1 << 22)383 384/* PLL rate to output rate divisions */385static struct {386	unsigned int div;387	unsigned int freqmode;388	unsigned int postscale;389} post_table[] = {390	{  2,  0, 0 },391	{  4,  0, 1 },392	{  4,  1, 0 },393	{  8,  1, 1 },394	{  8,  2, 0 },395	{ 16,  2, 1 },396	{ 12,  3, 0 },397	{ 24,  3, 1 }398};399 400static int pll_factors(struct _pll_div *pll_div, unsigned int target,401		       unsigned int source)402{403	u64 Kpart;404	unsigned int K, Ndiv, Nmod;405	int i;406 407	pr_debug("wm8580: PLL %uHz->%uHz\n", source, target);408 409	/* Scale the output frequency up; the PLL should run in the410	 * region of 90-100MHz.411	 */412	for (i = 0; i < ARRAY_SIZE(post_table); i++) {413		if (target * post_table[i].div >=  90000000 &&414		    target * post_table[i].div <= 100000000) {415			pll_div->freqmode = post_table[i].freqmode;416			pll_div->postscale = post_table[i].postscale;417			target *= post_table[i].div;418			break;419		}420	}421 422	if (i == ARRAY_SIZE(post_table)) {423		printk(KERN_ERR "wm8580: Unable to scale output frequency "424		       "%u\n", target);425		return -EINVAL;426	}427 428	Ndiv = target / source;429 430	if (Ndiv < 5) {431		source /= 2;432		pll_div->prescale = 1;433		Ndiv = target / source;434	} else435		pll_div->prescale = 0;436 437	if ((Ndiv < 5) || (Ndiv > 13)) {438		printk(KERN_ERR439			"WM8580 N=%u outside supported range\n", Ndiv);440		return -EINVAL;441	}442 443	pll_div->n = Ndiv;444	Nmod = target % source;445	Kpart = FIXED_PLL_SIZE * (long long)Nmod;446 447	do_div(Kpart, source);448 449	K = Kpart & 0xFFFFFFFF;450 451	pll_div->k = K;452 453	pr_debug("PLL %x.%x prescale %d freqmode %d postscale %d\n",454		 pll_div->n, pll_div->k, pll_div->prescale, pll_div->freqmode,455		 pll_div->postscale);456 457	return 0;458}459 460static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,461		int source, unsigned int freq_in, unsigned int freq_out)462{463	int offset;464	struct snd_soc_component *component = codec_dai->component;465	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);466	struct pll_state *state;467	struct _pll_div pll_div;468	unsigned int reg;469	unsigned int pwr_mask;470	int ret;471 472	/* GCC isn't able to work out the ifs below for initialising/using473	 * pll_div so suppress warnings.474	 */475	memset(&pll_div, 0, sizeof(pll_div));476 477	switch (pll_id) {478	case WM8580_PLLA:479		state = &wm8580->a;480		offset = 0;481		pwr_mask = WM8580_PWRDN2_PLLAPD;482		break;483	case WM8580_PLLB:484		state = &wm8580->b;485		offset = 4;486		pwr_mask = WM8580_PWRDN2_PLLBPD;487		break;488	default:489		return -ENODEV;490	}491 492	if (freq_in && freq_out) {493		ret = pll_factors(&pll_div, freq_out, freq_in);494		if (ret != 0)495			return ret;496	}497 498	state->in = freq_in;499	state->out = freq_out;500 501	/* Always disable the PLL - it is not safe to leave it running502	 * while reprogramming it.503	 */504	snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, pwr_mask);505 506	if (!freq_in || !freq_out)507		return 0;508 509	snd_soc_component_write(component, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);510	snd_soc_component_write(component, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);511	snd_soc_component_write(component, WM8580_PLLA3 + offset,512		     (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));513 514	reg = snd_soc_component_read(component, WM8580_PLLA4 + offset);515	reg &= ~0x1b;516	reg |= pll_div.prescale | pll_div.postscale << 1 |517		pll_div.freqmode << 3;518 519	snd_soc_component_write(component, WM8580_PLLA4 + offset, reg);520 521	/* All done, turn it on */522	snd_soc_component_update_bits(component, WM8580_PWRDN2, pwr_mask, 0);523 524	return 0;525}526 527static const int wm8580_sysclk_ratios[] = {528	128, 192, 256, 384, 512, 768, 1152,529};530 531/*532 * Set PCM DAI bit size and sample rate.533 */534static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,535				 struct snd_pcm_hw_params *params,536				 struct snd_soc_dai *dai)537{538	struct snd_soc_component *component = dai->component;539	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);540	u16 paifa = 0;541	u16 paifb = 0;542	int i, ratio, osr;543 544	/* bit size */545	switch (params_width(params)) {546	case 16:547		paifa |= 0x8;548		break;549	case 20:550		paifa |= 0x0;551		paifb |= WM8580_AIF_LENGTH_20;552		break;553	case 24:554		paifa |= 0x0;555		paifb |= WM8580_AIF_LENGTH_24;556		break;557	case 32:558		paifa |= 0x0;559		paifb |= WM8580_AIF_LENGTH_32;560		break;561	default:562		return -EINVAL;563	}564 565	/* Look up the SYSCLK ratio; accept only exact matches */566	ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);567	for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)568		if (ratio == wm8580_sysclk_ratios[i])569			break;570	if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {571		dev_err(component->dev, "Invalid clock ratio %d/%d\n",572			wm8580->sysclk[dai->driver->id], params_rate(params));573		return -EINVAL;574	}575	paifa |= i;576	dev_dbg(component->dev, "Running at %dfs with %dHz clock\n",577		wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);578 579	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {580		switch (ratio) {581		case 128:582		case 192:583			osr = WM8580_DACOSR;584			dev_dbg(component->dev, "Selecting 64x OSR\n");585			break;586		default:587			osr = 0;588			dev_dbg(component->dev, "Selecting 128x OSR\n");589			break;590		}591 592		snd_soc_component_update_bits(component, WM8580_PAIF3, WM8580_DACOSR, osr);593	}594 595	snd_soc_component_update_bits(component, WM8580_PAIF1 + dai->driver->id,596			    WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,597			    paifa);598	snd_soc_component_update_bits(component, WM8580_PAIF3 + dai->driver->id,599			    WM8580_AIF_LENGTH_MASK, paifb);600	return 0;601}602 603static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,604				      unsigned int fmt)605{606	struct snd_soc_component *component = codec_dai->component;607	unsigned int aifa;608	unsigned int aifb;609	int can_invert_lrclk;610 611	aifa = snd_soc_component_read(component, WM8580_PAIF1 + codec_dai->driver->id);612	aifb = snd_soc_component_read(component, WM8580_PAIF3 + codec_dai->driver->id);613 614	aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);615 616	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {617	case SND_SOC_DAIFMT_CBS_CFS:618		aifa &= ~WM8580_AIF_MS;619		break;620	case SND_SOC_DAIFMT_CBM_CFM:621		aifa |= WM8580_AIF_MS;622		break;623	default:624		return -EINVAL;625	}626 627	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {628	case SND_SOC_DAIFMT_I2S:629		can_invert_lrclk = 1;630		aifb |= WM8580_AIF_FMT_I2S;631		break;632	case SND_SOC_DAIFMT_RIGHT_J:633		can_invert_lrclk = 1;634		aifb |= WM8580_AIF_FMT_RIGHTJ;635		break;636	case SND_SOC_DAIFMT_LEFT_J:637		can_invert_lrclk = 1;638		aifb |= WM8580_AIF_FMT_LEFTJ;639		break;640	case SND_SOC_DAIFMT_DSP_A:641		can_invert_lrclk = 0;642		aifb |= WM8580_AIF_FMT_DSP;643		break;644	case SND_SOC_DAIFMT_DSP_B:645		can_invert_lrclk = 0;646		aifb |= WM8580_AIF_FMT_DSP;647		aifb |= WM8580_AIF_LRP;648		break;649	default:650		return -EINVAL;651	}652 653	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {654	case SND_SOC_DAIFMT_NB_NF:655		break;656 657	case SND_SOC_DAIFMT_IB_IF:658		if (!can_invert_lrclk)659			return -EINVAL;660		aifb |= WM8580_AIF_BCP;661		aifb |= WM8580_AIF_LRP;662		break;663 664	case SND_SOC_DAIFMT_IB_NF:665		aifb |= WM8580_AIF_BCP;666		break;667 668	case SND_SOC_DAIFMT_NB_IF:669		if (!can_invert_lrclk)670			return -EINVAL;671		aifb |= WM8580_AIF_LRP;672		break;673 674	default:675		return -EINVAL;676	}677 678	snd_soc_component_write(component, WM8580_PAIF1 + codec_dai->driver->id, aifa);679	snd_soc_component_write(component, WM8580_PAIF3 + codec_dai->driver->id, aifb);680 681	return 0;682}683 684static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,685				 int div_id, int div)686{687	struct snd_soc_component *component = codec_dai->component;688	unsigned int reg;689 690	switch (div_id) {691	case WM8580_MCLK:692		reg = snd_soc_component_read(component, WM8580_PLLB4);693		reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;694 695		switch (div) {696		case WM8580_CLKSRC_MCLK:697			/* Input */698			break;699 700		case WM8580_CLKSRC_PLLA:701			reg |= WM8580_PLLB4_MCLKOUTSRC_PLLA;702			break;703		case WM8580_CLKSRC_PLLB:704			reg |= WM8580_PLLB4_MCLKOUTSRC_PLLB;705			break;706 707		case WM8580_CLKSRC_OSC:708			reg |= WM8580_PLLB4_MCLKOUTSRC_OSC;709			break;710 711		default:712			return -EINVAL;713		}714		snd_soc_component_write(component, WM8580_PLLB4, reg);715		break;716 717	case WM8580_CLKOUTSRC:718		reg = snd_soc_component_read(component, WM8580_PLLB4);719		reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;720 721		switch (div) {722		case WM8580_CLKSRC_NONE:723			break;724 725		case WM8580_CLKSRC_PLLA:726			reg |= WM8580_PLLB4_CLKOUTSRC_PLLACLK;727			break;728 729		case WM8580_CLKSRC_PLLB:730			reg |= WM8580_PLLB4_CLKOUTSRC_PLLBCLK;731			break;732 733		case WM8580_CLKSRC_OSC:734			reg |= WM8580_PLLB4_CLKOUTSRC_OSCCLK;735			break;736 737		default:738			return -EINVAL;739		}740		snd_soc_component_write(component, WM8580_PLLB4, reg);741		break;742 743	default:744		return -EINVAL;745	}746 747	return 0;748}749 750static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,751			     unsigned int freq, int dir)752{753	struct snd_soc_component *component = dai->component;754	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);755	int ret, sel, sel_mask, sel_shift;756 757	switch (dai->driver->id) {758	case WM8580_DAI_PAIFRX:759		sel_mask = 0x3;760		sel_shift = 0;761		break;762 763	case WM8580_DAI_PAIFTX:764		sel_mask = 0xc;765		sel_shift = 2;766		break;767 768	default:769		WARN(1, "Unknown DAI driver ID\n");770		return -EINVAL;771	}772 773	switch (clk_id) {774	case WM8580_CLKSRC_ADCMCLK:775		if (dai->driver->id != WM8580_DAI_PAIFTX)776			return -EINVAL;777		sel = 0 << sel_shift;778		break;779	case WM8580_CLKSRC_PLLA:780		sel = 1 << sel_shift;781		break;782	case WM8580_CLKSRC_PLLB:783		sel = 2 << sel_shift;784		break;785	case WM8580_CLKSRC_MCLK:786		sel = 3 << sel_shift;787		break;788	default:789		dev_err(component->dev, "Unknown clock %d\n", clk_id);790		return -EINVAL;791	}792 793	/* We really should validate PLL settings but not yet */794	wm8580->sysclk[dai->driver->id] = freq;795 796	ret = snd_soc_component_update_bits(component, WM8580_CLKSEL, sel_mask, sel);797	if (ret < 0)798		return ret;799 800	return 0;801}802 803static int wm8580_mute(struct snd_soc_dai *codec_dai, int mute, int direction)804{805	struct snd_soc_component *component = codec_dai->component;806	unsigned int reg;807 808	reg = snd_soc_component_read(component, WM8580_DAC_CONTROL5);809 810	if (mute)811		reg |= WM8580_DAC_CONTROL5_MUTEALL;812	else813		reg &= ~WM8580_DAC_CONTROL5_MUTEALL;814 815	snd_soc_component_write(component, WM8580_DAC_CONTROL5, reg);816 817	return 0;818}819 820static int wm8580_set_bias_level(struct snd_soc_component *component,821	enum snd_soc_bias_level level)822{823	switch (level) {824	case SND_SOC_BIAS_ON:825	case SND_SOC_BIAS_PREPARE:826		break;827 828	case SND_SOC_BIAS_STANDBY:829		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {830			/* Power up and get individual control of the DACs */831			snd_soc_component_update_bits(component, WM8580_PWRDN1,832					    WM8580_PWRDN1_PWDN |833					    WM8580_PWRDN1_ALLDACPD, 0);834 835			/* Make VMID high impedance */836			snd_soc_component_update_bits(component, WM8580_ADC_CONTROL1,837					    0x100, 0);838		}839		break;840 841	case SND_SOC_BIAS_OFF:842		snd_soc_component_update_bits(component, WM8580_PWRDN1,843				    WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);844		break;845	}846	return 0;847}848 849static int wm8580_playback_startup(struct snd_pcm_substream *substream,850			   struct snd_soc_dai *dai)851{852	struct snd_soc_component *component = dai->component;853	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);854 855	return snd_pcm_hw_constraint_minmax(substream->runtime,856		SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2);857}858 859#define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\860			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)861 862static const struct snd_soc_dai_ops wm8580_dai_ops_playback = {863	.startup	= wm8580_playback_startup,864	.set_sysclk	= wm8580_set_sysclk,865	.hw_params	= wm8580_paif_hw_params,866	.set_fmt	= wm8580_set_paif_dai_fmt,867	.set_clkdiv	= wm8580_set_dai_clkdiv,868	.set_pll	= wm8580_set_dai_pll,869	.mute_stream	= wm8580_mute,870	.no_capture_mute = 1,871};872 873static const struct snd_soc_dai_ops wm8580_dai_ops_capture = {874	.set_sysclk	= wm8580_set_sysclk,875	.hw_params	= wm8580_paif_hw_params,876	.set_fmt	= wm8580_set_paif_dai_fmt,877	.set_clkdiv	= wm8580_set_dai_clkdiv,878	.set_pll	= wm8580_set_dai_pll,879};880 881static struct snd_soc_dai_driver wm8580_dai[] = {882	{883		.name = "wm8580-hifi-playback",884		.id	= WM8580_DAI_PAIFRX,885		.playback = {886			.stream_name = "Playback",887			.channels_min = 1,888			.rates = SNDRV_PCM_RATE_8000_192000,889			.formats = WM8580_FORMATS,890		},891		.ops = &wm8580_dai_ops_playback,892	},893	{894		.name = "wm8580-hifi-capture",895		.id	=	WM8580_DAI_PAIFTX,896		.capture = {897			.stream_name = "Capture",898			.channels_min = 2,899			.channels_max = 2,900			.rates = SNDRV_PCM_RATE_8000_192000,901			.formats = WM8580_FORMATS,902		},903		.ops = &wm8580_dai_ops_capture,904	},905};906 907static int wm8580_probe(struct snd_soc_component *component)908{909	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);910	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);911	int ret = 0;912 913	switch (wm8580->drvdata->num_dacs) {914	case 4:915		snd_soc_add_component_controls(component, wm8581_snd_controls,916					ARRAY_SIZE(wm8581_snd_controls));917		snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets,918					ARRAY_SIZE(wm8581_dapm_widgets));919		snd_soc_dapm_add_routes(dapm, wm8581_dapm_routes,920					ARRAY_SIZE(wm8581_dapm_routes));921		break;922	default:923		break;924	}925 926	ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),927				    wm8580->supplies);928	if (ret != 0) {929		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);930		goto err_regulator_get;931	}932 933	/* Get the codec into a known state */934	ret = snd_soc_component_write(component, WM8580_RESET, 0);935	if (ret != 0) {936		dev_err(component->dev, "Failed to reset component: %d\n", ret);937		goto err_regulator_enable;938	}939 940	return 0;941 942err_regulator_enable:943	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);944err_regulator_get:945	return ret;946}947 948/* power down chip */949static void wm8580_remove(struct snd_soc_component *component)950{951	struct wm8580_priv *wm8580 = snd_soc_component_get_drvdata(component);952 953	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);954}955 956static const struct snd_soc_component_driver soc_component_dev_wm8580 = {957	.probe			= wm8580_probe,958	.remove			= wm8580_remove,959	.set_bias_level		= wm8580_set_bias_level,960	.controls		= wm8580_snd_controls,961	.num_controls		= ARRAY_SIZE(wm8580_snd_controls),962	.dapm_widgets		= wm8580_dapm_widgets,963	.num_dapm_widgets	= ARRAY_SIZE(wm8580_dapm_widgets),964	.dapm_routes		= wm8580_dapm_routes,965	.num_dapm_routes	= ARRAY_SIZE(wm8580_dapm_routes),966	.idle_bias_on		= 1,967	.use_pmdown_time	= 1,968	.endianness		= 1,969};970 971static const struct regmap_config wm8580_regmap = {972	.reg_bits = 7,973	.val_bits = 9,974	.max_register = WM8580_MAX_REGISTER,975 976	.reg_defaults = wm8580_reg_defaults,977	.num_reg_defaults = ARRAY_SIZE(wm8580_reg_defaults),978	.cache_type = REGCACHE_MAPLE,979 980	.volatile_reg = wm8580_volatile,981};982 983static const struct wm8580_driver_data wm8580_data = {984	.num_dacs = 3,985};986 987static const struct wm8580_driver_data wm8581_data = {988	.num_dacs = 4,989};990 991static int wm8580_i2c_probe(struct i2c_client *i2c)992{993	struct wm8580_priv *wm8580;994	int ret, i;995 996	wm8580 = devm_kzalloc(&i2c->dev, sizeof(struct wm8580_priv),997			      GFP_KERNEL);998	if (wm8580 == NULL)999		return -ENOMEM;1000 1001	wm8580->regmap = devm_regmap_init_i2c(i2c, &wm8580_regmap);1002	if (IS_ERR(wm8580->regmap))1003		return PTR_ERR(wm8580->regmap);1004 1005	for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)1006		wm8580->supplies[i].supply = wm8580_supply_names[i];1007 1008	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8580->supplies),1009				      wm8580->supplies);1010	if (ret != 0) {1011		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);1012		return ret;1013	}1014 1015	i2c_set_clientdata(i2c, wm8580);1016 1017	wm8580->drvdata = i2c_get_match_data(i2c);1018	if (!wm8580->drvdata)1019		return dev_err_probe(&i2c->dev, -EINVAL, "failed to find driver data\n");1020 1021	ret = devm_snd_soc_register_component(&i2c->dev,1022			&soc_component_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));1023 1024	return ret;1025}1026 1027static const struct of_device_id wm8580_of_match[] = {1028	{ .compatible = "wlf,wm8580", .data = &wm8580_data },1029	{ .compatible = "wlf,wm8581", .data = &wm8581_data },1030	{ }1031};1032MODULE_DEVICE_TABLE(of, wm8580_of_match);1033 1034static const struct i2c_device_id wm8580_i2c_id[] = {1035	{ "wm8580", (kernel_ulong_t)&wm8580_data },1036	{ "wm8581", (kernel_ulong_t)&wm8581_data },1037	{ }1038};1039MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);1040 1041static struct i2c_driver wm8580_i2c_driver = {1042	.driver = {1043		.name = "wm8580",1044		.of_match_table = wm8580_of_match,1045	},1046	.probe = wm8580_i2c_probe,1047	.id_table = wm8580_i2c_id,1048};1049 1050module_i2c_driver(wm8580_i2c_driver);1051 1052MODULE_DESCRIPTION("ASoC WM8580 driver");1053MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");1054MODULE_AUTHOR("Matt Flax <flatmax@flatmax.org>");1055MODULE_LICENSE("GPL");1056