diff options
Diffstat (limited to 'sound/soc')
178 files changed, 9151 insertions, 4212 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3e598e7..21a5465 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -4,6 +4,8 @@ menuconfig SND_SOC tristate "ALSA for SoC audio support" + select LZO_COMPRESS + select LZO_DECOMPRESS select SND_PCM select AC97_BUS if SND_SOC_AC97_BUS select SND_JACK if INPUT=y || INPUT=SND @@ -36,7 +38,7 @@ source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" source "sound/soc/pxa/Kconfig" -source "sound/soc/s3c24xx/Kconfig" +source "sound/soc/samsung/Kconfig" source "sound/soc/s6000/Kconfig" source "sound/soc/sh/Kconfig" source "sound/soc/txx9/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index eb18344..ce913bf 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ obj-$(CONFIG_SND_SOC) += kirkwood/ obj-$(CONFIG_SND_SOC) += pxa/ -obj-$(CONFIG_SND_SOC) += s3c24xx/ +obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += s6000/ obj-$(CONFIG_SND_SOC) += sh/ obj-$(CONFIG_SND_SOC) += txx9/ diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c index 5f4e59f..1aac2f4 100644 --- a/sound/soc/atmel/playpaq_wm8510.c +++ b/sound/soc/atmel/playpaq_wm8510.c @@ -33,7 +33,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <mach/at32ap700x.h> #include <mach/portmux.h> @@ -318,27 +317,28 @@ static const struct snd_soc_dapm_route intercon[] = { static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; /* * Add DAPM widgets */ for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]); + snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); /* * Setup audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); /* always connected pins */ - snd_soc_dapm_enable_pin(codec, "Int Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(dapm, "Int Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_sync(dapm); diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 032e17d..1c9de19 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -44,7 +44,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -140,6 +139,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; printk(KERN_DEBUG @@ -154,25 +154,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) } /* Add specific widgets */ - snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets, + snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets, ARRAY_SIZE(at91sam9g20ek_dapm_widgets)); /* Set up specific audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); /* not connected */ - snd_soc_dapm_nc_pin(codec, "RLINEIN"); - snd_soc_dapm_nc_pin(codec, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); #ifdef ENABLE_MIC_INPUT - snd_soc_dapm_enable_pin(codec, "Int Mic"); + snd_soc_dapm_enable_pin(dapm, "Int Mic"); #else - snd_soc_dapm_nc_pin(codec, "Int Mic"); + snd_soc_dapm_nc_pin(dapm, "Int Mic"); #endif /* always connected */ - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index e3d2835..1202f5e 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c @@ -30,7 +30,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -105,19 +104,20 @@ static const struct snd_soc_dapm_route audio_map[] = { static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add afeb9260 specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up afeb9260 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index b62fcd3..cb99f04 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -13,7 +13,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1xxx_psc.h> #include <asm/mach-au1x00/au1xxx_dbdma.h> diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 2394bff..83012da 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -20,7 +20,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/pcm_params.h> #include <asm/blackfin.h> diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index e4a6253..d3ccb92 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -29,7 +29,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/pcm_params.h> #include <asm/blackfin.h> diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 900ced5..732fb8b 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -35,7 +35,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/pcm_params.h> #include <asm/blackfin.h> diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 36f2769..e902b24 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -33,7 +33,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/pcm_params.h> #include <asm/dma.h> diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 01d19e9..7e4d880 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -19,7 +19,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/initval.h> #include <sound/jack.h> @@ -1172,7 +1171,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable Audio PLL & Audio section */ data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; @@ -1185,7 +1184,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1346,6 +1345,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect); static int pm860x_probe(struct snd_soc_codec *codec) { struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int i, ret; pm860x->codec = codec; @@ -1374,9 +1374,9 @@ static int pm860x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, pm860x_snd_controls, ARRAY_SIZE(pm860x_snd_controls)); - snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets, ARRAY_SIZE(pm860x_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; out_codec: diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 3b5690d..0f33db2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4535 if I2C select SND_SOC_AK4642 if I2C select SND_SOC_AK4671 if I2C + select SND_SOC_ALC5623 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C select SND_SOC_CS4270 if I2C @@ -54,9 +55,11 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8727 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI + select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI + select SND_SOC_WM8770 if SPI_MASTER select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C @@ -130,6 +133,9 @@ config SND_SOC_AK4642 config SND_SOC_AK4671 tristate +config SND_SOC_ALC5623 + tristate + config SND_SOC_CQ0093VC tristate @@ -231,6 +237,9 @@ config SND_SOC_WM8728 config SND_SOC_WM8731 tristate +config SND_SOC_WM8737 + tristate + config SND_SOC_WM8741 tristate @@ -240,6 +249,9 @@ config SND_SOC_WM8750 config SND_SOC_WM8753 tristate +config SND_SOC_WM8770 + tristate + config SND_SOC_WM8776 tristate @@ -318,3 +330,4 @@ config SND_SOC_WM2000 config SND_SOC_WM9090 tristate + diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f67a2d6..10e5e09 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -17,6 +17,7 @@ snd-soc-da7210-objs := da7210.o snd-soc-l3-objs := l3.o snd-soc-max98088-objs := max98088.o snd-soc-pcm3008-objs := pcm3008.o +snd-soc-alc5623-objs := alc5623.o snd-soc-spdif-objs := spdif_transciever.o snd-soc-ssm2602-objs := ssm2602.o snd-soc-stac9766-objs := stac9766.o @@ -38,9 +39,11 @@ snd-soc-wm8711-objs := wm8711.o snd-soc-wm8727-objs := wm8727.o snd-soc-wm8728-objs := wm8728.o snd-soc-wm8731-objs := wm8731.o +snd-soc-wm8737-objs := wm8737.o snd-soc-wm8741-objs := wm8741.o snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o +snd-soc-wm8770-objs := wm8770.o snd-soc-wm8776-objs := wm8776.o snd-soc-wm8804-objs := wm8804.o snd-soc-wm8900-objs := wm8900.o @@ -58,7 +61,7 @@ snd-soc-wm8985-objs := wm8985.o snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm8993-objs := wm8993.o -snd-soc-wm8994-objs := wm8994.o +snd-soc-wm8994-objs := wm8994.o wm8994-tables.o snd-soc-wm9081-objs := wm9081.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o @@ -92,6 +95,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o +obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o @@ -113,9 +117,11 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o +obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o +obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index d272534..ab63d52 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -27,7 +27,6 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/tlv.h> -#include <sound/soc-dapm.h> #include <linux/spi/spi.h> #include "ad1836.h" @@ -220,6 +219,7 @@ static struct snd_soc_dai_driver ad1836_dai = { static int ad1836_probe(struct snd_soc_codec *codec) { struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; codec->control_data = ad1836->control_data; @@ -227,7 +227,6 @@ static int ad1836_probe(struct snd_soc_codec *codec) if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); - kfree(ad1836); return ret; } @@ -252,9 +251,9 @@ static int ad1836_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ad1836_snd_controls, ARRAY_SIZE(ad1836_snd_controls)); - snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, + snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets, ARRAY_SIZE(ad1836_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index fa2834c..a007bd7 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -19,7 +19,6 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/tlv.h> -#include <sound/soc-dapm.h> #include "ad193x.h" /* codec private data */ @@ -353,6 +352,7 @@ static struct snd_soc_dai_driver ad193x_dai = { static int ad193x_probe(struct snd_soc_codec *codec) { struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; codec->control_data = ad193x->control_data; @@ -363,7 +363,6 @@ static int ad193x_probe(struct snd_soc_codec *codec) if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); - kfree(ad193x); return ret; } @@ -385,9 +384,9 @@ static int ad193x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ad193x_snd_controls, ARRAY_SIZE(ad193x_snd_controls)); - snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets, ARRAY_SIZE(ad193x_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 410ccd5..34cb51e 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -29,7 +29,6 @@ #include <sound/ac97_codec.h> #include <sound/initval.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "ad1980.h" diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index cd88c8f..7367545 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "ak4535.h" @@ -290,10 +289,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int ak4535_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets, - ARRAY_SIZE(ak4535_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets, + ARRAY_SIZE(ak4535_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -399,7 +399,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, ak4535_write(codec, AK4535_PM1, i & (~0x80)); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 90c90b7..f00eba3 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -26,7 +26,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/slab.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/initval.h> #include <sound/tlv.h> diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 24f5f49..4faf105 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -437,10 +436,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int ak4671_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets, - ARRAY_SIZE(ak4671_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets, + ARRAY_SIZE(ak4671_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -602,7 +602,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c new file mode 100644 index 0000000..9783e7e --- /dev/null +++ b/sound/soc/codecs/alc5623.c @@ -0,0 +1,1113 @@ +/* + * alc5623.c -- alc562[123] ALSA Soc Audio driver + * + * Copyright 2008 Realtek Microelectronics + * Author: flove <flove@realtek.com> Ethan <eku@marvell.com> + * + * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org> + * + * + * Based on WM8753.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/platform_device.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/tlv.h> +#include <sound/soc.h> +#include <sound/initval.h> +#include <sound/alc5623.h> + +#include "alc5623.h" + +static int caps_charge = 2000; +module_param(caps_charge, int, 0); +MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); + +/* codec private data */ +struct alc5623_priv { + enum snd_soc_control_type control_type; + void *control_data; + struct mutex mutex; + u8 id; + unsigned int sysclk; + u16 reg_cache[ALC5623_VENDOR_ID2+2]; + unsigned int add_ctrl; + unsigned int jack_det_ctrl; +}; + +static void alc5623_fill_cache(struct snd_soc_codec *codec) +{ + int i, step = codec->driver->reg_cache_step; + u16 *cache = codec->reg_cache; + + /* not really efficient ... */ + for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) + cache[i] = codec->hw_read(codec, i); +} + +static inline int alc5623_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, ALC5623_RESET, 0); +} + +static int amp_mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + /* to power-on/off class-d amp generators/speaker */ + /* need to write to 'index-46h' register : */ + /* so write index num (here 0x46) to reg 0x6a */ + /* and then 0xffff/0 to reg 0x6c */ + snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0); + break; + } + + return 0; +} + +/* + * ALC5623 Controls + */ + +static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0); +static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); +static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); +static const unsigned int boost_tlv[] = { + TLV_DB_RANGE_HEAD(3), + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), +}; +static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); + +static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Speaker Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Speaker Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Headphone Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Headphone Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Speaker Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Speaker Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Line Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Line Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Line Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Line Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Headphone Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Headphone Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_snd_controls[] = { + SOC_DOUBLE_TLV("Auxout Playback Volume", + ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Auxout Playback Switch", + ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("PCM Playback Volume", + ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("AuxI Capture Volume", + ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("LineIn Capture Volume", + ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), + SOC_SINGLE_TLV("Mic1 Capture Volume", + ALC5623_MIC_VOL, 8, 31, 1, vol_tlv), + SOC_SINGLE_TLV("Mic2 Capture Volume", + ALC5623_MIC_VOL, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("Rec Capture Volume", + ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv), + SOC_SINGLE_TLV("Mic 1 Boost Volume", + ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Mic 2 Boost Volume", + ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Digital Boost Volume", + ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv), +}; + +/* + * DAPM Controls + */ +static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1), +SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1), +SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1), +SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1), +SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1), +SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1), +SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1), +}; + +/* Left Record Mixer */ +static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1), +SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1), +SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1), +SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1), +}; + +/* Right Record Mixer */ +static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1), +SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1), +SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1), +SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1), +}; + +static const char *alc5623_spk_n_sour_sel[] = { + "RN/-R", "RP/+R", "LN/-R", "Vmid" }; +static const char *alc5623_hpl_out_input_sel[] = { + "Vmid", "HP Left Mix"}; +static const char *alc5623_hpr_out_input_sel[] = { + "Vmid", "HP Right Mix"}; +static const char *alc5623_spkout_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; +static const char *alc5623_aux_out_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; + +/* auxout output mux */ +static const struct soc_enum alc5623_aux_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); +static const struct snd_kcontrol_new alc5623_auxout_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); + +/* speaker output mux */ +static const struct soc_enum alc5623_spkout_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); +static const struct snd_kcontrol_new alc5623_spkout_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); + +/* headphone left output mux */ +static const struct soc_enum alc5623_hpl_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); +static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); + +/* headphone right output mux */ +static const struct soc_enum alc5623_hpr_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); +static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); + +/* speaker output N select */ +static const struct soc_enum alc5623_spk_n_sour_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); +static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); + +static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = { +/* Muxes */ +SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0, + &alc5623_auxout_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0, + &alc5623_spkout_mux_controls), +SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5623_hpl_out_mux_controls), +SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5623_hpr_out_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, + &alc5623_spkoutn_mux_controls), + +/* output mixers */ +SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, + &alc5623_hp_mixer_controls[0], + ARRAY_SIZE(alc5623_hp_mixer_controls)), +SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0, + &alc5623_hpr_mixer_controls[0], + ARRAY_SIZE(alc5623_hpr_mixer_controls)), +SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0, + &alc5623_hpl_mixer_controls[0], + ARRAY_SIZE(alc5623_hpl_mixer_controls)), +SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0, + &alc5623_mono_mixer_controls[0], + ARRAY_SIZE(alc5623_mono_mixer_controls)), +SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0, + &alc5623_speaker_mixer_controls[0], + ARRAY_SIZE(alc5623_speaker_mixer_controls)), + +/* input mixers */ +SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0, + &alc5623_captureL_mixer_controls[0], + ARRAY_SIZE(alc5623_captureL_mixer_controls)), +SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0, + &alc5623_captureR_mixer_controls[0], + ARRAY_SIZE(alc5623_captureR_mixer_controls)), + +SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", + ALC5623_PWR_MANAG_ADD2, 9, 0), +SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", + ALC5623_PWR_MANAG_ADD2, 8, 0), +SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0), +SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", + ALC5623_PWR_MANAG_ADD2, 7, 0), +SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", + ALC5623_PWR_MANAG_ADD2, 6, 0), +SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0), +SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0), +SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0), + +SND_SOC_DAPM_OUTPUT("AUXOUTL"), +SND_SOC_DAPM_OUTPUT("AUXOUTR"), +SND_SOC_DAPM_OUTPUT("HPL"), +SND_SOC_DAPM_OUTPUT("HPR"), +SND_SOC_DAPM_OUTPUT("SPKOUT"), +SND_SOC_DAPM_OUTPUT("SPKOUTN"), +SND_SOC_DAPM_INPUT("LINEINL"), +SND_SOC_DAPM_INPUT("LINEINR"), +SND_SOC_DAPM_INPUT("AUXINL"), +SND_SOC_DAPM_INPUT("AUXINR"), +SND_SOC_DAPM_INPUT("MIC1"), +SND_SOC_DAPM_INPUT("MIC2"), +SND_SOC_DAPM_VMID("Vmid"), +}; + +static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; +static const struct soc_enum alc5623_amp_enum = + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); +static const struct snd_kcontrol_new alc5623_amp_mux_controls = + SOC_DAPM_ENUM("Route", alc5623_amp_enum); + +static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = { +SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0, + amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0), +SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0, + &alc5623_amp_mux_controls), +}; + +static const struct snd_soc_dapm_route intercon[] = { + /* virtual mixer - mixes left & right channels */ + {"I2S Mix", NULL, "Left DAC"}, + {"I2S Mix", NULL, "Right DAC"}, + {"Line Mix", NULL, "Right LineIn"}, + {"Line Mix", NULL, "Left LineIn"}, + {"AuxI Mix", NULL, "Left AuxI"}, + {"AuxI Mix", NULL, "Right AuxI"}, + {"AUXOUTL", NULL, "Left AuxOut"}, + {"AUXOUTR", NULL, "Right AuxOut"}, + + /* HP mixer */ + {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"}, + {"HPL Mix", NULL, "HP Mix"}, + {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"}, + {"HPR Mix", NULL, "HP Mix"}, + {"HP Mix", "LI2HP Playback Switch", "Line Mix"}, + {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"}, + {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, + {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, + {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"}, + + /* speaker mixer */ + {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, + {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"}, + {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, + {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, + {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"}, + + /* mono mixer */ + {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, + {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, + {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, + {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"}, + {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, + {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, + {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"}, + + /* Left record mixer */ + {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, + {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"}, + {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, + {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /*Right record mixer */ + {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, + {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"}, + {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, + {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /* headphone left mux */ + {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, + {"Left Headphone Mux", "Vmid", "Vmid"}, + + /* headphone right mux */ + {"Right Headphone Mux", "HP Right Mix", "HPR Mix"}, + {"Right Headphone Mux", "Vmid", "Vmid"}, + + /* speaker out mux */ + {"SpeakerOut Mux", "Vmid", "Vmid"}, + {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"}, + {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"}, + {"SpeakerOut Mux", "Mono Mix", "Mono Mix"}, + + /* Mono/Aux Out mux */ + {"AuxOut Mux", "Vmid", "Vmid"}, + {"AuxOut Mux", "HPOut Mix", "HPOut Mix"}, + {"AuxOut Mux", "Speaker Mix", "Speaker Mix"}, + {"AuxOut Mux", "Mono Mix", "Mono Mix"}, + + /* output pga */ + {"HPL", NULL, "Left Headphone"}, + {"Left Headphone", NULL, "Left Headphone Mux"}, + {"HPR", NULL, "Right Headphone"}, + {"Right Headphone", NULL, "Right Headphone Mux"}, + {"Left AuxOut", NULL, "AuxOut Mux"}, + {"Right AuxOut", NULL, "AuxOut Mux"}, + + /* input pga */ + {"Left LineIn", NULL, "LINEINL"}, + {"Right LineIn", NULL, "LINEINR"}, + {"Left AuxI", NULL, "AUXINL"}, + {"Right AuxI", NULL, "AUXINR"}, + {"MIC1 Pre Amp", NULL, "MIC1"}, + {"MIC2 Pre Amp", NULL, "MIC2"}, + {"MIC1 PGA", NULL, "MIC1 Pre Amp"}, + {"MIC2 PGA", NULL, "MIC2 Pre Amp"}, + + /* left ADC */ + {"Left ADC", NULL, "Left Capture Mix"}, + + /* right ADC */ + {"Right ADC", NULL, "Right Capture Mix"}, + + {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"}, + {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"}, + {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"}, + {"SpeakerOut N Mux", "Vmid", "Vmid"}, + + {"SPKOUT", NULL, "SpeakerOut"}, + {"SPKOUTN", NULL, "SpeakerOut N Mux"}, +}; + +static const struct snd_soc_dapm_route intercon_spk[] = { + {"SpeakerOut", NULL, "SpeakerOut Mux"}, +}; + +static const struct snd_soc_dapm_route intercon_amp_spk[] = { + {"AB Amp", NULL, "SpeakerOut Mux"}, + {"D Amp", NULL, "SpeakerOut Mux"}, + {"AB-D Amp Mux", "AB Amp", "AB Amp"}, + {"AB-D Amp Mux", "D Amp", "D Amp"}, + {"SpeakerOut", NULL, "AB-D Amp Mux"}, +}; + +/* PLL divisors */ +struct _pll_div { + u32 pll_in; + u32 pll_out; + u16 regvalue; +}; + +/* Note : pll code from original alc5623 driver. Not sure of how good it is */ +/* usefull only for master mode */ +static const struct _pll_div codec_master_pll_div[] = { + + { 2048000, 8192000, 0x0ea0}, + { 3686400, 8192000, 0x4e27}, + { 12000000, 8192000, 0x456b}, + { 13000000, 8192000, 0x495f}, + { 13100000, 8192000, 0x0320}, + { 2048000, 11289600, 0xf637}, + { 3686400, 11289600, 0x2f22}, + { 12000000, 11289600, 0x3e2f}, + { 13000000, 11289600, 0x4d5b}, + { 13100000, 11289600, 0x363b}, + { 2048000, 16384000, 0x1ea0}, + { 3686400, 16384000, 0x9e27}, + { 12000000, 16384000, 0x452b}, + { 13000000, 16384000, 0x542f}, + { 13100000, 16384000, 0x03a0}, + { 2048000, 16934400, 0xe625}, + { 3686400, 16934400, 0x9126}, + { 12000000, 16934400, 0x4d2c}, + { 13000000, 16934400, 0x742f}, + { 13100000, 16934400, 0x3c27}, + { 2048000, 22579200, 0x2aa0}, + { 3686400, 22579200, 0x2f20}, + { 12000000, 22579200, 0x7e2f}, + { 13000000, 22579200, 0x742f}, + { 13100000, 22579200, 0x3c27}, + { 2048000, 24576000, 0x2ea0}, + { 3686400, 24576000, 0xee27}, + { 12000000, 24576000, 0x2915}, + { 13000000, 24576000, 0x772e}, + { 13100000, 24576000, 0x0d20}, +}; + +static const struct _pll_div codec_slave_pll_div[] = { + + { 1024000, 16384000, 0x3ea0}, + { 1411200, 22579200, 0x3ea0}, + { 1536000, 24576000, 0x3ea0}, + { 2048000, 16384000, 0x1ea0}, + { 2822400, 22579200, 0x1ea0}, + { 3072000, 24576000, 0x1ea0}, + +}; + +static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + int i; + struct snd_soc_codec *codec = codec_dai->codec; + int gbl_clk = 0, pll_div = 0; + u16 reg; + + if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK) + return -ENODEV; + + /* Disable PLL power */ + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_PLL, + 0); + + /* pll is not used in slave mode */ + reg = snd_soc_read(codec, ALC5623_DAI_CONTROL); + if (reg & ALC5623_DAI_SDP_SLAVE_MODE) + return 0; + + if (!freq_in || !freq_out) + return 0; + + switch (pll_id) { + case ALC5623_PLL_FR_MCLK: + for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) { + if (codec_master_pll_div[i].pll_in == freq_in + && codec_master_pll_div[i].pll_out == freq_out) { + /* PLL source from MCLK */ + pll_div = codec_master_pll_div[i].regvalue; + break; + } + } + break; + case ALC5623_PLL_FR_BCK: + for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { + if (codec_slave_pll_div[i].pll_in == freq_in + && codec_slave_pll_div[i].pll_out == freq_out) { + /* PLL source from Bitclk */ + gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK; + pll_div = codec_slave_pll_div[i].regvalue; + break; + } + } + break; + default: + return -EINVAL; + } + + if (!pll_div) + return -EINVAL; + + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); + snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div); + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_PLL, + ALC5623_PWR_ADD2_PLL); + gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL; + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); + + return 0; +} + +struct _coeff_div { + u16 fs; + u16 regvalue; +}; + +/* codec hifi mclk (after PLL) clock divider coefficients */ +/* values inspired from column BCLK=32Fs of Appendix A table */ +static const struct _coeff_div coeff_div[] = { + {256*8, 0x3a69}, + {384*8, 0x3c6b}, + {256*4, 0x2a69}, + {384*4, 0x2c6b}, + {256*2, 0x1a69}, + {384*2, 0x1c6b}, + {256*1, 0x0a69}, + {384*1, 0x0c6b}, +}; + +static int get_coeff(struct snd_soc_codec *codec, int rate) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].fs * rate == alc5623->sysclk) + return i; + } + return -EINVAL; +} + +/* + * Clock after PLL and dividers + */ +static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + + switch (freq) { + case 8192000: + case 11289600: + case 12288000: + case 16384000: + case 16934400: + case 18432000: + case 22579200: + case 24576000: + alc5623->sysclk = freq; + return 0; + } + return -EINVAL; +} + +static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iface = ALC5623_DAI_SDP_MASTER_MODE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iface = ALC5623_DAI_SDP_SLAVE_MODE; + break; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= ALC5623_DAI_I2S_DF_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + iface |= ALC5623_DAI_I2S_DF_RIGHT; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= ALC5623_DAI_I2S_DF_LEFT; + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= ALC5623_DAI_I2S_DF_PCM; + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_NB_IF: + break; + default: + return -EINVAL; + } + + return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); +} + +static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + int coeff, rate; + u16 iface; + + iface = snd_soc_read(codec, ALC5623_DAI_CONTROL); + iface &= ~ALC5623_DAI_I2S_DL_MASK; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + iface |= ALC5623_DAI_I2S_DL_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= ALC5623_DAI_I2S_DL_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= ALC5623_DAI_I2S_DL_24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= ALC5623_DAI_I2S_DL_32; + break; + default: + return -EINVAL; + } + + /* set iface & srate */ + snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); + rate = params_rate(params); + coeff = get_coeff(codec, rate); + if (coeff < 0) + return -EINVAL; + + coeff = coeff_div[coeff].regvalue; + dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n", + __func__, alc5623->sysclk, rate, coeff); + snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff); + + return 0; +} + +static int alc5623_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT; + u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute; + + if (mute) + mute_reg |= hp_mute; + + return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg); +} + +#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \ + | ALC5623_PWR_ADD2_DAC_REF_CIR) + +#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \ + | ALC5623_PWR_ADD3_MIC1_BOOST_AD) + +#define ALC5623_ADD1_POWER_EN \ + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \ + | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \ + | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP) + +#define ALC5623_ADD1_POWER_EN_5622 \ + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \ + | ALC5623_PWR_ADD1_HP_OUT_AMP) + +static void enable_power_depop(struct snd_soc_codec *codec) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_PWR_ADD1_SOFTGEN_EN, + ALC5623_PWR_ADD1_SOFTGEN_EN); + + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN); + + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, + ALC5623_MISC_HP_DEPOP_MODE2_EN, + ALC5623_MISC_HP_DEPOP_MODE2_EN); + + msleep(500); + + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN); + + /* avoid writing '1' into 5622 reserved bits */ + if (alc5623->id == 0x22) + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_ADD1_POWER_EN_5622); + else + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_ADD1_POWER_EN); + + /* disable HP Depop2 */ + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, + ALC5623_MISC_HP_DEPOP_MODE2_EN, + 0); + +} + +static int alc5623_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + enable_power_depop(codec); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + /* everything off except vref/vmid, */ + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_VREF); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, + ALC5623_PWR_ADD3_MAIN_BIAS); + break; + case SND_SOC_BIAS_OFF: + /* everything off, dac mute, inactive */ + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops alc5623_dai_ops = { + .hw_params = alc5623_pcm_hw_params, + .digital_mute = alc5623_mute, + .set_fmt = alc5623_set_dai_fmt, + .set_sysclk = alc5623_set_dai_sysclk, + .set_pll = alc5623_set_dai_pll, +}; + +static struct snd_soc_dai_driver alc5623_dai = { + .name = "alc5623-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5623_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5623_FORMATS,}, + + .ops = &alc5623_dai_ops, +}; + +static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg) +{ + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int alc5623_resume(struct snd_soc_codec *codec) +{ + int i, step = codec->driver->reg_cache_step; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) + snd_soc_write(codec, i, cache[i]); + + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* charge alc5623 caps */ + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + codec->dapm.bias_level = SND_SOC_BIAS_ON; + alc5623_set_bias_level(codec, codec->dapm.bias_level); + } + + return 0; +} + +static int alc5623_probe(struct snd_soc_codec *codec) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + alc5623_reset(codec); + alc5623_fill_cache(codec); + + /* power on device */ + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + if (alc5623->add_ctrl) { + snd_soc_write(codec, ALC5623_ADD_CTRL_REG, + alc5623->add_ctrl); + } + + if (alc5623->jack_det_ctrl) { + snd_soc_write(codec, ALC5623_JACK_DET_CTRL, + alc5623->jack_det_ctrl); + } + + switch (alc5623->id) { + default: + case 0x21: + snd_soc_add_controls(codec, rt5621_vol_snd_controls, + ARRAY_SIZE(rt5621_vol_snd_controls)); + break; + case 0x22: + snd_soc_add_controls(codec, rt5622_vol_snd_controls, + ARRAY_SIZE(rt5622_vol_snd_controls)); + break; + case 0x23: + snd_soc_add_controls(codec, alc5623_vol_snd_controls, + ARRAY_SIZE(alc5623_vol_snd_controls)); + break; + } + + snd_soc_add_controls(codec, alc5623_snd_controls, + ARRAY_SIZE(alc5623_snd_controls)); + + snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, + ARRAY_SIZE(alc5623_dapm_widgets)); + + /* set up audio path interconnects */ + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + + switch (alc5623->id) { + default: + case 0x21: + case 0x22: + snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets, + ARRAY_SIZE(alc5623_dapm_amp_widgets)); + snd_soc_dapm_add_routes(dapm, intercon_amp_spk, + ARRAY_SIZE(intercon_amp_spk)); + break; + case 0x23: + snd_soc_dapm_add_routes(dapm, intercon_spk, + ARRAY_SIZE(intercon_spk)); + break; + } + + return ret; +} + +/* power down chip */ +static int alc5623_remove(struct snd_soc_codec *codec) +{ + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_device_alc5623 = { + .probe = alc5623_probe, + .remove = alc5623_remove, + .suspend = alc5623_suspend, + .resume = alc5623_resume, + .set_bias_level = alc5623_set_bias_level, + .reg_cache_size = ALC5623_VENDOR_ID2+2, + .reg_word_size = sizeof(u16), + .reg_cache_step = 2, +}; + +/* + * ALC5623 2 wire address is determined by A1 pin + * state during powerup. + * low = 0x1a + * high = 0x1b + */ +static int alc5623_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct alc5623_platform_data *pdata; + struct alc5623_priv *alc5623; + int ret, vid1, vid2; + + vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); + if (vid1 < 0) { + dev_err(&client->dev, "failed to read I2C\n"); + return -EIO; + } + vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); + + vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); + if (vid2 < 0) { + dev_err(&client->dev, "failed to read I2C\n"); + return -EIO; + } + + if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { + dev_err(&client->dev, "unknown or wrong codec\n"); + dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n", + 0x10ec, id->driver_data, + vid1, vid2); + return -ENODEV; + } + + dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); + + alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL); + if (alc5623 == NULL) + return -ENOMEM; + + pdata = client->dev.platform_data; + if (pdata) { + alc5623->add_ctrl = pdata->add_ctrl; + alc5623->jack_det_ctrl = pdata->jack_det_ctrl; + } + + alc5623->id = vid2; + switch (alc5623->id) { + case 0x21: + alc5623_dai.name = "alc5621-hifi"; + break; + case 0x22: + alc5623_dai.name = "alc5622-hifi"; + break; + default: + case 0x23: + alc5623_dai.name = "alc5623-hifi"; + break; + } + + i2c_set_clientdata(client, alc5623); + alc5623->control_data = client; + alc5623->control_type = SND_SOC_I2C; + mutex_init(&alc5623->mutex); + + ret = snd_soc_register_codec(&client->dev, + &soc_codec_device_alc5623, &alc5623_dai, 1); + if (ret != 0) { + dev_err(&client->dev, "Failed to register codec: %d\n", ret); + kfree(alc5623); + } + + return ret; +} + +static int alc5623_i2c_remove(struct i2c_client *client) +{ + struct alc5623_priv *alc5623 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + kfree(alc5623); + return 0; +} + +static const struct i2c_device_id alc5623_i2c_table[] = { + {"alc5621", 0x21}, + {"alc5622", 0x22}, + {"alc5623", 0x23}, + {} +}; +MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); + +/* i2c codec control layer */ +static struct i2c_driver alc5623_i2c_driver = { + .driver = { + .name = "alc562x-codec", + .owner = THIS_MODULE, + }, + .probe = alc5623_i2c_probe, + .remove = __devexit_p(alc5623_i2c_remove), + .id_table = alc5623_i2c_table, +}; + +static int __init alc5623_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&alc5623_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "%s: can't add i2c driver", __func__); + return ret; + } + + return ret; +} +module_init(alc5623_modinit); + +static void __exit alc5623_modexit(void) +{ + i2c_del_driver(&alc5623_i2c_driver); +} +module_exit(alc5623_modexit); + +MODULE_DESCRIPTION("ASoC alc5621/2/3 driver"); +MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h new file mode 100644 index 0000000..f3d6826 --- /dev/null +++ b/sound/soc/codecs/alc5623.h @@ -0,0 +1,161 @@ +/* + * alc5623.h -- alc562[123] ALSA Soc Audio driver + * + * Copyright 2008 Realtek Microelectronics + * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org> + * + * Author: flove <flove@realtek.com> + * Arnaud Patard <arnaud.patard@rtp-net.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _ALC5623_H +#define _ALC5623_H + +#define ALC5623_RESET 0x00 +/* 5621 5622 5623 */ +/* speaker output vol 2 2 */ +/* line output vol 4 2 */ +/* HP output vol 4 0 4 */ +#define ALC5623_SPK_OUT_VOL 0x02 +#define ALC5623_HP_OUT_VOL 0x04 +#define ALC5623_MONO_AUX_OUT_VOL 0x06 +#define ALC5623_AUXIN_VOL 0x08 +#define ALC5623_LINE_IN_VOL 0x0A +#define ALC5623_STEREO_DAC_VOL 0x0C +#define ALC5623_MIC_VOL 0x0E +#define ALC5623_MIC_ROUTING_CTRL 0x10 +#define ALC5623_ADC_REC_GAIN 0x12 +#define ALC5623_ADC_REC_MIXER 0x14 +#define ALC5623_SOFT_VOL_CTRL_TIME 0x16 +/* ALC5623_OUTPUT_MIXER_CTRL : */ +/* same remark as for reg 2 line vs speaker */ +#define ALC5623_OUTPUT_MIXER_CTRL 0x1C +#define ALC5623_MIC_CTRL 0x22 + +#define ALC5623_DAI_CONTROL 0x34 +#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15) +#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15) +#define ALC5623_DAI_I2S_PCM_MODE (1 << 14) +#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7) +#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5) +#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4) +#define ALC5623_DAI_I2S_DL_MASK (3 << 2) +#define ALC5623_DAI_I2S_DL_32 (3 << 2) +#define ALC5623_DAI_I2S_DL_24 (2 << 2) +#define ALC5623_DAI_I2S_DL_20 (1 << 2) +#define ALC5623_DAI_I2S_DL_16 (0 << 2) +#define ALC5623_DAI_I2S_DF_PCM (3 << 0) +#define ALC5623_DAI_I2S_DF_LEFT (2 << 0) +#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0) +#define ALC5623_DAI_I2S_DF_I2S (0 << 0) + +#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36 +#define ALC5623_COMPANDING_CTRL 0x38 + +#define ALC5623_PWR_MANAG_ADD1 0x3A +#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15) +#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14) +#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11) +#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10) +#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5) +#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2) +#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1) +#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */ + +#define ALC5623_PWR_MANAG_ADD2 0x3C +#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */ +#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */ +#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */ +#define ALC5623_PWR_ADD2_VREF (1 << 13) +#define ALC5623_PWR_ADD2_PLL (1 << 12) +#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10) +#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9) +#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8) +#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7) +#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6) +#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5) +#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4) +#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3) +#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2) +#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1) +#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0) + +#define ALC5623_PWR_MANAG_ADD3 0x3E +#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15) +#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14) +#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13) +#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12) +#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10) +#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9) +#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7) +#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6) +#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5) +#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4) +#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3) +#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2) +#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1) +#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0) + +#define ALC5623_ADD_CTRL_REG 0x40 + +#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42 +#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15) +#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15) +#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14) +#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1) +#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0) +#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0) + +#define ALC5623_PLL_CTRL 0x44 +#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8) +#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4) +#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf) + +#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A +#define ALC5623_GPIO_PIN_CONFIG 0x4C +#define ALC5623_GPIO_PIN_POLARITY 0x4E +#define ALC5623_GPIO_PIN_STICKY 0x50 +#define ALC5623_GPIO_PIN_WAKEUP 0x52 +#define ALC5623_GPIO_PIN_STATUS 0x54 +#define ALC5623_GPIO_PIN_SHARING 0x56 +#define ALC5623_OVER_CURR_STATUS 0x58 +#define ALC5623_JACK_DET_CTRL 0x5A + +#define ALC5623_MISC_CTRL 0x5E +#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15) +#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */ +#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */ +#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10) +#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9) +#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4) +#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3) +#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2) +#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0) + +#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60 +#define ALC5623_EQ_CTRL 0x62 +#define ALC5623_EQ_MODE_ENABLE 0x66 +#define ALC5623_AVC_CTRL 0x68 +#define ALC5623_HID_CTRL_INDEX 0x6A +#define ALC5623_HID_CTRL_DATA 0x6C +#define ALC5623_VENDOR_ID1 0x7C +#define ALC5623_VENDOR_ID2 0x7E + +#define ALC5623_PLL_FR_MCLK 0 +#define ALC5623_PLL_FR_BCK 1 +#endif diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 8236439..46dbfd0 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -36,8 +36,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dai.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <mach/dm365.h> @@ -116,7 +114,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec, DAVINCI_VC_REG12_POWER_ALL_OFF); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index cb086ea..d4e60dc 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -26,7 +26,6 @@ #include <linux/slab.h> #include <sound/core.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/initval.h> #include <sound/pcm_params.h> @@ -519,6 +518,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { static int cs42l51_probe(struct snd_soc_codec *codec) { struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, reg; codec->control_data = cs42l51->control_data; @@ -550,9 +550,9 @@ static int cs42l51_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, cs42l51_snd_controls, ARRAY_SIZE(cs42l51_snd_controls)); - snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, + snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets, ARRAY_SIZE(cs42l51_dapm_widgets)); - snd_soc_dapm_add_routes(codec, cs42l51_routes, + snd_soc_dapm_add_routes(dapm, cs42l51_routes, ARRAY_SIZE(cs42l51_routes)); return 0; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index e8d27c8..a9521ac 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -18,7 +18,7 @@ #include <sound/core.h> #include <sound/initval.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include "cx20442.h" @@ -89,10 +89,11 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = { static int cx20442_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets, - ARRAY_SIZE(cx20442_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, cx20442_audio_map, + snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets, + ARRAY_SIZE(cx20442_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, cx20442_audio_map, ARRAY_SIZE(cx20442_audio_map)); return 0; @@ -263,7 +264,7 @@ static void v253_close(struct tty_struct *tty) /* Prevent the codec driver from further accessing the modem */ codec->hw_write = NULL; cx20442->control_data = NULL; - codec->pop_time = 0; + codec->card->pop_time = 0; } /* Line discipline .hangup() */ @@ -291,7 +292,7 @@ static void v253_receive(struct tty_struct *tty, /* Set up codec driver access to modem controls */ cx20442->control_data = tty; codec->hw_write = (hw_write_t)tty->ops->write; - codec->pop_time = 1; + codec->card->pop_time = 1; } } @@ -348,7 +349,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) cx20442->control_data = NULL; codec->hw_write = NULL; - codec->pop_time = 0; + codec->card->pop_time = 0; return 0; } diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 58bb9b9..92fd9d7 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -21,7 +21,7 @@ #include <linux/slab.h> #include <sound/pcm.h> #include <sound/pcm_params.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/initval.h> #include <sound/tlv.h> diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 16253ec..f7cd346f 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -22,7 +22,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/initval.h> -#include <sound/soc-dapm.h> #include <sound/soc.h> #define JZ4740_REG_CODEC_1 0x0 @@ -266,7 +265,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: /* The only way to clear the suspend flag is to reset the codec */ - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) jz4740_codec_wakeup(codec); mask = JZ4740_CODEC_1_VREF_DISABLE | @@ -288,23 +287,25 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); snd_soc_add_controls(codec, jz4740_codec_controls, ARRAY_SIZE(jz4740_codec_controls)); - snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets, + snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets, ARRAY_SIZE(jz4740_codec_dapm_widgets)); - snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes, + snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes, ARRAY_SIZE(jz4740_codec_dapm_routes)); snd_soc_dapm_new_widgets(codec); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index d63e287..335a002 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -20,7 +20,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <linux/slab.h> @@ -1230,15 +1229,17 @@ static const struct snd_soc_dapm_route audio_map[] = { static int max98088_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, max98088_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets, ARRAY_SIZE(max98088_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_add_controls(codec, max98088_snd_controls, ARRAY_SIZE(max98088_snd_controls)); - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -1623,7 +1624,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) max98088_sync_cache(codec); snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, @@ -1636,7 +1637,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, codec->cache_sync = 1; break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 6f38d61..2727bef 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -38,7 +38,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "ssm2602.h" @@ -207,10 +206,11 @@ static const struct snd_soc_dapm_route audio_conn[] = { static int ssm2602_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets, - ARRAY_SIZE(ssm2602_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); + snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets, + ARRAY_SIZE(ssm2602_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn)); return 0; } @@ -493,7 +493,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 061f9e5..78b2b50 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -236,7 +236,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec, stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index e8652b1..54a30ef 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -30,7 +30,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/initval.h> @@ -391,11 +390,12 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk, static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, - ARRAY_SIZE(tlv320aic23_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, + ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -574,7 +574,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 6b7d71e..68f0ae4 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -18,7 +18,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "tlv320aic26.h" diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index fc68779..bfd036a 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -46,7 +46,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <sound/tlv320aic3x.h> @@ -61,6 +60,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = { "DRVDD", /* ADC Analog and Output Driver Voltage */ }; +static LIST_HEAD(reset_list); + struct aic3x_priv; struct aic3x_disable_nb { @@ -77,6 +78,7 @@ struct aic3x_priv { struct aic3x_setup_data *setup; void *control_data; unsigned int sysclk; + struct list_head list; int master; int gpio_reset; int power; @@ -183,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -199,7 +201,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, } if (found) - snd_soc_dapm_sync(widget->codec); + snd_soc_dapm_sync(widget->dapm); } ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); @@ -788,17 +790,19 @@ static const struct snd_soc_dapm_route intercon_3007[] = { static int aic3x_add_widgets(struct snd_soc_codec *codec) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); if (aic3x->model == AIC3X_MODEL_3007) { - snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, ARRAY_SIZE(aic3007_dapm_widgets)); - snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(intercon_3007)); + snd_soc_dapm_add_routes(dapm, intercon_3007, + ARRAY_SIZE(intercon_3007)); } return 0; @@ -1075,7 +1079,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, * Put codec to reset and require cache sync as at least one * of the supplies was disabled */ - if (aic3x->gpio_reset >= 0) + if (gpio_is_valid(aic3x->gpio_reset)) gpio_set_value(aic3x->gpio_reset, 0); aic3x->codec->cache_sync = 1; } @@ -1102,7 +1106,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) if (!codec->cache_sync) goto out; - if (aic3x->gpio_reset >= 0) { + if (gpio_is_valid(aic3x->gpio_reset)) { udelay(1); gpio_set_value(aic3x->gpio_reset, 1); } @@ -1135,7 +1139,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: - if (codec->bias_level == SND_SOC_BIAS_STANDBY && + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY && aic3x->master) { /* enable pll */ reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); @@ -1146,7 +1150,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (!aic3x->power) aic3x_set_power(codec, 1); - if (codec->bias_level == SND_SOC_BIAS_PREPARE && + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE && aic3x->master) { /* disable pll */ reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); @@ -1159,7 +1163,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, aic3x_set_power(codec, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1344,14 +1348,28 @@ static int aic3x_init(struct snd_soc_codec *codec) return 0; } +static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x) +{ + struct aic3x_priv *a; + + list_for_each_entry(a, &reset_list, list) { + if (gpio_is_valid(aic3x->gpio_reset) && + aic3x->gpio_reset == a->gpio_reset) + return true; + } + + return false; +} + static int aic3x_probe(struct snd_soc_codec *codec) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); int ret, i; + INIT_LIST_HEAD(&aic3x->list); codec->control_data = aic3x->control_data; aic3x->codec = codec; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); if (ret != 0) { @@ -1359,7 +1377,8 @@ static int aic3x_probe(struct snd_soc_codec *codec) return ret; } - if (aic3x->gpio_reset >= 0) { + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) { ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); if (ret != 0) goto err_gpio; @@ -1405,6 +1424,7 @@ static int aic3x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); aic3x_add_widgets(codec); + list_add(&aic3x->list, &reset_list); return 0; @@ -1414,10 +1434,10 @@ err_notif: &aic3x->disable_nb[i].nb); regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); err_get: - if (aic3x->gpio_reset >= 0) + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) gpio_free(aic3x->gpio_reset); err_gpio: - kfree(aic3x); return ret; } @@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec) int i; aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); - if (aic3x->gpio_reset >= 0) { + list_del(&aic3x->list); + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) { gpio_set_value(aic3x->gpio_reset, 0); gpio_free(aic3x->gpio_reset); } diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index c5ab8c8..ccb267f 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -36,7 +36,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -628,11 +627,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int dac33_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, dac33_dapm_widgets, - ARRAY_SIZE(dac33_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets, + ARRAY_SIZE(dac33_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -649,7 +649,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Coming from OFF, switch on the codec */ ret = dac33_hard_power(codec, 1); if (ret != 0) @@ -660,14 +660,14 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: /* Do not power off, when the codec is already off */ - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) return 0; ret = dac33_hard_power(codec, 0); if (ret != 0) return ret; break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1415,7 +1415,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) codec->control_data = dac33->control_data; codec->hw_write = (hw_write_t) i2c_master_send; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; dac33->codec = codec; /* Read the tlv320dac33 ID registers */ diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index d2c2430..9d61a1d 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -29,7 +29,6 @@ #include <linux/slab.h> #include <sound/tpa6130a2-plat.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include "tpa6130a2.h" @@ -128,9 +127,6 @@ static int tpa6130a2_power(int power) mutex_lock(&data->mutex); if (power && !data->power_state) { - /* Power on */ - if (data->power_gpio >= 0) - gpio_set_value(data->power_gpio, 1); ret = regulator_enable(data->supply); if (ret != 0) { @@ -138,6 +134,9 @@ static int tpa6130a2_power(int power) "Failed to enable supply: %d\n", ret); goto exit; } + /* Power on */ + if (data->power_gpio >= 0) + gpio_set_value(data->power_gpio, 1); data->power_state = 1; ret = tpa6130a2_initialize(); @@ -390,16 +389,17 @@ static const struct snd_soc_dapm_route audio_map[] = { int tpa6130a2_add_controls(struct snd_soc_codec *codec) { struct tpa6130a2_data *data; + struct snd_soc_dapm_context *dapm = &codec->dapm; if (tpa6130a2_client == NULL) return -ENODEV; data = i2c_get_clientdata(tpa6130a2_client); - snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tpa6130a2_dapm_widgets, ARRAY_SIZE(tpa6130a2_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (data->id == TPA6140A2) return snd_soc_add_controls(codec, tpa6140a2_controls, diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cbebec6..c173cf0 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -32,7 +32,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -233,6 +232,16 @@ static int twl4030_write(struct snd_soc_codec *codec, return 0; } +static inline void twl4030_wait_ms(int time) +{ + if (time < 60) { + time *= 1000; + usleep_range(time, time + 500); + } else { + msleep(time); + } +} + static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -338,10 +347,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) twl4030_write(codec, TWL4030_REG_ANAMICL, reg | TWL4030_CNCL_OFFSET_START); - /* wait for offset cancellation to complete */ + /* + * Wait for offset cancellation to complete. + * Since this takes a while, do not slam the i2c. + * Start polling the status after ~20ms. + */ + msleep(20); do { - /* this takes a little while, so don't slam i2c */ - udelay(2000); + usleep_range(1000, 2000); twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) && @@ -725,9 +738,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Base values for ramp delay calculation: 2^19 - 2^26 */ unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864}; + unsigned int delay; hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / + twl4030->sysclk) + 1; /* Enable external mute control, this dramatically reduces * the pop-noise */ @@ -751,16 +767,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) hs_pop |= TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); } else { /* Headset ramp-down _not_ according to * the TRM, but in a way that it is working */ hs_pop &= ~TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); /* Bypass the reg_cache to mute the headset */ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), @@ -835,7 +849,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w, struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); if (twl4030->digimic_delay) - mdelay(twl4030->digimic_delay); + twl4030_wait_ms(twl4030->digimic_delay); return 0; } @@ -1621,10 +1635,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl4030_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets, - ARRAY_SIZE(twl4030_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets, + ARRAY_SIZE(twl4030_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -1638,14 +1653,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) twl4030_codec_enable(codec, 1); break; case SND_SOC_BIAS_OFF: twl4030_codec_enable(codec, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -2245,7 +2260,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, twl4030); /* Set the defaults, and power up the codec */ twl4030->sysclk = twl4030_codec_get_mclk() / 1000; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; twl4030_init_chip(codec); @@ -2257,9 +2272,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) static int twl4030_soc_remove(struct snd_soc_codec *codec) { + struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); + /* Reset registers to their chip default before leaving */ twl4030_reset_registers(codec); twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); + kfree(twl4030); return 0; } @@ -2291,10 +2309,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) static int __devexit twl4030_codec_remove(struct platform_device *pdev) { - struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_codec(&pdev->dev); - kfree(twl4030); return 0; } diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 10f6e52..b92f2b7 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -34,7 +34,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -641,12 +640,12 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl6040_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets, - ARRAY_SIZE(twl6040_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets, + ARRAY_SIZE(twl6040_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -739,7 +738,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 464f0cf..e76847a 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -19,7 +19,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/uda134x.h> @@ -389,7 +388,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, pd->power(0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 0c6c725..800980e 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -27,7 +27,6 @@ #include <sound/control.h> #include <sound/initval.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/uda1380.h> @@ -414,10 +413,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int uda1380_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, - ARRAY_SIZE(uda1380_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, + ARRAY_SIZE(uda1380_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -603,7 +603,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, int reg; struct uda1380_platform_data *pdata = codec->dev->platform_data; - if (codec->bias_level == level) + if (codec->dapm.bias_level == level) return 0; switch (level) { @@ -613,7 +613,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (gpio_is_valid(pdata->gpio_power)) { gpio_set_value(pdata->gpio_power, 1); mdelay(1); @@ -636,7 +636,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++) set_bit(reg - 0x10, &uda1380_cache_dirty); } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 0c47c78..d3ffa2f 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -25,8 +25,7 @@ #include <linux/slab.h> #include <sound/pcm.h> #include <sound/pcm_params.h> -#include <sound/soc-dai.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/initval.h> #include "wl1273.h" diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 4bcd168..80ddf4f 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -36,7 +36,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -705,6 +704,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Called from the machine driver */ int wm2000_add_controls(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; if (!wm2000_i2c) { @@ -712,12 +712,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec) return -ENODEV; } - ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets, ARRAY_SIZE(wm2000_dapm_widgets)); if (ret < 0) return ret; - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret < 0) return ret; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 7611add..dc6912e 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -230,8 +229,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) */ static void wm8350_pga_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out1 = &wm8350_data->out1, *out2 = &wm8350_data->out2; @@ -302,8 +302,8 @@ static int pga_event(struct snd_soc_dapm_widget *w, out->ramp = WM8350_RAMP_UP; out->active = 1; - if (!delayed_work_pending(&codec->delayed_work)) - schedule_delayed_work(&codec->delayed_work, + if (!delayed_work_pending(&codec->dapm.delayed_work)) + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(1)); break; @@ -311,8 +311,8 @@ static int pga_event(struct snd_soc_dapm_widget *w, out->ramp = WM8350_RAMP_DOWN; out->active = 0; - if (!delayed_work_pending(&codec->delayed_work)) - schedule_delayed_work(&codec->delayed_work, + if (!delayed_work_pending(&codec->dapm.delayed_work)) + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(1)); break; } @@ -786,9 +786,10 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8350_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - ret = snd_soc_dapm_new_controls(codec, + ret = snd_soc_dapm_new_controls(dapm, wm8350_dapm_widgets, ARRAY_SIZE(wm8350_dapm_widgets)); if (ret != 0) { @@ -797,7 +798,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec) } /* set up audio paths */ - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret != 0) { dev_err(codec->dev, "DAPM route register failed\n"); return ret; @@ -1184,7 +1185,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); if (ret != 0) @@ -1317,7 +1318,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, priv->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1550,7 +1551,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) /* Put the codec into reset if it wasn't already */ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); - INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); /* Enable the codec */ wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1642,12 +1643,12 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) priv->mic.jack = NULL; /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(&codec->delayed_work); + ret = cancel_delayed_work(&codec->dapm.delayed_work); /* if there was any work waiting then we run it now and * wait for its completion */ if (ret) { - schedule_delayed_work(&codec->delayed_work, 0); + schedule_delayed_work(&codec->dapm.delayed_work, 0); flush_scheduled_work(); } diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 8502997..3c3bc07 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -26,7 +26,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -911,10 +910,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8400_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets, - ARRAY_SIZE(wm8400_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets, + ARRAY_SIZE(wm8400_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1219,7 +1219,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(power), &power[0]); if (ret != 0) { @@ -1306,7 +1306,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 8f10709..db0dced 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "wm8510.h" @@ -216,10 +215,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8510_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets, - ARRAY_SIZE(wm8510_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets, + ARRAY_SIZE(wm8510_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -478,7 +478,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); mdelay(100); @@ -495,7 +495,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 9a433a5..08f3189f 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -110,10 +109,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8523_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets, - ARRAY_SIZE(wm8523_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets, + ARRAY_SIZE(wm8523_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -327,7 +327,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); if (ret != 0) { @@ -366,7 +366,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, wm8523->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index a2e0ed5..e2a9276 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -31,7 +31,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/initval.h> #include <asm/div64.h> @@ -302,10 +301,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8580_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets, - ARRAY_SIZE(wm8580_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets, + ARRAY_SIZE(wm8580_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -767,7 +767,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Power up and get individual control of the DACs */ reg = snd_soc_read(codec, WM8580_PWRDN1); reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); @@ -785,7 +785,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -905,7 +905,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { .set_bias_level = wm8580_set_bias_level, .reg_cache_size = ARRAY_SIZE(wm8580_reg), .reg_word_size = sizeof(u16), - .reg_cache_default = &wm8580_reg, + .reg_cache_default = wm8580_reg, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 54fbd76..fec37eb 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -25,7 +25,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/initval.h> @@ -93,10 +92,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8711_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets, - ARRAY_SIZE(wm8711_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets, + ARRAY_SIZE(wm8711_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -318,7 +318,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8711_PWR, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 075f35e..736b035 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -73,10 +72,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8728_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets, - ARRAY_SIZE(wm8728_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets, + ARRAY_SIZE(wm8728_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -180,7 +180,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Power everything up... */ reg = snd_soc_read(codec, WM8728_DACCTL); snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); @@ -197,7 +197,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8728_DACCTL, reg | 0x4); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 6313858..a104145 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -26,7 +26,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -165,10 +164,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8731_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, - ARRAY_SIZE(wm8731_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, + ARRAY_SIZE(wm8731_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -319,7 +319,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, return -EINVAL; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); return 0; } @@ -399,7 +399,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); if (ret != 0) @@ -428,7 +428,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, wm8731->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -542,7 +542,6 @@ err_regulator_enable: err_regulator_get: regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); - kfree(wm8731); return ret; } diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c new file mode 100644 index 0000000..a325fe6 --- /dev/null +++ b/sound/soc/codecs/wm8737.c @@ -0,0 +1,713 @@ +/* + * wm8737.c -- WM8737 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/spi/spi.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> +#include <sound/tlv.h> + +#include "wm8737.h" + +#define WM8737_NUM_SUPPLIES 4 +static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = { + "DCVDD", + "DBVDD", + "AVDD", + "MVDD", +}; + +/* codec private data */ +struct wm8737_priv { + enum snd_soc_control_type control_type; + struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES]; + unsigned int mclk; +}; + +static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = { + 0x00C3, /* R0 - Left PGA volume */ + 0x00C3, /* R1 - Right PGA volume */ + 0x0007, /* R2 - AUDIO path L */ + 0x0007, /* R3 - AUDIO path R */ + 0x0000, /* R4 - 3D Enhance */ + 0x0000, /* R5 - ADC Control */ + 0x0000, /* R6 - Power Management */ + 0x000A, /* R7 - Audio Format */ + 0x0000, /* R8 - Clocking */ + 0x000F, /* R9 - MIC Preamp Control */ + 0x0003, /* R10 - Misc Bias Control */ + 0x0000, /* R11 - Noise Gate */ + 0x007C, /* R12 - ALC1 */ + 0x0000, /* R13 - ALC2 */ + 0x0032, /* R14 - ALC3 */ +}; + +static int wm8737_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8737_RESET, 0); +} + +static const unsigned int micboost_tlv[] = { + TLV_DB_RANGE_HEAD(4), + 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0), + 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0), +}; +static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1); +static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0); +static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0); + +static const char *micbias_enum_text[] = { + "25%", + "50%", + "75%", + "100%", +}; + +static const struct soc_enum micbias_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text); + +static const char *low_cutoff_text[] = { + "Low", "High" +}; + +static const struct soc_enum low_3d = + SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text); + +static const char *high_cutoff_text[] = { + "High", "Low" +}; + +static const struct soc_enum high_3d = + SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text); + +static const struct snd_kcontrol_new wm8737_snd_controls[] = { +SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 6, 3, 0, micboost_tlv), +SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 4, 1, 0), +SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 3, 1, 0), + +SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME, + WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv), +SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 2, 1, 0), + +SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0), + +SOC_ENUM("Mic PGA Bias", micbias_enum), +SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0), +SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1), +SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0), + +SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0), +SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0), +SOC_ENUM("3D Low Cut-off", low_3d), +SOC_ENUM("3D High Cut-off", low_3d), +SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv), + +SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0), +SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0, + ng_tlv), +}; + +static const char *linsel_text[] = { + "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC", +}; + +static const struct soc_enum linsel_enum = + SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text); + +static const struct snd_kcontrol_new linsel_mux = + SOC_DAPM_ENUM("LINSEL", linsel_enum); + + +static const char *rinsel_text[] = { + "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC", +}; + +static const struct soc_enum rinsel_enum = + SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text); + +static const struct snd_kcontrol_new rinsel_mux = + SOC_DAPM_ENUM("RINSEL", rinsel_enum); + +static const char *bypass_text[] = { + "Direct", "Preamp" +}; + +static const struct soc_enum lbypass_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text); + +static const struct snd_kcontrol_new lbypass_mux = + SOC_DAPM_ENUM("Left Bypass", lbypass_enum); + + +static const struct soc_enum rbypass_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text); + +static const struct snd_kcontrol_new rbypass_mux = + SOC_DAPM_ENUM("Left Bypass", rbypass_enum); + +static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("LINPUT1"), +SND_SOC_DAPM_INPUT("LINPUT2"), +SND_SOC_DAPM_INPUT("LINPUT3"), +SND_SOC_DAPM_INPUT("RINPUT1"), +SND_SOC_DAPM_INPUT("RINPUT2"), +SND_SOC_DAPM_INPUT("RINPUT3"), +SND_SOC_DAPM_INPUT("LACIN"), +SND_SOC_DAPM_INPUT("RACIN"), + +SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux), +SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux), + +SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux), +SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux), + +SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0), + +SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0), +SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0), + +SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0), +}; + +static const struct snd_soc_dapm_route intercon[] = { + { "LINSEL", "LINPUT1", "LINPUT1" }, + { "LINSEL", "LINPUT2", "LINPUT2" }, + { "LINSEL", "LINPUT3", "LINPUT3" }, + { "LINSEL", "LINPUT1 DC", "LINPUT1" }, + + { "RINSEL", "RINPUT1", "RINPUT1" }, + { "RINSEL", "RINPUT2", "RINPUT2" }, + { "RINSEL", "RINPUT3", "RINPUT3" }, + { "RINSEL", "RINPUT1 DC", "RINPUT1" }, + + { "Left Preamp Mux", "Preamp", "LINSEL" }, + { "Left Preamp Mux", "Direct", "LACIN" }, + + { "Right Preamp Mux", "Preamp", "RINSEL" }, + { "Right Preamp Mux", "Direct", "RACIN" }, + + { "PGAL", NULL, "Left Preamp Mux" }, + { "PGAR", NULL, "Right Preamp Mux" }, + + { "ADCL", NULL, "PGAL" }, + { "ADCR", NULL, "PGAR" }, + + { "AIF", NULL, "ADCL" }, + { "AIF", NULL, "ADCR" }, +}; + +static int wm8737_add_widgets(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets, + ARRAY_SIZE(wm8737_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + + return 0; +} + +/* codec mclk clock divider coefficients */ +static const struct { + u32 mclk; + u32 rate; + u8 usb; + u8 sr; +} coeff_div[] = { + { 12288000, 8000, 0, 0x4 }, + { 12288000, 12000, 0, 0x8 }, + { 12288000, 16000, 0, 0xa }, + { 12288000, 24000, 0, 0x1c }, + { 12288000, 32000, 0, 0xc }, + { 12288000, 48000, 0, 0 }, + { 12288000, 96000, 0, 0xe }, + + { 11289600, 8000, 0, 0x14 }, + { 11289600, 11025, 0, 0x18 }, + { 11289600, 22050, 0, 0x1a }, + { 11289600, 44100, 0, 0x10 }, + { 11289600, 88200, 0, 0x1e }, + + { 18432000, 8000, 0, 0x5 }, + { 18432000, 12000, 0, 0x9 }, + { 18432000, 16000, 0, 0xb }, + { 18432000, 24000, 0, 0x1b }, + { 18432000, 32000, 0, 0xd }, + { 18432000, 48000, 0, 0x1 }, + { 18432000, 96000, 0, 0x1f }, + + { 16934400, 8000, 0, 0x15 }, + { 16934400, 11025, 0, 0x19 }, + { 16934400, 22050, 0, 0x1b }, + { 16934400, 44100, 0, 0x11 }, + { 16934400, 88200, 0, 0x1f }, + + { 12000000, 8000, 1, 0x4 }, + { 12000000, 11025, 1, 0x19 }, + { 12000000, 12000, 1, 0x8 }, + { 12000000, 16000, 1, 0xa }, + { 12000000, 22050, 1, 0x1b }, + { 12000000, 24000, 1, 0x1c }, + { 12000000, 32000, 1, 0xc }, + { 12000000, 44100, 1, 0x11 }, + { 12000000, 48000, 1, 0x0 }, + { 12000000, 88200, 1, 0x1f }, + { 12000000, 96000, 1, 0xe }, +}; + +static int wm8737_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int i; + u16 clocking = 0; + u16 af = 0; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].rate != params_rate(params)) + continue; + + if (coeff_div[i].mclk == wm8737->mclk) + break; + + if (coeff_div[i].mclk == wm8737->mclk * 2) { + clocking |= WM8737_CLKDIV2; + break; + } + } + + if (i == ARRAY_SIZE(coeff_div)) { + dev_err(codec->dev, "%dHz MCLK can't support %dHz\n", + wm8737->mclk, params_rate(params)); + return -EINVAL; + } + + clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + af |= 0x8; + break; + case SNDRV_PCM_FORMAT_S24_LE: + af |= 0x10; + break; + case SNDRV_PCM_FORMAT_S32_LE: + af |= 0x18; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af); + snd_soc_update_bits(codec, WM8737_CLOCKING, + WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK, + clocking); + + return 0; +} + +static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (freq == coeff_div[i].mclk || + freq == coeff_div[i].mclk * 2) { + wm8737->mclk = freq; + return 0; + } + } + + dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq); + + return -EINVAL; +} + + +static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 af = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + af |= WM8737_MS; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + af |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + af |= 0x1; + break; + case SND_SOC_DAIFMT_DSP_A: + af |= 0x3; + break; + case SND_SOC_DAIFMT_DSP_B: + af |= 0x13; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + af |= WM8737_LRP; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, + WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af); + + return 0; +} + +static int wm8737_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VMID at 2*75k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 0); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + snd_soc_cache_sync(codec); + + /* Fast VMID ramp at 2*2.5k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 0x4); + + /* Bring VMID up */ + snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, + WM8737_VMID_MASK | + WM8737_VREF_MASK, + WM8737_VMID_MASK | + WM8737_VREF_MASK); + + msleep(500); + } + + /* VMID at 2*300k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 2); + + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, + WM8737_VMID_MASK | WM8737_VREF_MASK, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +#define WM8737_RATES SNDRV_PCM_RATE_8000_96000 + +#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8737_dai_ops = { + .hw_params = wm8737_hw_params, + .set_sysclk = wm8737_set_dai_sysclk, + .set_fmt = wm8737_set_dai_fmt, +}; + +static struct snd_soc_dai_driver wm8737_dai = { + .name = "wm8737", + .capture = { + .stream_name = "Capture", + .channels_min = 2, /* Mono modes not yet supported */ + .channels_max = 2, + .rates = WM8737_RATES, + .formats = WM8737_FORMATS, + }, + .ops = &wm8737_dai_ops, +}; + +#ifdef CONFIG_PM +static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8737_resume(struct snd_soc_codec *codec) +{ + wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define wm8737_suspend NULL +#define wm8737_resume NULL +#endif + +static int wm8737_probe(struct snd_soc_codec *codec) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int ret, i; + + codec->hw_write = (hw_write_t)i2c_master_send; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++) + wm8737->supplies[i].supply = wm8737_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = wm8737_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + goto err_enable; + } + + snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU, + WM8737_LVU); + snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU, + WM8737_RVU); + + wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + + snd_soc_add_controls(codec, wm8737_snd_controls, + ARRAY_SIZE(wm8737_snd_controls)); + wm8737_add_widgets(codec); + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + + return ret; +} + +static int wm8737_remove(struct snd_soc_codec *codec) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + + wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); + regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { + .probe = wm8737_probe, + .remove = wm8737_remove, + .suspend = wm8737_suspend, + .resume = wm8737_resume, + .set_bias_level = wm8737_set_bias_level, + + .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */ + .reg_word_size = sizeof(u16), + .reg_cache_default = wm8737_reg, +}; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8737_priv *wm8737; + int ret; + + wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); + if (wm8737 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, wm8737); + wm8737->control_type = SND_SOC_I2C; + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_wm8737, &wm8737_dai, 1); + if (ret < 0) + kfree(wm8737); + return ret; + +} + +static __devexit int wm8737_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id wm8737_i2c_id[] = { + { "wm8737", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id); + +static struct i2c_driver wm8737_i2c_driver = { + .driver = { + .name = "wm8737", + .owner = THIS_MODULE, + }, + .probe = wm8737_i2c_probe, + .remove = __devexit_p(wm8737_i2c_remove), + .id_table = wm8737_i2c_id, +}; +#endif + +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8737_spi_probe(struct spi_device *spi) +{ + struct wm8737_priv *wm8737; + int ret; + + wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); + if (wm8737 == NULL) + return -ENOMEM; + + wm8737->control_type = SND_SOC_SPI; + spi_set_drvdata(spi, wm8737); + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_wm8737, &wm8737_dai, 1); + if (ret < 0) + kfree(wm8737); + return ret; +} + +static int __devexit wm8737_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver wm8737_spi_driver = { + .driver = { + .name = "wm8737", + .owner = THIS_MODULE, + }, + .probe = wm8737_spi_probe, + .remove = __devexit_p(wm8737_spi_remove), +}; +#endif /* CONFIG_SPI_MASTER */ + +static int __init wm8737_modinit(void) +{ + int ret; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8737_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n", + ret); + } +#endif +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8737_spi_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n", + ret); + } +#endif + return 0; +} +module_init(wm8737_modinit); + +static void __exit wm8737_exit(void) +{ +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8737_spi_driver); +#endif +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8737_i2c_driver); +#endif +} +module_exit(wm8737_exit); + +MODULE_DESCRIPTION("ASoC WM8737 driver"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h new file mode 100644 index 0000000..23d14c8 --- /dev/null +++ b/sound/soc/codecs/wm8737.h @@ -0,0 +1,322 @@ +#ifndef _WM8737_H +#define _WM8737_H + +/* + * wm8737.c -- WM8523 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Register values. + */ +#define WM8737_LEFT_PGA_VOLUME 0x00 +#define WM8737_RIGHT_PGA_VOLUME 0x01 +#define WM8737_AUDIO_PATH_L 0x02 +#define WM8737_AUDIO_PATH_R 0x03 +#define WM8737_3D_ENHANCE 0x04 +#define WM8737_ADC_CONTROL 0x05 +#define WM8737_POWER_MANAGEMENT 0x06 +#define WM8737_AUDIO_FORMAT 0x07 +#define WM8737_CLOCKING 0x08 +#define WM8737_MIC_PREAMP_CONTROL 0x09 +#define WM8737_MISC_BIAS_CONTROL 0x0A +#define WM8737_NOISE_GATE 0x0B +#define WM8737_ALC1 0x0C +#define WM8737_ALC2 0x0D +#define WM8737_ALC3 0x0E +#define WM8737_RESET 0x0F + +#define WM8737_REGISTER_COUNT 16 +#define WM8737_MAX_REGISTER 0x0F + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Left PGA volume + */ +#define WM8737_LVU 0x0100 /* LVU */ +#define WM8737_LVU_MASK 0x0100 /* LVU */ +#define WM8737_LVU_SHIFT 8 /* LVU */ +#define WM8737_LVU_WIDTH 1 /* LVU */ +#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */ +#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */ +#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */ + +/* + * R1 (0x01) - Right PGA volume + */ +#define WM8737_RVU 0x0100 /* RVU */ +#define WM8737_RVU_MASK 0x0100 /* RVU */ +#define WM8737_RVU_SHIFT 8 /* RVU */ +#define WM8737_RVU_WIDTH 1 /* RVU */ +#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */ +#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */ +#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */ + +/* + * R2 (0x02) - AUDIO path L + */ +#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */ +#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */ +#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */ +#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */ +#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */ +#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */ +#define WM8737_LMBE 0x0010 /* LMBE */ +#define WM8737_LMBE_MASK 0x0010 /* LMBE */ +#define WM8737_LMBE_SHIFT 4 /* LMBE */ +#define WM8737_LMBE_WIDTH 1 /* LMBE */ +#define WM8737_LMZC 0x0008 /* LMZC */ +#define WM8737_LMZC_MASK 0x0008 /* LMZC */ +#define WM8737_LMZC_SHIFT 3 /* LMZC */ +#define WM8737_LMZC_WIDTH 1 /* LMZC */ +#define WM8737_LPZC 0x0004 /* LPZC */ +#define WM8737_LPZC_MASK 0x0004 /* LPZC */ +#define WM8737_LPZC_SHIFT 2 /* LPZC */ +#define WM8737_LPZC_WIDTH 1 /* LPZC */ +#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */ +#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */ +#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */ + +/* + * R3 (0x03) - AUDIO path R + */ +#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */ +#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */ +#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */ +#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */ +#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */ +#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */ +#define WM8737_RMBE 0x0010 /* RMBE */ +#define WM8737_RMBE_MASK 0x0010 /* RMBE */ +#define WM8737_RMBE_SHIFT 4 /* RMBE */ +#define WM8737_RMBE_WIDTH 1 /* RMBE */ +#define WM8737_RMZC 0x0008 /* RMZC */ +#define WM8737_RMZC_MASK 0x0008 /* RMZC */ +#define WM8737_RMZC_SHIFT 3 /* RMZC */ +#define WM8737_RMZC_WIDTH 1 /* RMZC */ +#define WM8737_RPZC 0x0004 /* RPZC */ +#define WM8737_RPZC_MASK 0x0004 /* RPZC */ +#define WM8737_RPZC_SHIFT 2 /* RPZC */ +#define WM8737_RPZC_WIDTH 1 /* RPZC */ +#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */ +#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */ +#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */ + +/* + * R4 (0x04) - 3D Enhance + */ +#define WM8737_DIV2 0x0080 /* DIV2 */ +#define WM8737_DIV2_MASK 0x0080 /* DIV2 */ +#define WM8737_DIV2_SHIFT 7 /* DIV2 */ +#define WM8737_DIV2_WIDTH 1 /* DIV2 */ +#define WM8737_3DLC 0x0040 /* 3DLC */ +#define WM8737_3DLC_MASK 0x0040 /* 3DLC */ +#define WM8737_3DLC_SHIFT 6 /* 3DLC */ +#define WM8737_3DLC_WIDTH 1 /* 3DLC */ +#define WM8737_3DUC 0x0020 /* 3DUC */ +#define WM8737_3DUC_MASK 0x0020 /* 3DUC */ +#define WM8737_3DUC_SHIFT 5 /* 3DUC */ +#define WM8737_3DUC_WIDTH 1 /* 3DUC */ +#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */ +#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */ +#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */ +#define WM8737_3DE 0x0001 /* 3DE */ +#define WM8737_3DE_MASK 0x0001 /* 3DE */ +#define WM8737_3DE_SHIFT 0 /* 3DE */ +#define WM8737_3DE_WIDTH 1 /* 3DE */ + +/* + * R5 (0x05) - ADC Control + */ +#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */ +#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */ +#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */ +#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */ +#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */ +#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */ +#define WM8737_HPOR 0x0010 /* HPOR */ +#define WM8737_HPOR_MASK 0x0010 /* HPOR */ +#define WM8737_HPOR_SHIFT 4 /* HPOR */ +#define WM8737_HPOR_WIDTH 1 /* HPOR */ +#define WM8737_LP 0x0004 /* LP */ +#define WM8737_LP_MASK 0x0004 /* LP */ +#define WM8737_LP_SHIFT 2 /* LP */ +#define WM8737_LP_WIDTH 1 /* LP */ +#define WM8737_MONOUT 0x0002 /* MONOUT */ +#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */ +#define WM8737_MONOUT_SHIFT 1 /* MONOUT */ +#define WM8737_MONOUT_WIDTH 1 /* MONOUT */ +#define WM8737_ADCHPD 0x0001 /* ADCHPD */ +#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */ +#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */ +#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */ + +/* + * R6 (0x06) - Power Management + */ +#define WM8737_VMID 0x0100 /* VMID */ +#define WM8737_VMID_MASK 0x0100 /* VMID */ +#define WM8737_VMID_SHIFT 8 /* VMID */ +#define WM8737_VMID_WIDTH 1 /* VMID */ +#define WM8737_VREF 0x0080 /* VREF */ +#define WM8737_VREF_MASK 0x0080 /* VREF */ +#define WM8737_VREF_SHIFT 7 /* VREF */ +#define WM8737_VREF_WIDTH 1 /* VREF */ +#define WM8737_AI 0x0040 /* AI */ +#define WM8737_AI_MASK 0x0040 /* AI */ +#define WM8737_AI_SHIFT 6 /* AI */ +#define WM8737_AI_WIDTH 1 /* AI */ +#define WM8737_PGL 0x0020 /* PGL */ +#define WM8737_PGL_MASK 0x0020 /* PGL */ +#define WM8737_PGL_SHIFT 5 /* PGL */ +#define WM8737_PGL_WIDTH 1 /* PGL */ +#define WM8737_PGR 0x0010 /* PGR */ +#define WM8737_PGR_MASK 0x0010 /* PGR */ +#define WM8737_PGR_SHIFT 4 /* PGR */ +#define WM8737_PGR_WIDTH 1 /* PGR */ +#define WM8737_ADL 0x0008 /* ADL */ +#define WM8737_ADL_MASK 0x0008 /* ADL */ +#define WM8737_ADL_SHIFT 3 /* ADL */ +#define WM8737_ADL_WIDTH 1 /* ADL */ +#define WM8737_ADR 0x0004 /* ADR */ +#define WM8737_ADR_MASK 0x0004 /* ADR */ +#define WM8737_ADR_SHIFT 2 /* ADR */ +#define WM8737_ADR_WIDTH 1 /* ADR */ +#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */ +#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */ +#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */ + +/* + * R7 (0x07) - Audio Format + */ +#define WM8737_SDODIS 0x0080 /* SDODIS */ +#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */ +#define WM8737_SDODIS_SHIFT 7 /* SDODIS */ +#define WM8737_SDODIS_WIDTH 1 /* SDODIS */ +#define WM8737_MS 0x0040 /* MS */ +#define WM8737_MS_MASK 0x0040 /* MS */ +#define WM8737_MS_SHIFT 6 /* MS */ +#define WM8737_MS_WIDTH 1 /* MS */ +#define WM8737_LRP 0x0010 /* LRP */ +#define WM8737_LRP_MASK 0x0010 /* LRP */ +#define WM8737_LRP_SHIFT 4 /* LRP */ +#define WM8737_LRP_WIDTH 1 /* LRP */ +#define WM8737_WL_MASK 0x000C /* WL - [3:2] */ +#define WM8737_WL_SHIFT 2 /* WL - [3:2] */ +#define WM8737_WL_WIDTH 2 /* WL - [3:2] */ +#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */ +#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */ +#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */ + +/* + * R8 (0x08) - Clocking + */ +#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */ +#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */ +#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */ +#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */ +#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */ +#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */ +#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */ +#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */ +#define WM8737_SR_MASK 0x003E /* SR - [5:1] */ +#define WM8737_SR_SHIFT 1 /* SR - [5:1] */ +#define WM8737_SR_WIDTH 5 /* SR - [5:1] */ +#define WM8737_USB_MODE 0x0001 /* USB MODE */ +#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */ +#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */ +#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */ + +/* + * R9 (0x09) - MIC Preamp Control + */ +#define WM8737_RBYPEN 0x0008 /* RBYPEN */ +#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */ +#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */ +#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */ +#define WM8737_LBYPEN 0x0004 /* LBYPEN */ +#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */ +#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */ +#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */ +#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */ +#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */ +#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */ + +/* + * R10 (0x0A) - Misc Bias Control + */ +#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */ +#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */ +#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */ + +/* + * R11 (0x0B) - Noise Gate + */ +#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */ +#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */ +#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */ +#define WM8737_NGAT 0x0001 /* NGAT */ +#define WM8737_NGAT_MASK 0x0001 /* NGAT */ +#define WM8737_NGAT_SHIFT 0 /* NGAT */ +#define WM8737_NGAT_WIDTH 1 /* NGAT */ + +/* + * R12 (0x0C) - ALC1 + */ +#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */ +#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */ +#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */ +#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */ +#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */ +#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */ +#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */ +#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */ +#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */ + +/* + * R13 (0x0D) - ALC2 + */ +#define WM8737_ALCZCE 0x0010 /* ALCZCE */ +#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */ +#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */ +#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */ +#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */ +#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */ +#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */ + +/* + * R14 (0x0E) - ALC3 + */ +#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */ +#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */ +#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */ +#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */ +#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */ +#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */ + +/* + * R15 (0x0F) - Reset + */ +#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */ +#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */ +#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */ + +#endif diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 90e31e9..35789b7 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -95,10 +94,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8741_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets, - ARRAY_SIZE(wm8741_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets, + ARRAY_SIZE(wm8741_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -455,7 +455,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { .resume = wm8741_resume, .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), .reg_word_size = sizeof(u16), - .reg_cache_default = &wm8741_reg_defaults, + .reg_cache_default = wm8741_reg_defaults, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 6c924cd..51280e9 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -25,7 +25,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "wm8750.h" @@ -399,10 +398,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8750_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, + ARRAY_SIZE(wm8750_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -615,7 +615,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Set VMID to 5k */ snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); @@ -630,7 +630,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8750_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a1..57bf946 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -45,7 +45,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <asm/div64.h> @@ -670,10 +669,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8753_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, - ARRAY_SIZE(wm8753_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1292,7 +1292,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, wm8753_write(codec, WM8753_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1482,9 +1482,11 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, static void wm8753_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - wm8753_set_bias_level(codec, codec->bias_level); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, + delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; + wm8753_set_bias_level(codec, dapm->bias_level); } static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) @@ -1516,10 +1518,10 @@ static int wm8753_resume(struct snd_soc_codec *codec) wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8753 caps */ - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->bias_level = SND_SOC_BIAS_ON; - schedule_delayed_work(&codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_ON; + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(caps_charge)); } @@ -1550,7 +1552,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); int ret = 0, reg; - INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); if (ret < 0) { @@ -1569,7 +1571,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* charge output caps */ wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - schedule_delayed_work(&codec->delayed_work, + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(caps_charge)); /* set the update bits */ @@ -1604,7 +1606,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8753_remove(struct snd_soc_codec *codec) { - run_delayed_work(&codec->delayed_work); + run_delayed_work(&codec->dapm.delayed_work); wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c new file mode 100644 index 0000000..19b92ba --- /dev/null +++ b/sound/soc/codecs/wm8770.c @@ -0,0 +1,749 @@ +/* + * wm8770.c -- WM8770 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/platform_device.h> +#include <linux/spi/spi.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/initval.h> +#include <sound/tlv.h> + +#include "wm8770.h" + +#define WM8770_NUM_SUPPLIES 3 +static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = { + "AVDD1", + "AVDD2", + "DVDD" +}; + +static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = { + 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0, 0x90, 0, + 0, 0x22, 0x22, 0x3e, + 0xc, 0xc, 0x100, 0x189, + 0x189, 0x8770 +}; + +struct wm8770_priv { + enum snd_soc_control_type control_type; + struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES]; + struct notifier_block disable_nb[WM8770_NUM_SUPPLIES]; + struct snd_soc_codec *codec; + int sysclk; +}; + +static int vout12supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int vout34supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +/* + * We can't use the same notifier block for more than one supply and + * there's no way I can see to get from a callback to the caller + * except container_of(). + */ +#define WM8770_REGULATOR_EVENT(n) \ +static int wm8770_regulator_event_##n(struct notifier_block *nb, \ + unsigned long event, void *data) \ +{ \ + struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \ + disable_nb[n]); \ + if (event & REGULATOR_EVENT_DISABLE) { \ + wm8770->codec->cache_sync = 1; \ + } \ + return 0; \ +} + +WM8770_REGULATOR_EVENT(0) +WM8770_REGULATOR_EVENT(1) +WM8770_REGULATOR_EVENT(2) + +static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0); +static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1); + +static const char *dac_phase_text[][2] = { + { "DAC1 Normal", "DAC1 Inverted" }, + { "DAC2 Normal", "DAC2 Inverted" }, + { "DAC3 Normal", "DAC3 Inverted" }, + { "DAC4 Normal", "DAC4 Inverted" }, +}; + +static const struct soc_enum dac_phase[] = { + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]), +}; + +static const struct snd_kcontrol_new wm8770_snd_controls[] = { + /* global DAC playback controls */ + SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0, + dac_dig_tlv), + SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1), + SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0), + + /* global VOUT playback controls */ + SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0, + dac_alg_tlv), + SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0), + + /* VOUT1/2/3/4 specific controls */ + SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL, + WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL, + WM8770_VOUT1RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL, + WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL, + WM8770_VOUT2RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL, + WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL, + WM8770_VOUT3RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL, + WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL, + WM8770_VOUT4RVOL, 7, 1, 0), + + /* DAC1/2/3/4 specific controls */ + SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL, + WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0), + SOC_ENUM("DAC1 Phase", dac_phase[0]), + SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL, + WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0), + SOC_ENUM("DAC2 Phase", dac_phase[1]), + SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL, + WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0), + SOC_ENUM("DAC3 Phase", dac_phase[2]), + SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL, + WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0), + SOC_ENUM("DAC4 Phase", dac_phase[3]), + + /* ADC specific controls */ + SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL, + 0, 31, 0, adc_tlv), + SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL, + 5, 1, 1), + + /* other controls */ + SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0), + SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1) +}; + +static const char *ain_text[] = { + "AIN1", "AIN2", "AIN3", "AIN4", + "AIN5", "AIN6", "AIN7", "AIN8" +}; + +static const struct soc_enum ain_enum = + SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); + +static const struct snd_kcontrol_new ain_mux = + SOC_DAPM_ENUM("Capture Mux", ain_enum); + +static const struct snd_kcontrol_new vout1_mix_controls[] = { + SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0), + SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0) +}; + +static const struct snd_kcontrol_new vout2_mix_controls[] = { + SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0), + SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0) +}; + +static const struct snd_kcontrol_new vout3_mix_controls[] = { + SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0), + SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0) +}; + +static const struct snd_kcontrol_new vout4_mix_controls[] = { + SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0) +}; + +static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("AUX1"), + SND_SOC_DAPM_INPUT("AUX2"), + SND_SOC_DAPM_INPUT("AUX3"), + + SND_SOC_DAPM_INPUT("AIN1"), + SND_SOC_DAPM_INPUT("AIN2"), + SND_SOC_DAPM_INPUT("AIN3"), + SND_SOC_DAPM_INPUT("AIN4"), + SND_SOC_DAPM_INPUT("AIN5"), + SND_SOC_DAPM_INPUT("AIN6"), + SND_SOC_DAPM_INPUT("AIN7"), + SND_SOC_DAPM_INPUT("AIN8"), + + SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux), + + SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1), + + SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1), + SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1), + SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1), + SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1), + + SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0, + vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0, + vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0, + vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0, + vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0, + vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0, + vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)), + + SND_SOC_DAPM_OUTPUT("VOUT1"), + SND_SOC_DAPM_OUTPUT("VOUT2"), + SND_SOC_DAPM_OUTPUT("VOUT3"), + SND_SOC_DAPM_OUTPUT("VOUT4") +}; + +static const struct snd_soc_dapm_route wm8770_intercon[] = { + { "Capture Mux", "AIN1", "AIN1" }, + { "Capture Mux", "AIN2", "AIN2" }, + { "Capture Mux", "AIN3", "AIN3" }, + { "Capture Mux", "AIN4", "AIN4" }, + { "Capture Mux", "AIN5", "AIN5" }, + { "Capture Mux", "AIN6", "AIN6" }, + { "Capture Mux", "AIN7", "AIN7" }, + { "Capture Mux", "AIN8", "AIN8" }, + + { "ADC", NULL, "Capture Mux" }, + + { "VOUT1 Mixer", NULL, "VOUT12 Supply" }, + { "VOUT1 Mixer", "DAC1 Switch", "DAC1" }, + { "VOUT1 Mixer", "AUX1 Switch", "AUX1" }, + { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT2 Mixer", NULL, "VOUT12 Supply" }, + { "VOUT2 Mixer", "DAC2 Switch", "DAC2" }, + { "VOUT2 Mixer", "AUX2 Switch", "AUX2" }, + { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT3 Mixer", NULL, "VOUT34 Supply" }, + { "VOUT3 Mixer", "DAC3 Switch", "DAC3" }, + { "VOUT3 Mixer", "AUX3 Switch", "AUX3" }, + { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT4 Mixer", NULL, "VOUT34 Supply" }, + { "VOUT4 Mixer", "DAC4 Switch", "DAC4" }, + { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT1", NULL, "VOUT1 Mixer" }, + { "VOUT2", NULL, "VOUT2 Mixer" }, + { "VOUT3", NULL, "VOUT3 Mixer" }, + { "VOUT4", NULL, "VOUT4 Mixer" } +}; + +static int vout12supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + + codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180); + break; + } + + return 0; +} + +static int vout34supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + + codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180); + break; + } + + return 0; +} + +static int wm8770_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8770_RESET, 0); +} + +static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec; + int iface, master; + + codec = dai->codec; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + master = 0x100; + break; + case SND_SOC_DAIFMT_CBS_CFS: + master = 0; + break; + default: + return -EINVAL; + } + + iface = 0; + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= 0x1; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= 0xc; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= 0x8; + break; + case SND_SOC_DAIFMT_NB_IF: + iface |= 0x4; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface); + snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master); + + return 0; +} + +static const int mclk_ratios[] = { + 128, + 192, + 256, + 384, + 512, + 768 +}; + +static int wm8770_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec; + struct wm8770_priv *wm8770; + int i; + int iface; + int shift; + int ratio; + + codec = dai->codec; + wm8770 = snd_soc_codec_get_drvdata(codec); + + iface = 0; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= 0x10; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= 0x20; + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= 0x30; + break; + } + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + i = 0; + shift = 4; + break; + case SNDRV_PCM_STREAM_CAPTURE: + i = 2; + shift = 0; + break; + default: + return -EINVAL; + } + + /* Only need to set MCLK/LRCLK ratio if we're master */ + if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) { + for (; i < ARRAY_SIZE(mclk_ratios); ++i) { + ratio = wm8770->sysclk / params_rate(params); + if (ratio == mclk_ratios[i]) + break; + } + + if (i == ARRAY_SIZE(mclk_ratios)) { + dev_err(codec->dev, + "Unable to configure MCLK ratio %d/%d\n", + wm8770->sysclk, params_rate(params)); + return -EINVAL; + } + + dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]); + + snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift, + i << shift); + } + + snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface); + + return 0; +} + +static int wm8770_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec; + + codec = dai->codec; + return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, + !!mute << 4); +} + +static int wm8770_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec; + struct wm8770_priv *wm8770; + + codec = dai->codec; + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770->sysclk = freq; + return 0; +} + +static void wm8770_sync_cache(struct snd_soc_codec *codec) +{ + int i; + u16 *cache; + + if (!codec->cache_sync) + return; + + codec->cache_only = 0; + cache = codec->reg_cache; + for (i = 0; i < codec->driver->reg_cache_size; i++) { + if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i]) + continue; + snd_soc_write(codec, i, cache[i]); + } + codec->cache_sync = 0; +} + +static int wm8770_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + int ret; + struct wm8770_priv *wm8770; + + wm8770 = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + wm8770_sync_cache(codec); + /* global powerup */ + snd_soc_write(codec, WM8770_PWDNCTRL, 0); + } + break; + case SND_SOC_BIAS_OFF: + /* global powerdown */ + snd_soc_write(codec, WM8770_PWDNCTRL, 1); + regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8770_dai_ops = { + .digital_mute = wm8770_mute, + .hw_params = wm8770_hw_params, + .set_fmt = wm8770_set_fmt, + .set_sysclk = wm8770_set_sysclk, +}; + +static struct snd_soc_dai_driver wm8770_dai = { + .name = "wm8770-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = WM8770_FORMATS + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = WM8770_FORMATS + }, + .ops = &wm8770_dai_ops, + .symmetric_rates = 1 +}; + +#ifdef CONFIG_PM +static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8770_resume(struct snd_soc_codec *codec) +{ + wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define wm8770_suspend NULL +#define wm8770_resume NULL +#endif + +static int wm8770_probe(struct snd_soc_codec *codec) +{ + struct wm8770_priv *wm8770; + int ret; + int i; + + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770->codec = codec; + + codec->dapm.idle_bias_off = 1; + + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) + wm8770->supplies[i].supply = wm8770_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; + wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; + wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { + ret = regulator_register_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + if (ret) { + dev_err(codec->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_reg_get; + } + + ret = wm8770_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); + goto err_reg_enable; + } + + wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* latch the volume update bits */ + snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100); + + /* mute all DACs */ + snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); + + snd_soc_add_controls(codec, wm8770_snd_controls, + ARRAY_SIZE(wm8770_snd_controls)); + snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, + ARRAY_SIZE(wm8770_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon, + ARRAY_SIZE(wm8770_intercon)); + return 0; + +err_reg_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); +err_reg_get: + regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); + return ret; +} + +static int wm8770_remove(struct snd_soc_codec *codec) +{ + struct wm8770_priv *wm8770; + int i; + + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); + + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) + regulator_unregister_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { + .probe = wm8770_probe, + .remove = wm8770_remove, + .suspend = wm8770_suspend, + .resume = wm8770_resume, + .set_bias_level = wm8770_set_bias_level, + .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), + .reg_word_size = sizeof (u16), + .reg_cache_default = wm8770_reg_defs +}; + +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8770_spi_probe(struct spi_device *spi) +{ + struct wm8770_priv *wm8770; + int ret; + + wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL); + if (!wm8770) + return -ENOMEM; + + wm8770->control_type = SND_SOC_SPI; + spi_set_drvdata(spi, wm8770); + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_wm8770, &wm8770_dai, 1); + if (ret < 0) + kfree(wm8770); + return ret; +} + +static int __devexit wm8770_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver wm8770_spi_driver = { + .driver = { + .name = "wm8770", + .owner = THIS_MODULE, + }, + .probe = wm8770_spi_probe, + .remove = __devexit_p(wm8770_spi_remove) +}; +#endif + +static int __init wm8770_modinit(void) +{ + int ret = 0; + +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8770_spi_driver); + if (ret) { + printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n", + ret); + } +#endif + return ret; +} +module_init(wm8770_modinit); + +static void __exit wm8770_exit(void) +{ +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8770_spi_driver); +#endif +} +module_exit(wm8770_exit); + +MODULE_DESCRIPTION("ASoC WM8770 driver"); +MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h new file mode 100644 index 0000000..5f1b3bd --- /dev/null +++ b/sound/soc/codecs/wm8770.h @@ -0,0 +1,51 @@ +/* + * wm8770.h -- WM8770 ASoC driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _WM8770_H +#define _WM8770_H + +/* Registers */ +#define WM8770_VOUT1LVOL 0 +#define WM8770_VOUT1RVOL 0x1 +#define WM8770_VOUT2LVOL 0x2 +#define WM8770_VOUT2RVOL 0x3 +#define WM8770_VOUT3LVOL 0x4 +#define WM8770_VOUT3RVOL 0x5 +#define WM8770_VOUT4LVOL 0x6 +#define WM8770_VOUT4RVOL 0x7 +#define WM8770_MSALGVOL 0x8 +#define WM8770_DAC1LVOL 0x9 +#define WM8770_DAC1RVOL 0xa +#define WM8770_DAC2LVOL 0xb +#define WM8770_DAC2RVOL 0xc +#define WM8770_DAC3LVOL 0xd +#define WM8770_DAC3RVOL 0xe +#define WM8770_DAC4LVOL 0xf +#define WM8770_DAC4RVOL 0x10 +#define WM8770_MSDIGVOL 0x11 +#define WM8770_DACPHASE 0x12 +#define WM8770_DACCTRL1 0x13 +#define WM8770_DACMUTE 0x14 +#define WM8770_DACCTRL2 0x15 +#define WM8770_IFACECTRL 0x16 +#define WM8770_MSTRCTRL 0x17 +#define WM8770_PWDNCTRL 0x18 +#define WM8770_ADCLCTRL 0x19 +#define WM8770_ADCRCTRL 0x1a +#define WM8770_ADCMUX 0x1b +#define WM8770_OUTMUX1 0x1c +#define WM8770_OUTMUX2 0x1d +#define WM8770_RESET 0x31 + +#define WM8770_CACHEREGNUM 0x20 + +#endif diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 0132a27..8e7953b 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -25,7 +25,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -306,7 +305,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Disable the global powerdown; DAPM does the rest */ snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); } @@ -317,7 +316,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -404,6 +403,7 @@ static int wm8776_resume(struct snd_soc_codec *codec) static int wm8776_probe(struct snd_soc_codec *codec) { struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); @@ -427,9 +427,9 @@ static int wm8776_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8776_snd_controls, ARRAY_SIZE(wm8776_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets, ARRAY_SIZE(wm8776_dapm_widgets)); - snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); + snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); return ret; } diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 4599e8e..6dae1b4 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -515,7 +514,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); if (ret) { @@ -537,7 +536,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -581,7 +580,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) wm8804 = snd_soc_codec_get_drvdata(codec); wm8804->codec = codec; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); if (ret < 0) { diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index aca4b1e..cfbaac1 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -30,7 +30,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -611,10 +610,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8900_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, - ARRAY_SIZE(wm8900_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets, + ARRAY_SIZE(wm8900_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1051,7 +1051,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: /* Charge capacitors if initial power up */ - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* STARTUP_BIAS_ENA on */ snd_soc_write(codec, WM8900_REG_POWER1, WM8900_REG_POWER1_STARTUP_BIAS_ENA); @@ -1119,7 +1119,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, WM8900_REG_POWER2_SYSCLK_ENA); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 622b602..620793e 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -29,7 +29,6 @@ #include <sound/pcm_params.h> #include <sound/tlv.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/wm8903.h> @@ -923,10 +922,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8903_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, - ARRAY_SIZE(wm8903_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets, + ARRAY_SIZE(wm8903_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -946,7 +946,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { snd_soc_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA); @@ -991,7 +991,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index fca60a0..d0024666 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <sound/wm8904.h> @@ -1428,10 +1427,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = { static int wm8904_add_widgets(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets, ARRAY_SIZE(wm8904_core_dapm_widgets)); - snd_soc_dapm_add_routes(codec, core_intercon, + snd_soc_dapm_add_routes(dapm, core_intercon, ARRAY_SIZE(core_intercon)); switch (wm8904->devtype) { @@ -1443,20 +1443,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8904_snd_controls, ARRAY_SIZE(wm8904_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, ARRAY_SIZE(wm8904_adc_dapm_widgets)); - snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, ARRAY_SIZE(wm8904_dac_dapm_widgets)); - snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets, ARRAY_SIZE(wm8904_dapm_widgets)); - snd_soc_dapm_add_routes(codec, core_intercon, + snd_soc_dapm_add_routes(dapm, core_intercon, ARRAY_SIZE(core_intercon)); - snd_soc_dapm_add_routes(codec, adc_intercon, + snd_soc_dapm_add_routes(dapm, adc_intercon, ARRAY_SIZE(adc_intercon)); - snd_soc_dapm_add_routes(codec, dac_intercon, + snd_soc_dapm_add_routes(dapm, dac_intercon, ARRAY_SIZE(dac_intercon)); - snd_soc_dapm_add_routes(codec, wm8904_intercon, + snd_soc_dapm_add_routes(dapm, wm8904_intercon, ARRAY_SIZE(wm8904_intercon)); break; @@ -1464,17 +1464,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8904_dac_snd_controls, ARRAY_SIZE(wm8904_dac_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, ARRAY_SIZE(wm8904_dac_dapm_widgets)); - snd_soc_dapm_add_routes(codec, dac_intercon, + snd_soc_dapm_add_routes(dapm, dac_intercon, ARRAY_SIZE(dac_intercon)); - snd_soc_dapm_add_routes(codec, wm8912_intercon, + snd_soc_dapm_add_routes(dapm, wm8912_intercon, ARRAY_SIZE(wm8912_intercon)); break; } - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -1590,7 +1590,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream, - wm8904->fs); for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { cur_val = abs((wm8904->sysclk_rate / - clk_sys_rates[i].ratio) - wm8904->fs);; + clk_sys_rates[i].ratio) - wm8904->fs); if (cur_val < best_val) { best = i; best_val = cur_val; @@ -2139,7 +2139,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); if (ret != 0) { @@ -2198,7 +2198,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, wm8904->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -2373,7 +2373,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) int ret, i; codec->cache_sync = 1; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; switch (wm8904->devtype) { case WM8904: diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 2cb16f8..381934f 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -35,7 +35,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -291,13 +290,14 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8940_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets, ARRAY_SIZE(wm8940_dapm_widgets)); if (ret) goto error_ret; - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret) goto error_ret; @@ -735,7 +735,6 @@ static int wm8940_probe(struct snd_soc_codec *codec) return ret; return ret; -; } static int wm8940_remove(struct snd_soc_codec *codec) diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index f89ad6c..6200beb 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <sound/wm8955.h> @@ -577,13 +576,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = { static int wm8955_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_add_controls(codec, wm8955_snd_controls, ARRAY_SIZE(wm8955_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets, ARRAY_SIZE(wm8955_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, wm8955_intercon, + snd_soc_dapm_add_routes(dapm, wm8955_intercon, ARRAY_SIZE(wm8955_intercon)); return 0; @@ -786,7 +786,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); if (ret != 0) { @@ -850,7 +850,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, wm8955->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8d5efb3..0bcf36e 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -20,7 +20,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <sound/wm8960.h> @@ -388,27 +387,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) { struct wm8960_data *pdata = codec->dev->platform_data; struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_widget *w; - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets, ARRAY_SIZE(wm8960_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); /* In capless mode OUT3 is used to provide VMID for the * headphone outputs, otherwise it is used as a mono mixer. */ if (pdata && pdata->capless) { - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless, ARRAY_SIZE(wm8960_dapm_widgets_capless)); - snd_soc_dapm_add_routes(codec, audio_paths_capless, + snd_soc_dapm_add_routes(dapm, audio_paths_capless, ARRAY_SIZE(audio_paths_capless)); } else { - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3, ARRAY_SIZE(wm8960_dapm_widgets_out3)); - snd_soc_dapm_add_routes(codec, audio_paths_out3, + snd_soc_dapm_add_routes(dapm, audio_paths_out3, ARRAY_SIZE(audio_paths_out3)); } @@ -417,7 +417,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) * list each time to find the desired power state do so now * and save the result. */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &codec->dapm.widgets, list) { if (strcmp(w->name, "LOUT1 PGA") == 0) wm8960->lout1 = w; if (strcmp(w->name, "ROUT1 PGA") == 0) @@ -572,7 +572,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable anti-pop features */ snd_soc_write(codec, WM8960_APOP1, WM8960_POBCTRL | WM8960_SOFT_ST | @@ -610,7 +610,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -626,7 +626,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: /* Enable anti pop mode */ snd_soc_update_bits(codec, WM8960_APOP1, @@ -681,7 +681,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_PREPARE: /* Disable HP discharge */ snd_soc_update_bits(codec, WM8960_APOP2, @@ -705,7 +705,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 8340485..6b22ef2 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -882,7 +881,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: - if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { /* Enable bias generation */ reg = snd_soc_read(codec, WM8961_ANTI_POP); reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; @@ -897,7 +896,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_PREPARE) { + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { /* VREF off */ reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); reg &= ~WM8961_VREF; @@ -919,7 +918,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -959,6 +958,7 @@ static struct snd_soc_dai_driver wm8961_dai = { static int wm8961_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; u16 reg; @@ -1024,9 +1024,9 @@ static int wm8961_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8961_snd_controls, ARRAY_SIZE(wm8961_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, ARRAY_SIZE(wm8961_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return 0; } diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e809274..cf4b272 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -29,7 +29,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <sound/wm8962.h> @@ -1958,7 +1957,7 @@ static int wm8962_readable_register(unsigned int reg) static int wm8962_reset(struct snd_soc_codec *codec) { - return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0); + return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); } static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); @@ -2682,6 +2681,7 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = { static int wm8962_add_widgets(struct snd_soc_codec *codec) { struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); + struct snd_soc_dapm_context *dapm = &codec->dapm; snd_soc_add_controls(codec, wm8962_snd_controls, ARRAY_SIZE(wm8962_snd_controls)); @@ -2693,26 +2693,26 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) ARRAY_SIZE(wm8962_spk_stereo_controls)); - snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, ARRAY_SIZE(wm8962_dapm_widgets)); if (pdata && pdata->spk_mono) - snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); else - snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets, ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets)); - snd_soc_dapm_add_routes(codec, wm8962_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_intercon, ARRAY_SIZE(wm8962_intercon)); if (pdata && pdata->spk_mono) - snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, ARRAY_SIZE(wm8962_spk_mono_intercon)); else - snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon, ARRAY_SIZE(wm8962_spk_stereo_intercon)); - snd_soc_dapm_disable_pin(codec, "Beep"); + snd_soc_dapm_disable_pin(dapm, "Beep"); return 0; } @@ -2819,7 +2819,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); int ret; - if (level == codec->bias_level) + if (level == codec->dapm.bias_level) return 0; switch (level) { @@ -2833,7 +2833,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (ret != 0) { @@ -2883,7 +2883,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, wm8962->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -3353,6 +3353,8 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); + pm_wakeup_event(codec->dev, 300); + schedule_delayed_work(&wm8962->mic_work, msecs_to_jiffies(250)); } @@ -3439,6 +3441,7 @@ static void wm8962_beep_work(struct work_struct *work) struct wm8962_priv *wm8962 = container_of(work, struct wm8962_priv, beep_work); struct snd_soc_codec *codec = wm8962->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; int reg = 0; int best = 0; @@ -3455,16 +3458,16 @@ static void wm8962_beep_work(struct work_struct *work) reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT); - snd_soc_dapm_enable_pin(codec, "Beep"); + snd_soc_dapm_enable_pin(dapm, "Beep"); } else { dev_dbg(codec->dev, "Disabling beep\n"); - snd_soc_dapm_disable_pin(codec, "Beep"); + snd_soc_dapm_disable_pin(dapm, "Beep"); } snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } /* For usability define a way of injecting beep events for the device - @@ -3711,7 +3714,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); codec->cache_sync = 1; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); if (ret != 0) { @@ -3870,7 +3873,6 @@ err_enable: err_get: regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); err: - kfree(wm8962); return ret; } diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 63f6dbf..8805636 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -25,7 +25,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "wm8971.h" @@ -333,10 +332,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8971_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets, - ARRAY_SIZE(wm8971_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets, + ARRAY_SIZE(wm8971_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -553,7 +553,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8971_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -590,9 +590,11 @@ static struct snd_soc_dai_driver wm8971_dai = { static void wm8971_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - wm8971_set_bias_level(codec, codec->bias_level); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, + delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; + wm8971_set_bias_level(codec, codec->dapm.bias_level); } static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) @@ -620,11 +622,11 @@ static int wm8971_resume(struct snd_soc_codec *codec) wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8971 caps */ - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); - codec->bias_level = SND_SOC_BIAS_ON; - queue_delayed_work(wm8971_workq, &codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_ON; + queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work, msecs_to_jiffies(1000)); } @@ -643,7 +645,7 @@ static int wm8971_probe(struct snd_soc_codec *codec) return ret; } - INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); wm8971_workq = create_workqueue("wm8971"); if (wm8971_workq == NULL) return -ENOMEM; @@ -653,8 +655,8 @@ static int wm8971_probe(struct snd_soc_codec *codec) /* charge output caps - set vmid to 5k for quick power up */ reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); - codec->bias_level = SND_SOC_BIAS_STANDBY; - queue_delayed_work(wm8971_workq, &codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; + queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work, msecs_to_jiffies(1000)); /* set the update bits */ diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index b4363f6..5d28642 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -274,10 +273,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8974_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets, - ARRAY_SIZE(wm8974_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets, + ARRAY_SIZE(wm8974_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -530,7 +530,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); mdelay(100); @@ -547,7 +547,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 13b979a..a195af9 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <asm/div64.h> @@ -355,11 +354,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8978_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets, - ARRAY_SIZE(wm8978_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets, + ARRAY_SIZE(wm8978_dapm_widgets)); /* set up the WM8978 audio map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -837,7 +837,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec, /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ power1 |= 0xc; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1 | 0x3); @@ -857,7 +857,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec, dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1); - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index fd2e7cc..bae510a 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -26,7 +26,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -533,10 +532,11 @@ static int eqmode_put(struct snd_kcontrol *kcontrol, static int wm8985_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets, - ARRAY_SIZE(wm8985_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, + snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets, + ARRAY_SIZE(wm8985_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -879,7 +879,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, 1 << WM8985_VMIDSEL_SHIFT); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); if (ret) { @@ -939,7 +939,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index d7f2597..65807b1 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -25,7 +25,6 @@ #include <sound/pcm_params.h> #include <sound/tlv.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "wm8988.h" @@ -677,7 +676,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* VREF, VMID=2x5k */ snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); @@ -693,7 +692,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8988_PWR1, 0x0000); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -759,6 +758,7 @@ static int wm8988_resume(struct snd_soc_codec *codec) static int wm8988_probe(struct snd_soc_codec *codec) { struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; u16 reg; @@ -790,9 +790,9 @@ static int wm8988_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8988_snd_controls, ARRAY_SIZE(wm8988_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets, ARRAY_SIZE(wm8988_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 264828e..5c87a63 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> #include <asm/div64.h> @@ -914,11 +913,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8990_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets, - ARRAY_SIZE(wm8990_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets, + ARRAY_SIZE(wm8990_dapm_widgets)); /* set up the WM8990 audio map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1170,7 +1170,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable all output discharge bits */ snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | WM8990_DIS_RLINE | WM8990_DIS_OUT3 | @@ -1266,7 +1266,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 589e3fa..77b1d44 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -24,7 +24,6 @@ #include <sound/pcm_params.h> #include <sound/tlv.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/wm8993.h> @@ -735,6 +734,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol, 0); } wm8993->class_w_users++; + wm8993->hubs_data.class_w = true; } /* Implement the change */ @@ -751,6 +751,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol, WM8993_CP_DYN_V); } wm8993->class_w_users--; + wm8993->hubs_data.class_w = false; } dev_dbg(codec->dev, "Indirect DAC use count now %d\n", @@ -968,7 +969,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) @@ -1043,7 +1044,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1225,7 +1226,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, - wm8993->fs); for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { cur_val = abs((wm8993->sysclk_rate / - clk_sys_rates[i].ratio) - wm8993->fs);; + clk_sys_rates[i].ratio) - wm8993->fs); if (cur_val < best_val) { best = i; best_val = cur_val; @@ -1422,6 +1423,7 @@ static struct snd_soc_dai_driver wm8993_dai = { static int wm8993_probe(struct snd_soc_codec *codec) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, i, val; wm8993->hubs_data.hp_startup_mode = 1; @@ -1503,11 +1505,11 @@ static int wm8993_probe(struct snd_soc_codec *codec) ARRAY_SIZE(wm8993_eq_controls)); } - snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets, ARRAY_SIZE(wm8993_dapm_widgets)); wm_hubs_add_analogue_controls(codec); - snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); + snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, wm8993->pdata.lineout2_diff); diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c new file mode 100644 index 0000000..7b93538 --- /dev/null +++ b/sound/soc/codecs/wm8994-tables.c @@ -0,0 +1,1575 @@ +#include "wm8994.h" + +const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { + { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */ + { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */ + { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */ + { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */ + { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */ + { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */ + { 0x003F, 0x003F }, /* R6 - Power Management (6) */ + { 0x0000, 0x0000 }, /* R7 */ + { 0x0000, 0x0000 }, /* R8 */ + { 0x0000, 0x0000 }, /* R9 */ + { 0x0000, 0x0000 }, /* R10 */ + { 0x0000, 0x0000 }, /* R11 */ + { 0x0000, 0x0000 }, /* R12 */ + { 0x0000, 0x0000 }, /* R13 */ + { 0x0000, 0x0000 }, /* R14 */ + { 0x0000, 0x0000 }, /* R15 */ + { 0x0000, 0x0000 }, /* R16 */ + { 0x0000, 0x0000 }, /* R17 */ + { 0x0000, 0x0000 }, /* R18 */ + { 0x0000, 0x0000 }, /* R19 */ + { 0x0000, 0x0000 }, /* R20 */ + { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */ + { 0x0000, 0x0000 }, /* R22 */ + { 0x0000, 0x0000 }, /* R23 */ + { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */ + { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */ + { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */ + { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */ + { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */ + { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */ + { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */ + { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */ + { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */ + { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */ + { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */ + { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */ + { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */ + { 0x003F, 0x003F }, /* R37 - ClassD */ + { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */ + { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */ + { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */ + { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */ + { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */ + { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */ + { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */ + { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */ + { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */ + { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */ + { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */ + { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */ + { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */ + { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */ + { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */ + { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */ + { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */ + { 0x00C1, 0x00C1 }, /* R55 - Additional Control */ + { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */ + { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */ + { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ + { 0x000F, 0x000F }, /* R59 - LDO 1 */ + { 0x0007, 0x0007 }, /* R60 - LDO 2 */ + { 0x0000, 0x0000 }, /* R61 */ + { 0x0000, 0x0000 }, /* R62 */ + { 0x0000, 0x0000 }, /* R63 */ + { 0x0000, 0x0000 }, /* R64 */ + { 0x0000, 0x0000 }, /* R65 */ + { 0x0000, 0x0000 }, /* R66 */ + { 0x0000, 0x0000 }, /* R67 */ + { 0x0000, 0x0000 }, /* R68 */ + { 0x0000, 0x0000 }, /* R69 */ + { 0x0000, 0x0000 }, /* R70 */ + { 0x0000, 0x0000 }, /* R71 */ + { 0x0000, 0x0000 }, /* R72 */ + { 0x0000, 0x0000 }, /* R73 */ + { 0x0000, 0x0000 }, /* R74 */ + { 0x0000, 0x0000 }, /* R75 */ + { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ + { 0x0000, 0x0000 }, /* R77 */ + { 0x0000, 0x0000 }, /* R78 */ + { 0x0000, 0x0000 }, /* R79 */ + { 0x0000, 0x0000 }, /* R80 */ + { 0x0301, 0x0301 }, /* R81 - Class W (1) */ + { 0x0000, 0x0000 }, /* R82 */ + { 0x0000, 0x0000 }, /* R83 */ + { 0x333F, 0x333F }, /* R84 - DC Servo (1) */ + { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */ + { 0x0000, 0x0000 }, /* R86 */ + { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */ + { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */ + { 0x0000, 0x0000 }, /* R89 */ + { 0x0000, 0x0000 }, /* R90 */ + { 0x0000, 0x0000 }, /* R91 */ + { 0x0000, 0x0000 }, /* R92 */ + { 0x0000, 0x0000 }, /* R93 */ + { 0x0000, 0x0000 }, /* R94 */ + { 0x0000, 0x0000 }, /* R95 */ + { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */ + { 0x0000, 0x0000 }, /* R97 */ + { 0x0000, 0x0000 }, /* R98 */ + { 0x0000, 0x0000 }, /* R99 */ + { 0x0000, 0x0000 }, /* R100 */ + { 0x0000, 0x0000 }, /* R101 */ + { 0x0000, 0x0000 }, /* R102 */ + { 0x0000, 0x0000 }, /* R103 */ + { 0x0000, 0x0000 }, /* R104 */ + { 0x0000, 0x0000 }, /* R105 */ + { 0x0000, 0x0000 }, /* R106 */ + { 0x0000, 0x0000 }, /* R107 */ + { 0x0000, 0x0000 }, /* R108 */ + { 0x0000, 0x0000 }, /* R109 */ + { 0x0000, 0x0000 }, /* R110 */ + { 0x0000, 0x0000 }, /* R111 */ + { 0x0000, 0x0000 }, /* R112 */ + { 0x0000, 0x0000 }, /* R113 */ + { 0x0000, 0x0000 }, /* R114 */ + { 0x0000, 0x0000 }, /* R115 */ + { 0x0000, 0x0000 }, /* R116 */ + { 0x0000, 0x0000 }, /* R117 */ + { 0x0000, 0x0000 }, /* R118 */ + { 0x0000, 0x0000 }, /* R119 */ + { 0x0000, 0x0000 }, /* R120 */ + { 0x0000, 0x0000 }, /* R121 */ + { 0x0000, 0x0000 }, /* R122 */ + { 0x0000, 0x0000 }, /* R123 */ + { 0x0000, 0x0000 }, /* R124 */ + { 0x0000, 0x0000 }, /* R125 */ + { 0x0000, 0x0000 }, /* R126 */ + { 0x0000, 0x0000 }, /* R127 */ + { 0x0000, 0x0000 }, /* R128 */ + { 0x0000, 0x0000 }, /* R129 */ + { 0x0000, 0x0000 }, /* R130 */ + { 0x0000, 0x0000 }, /* R131 */ + { 0x0000, 0x0000 }, /* R132 */ + { 0x0000, 0x0000 }, /* R133 */ + { 0x0000, 0x0000 }, /* R134 */ + { 0x0000, 0x0000 }, /* R135 */ + { 0x0000, 0x0000 }, /* R136 */ + { 0x0000, 0x0000 }, /* R137 */ + { 0x0000, 0x0000 }, /* R138 */ + { 0x0000, 0x0000 }, /* R139 */ + { 0x0000, 0x0000 }, /* R140 */ + { 0x0000, 0x0000 }, /* R141 */ + { 0x0000, 0x0000 }, /* R142 */ + { 0x0000, 0x0000 }, /* R143 */ + { 0x0000, 0x0000 }, /* R144 */ + { 0x0000, 0x0000 }, /* R145 */ + { 0x0000, 0x0000 }, /* R146 */ + { 0x0000, 0x0000 }, /* R147 */ + { 0x0000, 0x0000 }, /* R148 */ + { 0x0000, 0x0000 }, /* R149 */ + { 0x0000, 0x0000 }, /* R150 */ + { 0x0000, 0x0000 }, /* R151 */ + { 0x0000, 0x0000 }, /* R152 */ + { 0x0000, 0x0000 }, /* R153 */ + { 0x0000, 0x0000 }, /* R154 */ + { 0x0000, 0x0000 }, /* R155 */ + { 0x0000, 0x0000 }, /* R156 */ + { 0x0000, 0x0000 }, /* R157 */ + { 0x0000, 0x0000 }, /* R158 */ + { 0x0000, 0x0000 }, /* R159 */ + { 0x0000, 0x0000 }, /* R160 */ + { 0x0000, 0x0000 }, /* R161 */ + { 0x0000, 0x0000 }, /* R162 */ + { 0x0000, 0x0000 }, /* R163 */ + { 0x0000, 0x0000 }, /* R164 */ + { 0x0000, 0x0000 }, /* R165 */ + { 0x0000, 0x0000 }, /* R166 */ + { 0x0000, 0x0000 }, /* R167 */ + { 0x0000, 0x0000 }, /* R168 */ + { 0x0000, 0x0000 }, /* R169 */ + { 0x0000, 0x0000 }, /* R170 */ + { 0x0000, 0x0000 }, /* R171 */ + { 0x0000, 0x0000 }, /* R172 */ + { 0x0000, 0x0000 }, /* R173 */ + { 0x0000, 0x0000 }, /* R174 */ + { 0x0000, 0x0000 }, /* R175 */ + { 0x0000, 0x0000 }, /* R176 */ + { 0x0000, 0x0000 }, /* R177 */ + { 0x0000, 0x0000 }, /* R178 */ + { 0x0000, 0x0000 }, /* R179 */ + { 0x0000, 0x0000 }, /* R180 */ + { 0x0000, 0x0000 }, /* R181 */ + { 0x0000, 0x0000 }, /* R182 */ + { 0x0000, 0x0000 }, /* R183 */ + { 0x0000, 0x0000 }, /* R184 */ + { 0x0000, 0x0000 }, /* R185 */ + { 0x0000, 0x0000 }, /* R186 */ + { 0x0000, 0x0000 }, /* R187 */ + { 0x0000, 0x0000 }, /* R188 */ + { 0x0000, 0x0000 }, /* R189 */ + { 0x0000, 0x0000 }, /* R190 */ + { 0x0000, 0x0000 }, /* R191 */ + { 0x0000, 0x0000 }, /* R192 */ + { 0x0000, 0x0000 }, /* R193 */ + { 0x0000, 0x0000 }, /* R194 */ + { 0x0000, 0x0000 }, /* R195 */ + { 0x0000, 0x0000 }, /* R196 */ + { 0x0000, 0x0000 }, /* R197 */ + { 0x0000, 0x0000 }, /* R198 */ + { 0x0000, 0x0000 }, /* R199 */ + { 0x0000, 0x0000 }, /* R200 */ + { 0x0000, 0x0000 }, /* R201 */ + { 0x0000, 0x0000 }, /* R202 */ + { 0x0000, 0x0000 }, /* R203 */ + { 0x0000, 0x0000 }, /* R204 */ + { 0x0000, 0x0000 }, /* R205 */ + { 0x0000, 0x0000 }, /* R206 */ + { 0x0000, 0x0000 }, /* R207 */ + { 0x0000, 0x0000 }, /* R208 */ + { 0x0000, 0x0000 }, /* R209 */ + { 0x0000, 0x0000 }, /* R210 */ + { 0x0000, 0x0000 }, /* R211 */ + { 0x0000, 0x0000 }, /* R212 */ + { 0x0000, 0x0000 }, /* R213 */ + { 0x0000, 0x0000 }, /* R214 */ + { 0x0000, 0x0000 }, /* R215 */ + { 0x0000, 0x0000 }, /* R216 */ + { 0x0000, 0x0000 }, /* R217 */ + { 0x0000, 0x0000 }, /* R218 */ + { 0x0000, 0x0000 }, /* R219 */ + { 0x0000, 0x0000 }, /* R220 */ + { 0x0000, 0x0000 }, /* R221 */ + { 0x0000, 0x0000 }, /* R222 */ + { 0x0000, 0x0000 }, /* R223 */ + { 0x0000, 0x0000 }, /* R224 */ + { 0x0000, 0x0000 }, /* R225 */ + { 0x0000, 0x0000 }, /* R226 */ + { 0x0000, 0x0000 }, /* R227 */ + { 0x0000, 0x0000 }, /* R228 */ + { 0x0000, 0x0000 }, /* R229 */ + { 0x0000, 0x0000 }, /* R230 */ + { 0x0000, 0x0000 }, /* R231 */ + { 0x0000, 0x0000 }, /* R232 */ + { 0x0000, 0x0000 }, /* R233 */ + { 0x0000, 0x0000 }, /* R234 */ + { 0x0000, 0x0000 }, /* R235 */ + { 0x0000, 0x0000 }, /* R236 */ + { 0x0000, 0x0000 }, /* R237 */ + { 0x0000, 0x0000 }, /* R238 */ + { 0x0000, 0x0000 }, /* R239 */ + { 0x0000, 0x0000 }, /* R240 */ + { 0x0000, 0x0000 }, /* R241 */ + { 0x0000, 0x0000 }, /* R242 */ + { 0x0000, 0x0000 }, /* R243 */ + { 0x0000, 0x0000 }, /* R244 */ + { 0x0000, 0x0000 }, /* R245 */ + { 0x0000, 0x0000 }, /* R246 */ + { 0x0000, 0x0000 }, /* R247 */ + { 0x0000, 0x0000 }, /* R248 */ + { 0x0000, 0x0000 }, /* R249 */ + { 0x0000, 0x0000 }, /* R250 */ + { 0x0000, 0x0000 }, /* R251 */ + { 0x0000, 0x0000 }, /* R252 */ + { 0x0000, 0x0000 }, /* R253 */ + { 0x0000, 0x0000 }, /* R254 */ + { 0x0000, 0x0000 }, /* R255 */ + { 0x000F, 0x0000 }, /* R256 - Chip Revision */ + { 0x0074, 0x0074 }, /* R257 - Control Interface */ + { 0x0000, 0x0000 }, /* R258 */ + { 0x0000, 0x0000 }, /* R259 */ + { 0x0000, 0x0000 }, /* R260 */ + { 0x0000, 0x0000 }, /* R261 */ + { 0x0000, 0x0000 }, /* R262 */ + { 0x0000, 0x0000 }, /* R263 */ + { 0x0000, 0x0000 }, /* R264 */ + { 0x0000, 0x0000 }, /* R265 */ + { 0x0000, 0x0000 }, /* R266 */ + { 0x0000, 0x0000 }, /* R267 */ + { 0x0000, 0x0000 }, /* R268 */ + { 0x0000, 0x0000 }, /* R269 */ + { 0x0000, 0x0000 }, /* R270 */ + { 0x0000, 0x0000 }, /* R271 */ + { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */ + { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ + { 0x0000, 0x0000 }, /* R274 */ + { 0x0000, 0x0000 }, /* R275 */ + { 0x0000, 0x0000 }, /* R276 */ + { 0x0000, 0x0000 }, /* R277 */ + { 0x0000, 0x0000 }, /* R278 */ + { 0x0000, 0x0000 }, /* R279 */ + { 0x0000, 0x0000 }, /* R280 */ + { 0x0000, 0x0000 }, /* R281 */ + { 0x0000, 0x0000 }, /* R282 */ + { 0x0000, 0x0000 }, /* R283 */ + { 0x0000, 0x0000 }, /* R284 */ + { 0x0000, 0x0000 }, /* R285 */ + { 0x0000, 0x0000 }, /* R286 */ + { 0x0000, 0x0000 }, /* R287 */ + { 0x0000, 0x0000 }, /* R288 */ + { 0x0000, 0x0000 }, /* R289 */ + { 0x0000, 0x0000 }, /* R290 */ + { 0x0000, 0x0000 }, /* R291 */ + { 0x0000, 0x0000 }, /* R292 */ + { 0x0000, 0x0000 }, /* R293 */ + { 0x0000, 0x0000 }, /* R294 */ + { 0x0000, 0x0000 }, /* R295 */ + { 0x0000, 0x0000 }, /* R296 */ + { 0x0000, 0x0000 }, /* R297 */ + { 0x0000, 0x0000 }, /* R298 */ + { 0x0000, 0x0000 }, /* R299 */ + { 0x0000, 0x0000 }, /* R300 */ + { 0x0000, 0x0000 }, /* R301 */ + { 0x0000, 0x0000 }, /* R302 */ + { 0x0000, 0x0000 }, /* R303 */ + { 0x0000, 0x0000 }, /* R304 */ + { 0x0000, 0x0000 }, /* R305 */ + { 0x0000, 0x0000 }, /* R306 */ + { 0x0000, 0x0000 }, /* R307 */ + { 0x0000, 0x0000 }, /* R308 */ + { 0x0000, 0x0000 }, /* R309 */ + { 0x0000, 0x0000 }, /* R310 */ + { 0x0000, 0x0000 }, /* R311 */ + { 0x0000, 0x0000 }, /* R312 */ + { 0x0000, 0x0000 }, /* R313 */ + { 0x0000, 0x0000 }, /* R314 */ + { 0x0000, 0x0000 }, /* R315 */ + { 0x0000, 0x0000 }, /* R316 */ + { 0x0000, 0x0000 }, /* R317 */ + { 0x0000, 0x0000 }, /* R318 */ + { 0x0000, 0x0000 }, /* R319 */ + { 0x0000, 0x0000 }, /* R320 */ + { 0x0000, 0x0000 }, /* R321 */ + { 0x0000, 0x0000 }, /* R322 */ + { 0x0000, 0x0000 }, /* R323 */ + { 0x0000, 0x0000 }, /* R324 */ + { 0x0000, 0x0000 }, /* R325 */ + { 0x0000, 0x0000 }, /* R326 */ + { 0x0000, 0x0000 }, /* R327 */ + { 0x0000, 0x0000 }, /* R328 */ + { 0x0000, 0x0000 }, /* R329 */ + { 0x0000, 0x0000 }, /* R330 */ + { 0x0000, 0x0000 }, /* R331 */ + { 0x0000, 0x0000 }, /* R332 */ + { 0x0000, 0x0000 }, /* R333 */ + { 0x0000, 0x0000 }, /* R334 */ + { 0x0000, 0x0000 }, /* R335 */ + { 0x0000, 0x0000 }, /* R336 */ + { 0x0000, 0x0000 }, /* R337 */ + { 0x0000, 0x0000 }, /* R338 */ + { 0x0000, 0x0000 }, /* R339 */ + { 0x0000, 0x0000 }, /* R340 */ + { 0x0000, 0x0000 }, /* R341 */ + { 0x0000, 0x0000 }, /* R342 */ + { 0x0000, 0x0000 }, /* R343 */ + { 0x0000, 0x0000 }, /* R344 */ + { 0x0000, 0x0000 }, /* R345 */ + { 0x0000, 0x0000 }, /* R346 */ + { 0x0000, 0x0000 }, /* R347 */ + { 0x0000, 0x0000 }, /* R348 */ + { 0x0000, 0x0000 }, /* R349 */ + { 0x0000, 0x0000 }, /* R350 */ + { 0x0000, 0x0000 }, /* R351 */ + { 0x0000, 0x0000 }, /* R352 */ + { 0x0000, 0x0000 }, /* R353 */ + { 0x0000, 0x0000 }, /* R354 */ + { 0x0000, 0x0000 }, /* R355 */ + { 0x0000, 0x0000 }, /* R356 */ + { 0x0000, 0x0000 }, /* R357 */ + { 0x0000, 0x0000 }, /* R358 */ + { 0x0000, 0x0000 }, /* R359 */ + { 0x0000, 0x0000 }, /* R360 */ + { 0x0000, 0x0000 }, /* R361 */ + { 0x0000, 0x0000 }, /* R362 */ + { 0x0000, 0x0000 }, /* R363 */ + { 0x0000, 0x0000 }, /* R364 */ + { 0x0000, 0x0000 }, /* R365 */ + { 0x0000, 0x0000 }, /* R366 */ + { 0x0000, 0x0000 }, /* R367 */ + { 0x0000, 0x0000 }, /* R368 */ + { 0x0000, 0x0000 }, /* R369 */ + { 0x0000, 0x0000 }, /* R370 */ + { 0x0000, 0x0000 }, /* R371 */ + { 0x0000, 0x0000 }, /* R372 */ + { 0x0000, 0x0000 }, /* R373 */ + { 0x0000, 0x0000 }, /* R374 */ + { 0x0000, 0x0000 }, /* R375 */ + { 0x0000, 0x0000 }, /* R376 */ + { 0x0000, 0x0000 }, /* R377 */ + { 0x0000, 0x0000 }, /* R378 */ + { 0x0000, 0x0000 }, /* R379 */ + { 0x0000, 0x0000 }, /* R380 */ + { 0x0000, 0x0000 }, /* R381 */ + { 0x0000, 0x0000 }, /* R382 */ + { 0x0000, 0x0000 }, /* R383 */ + { 0x0000, 0x0000 }, /* R384 */ + { 0x0000, 0x0000 }, /* R385 */ + { 0x0000, 0x0000 }, /* R386 */ + { 0x0000, 0x0000 }, /* R387 */ + { 0x0000, 0x0000 }, /* R388 */ + { 0x0000, 0x0000 }, /* R389 */ + { 0x0000, 0x0000 }, /* R390 */ + { 0x0000, 0x0000 }, /* R391 */ + { 0x0000, 0x0000 }, /* R392 */ + { 0x0000, 0x0000 }, /* R393 */ + { 0x0000, 0x0000 }, /* R394 */ + { 0x0000, 0x0000 }, /* R395 */ + { 0x0000, 0x0000 }, /* R396 */ + { 0x0000, 0x0000 }, /* R397 */ + { 0x0000, 0x0000 }, /* R398 */ + { 0x0000, 0x0000 }, /* R399 */ + { 0x0000, 0x0000 }, /* R400 */ + { 0x0000, 0x0000 }, /* R401 */ + { 0x0000, 0x0000 }, /* R402 */ + { 0x0000, 0x0000 }, /* R403 */ + { 0x0000, 0x0000 }, /* R404 */ + { 0x0000, 0x0000 }, /* R405 */ + { 0x0000, 0x0000 }, /* R406 */ + { 0x0000, 0x0000 }, /* R407 */ + { 0x0000, 0x0000 }, /* R408 */ + { 0x0000, 0x0000 }, /* R409 */ + { 0x0000, 0x0000 }, /* R410 */ + { 0x0000, 0x0000 }, /* R411 */ + { 0x0000, 0x0000 }, /* R412 */ + { 0x0000, 0x0000 }, /* R413 */ + { 0x0000, 0x0000 }, /* R414 */ + { 0x0000, 0x0000 }, /* R415 */ + { 0x0000, 0x0000 }, /* R416 */ + { 0x0000, 0x0000 }, /* R417 */ + { 0x0000, 0x0000 }, /* R418 */ + { 0x0000, 0x0000 }, /* R419 */ + { 0x0000, 0x0000 }, /* R420 */ + { 0x0000, 0x0000 }, /* R421 */ + { 0x0000, 0x0000 }, /* R422 */ + { 0x0000, 0x0000 }, /* R423 */ + { 0x0000, 0x0000 }, /* R424 */ + { 0x0000, 0x0000 }, /* R425 */ + { 0x0000, 0x0000 }, /* R426 */ + { 0x0000, 0x0000 }, /* R427 */ + { 0x0000, 0x0000 }, /* R428 */ + { 0x0000, 0x0000 }, /* R429 */ + { 0x0000, 0x0000 }, /* R430 */ + { 0x0000, 0x0000 }, /* R431 */ + { 0x0000, 0x0000 }, /* R432 */ + { 0x0000, 0x0000 }, /* R433 */ + { 0x0000, 0x0000 }, /* R434 */ + { 0x0000, 0x0000 }, /* R435 */ + { 0x0000, 0x0000 }, /* R436 */ + { 0x0000, 0x0000 }, /* R437 */ + { 0x0000, 0x0000 }, /* R438 */ + { 0x0000, 0x0000 }, /* R439 */ + { 0x0000, 0x0000 }, /* R440 */ + { 0x0000, 0x0000 }, /* R441 */ + { 0x0000, 0x0000 }, /* R442 */ + { 0x0000, 0x0000 }, /* R443 */ + { 0x0000, 0x0000 }, /* R444 */ + { 0x0000, 0x0000 }, /* R445 */ + { 0x0000, 0x0000 }, /* R446 */ + { 0x0000, 0x0000 }, /* R447 */ + { 0x0000, 0x0000 }, /* R448 */ + { 0x0000, 0x0000 }, /* R449 */ + { 0x0000, 0x0000 }, /* R450 */ + { 0x0000, 0x0000 }, /* R451 */ + { 0x0000, 0x0000 }, /* R452 */ + { 0x0000, 0x0000 }, /* R453 */ + { 0x0000, 0x0000 }, /* R454 */ + { 0x0000, 0x0000 }, /* R455 */ + { 0x0000, 0x0000 }, /* R456 */ + { 0x0000, 0x0000 }, /* R457 */ + { 0x0000, 0x0000 }, /* R458 */ + { 0x0000, 0x0000 }, /* R459 */ + { 0x0000, 0x0000 }, /* R460 */ + { 0x0000, 0x0000 }, /* R461 */ + { 0x0000, 0x0000 }, /* R462 */ + { 0x0000, 0x0000 }, /* R463 */ + { 0x0000, 0x0000 }, /* R464 */ + { 0x0000, 0x0000 }, /* R465 */ + { 0x0000, 0x0000 }, /* R466 */ + { 0x0000, 0x0000 }, /* R467 */ + { 0x0000, 0x0000 }, /* R468 */ + { 0x0000, 0x0000 }, /* R469 */ + { 0x0000, 0x0000 }, /* R470 */ + { 0x0000, 0x0000 }, /* R471 */ + { 0x0000, 0x0000 }, /* R472 */ + { 0x0000, 0x0000 }, /* R473 */ + { 0x0000, 0x0000 }, /* R474 */ + { 0x0000, 0x0000 }, /* R475 */ + { 0x0000, 0x0000 }, /* R476 */ + { 0x0000, 0x0000 }, /* R477 */ + { 0x0000, 0x0000 }, /* R478 */ + { 0x0000, 0x0000 }, /* R479 */ + { 0x0000, 0x0000 }, /* R480 */ + { 0x0000, 0x0000 }, /* R481 */ + { 0x0000, 0x0000 }, /* R482 */ + { 0x0000, 0x0000 }, /* R483 */ + { 0x0000, 0x0000 }, /* R484 */ + { 0x0000, 0x0000 }, /* R485 */ + { 0x0000, 0x0000 }, /* R486 */ + { 0x0000, 0x0000 }, /* R487 */ + { 0x0000, 0x0000 }, /* R488 */ + { 0x0000, 0x0000 }, /* R489 */ + { 0x0000, 0x0000 }, /* R490 */ + { 0x0000, 0x0000 }, /* R491 */ + { 0x0000, 0x0000 }, /* R492 */ + { 0x0000, 0x0000 }, /* R493 */ + { 0x0000, 0x0000 }, /* R494 */ + { 0x0000, 0x0000 }, /* R495 */ + { 0x0000, 0x0000 }, /* R496 */ + { 0x0000, 0x0000 }, /* R497 */ + { 0x0000, 0x0000 }, /* R498 */ + { 0x0000, 0x0000 }, /* R499 */ + { 0x0000, 0x0000 }, /* R500 */ + { 0x0000, 0x0000 }, /* R501 */ + { 0x0000, 0x0000 }, /* R502 */ + { 0x0000, 0x0000 }, /* R503 */ + { 0x0000, 0x0000 }, /* R504 */ + { 0x0000, 0x0000 }, /* R505 */ + { 0x0000, 0x0000 }, /* R506 */ + { 0x0000, 0x0000 }, /* R507 */ + { 0x0000, 0x0000 }, /* R508 */ + { 0x0000, 0x0000 }, /* R509 */ + { 0x0000, 0x0000 }, /* R510 */ + { 0x0000, 0x0000 }, /* R511 */ + { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */ + { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */ + { 0x0000, 0x0000 }, /* R514 */ + { 0x0000, 0x0000 }, /* R515 */ + { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */ + { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */ + { 0x0000, 0x0000 }, /* R518 */ + { 0x0000, 0x0000 }, /* R519 */ + { 0x001F, 0x001F }, /* R520 - Clocking (1) */ + { 0x0777, 0x0777 }, /* R521 - Clocking (2) */ + { 0x0000, 0x0000 }, /* R522 */ + { 0x0000, 0x0000 }, /* R523 */ + { 0x0000, 0x0000 }, /* R524 */ + { 0x0000, 0x0000 }, /* R525 */ + { 0x0000, 0x0000 }, /* R526 */ + { 0x0000, 0x0000 }, /* R527 */ + { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */ + { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */ + { 0x000F, 0x0000 }, /* R530 - Rate Status */ + { 0x0000, 0x0000 }, /* R531 */ + { 0x0000, 0x0000 }, /* R532 */ + { 0x0000, 0x0000 }, /* R533 */ + { 0x0000, 0x0000 }, /* R534 */ + { 0x0000, 0x0000 }, /* R535 */ + { 0x0000, 0x0000 }, /* R536 */ + { 0x0000, 0x0000 }, /* R537 */ + { 0x0000, 0x0000 }, /* R538 */ + { 0x0000, 0x0000 }, /* R539 */ + { 0x0000, 0x0000 }, /* R540 */ + { 0x0000, 0x0000 }, /* R541 */ + { 0x0000, 0x0000 }, /* R542 */ + { 0x0000, 0x0000 }, /* R543 */ + { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */ + { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */ + { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */ + { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */ + { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */ + { 0x0000, 0x0000 }, /* R549 */ + { 0x0000, 0x0000 }, /* R550 */ + { 0x0000, 0x0000 }, /* R551 */ + { 0x0000, 0x0000 }, /* R552 */ + { 0x0000, 0x0000 }, /* R553 */ + { 0x0000, 0x0000 }, /* R554 */ + { 0x0000, 0x0000 }, /* R555 */ + { 0x0000, 0x0000 }, /* R556 */ + { 0x0000, 0x0000 }, /* R557 */ + { 0x0000, 0x0000 }, /* R558 */ + { 0x0000, 0x0000 }, /* R559 */ + { 0x0000, 0x0000 }, /* R560 */ + { 0x0000, 0x0000 }, /* R561 */ + { 0x0000, 0x0000 }, /* R562 */ + { 0x0000, 0x0000 }, /* R563 */ + { 0x0000, 0x0000 }, /* R564 */ + { 0x0000, 0x0000 }, /* R565 */ + { 0x0000, 0x0000 }, /* R566 */ + { 0x0000, 0x0000 }, /* R567 */ + { 0x0000, 0x0000 }, /* R568 */ + { 0x0000, 0x0000 }, /* R569 */ + { 0x0000, 0x0000 }, /* R570 */ + { 0x0000, 0x0000 }, /* R571 */ + { 0x0000, 0x0000 }, /* R572 */ + { 0x0000, 0x0000 }, /* R573 */ + { 0x0000, 0x0000 }, /* R574 */ + { 0x0000, 0x0000 }, /* R575 */ + { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */ + { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */ + { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */ + { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */ + { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */ + { 0x0000, 0x0000 }, /* R581 */ + { 0x0000, 0x0000 }, /* R582 */ + { 0x0000, 0x0000 }, /* R583 */ + { 0x0000, 0x0000 }, /* R584 */ + { 0x0000, 0x0000 }, /* R585 */ + { 0x0000, 0x0000 }, /* R586 */ + { 0x0000, 0x0000 }, /* R587 */ + { 0x0000, 0x0000 }, /* R588 */ + { 0x0000, 0x0000 }, /* R589 */ + { 0x0000, 0x0000 }, /* R590 */ + { 0x0000, 0x0000 }, /* R591 */ + { 0x0000, 0x0000 }, /* R592 */ + { 0x0000, 0x0000 }, /* R593 */ + { 0x0000, 0x0000 }, /* R594 */ + { 0x0000, 0x0000 }, /* R595 */ + { 0x0000, 0x0000 }, /* R596 */ + { 0x0000, 0x0000 }, /* R597 */ + { 0x0000, 0x0000 }, /* R598 */ + { 0x0000, 0x0000 }, /* R599 */ + { 0x0000, 0x0000 }, /* R600 */ + { 0x0000, 0x0000 }, /* R601 */ + { 0x0000, 0x0000 }, /* R602 */ + { 0x0000, 0x0000 }, /* R603 */ + { 0x0000, 0x0000 }, /* R604 */ + { 0x0000, 0x0000 }, /* R605 */ + { 0x0000, 0x0000 }, /* R606 */ + { 0x0000, 0x0000 }, /* R607 */ + { 0x0000, 0x0000 }, /* R608 */ + { 0x0000, 0x0000 }, /* R609 */ + { 0x0000, 0x0000 }, /* R610 */ + { 0x0000, 0x0000 }, /* R611 */ + { 0x0000, 0x0000 }, /* R612 */ + { 0x0000, 0x0000 }, /* R613 */ + { 0x0000, 0x0000 }, /* R614 */ + { 0x0000, 0x0000 }, /* R615 */ + { 0x0000, 0x0000 }, /* R616 */ + { 0x0000, 0x0000 }, /* R617 */ + { 0x0000, 0x0000 }, /* R618 */ + { 0x0000, 0x0000 }, /* R619 */ + { 0x0000, 0x0000 }, /* R620 */ + { 0x0000, 0x0000 }, /* R621 */ + { 0x0000, 0x0000 }, /* R622 */ + { 0x0000, 0x0000 }, /* R623 */ + { 0x0000, 0x0000 }, /* R624 */ + { 0x0000, 0x0000 }, /* R625 */ + { 0x0000, 0x0000 }, /* R626 */ + { 0x0000, 0x0000 }, /* R627 */ + { 0x0000, 0x0000 }, /* R628 */ + { 0x0000, 0x0000 }, /* R629 */ + { 0x0000, 0x0000 }, /* R630 */ + { 0x0000, 0x0000 }, /* R631 */ + { 0x0000, 0x0000 }, /* R632 */ + { 0x0000, 0x0000 }, /* R633 */ + { 0x0000, 0x0000 }, /* R634 */ + { 0x0000, 0x0000 }, /* R635 */ + { 0x0000, 0x0000 }, /* R636 */ + { 0x0000, 0x0000 }, /* R637 */ + { 0x0000, 0x0000 }, /* R638 */ + { 0x0000, 0x0000 }, /* R639 */ + { 0x0000, 0x0000 }, /* R640 */ + { 0x0000, 0x0000 }, /* R641 */ + { 0x0000, 0x0000 }, /* R642 */ + { 0x0000, 0x0000 }, /* R643 */ + { 0x0000, 0x0000 }, /* R644 */ + { 0x0000, 0x0000 }, /* R645 */ + { 0x0000, 0x0000 }, /* R646 */ + { 0x0000, 0x0000 }, /* R647 */ + { 0x0000, 0x0000 }, /* R648 */ + { 0x0000, 0x0000 }, /* R649 */ + { 0x0000, 0x0000 }, /* R650 */ + { 0x0000, 0x0000 }, /* R651 */ + { 0x0000, 0x0000 }, /* R652 */ + { 0x0000, 0x0000 }, /* R653 */ + { 0x0000, 0x0000 }, /* R654 */ + { 0x0000, 0x0000 }, /* R655 */ + { 0x0000, 0x0000 }, /* R656 */ + { 0x0000, 0x0000 }, /* R657 */ + { 0x0000, 0x0000 }, /* R658 */ + { 0x0000, 0x0000 }, /* R659 */ + { 0x0000, 0x0000 }, /* R660 */ + { 0x0000, 0x0000 }, /* R661 */ + { 0x0000, 0x0000 }, /* R662 */ + { 0x0000, 0x0000 }, /* R663 */ + { 0x0000, 0x0000 }, /* R664 */ + { 0x0000, 0x0000 }, /* R665 */ + { 0x0000, 0x0000 }, /* R666 */ + { 0x0000, 0x0000 }, /* R667 */ + { 0x0000, 0x0000 }, /* R668 */ + { 0x0000, 0x0000 }, /* R669 */ + { 0x0000, 0x0000 }, /* R670 */ + { 0x0000, 0x0000 }, /* R671 */ + { 0x0000, 0x0000 }, /* R672 */ + { 0x0000, 0x0000 }, /* R673 */ + { 0x0000, 0x0000 }, /* R674 */ + { 0x0000, 0x0000 }, /* R675 */ + { 0x0000, 0x0000 }, /* R676 */ + { 0x0000, 0x0000 }, /* R677 */ + { 0x0000, 0x0000 }, /* R678 */ + { 0x0000, 0x0000 }, /* R679 */ + { 0x0000, 0x0000 }, /* R680 */ + { 0x0000, 0x0000 }, /* R681 */ + { 0x0000, 0x0000 }, /* R682 */ + { 0x0000, 0x0000 }, /* R683 */ + { 0x0000, 0x0000 }, /* R684 */ + { 0x0000, 0x0000 }, /* R685 */ + { 0x0000, 0x0000 }, /* R686 */ + { 0x0000, 0x0000 }, /* R687 */ + { 0x0000, 0x0000 }, /* R688 */ + { 0x0000, 0x0000 }, /* R689 */ + { 0x0000, 0x0000 }, /* R690 */ + { 0x0000, 0x0000 }, /* R691 */ + { 0x0000, 0x0000 }, /* R692 */ + { 0x0000, 0x0000 }, /* R693 */ + { 0x0000, 0x0000 }, /* R694 */ + { 0x0000, 0x0000 }, /* R695 */ + { 0x0000, 0x0000 }, /* R696 */ + { 0x0000, 0x0000 }, /* R697 */ + { 0x0000, 0x0000 }, /* R698 */ + { 0x0000, 0x0000 }, /* R699 */ + { 0x0000, 0x0000 }, /* R700 */ + { 0x0000, 0x0000 }, /* R701 */ + { 0x0000, 0x0000 }, /* R702 */ + { 0x0000, 0x0000 }, /* R703 */ + { 0x0000, 0x0000 }, /* R704 */ + { 0x0000, 0x0000 }, /* R705 */ + { 0x0000, 0x0000 }, /* R706 */ + { 0x0000, 0x0000 }, /* R707 */ + { 0x0000, 0x0000 }, /* R708 */ + { 0x0000, 0x0000 }, /* R709 */ + { 0x0000, 0x0000 }, /* R710 */ + { 0x0000, 0x0000 }, /* R711 */ + { 0x0000, 0x0000 }, /* R712 */ + { 0x0000, 0x0000 }, /* R713 */ + { 0x0000, 0x0000 }, /* R714 */ + { 0x0000, 0x0000 }, /* R715 */ + { 0x0000, 0x0000 }, /* R716 */ + { 0x0000, 0x0000 }, /* R717 */ + { 0x0000, 0x0000 }, /* R718 */ + { 0x0000, 0x0000 }, /* R719 */ + { 0x0000, 0x0000 }, /* R720 */ + { 0x0000, 0x0000 }, /* R721 */ + { 0x0000, 0x0000 }, /* R722 */ + { 0x0000, 0x0000 }, /* R723 */ + { 0x0000, 0x0000 }, /* R724 */ + { 0x0000, 0x0000 }, /* R725 */ + { 0x0000, 0x0000 }, /* R726 */ + { 0x0000, 0x0000 }, /* R727 */ + { 0x0000, 0x0000 }, /* R728 */ + { 0x0000, 0x0000 }, /* R729 */ + { 0x0000, 0x0000 }, /* R730 */ + { 0x0000, 0x0000 }, /* R731 */ + { 0x0000, 0x0000 }, /* R732 */ + { 0x0000, 0x0000 }, /* R733 */ + { 0x0000, 0x0000 }, /* R734 */ + { 0x0000, 0x0000 }, /* R735 */ + { 0x0000, 0x0000 }, /* R736 */ + { 0x0000, 0x0000 }, /* R737 */ + { 0x0000, 0x0000 }, /* R738 */ + { 0x0000, 0x0000 }, /* R739 */ + { 0x0000, 0x0000 }, /* R740 */ + { 0x0000, 0x0000 }, /* R741 */ + { 0x0000, 0x0000 }, /* R742 */ + { 0x0000, 0x0000 }, /* R743 */ + { 0x0000, 0x0000 }, /* R744 */ + { 0x0000, 0x0000 }, /* R745 */ + { 0x0000, 0x0000 }, /* R746 */ + { 0x0000, 0x0000 }, /* R747 */ + { 0x0000, 0x0000 }, /* R748 */ + { 0x0000, 0x0000 }, /* R749 */ + { 0x0000, 0x0000 }, /* R750 */ + { 0x0000, 0x0000 }, /* R751 */ + { 0x0000, 0x0000 }, /* R752 */ + { 0x0000, 0x0000 }, /* R753 */ + { 0x0000, 0x0000 }, /* R754 */ + { 0x0000, 0x0000 }, /* R755 */ + { 0x0000, 0x0000 }, /* R756 */ + { 0x0000, 0x0000 }, /* R757 */ + { 0x0000, 0x0000 }, /* R758 */ + { 0x0000, 0x0000 }, /* R759 */ + { 0x0000, 0x0000 }, /* R760 */ + { 0x0000, 0x0000 }, /* R761 */ + { 0x0000, 0x0000 }, /* R762 */ + { 0x0000, 0x0000 }, /* R763 */ + { 0x0000, 0x0000 }, /* R764 */ + { 0x0000, 0x0000 }, /* R765 */ + { 0x0000, 0x0000 }, /* R766 */ + { 0x0000, 0x0000 }, /* R767 */ + { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */ + { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */ + { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */ + { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */ + { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */ + { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */ + { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */ + { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */ + { 0x0000, 0x0000 }, /* R776 */ + { 0x0000, 0x0000 }, /* R777 */ + { 0x0000, 0x0000 }, /* R778 */ + { 0x0000, 0x0000 }, /* R779 */ + { 0x0000, 0x0000 }, /* R780 */ + { 0x0000, 0x0000 }, /* R781 */ + { 0x0000, 0x0000 }, /* R782 */ + { 0x0000, 0x0000 }, /* R783 */ + { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */ + { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */ + { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */ + { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */ + { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */ + { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */ + { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */ + { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */ + { 0x0000, 0x0000 }, /* R792 */ + { 0x0000, 0x0000 }, /* R793 */ + { 0x0000, 0x0000 }, /* R794 */ + { 0x0000, 0x0000 }, /* R795 */ + { 0x0000, 0x0000 }, /* R796 */ + { 0x0000, 0x0000 }, /* R797 */ + { 0x0000, 0x0000 }, /* R798 */ + { 0x0000, 0x0000 }, /* R799 */ + { 0x0000, 0x0000 }, /* R800 */ + { 0x0000, 0x0000 }, /* R801 */ + { 0x0000, 0x0000 }, /* R802 */ + { 0x0000, 0x0000 }, /* R803 */ + { 0x0000, 0x0000 }, /* R804 */ + { 0x0000, 0x0000 }, /* R805 */ + { 0x0000, 0x0000 }, /* R806 */ + { 0x0000, 0x0000 }, /* R807 */ + { 0x0000, 0x0000 }, /* R808 */ + { 0x0000, 0x0000 }, /* R809 */ + { 0x0000, 0x0000 }, /* R810 */ + { 0x0000, 0x0000 }, /* R811 */ + { 0x0000, 0x0000 }, /* R812 */ + { 0x0000, 0x0000 }, /* R813 */ + { 0x0000, 0x0000 }, /* R814 */ + { 0x0000, 0x0000 }, /* R815 */ + { 0x0000, 0x0000 }, /* R816 */ + { 0x0000, 0x0000 }, /* R817 */ + { 0x0000, 0x0000 }, /* R818 */ + { 0x0000, 0x0000 }, /* R819 */ + { 0x0000, 0x0000 }, /* R820 */ + { 0x0000, 0x0000 }, /* R821 */ + { 0x0000, 0x0000 }, /* R822 */ + { 0x0000, 0x0000 }, /* R823 */ + { 0x0000, 0x0000 }, /* R824 */ + { 0x0000, 0x0000 }, /* R825 */ + { 0x0000, 0x0000 }, /* R826 */ + { 0x0000, 0x0000 }, /* R827 */ + { 0x0000, 0x0000 }, /* R828 */ + { 0x0000, 0x0000 }, /* R829 */ + { 0x0000, 0x0000 }, /* R830 */ + { 0x0000, 0x0000 }, /* R831 */ + { 0x0000, 0x0000 }, /* R832 */ + { 0x0000, 0x0000 }, /* R833 */ + { 0x0000, 0x0000 }, /* R834 */ + { 0x0000, 0x0000 }, /* R835 */ + { 0x0000, 0x0000 }, /* R836 */ + { 0x0000, 0x0000 }, /* R837 */ + { 0x0000, 0x0000 }, /* R838 */ + { 0x0000, 0x0000 }, /* R839 */ + { 0x0000, 0x0000 }, /* R840 */ + { 0x0000, 0x0000 }, /* R841 */ + { 0x0000, 0x0000 }, /* R842 */ + { 0x0000, 0x0000 }, /* R843 */ + { 0x0000, 0x0000 }, /* R844 */ + { 0x0000, 0x0000 }, /* R845 */ + { 0x0000, 0x0000 }, /* R846 */ + { 0x0000, 0x0000 }, /* R847 */ + { 0x0000, 0x0000 }, /* R848 */ + { 0x0000, 0x0000 }, /* R849 */ + { 0x0000, 0x0000 }, /* R850 */ + { 0x0000, 0x0000 }, /* R851 */ + { 0x0000, 0x0000 }, /* R852 */ + { 0x0000, 0x0000 }, /* R853 */ + { 0x0000, 0x0000 }, /* R854 */ + { 0x0000, 0x0000 }, /* R855 */ + { 0x0000, 0x0000 }, /* R856 */ + { 0x0000, 0x0000 }, /* R857 */ + { 0x0000, 0x0000 }, /* R858 */ + { 0x0000, 0x0000 }, /* R859 */ + { 0x0000, 0x0000 }, /* R860 */ + { 0x0000, 0x0000 }, /* R861 */ + { 0x0000, 0x0000 }, /* R862 */ + { 0x0000, 0x0000 }, /* R863 */ + { 0x0000, 0x0000 }, /* R864 */ + { 0x0000, 0x0000 }, /* R865 */ + { 0x0000, 0x0000 }, /* R866 */ + { 0x0000, 0x0000 }, /* R867 */ + { 0x0000, 0x0000 }, /* R868 */ + { 0x0000, 0x0000 }, /* R869 */ + { 0x0000, 0x0000 }, /* R870 */ + { 0x0000, 0x0000 }, /* R871 */ + { 0x0000, 0x0000 }, /* R872 */ + { 0x0000, 0x0000 }, /* R873 */ + { 0x0000, 0x0000 }, /* R874 */ + { 0x0000, 0x0000 }, /* R875 */ + { 0x0000, 0x0000 }, /* R876 */ + { 0x0000, 0x0000 }, /* R877 */ + { 0x0000, 0x0000 }, /* R878 */ + { 0x0000, 0x0000 }, /* R879 */ + { 0x0000, 0x0000 }, /* R880 */ + { 0x0000, 0x0000 }, /* R881 */ + { 0x0000, 0x0000 }, /* R882 */ + { 0x0000, 0x0000 }, /* R883 */ + { 0x0000, 0x0000 }, /* R884 */ + { 0x0000, 0x0000 }, /* R885 */ + { 0x0000, 0x0000 }, /* R886 */ + { 0x0000, 0x0000 }, /* R887 */ + { 0x0000, 0x0000 }, /* R888 */ + { 0x0000, 0x0000 }, /* R889 */ + { 0x0000, 0x0000 }, /* R890 */ + { 0x0000, 0x0000 }, /* R891 */ + { 0x0000, 0x0000 }, /* R892 */ + { 0x0000, 0x0000 }, /* R893 */ + { 0x0000, 0x0000 }, /* R894 */ + { 0x0000, 0x0000 }, /* R895 */ + { 0x0000, 0x0000 }, /* R896 */ + { 0x0000, 0x0000 }, /* R897 */ + { 0x0000, 0x0000 }, /* R898 */ + { 0x0000, 0x0000 }, /* R899 */ + { 0x0000, 0x0000 }, /* R900 */ + { 0x0000, 0x0000 }, /* R901 */ + { 0x0000, 0x0000 }, /* R902 */ + { 0x0000, 0x0000 }, /* R903 */ + { 0x0000, 0x0000 }, /* R904 */ + { 0x0000, 0x0000 }, /* R905 */ + { 0x0000, 0x0000 }, /* R906 */ + { 0x0000, 0x0000 }, /* R907 */ + { 0x0000, 0x0000 }, /* R908 */ + { 0x0000, 0x0000 }, /* R909 */ + { 0x0000, 0x0000 }, /* R910 */ + { 0x0000, 0x0000 }, /* R911 */ + { 0x0000, 0x0000 }, /* R912 */ + { 0x0000, 0x0000 }, /* R913 */ + { 0x0000, 0x0000 }, /* R914 */ + { 0x0000, 0x0000 }, /* R915 */ + { 0x0000, 0x0000 }, /* R916 */ + { 0x0000, 0x0000 }, /* R917 */ + { 0x0000, 0x0000 }, /* R918 */ + { 0x0000, 0x0000 }, /* R919 */ + { 0x0000, 0x0000 }, /* R920 */ + { 0x0000, 0x0000 }, /* R921 */ + { 0x0000, 0x0000 }, /* R922 */ + { 0x0000, 0x0000 }, /* R923 */ + { 0x0000, 0x0000 }, /* R924 */ + { 0x0000, 0x0000 }, /* R925 */ + { 0x0000, 0x0000 }, /* R926 */ + { 0x0000, 0x0000 }, /* R927 */ + { 0x0000, 0x0000 }, /* R928 */ + { 0x0000, 0x0000 }, /* R929 */ + { 0x0000, 0x0000 }, /* R930 */ + { 0x0000, 0x0000 }, /* R931 */ + { 0x0000, 0x0000 }, /* R932 */ + { 0x0000, 0x0000 }, /* R933 */ + { 0x0000, 0x0000 }, /* R934 */ + { 0x0000, 0x0000 }, /* R935 */ + { 0x0000, 0x0000 }, /* R936 */ + { 0x0000, 0x0000 }, /* R937 */ + { 0x0000, 0x0000 }, /* R938 */ + { 0x0000, 0x0000 }, /* R939 */ + { 0x0000, 0x0000 }, /* R940 */ + { 0x0000, 0x0000 }, /* R941 */ + { 0x0000, 0x0000 }, /* R942 */ + { 0x0000, 0x0000 }, /* R943 */ + { 0x0000, 0x0000 }, /* R944 */ + { 0x0000, 0x0000 }, /* R945 */ + { 0x0000, 0x0000 }, /* R946 */ + { 0x0000, 0x0000 }, /* R947 */ + { 0x0000, 0x0000 }, /* R948 */ + { 0x0000, 0x0000 }, /* R949 */ + { 0x0000, 0x0000 }, /* R950 */ + { 0x0000, 0x0000 }, /* R951 */ + { 0x0000, 0x0000 }, /* R952 */ + { 0x0000, 0x0000 }, /* R953 */ + { 0x0000, 0x0000 }, /* R954 */ + { 0x0000, 0x0000 }, /* R955 */ + { 0x0000, 0x0000 }, /* R956 */ + { 0x0000, 0x0000 }, /* R957 */ + { 0x0000, 0x0000 }, /* R958 */ + { 0x0000, 0x0000 }, /* R959 */ + { 0x0000, 0x0000 }, /* R960 */ + { 0x0000, 0x0000 }, /* R961 */ + { 0x0000, 0x0000 }, /* R962 */ + { 0x0000, 0x0000 }, /* R963 */ + { 0x0000, 0x0000 }, /* R964 */ + { 0x0000, 0x0000 }, /* R965 */ + { 0x0000, 0x0000 }, /* R966 */ + { 0x0000, 0x0000 }, /* R967 */ + { 0x0000, 0x0000 }, /* R968 */ + { 0x0000, 0x0000 }, /* R969 */ + { 0x0000, 0x0000 }, /* R970 */ + { 0x0000, 0x0000 }, /* R971 */ + { 0x0000, 0x0000 }, /* R972 */ + { 0x0000, 0x0000 }, /* R973 */ + { 0x0000, 0x0000 }, /* R974 */ + { 0x0000, 0x0000 }, /* R975 */ + { 0x0000, 0x0000 }, /* R976 */ + { 0x0000, 0x0000 }, /* R977 */ + { 0x0000, 0x0000 }, /* R978 */ + { 0x0000, 0x0000 }, /* R979 */ + { 0x0000, 0x0000 }, /* R980 */ + { 0x0000, 0x0000 }, /* R981 */ + { 0x0000, 0x0000 }, /* R982 */ + { 0x0000, 0x0000 }, /* R983 */ + { 0x0000, 0x0000 }, /* R984 */ + { 0x0000, 0x0000 }, /* R985 */ + { 0x0000, 0x0000 }, /* R986 */ + { 0x0000, 0x0000 }, /* R987 */ + { 0x0000, 0x0000 }, /* R988 */ + { 0x0000, 0x0000 }, /* R989 */ + { 0x0000, 0x0000 }, /* R990 */ + { 0x0000, 0x0000 }, /* R991 */ + { 0x0000, 0x0000 }, /* R992 */ + { 0x0000, 0x0000 }, /* R993 */ + { 0x0000, 0x0000 }, /* R994 */ + { 0x0000, 0x0000 }, /* R995 */ + { 0x0000, 0x0000 }, /* R996 */ + { 0x0000, 0x0000 }, /* R997 */ + { 0x0000, 0x0000 }, /* R998 */ + { 0x0000, 0x0000 }, /* R999 */ + { 0x0000, 0x0000 }, /* R1000 */ + { 0x0000, 0x0000 }, /* R1001 */ + { 0x0000, 0x0000 }, /* R1002 */ + { 0x0000, 0x0000 }, /* R1003 */ + { 0x0000, 0x0000 }, /* R1004 */ + { 0x0000, 0x0000 }, /* R1005 */ + { 0x0000, 0x0000 }, /* R1006 */ + { 0x0000, 0x0000 }, /* R1007 */ + { 0x0000, 0x0000 }, /* R1008 */ + { 0x0000, 0x0000 }, /* R1009 */ + { 0x0000, 0x0000 }, /* R1010 */ + { 0x0000, 0x0000 }, /* R1011 */ + { 0x0000, 0x0000 }, /* R1012 */ + { 0x0000, 0x0000 }, /* R1013 */ + { 0x0000, 0x0000 }, /* R1014 */ + { 0x0000, 0x0000 }, /* R1015 */ + { 0x0000, 0x0000 }, /* R1016 */ + { 0x0000, 0x0000 }, /* R1017 */ + { 0x0000, 0x0000 }, /* R1018 */ + { 0x0000, 0x0000 }, /* R1019 */ + { 0x0000, 0x0000 }, /* R1020 */ + { 0x0000, 0x0000 }, /* R1021 */ + { 0x0000, 0x0000 }, /* R1022 */ + { 0x0000, 0x0000 }, /* R1023 */ + { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */ + { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */ + { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */ + { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */ + { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */ + { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */ + { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */ + { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */ + { 0x0000, 0x0000 }, /* R1032 */ + { 0x0000, 0x0000 }, /* R1033 */ + { 0x0000, 0x0000 }, /* R1034 */ + { 0x0000, 0x0000 }, /* R1035 */ + { 0x0000, 0x0000 }, /* R1036 */ + { 0x0000, 0x0000 }, /* R1037 */ + { 0x0000, 0x0000 }, /* R1038 */ + { 0x0000, 0x0000 }, /* R1039 */ + { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */ + { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */ + { 0x0000, 0x0000 }, /* R1042 */ + { 0x0000, 0x0000 }, /* R1043 */ + { 0x0000, 0x0000 }, /* R1044 */ + { 0x0000, 0x0000 }, /* R1045 */ + { 0x0000, 0x0000 }, /* R1046 */ + { 0x0000, 0x0000 }, /* R1047 */ + { 0x0000, 0x0000 }, /* R1048 */ + { 0x0000, 0x0000 }, /* R1049 */ + { 0x0000, 0x0000 }, /* R1050 */ + { 0x0000, 0x0000 }, /* R1051 */ + { 0x0000, 0x0000 }, /* R1052 */ + { 0x0000, 0x0000 }, /* R1053 */ + { 0x0000, 0x0000 }, /* R1054 */ + { 0x0000, 0x0000 }, /* R1055 */ + { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */ + { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */ + { 0x0000, 0x0000 }, /* R1060 */ + { 0x0000, 0x0000 }, /* R1061 */ + { 0x0000, 0x0000 }, /* R1062 */ + { 0x0000, 0x0000 }, /* R1063 */ + { 0x0000, 0x0000 }, /* R1064 */ + { 0x0000, 0x0000 }, /* R1065 */ + { 0x0000, 0x0000 }, /* R1066 */ + { 0x0000, 0x0000 }, /* R1067 */ + { 0x0000, 0x0000 }, /* R1068 */ + { 0x0000, 0x0000 }, /* R1069 */ + { 0x0000, 0x0000 }, /* R1070 */ + { 0x0000, 0x0000 }, /* R1071 */ + { 0x0000, 0x0000 }, /* R1072 */ + { 0x0000, 0x0000 }, /* R1073 */ + { 0x0000, 0x0000 }, /* R1074 */ + { 0x0000, 0x0000 }, /* R1075 */ + { 0x0000, 0x0000 }, /* R1076 */ + { 0x0000, 0x0000 }, /* R1077 */ + { 0x0000, 0x0000 }, /* R1078 */ + { 0x0000, 0x0000 }, /* R1079 */ + { 0x0000, 0x0000 }, /* R1080 */ + { 0x0000, 0x0000 }, /* R1081 */ + { 0x0000, 0x0000 }, /* R1082 */ + { 0x0000, 0x0000 }, /* R1083 */ + { 0x0000, 0x0000 }, /* R1084 */ + { 0x0000, 0x0000 }, /* R1085 */ + { 0x0000, 0x0000 }, /* R1086 */ + { 0x0000, 0x0000 }, /* R1087 */ + { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */ + { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */ + { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */ + { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */ + { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */ + { 0x0000, 0x0000 }, /* R1093 */ + { 0x0000, 0x0000 }, /* R1094 */ + { 0x0000, 0x0000 }, /* R1095 */ + { 0x0000, 0x0000 }, /* R1096 */ + { 0x0000, 0x0000 }, /* R1097 */ + { 0x0000, 0x0000 }, /* R1098 */ + { 0x0000, 0x0000 }, /* R1099 */ + { 0x0000, 0x0000 }, /* R1100 */ + { 0x0000, 0x0000 }, /* R1101 */ + { 0x0000, 0x0000 }, /* R1102 */ + { 0x0000, 0x0000 }, /* R1103 */ + { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */ + { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */ + { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */ + { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */ + { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */ + { 0x0000, 0x0000 }, /* R1109 */ + { 0x0000, 0x0000 }, /* R1110 */ + { 0x0000, 0x0000 }, /* R1111 */ + { 0x0000, 0x0000 }, /* R1112 */ + { 0x0000, 0x0000 }, /* R1113 */ + { 0x0000, 0x0000 }, /* R1114 */ + { 0x0000, 0x0000 }, /* R1115 */ + { 0x0000, 0x0000 }, /* R1116 */ + { 0x0000, 0x0000 }, /* R1117 */ + { 0x0000, 0x0000 }, /* R1118 */ + { 0x0000, 0x0000 }, /* R1119 */ + { 0x0000, 0x0000 }, /* R1120 */ + { 0x0000, 0x0000 }, /* R1121 */ + { 0x0000, 0x0000 }, /* R1122 */ + { 0x0000, 0x0000 }, /* R1123 */ + { 0x0000, 0x0000 }, /* R1124 */ + { 0x0000, 0x0000 }, /* R1125 */ + { 0x0000, 0x0000 }, /* R1126 */ + { 0x0000, 0x0000 }, /* R1127 */ + { 0x0000, 0x0000 }, /* R1128 */ + { 0x0000, 0x0000 }, /* R1129 */ + { 0x0000, 0x0000 }, /* R1130 */ + { 0x0000, 0x0000 }, /* R1131 */ + { 0x0000, 0x0000 }, /* R1132 */ + { 0x0000, 0x0000 }, /* R1133 */ + { 0x0000, 0x0000 }, /* R1134 */ + { 0x0000, 0x0000 }, /* R1135 */ + { 0x0000, 0x0000 }, /* R1136 */ + { 0x0000, 0x0000 }, /* R1137 */ + { 0x0000, 0x0000 }, /* R1138 */ + { 0x0000, 0x0000 }, /* R1139 */ + { 0x0000, 0x0000 }, /* R1140 */ + { 0x0000, 0x0000 }, /* R1141 */ + { 0x0000, 0x0000 }, /* R1142 */ + { 0x0000, 0x0000 }, /* R1143 */ + { 0x0000, 0x0000 }, /* R1144 */ + { 0x0000, 0x0000 }, /* R1145 */ + { 0x0000, 0x0000 }, /* R1146 */ + { 0x0000, 0x0000 }, /* R1147 */ + { 0x0000, 0x0000 }, /* R1148 */ + { 0x0000, 0x0000 }, /* R1149 */ + { 0x0000, 0x0000 }, /* R1150 */ + { 0x0000, 0x0000 }, /* R1151 */ + { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1172 */ + { 0x0000, 0x0000 }, /* R1173 */ + { 0x0000, 0x0000 }, /* R1174 */ + { 0x0000, 0x0000 }, /* R1175 */ + { 0x0000, 0x0000 }, /* R1176 */ + { 0x0000, 0x0000 }, /* R1177 */ + { 0x0000, 0x0000 }, /* R1178 */ + { 0x0000, 0x0000 }, /* R1179 */ + { 0x0000, 0x0000 }, /* R1180 */ + { 0x0000, 0x0000 }, /* R1181 */ + { 0x0000, 0x0000 }, /* R1182 */ + { 0x0000, 0x0000 }, /* R1183 */ + { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1204 */ + { 0x0000, 0x0000 }, /* R1205 */ + { 0x0000, 0x0000 }, /* R1206 */ + { 0x0000, 0x0000 }, /* R1207 */ + { 0x0000, 0x0000 }, /* R1208 */ + { 0x0000, 0x0000 }, /* R1209 */ + { 0x0000, 0x0000 }, /* R1210 */ + { 0x0000, 0x0000 }, /* R1211 */ + { 0x0000, 0x0000 }, /* R1212 */ + { 0x0000, 0x0000 }, /* R1213 */ + { 0x0000, 0x0000 }, /* R1214 */ + { 0x0000, 0x0000 }, /* R1215 */ + { 0x0000, 0x0000 }, /* R1216 */ + { 0x0000, 0x0000 }, /* R1217 */ + { 0x0000, 0x0000 }, /* R1218 */ + { 0x0000, 0x0000 }, /* R1219 */ + { 0x0000, 0x0000 }, /* R1220 */ + { 0x0000, 0x0000 }, /* R1221 */ + { 0x0000, 0x0000 }, /* R1222 */ + { 0x0000, 0x0000 }, /* R1223 */ + { 0x0000, 0x0000 }, /* R1224 */ + { 0x0000, 0x0000 }, /* R1225 */ + { 0x0000, 0x0000 }, /* R1226 */ + { 0x0000, 0x0000 }, /* R1227 */ + { 0x0000, 0x0000 }, /* R1228 */ + { 0x0000, 0x0000 }, /* R1229 */ + { 0x0000, 0x0000 }, /* R1230 */ + { 0x0000, 0x0000 }, /* R1231 */ + { 0x0000, 0x0000 }, /* R1232 */ + { 0x0000, 0x0000 }, /* R1233 */ + { 0x0000, 0x0000 }, /* R1234 */ + { 0x0000, 0x0000 }, /* R1235 */ + { 0x0000, 0x0000 }, /* R1236 */ + { 0x0000, 0x0000 }, /* R1237 */ + { 0x0000, 0x0000 }, /* R1238 */ + { 0x0000, 0x0000 }, /* R1239 */ + { 0x0000, 0x0000 }, /* R1240 */ + { 0x0000, 0x0000 }, /* R1241 */ + { 0x0000, 0x0000 }, /* R1242 */ + { 0x0000, 0x0000 }, /* R1243 */ + { 0x0000, 0x0000 }, /* R1244 */ + { 0x0000, 0x0000 }, /* R1245 */ + { 0x0000, 0x0000 }, /* R1246 */ + { 0x0000, 0x0000 }, /* R1247 */ + { 0x0000, 0x0000 }, /* R1248 */ + { 0x0000, 0x0000 }, /* R1249 */ + { 0x0000, 0x0000 }, /* R1250 */ + { 0x0000, 0x0000 }, /* R1251 */ + { 0x0000, 0x0000 }, /* R1252 */ + { 0x0000, 0x0000 }, /* R1253 */ + { 0x0000, 0x0000 }, /* R1254 */ + { 0x0000, 0x0000 }, /* R1255 */ + { 0x0000, 0x0000 }, /* R1256 */ + { 0x0000, 0x0000 }, /* R1257 */ + { 0x0000, 0x0000 }, /* R1258 */ + { 0x0000, 0x0000 }, /* R1259 */ + { 0x0000, 0x0000 }, /* R1260 */ + { 0x0000, 0x0000 }, /* R1261 */ + { 0x0000, 0x0000 }, /* R1262 */ + { 0x0000, 0x0000 }, /* R1263 */ + { 0x0000, 0x0000 }, /* R1264 */ + { 0x0000, 0x0000 }, /* R1265 */ + { 0x0000, 0x0000 }, /* R1266 */ + { 0x0000, 0x0000 }, /* R1267 */ + { 0x0000, 0x0000 }, /* R1268 */ + { 0x0000, 0x0000 }, /* R1269 */ + { 0x0000, 0x0000 }, /* R1270 */ + { 0x0000, 0x0000 }, /* R1271 */ + { 0x0000, 0x0000 }, /* R1272 */ + { 0x0000, 0x0000 }, /* R1273 */ + { 0x0000, 0x0000 }, /* R1274 */ + { 0x0000, 0x0000 }, /* R1275 */ + { 0x0000, 0x0000 }, /* R1276 */ + { 0x0000, 0x0000 }, /* R1277 */ + { 0x0000, 0x0000 }, /* R1278 */ + { 0x0000, 0x0000 }, /* R1279 */ + { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */ + { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */ + { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */ + { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */ + { 0x0000, 0x0000 }, /* R1284 */ + { 0x0000, 0x0000 }, /* R1285 */ + { 0x0000, 0x0000 }, /* R1286 */ + { 0x0000, 0x0000 }, /* R1287 */ + { 0x0000, 0x0000 }, /* R1288 */ + { 0x0000, 0x0000 }, /* R1289 */ + { 0x0000, 0x0000 }, /* R1290 */ + { 0x0000, 0x0000 }, /* R1291 */ + { 0x0000, 0x0000 }, /* R1292 */ + { 0x0000, 0x0000 }, /* R1293 */ + { 0x0000, 0x0000 }, /* R1294 */ + { 0x0000, 0x0000 }, /* R1295 */ + { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */ + { 0x0000, 0x0000 }, /* R1297 */ + { 0x0000, 0x0000 }, /* R1298 */ + { 0x0000, 0x0000 }, /* R1299 */ + { 0x0000, 0x0000 }, /* R1300 */ + { 0x0000, 0x0000 }, /* R1301 */ + { 0x0000, 0x0000 }, /* R1302 */ + { 0x0000, 0x0000 }, /* R1303 */ + { 0x0000, 0x0000 }, /* R1304 */ + { 0x0000, 0x0000 }, /* R1305 */ + { 0x0000, 0x0000 }, /* R1306 */ + { 0x0000, 0x0000 }, /* R1307 */ + { 0x0000, 0x0000 }, /* R1308 */ + { 0x0000, 0x0000 }, /* R1309 */ + { 0x0000, 0x0000 }, /* R1310 */ + { 0x0000, 0x0000 }, /* R1311 */ + { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */ + { 0x0000, 0x0000 }, /* R1314 */ + { 0x0000, 0x0000 }, /* R1315 */ + { 0x0000, 0x0000 }, /* R1316 */ + { 0x0000, 0x0000 }, /* R1317 */ + { 0x0000, 0x0000 }, /* R1318 */ + { 0x0000, 0x0000 }, /* R1319 */ + { 0x0000, 0x0000 }, /* R1320 */ + { 0x0000, 0x0000 }, /* R1321 */ + { 0x0000, 0x0000 }, /* R1322 */ + { 0x0000, 0x0000 }, /* R1323 */ + { 0x0000, 0x0000 }, /* R1324 */ + { 0x0000, 0x0000 }, /* R1325 */ + { 0x0000, 0x0000 }, /* R1326 */ + { 0x0000, 0x0000 }, /* R1327 */ + { 0x0000, 0x0000 }, /* R1328 */ + { 0x0000, 0x0000 }, /* R1329 */ + { 0x0000, 0x0000 }, /* R1330 */ + { 0x0000, 0x0000 }, /* R1331 */ + { 0x0000, 0x0000 }, /* R1332 */ + { 0x0000, 0x0000 }, /* R1333 */ + { 0x0000, 0x0000 }, /* R1334 */ + { 0x0000, 0x0000 }, /* R1335 */ + { 0x0000, 0x0000 }, /* R1336 */ + { 0x0000, 0x0000 }, /* R1337 */ + { 0x0000, 0x0000 }, /* R1338 */ + { 0x0000, 0x0000 }, /* R1339 */ + { 0x0000, 0x0000 }, /* R1340 */ + { 0x0000, 0x0000 }, /* R1341 */ + { 0x0000, 0x0000 }, /* R1342 */ + { 0x0000, 0x0000 }, /* R1343 */ + { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */ + { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */ + { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */ + { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */ + { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */ + { 0x0000, 0x0000 }, /* R1349 */ + { 0x0000, 0x0000 }, /* R1350 */ + { 0x0000, 0x0000 }, /* R1351 */ + { 0x0000, 0x0000 }, /* R1352 */ + { 0x0000, 0x0000 }, /* R1353 */ + { 0x0000, 0x0000 }, /* R1354 */ + { 0x0000, 0x0000 }, /* R1355 */ + { 0x0000, 0x0000 }, /* R1356 */ + { 0x0000, 0x0000 }, /* R1357 */ + { 0x0000, 0x0000 }, /* R1358 */ + { 0x0000, 0x0000 }, /* R1359 */ + { 0x0000, 0x0000 }, /* R1360 */ + { 0x0000, 0x0000 }, /* R1361 */ + { 0x0000, 0x0000 }, /* R1362 */ + { 0x0000, 0x0000 }, /* R1363 */ + { 0x0000, 0x0000 }, /* R1364 */ + { 0x0000, 0x0000 }, /* R1365 */ + { 0x0000, 0x0000 }, /* R1366 */ + { 0x0000, 0x0000 }, /* R1367 */ + { 0x0000, 0x0000 }, /* R1368 */ + { 0x0000, 0x0000 }, /* R1369 */ + { 0x0000, 0x0000 }, /* R1370 */ + { 0x0000, 0x0000 }, /* R1371 */ + { 0x0000, 0x0000 }, /* R1372 */ + { 0x0000, 0x0000 }, /* R1373 */ + { 0x0000, 0x0000 }, /* R1374 */ + { 0x0000, 0x0000 }, /* R1375 */ + { 0x0000, 0x0000 }, /* R1376 */ + { 0x0000, 0x0000 }, /* R1377 */ + { 0x0000, 0x0000 }, /* R1378 */ + { 0x0000, 0x0000 }, /* R1379 */ + { 0x0000, 0x0000 }, /* R1380 */ + { 0x0000, 0x0000 }, /* R1381 */ + { 0x0000, 0x0000 }, /* R1382 */ + { 0x0000, 0x0000 }, /* R1383 */ + { 0x0000, 0x0000 }, /* R1384 */ + { 0x0000, 0x0000 }, /* R1385 */ + { 0x0000, 0x0000 }, /* R1386 */ + { 0x0000, 0x0000 }, /* R1387 */ + { 0x0000, 0x0000 }, /* R1388 */ + { 0x0000, 0x0000 }, /* R1389 */ + { 0x0000, 0x0000 }, /* R1390 */ + { 0x0000, 0x0000 }, /* R1391 */ + { 0x0000, 0x0000 }, /* R1392 */ + { 0x0000, 0x0000 }, /* R1393 */ + { 0x0000, 0x0000 }, /* R1394 */ + { 0x0000, 0x0000 }, /* R1395 */ + { 0x0000, 0x0000 }, /* R1396 */ + { 0x0000, 0x0000 }, /* R1397 */ + { 0x0000, 0x0000 }, /* R1398 */ + { 0x0000, 0x0000 }, /* R1399 */ + { 0x0000, 0x0000 }, /* R1400 */ + { 0x0000, 0x0000 }, /* R1401 */ + { 0x0000, 0x0000 }, /* R1402 */ + { 0x0000, 0x0000 }, /* R1403 */ + { 0x0000, 0x0000 }, /* R1404 */ + { 0x0000, 0x0000 }, /* R1405 */ + { 0x0000, 0x0000 }, /* R1406 */ + { 0x0000, 0x0000 }, /* R1407 */ + { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1428 */ + { 0x0000, 0x0000 }, /* R1429 */ + { 0x0000, 0x0000 }, /* R1430 */ + { 0x0000, 0x0000 }, /* R1431 */ + { 0x0000, 0x0000 }, /* R1432 */ + { 0x0000, 0x0000 }, /* R1433 */ + { 0x0000, 0x0000 }, /* R1434 */ + { 0x0000, 0x0000 }, /* R1435 */ + { 0x0000, 0x0000 }, /* R1436 */ + { 0x0000, 0x0000 }, /* R1437 */ + { 0x0000, 0x0000 }, /* R1438 */ + { 0x0000, 0x0000 }, /* R1439 */ + { 0x0000, 0x0000 }, /* R1440 */ + { 0x0000, 0x0000 }, /* R1441 */ + { 0x0000, 0x0000 }, /* R1442 */ + { 0x0000, 0x0000 }, /* R1443 */ + { 0x0000, 0x0000 }, /* R1444 */ + { 0x0000, 0x0000 }, /* R1445 */ + { 0x0000, 0x0000 }, /* R1446 */ + { 0x0000, 0x0000 }, /* R1447 */ + { 0x0000, 0x0000 }, /* R1448 */ + { 0x0000, 0x0000 }, /* R1449 */ + { 0x0000, 0x0000 }, /* R1450 */ + { 0x0000, 0x0000 }, /* R1451 */ + { 0x0000, 0x0000 }, /* R1452 */ + { 0x0000, 0x0000 }, /* R1453 */ + { 0x0000, 0x0000 }, /* R1454 */ + { 0x0000, 0x0000 }, /* R1455 */ + { 0x0000, 0x0000 }, /* R1456 */ + { 0x0000, 0x0000 }, /* R1457 */ + { 0x0000, 0x0000 }, /* R1458 */ + { 0x0000, 0x0000 }, /* R1459 */ + { 0x0000, 0x0000 }, /* R1460 */ + { 0x0000, 0x0000 }, /* R1461 */ + { 0x0000, 0x0000 }, /* R1462 */ + { 0x0000, 0x0000 }, /* R1463 */ + { 0x0000, 0x0000 }, /* R1464 */ + { 0x0000, 0x0000 }, /* R1465 */ + { 0x0000, 0x0000 }, /* R1466 */ + { 0x0000, 0x0000 }, /* R1467 */ + { 0x0000, 0x0000 }, /* R1468 */ + { 0x0000, 0x0000 }, /* R1469 */ + { 0x0000, 0x0000 }, /* R1470 */ + { 0x0000, 0x0000 }, /* R1471 */ + { 0x0000, 0x0000 }, /* R1472 */ + { 0x0000, 0x0000 }, /* R1473 */ + { 0x0000, 0x0000 }, /* R1474 */ + { 0x0000, 0x0000 }, /* R1475 */ + { 0x0000, 0x0000 }, /* R1476 */ + { 0x0000, 0x0000 }, /* R1477 */ + { 0x0000, 0x0000 }, /* R1478 */ + { 0x0000, 0x0000 }, /* R1479 */ + { 0x0000, 0x0000 }, /* R1480 */ + { 0x0000, 0x0000 }, /* R1481 */ + { 0x0000, 0x0000 }, /* R1482 */ + { 0x0000, 0x0000 }, /* R1483 */ + { 0x0000, 0x0000 }, /* R1484 */ + { 0x0000, 0x0000 }, /* R1485 */ + { 0x0000, 0x0000 }, /* R1486 */ + { 0x0000, 0x0000 }, /* R1487 */ + { 0x0000, 0x0000 }, /* R1488 */ + { 0x0000, 0x0000 }, /* R1489 */ + { 0x0000, 0x0000 }, /* R1490 */ + { 0x0000, 0x0000 }, /* R1491 */ + { 0x0000, 0x0000 }, /* R1492 */ + { 0x0000, 0x0000 }, /* R1493 */ + { 0x0000, 0x0000 }, /* R1494 */ + { 0x0000, 0x0000 }, /* R1495 */ + { 0x0000, 0x0000 }, /* R1496 */ + { 0x0000, 0x0000 }, /* R1497 */ + { 0x0000, 0x0000 }, /* R1498 */ + { 0x0000, 0x0000 }, /* R1499 */ + { 0x0000, 0x0000 }, /* R1500 */ + { 0x0000, 0x0000 }, /* R1501 */ + { 0x0000, 0x0000 }, /* R1502 */ + { 0x0000, 0x0000 }, /* R1503 */ + { 0x0000, 0x0000 }, /* R1504 */ + { 0x0000, 0x0000 }, /* R1505 */ + { 0x0000, 0x0000 }, /* R1506 */ + { 0x0000, 0x0000 }, /* R1507 */ + { 0x0000, 0x0000 }, /* R1508 */ + { 0x0000, 0x0000 }, /* R1509 */ + { 0x0000, 0x0000 }, /* R1510 */ + { 0x0000, 0x0000 }, /* R1511 */ + { 0x0000, 0x0000 }, /* R1512 */ + { 0x0000, 0x0000 }, /* R1513 */ + { 0x0000, 0x0000 }, /* R1514 */ + { 0x0000, 0x0000 }, /* R1515 */ + { 0x0000, 0x0000 }, /* R1516 */ + { 0x0000, 0x0000 }, /* R1517 */ + { 0x0000, 0x0000 }, /* R1518 */ + { 0x0000, 0x0000 }, /* R1519 */ + { 0x0000, 0x0000 }, /* R1520 */ + { 0x0000, 0x0000 }, /* R1521 */ + { 0x0000, 0x0000 }, /* R1522 */ + { 0x0000, 0x0000 }, /* R1523 */ + { 0x0000, 0x0000 }, /* R1524 */ + { 0x0000, 0x0000 }, /* R1525 */ + { 0x0000, 0x0000 }, /* R1526 */ + { 0x0000, 0x0000 }, /* R1527 */ + { 0x0000, 0x0000 }, /* R1528 */ + { 0x0000, 0x0000 }, /* R1529 */ + { 0x0000, 0x0000 }, /* R1530 */ + { 0x0000, 0x0000 }, /* R1531 */ + { 0x0000, 0x0000 }, /* R1532 */ + { 0x0000, 0x0000 }, /* R1533 */ + { 0x0000, 0x0000 }, /* R1534 */ + { 0x0000, 0x0000 }, /* R1535 */ + { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */ + { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */ + { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */ + { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */ + { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */ + { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */ + { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ + { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ + { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ + { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ + { 0x0000, 0x0000 }, /* R1546 */ + { 0x0000, 0x0000 }, /* R1547 */ + { 0x0000, 0x0000 }, /* R1548 */ + { 0x0000, 0x0000 }, /* R1549 */ + { 0x0000, 0x0000 }, /* R1550 */ + { 0x0000, 0x0000 }, /* R1551 */ + { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */ + { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */ + { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */ + { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */ + { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */ + { 0x0000, 0x0000 }, /* R1557 */ + { 0x0000, 0x0000 }, /* R1558 */ + { 0x0000, 0x0000 }, /* R1559 */ + { 0x0000, 0x0000 }, /* R1560 */ + { 0x0000, 0x0000 }, /* R1561 */ + { 0x0000, 0x0000 }, /* R1562 */ + { 0x0000, 0x0000 }, /* R1563 */ + { 0x0000, 0x0000 }, /* R1564 */ + { 0x0000, 0x0000 }, /* R1565 */ + { 0x0000, 0x0000 }, /* R1566 */ + { 0x0000, 0x0000 }, /* R1567 */ + { 0x0003, 0x0003 }, /* R1568 - Oversampling */ + { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ +}; + diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 4d3e6f1..2833994 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -24,7 +24,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -98,1582 +97,6 @@ struct wm8994_priv { struct wm8994_pdata *pdata; }; -static const struct { - unsigned short readable; /* Mask of readable bits */ - unsigned short writable; /* Mask of writable bits */ -} access_masks[] = { - { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */ - { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */ - { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */ - { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */ - { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */ - { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */ - { 0x003F, 0x003F }, /* R6 - Power Management (6) */ - { 0x0000, 0x0000 }, /* R7 */ - { 0x0000, 0x0000 }, /* R8 */ - { 0x0000, 0x0000 }, /* R9 */ - { 0x0000, 0x0000 }, /* R10 */ - { 0x0000, 0x0000 }, /* R11 */ - { 0x0000, 0x0000 }, /* R12 */ - { 0x0000, 0x0000 }, /* R13 */ - { 0x0000, 0x0000 }, /* R14 */ - { 0x0000, 0x0000 }, /* R15 */ - { 0x0000, 0x0000 }, /* R16 */ - { 0x0000, 0x0000 }, /* R17 */ - { 0x0000, 0x0000 }, /* R18 */ - { 0x0000, 0x0000 }, /* R19 */ - { 0x0000, 0x0000 }, /* R20 */ - { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */ - { 0x0000, 0x0000 }, /* R22 */ - { 0x0000, 0x0000 }, /* R23 */ - { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */ - { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */ - { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */ - { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */ - { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */ - { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */ - { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */ - { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */ - { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */ - { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */ - { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */ - { 0x003F, 0x003F }, /* R37 - ClassD */ - { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */ - { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */ - { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */ - { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */ - { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */ - { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */ - { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */ - { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */ - { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */ - { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */ - { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */ - { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */ - { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */ - { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */ - { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */ - { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */ - { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */ - { 0x00C1, 0x00C1 }, /* R55 - Additional Control */ - { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */ - { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */ - { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ - { 0x000F, 0x000F }, /* R59 - LDO 1 */ - { 0x0007, 0x0007 }, /* R60 - LDO 2 */ - { 0x0000, 0x0000 }, /* R61 */ - { 0x0000, 0x0000 }, /* R62 */ - { 0x0000, 0x0000 }, /* R63 */ - { 0x0000, 0x0000 }, /* R64 */ - { 0x0000, 0x0000 }, /* R65 */ - { 0x0000, 0x0000 }, /* R66 */ - { 0x0000, 0x0000 }, /* R67 */ - { 0x0000, 0x0000 }, /* R68 */ - { 0x0000, 0x0000 }, /* R69 */ - { 0x0000, 0x0000 }, /* R70 */ - { 0x0000, 0x0000 }, /* R71 */ - { 0x0000, 0x0000 }, /* R72 */ - { 0x0000, 0x0000 }, /* R73 */ - { 0x0000, 0x0000 }, /* R74 */ - { 0x0000, 0x0000 }, /* R75 */ - { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ - { 0x0000, 0x0000 }, /* R77 */ - { 0x0000, 0x0000 }, /* R78 */ - { 0x0000, 0x0000 }, /* R79 */ - { 0x0000, 0x0000 }, /* R80 */ - { 0x0301, 0x0301 }, /* R81 - Class W (1) */ - { 0x0000, 0x0000 }, /* R82 */ - { 0x0000, 0x0000 }, /* R83 */ - { 0x333F, 0x333F }, /* R84 - DC Servo (1) */ - { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */ - { 0x0000, 0x0000 }, /* R86 */ - { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */ - { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */ - { 0x0000, 0x0000 }, /* R89 */ - { 0x0000, 0x0000 }, /* R90 */ - { 0x0000, 0x0000 }, /* R91 */ - { 0x0000, 0x0000 }, /* R92 */ - { 0x0000, 0x0000 }, /* R93 */ - { 0x0000, 0x0000 }, /* R94 */ - { 0x0000, 0x0000 }, /* R95 */ - { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */ - { 0x0000, 0x0000 }, /* R97 */ - { 0x0000, 0x0000 }, /* R98 */ - { 0x0000, 0x0000 }, /* R99 */ - { 0x0000, 0x0000 }, /* R100 */ - { 0x0000, 0x0000 }, /* R101 */ - { 0x0000, 0x0000 }, /* R102 */ - { 0x0000, 0x0000 }, /* R103 */ - { 0x0000, 0x0000 }, /* R104 */ - { 0x0000, 0x0000 }, /* R105 */ - { 0x0000, 0x0000 }, /* R106 */ - { 0x0000, 0x0000 }, /* R107 */ - { 0x0000, 0x0000 }, /* R108 */ - { 0x0000, 0x0000 }, /* R109 */ - { 0x0000, 0x0000 }, /* R110 */ - { 0x0000, 0x0000 }, /* R111 */ - { 0x0000, 0x0000 }, /* R112 */ - { 0x0000, 0x0000 }, /* R113 */ - { 0x0000, 0x0000 }, /* R114 */ - { 0x0000, 0x0000 }, /* R115 */ - { 0x0000, 0x0000 }, /* R116 */ - { 0x0000, 0x0000 }, /* R117 */ - { 0x0000, 0x0000 }, /* R118 */ - { 0x0000, 0x0000 }, /* R119 */ - { 0x0000, 0x0000 }, /* R120 */ - { 0x0000, 0x0000 }, /* R121 */ - { 0x0000, 0x0000 }, /* R122 */ - { 0x0000, 0x0000 }, /* R123 */ - { 0x0000, 0x0000 }, /* R124 */ - { 0x0000, 0x0000 }, /* R125 */ - { 0x0000, 0x0000 }, /* R126 */ - { 0x0000, 0x0000 }, /* R127 */ - { 0x0000, 0x0000 }, /* R128 */ - { 0x0000, 0x0000 }, /* R129 */ - { 0x0000, 0x0000 }, /* R130 */ - { 0x0000, 0x0000 }, /* R131 */ - { 0x0000, 0x0000 }, /* R132 */ - { 0x0000, 0x0000 }, /* R133 */ - { 0x0000, 0x0000 }, /* R134 */ - { 0x0000, 0x0000 }, /* R135 */ - { 0x0000, 0x0000 }, /* R136 */ - { 0x0000, 0x0000 }, /* R137 */ - { 0x0000, 0x0000 }, /* R138 */ - { 0x0000, 0x0000 }, /* R139 */ - { 0x0000, 0x0000 }, /* R140 */ - { 0x0000, 0x0000 }, /* R141 */ - { 0x0000, 0x0000 }, /* R142 */ - { 0x0000, 0x0000 }, /* R143 */ - { 0x0000, 0x0000 }, /* R144 */ - { 0x0000, 0x0000 }, /* R145 */ - { 0x0000, 0x0000 }, /* R146 */ - { 0x0000, 0x0000 }, /* R147 */ - { 0x0000, 0x0000 }, /* R148 */ - { 0x0000, 0x0000 }, /* R149 */ - { 0x0000, 0x0000 }, /* R150 */ - { 0x0000, 0x0000 }, /* R151 */ - { 0x0000, 0x0000 }, /* R152 */ - { 0x0000, 0x0000 }, /* R153 */ - { 0x0000, 0x0000 }, /* R154 */ - { 0x0000, 0x0000 }, /* R155 */ - { 0x0000, 0x0000 }, /* R156 */ - { 0x0000, 0x0000 }, /* R157 */ - { 0x0000, 0x0000 }, /* R158 */ - { 0x0000, 0x0000 }, /* R159 */ - { 0x0000, 0x0000 }, /* R160 */ - { 0x0000, 0x0000 }, /* R161 */ - { 0x0000, 0x0000 }, /* R162 */ - { 0x0000, 0x0000 }, /* R163 */ - { 0x0000, 0x0000 }, /* R164 */ - { 0x0000, 0x0000 }, /* R165 */ - { 0x0000, 0x0000 }, /* R166 */ - { 0x0000, 0x0000 }, /* R167 */ - { 0x0000, 0x0000 }, /* R168 */ - { 0x0000, 0x0000 }, /* R169 */ - { 0x0000, 0x0000 }, /* R170 */ - { 0x0000, 0x0000 }, /* R171 */ - { 0x0000, 0x0000 }, /* R172 */ - { 0x0000, 0x0000 }, /* R173 */ - { 0x0000, 0x0000 }, /* R174 */ - { 0x0000, 0x0000 }, /* R175 */ - { 0x0000, 0x0000 }, /* R176 */ - { 0x0000, 0x0000 }, /* R177 */ - { 0x0000, 0x0000 }, /* R178 */ - { 0x0000, 0x0000 }, /* R179 */ - { 0x0000, 0x0000 }, /* R180 */ - { 0x0000, 0x0000 }, /* R181 */ - { 0x0000, 0x0000 }, /* R182 */ - { 0x0000, 0x0000 }, /* R183 */ - { 0x0000, 0x0000 }, /* R184 */ - { 0x0000, 0x0000 }, /* R185 */ - { 0x0000, 0x0000 }, /* R186 */ - { 0x0000, 0x0000 }, /* R187 */ - { 0x0000, 0x0000 }, /* R188 */ - { 0x0000, 0x0000 }, /* R189 */ - { 0x0000, 0x0000 }, /* R190 */ - { 0x0000, 0x0000 }, /* R191 */ - { 0x0000, 0x0000 }, /* R192 */ - { 0x0000, 0x0000 }, /* R193 */ - { 0x0000, 0x0000 }, /* R194 */ - { 0x0000, 0x0000 }, /* R195 */ - { 0x0000, 0x0000 }, /* R196 */ - { 0x0000, 0x0000 }, /* R197 */ - { 0x0000, 0x0000 }, /* R198 */ - { 0x0000, 0x0000 }, /* R199 */ - { 0x0000, 0x0000 }, /* R200 */ - { 0x0000, 0x0000 }, /* R201 */ - { 0x0000, 0x0000 }, /* R202 */ - { 0x0000, 0x0000 }, /* R203 */ - { 0x0000, 0x0000 }, /* R204 */ - { 0x0000, 0x0000 }, /* R205 */ - { 0x0000, 0x0000 }, /* R206 */ - { 0x0000, 0x0000 }, /* R207 */ - { 0x0000, 0x0000 }, /* R208 */ - { 0x0000, 0x0000 }, /* R209 */ - { 0x0000, 0x0000 }, /* R210 */ - { 0x0000, 0x0000 }, /* R211 */ - { 0x0000, 0x0000 }, /* R212 */ - { 0x0000, 0x0000 }, /* R213 */ - { 0x0000, 0x0000 }, /* R214 */ - { 0x0000, 0x0000 }, /* R215 */ - { 0x0000, 0x0000 }, /* R216 */ - { 0x0000, 0x0000 }, /* R217 */ - { 0x0000, 0x0000 }, /* R218 */ - { 0x0000, 0x0000 }, /* R219 */ - { 0x0000, 0x0000 }, /* R220 */ - { 0x0000, 0x0000 }, /* R221 */ - { 0x0000, 0x0000 }, /* R222 */ - { 0x0000, 0x0000 }, /* R223 */ - { 0x0000, 0x0000 }, /* R224 */ - { 0x0000, 0x0000 }, /* R225 */ - { 0x0000, 0x0000 }, /* R226 */ - { 0x0000, 0x0000 }, /* R227 */ - { 0x0000, 0x0000 }, /* R228 */ - { 0x0000, 0x0000 }, /* R229 */ - { 0x0000, 0x0000 }, /* R230 */ - { 0x0000, 0x0000 }, /* R231 */ - { 0x0000, 0x0000 }, /* R232 */ - { 0x0000, 0x0000 }, /* R233 */ - { 0x0000, 0x0000 }, /* R234 */ - { 0x0000, 0x0000 }, /* R235 */ - { 0x0000, 0x0000 }, /* R236 */ - { 0x0000, 0x0000 }, /* R237 */ - { 0x0000, 0x0000 }, /* R238 */ - { 0x0000, 0x0000 }, /* R239 */ - { 0x0000, 0x0000 }, /* R240 */ - { 0x0000, 0x0000 }, /* R241 */ - { 0x0000, 0x0000 }, /* R242 */ - { 0x0000, 0x0000 }, /* R243 */ - { 0x0000, 0x0000 }, /* R244 */ - { 0x0000, 0x0000 }, /* R245 */ - { 0x0000, 0x0000 }, /* R246 */ - { 0x0000, 0x0000 }, /* R247 */ - { 0x0000, 0x0000 }, /* R248 */ - { 0x0000, 0x0000 }, /* R249 */ - { 0x0000, 0x0000 }, /* R250 */ - { 0x0000, 0x0000 }, /* R251 */ - { 0x0000, 0x0000 }, /* R252 */ - { 0x0000, 0x0000 }, /* R253 */ - { 0x0000, 0x0000 }, /* R254 */ - { 0x0000, 0x0000 }, /* R255 */ - { 0x000F, 0x0000 }, /* R256 - Chip Revision */ - { 0x0074, 0x0074 }, /* R257 - Control Interface */ - { 0x0000, 0x0000 }, /* R258 */ - { 0x0000, 0x0000 }, /* R259 */ - { 0x0000, 0x0000 }, /* R260 */ - { 0x0000, 0x0000 }, /* R261 */ - { 0x0000, 0x0000 }, /* R262 */ - { 0x0000, 0x0000 }, /* R263 */ - { 0x0000, 0x0000 }, /* R264 */ - { 0x0000, 0x0000 }, /* R265 */ - { 0x0000, 0x0000 }, /* R266 */ - { 0x0000, 0x0000 }, /* R267 */ - { 0x0000, 0x0000 }, /* R268 */ - { 0x0000, 0x0000 }, /* R269 */ - { 0x0000, 0x0000 }, /* R270 */ - { 0x0000, 0x0000 }, /* R271 */ - { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */ - { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ - { 0x0000, 0x0000 }, /* R274 */ - { 0x0000, 0x0000 }, /* R275 */ - { 0x0000, 0x0000 }, /* R276 */ - { 0x0000, 0x0000 }, /* R277 */ - { 0x0000, 0x0000 }, /* R278 */ - { 0x0000, 0x0000 }, /* R279 */ - { 0x0000, 0x0000 }, /* R280 */ - { 0x0000, 0x0000 }, /* R281 */ - { 0x0000, 0x0000 }, /* R282 */ - { 0x0000, 0x0000 }, /* R283 */ - { 0x0000, 0x0000 }, /* R284 */ - { 0x0000, 0x0000 }, /* R285 */ - { 0x0000, 0x0000 }, /* R286 */ - { 0x0000, 0x0000 }, /* R287 */ - { 0x0000, 0x0000 }, /* R288 */ - { 0x0000, 0x0000 }, /* R289 */ - { 0x0000, 0x0000 }, /* R290 */ - { 0x0000, 0x0000 }, /* R291 */ - { 0x0000, 0x0000 }, /* R292 */ - { 0x0000, 0x0000 }, /* R293 */ - { 0x0000, 0x0000 }, /* R294 */ - { 0x0000, 0x0000 }, /* R295 */ - { 0x0000, 0x0000 }, /* R296 */ - { 0x0000, 0x0000 }, /* R297 */ - { 0x0000, 0x0000 }, /* R298 */ - { 0x0000, 0x0000 }, /* R299 */ - { 0x0000, 0x0000 }, /* R300 */ - { 0x0000, 0x0000 }, /* R301 */ - { 0x0000, 0x0000 }, /* R302 */ - { 0x0000, 0x0000 }, /* R303 */ - { 0x0000, 0x0000 }, /* R304 */ - { 0x0000, 0x0000 }, /* R305 */ - { 0x0000, 0x0000 }, /* R306 */ - { 0x0000, 0x0000 }, /* R307 */ - { 0x0000, 0x0000 }, /* R308 */ - { 0x0000, 0x0000 }, /* R309 */ - { 0x0000, 0x0000 }, /* R310 */ - { 0x0000, 0x0000 }, /* R311 */ - { 0x0000, 0x0000 }, /* R312 */ - { 0x0000, 0x0000 }, /* R313 */ - { 0x0000, 0x0000 }, /* R314 */ - { 0x0000, 0x0000 }, /* R315 */ - { 0x0000, 0x0000 }, /* R316 */ - { 0x0000, 0x0000 }, /* R317 */ - { 0x0000, 0x0000 }, /* R318 */ - { 0x0000, 0x0000 }, /* R319 */ - { 0x0000, 0x0000 }, /* R320 */ - { 0x0000, 0x0000 }, /* R321 */ - { 0x0000, 0x0000 }, /* R322 */ - { 0x0000, 0x0000 }, /* R323 */ - { 0x0000, 0x0000 }, /* R324 */ - { 0x0000, 0x0000 }, /* R325 */ - { 0x0000, 0x0000 }, /* R326 */ - { 0x0000, 0x0000 }, /* R327 */ - { 0x0000, 0x0000 }, /* R328 */ - { 0x0000, 0x0000 }, /* R329 */ - { 0x0000, 0x0000 }, /* R330 */ - { 0x0000, 0x0000 }, /* R331 */ - { 0x0000, 0x0000 }, /* R332 */ - { 0x0000, 0x0000 }, /* R333 */ - { 0x0000, 0x0000 }, /* R334 */ - { 0x0000, 0x0000 }, /* R335 */ - { 0x0000, 0x0000 }, /* R336 */ - { 0x0000, 0x0000 }, /* R337 */ - { 0x0000, 0x0000 }, /* R338 */ - { 0x0000, 0x0000 }, /* R339 */ - { 0x0000, 0x0000 }, /* R340 */ - { 0x0000, 0x0000 }, /* R341 */ - { 0x0000, 0x0000 }, /* R342 */ - { 0x0000, 0x0000 }, /* R343 */ - { 0x0000, 0x0000 }, /* R344 */ - { 0x0000, 0x0000 }, /* R345 */ - { 0x0000, 0x0000 }, /* R346 */ - { 0x0000, 0x0000 }, /* R347 */ - { 0x0000, 0x0000 }, /* R348 */ - { 0x0000, 0x0000 }, /* R349 */ - { 0x0000, 0x0000 }, /* R350 */ - { 0x0000, 0x0000 }, /* R351 */ - { 0x0000, 0x0000 }, /* R352 */ - { 0x0000, 0x0000 }, /* R353 */ - { 0x0000, 0x0000 }, /* R354 */ - { 0x0000, 0x0000 }, /* R355 */ - { 0x0000, 0x0000 }, /* R356 */ - { 0x0000, 0x0000 }, /* R357 */ - { 0x0000, 0x0000 }, /* R358 */ - { 0x0000, 0x0000 }, /* R359 */ - { 0x0000, 0x0000 }, /* R360 */ - { 0x0000, 0x0000 }, /* R361 */ - { 0x0000, 0x0000 }, /* R362 */ - { 0x0000, 0x0000 }, /* R363 */ - { 0x0000, 0x0000 }, /* R364 */ - { 0x0000, 0x0000 }, /* R365 */ - { 0x0000, 0x0000 }, /* R366 */ - { 0x0000, 0x0000 }, /* R367 */ - { 0x0000, 0x0000 }, /* R368 */ - { 0x0000, 0x0000 }, /* R369 */ - { 0x0000, 0x0000 }, /* R370 */ - { 0x0000, 0x0000 }, /* R371 */ - { 0x0000, 0x0000 }, /* R372 */ - { 0x0000, 0x0000 }, /* R373 */ - { 0x0000, 0x0000 }, /* R374 */ - { 0x0000, 0x0000 }, /* R375 */ - { 0x0000, 0x0000 }, /* R376 */ - { 0x0000, 0x0000 }, /* R377 */ - { 0x0000, 0x0000 }, /* R378 */ - { 0x0000, 0x0000 }, /* R379 */ - { 0x0000, 0x0000 }, /* R380 */ - { 0x0000, 0x0000 }, /* R381 */ - { 0x0000, 0x0000 }, /* R382 */ - { 0x0000, 0x0000 }, /* R383 */ - { 0x0000, 0x0000 }, /* R384 */ - { 0x0000, 0x0000 }, /* R385 */ - { 0x0000, 0x0000 }, /* R386 */ - { 0x0000, 0x0000 }, /* R387 */ - { 0x0000, 0x0000 }, /* R388 */ - { 0x0000, 0x0000 }, /* R389 */ - { 0x0000, 0x0000 }, /* R390 */ - { 0x0000, 0x0000 }, /* R391 */ - { 0x0000, 0x0000 }, /* R392 */ - { 0x0000, 0x0000 }, /* R393 */ - { 0x0000, 0x0000 }, /* R394 */ - { 0x0000, 0x0000 }, /* R395 */ - { 0x0000, 0x0000 }, /* R396 */ - { 0x0000, 0x0000 }, /* R397 */ - { 0x0000, 0x0000 }, /* R398 */ - { 0x0000, 0x0000 }, /* R399 */ - { 0x0000, 0x0000 }, /* R400 */ - { 0x0000, 0x0000 }, /* R401 */ - { 0x0000, 0x0000 }, /* R402 */ - { 0x0000, 0x0000 }, /* R403 */ - { 0x0000, 0x0000 }, /* R404 */ - { 0x0000, 0x0000 }, /* R405 */ - { 0x0000, 0x0000 }, /* R406 */ - { 0x0000, 0x0000 }, /* R407 */ - { 0x0000, 0x0000 }, /* R408 */ - { 0x0000, 0x0000 }, /* R409 */ - { 0x0000, 0x0000 }, /* R410 */ - { 0x0000, 0x0000 }, /* R411 */ - { 0x0000, 0x0000 }, /* R412 */ - { 0x0000, 0x0000 }, /* R413 */ - { 0x0000, 0x0000 }, /* R414 */ - { 0x0000, 0x0000 }, /* R415 */ - { 0x0000, 0x0000 }, /* R416 */ - { 0x0000, 0x0000 }, /* R417 */ - { 0x0000, 0x0000 }, /* R418 */ - { 0x0000, 0x0000 }, /* R419 */ - { 0x0000, 0x0000 }, /* R420 */ - { 0x0000, 0x0000 }, /* R421 */ - { 0x0000, 0x0000 }, /* R422 */ - { 0x0000, 0x0000 }, /* R423 */ - { 0x0000, 0x0000 }, /* R424 */ - { 0x0000, 0x0000 }, /* R425 */ - { 0x0000, 0x0000 }, /* R426 */ - { 0x0000, 0x0000 }, /* R427 */ - { 0x0000, 0x0000 }, /* R428 */ - { 0x0000, 0x0000 }, /* R429 */ - { 0x0000, 0x0000 }, /* R430 */ - { 0x0000, 0x0000 }, /* R431 */ - { 0x0000, 0x0000 }, /* R432 */ - { 0x0000, 0x0000 }, /* R433 */ - { 0x0000, 0x0000 }, /* R434 */ - { 0x0000, 0x0000 }, /* R435 */ - { 0x0000, 0x0000 }, /* R436 */ - { 0x0000, 0x0000 }, /* R437 */ - { 0x0000, 0x0000 }, /* R438 */ - { 0x0000, 0x0000 }, /* R439 */ - { 0x0000, 0x0000 }, /* R440 */ - { 0x0000, 0x0000 }, /* R441 */ - { 0x0000, 0x0000 }, /* R442 */ - { 0x0000, 0x0000 }, /* R443 */ - { 0x0000, 0x0000 }, /* R444 */ - { 0x0000, 0x0000 }, /* R445 */ - { 0x0000, 0x0000 }, /* R446 */ - { 0x0000, 0x0000 }, /* R447 */ - { 0x0000, 0x0000 }, /* R448 */ - { 0x0000, 0x0000 }, /* R449 */ - { 0x0000, 0x0000 }, /* R450 */ - { 0x0000, 0x0000 }, /* R451 */ - { 0x0000, 0x0000 }, /* R452 */ - { 0x0000, 0x0000 }, /* R453 */ - { 0x0000, 0x0000 }, /* R454 */ - { 0x0000, 0x0000 }, /* R455 */ - { 0x0000, 0x0000 }, /* R456 */ - { 0x0000, 0x0000 }, /* R457 */ - { 0x0000, 0x0000 }, /* R458 */ - { 0x0000, 0x0000 }, /* R459 */ - { 0x0000, 0x0000 }, /* R460 */ - { 0x0000, 0x0000 }, /* R461 */ - { 0x0000, 0x0000 }, /* R462 */ - { 0x0000, 0x0000 }, /* R463 */ - { 0x0000, 0x0000 }, /* R464 */ - { 0x0000, 0x0000 }, /* R465 */ - { 0x0000, 0x0000 }, /* R466 */ - { 0x0000, 0x0000 }, /* R467 */ - { 0x0000, 0x0000 }, /* R468 */ - { 0x0000, 0x0000 }, /* R469 */ - { 0x0000, 0x0000 }, /* R470 */ - { 0x0000, 0x0000 }, /* R471 */ - { 0x0000, 0x0000 }, /* R472 */ - { 0x0000, 0x0000 }, /* R473 */ - { 0x0000, 0x0000 }, /* R474 */ - { 0x0000, 0x0000 }, /* R475 */ - { 0x0000, 0x0000 }, /* R476 */ - { 0x0000, 0x0000 }, /* R477 */ - { 0x0000, 0x0000 }, /* R478 */ - { 0x0000, 0x0000 }, /* R479 */ - { 0x0000, 0x0000 }, /* R480 */ - { 0x0000, 0x0000 }, /* R481 */ - { 0x0000, 0x0000 }, /* R482 */ - { 0x0000, 0x0000 }, /* R483 */ - { 0x0000, 0x0000 }, /* R484 */ - { 0x0000, 0x0000 }, /* R485 */ - { 0x0000, 0x0000 }, /* R486 */ - { 0x0000, 0x0000 }, /* R487 */ - { 0x0000, 0x0000 }, /* R488 */ - { 0x0000, 0x0000 }, /* R489 */ - { 0x0000, 0x0000 }, /* R490 */ - { 0x0000, 0x0000 }, /* R491 */ - { 0x0000, 0x0000 }, /* R492 */ - { 0x0000, 0x0000 }, /* R493 */ - { 0x0000, 0x0000 }, /* R494 */ - { 0x0000, 0x0000 }, /* R495 */ - { 0x0000, 0x0000 }, /* R496 */ - { 0x0000, 0x0000 }, /* R497 */ - { 0x0000, 0x0000 }, /* R498 */ - { 0x0000, 0x0000 }, /* R499 */ - { 0x0000, 0x0000 }, /* R500 */ - { 0x0000, 0x0000 }, /* R501 */ - { 0x0000, 0x0000 }, /* R502 */ - { 0x0000, 0x0000 }, /* R503 */ - { 0x0000, 0x0000 }, /* R504 */ - { 0x0000, 0x0000 }, /* R505 */ - { 0x0000, 0x0000 }, /* R506 */ - { 0x0000, 0x0000 }, /* R507 */ - { 0x0000, 0x0000 }, /* R508 */ - { 0x0000, 0x0000 }, /* R509 */ - { 0x0000, 0x0000 }, /* R510 */ - { 0x0000, 0x0000 }, /* R511 */ - { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */ - { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */ - { 0x0000, 0x0000 }, /* R514 */ - { 0x0000, 0x0000 }, /* R515 */ - { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */ - { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */ - { 0x0000, 0x0000 }, /* R518 */ - { 0x0000, 0x0000 }, /* R519 */ - { 0x001F, 0x001F }, /* R520 - Clocking (1) */ - { 0x0777, 0x0777 }, /* R521 - Clocking (2) */ - { 0x0000, 0x0000 }, /* R522 */ - { 0x0000, 0x0000 }, /* R523 */ - { 0x0000, 0x0000 }, /* R524 */ - { 0x0000, 0x0000 }, /* R525 */ - { 0x0000, 0x0000 }, /* R526 */ - { 0x0000, 0x0000 }, /* R527 */ - { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */ - { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */ - { 0x000F, 0x0000 }, /* R530 - Rate Status */ - { 0x0000, 0x0000 }, /* R531 */ - { 0x0000, 0x0000 }, /* R532 */ - { 0x0000, 0x0000 }, /* R533 */ - { 0x0000, 0x0000 }, /* R534 */ - { 0x0000, 0x0000 }, /* R535 */ - { 0x0000, 0x0000 }, /* R536 */ - { 0x0000, 0x0000 }, /* R537 */ - { 0x0000, 0x0000 }, /* R538 */ - { 0x0000, 0x0000 }, /* R539 */ - { 0x0000, 0x0000 }, /* R540 */ - { 0x0000, 0x0000 }, /* R541 */ - { 0x0000, 0x0000 }, /* R542 */ - { 0x0000, 0x0000 }, /* R543 */ - { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */ - { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */ - { 0x0000, 0x0000 }, /* R549 */ - { 0x0000, 0x0000 }, /* R550 */ - { 0x0000, 0x0000 }, /* R551 */ - { 0x0000, 0x0000 }, /* R552 */ - { 0x0000, 0x0000 }, /* R553 */ - { 0x0000, 0x0000 }, /* R554 */ - { 0x0000, 0x0000 }, /* R555 */ - { 0x0000, 0x0000 }, /* R556 */ - { 0x0000, 0x0000 }, /* R557 */ - { 0x0000, 0x0000 }, /* R558 */ - { 0x0000, 0x0000 }, /* R559 */ - { 0x0000, 0x0000 }, /* R560 */ - { 0x0000, 0x0000 }, /* R561 */ - { 0x0000, 0x0000 }, /* R562 */ - { 0x0000, 0x0000 }, /* R563 */ - { 0x0000, 0x0000 }, /* R564 */ - { 0x0000, 0x0000 }, /* R565 */ - { 0x0000, 0x0000 }, /* R566 */ - { 0x0000, 0x0000 }, /* R567 */ - { 0x0000, 0x0000 }, /* R568 */ - { 0x0000, 0x0000 }, /* R569 */ - { 0x0000, 0x0000 }, /* R570 */ - { 0x0000, 0x0000 }, /* R571 */ - { 0x0000, 0x0000 }, /* R572 */ - { 0x0000, 0x0000 }, /* R573 */ - { 0x0000, 0x0000 }, /* R574 */ - { 0x0000, 0x0000 }, /* R575 */ - { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */ - { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */ - { 0x0000, 0x0000 }, /* R581 */ - { 0x0000, 0x0000 }, /* R582 */ - { 0x0000, 0x0000 }, /* R583 */ - { 0x0000, 0x0000 }, /* R584 */ - { 0x0000, 0x0000 }, /* R585 */ - { 0x0000, 0x0000 }, /* R586 */ - { 0x0000, 0x0000 }, /* R587 */ - { 0x0000, 0x0000 }, /* R588 */ - { 0x0000, 0x0000 }, /* R589 */ - { 0x0000, 0x0000 }, /* R590 */ - { 0x0000, 0x0000 }, /* R591 */ - { 0x0000, 0x0000 }, /* R592 */ - { 0x0000, 0x0000 }, /* R593 */ - { 0x0000, 0x0000 }, /* R594 */ - { 0x0000, 0x0000 }, /* R595 */ - { 0x0000, 0x0000 }, /* R596 */ - { 0x0000, 0x0000 }, /* R597 */ - { 0x0000, 0x0000 }, /* R598 */ - { 0x0000, 0x0000 }, /* R599 */ - { 0x0000, 0x0000 }, /* R600 */ - { 0x0000, 0x0000 }, /* R601 */ - { 0x0000, 0x0000 }, /* R602 */ - { 0x0000, 0x0000 }, /* R603 */ - { 0x0000, 0x0000 }, /* R604 */ - { 0x0000, 0x0000 }, /* R605 */ - { 0x0000, 0x0000 }, /* R606 */ - { 0x0000, 0x0000 }, /* R607 */ - { 0x0000, 0x0000 }, /* R608 */ - { 0x0000, 0x0000 }, /* R609 */ - { 0x0000, 0x0000 }, /* R610 */ - { 0x0000, 0x0000 }, /* R611 */ - { 0x0000, 0x0000 }, /* R612 */ - { 0x0000, 0x0000 }, /* R613 */ - { 0x0000, 0x0000 }, /* R614 */ - { 0x0000, 0x0000 }, /* R615 */ - { 0x0000, 0x0000 }, /* R616 */ - { 0x0000, 0x0000 }, /* R617 */ - { 0x0000, 0x0000 }, /* R618 */ - { 0x0000, 0x0000 }, /* R619 */ - { 0x0000, 0x0000 }, /* R620 */ - { 0x0000, 0x0000 }, /* R621 */ - { 0x0000, 0x0000 }, /* R622 */ - { 0x0000, 0x0000 }, /* R623 */ - { 0x0000, 0x0000 }, /* R624 */ - { 0x0000, 0x0000 }, /* R625 */ - { 0x0000, 0x0000 }, /* R626 */ - { 0x0000, 0x0000 }, /* R627 */ - { 0x0000, 0x0000 }, /* R628 */ - { 0x0000, 0x0000 }, /* R629 */ - { 0x0000, 0x0000 }, /* R630 */ - { 0x0000, 0x0000 }, /* R631 */ - { 0x0000, 0x0000 }, /* R632 */ - { 0x0000, 0x0000 }, /* R633 */ - { 0x0000, 0x0000 }, /* R634 */ - { 0x0000, 0x0000 }, /* R635 */ - { 0x0000, 0x0000 }, /* R636 */ - { 0x0000, 0x0000 }, /* R637 */ - { 0x0000, 0x0000 }, /* R638 */ - { 0x0000, 0x0000 }, /* R639 */ - { 0x0000, 0x0000 }, /* R640 */ - { 0x0000, 0x0000 }, /* R641 */ - { 0x0000, 0x0000 }, /* R642 */ - { 0x0000, 0x0000 }, /* R643 */ - { 0x0000, 0x0000 }, /* R644 */ - { 0x0000, 0x0000 }, /* R645 */ - { 0x0000, 0x0000 }, /* R646 */ - { 0x0000, 0x0000 }, /* R647 */ - { 0x0000, 0x0000 }, /* R648 */ - { 0x0000, 0x0000 }, /* R649 */ - { 0x0000, 0x0000 }, /* R650 */ - { 0x0000, 0x0000 }, /* R651 */ - { 0x0000, 0x0000 }, /* R652 */ - { 0x0000, 0x0000 }, /* R653 */ - { 0x0000, 0x0000 }, /* R654 */ - { 0x0000, 0x0000 }, /* R655 */ - { 0x0000, 0x0000 }, /* R656 */ - { 0x0000, 0x0000 }, /* R657 */ - { 0x0000, 0x0000 }, /* R658 */ - { 0x0000, 0x0000 }, /* R659 */ - { 0x0000, 0x0000 }, /* R660 */ - { 0x0000, 0x0000 }, /* R661 */ - { 0x0000, 0x0000 }, /* R662 */ - { 0x0000, 0x0000 }, /* R663 */ - { 0x0000, 0x0000 }, /* R664 */ - { 0x0000, 0x0000 }, /* R665 */ - { 0x0000, 0x0000 }, /* R666 */ - { 0x0000, 0x0000 }, /* R667 */ - { 0x0000, 0x0000 }, /* R668 */ - { 0x0000, 0x0000 }, /* R669 */ - { 0x0000, 0x0000 }, /* R670 */ - { 0x0000, 0x0000 }, /* R671 */ - { 0x0000, 0x0000 }, /* R672 */ - { 0x0000, 0x0000 }, /* R673 */ - { 0x0000, 0x0000 }, /* R674 */ - { 0x0000, 0x0000 }, /* R675 */ - { 0x0000, 0x0000 }, /* R676 */ - { 0x0000, 0x0000 }, /* R677 */ - { 0x0000, 0x0000 }, /* R678 */ - { 0x0000, 0x0000 }, /* R679 */ - { 0x0000, 0x0000 }, /* R680 */ - { 0x0000, 0x0000 }, /* R681 */ - { 0x0000, 0x0000 }, /* R682 */ - { 0x0000, 0x0000 }, /* R683 */ - { 0x0000, 0x0000 }, /* R684 */ - { 0x0000, 0x0000 }, /* R685 */ - { 0x0000, 0x0000 }, /* R686 */ - { 0x0000, 0x0000 }, /* R687 */ - { 0x0000, 0x0000 }, /* R688 */ - { 0x0000, 0x0000 }, /* R689 */ - { 0x0000, 0x0000 }, /* R690 */ - { 0x0000, 0x0000 }, /* R691 */ - { 0x0000, 0x0000 }, /* R692 */ - { 0x0000, 0x0000 }, /* R693 */ - { 0x0000, 0x0000 }, /* R694 */ - { 0x0000, 0x0000 }, /* R695 */ - { 0x0000, 0x0000 }, /* R696 */ - { 0x0000, 0x0000 }, /* R697 */ - { 0x0000, 0x0000 }, /* R698 */ - { 0x0000, 0x0000 }, /* R699 */ - { 0x0000, 0x0000 }, /* R700 */ - { 0x0000, 0x0000 }, /* R701 */ - { 0x0000, 0x0000 }, /* R702 */ - { 0x0000, 0x0000 }, /* R703 */ - { 0x0000, 0x0000 }, /* R704 */ - { 0x0000, 0x0000 }, /* R705 */ - { 0x0000, 0x0000 }, /* R706 */ - { 0x0000, 0x0000 }, /* R707 */ - { 0x0000, 0x0000 }, /* R708 */ - { 0x0000, 0x0000 }, /* R709 */ - { 0x0000, 0x0000 }, /* R710 */ - { 0x0000, 0x0000 }, /* R711 */ - { 0x0000, 0x0000 }, /* R712 */ - { 0x0000, 0x0000 }, /* R713 */ - { 0x0000, 0x0000 }, /* R714 */ - { 0x0000, 0x0000 }, /* R715 */ - { 0x0000, 0x0000 }, /* R716 */ - { 0x0000, 0x0000 }, /* R717 */ - { 0x0000, 0x0000 }, /* R718 */ - { 0x0000, 0x0000 }, /* R719 */ - { 0x0000, 0x0000 }, /* R720 */ - { 0x0000, 0x0000 }, /* R721 */ - { 0x0000, 0x0000 }, /* R722 */ - { 0x0000, 0x0000 }, /* R723 */ - { 0x0000, 0x0000 }, /* R724 */ - { 0x0000, 0x0000 }, /* R725 */ - { 0x0000, 0x0000 }, /* R726 */ - { 0x0000, 0x0000 }, /* R727 */ - { 0x0000, 0x0000 }, /* R728 */ - { 0x0000, 0x0000 }, /* R729 */ - { 0x0000, 0x0000 }, /* R730 */ - { 0x0000, 0x0000 }, /* R731 */ - { 0x0000, 0x0000 }, /* R732 */ - { 0x0000, 0x0000 }, /* R733 */ - { 0x0000, 0x0000 }, /* R734 */ - { 0x0000, 0x0000 }, /* R735 */ - { 0x0000, 0x0000 }, /* R736 */ - { 0x0000, 0x0000 }, /* R737 */ - { 0x0000, 0x0000 }, /* R738 */ - { 0x0000, 0x0000 }, /* R739 */ - { 0x0000, 0x0000 }, /* R740 */ - { 0x0000, 0x0000 }, /* R741 */ - { 0x0000, 0x0000 }, /* R742 */ - { 0x0000, 0x0000 }, /* R743 */ - { 0x0000, 0x0000 }, /* R744 */ - { 0x0000, 0x0000 }, /* R745 */ - { 0x0000, 0x0000 }, /* R746 */ - { 0x0000, 0x0000 }, /* R747 */ - { 0x0000, 0x0000 }, /* R748 */ - { 0x0000, 0x0000 }, /* R749 */ - { 0x0000, 0x0000 }, /* R750 */ - { 0x0000, 0x0000 }, /* R751 */ - { 0x0000, 0x0000 }, /* R752 */ - { 0x0000, 0x0000 }, /* R753 */ - { 0x0000, 0x0000 }, /* R754 */ - { 0x0000, 0x0000 }, /* R755 */ - { 0x0000, 0x0000 }, /* R756 */ - { 0x0000, 0x0000 }, /* R757 */ - { 0x0000, 0x0000 }, /* R758 */ - { 0x0000, 0x0000 }, /* R759 */ - { 0x0000, 0x0000 }, /* R760 */ - { 0x0000, 0x0000 }, /* R761 */ - { 0x0000, 0x0000 }, /* R762 */ - { 0x0000, 0x0000 }, /* R763 */ - { 0x0000, 0x0000 }, /* R764 */ - { 0x0000, 0x0000 }, /* R765 */ - { 0x0000, 0x0000 }, /* R766 */ - { 0x0000, 0x0000 }, /* R767 */ - { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */ - { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */ - { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */ - { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */ - { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */ - { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */ - { 0x0000, 0x0000 }, /* R776 */ - { 0x0000, 0x0000 }, /* R777 */ - { 0x0000, 0x0000 }, /* R778 */ - { 0x0000, 0x0000 }, /* R779 */ - { 0x0000, 0x0000 }, /* R780 */ - { 0x0000, 0x0000 }, /* R781 */ - { 0x0000, 0x0000 }, /* R782 */ - { 0x0000, 0x0000 }, /* R783 */ - { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */ - { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */ - { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */ - { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */ - { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */ - { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */ - { 0x0000, 0x0000 }, /* R792 */ - { 0x0000, 0x0000 }, /* R793 */ - { 0x0000, 0x0000 }, /* R794 */ - { 0x0000, 0x0000 }, /* R795 */ - { 0x0000, 0x0000 }, /* R796 */ - { 0x0000, 0x0000 }, /* R797 */ - { 0x0000, 0x0000 }, /* R798 */ - { 0x0000, 0x0000 }, /* R799 */ - { 0x0000, 0x0000 }, /* R800 */ - { 0x0000, 0x0000 }, /* R801 */ - { 0x0000, 0x0000 }, /* R802 */ - { 0x0000, 0x0000 }, /* R803 */ - { 0x0000, 0x0000 }, /* R804 */ - { 0x0000, 0x0000 }, /* R805 */ - { 0x0000, 0x0000 }, /* R806 */ - { 0x0000, 0x0000 }, /* R807 */ - { 0x0000, 0x0000 }, /* R808 */ - { 0x0000, 0x0000 }, /* R809 */ - { 0x0000, 0x0000 }, /* R810 */ - { 0x0000, 0x0000 }, /* R811 */ - { 0x0000, 0x0000 }, /* R812 */ - { 0x0000, 0x0000 }, /* R813 */ - { 0x0000, 0x0000 }, /* R814 */ - { 0x0000, 0x0000 }, /* R815 */ - { 0x0000, 0x0000 }, /* R816 */ - { 0x0000, 0x0000 }, /* R817 */ - { 0x0000, 0x0000 }, /* R818 */ - { 0x0000, 0x0000 }, /* R819 */ - { 0x0000, 0x0000 }, /* R820 */ - { 0x0000, 0x0000 }, /* R821 */ - { 0x0000, 0x0000 }, /* R822 */ - { 0x0000, 0x0000 }, /* R823 */ - { 0x0000, 0x0000 }, /* R824 */ - { 0x0000, 0x0000 }, /* R825 */ - { 0x0000, 0x0000 }, /* R826 */ - { 0x0000, 0x0000 }, /* R827 */ - { 0x0000, 0x0000 }, /* R828 */ - { 0x0000, 0x0000 }, /* R829 */ - { 0x0000, 0x0000 }, /* R830 */ - { 0x0000, 0x0000 }, /* R831 */ - { 0x0000, 0x0000 }, /* R832 */ - { 0x0000, 0x0000 }, /* R833 */ - { 0x0000, 0x0000 }, /* R834 */ - { 0x0000, 0x0000 }, /* R835 */ - { 0x0000, 0x0000 }, /* R836 */ - { 0x0000, 0x0000 }, /* R837 */ - { 0x0000, 0x0000 }, /* R838 */ - { 0x0000, 0x0000 }, /* R839 */ - { 0x0000, 0x0000 }, /* R840 */ - { 0x0000, 0x0000 }, /* R841 */ - { 0x0000, 0x0000 }, /* R842 */ - { 0x0000, 0x0000 }, /* R843 */ - { 0x0000, 0x0000 }, /* R844 */ - { 0x0000, 0x0000 }, /* R845 */ - { 0x0000, 0x0000 }, /* R846 */ - { 0x0000, 0x0000 }, /* R847 */ - { 0x0000, 0x0000 }, /* R848 */ - { 0x0000, 0x0000 }, /* R849 */ - { 0x0000, 0x0000 }, /* R850 */ - { 0x0000, 0x0000 }, /* R851 */ - { 0x0000, 0x0000 }, /* R852 */ - { 0x0000, 0x0000 }, /* R853 */ - { 0x0000, 0x0000 }, /* R854 */ - { 0x0000, 0x0000 }, /* R855 */ - { 0x0000, 0x0000 }, /* R856 */ - { 0x0000, 0x0000 }, /* R857 */ - { 0x0000, 0x0000 }, /* R858 */ - { 0x0000, 0x0000 }, /* R859 */ - { 0x0000, 0x0000 }, /* R860 */ - { 0x0000, 0x0000 }, /* R861 */ - { 0x0000, 0x0000 }, /* R862 */ - { 0x0000, 0x0000 }, /* R863 */ - { 0x0000, 0x0000 }, /* R864 */ - { 0x0000, 0x0000 }, /* R865 */ - { 0x0000, 0x0000 }, /* R866 */ - { 0x0000, 0x0000 }, /* R867 */ - { 0x0000, 0x0000 }, /* R868 */ - { 0x0000, 0x0000 }, /* R869 */ - { 0x0000, 0x0000 }, /* R870 */ - { 0x0000, 0x0000 }, /* R871 */ - { 0x0000, 0x0000 }, /* R872 */ - { 0x0000, 0x0000 }, /* R873 */ - { 0x0000, 0x0000 }, /* R874 */ - { 0x0000, 0x0000 }, /* R875 */ - { 0x0000, 0x0000 }, /* R876 */ - { 0x0000, 0x0000 }, /* R877 */ - { 0x0000, 0x0000 }, /* R878 */ - { 0x0000, 0x0000 }, /* R879 */ - { 0x0000, 0x0000 }, /* R880 */ - { 0x0000, 0x0000 }, /* R881 */ - { 0x0000, 0x0000 }, /* R882 */ - { 0x0000, 0x0000 }, /* R883 */ - { 0x0000, 0x0000 }, /* R884 */ - { 0x0000, 0x0000 }, /* R885 */ - { 0x0000, 0x0000 }, /* R886 */ - { 0x0000, 0x0000 }, /* R887 */ - { 0x0000, 0x0000 }, /* R888 */ - { 0x0000, 0x0000 }, /* R889 */ - { 0x0000, 0x0000 }, /* R890 */ - { 0x0000, 0x0000 }, /* R891 */ - { 0x0000, 0x0000 }, /* R892 */ - { 0x0000, 0x0000 }, /* R893 */ - { 0x0000, 0x0000 }, /* R894 */ - { 0x0000, 0x0000 }, /* R895 */ - { 0x0000, 0x0000 }, /* R896 */ - { 0x0000, 0x0000 }, /* R897 */ - { 0x0000, 0x0000 }, /* R898 */ - { 0x0000, 0x0000 }, /* R899 */ - { 0x0000, 0x0000 }, /* R900 */ - { 0x0000, 0x0000 }, /* R901 */ - { 0x0000, 0x0000 }, /* R902 */ - { 0x0000, 0x0000 }, /* R903 */ - { 0x0000, 0x0000 }, /* R904 */ - { 0x0000, 0x0000 }, /* R905 */ - { 0x0000, 0x0000 }, /* R906 */ - { 0x0000, 0x0000 }, /* R907 */ - { 0x0000, 0x0000 }, /* R908 */ - { 0x0000, 0x0000 }, /* R909 */ - { 0x0000, 0x0000 }, /* R910 */ - { 0x0000, 0x0000 }, /* R911 */ - { 0x0000, 0x0000 }, /* R912 */ - { 0x0000, 0x0000 }, /* R913 */ - { 0x0000, 0x0000 }, /* R914 */ - { 0x0000, 0x0000 }, /* R915 */ - { 0x0000, 0x0000 }, /* R916 */ - { 0x0000, 0x0000 }, /* R917 */ - { 0x0000, 0x0000 }, /* R918 */ - { 0x0000, 0x0000 }, /* R919 */ - { 0x0000, 0x0000 }, /* R920 */ - { 0x0000, 0x0000 }, /* R921 */ - { 0x0000, 0x0000 }, /* R922 */ - { 0x0000, 0x0000 }, /* R923 */ - { 0x0000, 0x0000 }, /* R924 */ - { 0x0000, 0x0000 }, /* R925 */ - { 0x0000, 0x0000 }, /* R926 */ - { 0x0000, 0x0000 }, /* R927 */ - { 0x0000, 0x0000 }, /* R928 */ - { 0x0000, 0x0000 }, /* R929 */ - { 0x0000, 0x0000 }, /* R930 */ - { 0x0000, 0x0000 }, /* R931 */ - { 0x0000, 0x0000 }, /* R932 */ - { 0x0000, 0x0000 }, /* R933 */ - { 0x0000, 0x0000 }, /* R934 */ - { 0x0000, 0x0000 }, /* R935 */ - { 0x0000, 0x0000 }, /* R936 */ - { 0x0000, 0x0000 }, /* R937 */ - { 0x0000, 0x0000 }, /* R938 */ - { 0x0000, 0x0000 }, /* R939 */ - { 0x0000, 0x0000 }, /* R940 */ - { 0x0000, 0x0000 }, /* R941 */ - { 0x0000, 0x0000 }, /* R942 */ - { 0x0000, 0x0000 }, /* R943 */ - { 0x0000, 0x0000 }, /* R944 */ - { 0x0000, 0x0000 }, /* R945 */ - { 0x0000, 0x0000 }, /* R946 */ - { 0x0000, 0x0000 }, /* R947 */ - { 0x0000, 0x0000 }, /* R948 */ - { 0x0000, 0x0000 }, /* R949 */ - { 0x0000, 0x0000 }, /* R950 */ - { 0x0000, 0x0000 }, /* R951 */ - { 0x0000, 0x0000 }, /* R952 */ - { 0x0000, 0x0000 }, /* R953 */ - { 0x0000, 0x0000 }, /* R954 */ - { 0x0000, 0x0000 }, /* R955 */ - { 0x0000, 0x0000 }, /* R956 */ - { 0x0000, 0x0000 }, /* R957 */ - { 0x0000, 0x0000 }, /* R958 */ - { 0x0000, 0x0000 }, /* R959 */ - { 0x0000, 0x0000 }, /* R960 */ - { 0x0000, 0x0000 }, /* R961 */ - { 0x0000, 0x0000 }, /* R962 */ - { 0x0000, 0x0000 }, /* R963 */ - { 0x0000, 0x0000 }, /* R964 */ - { 0x0000, 0x0000 }, /* R965 */ - { 0x0000, 0x0000 }, /* R966 */ - { 0x0000, 0x0000 }, /* R967 */ - { 0x0000, 0x0000 }, /* R968 */ - { 0x0000, 0x0000 }, /* R969 */ - { 0x0000, 0x0000 }, /* R970 */ - { 0x0000, 0x0000 }, /* R971 */ - { 0x0000, 0x0000 }, /* R972 */ - { 0x0000, 0x0000 }, /* R973 */ - { 0x0000, 0x0000 }, /* R974 */ - { 0x0000, 0x0000 }, /* R975 */ - { 0x0000, 0x0000 }, /* R976 */ - { 0x0000, 0x0000 }, /* R977 */ - { 0x0000, 0x0000 }, /* R978 */ - { 0x0000, 0x0000 }, /* R979 */ - { 0x0000, 0x0000 }, /* R980 */ - { 0x0000, 0x0000 }, /* R981 */ - { 0x0000, 0x0000 }, /* R982 */ - { 0x0000, 0x0000 }, /* R983 */ - { 0x0000, 0x0000 }, /* R984 */ - { 0x0000, 0x0000 }, /* R985 */ - { 0x0000, 0x0000 }, /* R986 */ - { 0x0000, 0x0000 }, /* R987 */ - { 0x0000, 0x0000 }, /* R988 */ - { 0x0000, 0x0000 }, /* R989 */ - { 0x0000, 0x0000 }, /* R990 */ - { 0x0000, 0x0000 }, /* R991 */ - { 0x0000, 0x0000 }, /* R992 */ - { 0x0000, 0x0000 }, /* R993 */ - { 0x0000, 0x0000 }, /* R994 */ - { 0x0000, 0x0000 }, /* R995 */ - { 0x0000, 0x0000 }, /* R996 */ - { 0x0000, 0x0000 }, /* R997 */ - { 0x0000, 0x0000 }, /* R998 */ - { 0x0000, 0x0000 }, /* R999 */ - { 0x0000, 0x0000 }, /* R1000 */ - { 0x0000, 0x0000 }, /* R1001 */ - { 0x0000, 0x0000 }, /* R1002 */ - { 0x0000, 0x0000 }, /* R1003 */ - { 0x0000, 0x0000 }, /* R1004 */ - { 0x0000, 0x0000 }, /* R1005 */ - { 0x0000, 0x0000 }, /* R1006 */ - { 0x0000, 0x0000 }, /* R1007 */ - { 0x0000, 0x0000 }, /* R1008 */ - { 0x0000, 0x0000 }, /* R1009 */ - { 0x0000, 0x0000 }, /* R1010 */ - { 0x0000, 0x0000 }, /* R1011 */ - { 0x0000, 0x0000 }, /* R1012 */ - { 0x0000, 0x0000 }, /* R1013 */ - { 0x0000, 0x0000 }, /* R1014 */ - { 0x0000, 0x0000 }, /* R1015 */ - { 0x0000, 0x0000 }, /* R1016 */ - { 0x0000, 0x0000 }, /* R1017 */ - { 0x0000, 0x0000 }, /* R1018 */ - { 0x0000, 0x0000 }, /* R1019 */ - { 0x0000, 0x0000 }, /* R1020 */ - { 0x0000, 0x0000 }, /* R1021 */ - { 0x0000, 0x0000 }, /* R1022 */ - { 0x0000, 0x0000 }, /* R1023 */ - { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */ - { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */ - { 0x0000, 0x0000 }, /* R1032 */ - { 0x0000, 0x0000 }, /* R1033 */ - { 0x0000, 0x0000 }, /* R1034 */ - { 0x0000, 0x0000 }, /* R1035 */ - { 0x0000, 0x0000 }, /* R1036 */ - { 0x0000, 0x0000 }, /* R1037 */ - { 0x0000, 0x0000 }, /* R1038 */ - { 0x0000, 0x0000 }, /* R1039 */ - { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */ - { 0x0000, 0x0000 }, /* R1042 */ - { 0x0000, 0x0000 }, /* R1043 */ - { 0x0000, 0x0000 }, /* R1044 */ - { 0x0000, 0x0000 }, /* R1045 */ - { 0x0000, 0x0000 }, /* R1046 */ - { 0x0000, 0x0000 }, /* R1047 */ - { 0x0000, 0x0000 }, /* R1048 */ - { 0x0000, 0x0000 }, /* R1049 */ - { 0x0000, 0x0000 }, /* R1050 */ - { 0x0000, 0x0000 }, /* R1051 */ - { 0x0000, 0x0000 }, /* R1052 */ - { 0x0000, 0x0000 }, /* R1053 */ - { 0x0000, 0x0000 }, /* R1054 */ - { 0x0000, 0x0000 }, /* R1055 */ - { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */ - { 0x0000, 0x0000 }, /* R1060 */ - { 0x0000, 0x0000 }, /* R1061 */ - { 0x0000, 0x0000 }, /* R1062 */ - { 0x0000, 0x0000 }, /* R1063 */ - { 0x0000, 0x0000 }, /* R1064 */ - { 0x0000, 0x0000 }, /* R1065 */ - { 0x0000, 0x0000 }, /* R1066 */ - { 0x0000, 0x0000 }, /* R1067 */ - { 0x0000, 0x0000 }, /* R1068 */ - { 0x0000, 0x0000 }, /* R1069 */ - { 0x0000, 0x0000 }, /* R1070 */ - { 0x0000, 0x0000 }, /* R1071 */ - { 0x0000, 0x0000 }, /* R1072 */ - { 0x0000, 0x0000 }, /* R1073 */ - { 0x0000, 0x0000 }, /* R1074 */ - { 0x0000, 0x0000 }, /* R1075 */ - { 0x0000, 0x0000 }, /* R1076 */ - { 0x0000, 0x0000 }, /* R1077 */ - { 0x0000, 0x0000 }, /* R1078 */ - { 0x0000, 0x0000 }, /* R1079 */ - { 0x0000, 0x0000 }, /* R1080 */ - { 0x0000, 0x0000 }, /* R1081 */ - { 0x0000, 0x0000 }, /* R1082 */ - { 0x0000, 0x0000 }, /* R1083 */ - { 0x0000, 0x0000 }, /* R1084 */ - { 0x0000, 0x0000 }, /* R1085 */ - { 0x0000, 0x0000 }, /* R1086 */ - { 0x0000, 0x0000 }, /* R1087 */ - { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */ - { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */ - { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */ - { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */ - { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0000, 0x0000 }, /* R1093 */ - { 0x0000, 0x0000 }, /* R1094 */ - { 0x0000, 0x0000 }, /* R1095 */ - { 0x0000, 0x0000 }, /* R1096 */ - { 0x0000, 0x0000 }, /* R1097 */ - { 0x0000, 0x0000 }, /* R1098 */ - { 0x0000, 0x0000 }, /* R1099 */ - { 0x0000, 0x0000 }, /* R1100 */ - { 0x0000, 0x0000 }, /* R1101 */ - { 0x0000, 0x0000 }, /* R1102 */ - { 0x0000, 0x0000 }, /* R1103 */ - { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */ - { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */ - { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */ - { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */ - { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */ - { 0x0000, 0x0000 }, /* R1109 */ - { 0x0000, 0x0000 }, /* R1110 */ - { 0x0000, 0x0000 }, /* R1111 */ - { 0x0000, 0x0000 }, /* R1112 */ - { 0x0000, 0x0000 }, /* R1113 */ - { 0x0000, 0x0000 }, /* R1114 */ - { 0x0000, 0x0000 }, /* R1115 */ - { 0x0000, 0x0000 }, /* R1116 */ - { 0x0000, 0x0000 }, /* R1117 */ - { 0x0000, 0x0000 }, /* R1118 */ - { 0x0000, 0x0000 }, /* R1119 */ - { 0x0000, 0x0000 }, /* R1120 */ - { 0x0000, 0x0000 }, /* R1121 */ - { 0x0000, 0x0000 }, /* R1122 */ - { 0x0000, 0x0000 }, /* R1123 */ - { 0x0000, 0x0000 }, /* R1124 */ - { 0x0000, 0x0000 }, /* R1125 */ - { 0x0000, 0x0000 }, /* R1126 */ - { 0x0000, 0x0000 }, /* R1127 */ - { 0x0000, 0x0000 }, /* R1128 */ - { 0x0000, 0x0000 }, /* R1129 */ - { 0x0000, 0x0000 }, /* R1130 */ - { 0x0000, 0x0000 }, /* R1131 */ - { 0x0000, 0x0000 }, /* R1132 */ - { 0x0000, 0x0000 }, /* R1133 */ - { 0x0000, 0x0000 }, /* R1134 */ - { 0x0000, 0x0000 }, /* R1135 */ - { 0x0000, 0x0000 }, /* R1136 */ - { 0x0000, 0x0000 }, /* R1137 */ - { 0x0000, 0x0000 }, /* R1138 */ - { 0x0000, 0x0000 }, /* R1139 */ - { 0x0000, 0x0000 }, /* R1140 */ - { 0x0000, 0x0000 }, /* R1141 */ - { 0x0000, 0x0000 }, /* R1142 */ - { 0x0000, 0x0000 }, /* R1143 */ - { 0x0000, 0x0000 }, /* R1144 */ - { 0x0000, 0x0000 }, /* R1145 */ - { 0x0000, 0x0000 }, /* R1146 */ - { 0x0000, 0x0000 }, /* R1147 */ - { 0x0000, 0x0000 }, /* R1148 */ - { 0x0000, 0x0000 }, /* R1149 */ - { 0x0000, 0x0000 }, /* R1150 */ - { 0x0000, 0x0000 }, /* R1151 */ - { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1172 */ - { 0x0000, 0x0000 }, /* R1173 */ - { 0x0000, 0x0000 }, /* R1174 */ - { 0x0000, 0x0000 }, /* R1175 */ - { 0x0000, 0x0000 }, /* R1176 */ - { 0x0000, 0x0000 }, /* R1177 */ - { 0x0000, 0x0000 }, /* R1178 */ - { 0x0000, 0x0000 }, /* R1179 */ - { 0x0000, 0x0000 }, /* R1180 */ - { 0x0000, 0x0000 }, /* R1181 */ - { 0x0000, 0x0000 }, /* R1182 */ - { 0x0000, 0x0000 }, /* R1183 */ - { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1204 */ - { 0x0000, 0x0000 }, /* R1205 */ - { 0x0000, 0x0000 }, /* R1206 */ - { 0x0000, 0x0000 }, /* R1207 */ - { 0x0000, 0x0000 }, /* R1208 */ - { 0x0000, 0x0000 }, /* R1209 */ - { 0x0000, 0x0000 }, /* R1210 */ - { 0x0000, 0x0000 }, /* R1211 */ - { 0x0000, 0x0000 }, /* R1212 */ - { 0x0000, 0x0000 }, /* R1213 */ - { 0x0000, 0x0000 }, /* R1214 */ - { 0x0000, 0x0000 }, /* R1215 */ - { 0x0000, 0x0000 }, /* R1216 */ - { 0x0000, 0x0000 }, /* R1217 */ - { 0x0000, 0x0000 }, /* R1218 */ - { 0x0000, 0x0000 }, /* R1219 */ - { 0x0000, 0x0000 }, /* R1220 */ - { 0x0000, 0x0000 }, /* R1221 */ - { 0x0000, 0x0000 }, /* R1222 */ - { 0x0000, 0x0000 }, /* R1223 */ - { 0x0000, 0x0000 }, /* R1224 */ - { 0x0000, 0x0000 }, /* R1225 */ - { 0x0000, 0x0000 }, /* R1226 */ - { 0x0000, 0x0000 }, /* R1227 */ - { 0x0000, 0x0000 }, /* R1228 */ - { 0x0000, 0x0000 }, /* R1229 */ - { 0x0000, 0x0000 }, /* R1230 */ - { 0x0000, 0x0000 }, /* R1231 */ - { 0x0000, 0x0000 }, /* R1232 */ - { 0x0000, 0x0000 }, /* R1233 */ - { 0x0000, 0x0000 }, /* R1234 */ - { 0x0000, 0x0000 }, /* R1235 */ - { 0x0000, 0x0000 }, /* R1236 */ - { 0x0000, 0x0000 }, /* R1237 */ - { 0x0000, 0x0000 }, /* R1238 */ - { 0x0000, 0x0000 }, /* R1239 */ - { 0x0000, 0x0000 }, /* R1240 */ - { 0x0000, 0x0000 }, /* R1241 */ - { 0x0000, 0x0000 }, /* R1242 */ - { 0x0000, 0x0000 }, /* R1243 */ - { 0x0000, 0x0000 }, /* R1244 */ - { 0x0000, 0x0000 }, /* R1245 */ - { 0x0000, 0x0000 }, /* R1246 */ - { 0x0000, 0x0000 }, /* R1247 */ - { 0x0000, 0x0000 }, /* R1248 */ - { 0x0000, 0x0000 }, /* R1249 */ - { 0x0000, 0x0000 }, /* R1250 */ - { 0x0000, 0x0000 }, /* R1251 */ - { 0x0000, 0x0000 }, /* R1252 */ - { 0x0000, 0x0000 }, /* R1253 */ - { 0x0000, 0x0000 }, /* R1254 */ - { 0x0000, 0x0000 }, /* R1255 */ - { 0x0000, 0x0000 }, /* R1256 */ - { 0x0000, 0x0000 }, /* R1257 */ - { 0x0000, 0x0000 }, /* R1258 */ - { 0x0000, 0x0000 }, /* R1259 */ - { 0x0000, 0x0000 }, /* R1260 */ - { 0x0000, 0x0000 }, /* R1261 */ - { 0x0000, 0x0000 }, /* R1262 */ - { 0x0000, 0x0000 }, /* R1263 */ - { 0x0000, 0x0000 }, /* R1264 */ - { 0x0000, 0x0000 }, /* R1265 */ - { 0x0000, 0x0000 }, /* R1266 */ - { 0x0000, 0x0000 }, /* R1267 */ - { 0x0000, 0x0000 }, /* R1268 */ - { 0x0000, 0x0000 }, /* R1269 */ - { 0x0000, 0x0000 }, /* R1270 */ - { 0x0000, 0x0000 }, /* R1271 */ - { 0x0000, 0x0000 }, /* R1272 */ - { 0x0000, 0x0000 }, /* R1273 */ - { 0x0000, 0x0000 }, /* R1274 */ - { 0x0000, 0x0000 }, /* R1275 */ - { 0x0000, 0x0000 }, /* R1276 */ - { 0x0000, 0x0000 }, /* R1277 */ - { 0x0000, 0x0000 }, /* R1278 */ - { 0x0000, 0x0000 }, /* R1279 */ - { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */ - { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */ - { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */ - { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0000, 0x0000 }, /* R1284 */ - { 0x0000, 0x0000 }, /* R1285 */ - { 0x0000, 0x0000 }, /* R1286 */ - { 0x0000, 0x0000 }, /* R1287 */ - { 0x0000, 0x0000 }, /* R1288 */ - { 0x0000, 0x0000 }, /* R1289 */ - { 0x0000, 0x0000 }, /* R1290 */ - { 0x0000, 0x0000 }, /* R1291 */ - { 0x0000, 0x0000 }, /* R1292 */ - { 0x0000, 0x0000 }, /* R1293 */ - { 0x0000, 0x0000 }, /* R1294 */ - { 0x0000, 0x0000 }, /* R1295 */ - { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */ - { 0x0000, 0x0000 }, /* R1297 */ - { 0x0000, 0x0000 }, /* R1298 */ - { 0x0000, 0x0000 }, /* R1299 */ - { 0x0000, 0x0000 }, /* R1300 */ - { 0x0000, 0x0000 }, /* R1301 */ - { 0x0000, 0x0000 }, /* R1302 */ - { 0x0000, 0x0000 }, /* R1303 */ - { 0x0000, 0x0000 }, /* R1304 */ - { 0x0000, 0x0000 }, /* R1305 */ - { 0x0000, 0x0000 }, /* R1306 */ - { 0x0000, 0x0000 }, /* R1307 */ - { 0x0000, 0x0000 }, /* R1308 */ - { 0x0000, 0x0000 }, /* R1309 */ - { 0x0000, 0x0000 }, /* R1310 */ - { 0x0000, 0x0000 }, /* R1311 */ - { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0000, 0x0000 }, /* R1314 */ - { 0x0000, 0x0000 }, /* R1315 */ - { 0x0000, 0x0000 }, /* R1316 */ - { 0x0000, 0x0000 }, /* R1317 */ - { 0x0000, 0x0000 }, /* R1318 */ - { 0x0000, 0x0000 }, /* R1319 */ - { 0x0000, 0x0000 }, /* R1320 */ - { 0x0000, 0x0000 }, /* R1321 */ - { 0x0000, 0x0000 }, /* R1322 */ - { 0x0000, 0x0000 }, /* R1323 */ - { 0x0000, 0x0000 }, /* R1324 */ - { 0x0000, 0x0000 }, /* R1325 */ - { 0x0000, 0x0000 }, /* R1326 */ - { 0x0000, 0x0000 }, /* R1327 */ - { 0x0000, 0x0000 }, /* R1328 */ - { 0x0000, 0x0000 }, /* R1329 */ - { 0x0000, 0x0000 }, /* R1330 */ - { 0x0000, 0x0000 }, /* R1331 */ - { 0x0000, 0x0000 }, /* R1332 */ - { 0x0000, 0x0000 }, /* R1333 */ - { 0x0000, 0x0000 }, /* R1334 */ - { 0x0000, 0x0000 }, /* R1335 */ - { 0x0000, 0x0000 }, /* R1336 */ - { 0x0000, 0x0000 }, /* R1337 */ - { 0x0000, 0x0000 }, /* R1338 */ - { 0x0000, 0x0000 }, /* R1339 */ - { 0x0000, 0x0000 }, /* R1340 */ - { 0x0000, 0x0000 }, /* R1341 */ - { 0x0000, 0x0000 }, /* R1342 */ - { 0x0000, 0x0000 }, /* R1343 */ - { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */ - { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */ - { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */ - { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */ - { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */ - { 0x0000, 0x0000 }, /* R1349 */ - { 0x0000, 0x0000 }, /* R1350 */ - { 0x0000, 0x0000 }, /* R1351 */ - { 0x0000, 0x0000 }, /* R1352 */ - { 0x0000, 0x0000 }, /* R1353 */ - { 0x0000, 0x0000 }, /* R1354 */ - { 0x0000, 0x0000 }, /* R1355 */ - { 0x0000, 0x0000 }, /* R1356 */ - { 0x0000, 0x0000 }, /* R1357 */ - { 0x0000, 0x0000 }, /* R1358 */ - { 0x0000, 0x0000 }, /* R1359 */ - { 0x0000, 0x0000 }, /* R1360 */ - { 0x0000, 0x0000 }, /* R1361 */ - { 0x0000, 0x0000 }, /* R1362 */ - { 0x0000, 0x0000 }, /* R1363 */ - { 0x0000, 0x0000 }, /* R1364 */ - { 0x0000, 0x0000 }, /* R1365 */ - { 0x0000, 0x0000 }, /* R1366 */ - { 0x0000, 0x0000 }, /* R1367 */ - { 0x0000, 0x0000 }, /* R1368 */ - { 0x0000, 0x0000 }, /* R1369 */ - { 0x0000, 0x0000 }, /* R1370 */ - { 0x0000, 0x0000 }, /* R1371 */ - { 0x0000, 0x0000 }, /* R1372 */ - { 0x0000, 0x0000 }, /* R1373 */ - { 0x0000, 0x0000 }, /* R1374 */ - { 0x0000, 0x0000 }, /* R1375 */ - { 0x0000, 0x0000 }, /* R1376 */ - { 0x0000, 0x0000 }, /* R1377 */ - { 0x0000, 0x0000 }, /* R1378 */ - { 0x0000, 0x0000 }, /* R1379 */ - { 0x0000, 0x0000 }, /* R1380 */ - { 0x0000, 0x0000 }, /* R1381 */ - { 0x0000, 0x0000 }, /* R1382 */ - { 0x0000, 0x0000 }, /* R1383 */ - { 0x0000, 0x0000 }, /* R1384 */ - { 0x0000, 0x0000 }, /* R1385 */ - { 0x0000, 0x0000 }, /* R1386 */ - { 0x0000, 0x0000 }, /* R1387 */ - { 0x0000, 0x0000 }, /* R1388 */ - { 0x0000, 0x0000 }, /* R1389 */ - { 0x0000, 0x0000 }, /* R1390 */ - { 0x0000, 0x0000 }, /* R1391 */ - { 0x0000, 0x0000 }, /* R1392 */ - { 0x0000, 0x0000 }, /* R1393 */ - { 0x0000, 0x0000 }, /* R1394 */ - { 0x0000, 0x0000 }, /* R1395 */ - { 0x0000, 0x0000 }, /* R1396 */ - { 0x0000, 0x0000 }, /* R1397 */ - { 0x0000, 0x0000 }, /* R1398 */ - { 0x0000, 0x0000 }, /* R1399 */ - { 0x0000, 0x0000 }, /* R1400 */ - { 0x0000, 0x0000 }, /* R1401 */ - { 0x0000, 0x0000 }, /* R1402 */ - { 0x0000, 0x0000 }, /* R1403 */ - { 0x0000, 0x0000 }, /* R1404 */ - { 0x0000, 0x0000 }, /* R1405 */ - { 0x0000, 0x0000 }, /* R1406 */ - { 0x0000, 0x0000 }, /* R1407 */ - { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1428 */ - { 0x0000, 0x0000 }, /* R1429 */ - { 0x0000, 0x0000 }, /* R1430 */ - { 0x0000, 0x0000 }, /* R1431 */ - { 0x0000, 0x0000 }, /* R1432 */ - { 0x0000, 0x0000 }, /* R1433 */ - { 0x0000, 0x0000 }, /* R1434 */ - { 0x0000, 0x0000 }, /* R1435 */ - { 0x0000, 0x0000 }, /* R1436 */ - { 0x0000, 0x0000 }, /* R1437 */ - { 0x0000, 0x0000 }, /* R1438 */ - { 0x0000, 0x0000 }, /* R1439 */ - { 0x0000, 0x0000 }, /* R1440 */ - { 0x0000, 0x0000 }, /* R1441 */ - { 0x0000, 0x0000 }, /* R1442 */ - { 0x0000, 0x0000 }, /* R1443 */ - { 0x0000, 0x0000 }, /* R1444 */ - { 0x0000, 0x0000 }, /* R1445 */ - { 0x0000, 0x0000 }, /* R1446 */ - { 0x0000, 0x0000 }, /* R1447 */ - { 0x0000, 0x0000 }, /* R1448 */ - { 0x0000, 0x0000 }, /* R1449 */ - { 0x0000, 0x0000 }, /* R1450 */ - { 0x0000, 0x0000 }, /* R1451 */ - { 0x0000, 0x0000 }, /* R1452 */ - { 0x0000, 0x0000 }, /* R1453 */ - { 0x0000, 0x0000 }, /* R1454 */ - { 0x0000, 0x0000 }, /* R1455 */ - { 0x0000, 0x0000 }, /* R1456 */ - { 0x0000, 0x0000 }, /* R1457 */ - { 0x0000, 0x0000 }, /* R1458 */ - { 0x0000, 0x0000 }, /* R1459 */ - { 0x0000, 0x0000 }, /* R1460 */ - { 0x0000, 0x0000 }, /* R1461 */ - { 0x0000, 0x0000 }, /* R1462 */ - { 0x0000, 0x0000 }, /* R1463 */ - { 0x0000, 0x0000 }, /* R1464 */ - { 0x0000, 0x0000 }, /* R1465 */ - { 0x0000, 0x0000 }, /* R1466 */ - { 0x0000, 0x0000 }, /* R1467 */ - { 0x0000, 0x0000 }, /* R1468 */ - { 0x0000, 0x0000 }, /* R1469 */ - { 0x0000, 0x0000 }, /* R1470 */ - { 0x0000, 0x0000 }, /* R1471 */ - { 0x0000, 0x0000 }, /* R1472 */ - { 0x0000, 0x0000 }, /* R1473 */ - { 0x0000, 0x0000 }, /* R1474 */ - { 0x0000, 0x0000 }, /* R1475 */ - { 0x0000, 0x0000 }, /* R1476 */ - { 0x0000, 0x0000 }, /* R1477 */ - { 0x0000, 0x0000 }, /* R1478 */ - { 0x0000, 0x0000 }, /* R1479 */ - { 0x0000, 0x0000 }, /* R1480 */ - { 0x0000, 0x0000 }, /* R1481 */ - { 0x0000, 0x0000 }, /* R1482 */ - { 0x0000, 0x0000 }, /* R1483 */ - { 0x0000, 0x0000 }, /* R1484 */ - { 0x0000, 0x0000 }, /* R1485 */ - { 0x0000, 0x0000 }, /* R1486 */ - { 0x0000, 0x0000 }, /* R1487 */ - { 0x0000, 0x0000 }, /* R1488 */ - { 0x0000, 0x0000 }, /* R1489 */ - { 0x0000, 0x0000 }, /* R1490 */ - { 0x0000, 0x0000 }, /* R1491 */ - { 0x0000, 0x0000 }, /* R1492 */ - { 0x0000, 0x0000 }, /* R1493 */ - { 0x0000, 0x0000 }, /* R1494 */ - { 0x0000, 0x0000 }, /* R1495 */ - { 0x0000, 0x0000 }, /* R1496 */ - { 0x0000, 0x0000 }, /* R1497 */ - { 0x0000, 0x0000 }, /* R1498 */ - { 0x0000, 0x0000 }, /* R1499 */ - { 0x0000, 0x0000 }, /* R1500 */ - { 0x0000, 0x0000 }, /* R1501 */ - { 0x0000, 0x0000 }, /* R1502 */ - { 0x0000, 0x0000 }, /* R1503 */ - { 0x0000, 0x0000 }, /* R1504 */ - { 0x0000, 0x0000 }, /* R1505 */ - { 0x0000, 0x0000 }, /* R1506 */ - { 0x0000, 0x0000 }, /* R1507 */ - { 0x0000, 0x0000 }, /* R1508 */ - { 0x0000, 0x0000 }, /* R1509 */ - { 0x0000, 0x0000 }, /* R1510 */ - { 0x0000, 0x0000 }, /* R1511 */ - { 0x0000, 0x0000 }, /* R1512 */ - { 0x0000, 0x0000 }, /* R1513 */ - { 0x0000, 0x0000 }, /* R1514 */ - { 0x0000, 0x0000 }, /* R1515 */ - { 0x0000, 0x0000 }, /* R1516 */ - { 0x0000, 0x0000 }, /* R1517 */ - { 0x0000, 0x0000 }, /* R1518 */ - { 0x0000, 0x0000 }, /* R1519 */ - { 0x0000, 0x0000 }, /* R1520 */ - { 0x0000, 0x0000 }, /* R1521 */ - { 0x0000, 0x0000 }, /* R1522 */ - { 0x0000, 0x0000 }, /* R1523 */ - { 0x0000, 0x0000 }, /* R1524 */ - { 0x0000, 0x0000 }, /* R1525 */ - { 0x0000, 0x0000 }, /* R1526 */ - { 0x0000, 0x0000 }, /* R1527 */ - { 0x0000, 0x0000 }, /* R1528 */ - { 0x0000, 0x0000 }, /* R1529 */ - { 0x0000, 0x0000 }, /* R1530 */ - { 0x0000, 0x0000 }, /* R1531 */ - { 0x0000, 0x0000 }, /* R1532 */ - { 0x0000, 0x0000 }, /* R1533 */ - { 0x0000, 0x0000 }, /* R1534 */ - { 0x0000, 0x0000 }, /* R1535 */ - { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ - { 0x0000, 0x0000 }, /* R1546 */ - { 0x0000, 0x0000 }, /* R1547 */ - { 0x0000, 0x0000 }, /* R1548 */ - { 0x0000, 0x0000 }, /* R1549 */ - { 0x0000, 0x0000 }, /* R1550 */ - { 0x0000, 0x0000 }, /* R1551 */ - { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */ - { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */ - { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */ - { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */ - { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */ - { 0x0000, 0x0000 }, /* R1557 */ - { 0x0000, 0x0000 }, /* R1558 */ - { 0x0000, 0x0000 }, /* R1559 */ - { 0x0000, 0x0000 }, /* R1560 */ - { 0x0000, 0x0000 }, /* R1561 */ - { 0x0000, 0x0000 }, /* R1562 */ - { 0x0000, 0x0000 }, /* R1563 */ - { 0x0000, 0x0000 }, /* R1564 */ - { 0x0000, 0x0000 }, /* R1565 */ - { 0x0000, 0x0000 }, /* R1566 */ - { 0x0000, 0x0000 }, /* R1567 */ - { 0x0003, 0x0003 }, /* R1568 - Oversampling */ - { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ -}; - static int wm8994_readable(unsigned int reg) { switch (reg) { @@ -1696,9 +119,9 @@ static int wm8994_readable(unsigned int reg) break; } - if (reg >= ARRAY_SIZE(access_masks)) + if (reg >= WM8994_CACHE_SIZE) return 0; - return access_masks[reg].readable != 0; + return wm8994_access_masks[reg].readable != 0; } static int wm8994_volatile(unsigned int reg) @@ -1730,8 +153,6 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, if (!wm8994_volatile(reg)) wm8994->reg_cache[reg] = value; - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - return wm8994_reg_write(codec->control_data, reg, value); } @@ -1837,7 +258,7 @@ static int configure_clock(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); return 0; } @@ -2071,21 +492,33 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, return 0; } -static const char *aifdac_src_text[] = { +static const char *aif_chan_src_text[] = { "Left", "Right" }; +static const struct soc_enum aif1adcl_src = + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); + +static const struct soc_enum aif1adcr_src = + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); + +static const struct soc_enum aif2adcl_src = + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); + +static const struct soc_enum aif2adcr_src = + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); + static const struct soc_enum aif1dacl_src = - SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); static const struct soc_enum aif1dacr_src = - SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); static const struct soc_enum aif2dacl_src = - SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); static const struct soc_enum aif2dacr_src = - SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); static const struct snd_kcontrol_new wm8994_snd_controls[] = { SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, @@ -2098,6 +531,11 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2_ADC_RIGHT_VOLUME, 1, 119, 0, digital_tlv), +SOC_ENUM("AIF1ADCL Source", aif1adcl_src), +SOC_ENUM("AIF1ADCR Source", aif1adcr_src), +SOC_ENUM("AIF2ADCL Source", aif1adcl_src), +SOC_ENUM("AIF2ADCR Source", aif1adcr_src), + SOC_ENUM("AIF1DACL Source", aif1dacl_src), SOC_ENUM("AIF1DACR Source", aif1dacr_src), SOC_ENUM("AIF2DACL Source", aif1dacl_src), @@ -2228,6 +666,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, static void wm8994_update_class_w(struct snd_soc_codec *codec) { + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int enable = 1; int source = 0; /* GCC flow analysis can't track enable */ int reg, reg_r; @@ -2278,11 +717,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) WM8994_CP_DYN_PWR | WM8994_CP_DYN_SRC_SEL_MASK, source | WM8994_CP_DYN_PWR); + wm8994->hubs.class_w = true; } else { dev_dbg(codec->dev, "Class W disabled\n"); snd_soc_update_bits(codec, WM8994_CLASS_W_1, WM8994_CP_DYN_PWR, 0); + wm8994->hubs.class_w = false; } } @@ -3107,7 +1548,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Tweak DC servo and DSP configuration for * improved performance. */ if (wm8994->revision < 4) { @@ -3151,7 +1592,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { /* Switch over to startup biases */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_BIAS_SRC | @@ -3186,7 +1627,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, } break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -3640,7 +2081,7 @@ static int wm8994_resume(struct snd_soc_codec *codec) break; } - if (!access_masks[i].writable) + if (!wm8994_access_masks[i].writable) continue; wm8994_reg_write(codec->control_data, i, reg_cache[i]); @@ -3894,6 +2335,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) static int wm8994_codec_probe(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, i; codec->control_data = dev_get_drvdata(codec->dev->parent); @@ -4034,10 +2476,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm_hubs_add_analogue_controls(codec); snd_soc_add_controls(codec, wm8994_snd_controls, ARRAY_SIZE(wm8994_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets)); wm_hubs_add_analogue_routes(codec, 0, 0); - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index d8dce26..b8b3166 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -31,4 +31,13 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int micbias, int det, int shrt); +#define WM8994_CACHE_SIZE 1570 + +struct wm8994_access_mask { + unsigned short readable; /* Mask of readable bits */ + unsigned short writable; /* Mask of writable bits */ +}; + +extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; + #endif diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index ecc7c37..c706077 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -23,7 +23,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -805,7 +804,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: /* Initial cold start */ - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Disable LINEOUT discharge */ reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); reg &= ~WM9081_LINEOUT_DISCH; @@ -865,7 +864,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1228,6 +1227,7 @@ static struct snd_soc_dai_driver wm9081_dai = { static int wm9081_probe(struct snd_soc_codec *codec) { struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; u16 reg; @@ -1269,9 +1269,9 @@ static int wm9081_probe(struct snd_soc_codec *codec) ARRAY_SIZE(wm9081_eq_controls)); } - snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets, ARRAY_SIZE(wm9081_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 99c046b..7ba5807 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -28,7 +28,6 @@ #include <linux/slab.h> #include <sound/initval.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <sound/wm9090.h> @@ -443,31 +442,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = { static int wm9090_add_controls(struct snd_soc_codec *codec) { struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; - snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets, ARRAY_SIZE(wm9090_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_add_controls(codec, wm9090_controls, ARRAY_SIZE(wm9090_controls)); if (wm9090->pdata.lin1_diff) { - snd_soc_dapm_add_routes(codec, audio_map_in1_diff, + snd_soc_dapm_add_routes(dapm, audio_map_in1_diff, ARRAY_SIZE(audio_map_in1_diff)); } else { - snd_soc_dapm_add_routes(codec, audio_map_in1_se, + snd_soc_dapm_add_routes(dapm, audio_map_in1_se, ARRAY_SIZE(audio_map_in1_se)); snd_soc_add_controls(codec, wm9090_in1_se_controls, ARRAY_SIZE(wm9090_in1_se_controls)); } if (wm9090->pdata.lin2_diff) { - snd_soc_dapm_add_routes(codec, audio_map_in2_diff, + snd_soc_dapm_add_routes(dapm, audio_map_in2_diff, ARRAY_SIZE(audio_map_in2_diff)); } else { - snd_soc_dapm_add_routes(codec, audio_map_in2_se, + snd_soc_dapm_add_routes(dapm, audio_map_in2_se, ARRAY_SIZE(audio_map_in2_se)); snd_soc_add_controls(codec, wm9090_in2_se_controls, ARRAY_SIZE(wm9090_in2_se_controls)); @@ -514,7 +514,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Restore the register cache */ for (i = 1; i < codec->driver->reg_cache_size; i++) { if (reg_cache[i] == wm9090_reg_defaults[i]) @@ -544,7 +544,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index a144acd..47b357a 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -19,7 +19,6 @@ #include <sound/ac97_codec.h> #include <sound/initval.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "wm9705.h" @@ -203,9 +202,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9705_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets, ARRAY_SIZE(wm9705_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index d2f224d..bf5d4ef 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -20,7 +20,6 @@ #include <sound/ac97_codec.h> #include <sound/initval.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "wm9712.h" #define WM9712_VERSION "0.4" @@ -432,10 +431,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9712_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets, - ARRAY_SIZE(wm9712_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets, + ARRAY_SIZE(wm9712_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -570,7 +570,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec, ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 7da13b0..38ed985 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -26,7 +26,6 @@ #include <sound/pcm_params.h> #include <sound/tlv.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "wm9713.h" @@ -647,10 +646,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9713_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets, ARRAY_SIZE(wm9713_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1147,7 +1148,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec, ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 19ca782..e7a19d6 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -22,7 +22,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -94,6 +93,18 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); u16 reg, reg_l, reg_r, dcs_cfg; + /* If we're using a digital only path and have a previously + * callibrated DC servo offset stored then use that. */ + if (hubs->class_w && hubs->class_w_dcs) { + dev_dbg(codec->dev, "Using cached DC servo offset %x\n", + hubs->class_w_dcs); + snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_DAC_WR_0 | + WM8993_DCS_TRIG_DAC_WR_1); + return; + } + /* Set for 32 series updates */ snd_soc_update_bits(codec, WM8993_DC_SERVO_1, WM8993_DCS_SERIES_NO_01_MASK, @@ -101,34 +112,34 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) wait_for_dc_servo(codec, WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); + /* Different chips in the family support different readback + * methods. + */ + switch (hubs->dcs_readback_mode) { + case 0: + reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) + & WM8993_DCS_INTEG_CHAN_0_MASK; + reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) + & WM8993_DCS_INTEG_CHAN_1_MASK; + break; + case 1: + reg = snd_soc_read(codec, WM8993_DC_SERVO_3); + reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) + >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; + reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; + break; + default: + WARN(1, "Unknown DCS readback method\n"); + break; + } + + dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); + /* Apply correction to DC servo result */ if (hubs->dcs_codes) { dev_dbg(codec->dev, "Applying %d code DC servo correction\n", hubs->dcs_codes); - /* Different chips in the family support different - * readback methods. - */ - switch (hubs->dcs_readback_mode) { - case 0: - reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) - & WM8993_DCS_INTEG_CHAN_0_MASK;; - reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) - & WM8993_DCS_INTEG_CHAN_1_MASK; - break; - case 1: - reg = snd_soc_read(codec, WM8993_DC_SERVO_3); - reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) - >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; - reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; - break; - default: - WARN(1, "Unknown DCS readback method\n"); - break; - } - - dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); - /* HPOUT1L */ if (reg_l + hubs->dcs_codes > 0 && reg_l + hubs->dcs_codes < 0xff) @@ -148,7 +159,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) wait_for_dc_servo(codec, WM8993_DCS_TRIG_DAC_WR_0 | WM8993_DCS_TRIG_DAC_WR_1); + } else { + dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT; + dcs_cfg |= reg_r; } + + /* Save the callibrated offset if we're in class W mode and + * therefore don't have any analogue signal mixed in. */ + if (hubs->class_w) + hubs->class_w_dcs = dcs_cfg; } /* @@ -163,6 +182,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); + /* Updating the analogue gains invalidates the DC servo cache */ + hubs->class_w_dcs = 0; + /* If we're applying an offset correction then updating the * callibration would be likely to introduce further offsets. */ if (hubs->dcs_codes) @@ -791,6 +813,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = { int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* Latch volume update bits & default ZC on */ snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME, WM8993_IN1_VU, WM8993_IN1_VU); @@ -819,7 +843,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) snd_soc_add_controls(codec, analogue_snd_controls, ARRAY_SIZE(analogue_snd_controls)); - snd_soc_dapm_new_controls(codec, analogue_dapm_widgets, + snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, ARRAY_SIZE(analogue_dapm_widgets)); return 0; } @@ -828,24 +852,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls); int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, int lineout1_diff, int lineout2_diff) { - snd_soc_dapm_add_routes(codec, analogue_routes, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_add_routes(dapm, analogue_routes, ARRAY_SIZE(analogue_routes)); if (lineout1_diff) - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout1_diff_routes, ARRAY_SIZE(lineout1_diff_routes)); else - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout1_se_routes, ARRAY_SIZE(lineout1_se_routes)); if (lineout2_diff) - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout2_diff_routes, ARRAY_SIZE(lineout2_diff_routes)); else - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout2_se_routes, ARRAY_SIZE(lineout2_se_routes)); @@ -872,7 +898,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, * VMID as an output and can disable it. */ if (lineout1_diff && lineout2_diff) - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; if (lineout1fb) snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index e51c166..f8a5e97 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -23,6 +23,9 @@ struct wm_hubs_data { int dcs_codes; int dcs_readback_mode; int hp_startup_mode; + + bool class_w; + u16 class_w_dcs; }; extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index bc9e6b0b..24b031e 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -18,7 +18,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/dma.h> #include <asm/mach-types.h> @@ -132,26 +131,27 @@ static const struct snd_soc_dapm_route audio_map[] = { static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add davinci-evm specific widgets */ - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* not connected */ - snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); - snd_soc_dapm_disable_pin(codec, "HPLCOM"); - snd_soc_dapm_disable_pin(codec, "HPRCOM"); + snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_disable_pin(dapm, "HPLCOM"); + snd_soc_dapm_disable_pin(dapm, "HPRCOM"); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c index 6c6666a..0fe558c 100644 --- a/sound/soc/davinci/davinci-sffsdr.c +++ b/sound/soc/davinci/davinci-sffsdr.c @@ -21,7 +21,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/dma.h> #include <asm/mach-types.h> diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index 28ab5ff..dfe1d7f 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -15,7 +15,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -79,11 +78,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index dd4fffd..e20c9e1 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c @@ -22,7 +22,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include "../codecs/tlv320aic23.h" diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index d2d98c7..ad21f81 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -456,13 +456,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) static struct snd_soc_dai_driver imx_ssi_dai = { .probe = imx_ssi_dai_probe, .playback = { - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index 39f2373..db157f7 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c @@ -17,7 +17,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> static struct snd_soc_card imx_phycore; diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 30fdb15..75b4c72 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c @@ -19,7 +19,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <mach/audmux.h> @@ -213,11 +212,12 @@ static struct snd_soc_jack_pin mic_jack_pins[] = { static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets, + snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets, ARRAY_SIZE(wm1133_ev1_widgets)); - snd_soc_dapm_add_routes(codec, wm1133_ev1_map, + snd_soc_dapm_add_routes(dapm, wm1133_ev1_map, ARRAY_SIZE(wm1133_ev1_map)); /* Headphone jack detection */ @@ -234,7 +234,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, SND_JACK_BTN_0); - snd_soc_dapm_force_enable_pin(codec, "Mic Bias"); + snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); return 0; } diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index f3cffd1..419bf4f 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -28,7 +28,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include "jz4740-i2s.h" diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index ef1a99e..49723e3 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -19,7 +19,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <linux/gpio.h> #define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29) @@ -59,10 +58,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_nc_pin(codec, "LIN"); - snd_soc_dapm_nc_pin(codec, "RIN"); + snd_soc_dapm_nc_pin(dapm, "LIN"); + snd_soc_dapm_nc_pin(dapm, "RIN"); ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT); if (ret < 0) { @@ -70,9 +70,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets)); - snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_new_controls(dapm, qi_lb60_widgets, + ARRAY_SIZE(qi_lb60_widgets)); + snd_soc_dapm_add_routes(dapm, qi_lb60_routes, + ARRAY_SIZE(qi_lb60_routes)); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 16ec2a2..8f49e16 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig @@ -11,10 +11,19 @@ config SND_KIRKWOOD_SOC_I2S config SND_KIRKWOOD_SOC_OPENRD tristate "SoC Audio support for Kirkwood Openrd Client" - depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT + depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) select SND_KIRKWOOD_SOC_I2S select SND_SOC_CS42L51 help Say Y if you want to add support for SoC audio on Openrd Client. +config SND_KIRKWOOD_SOC_T5325 + tristate "SoC Audio support for HP t5325" + depends on SND_KIRKWOOD_SOC && MACH_T5325 + select SND_KIRKWOOD_SOC_I2S + select SND_SOC_ALC5623 + help + Say Y if you want to add support for SoC audio on + the HP t5325 thin client. + diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile index 33a16dc..3e62ae9 100644 --- a/sound/soc/kirkwood/Makefile +++ b/sound/soc/kirkwood/Makefile @@ -5,5 +5,7 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o snd-soc-openrd-objs := kirkwood-openrd.o +snd-soc-t5325-objs := kirkwood-t5325.o obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o +obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c index 9d7c81e..d863afb 100644 --- a/sound/soc/kirkwood/kirkwood-openrd.c +++ b/sound/soc/kirkwood/kirkwood-openrd.c @@ -86,7 +86,7 @@ static int __init openrd_client_init(void) { int ret; - if (!machine_is_openrd_client()) + if (!machine_is_openrd_client() && !machine_is_openrd_ultimate()) return 0; openrd_client_snd_device = platform_device_alloc("soc-audio", -1); diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c new file mode 100644 index 0000000..c8d2195 --- /dev/null +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -0,0 +1,141 @@ +/* + * kirkwood-t5325.c + * + * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <sound/soc.h> +#include <mach/kirkwood.h> +#include <plat/audio.h> +#include <asm/mach-types.h> +#include "../codecs/alc5623.h" + +static int t5325_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + unsigned int freq, fmt; + + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) + return ret; + + freq = params_rate(params) * 256; + + return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN); + +} + +static struct snd_soc_ops t5325_ops = { + .hw_params = t5325_hw_params, +}; + +static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_soc_dapm_route t5325_route[] = { + { "Headphone Jack", NULL, "HPL" }, + { "Headphone Jack", NULL, "HPR" }, + + {"Speaker", NULL, "SPKOUT"}, + {"Speaker", NULL, "SPKOUTN"}, + + { "MIC1", NULL, "Mic Jack" }, + { "MIC2", NULL, "Mic Jack" }, +}; + +static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets, + ARRAY_SIZE(t5325_dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route)); + + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link t5325_dai[] = { +{ + .name = "ALC5621", + .stream_name = "ALC5621 HiFi", + .cpu_dai_name = "kirkwood-i2s", + .platform_name = "kirkwood-pcm-audio", + .codec_dai_name = "alc5621-hifi", + .codec_name = "alc562x-codec.0-001a", + .ops = &t5325_ops, + .init = t5325_dai_init, +}, +}; + + +static struct snd_soc_card t5325 = { + .name = "t5325", + .dai_link = t5325_dai, + .num_links = ARRAY_SIZE(t5325_dai), +}; + +static struct platform_device *t5325_snd_device; + +static int __init t5325_init(void) +{ + int ret; + + if (!machine_is_t5325()) + return 0; + + t5325_snd_device = platform_device_alloc("soc-audio", -1); + if (!t5325_snd_device) + return -ENOMEM; + + platform_set_drvdata(t5325_snd_device, + &t5325); + + ret = platform_device_add(t5325_snd_device); + if (ret) { + printk(KERN_ERR "%s: platform_device_add failed\n", __func__); + platform_device_put(t5325_snd_device); + } + + return ret; +} +module_init(t5325_init); + +static void __exit t5325_exit(void) +{ + platform_device_unregister(t5325_snd_device); +} +module_exit(t5325_exit); + +MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); +MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c index 161f5b6..38a2d0d 100644 --- a/sound/soc/nuc900/nuc900-audio.c +++ b/sound/soc/nuc900/nuc900-audio.c @@ -18,7 +18,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "nuc900-audio.h" diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 979dd50..1617504 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -22,7 +22,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -114,20 +113,21 @@ static const struct snd_soc_dapm_route audio_map[] = { static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add am3517-evm specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic In"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 438146a..2101bdc 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -26,7 +26,7 @@ #include <linux/spinlock.h> #include <linux/tty.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -94,6 +94,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &codec->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; @@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, /* Setup pins after corresponding bits if changed */ pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); else - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); } pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); else - snd_soc_dapm_disable_pin(codec, "Earpiece"); + snd_soc_dapm_disable_pin(dapm, "Earpiece"); } pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Microphone"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); else - snd_soc_dapm_disable_pin(codec, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Microphone"); } pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); } pin = !!(pins & (1 << AMS_DELTA_AGC)); if (pin != ams_delta_audio_agc) { ams_delta_audio_agc = pin; changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "AGCIN"); + snd_soc_dapm_enable_pin(dapm, "AGCIN"); else - snd_soc_dapm_disable_pin(codec, "AGCIN"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); } if (changed) - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); @@ -164,19 +165,20 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned short pins, mode; - pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") << + pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << AMS_DELTA_MOUTHPIECE) | - (snd_soc_dapm_get_pin_status(codec, "Earpiece") << + (snd_soc_dapm_get_pin_status(dapm, "Earpiece") << AMS_DELTA_EARPIECE)); if (pins) - pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") << + pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") << AMS_DELTA_MICROPHONE); else - pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") << + pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") << AMS_DELTA_MICROPHONE) | - (snd_soc_dapm_get_pin_status(codec, "Speaker") << + (snd_soc_dapm_get_pin_status(dapm, "Speaker") << AMS_DELTA_SPEAKER) | (ams_delta_audio_agc << AMS_DELTA_AGC)); @@ -300,6 +302,7 @@ static int cx81801_open(struct tty_struct *tty) static void cx81801_close(struct tty_struct *tty) { struct snd_soc_codec *codec = tty->disc_data; + struct snd_soc_dapm_context *dapm = &codec->dapm; del_timer_sync(&cx81801_timer); @@ -312,12 +315,12 @@ static void cx81801_close(struct tty_struct *tty) v253_ops.close(tty); /* Revert back to default audio input/output constellation */ - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); - snd_soc_dapm_enable_pin(codec, "Earpiece"); - snd_soc_dapm_enable_pin(codec, "Microphone"); - snd_soc_dapm_disable_pin(codec, "Speaker"); - snd_soc_dapm_disable_pin(codec, "AGCIN"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); + snd_soc_dapm_sync(dapm); } /* Line discipline .hangup() */ @@ -432,16 +435,16 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card, case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, AMS_DELTA_LATCH2_MODEM_NRESET); break; case SND_SOC_BIAS_OFF: - if (codec->bias_level != SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level != SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 0); } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -492,6 +495,7 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; int ret; @@ -541,7 +545,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) } /* Add board specific DAPM widgets and routes */ - ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, ARRAY_SIZE(ams_delta_dapm_widgets)); if (ret) { dev_warn(card->dev, @@ -550,7 +554,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } - ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map, + ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, ARRAY_SIZE(ams_delta_audio_map)); if (ret) { dev_warn(card->dev, @@ -560,13 +564,13 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) } /* Set up initial pin constellation */ - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); - snd_soc_dapm_enable_pin(codec, "Earpiece"); - snd_soc_dapm_enable_pin(codec, "Microphone"); - snd_soc_dapm_disable_pin(codec, "Speaker"); - snd_soc_dapm_disable_pin(codec, "AGCIN"); - snd_soc_dapm_disable_pin(codec, "AGCOUT"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); + snd_soc_dapm_disable_pin(dapm, "AGCOUT"); + snd_soc_dapm_sync(dapm); /* Add virtual switch */ ret = snd_soc_add_controls(codec, ams_delta_audio_controls, diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c index fd3a40f..0ae3470 100644 --- a/sound/soc/omap/igep0020.c +++ b/sound/soc/omap/igep0020.c @@ -24,7 +24,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index a3b6d89..fe215f3 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -27,7 +27,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -58,6 +57,7 @@ static int n810_dmic_func; static void n810_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int hp = 0, line1l = 0; switch (n810_jack_func) { @@ -72,25 +72,25 @@ static void n810_ext_control(struct snd_soc_codec *codec) } if (n810_spk_func) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); if (hp) - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); else - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); if (line1l) - snd_soc_dapm_enable_pin(codec, "LINE1L"); + snd_soc_dapm_enable_pin(dapm, "LINE1L"); else - snd_soc_dapm_disable_pin(codec, "LINE1L"); + snd_soc_dapm_disable_pin(dapm, "LINE1L"); if (n810_dmic_func) - snd_soc_dapm_enable_pin(codec, "DMic"); + snd_soc_dapm_enable_pin(dapm, "DMic"); else - snd_soc_dapm_disable_pin(codec, "DMic"); + snd_soc_dapm_disable_pin(dapm, "DMic"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int n810_startup(struct snd_pcm_substream *substream) @@ -274,17 +274,18 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = { static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Not connected */ - snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); - snd_soc_dapm_nc_pin(codec, "HPLCOM"); - snd_soc_dapm_nc_pin(codec, "HPRCOM"); - snd_soc_dapm_nc_pin(codec, "MIC3L"); - snd_soc_dapm_nc_pin(codec, "MIC3R"); - snd_soc_dapm_nc_pin(codec, "LINE1R"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); + snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_nc_pin(dapm, "HPLCOM"); + snd_soc_dapm_nc_pin(dapm, "HPRCOM"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); + snd_soc_dapm_nc_pin(dapm, "MIC3R"); + snd_soc_dapm_nc_pin(dapm, "LINE1R"); + snd_soc_dapm_nc_pin(dapm, "LINE2L"); + snd_soc_dapm_nc_pin(dapm, "LINE2R"); /* Add N810 specific controls */ err = snd_soc_add_controls(codec, aic33_n810_controls, @@ -293,13 +294,13 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add N810 specific widgets */ - snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets, ARRAY_SIZE(aic33_dapm_widgets)); /* Set up N810 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c index cf3fc8a..29b60d6 100644 --- a/sound/soc/omap/omap2evm.c +++ b/sound/soc/omap/omap2evm.c @@ -26,7 +26,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index e56832b..40db813 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c @@ -24,7 +24,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 810f1e36..0daa044 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c @@ -22,7 +22,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 4ee33ce..8047c521e 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -28,7 +28,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <plat/mcbsp.h> @@ -170,51 +169,53 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = { static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* All TWL4030 output pins are floating */ - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "HSOL"); - snd_soc_dapm_nc_pin(codec, "HSOR"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - snd_soc_dapm_nc_pin(codec, "HFL"); - snd_soc_dapm_nc_pin(codec, "HFR"); - snd_soc_dapm_nc_pin(codec, "VIBRA"); - - ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "HSOL"); + snd_soc_dapm_nc_pin(dapm, "HSOR"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + snd_soc_dapm_nc_pin(dapm, "HFL"); + snd_soc_dapm_nc_pin(dapm, "HFR"); + snd_soc_dapm_nc_pin(dapm, "VIBRA"); + + ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets, ARRAY_SIZE(omap3pandora_out_dapm_widgets)); if (ret < 0) return ret; - snd_soc_dapm_add_routes(codec, omap3pandora_out_map, + snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, ARRAY_SIZE(omap3pandora_out_map)); - return snd_soc_dapm_sync(codec); + return snd_soc_dapm_sync(dapm); } static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Not comnnected */ - snd_soc_dapm_nc_pin(codec, "HSMIC"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); + snd_soc_dapm_nc_pin(dapm, "HSMIC"); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); - ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, ARRAY_SIZE(omap3pandora_in_dapm_widgets)); if (ret < 0) return ret; - snd_soc_dapm_add_routes(codec, omap3pandora_in_map, + snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, ARRAY_SIZE(omap3pandora_in_map)); - return snd_soc_dapm_sync(codec); + return snd_soc_dapm_sync(dapm); } static struct snd_soc_ops omap3pandora_ops = { diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index f0e6625..18d053d 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c @@ -26,7 +26,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -116,19 +115,20 @@ static const struct snd_soc_dapm_route audio_map[] = { static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add osk5912 specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up osk5912 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index e95a607..bbcf380 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c @@ -24,7 +24,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 04b5723..150042a 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -30,7 +30,6 @@ #include <sound/jack.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <plat/mcbsp.h> #include <asm/mach-types.h> @@ -58,19 +57,21 @@ static int rx51_jack_func; static void rx51_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (rx51_spk_func) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); if (rx51_dmic_func) - snd_soc_dapm_enable_pin(codec, "DMic"); + snd_soc_dapm_enable_pin(dapm, "DMic"); else - snd_soc_dapm_disable_pin(codec, "DMic"); + snd_soc_dapm_disable_pin(dapm, "DMic"); gpio_set_value(RX51_TVOUT_SEL_GPIO, rx51_jack_func == RX51_JACK_TVOUT); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int rx51_startup(struct snd_pcm_substream *substream) @@ -244,12 +245,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "MIC3L"); - snd_soc_dapm_nc_pin(codec, "MIC3R"); - snd_soc_dapm_nc_pin(codec, "LINE1R"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); + snd_soc_dapm_nc_pin(dapm, "MIC3R"); + snd_soc_dapm_nc_pin(dapm, "LINE1R"); /* Add RX-51 specific controls */ err = snd_soc_add_controls(codec, aic34_rx51_controls, @@ -258,13 +260,13 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add RX-51 specific widgets */ - snd_soc_dapm_new_controls(codec, aic34_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets, ARRAY_SIZE(aic34_dapm_widgets)); /* Set up RX-51 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); /* AV jack detection */ err = snd_soc_jack_new(codec, "AV Jack", diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 07fbcf7..3f72d17 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -28,7 +28,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -191,39 +190,40 @@ static const struct snd_soc_dapm_route audio_map[] = { static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add SDP3430 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets, ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); if (ret) return ret; /* Set up SDP3430 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP3430 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); /* TWL4030 not connected pins */ - snd_soc_dapm_nc_pin(codec, "AUXL"); - snd_soc_dapm_nc_pin(codec, "AUXR"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); - - snd_soc_dapm_nc_pin(codec, "OUTL"); - snd_soc_dapm_nc_pin(codec, "OUTR"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - - ret = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "AUXL"); + snd_soc_dapm_nc_pin(dapm, "AUXR"); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); + + snd_soc_dapm_nc_pin(dapm, "OUTL"); + snd_soc_dapm_nc_pin(dapm, "OUTR"); + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 4b4463d..ebbd62f 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -24,7 +24,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <plat/hardware.h> @@ -129,6 +128,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add SDP4430 specific controls */ @@ -138,25 +138,25 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) return ret; /* Add SDP4430 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); if (ret) return ret; /* Set up SDP4430 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP4430 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); /* TWL6040 not connected pins */ - snd_soc_dapm_nc_pin(codec, "AFML"); - snd_soc_dapm_nc_pin(codec, "AFMR"); + snd_soc_dapm_nc_pin(dapm, "AFML"); + snd_soc_dapm_nc_pin(dapm, "AFMR"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); return ret; } diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 718031e..0170994 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c @@ -24,7 +24,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/hardware.h> @@ -162,35 +161,36 @@ static const struct snd_soc_dapm_route audio_map[] = { static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add Zoom2 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets, ARRAY_SIZE(zoom2_twl4030_dapm_widgets)); if (ret) return ret; /* Set up Zoom2 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* Zoom2 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); - snd_soc_dapm_enable_pin(codec, "Aux In"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Aux In"); /* TWL4030 not connected pins */ - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - - ret = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + + ret = snd_soc_dapm_sync(dapm); return ret; } diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index f451acd..fc592f0 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -23,7 +23,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/corgi.h> @@ -48,51 +47,53 @@ static int corgi_spk_func; static void corgi_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ switch (corgi_jack_func) { case CORGI_HP: /* set = unmute headphone */ gpio_set_value(CORGI_GPIO_MUTE_L, 1); gpio_set_value(CORGI_GPIO_MUTE_R, 1); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_MIC: /* reset = mute headphone */ gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 0); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_LINE: gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 0); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_HEADSET: gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 1); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); break; } if (corgi_spk_func == CORGI_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int corgi_startup(struct snd_pcm_substream *substream) @@ -279,10 +280,11 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = { static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "LLINEIN"); - snd_soc_dapm_nc_pin(codec, "RLINEIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); /* Add corgi specific controls */ err = snd_soc_add_controls(codec, wm8731_corgi_controls, @@ -291,13 +293,13 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add corgi specific widgets */ - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up corgi specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index c82cedb..28333e7 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -16,7 +16,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <mach/audio.h> #include <mach/eseries-gpio.h> @@ -92,23 +91,24 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - - snd_soc_dapm_nc_pin(codec, "HPOUTL"); - snd_soc_dapm_nc_pin(codec, "HPOUTR"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e740_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_nc_pin(dapm, "HPOUTL"); + snd_soc_dapm_nc_pin(dapm, "HPOUTR"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "CDINL"); + snd_soc_dapm_nc_pin(dapm, "CDINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + snd_soc_dapm_new_controls(dapm, e740_dapm_widgets, ARRAY_SIZE(e740_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 4c14380..01bf316 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -16,7 +16,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <mach/audio.h> #include <mach/eseries-gpio.h> @@ -74,23 +73,24 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - - snd_soc_dapm_nc_pin(codec, "LOUT"); - snd_soc_dapm_nc_pin(codec, "ROUT"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e750_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_nc_pin(dapm, "LOUT"); + snd_soc_dapm_nc_pin(dapm, "ROUT"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "CDINL"); + snd_soc_dapm_nc_pin(dapm, "CDINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + snd_soc_dapm_new_controls(dapm, e750_dapm_widgets, ARRAY_SIZE(e750_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index d42e5fe..c6a37c6 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -16,7 +16,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/audio.h> @@ -75,12 +74,13 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, e800_dapm_widgets, + snd_soc_dapm_new_controls(dapm, e800_dapm_widgets, ARRAY_SIZE(e800_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index eadf9d3..fc22e6e 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -26,7 +26,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/audio.h> diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 5ef0526..67dcc36 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c @@ -26,7 +26,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/uda1380.h> #include <mach/magician.h> @@ -44,27 +43,29 @@ static int magician_in_sel = MAGICIAN_MIC; static void magician_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (magician_spk_switch) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); if (magician_hp_switch) - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); else - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); switch (magician_in_sel) { case MAGICIAN_MIC: - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case MAGICIAN_MIC_EXT: - snd_soc_dapm_disable_pin(codec, "Call Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); break; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int magician_startup(struct snd_pcm_substream *substream) @@ -399,15 +400,16 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = { static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* NC codec pins */ - snd_soc_dapm_nc_pin(codec, "VOUTLHP"); - snd_soc_dapm_nc_pin(codec, "VOUTRHP"); + snd_soc_dapm_nc_pin(dapm, "VOUTLHP"); + snd_soc_dapm_nc_pin(dapm, "VOUTRHP"); /* FIXME: is anything connected here? */ - snd_soc_dapm_nc_pin(codec, "VINL"); - snd_soc_dapm_nc_pin(codec, "VINR"); + snd_soc_dapm_nc_pin(dapm, "VINL"); + snd_soc_dapm_nc_pin(dapm, "VINR"); /* Add magician specific controls */ err = snd_soc_add_controls(codec, uda1380_magician_controls, @@ -416,13 +418,13 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add magician specific widgets */ - snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, + snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, ARRAY_SIZE(uda1380_dapm_widgets)); /* Set up magician specific audio path interconnects */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index f284cc5..0d70fc8 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -50,7 +50,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/ac97_codec.h> @@ -130,13 +129,14 @@ static const struct snd_soc_dapm_route audio_map[] = { static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned short reg; /* Add mioa701 specific widgets */ - snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets)); + snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets)); /* Set up mioa701 specific audio path audio_mapnects */ - snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map)); /* Prepare GPIO8 for rear speaker amplifier */ reg = codec->driver->read(codec, AC97_GPIO_CFG); @@ -146,12 +146,12 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) reg = codec->driver->read(codec, AC97_3D_CONTROL); codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000); - snd_soc_dapm_enable_pin(codec, "Front Speaker"); - snd_soc_dapm_enable_pin(codec, "Rear Speaker"); - snd_soc_dapm_enable_pin(codec, "Front Mic"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(dapm, "Front Speaker"); + snd_soc_dapm_enable_pin(dapm, "Rear Speaker"); + snd_soc_dapm_enable_pin(dapm, "Front Mic"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 13f6d48..857db96 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -21,7 +21,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -77,37 +76,38 @@ static struct snd_soc_card palm27x_asoc; static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* add palm27x specific widgets */ - err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets, ARRAY_SIZE(palm27x_dapm_widgets)); if (err) return err; /* set up palm27x specific audio path audio_map */ - err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (err) return err; /* connected pins */ if (machine_is_palmld()) - snd_soc_dapm_enable_pin(codec, "MIC1"); - snd_soc_dapm_enable_pin(codec, "HPOUTL"); - snd_soc_dapm_enable_pin(codec, "HPOUTR"); - snd_soc_dapm_enable_pin(codec, "LOUT2"); - snd_soc_dapm_enable_pin(codec, "ROUT2"); + snd_soc_dapm_enable_pin(dapm, "MIC1"); + snd_soc_dapm_enable_pin(dapm, "HPOUTL"); + snd_soc_dapm_enable_pin(dapm, "HPOUTR"); + snd_soc_dapm_enable_pin(dapm, "LOUT2"); + snd_soc_dapm_enable_pin(dapm, "ROUT2"); /* not connected pins */ - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONOOUT"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - err = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONOOUT"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + err = snd_soc_dapm_sync(dapm); if (err) return err; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 84edd03..6298ee1 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -23,7 +23,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <asm/hardware/locomo.h> @@ -46,6 +45,8 @@ static int poodle_spk_func; static void poodle_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ if (poodle_jack_func == POODLE_HP) { /* set = unmute headphone */ @@ -53,23 +54,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec) POODLE_LOCOMO_GPIO_MUTE_L, 1); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 1); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); } else { locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_L, 0); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 0); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); } /* set the enpoints to their new connetion states */ if (poodle_spk_func == POODLE_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int poodle_startup(struct snd_pcm_substream *substream) @@ -244,11 +245,12 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = { static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "LLINEIN"); - snd_soc_dapm_nc_pin(codec, "RLINEIN"); - snd_soc_dapm_enable_pin(codec, "MICIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); + snd_soc_dapm_enable_pin(dapm, "MICIN"); /* Add poodle specific controls */ err = snd_soc_add_controls(codec, wm8731_poodle_controls, @@ -257,13 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add poodle specific widgets */ - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up poodle specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 2cda82bc..0fd60f4 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c @@ -22,7 +22,6 @@ #include <linux/gpio.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c index d63cb47..9595189 100644 --- a/sound/soc/pxa/saarb.c +++ b/sound/soc/pxa/saarb.c @@ -18,7 +18,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_saarb = { static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_new_controls(codec, saarb_dapm_widgets, + snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets, ARRAY_SIZE(saarb_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Speaker"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); - snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 0b30d7d..c2acb69 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -23,7 +23,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/spitz.h> @@ -46,61 +45,63 @@ static int spitz_spk_func; static void spitz_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (spitz_spk_func == SPITZ_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* set up jack connection */ switch (spitz_jack_func) { case SPITZ_HP: /* enable and unmute hp jack, disable mic bias */ - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 1); gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_MIC: /* enable mic jack and bias, mute hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_LINE: /* enable line jack, disable mic bias and mute hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_HEADSET: /* enable and unmute headset jack enable mic bias, mute L hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_HP_OFF: /* jack removed, everything off */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int spitz_startup(struct snd_pcm_substream *substream) @@ -281,16 +282,17 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = { static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* NC codec pins */ - snd_soc_dapm_nc_pin(codec, "RINPUT1"); - snd_soc_dapm_nc_pin(codec, "LINPUT2"); - snd_soc_dapm_nc_pin(codec, "RINPUT2"); - snd_soc_dapm_nc_pin(codec, "LINPUT3"); - snd_soc_dapm_nc_pin(codec, "RINPUT3"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONO1"); + snd_soc_dapm_nc_pin(dapm, "RINPUT1"); + snd_soc_dapm_nc_pin(dapm, "LINPUT2"); + snd_soc_dapm_nc_pin(dapm, "RINPUT2"); + snd_soc_dapm_nc_pin(dapm, "LINPUT3"); + snd_soc_dapm_nc_pin(dapm, "RINPUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONO1"); /* Add spitz specific controls */ err = snd_soc_add_controls(codec, wm8750_spitz_controls, @@ -299,13 +301,13 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add spitz specific widgets */ - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); /* Set up spitz specific audio paths */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c index 248c283..f881f65 100644 --- a/sound/soc/pxa/tavorevb3.c +++ b/sound/soc/pxa/tavorevb3.c @@ -18,7 +18,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_evb3 = { static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_new_controls(codec, evb3_dapm_widgets, + snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets, ARRAY_SIZE(evb3_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Speaker"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); - snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 7b983f9..f75804e 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -26,7 +26,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> #include <mach/tosa.h> @@ -49,31 +48,33 @@ static int tosa_spk_func; static void tosa_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ switch (tosa_jack_func) { case TOSA_HP: - snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case TOSA_MIC_INT: - snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case TOSA_HEADSET: - snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); break; } if (tosa_spk_func == TOSA_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int tosa_startup(struct snd_pcm_substream *substream) @@ -191,10 +192,11 @@ static const struct snd_kcontrol_new tosa_controls[] = { static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONOOUT"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONOOUT"); /* add tosa specific controls */ err = snd_soc_add_controls(codec, tosa_controls, @@ -203,13 +205,13 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) return err; /* add tosa specific widgets */ - snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets, ARRAY_SIZE(tosa_dapm_widgets)); /* set up tosa specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index 4cc841b..2d4f896 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c @@ -21,7 +21,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> @@ -140,22 +139,23 @@ static const struct snd_soc_dapm_route audio_map[] = { static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* NC codec pins */ - snd_soc_dapm_disable_pin(codec, "LINPUT3"); - snd_soc_dapm_disable_pin(codec, "RINPUT3"); - snd_soc_dapm_disable_pin(codec, "OUT3"); - snd_soc_dapm_disable_pin(codec, "MONO"); + snd_soc_dapm_disable_pin(dapm, "LINPUT3"); + snd_soc_dapm_disable_pin(dapm, "RINPUT3"); + snd_soc_dapm_disable_pin(dapm, "OUT3"); + snd_soc_dapm_disable_pin(dapm, "MONO"); /* Add z2 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); /* Set up z2 specific audio paths */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) goto err; diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index d27e05a..b222a7d 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c @@ -20,7 +20,6 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "../codecs/wm9713.h" #include "pxa2xx-ac97.h" @@ -73,21 +72,22 @@ static const struct snd_soc_dapm_route audio_map[] = { static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; if (clk_pout) snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, clk_get_rate(pout), 0); - snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, + snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets, ARRAY_SIZE(zylonite_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* Static setup for now */ - snd_soc_dapm_enable_pin(codec, "Headphone"); - snd_soc_dapm_enable_pin(codec, "Headset Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Headphone"); + snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig deleted file mode 100644 index d85bf8a..0000000 --- a/sound/soc/s3c24xx/Kconfig +++ /dev/null @@ -1,171 +0,0 @@ -config SND_S3C24XX_SOC - tristate "SoC Audio for the Samsung S3CXXXX chips" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 - select S3C64XX_DMA if ARCH_S3C64XX - select S3C2410_DMA if ARCH_S3C2410 - help - Say Y or M if you want to add support for codecs attached to - the S3C24XX AC97 or I2S interfaces. You will also need to - select the audio interfaces to support below. - -config SND_S3C24XX_SOC_I2S - tristate - select S3C2410_DMA - -config SND_S3C_I2SV2_SOC - tristate - -config SND_S3C2412_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - select S3C2410_DMA - -config SND_S3C64XX_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - select S3C64XX_DMA - -config SND_S3C64XX_SOC_I2S_V4 - tristate - select SND_S3C_I2SV2_SOC - select S3C64XX_DMA - -config SND_S3C_SOC_PCM - tristate - -config SND_S3C_SOC_AC97 - tristate - select SND_SOC_AC97_BUS - -config SND_S5P_SOC_SPDIF - tristate - select SND_SOC_SPDIF - -config SND_S3C24XX_SOC_NEO1973_WM8753 - tristate "SoC I2S Audio support for NEO1973 - WM8753" - depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 - select SND_S3C24XX_SOC_I2S - select SND_SOC_WM8753 - help - Say Y if you want to add support for SoC audio on smdk2440 - with the WM8753. - -config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753 - tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" - depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02 - select SND_S3C24XX_SOC_I2S - select SND_SOC_WM8753 - help - This driver provides audio support for the Openmoko Neo FreeRunner - smartphone. - -config SND_S3C24XX_SOC_JIVE_WM8750 - tristate "SoC I2S Audio support for Jive" - depends on SND_S3C24XX_SOC && MACH_JIVE - select SND_SOC_WM8750 - select SND_S3C2412_SOC_I2S - help - Sat Y if you want to add support for SoC audio on the Jive. - -config SND_S3C64XX_SOC_WM8580 - tristate "SoC I2S Audio support for WM8580 on SMDK64XX" - depends on SND_S3C24XX_SOC && MACH_SMDK6410 - select SND_SOC_WM8580 - select SND_S3C64XX_SOC_I2S_V4 - help - Say Y if you want to add support for SoC audio on the SMDK6410. - -config SND_S3C24XX_SOC_SMDK2443_WM9710 - tristate "SoC AC97 Audio support for SMDK2443 - WM9710" - depends on SND_S3C24XX_SOC && MACH_SMDK2443 - select S3C2410_DMA - select AC97_BUS - select SND_SOC_AC97_CODEC - select SND_S3C_SOC_AC97 - help - Say Y if you want to add support for SoC audio on smdk2443 - with the WM9710. - -config SND_S3C24XX_SOC_LN2440SBC_ALC650 - tristate "SoC AC97 Audio support for LN2440SBC - ALC650" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select S3C2410_DMA - select AC97_BUS - select SND_SOC_AC97_CODEC - select SND_S3C_SOC_AC97 - help - Say Y if you want to add support for SoC audio on ln2440sbc - with the ALC650. - -config SND_S3C24XX_SOC_S3C24XX_UDA134X - tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S - select SND_SOC_L3 - select SND_SOC_UDA134X - -config SND_S3C24XX_SOC_SIMTEC - tristate - help - Internal node for common S3C24XX/Simtec suppor - -config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23 - tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S - select SND_SOC_TLV320AIC23 - select SND_S3C24XX_SOC_SIMTEC - -config SND_S3C24XX_SOC_SIMTEC_HERMES - tristate "SoC I2S Audio support for Simtec Hermes board" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S - select SND_SOC_TLV320AIC3X - select SND_S3C24XX_SOC_SIMTEC - -config SND_S3C24XX_SOC_RX1950_UDA1380 - tristate "Audio support for the HP iPAQ RX1950" - depends on SND_S3C24XX_SOC && MACH_RX1950 - select SND_S3C24XX_SOC_I2S - select SND_SOC_UDA1380 - help - This driver provides audio support for HP iPAQ RX1950 PDA. - -config SND_SOC_SMDK_WM9713 - tristate "SoC AC97 Audio support for SMDK with WM9713" - depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) - select SND_SOC_WM9713 - select SND_S3C_SOC_AC97 - help - Sat Y if you want to add support for SoC audio on the SMDK. - -config SND_S3C64XX_SOC_SMARTQ - tristate "SoC I2S Audio support for SmartQ board" - depends on SND_S3C24XX_SOC && MACH_SMARTQ - select SND_S3C64XX_SOC_I2S - select SND_SOC_WM8750 - -config SND_S5PC110_SOC_AQUILA_WM8994 - tristate "SoC I2S Audio support for AQUILA - WM8994" - depends on SND_S3C24XX_SOC && MACH_AQUILA - select SND_S3C64XX_SOC_I2S_V4 - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on aquila - with the WM8994. - -config SND_S5PV210_SOC_GONI_WM8994 - tristate "SoC I2S Audio support for GONI - WM8994" - depends on SND_S3C24XX_SOC && MACH_GONI - select SND_S3C64XX_SOC_I2S_V4 - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on goni - with the WM8994. - -config SND_SOC_SMDK_SPDIF - tristate "SoC S/PDIF Audio support for SMDK" - depends on SND_S3C24XX_SOC && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) - select SND_S5P_SOC_SPDIF - help - Say Y if you want to add support for SoC S/PDIF audio on the SMDK. diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile deleted file mode 100644 index ee8f41d..0000000 --- a/sound/soc/s3c24xx/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -# S3c24XX Platform Support -snd-soc-s3c24xx-objs := s3c-dma.o -snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o -snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o -snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o -snd-soc-s3c-ac97-objs := s3c-ac97.o -snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o -snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o -snd-soc-s3c-pcm-objs := s3c-pcm.o -snd-soc-samsung-spdif-objs := spdif.o - -obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o -obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o -obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o -obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o -obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o -obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o - -# S3C24XX Machine Support -snd-soc-jive-wm8750-objs := jive_wm8750.o -snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o -snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o -snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o -snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o -snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o -snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o -snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o -snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o -snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o -snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o -snd-soc-smdk-wm9713-objs := smdk_wm9713.o -snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o -snd-soc-aquila-wm8994-objs := aquila_wm8994.o -snd-soc-goni-wm8994-objs := goni_wm8994.o -snd-soc-smdk-spdif-objs := smdk_spdif.o - -obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o -obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o -obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o -obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o -obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o -obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o -obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o -obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o -obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o -obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c deleted file mode 100644 index 235d197..0000000 --- a/sound/soc/s3c24xx/aquila_wm8994.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * aquila_wm8994.c - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Chanwoo Choi <cw00.choi@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <sound/soc.h> -#include <sound/soc-dapm.h> -#include <sound/jack.h> -#include <asm/mach-types.h> -#include <mach/gpio.h> -#include <mach/regs-clock.h> - -#include <linux/mfd/wm8994/core.h> -#include <linux/mfd/wm8994/registers.h> -#include "../codecs/wm8994.h" -#include "s3c-dma.h" -#include "s3c64xx-i2s.h" - -static struct snd_soc_card aquila; -static struct platform_device *aquila_snd_device; - -/* 3.5 pie jack */ -static struct snd_soc_jack jack; - -/* 3.5 pie jack detection DAPM pins */ -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - }, -}; - -/* 3.5 pie jack detection gpios */ -static struct snd_soc_jack_gpio jack_gpios[] = { - { - .gpio = S5PV210_GPH0(6), - .name = "DET_3.5", - .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - .debounce_time = 200, - }, -}; - -static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_SPK("Ext Rcv", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Main Mic", NULL), - SND_SOC_DAPM_MIC("2nd Mic", NULL), - SND_SOC_DAPM_LINE("Radio In", NULL), -}; - -static const struct snd_soc_dapm_route aquila_dapm_routes[] = { - {"Ext Spk", NULL, "SPKOUTLP"}, - {"Ext Spk", NULL, "SPKOUTLN"}, - - {"Ext Rcv", NULL, "HPOUT2N"}, - {"Ext Rcv", NULL, "HPOUT2P"}, - - {"Headset Stereophone", NULL, "HPOUT1L"}, - {"Headset Stereophone", NULL, "HPOUT1R"}, - - {"IN1RN", NULL, "Headset Mic"}, - {"IN1RP", NULL, "Headset Mic"}, - - {"IN1RN", NULL, "2nd Mic"}, - {"IN1RP", NULL, "2nd Mic"}, - - {"IN1LN", NULL, "Main Mic"}, - {"IN1LP", NULL, "Main Mic"}, - - {"IN2LN", NULL, "Radio In"}, - {"IN2RN", NULL, "Radio In"}, -}; - -static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - int ret; - - /* add aquila specific widgets */ - snd_soc_dapm_new_controls(codec, aquila_dapm_widgets, - ARRAY_SIZE(aquila_dapm_widgets)); - - /* set up aquila specific audio routes */ - snd_soc_dapm_add_routes(codec, aquila_dapm_routes, - ARRAY_SIZE(aquila_dapm_routes)); - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); - snd_soc_dapm_nc_pin(codec, "SPKOUTRN"); - snd_soc_dapm_nc_pin(codec, "SPKOUTRP"); - - snd_soc_dapm_sync(codec); - - /* Headset jack detection */ - ret = snd_soc_jack_new(&aquila, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, - &jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); - if (ret) - return ret; - - ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); - if (ret) - return ret; - - return 0; -} - -static int aquila_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - /* set the cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the cpu system clock */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops aquila_hifi_ops = { - .hw_params = aquila_hifi_hw_params, -}; - -static int aquila_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - if (params_rate(params) != 8000) - return -EINVAL; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_dai_driver voice_dai = { - .name = "aquila-voice-dai", - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_ops aquila_voice_ops = { - .hw_params = aquila_voice_hw_params, -}; - -static struct snd_soc_dai_link aquila_dai[] = { -{ - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .cpu_dai_name = "s3c64xx-i2s-v4", - .codec_dai_name = "wm8994-hifi", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8994-codec.0-0x1a", - .init = aquila_wm8994_init, - .ops = &aquila_hifi_ops, -}, { - .name = "WM8994 Voice", - .stream_name = "Voice", - .cpu_dai_name = "aquila-voice-dai", - .codec_dai_name = "wm8994-voice", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8994-codec.0-0x1a", - .ops = &aquila_voice_ops, -}, -}; - -static struct snd_soc_card aquila = { - .name = "aquila", - .dai_link = aquila_dai, - .num_links = ARRAY_SIZE(aquila_dai), -}; - -static int __init aquila_init(void) -{ - int ret; - - if (!machine_is_aquila()) - return -ENODEV; - - aquila_snd_device = platform_device_alloc("soc-audio", -1); - if (!aquila_snd_device) - return -ENOMEM; - - /* register voice DAI here */ - ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai); - if (ret) - return ret; - - platform_set_drvdata(aquila_snd_device, &aquila); - ret = platform_device_add(aquila_snd_device); - - if (ret) - platform_device_put(aquila_snd_device); - - return ret; -} - -static void __exit aquila_exit(void) -{ - platform_device_unregister(aquila_snd_device); -} - -module_init(aquila_init); -module_exit(aquila_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)"); -MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c deleted file mode 100644 index a962847..0000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c +++ /dev/null @@ -1,230 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c - * - * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh <jassi.brar@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/io.h> - -#include <sound/soc.h> -#include <sound/pcm_params.h> - -#include <plat/audio.h> - -#include <mach/map.h> -#include <mach/dma.h> - -#include "s3c-dma.h" -#include "regs-i2s-v2.h" -#include "s3c64xx-i2s.h" - -static struct s3c2410_dma_client s3c64xx_dma_client_out = { - .name = "I2Sv4 PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c64xx_dma_client_in = { - .name = "I2Sv4 PCM Stereo in" -}; - -static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out; -static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in; -static struct s3c_i2sv2_info s3c64xx_i2sv4; - -static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4; - int ret = 0; - - snd_soc_dai_set_drvdata(dai, i2s); - - ret = s3c_i2sv2_probe(dai, i2s, i2s->base); - - return ret; -} - -static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - struct s3c_dma_params *dma_data; - u32 iismod; - - dev_dbg(cpu_dai->dev, "Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = i2s->dma_playback; - else - dma_data = i2s->dma_capture; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod); - - iismod &= ~S3C64XX_IISMOD_BLC_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod |= S3C64XX_IISMOD_BLC_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S24_LE: - iismod |= S3C64XX_IISMOD_BLC_24BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = { - .hw_params = s3c_i2sv4_hw_params, -}; - -static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = { - .symmetric_rates = 1, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .probe = s3c64xx_i2sv4_probe, - .ops = &s3c64xx_i2sv4_dai_ops, -}; - -static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *i2s_pdata; - struct s3c_i2sv2_info *i2s; - struct resource *res; - int ret; - - i2s = &s3c64xx_i2sv4; - - i2s->feature |= S3C_FEATURE_CDCLKCON; - - i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in; - i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); - return -ENXIO; - } - i2s->dma_playback->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); - return -ENXIO; - } - i2s->dma_capture->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s-v4")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } - i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; - i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; - - i2s->dma_capture->client = &s3c64xx_dma_client_in; - i2s->dma_capture->dma_size = 4; - i2s->dma_playback->client = &s3c64xx_dma_client_out; - i2s->dma_playback->dma_size = 4; - - i2s->base = res->start; - - i2s_pdata = pdev->dev.platform_data; - if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - - i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; - } - - clk_enable(i2s->iis_cclk); - - ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai); - if (ret != 0) - goto err_i2sv2; - - return 0; - -err_i2sv2: - clk_put(i2s->iis_cclk); -err: - return ret; -} - -static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev) -{ - struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4; - struct resource *res; - - snd_soc_unregister_dai(&pdev->dev); - clk_put(i2s->iis_cclk); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, resource_size(res)); - else - dev_warn(&pdev->dev, "Unable to get I2S SFR address\n"); - - return 0; -} - -static struct platform_driver s3c64xx_i2sv4_driver = { - .probe = s3c64xx_i2sv4_dev_probe, - .remove = s3c64xx_i2sv4_dev_remove, - .driver = { - .name = "s3c64xx-iis-v4", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c64xx_i2sv4_init(void) -{ - return platform_driver_register(&s3c64xx_i2sv4_driver); -} -module_init(s3c64xx_i2sv4_init); - -static void __exit s3c64xx_i2sv4_exit(void) -{ - platform_driver_unregister(&s3c64xx_i2sv4_driver); -} -module_exit(s3c64xx_i2sv4_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); -MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c64xx-iis-v4"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c deleted file mode 100644 index ae7acb6..0000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ /dev/null @@ -1,242 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.c - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/module.h> -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/io.h> -#include <linux/slab.h> - -#include <sound/soc.h> - -#include <plat/audio.h> - -#include <mach/map.h> -#include <mach/dma.h> - -#include "s3c-dma.h" -#include "regs-i2s-v2.h" -#include "s3c64xx-i2s.h" - -/* The value should be set to maximum of the total number - * of I2Sv3 controllers that any supported SoC has. - */ -#define MAX_I2SV3 2 - -static struct s3c2410_dma_client s3c64xx_dma_client_out = { - .name = "I2S PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c64xx_dma_client_in = { - .name = "I2S PCM Stereo in" -}; - -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3]; -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3]; -static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3]; - -struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISMOD_IMS_SYSMUX) - return i2s->iis_cclk; - else - return i2s->iis_pclk; -} -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); - -static int s3c64xx_i2s_probe(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s; - int ret; - - if (dai->id >= MAX_I2SV3) { - dev_err(dai->dev, "id %d out of range\n", dai->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[dai->id]; - snd_soc_dai_set_drvdata(dai, i2s); - - i2s->iis_cclk = clk_get(dai->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(dai->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; - } - - clk_enable(i2s->iis_cclk); - - ret = s3c_i2sv2_probe(dai, i2s, i2s->base); - if (ret) - goto err_clk; - - return 0; - -err_clk: - clk_disable(i2s->iis_cclk); - clk_put(i2s->iis_cclk); -err: - kfree(i2s); - return ret; -} - -static int s3c64xx_i2s_remove(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); - - clk_disable(i2s->iis_cclk); - clk_put(i2s->iis_cclk); - kfree(i2s); - return 0; -} - -static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops; - -static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = { -{ - .name = "s3c64xx-i2s-0", - .probe = s3c64xx_i2s_probe, - .remove = s3c64xx_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, -}, { - .name = "s3c64xx-i2s-1", - .probe = s3c64xx_i2s_probe, - .remove = s3c64xx_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, -},}; - -static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *i2s_pdata; - struct s3c_i2sv2_info *i2s; - struct resource *res; - int i, ret; - - if (pdev->id >= MAX_I2SV3) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[pdev->id]; - - i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; - i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); - return -ENXIO; - } - i2s->dma_playback->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); - return -ENXIO; - } - i2s->dma_capture->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } - i2s->base = res->start; - - i2s_pdata = pdev->dev.platform_data; - if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; - i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; - - i2s->dma_capture->client = &s3c64xx_dma_client_in; - i2s->dma_capture->dma_size = 4; - i2s->dma_playback->client = &s3c64xx_dma_client_out; - i2s->dma_playback->dma_size = 4; - - for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) { - ret = s3c_i2sv2_register_dai(&pdev->dev, i, - &s3c64xx_i2s_dai[i]); - if (ret != 0) - return ret; - } - - return 0; -} - -static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai)); - return 0; -} - -static struct platform_driver s3c64xx_iis_driver = { - .probe = s3c64xx_iis_dev_probe, - .remove = s3c64xx_iis_dev_remove, - .driver = { - .name = "s3c64xx-iis", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c64xx_i2s_init(void) -{ - return platform_driver_register(&s3c64xx_iis_driver); -} -module_init(s3c64xx_i2s_init); - -static void __exit s3c64xx_i2s_exit(void) -{ - platform_driver_unregister(&s3c64xx_iis_driver); -} -module_exit(s3c64xx_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c64xx-iis"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h deleted file mode 100644 index de4075d..0000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ /dev/null @@ -1,41 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.h - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H -#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ - -struct clk; - -#include "s3c-i2s-v2.h" - -#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER - -#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK -#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS -#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK - -#define S3C64XX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -#define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); - -#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c index 96c05e1..2e977e4 100644 --- a/sound/soc/s6000/s6105-ipcam.c +++ b/sound/soc/s6000/s6105-ipcam.c @@ -18,7 +18,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <variant/dmac.h> @@ -107,6 +106,7 @@ static int output_type_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = kcontrol->private_data; + struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned int val = (ucontrol->value.enumerated.item[0] != 0); char *differential = "Audio Out Differential"; char *stereo = "Audio Out Stereo"; @@ -114,10 +114,10 @@ static int output_type_put(struct snd_kcontrol *kcontrol, if (kcontrol->private_value == val) return 0; kcontrol->private_value = val; - snd_soc_dapm_disable_pin(codec, val ? differential : stereo); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, val ? stereo : differential); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, val ? differential : stereo); + snd_soc_dapm_sync(dapm); + snd_soc_dapm_enable_pin(dapm, val ? stereo : differential); + snd_soc_dapm_sync(dapm); return 1; } @@ -137,35 +137,36 @@ static const struct snd_kcontrol_new audio_out_mux = { static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add s6105 specific widgets */ - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* Set up s6105 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* not present */ - snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); + snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_nc_pin(dapm, "LINE2L"); + snd_soc_dapm_nc_pin(dapm, "LINE2R"); /* not connected */ - snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ - snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ - snd_soc_dapm_nc_pin(codec, "LLOUT"); - snd_soc_dapm_nc_pin(codec, "RLOUT"); - snd_soc_dapm_nc_pin(codec, "HPRCOM"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */ + snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */ + snd_soc_dapm_nc_pin(dapm, "LLOUT"); + snd_soc_dapm_nc_pin(dapm, "RLOUT"); + snd_soc_dapm_nc_pin(dapm, "HPRCOM"); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Audio In"); + snd_soc_dapm_enable_pin(dapm, "Audio In"); /* must correspond to audio_out_mux.private_value initializer */ - snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); + snd_soc_dapm_disable_pin(dapm, "Audio Out Differential"); + snd_soc_dapm_sync(dapm); + snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec)); diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig new file mode 100644 index 0000000..eb45cf9 --- /dev/null +++ b/sound/soc/samsung/Kconfig @@ -0,0 +1,155 @@ +config ASOC_SAMSUNG + tristate "ASoC support for Samsung" + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 + select S3C64XX_DMA if ARCH_S3C64XX + select S3C2410_DMA if ARCH_S3C2410 + help + Say Y or M if you want to add support for codecs attached to + the Samsung SoCs' Audio interfaces. You will also need to + select the audio interfaces to support below. + +config SND_S3C24XX_I2S + tristate + select S3C2410_DMA + +config SND_S3C_I2SV2_SOC + tristate + +config SND_S3C2412_SOC_I2S + tristate + select SND_S3C_I2SV2_SOC + select S3C2410_DMA + +config SND_SAMSUNG_PCM + tristate + +config SND_SAMSUNG_AC97 + tristate + select SND_SOC_AC97_BUS + +config SND_SAMSUNG_SPDIF + tristate + select SND_SOC_SPDIF + +config SND_SAMSUNG_I2S + tristate + +config ASOC_SAMSUNG_NEO1973_WM8753 + tristate "SoC I2S Audio support for NEO1973 - WM8753" + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01 + select SND_S3C24XX_I2S + select SND_SOC_WM8753 + help + Say Y if you want to add support for SoC audio on smdk2440 + with the WM8753. + +config ASOC_SAMSUNG_NEO1973_GTA02_WM8753 + tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02 + select SND_S3C24XX_I2S + select SND_SOC_WM8753 + help + This driver provides audio support for the Openmoko Neo FreeRunner + smartphone. + +config ASOC_SAMSUNG_JIVE_WM8750 + tristate "SoC I2S Audio support for Jive" + depends on ASOC_SAMSUNG && MACH_JIVE + select SND_SOC_WM8750 + select SND_S3C2412_SOC_I2S + help + Sat Y if you want to add support for SoC audio on the Jive. + +config ASOC_SAMSUNG_SMDK_WM8580 + tristate "SoC I2S Audio support for WM8580 on SMDK" + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100) + select SND_SOC_WM8580 + select SND_SAMSUNG_I2S + help + Say Y if you want to add support for SoC audio on the SMDKs. + +config ASOC_SAMSUNG_SMDK2443_WM9710 + tristate "SoC AC97 Audio support for SMDK2443 - WM9710" + depends on ASOC_SAMSUNG && MACH_SMDK2443 + select S3C2410_DMA + select AC97_BUS + select SND_SOC_AC97_CODEC + select SND_SAMSUNG_AC97 + help + Say Y if you want to add support for SoC audio on smdk2443 + with the WM9710. + +config ASOC_SAMSUNG_LN2440SBC_ALC650 + tristate "SoC AC97 Audio support for LN2440SBC - ALC650" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select S3C2410_DMA + select AC97_BUS + select SND_SOC_AC97_CODEC + select SND_SAMSUNG_AC97 + help + Say Y if you want to add support for SoC audio on ln2440sbc + with the ALC650. + +config ASOC_SAMSUNG_S3C24XX_UDA134X + tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_L3 + select SND_SOC_UDA134X + +config ASOC_SAMSUNG_SIMTEC + tristate + help + Internal node for common S3C24XX/Simtec suppor + +config ASOC_SAMSUNG_SIMTEC_TLV320AIC23 + tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_TLV320AIC23 + select ASOC_SAMSUNG_SIMTEC + +config ASOC_SAMSUNG_SIMTEC_HERMES + tristate "SoC I2S Audio support for Simtec Hermes board" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_TLV320AIC3X + select ASOC_SAMSUNG_SIMTEC + +config ASOC_SAMSUNG_RX1950_UDA1380 + tristate "Audio support for the HP iPAQ RX1950" + depends on ASOC_SAMSUNG && MACH_RX1950 + select SND_S3C24XX_I2S + select SND_SOC_UDA1380 + help + This driver provides audio support for HP iPAQ RX1950 PDA. + +config ASOC_SAMSUNG_SMDK_WM9713 + tristate "SoC AC97 Audio support for SMDK with WM9713" + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) + select SND_SOC_WM9713 + select SND_SAMSUNG_AC97 + help + Sat Y if you want to add support for SoC audio on the SMDK. + +config ASOC_SMARTQ + tristate "SoC I2S Audio support for SmartQ board" + depends on ASOC_SAMSUNG && MACH_SMARTQ + select SND_SAMSUNG_I2S + select SND_SOC_WM8750 + +config ASOC_GONI_AQUILA_WM8994 + tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" + depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) + select SND_SAMSUNG_I2S + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on goni or aquila + with the WM8994. + +config ASOC_SAMSUNG_SMDK_SPDIF + tristate "SoC S/PDIF Audio support for SMDK" + depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) + select SND_SAMSUNG_SPDIF + help + Say Y if you want to add support for SoC S/PDIF audio on the SMDK. diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile new file mode 100644 index 0000000..0d24f95 --- /dev/null +++ b/sound/soc/samsung/Makefile @@ -0,0 +1,51 @@ +# S3c24XX Platform Support +snd-soc-s3c24xx-objs := dma.o +snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o +snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o +snd-soc-ac97-objs := ac97.o +snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o +snd-soc-samsung-spdif-objs := spdif.o +snd-soc-pcm-objs := pcm.o +snd-soc-i2s-objs := i2s.o + +obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o +obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o +obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o +obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o +obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o +obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o +obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o + +# S3C24XX Machine Support +snd-soc-jive-wm8750-objs := jive_wm8750.o +snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o +snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o +snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o +snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o +snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o +snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o +snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o +snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o +snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o +snd-soc-smdk-wm8580-objs := smdk_wm8580.o +snd-soc-smdk-wm9713-objs := smdk_wm9713.o +snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o +snd-soc-goni-wm8994-objs := goni_wm8994.o +snd-soc-smdk-spdif-objs := smdk_spdif.o + +obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o +obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o +obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o +obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o +obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o +obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/samsung/ac97.c index f891eb7..4770a95 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/samsung/ac97.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c-ac97.c +/* sound/soc/samsung/ac97.c * * ALSA SoC Audio Layer - S3C AC97 Controller driver * Evolved from s3c2443-ac97.c @@ -24,8 +24,8 @@ #include <mach/dma.h> #include <plat/audio.h> -#include "s3c-dma.h" -#include "s3c-ac97.h" +#include "dma.h" +#include "ac97.h" #define AC_CMD_ADDR(x) (x << 16) #define AC_CMD_DATA(x) (x & 0xffff) @@ -122,7 +122,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, data = (stat & 0xffff); if (addr != reg) - pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n", + pr_err("ac97: req addr = %02x, rep addr = %02x\n", reg, addr); mutex_unlock(&s3c_ac97.lock); @@ -334,7 +334,7 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { static struct snd_soc_dai_driver s3c_ac97_dai[] = { [S3C_AC97_DAI_PCM] = { - .name = "s3c-ac97", + .name = "samsung-ac97", .ac97_control = 1, .playback = { .stream_name = "AC97 Playback", @@ -351,7 +351,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = { .ops = &s3c_ac97_dai_ops, }, [S3C_AC97_DAI_MIC] = { - .name = "s3c-ac97-mic", + .name = "samsung-ac97-mic", .ac97_control = 1, .capture = { .stream_name = "AC97 Mic Capture", @@ -407,7 +407,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) } if (!request_mem_region(mem_res->start, - resource_size(mem_res), "s3c-ac97")) { + resource_size(mem_res), "ac97")) { dev_err(&pdev->dev, "Unable to request register region\n"); return -EBUSY; } @@ -431,7 +431,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); if (IS_ERR(s3c_ac97.ac97_clk)) { - dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n"); + dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); ret = -ENODEV; goto err2; } @@ -446,7 +446,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) ret = request_irq(irq_res->start, s3c_ac97_irq, IRQF_DISABLED, "AC97", NULL); if (ret < 0) { - dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n"); + dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); goto err4; } @@ -497,7 +497,7 @@ static struct platform_driver s3c_ac97_driver = { .probe = s3c_ac97_probe, .remove = s3c_ac97_remove, .driver = { - .name = "s3c-ac97", + .name = "samsung-ac97", .owner = THIS_MODULE, }, }; @@ -517,4 +517,4 @@ module_exit(s3c_ac97_exit); MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c-ac97"); +MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/samsung/ac97.h index 5dcedd0..0d0e1b5 100644 --- a/sound/soc/s3c24xx/s3c-ac97.h +++ b/sound/soc/samsung/ac97.h @@ -1,11 +1,11 @@ -/* sound/soc/s3c24xx/s3c-ac97.h +/* sound/soc/samsung/ac97.h * * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.h + * Evolved from s3c2443-ac97.h * * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh <jassi.brar@samsung.com> - * Credits: Graeme Gregory, Sean Choi + * Author: Jaswinder Singh <jassi.brar@samsung.com> + * Credits: Graeme Gregory, Sean Choi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/samsung/dma.c index 243f79b..2124019 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/samsung/dma.c @@ -1,5 +1,5 @@ /* - * s3c-dma.c -- ALSA Soc Audio Layer + * dma.c -- ALSA Soc Audio Layer * * (c) 2006 Wolfson Microelectronics PLC. * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com @@ -30,9 +30,9 @@ #include <mach/hardware.h> #include <mach/dma.h> -#include "s3c-dma.h" +#include "dma.h" -static const struct snd_pcm_hardware s3c_dma_hardware = { +static const struct snd_pcm_hardware dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -53,7 +53,7 @@ static const struct snd_pcm_hardware s3c_dma_hardware = { .fifo_size = 32, }; -struct s3c24xx_runtime_data { +struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; @@ -65,14 +65,14 @@ struct s3c24xx_runtime_data { struct s3c_dma_params *params; }; -/* s3c_dma_enqueue +/* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. */ -static void s3c_dma_enqueue(struct snd_pcm_substream *substream) +static void dma_enqueue(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit; int ret; @@ -112,12 +112,12 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream) prtd->dma_pos = pos; } -static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, +static void audio_buffdone(struct s3c2410_dma_chan *channel, void *dev_id, int size, enum s3c2410_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; - struct s3c24xx_runtime_data *prtd; + struct runtime_data *prtd; pr_debug("Entered %s\n", __func__); @@ -132,17 +132,17 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, spin_lock(&prtd->lock); if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { prtd->dma_loaded--; - s3c_dma_enqueue(substream); + dma_enqueue(substream); } spin_unlock(&prtd->lock); } -static int s3c_dma_hw_params(struct snd_pcm_substream *substream, +static int dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = @@ -181,7 +181,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, } s3c2410_dma_set_buffdone_fn(prtd->params->channel, - s3c24xx_audio_buffdone); + audio_buffdone); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); @@ -199,9 +199,9 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, return 0; } -static int s3c_dma_hw_free(struct snd_pcm_substream *substream) +static int dma_hw_free(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; pr_debug("Entered %s\n", __func__); @@ -216,9 +216,9 @@ static int s3c_dma_hw_free(struct snd_pcm_substream *substream) return 0; } -static int s3c_dma_prepare(struct snd_pcm_substream *substream) +static int dma_prepare(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; int ret = 0; pr_debug("Entered %s\n", __func__); @@ -249,14 +249,14 @@ static int s3c_dma_prepare(struct snd_pcm_substream *substream) prtd->dma_pos = prtd->dma_start; /* enqueue dma buffers */ - s3c_dma_enqueue(substream); + dma_enqueue(substream); return ret; } -static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) +static int dma_trigger(struct snd_pcm_substream *substream, int cmd) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; int ret = 0; pr_debug("Entered %s\n", __func__); @@ -289,10 +289,10 @@ static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) } static snd_pcm_uframes_t -s3c_dma_pointer(struct snd_pcm_substream *substream) +dma_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; unsigned long res; dma_addr_t src, dst; @@ -324,17 +324,17 @@ s3c_dma_pointer(struct snd_pcm_substream *substream) return bytes_to_frames(substream->runtime, res); } -static int s3c_dma_open(struct snd_pcm_substream *substream) +static int dma_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd; + struct runtime_data *prtd; pr_debug("Entered %s\n", __func__); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware); + snd_soc_set_runtime_hwparams(substream, &dma_hardware); - prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); + prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; @@ -344,22 +344,22 @@ static int s3c_dma_open(struct snd_pcm_substream *substream) return 0; } -static int s3c_dma_close(struct snd_pcm_substream *substream) +static int dma_close(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; pr_debug("Entered %s\n", __func__); if (!prtd) - pr_debug("s3c_dma_close called with prtd == NULL\n"); + pr_debug("dma_close called with prtd == NULL\n"); kfree(prtd); return 0; } -static int s3c_dma_mmap(struct snd_pcm_substream *substream, +static int dma_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -372,23 +372,23 @@ static int s3c_dma_mmap(struct snd_pcm_substream *substream, runtime->dma_bytes); } -static struct snd_pcm_ops s3c_dma_ops = { - .open = s3c_dma_open, - .close = s3c_dma_close, +static struct snd_pcm_ops dma_ops = { + .open = dma_open, + .close = dma_close, .ioctl = snd_pcm_lib_ioctl, - .hw_params = s3c_dma_hw_params, - .hw_free = s3c_dma_hw_free, - .prepare = s3c_dma_prepare, - .trigger = s3c_dma_trigger, - .pointer = s3c_dma_pointer, - .mmap = s3c_dma_mmap, + .hw_params = dma_hw_params, + .hw_free = dma_hw_free, + .prepare = dma_prepare, + .trigger = dma_trigger, + .pointer = dma_pointer, + .mmap = dma_mmap, }; -static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream) { struct snd_pcm_substream *substream = pcm->streams[stream].substream; struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = s3c_dma_hardware.buffer_bytes_max; + size_t size = dma_hardware.buffer_bytes_max; pr_debug("Entered %s\n", __func__); @@ -403,7 +403,7 @@ static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) return 0; } -static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) +static void dma_free_dma_buffers(struct snd_pcm *pcm) { struct snd_pcm_substream *substream; struct snd_dma_buffer *buf; @@ -426,9 +426,9 @@ static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) } } -static u64 s3c_dma_mask = DMA_BIT_MASK(32); +static u64 dma_mask = DMA_BIT_MASK(32); -static int s3c_dma_new(struct snd_card *card, +static int dma_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; @@ -436,67 +436,67 @@ static int s3c_dma_new(struct snd_card *card, pr_debug("Entered %s\n", __func__); if (!card->dev->dma_mask) - card->dev->dma_mask = &s3c_dma_mask; + card->dev->dma_mask = &dma_mask; if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; if (dai->driver->playback.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, + ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } if (dai->driver->capture.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, + ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) goto out; } - out: +out: return ret; } -static struct snd_soc_platform_driver s3c24xx_soc_platform = { - .ops = &s3c_dma_ops, - .pcm_new = s3c_dma_new, - .pcm_free = s3c_dma_free_dma_buffers, +static struct snd_soc_platform_driver samsung_asoc_platform = { + .ops = &dma_ops, + .pcm_new = dma_new, + .pcm_free = dma_free_dma_buffers, }; -static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) +static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); + return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); } -static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) +static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; } -static struct platform_driver s3c24xx_pcm_driver = { +static struct platform_driver asoc_dma_driver = { .driver = { - .name = "s3c24xx-pcm-audio", + .name = "samsung-audio", .owner = THIS_MODULE, }, - .probe = s3c24xx_soc_platform_probe, - .remove = __devexit_p(s3c24xx_soc_platform_remove), + .probe = samsung_asoc_platform_probe, + .remove = __devexit_p(samsung_asoc_platform_remove), }; -static int __init snd_s3c24xx_pcm_init(void) +static int __init samsung_asoc_init(void) { - return platform_driver_register(&s3c24xx_pcm_driver); + return platform_driver_register(&asoc_dma_driver); } -module_init(snd_s3c24xx_pcm_init); +module_init(samsung_asoc_init); -static void __exit snd_s3c24xx_pcm_exit(void) +static void __exit samsung_asoc_exit(void) { - platform_driver_unregister(&s3c24xx_pcm_driver); + platform_driver_unregister(&asoc_dma_driver); } -module_exit(snd_s3c24xx_pcm_exit); +module_exit(samsung_asoc_exit); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); +MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c24xx-pcm-audio"); +MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/samsung/dma.h index 748c07d..f8cd2b4 100644 --- a/sound/soc/s3c24xx/s3c-dma.h +++ b/sound/soc/samsung/dma.h @@ -1,5 +1,5 @@ /* - * s3c-dma.h -- + * dma.h -- * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index 694f702..dcfac54 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -16,7 +16,6 @@ #include <linux/io.h> #include <linux/platform_device.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/jack.h> #include <asm/mach-types.h> #include <mach/gpio.h> @@ -25,8 +24,16 @@ #include <linux/mfd/wm8994/core.h> #include <linux/mfd/wm8994/registers.h> #include "../codecs/wm8994.h" -#include "s3c-dma.h" -#include "s3c64xx-i2s.h" +#include "dma.h" +#include "i2s.h" + +#define MACHINE_NAME 0 +#define CPU_VOICE_DAI 1 + +static const char *aquila_str[] = { + [MACHINE_NAME] = "aquila", + [CPU_VOICE_DAI] = "aquila-voice-dai", +}; static struct snd_soc_card goni; static struct platform_device *goni_snd_device; @@ -97,25 +104,31 @@ static const struct snd_soc_dapm_route goni_dapm_routes[] = { static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* add goni specific widgets */ - snd_soc_dapm_new_controls(codec, goni_dapm_widgets, + snd_soc_dapm_new_controls(dapm, goni_dapm_widgets, ARRAY_SIZE(goni_dapm_widgets)); /* set up goni specific audio routes */ - snd_soc_dapm_add_routes(codec, goni_dapm_routes, + snd_soc_dapm_add_routes(dapm, goni_dapm_routes, ARRAY_SIZE(goni_dapm_routes)); /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + + if (machine_is_aquila()) { + snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); + } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); /* Headset jack detection */ ret = snd_soc_jack_new(&goni, "Headset Jack", @@ -150,12 +163,6 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - /* set the cpu system clock */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); @@ -236,9 +243,9 @@ static struct snd_soc_dai_link goni_dai[] = { { .name = "WM8994", .stream_name = "WM8994 HiFi", - .cpu_dai_name = "s3c64xx-i2s-v4", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8994-codec.0-0x1a", .init = goni_wm8994_init, .ops = &goni_hifi_ops, @@ -247,7 +254,7 @@ static struct snd_soc_dai_link goni_dai[] = { .stream_name = "Voice", .cpu_dai_name = "goni-voice-dai", .codec_dai_name = "wm8994-voice", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8994-codec.0-0x1a", .ops = &goni_voice_ops, }, @@ -263,7 +270,11 @@ static int __init goni_init(void) { int ret; - if (!machine_is_goni()) + if (machine_is_aquila()) { + voice_dai.name = aquila_str[CPU_VOICE_DAI]; + goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; + goni.name = aquila_str[MACHINE_NAME]; + } else if (!machine_is_goni()) return -ENODEV; goni_snd_device = platform_device_alloc("soc-audio", -1); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c new file mode 100644 index 0000000..d6de3f0 --- /dev/null +++ b/sound/soc/samsung/i2s.c @@ -0,0 +1,1256 @@ +/* sound/soc/samsung/i2s.c + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/io.h> + +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> + +#include <plat/audio.h> + +#include "dma.h" +#include "i2s.h" + +#define I2SCON 0x0 +#define I2SMOD 0x4 +#define I2SFIC 0x8 +#define I2SPSR 0xc +#define I2STXD 0x10 +#define I2SRXD 0x14 +#define I2SFICS 0x18 +#define I2STXDS 0x1c + +#define CON_RSTCLR (1 << 31) +#define CON_FRXOFSTATUS (1 << 26) +#define CON_FRXORINTEN (1 << 25) +#define CON_FTXSURSTAT (1 << 24) +#define CON_FTXSURINTEN (1 << 23) +#define CON_TXSDMA_PAUSE (1 << 20) +#define CON_TXSDMA_ACTIVE (1 << 18) + +#define CON_FTXURSTATUS (1 << 17) +#define CON_FTXURINTEN (1 << 16) +#define CON_TXFIFO2_EMPTY (1 << 15) +#define CON_TXFIFO1_EMPTY (1 << 14) +#define CON_TXFIFO2_FULL (1 << 13) +#define CON_TXFIFO1_FULL (1 << 12) + +#define CON_LRINDEX (1 << 11) +#define CON_TXFIFO_EMPTY (1 << 10) +#define CON_RXFIFO_EMPTY (1 << 9) +#define CON_TXFIFO_FULL (1 << 8) +#define CON_RXFIFO_FULL (1 << 7) +#define CON_TXDMA_PAUSE (1 << 6) +#define CON_RXDMA_PAUSE (1 << 5) +#define CON_TXCH_PAUSE (1 << 4) +#define CON_RXCH_PAUSE (1 << 3) +#define CON_TXDMA_ACTIVE (1 << 2) +#define CON_RXDMA_ACTIVE (1 << 1) +#define CON_ACTIVE (1 << 0) + +#define MOD_OPCLK_CDCLK_OUT (0 << 30) +#define MOD_OPCLK_CDCLK_IN (1 << 30) +#define MOD_OPCLK_BCLK_OUT (2 << 30) +#define MOD_OPCLK_PCLK (3 << 30) +#define MOD_OPCLK_MASK (3 << 30) +#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ + +#define MOD_BLCS_SHIFT 26 +#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT) +#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT) +#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT) +#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT) +#define MOD_BLCP_SHIFT 24 +#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT) +#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT) +#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT) +#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT) + +#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ +#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ +#define MOD_C1DD_HHALF (1 << 19) +#define MOD_C1DD_LHALF (1 << 18) +#define MOD_DC2_EN (1 << 17) +#define MOD_DC1_EN (1 << 16) +#define MOD_BLC_16BIT (0 << 13) +#define MOD_BLC_8BIT (1 << 13) +#define MOD_BLC_24BIT (2 << 13) +#define MOD_BLC_MASK (3 << 13) + +#define MOD_IMS_SYSMUX (1 << 10) +#define MOD_SLAVE (1 << 11) +#define MOD_TXONLY (0 << 8) +#define MOD_RXONLY (1 << 8) +#define MOD_TXRX (2 << 8) +#define MOD_MASK (3 << 8) +#define MOD_LR_LLOW (0 << 7) +#define MOD_LR_RLOW (1 << 7) +#define MOD_SDF_IIS (0 << 5) +#define MOD_SDF_MSB (1 << 5) +#define MOD_SDF_LSB (2 << 5) +#define MOD_SDF_MASK (3 << 5) +#define MOD_RCLK_256FS (0 << 3) +#define MOD_RCLK_512FS (1 << 3) +#define MOD_RCLK_384FS (2 << 3) +#define MOD_RCLK_768FS (3 << 3) +#define MOD_RCLK_MASK (3 << 3) +#define MOD_BCLK_32FS (0 << 1) +#define MOD_BCLK_48FS (1 << 1) +#define MOD_BCLK_16FS (2 << 1) +#define MOD_BCLK_24FS (3 << 1) +#define MOD_BCLK_MASK (3 << 1) +#define MOD_8BIT (1 << 0) + +#define MOD_CDCLKCON (1 << 12) + +#define PSR_PSREN (1 << 15) + +#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf) +#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf) + +#define FIC_TXFLUSH (1 << 15) +#define FIC_RXFLUSH (1 << 7) +#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf) +#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf) +#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f) + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +struct i2s_dai { + /* Platform device for this DAI */ + struct platform_device *pdev; + /* IOREMAP'd SFRs */ + void __iomem *addr; + /* Physical base address of SFRs */ + u32 base; + /* Rate of RCLK source clock */ + unsigned long rclk_srcrate; + /* Frame Clock */ + unsigned frmclk; + /* + * Specifically requested RCLK,BCLK by MACHINE Driver. + * 0 indicates CPU driver is free to choose any value. + */ + unsigned rfs, bfs; + /* I2S Controller's core clock */ + struct clk *clk; + /* Clock for generating I2S signals */ + struct clk *op_clk; + /* Array of clock names for op_clk */ + const char **src_clk; + /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ + struct i2s_dai *pri_dai; + /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ + struct i2s_dai *sec_dai; +#define DAI_OPENED (1 << 0) /* Dai is opened */ +#define DAI_MANAGER (1 << 1) /* Dai is the manager */ + unsigned mode; + /* Driver for this DAI */ + struct snd_soc_dai_driver i2s_dai_drv; + /* DMA parameters */ + struct s3c_dma_params dma_playback; + struct s3c_dma_params dma_capture; + u32 quirks; + u32 suspend_i2smod; + u32 suspend_i2scon; + u32 suspend_i2spsr; +}; + +/* Lock for cross i/f checks */ +static DEFINE_SPINLOCK(lock); + +/* If this is the 'overlay' stereo DAI */ +static inline bool is_secondary(struct i2s_dai *i2s) +{ + return i2s->pri_dai ? true : false; +} + +/* If operating in SoC-Slave mode */ +static inline bool is_slave(struct i2s_dai *i2s) +{ + return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false; +} + +/* If this interface of the controller is transmitting data */ +static inline bool tx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD); + + if (is_secondary(i2s)) + active &= CON_TXSDMA_ACTIVE; + else + active &= CON_TXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is transmitting data */ +static inline bool other_tx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return tx_active(other); +} + +/* If any interface of the controller is transmitting data */ +static inline bool any_tx_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || other_tx_active(i2s); +} + +/* If this interface of the controller is receiving data */ +static inline bool rx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is receiving data */ +static inline bool other_rx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return rx_active(other); +} + +/* If any interface of the controller is receiving data */ +static inline bool any_rx_active(struct i2s_dai *i2s) +{ + return rx_active(i2s) || other_rx_active(i2s); +} + +/* If the other DAI is transmitting or receiving data */ +static inline bool other_active(struct i2s_dai *i2s) +{ + return other_rx_active(i2s) || other_tx_active(i2s); +} + +/* If this DAI is transmitting or receiving data */ +static inline bool this_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || rx_active(i2s); +} + +/* If the controller is active anyway */ +static inline bool any_active(struct i2s_dai *i2s) +{ + return this_active(i2s) || other_active(i2s); +} + +static inline struct i2s_dai *to_info(struct snd_soc_dai *dai) +{ + return snd_soc_dai_get_drvdata(dai); +} + +static inline bool is_opened(struct i2s_dai *i2s) +{ + if (i2s && (i2s->mode & DAI_OPENED)) + return true; + else + return false; +} + +static inline bool is_manager(struct i2s_dai *i2s) +{ + if (is_opened(i2s) && (i2s->mode & DAI_MANAGER)) + return true; + else + return false; +} + +/* Read RCLK of I2S (in multiples of LRCLK) */ +static inline unsigned get_rfs(struct i2s_dai *i2s) +{ + u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; + + switch (rfs) { + case 3: return 768; + case 2: return 384; + case 1: return 512; + default: return 256; + } +} + +/* Write RCLK of I2S (in multiples of LRCLK) */ +static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_RCLK_MASK; + + switch (rfs) { + case 768: + mod |= MOD_RCLK_768FS; + break; + case 512: + mod |= MOD_RCLK_512FS; + break; + case 384: + mod |= MOD_RCLK_384FS; + break; + default: + mod |= MOD_RCLK_256FS; + break; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Read Bit-Clock of I2S (in multiples of LRCLK) */ +static inline unsigned get_bfs(struct i2s_dai *i2s) +{ + u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; + + switch (bfs) { + case 3: return 24; + case 2: return 16; + case 1: return 48; + default: return 32; + } +} + +/* Write Bit-Clock of I2S (in multiples of LRCLK) */ +static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_BCLK_MASK; + + switch (bfs) { + case 48: + mod |= MOD_BCLK_48FS; + break; + case 32: + mod |= MOD_BCLK_32FS; + break; + case 24: + mod |= MOD_BCLK_24FS; + break; + case 16: + mod |= MOD_BCLK_16FS; + break; + default: + dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); + return; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Sample-Size */ +static inline int get_blc(struct i2s_dai *i2s) +{ + int blc = readl(i2s->addr + I2SMOD); + + blc = (blc >> 13) & 0x3; + + switch (blc) { + case 2: return 24; + case 1: return 8; + default: return 16; + } +} + +/* TX Channel Control */ +static void i2s_txctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_ACTIVE; + con &= ~CON_TXCH_PAUSE; + + if (is_secondary(i2s)) { + con |= CON_TXSDMA_ACTIVE; + con &= ~CON_TXSDMA_PAUSE; + } else { + con |= CON_TXDMA_ACTIVE; + con &= ~CON_TXDMA_PAUSE; + } + + if (any_rx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_TXONLY; + } else { + if (is_secondary(i2s)) { + con |= CON_TXSDMA_PAUSE; + con &= ~CON_TXSDMA_ACTIVE; + } else { + con |= CON_TXDMA_PAUSE; + con &= ~CON_TXDMA_ACTIVE; + } + + if (other_tx_active(i2s)) { + writel(con, addr + I2SCON); + return; + } + + con |= CON_TXCH_PAUSE; + + if (any_rx_active(i2s)) + mod |= MOD_RXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* RX Channel Control */ +static void i2s_rxctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_RXDMA_ACTIVE | CON_ACTIVE; + con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE); + + if (any_tx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_RXONLY; + } else { + con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE; + con &= ~CON_RXDMA_ACTIVE; + + if (any_tx_active(i2s)) + mod |= MOD_TXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* Flush FIFO of an interface */ +static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush) +{ + void __iomem *fic; + u32 val; + + if (!i2s) + return; + + if (is_secondary(i2s)) + fic = i2s->addr + I2SFICS; + else + fic = i2s->addr + I2SFIC; + + /* Flush the FIFO */ + writel(readl(fic) | flush, fic); + + /* Be patient */ + val = msecs_to_loops(1) / 1000; /* 1 usec */ + while (--val) + cpu_relax(); + + writel(readl(fic) & ~flush, fic); +} + +static int i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int rfs, int dir) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + u32 mod = readl(i2s->addr + I2SMOD); + + switch (clk_id) { + case SAMSUNG_I2S_CDCLK: + /* Shouldn't matter in GATING(CLOCK_IN) mode */ + if (dir == SND_SOC_CLOCK_IN) + rfs = 0; + + if ((rfs && other->rfs && (other->rfs != rfs)) || + (any_active(i2s) && + (((dir == SND_SOC_CLOCK_IN) + && !(mod & MOD_CDCLKCON)) || + ((dir == SND_SOC_CLOCK_OUT) + && (mod & MOD_CDCLKCON))))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + if (dir == SND_SOC_CLOCK_IN) + mod |= MOD_CDCLKCON; + else + mod &= ~MOD_CDCLKCON; + + i2s->rfs = rfs; + break; + + case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ + case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ + if ((i2s->quirks & QUIRK_NO_MUXPSR) + || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) + clk_id = 0; + else + clk_id = 1; + + if (!any_active(i2s)) { + if (i2s->op_clk) { + if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || + (!clk_id && (mod & MOD_IMS_SYSMUX))) { + clk_disable(i2s->op_clk); + clk_put(i2s->op_clk); + } else { + return 0; + } + } + + i2s->op_clk = clk_get(&i2s->pdev->dev, + i2s->src_clk[clk_id]); + clk_enable(i2s->op_clk); + i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); + + /* Over-ride the other's */ + if (other) { + other->op_clk = i2s->op_clk; + other->rclk_srcrate = i2s->rclk_srcrate; + } + } else if ((!clk_id && (mod & MOD_IMS_SYSMUX)) + || (clk_id && !(mod & MOD_IMS_SYSMUX))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } else { + /* Call can't be on the active DAI */ + i2s->op_clk = other->op_clk; + i2s->rclk_srcrate = other->rclk_srcrate; + return 0; + } + + if (clk_id == 0) + mod &= ~MOD_IMS_SYSMUX; + else + mod |= MOD_IMS_SYSMUX; + break; + + default: + dev_err(&i2s->pdev->dev, "We don't serve that!\n"); + return -EINVAL; + } + + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + u32 tmp = 0; + + /* Format is priority */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_MSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_LSB; + break; + case SND_SOC_DAIFMT_I2S: + tmp |= MOD_SDF_IIS; + break; + default: + dev_err(&i2s->pdev->dev, "Format not supported\n"); + return -EINVAL; + } + + /* + * INV flag is relative to the FORMAT flag - if set it simply + * flips the polarity specified by the Standard + */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + if (tmp & MOD_LR_RLOW) + tmp &= ~MOD_LR_RLOW; + else + tmp |= MOD_LR_RLOW; + break; + default: + dev_err(&i2s->pdev->dev, "Polarity not supported\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + tmp |= MOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + /* Set default source clock in Master mode */ + if (i2s->rclk_srcrate == 0) + i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); + break; + default: + dev_err(&i2s->pdev->dev, "master/slave format not supported\n"); + return -EINVAL; + } + + if (any_active(i2s) && + ((mod & (MOD_SDF_MASK | MOD_LR_RLOW + | MOD_SLAVE)) != tmp)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); + mod |= tmp; + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + + if (!is_secondary(i2s)) + mod &= ~(MOD_DC2_EN | MOD_DC1_EN); + + switch (params_channels(params)) { + case 6: + mod |= MOD_DC2_EN; + case 4: + mod |= MOD_DC1_EN; + break; + case 2: + break; + default: + dev_err(&i2s->pdev->dev, "%d channels not supported\n", + params_channels(params)); + return -EINVAL; + } + + if (is_secondary(i2s)) + mod &= ~MOD_BLCS_MASK; + else + mod &= ~MOD_BLCP_MASK; + + if (is_manager(i2s)) + mod &= ~MOD_BLC_MASK; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + if (is_secondary(i2s)) + mod |= MOD_BLCS_8BIT; + else + mod |= MOD_BLCP_8BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_16BIT; + else + mod |= MOD_BLCP_16BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_16BIT; + break; + case SNDRV_PCM_FORMAT_S24_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_24BIT; + else + mod |= MOD_BLCP_24BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_24BIT; + break; + default: + dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", + params_format(params)); + return -EINVAL; + } + writel(mod, i2s->addr + I2SMOD); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_playback); + else + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_capture); + + i2s->frmclk = params_rate(params); + + return 0; +} + +/* We set constraints on the substream acc to the version of I2S */ +static int i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode |= DAI_OPENED; + + if (is_manager(other)) + i2s->mode &= ~DAI_MANAGER; + else + i2s->mode |= DAI_MANAGER; + + /* Enforce set_sysclk in Master mode */ + i2s->rclk_srcrate = 0; + + spin_unlock_irqrestore(&lock, flags); + + return 0; +} + +static void i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode &= ~DAI_OPENED; + i2s->mode &= ~DAI_MANAGER; + + if (is_opened(other)) + other->mode |= DAI_MANAGER; + + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + + spin_unlock_irqrestore(&lock, flags); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); +} + +static int config_setup(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned rfs, bfs, blc; + u32 psr; + + blc = get_blc(i2s); + + bfs = i2s->bfs; + + if (!bfs && other) + bfs = other->bfs; + + /* Select least possible multiple(2) if no constraint set */ + if (!bfs) + bfs = blc * 2; + + rfs = i2s->rfs; + + if (!rfs && other) + rfs = other->rfs; + + if ((rfs == 256 || rfs == 512) && (blc == 24)) { + dev_err(&i2s->pdev->dev, + "%d-RFS not supported for 24-blc\n", rfs); + return -EINVAL; + } + + if (!rfs) { + if (bfs == 16 || bfs == 32) + rfs = 256; + else + rfs = 384; + } + + /* If already setup and running */ + if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + /* Don't bother RFS, BFS & PSR in Slave mode */ + if (is_slave(i2s)) + return 0; + + set_bfs(i2s, bfs); + set_rfs(i2s, rfs); + + if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { + psr = i2s->rclk_srcrate / i2s->frmclk / rfs; + writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR); + dev_dbg(&i2s->pdev->dev, + "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n", + i2s->rclk_srcrate, psr, rfs, bfs); + } + + return 0; +} + +static int i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct i2s_dai *i2s = to_info(rtd->cpu_dai); + unsigned long flags; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + local_irq_save(flags); + + if (capture) + i2s_fifo(i2s, FIC_RXFLUSH); + else + i2s_fifo(i2s, FIC_TXFLUSH); + + if (config_setup(i2s)) { + local_irq_restore(flags); + return -EINVAL; + } + + if (capture) + i2s_rxctrl(i2s, 1); + else + i2s_txctrl(i2s, 1); + + local_irq_restore(flags); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + local_irq_save(flags); + + if (capture) + i2s_rxctrl(i2s, 0); + else + i2s_txctrl(i2s, 0); + + local_irq_restore(flags); + break; + } + + return 0; +} + +static int i2s_set_clkdiv(struct snd_soc_dai *dai, + int div_id, int div) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + switch (div_id) { + case SAMSUNG_I2S_DIV_BCLK: + if ((any_active(i2s) && div && (get_bfs(i2s) != div)) + || (other && other->bfs && (other->bfs != div))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + i2s->bfs = div; + break; + default: + dev_err(&i2s->pdev->dev, + "Invalid clock divider(%d)\n", div_id); + return -EINVAL; + } + + return 0; +} + +static snd_pcm_sframes_t +i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 reg = readl(i2s->addr + I2SFIC); + snd_pcm_sframes_t delay; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + delay = FIC_RXCOUNT(reg); + else if (is_secondary(i2s)) + delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS)); + else + delay = FIC_TXCOUNT(reg); + + return delay; +} + +#ifdef CONFIG_PM +static int i2s_suspend(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); + i2s->suspend_i2scon = readl(i2s->addr + I2SCON); + i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); + } + + return 0; +} + +static int i2s_resume(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + writel(i2s->suspend_i2scon, i2s->addr + I2SCON); + writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); + writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); + } + + return 0; +} +#else +#define i2s_suspend NULL +#define i2s_resume NULL +#endif + +static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (other && other->clk) /* If this is probe on secondary */ + goto probe_exit; + + i2s->addr = ioremap(i2s->base, 0x100); + if (i2s->addr == NULL) { + dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); + return -ENXIO; + } + + i2s->clk = clk_get(&i2s->pdev->dev, "iis"); + if (IS_ERR(i2s->clk)) { + dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); + iounmap(i2s->addr); + return -ENOENT; + } + clk_enable(i2s->clk); + + if (other) { + other->addr = i2s->addr; + other->clk = i2s->clk; + } + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(CON_RSTCLR, i2s->addr + I2SCON); + +probe_exit: + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + i2s_txctrl(i2s, 0); + i2s_rxctrl(i2s, 0); + i2s_fifo(i2s, FIC_TXFLUSH); + i2s_fifo(other, FIC_TXFLUSH); + i2s_fifo(i2s, FIC_RXFLUSH); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); + + return 0; +} + +static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (!other || !other->clk) { + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(0, i2s->addr + I2SCON); + + clk_disable(i2s->clk); + clk_put(i2s->clk); + + iounmap(i2s->addr); + } + + i2s->clk = NULL; + + return 0; +} + +static struct snd_soc_dai_ops samsung_i2s_dai_ops = { + .trigger = i2s_trigger, + .hw_params = i2s_hw_params, + .set_fmt = i2s_set_fmt, + .set_clkdiv = i2s_set_clkdiv, + .set_sysclk = i2s_set_sysclk, + .startup = i2s_startup, + .shutdown = i2s_shutdown, + .delay = i2s_delay, +}; + +#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 + +#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +static __devinit +struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +{ + struct i2s_dai *i2s; + + i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL); + if (i2s == NULL) + return NULL; + + i2s->pdev = pdev; + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + i2s->i2s_dai_drv.symmetric_rates = 1; + i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe; + i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove; + i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops; + i2s->i2s_dai_drv.suspend = i2s_suspend; + i2s->i2s_dai_drv.resume = i2s_resume; + i2s->i2s_dai_drv.playback.channels_min = 2; + i2s->i2s_dai_drv.playback.channels_max = 2; + i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; + + if (!sec) { + i2s->i2s_dai_drv.capture.channels_min = 2; + i2s->i2s_dai_drv.capture.channels_max = 2; + i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; + } else { /* Create a new platform_device for Secondary */ + i2s->pdev = platform_device_register_resndata(NULL, + pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, + NULL, 0, NULL, 0); + if (IS_ERR(i2s->pdev)) { + kfree(i2s); + return NULL; + } + } + + /* Pre-assign snd_soc_dai_set_drvdata */ + dev_set_drvdata(&i2s->pdev->dev, i2s); + + return i2s; +} + +static __devinit int samsung_i2s_probe(struct platform_device *pdev) +{ + u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan; + struct i2s_dai *pri_dai, *sec_dai = NULL; + struct s3c_audio_pdata *i2s_pdata; + struct samsung_i2s *i2s_cfg; + struct resource *res; + u32 regs_base, quirks; + int ret = 0; + + /* Call during Seconday interface registration */ + if (pdev->id >= SAMSUNG_I2S_SECOFF) { + sec_dai = dev_get_drvdata(&pdev->dev); + snd_soc_register_dai(&sec_dai->pdev->dev, + &sec_dai->i2s_dai_drv); + return 0; + } + + i2s_pdata = pdev->dev.platform_data; + if (i2s_pdata == NULL) { + dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); + return -ENXIO; + } + dma_pl_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); + return -ENXIO; + } + dma_cp_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (res) + dma_pl_sec_chan = res->start; + else + dma_pl_sec_chan = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "samsung-i2s")) { + dev_err(&pdev->dev, "Unable to request SFR region\n"); + return -EBUSY; + } + regs_base = res->start; + + i2s_cfg = &i2s_pdata->type.i2s; + quirks = i2s_cfg->quirks; + + pri_dai = i2s_alloc_dai(pdev, false); + if (!pri_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); + ret = -ENOMEM; + goto err1; + } + + pri_dai->dma_playback.dma_addr = regs_base + I2STXD; + pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; + pri_dai->dma_playback.client = + (struct s3c2410_dma_client *)&pri_dai->dma_playback; + pri_dai->dma_capture.client = + (struct s3c2410_dma_client *)&pri_dai->dma_capture; + pri_dai->dma_playback.channel = dma_pl_chan; + pri_dai->dma_capture.channel = dma_cp_chan; + pri_dai->src_clk = i2s_cfg->src_clk; + pri_dai->dma_playback.dma_size = 4; + pri_dai->dma_capture.dma_size = 4; + pri_dai->base = regs_base; + pri_dai->quirks = quirks; + + if (quirks & QUIRK_PRI_6CHAN) + pri_dai->i2s_dai_drv.playback.channels_max = 6; + + if (quirks & QUIRK_SEC_DAI) { + sec_dai = i2s_alloc_dai(pdev, true); + if (!sec_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); + ret = -ENOMEM; + goto err2; + } + sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; + sec_dai->dma_playback.client = + (struct s3c2410_dma_client *)&sec_dai->dma_playback; + /* Use iDMA always if SysDMA not provided */ + sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; + sec_dai->src_clk = i2s_cfg->src_clk; + sec_dai->dma_playback.dma_size = 4; + sec_dai->base = regs_base; + sec_dai->quirks = quirks; + sec_dai->pri_dai = pri_dai; + pri_dai->sec_dai = sec_dai; + } + + if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); + + return 0; +err3: + kfree(sec_dai); +err2: + kfree(pri_dai); +err1: + release_mem_region(regs_base, resource_size(res)); + + return ret; +} + +static __devexit int samsung_i2s_remove(struct platform_device *pdev) +{ + struct i2s_dai *i2s, *other; + + i2s = dev_get_drvdata(&pdev->dev); + other = i2s->pri_dai ? : i2s->sec_dai; + + if (other) { + other->pri_dai = NULL; + other->sec_dai = NULL; + } else { + struct resource *res; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) + release_mem_region(res->start, resource_size(res)); + } + + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + + kfree(i2s); + + snd_soc_unregister_dai(&pdev->dev); + + return 0; +} + +static struct platform_driver samsung_i2s_driver = { + .probe = samsung_i2s_probe, + .remove = samsung_i2s_remove, + .driver = { + .name = "samsung-i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init samsung_i2s_init(void) +{ + return platform_driver_register(&samsung_i2s_driver); +} +module_init(samsung_i2s_init); + +static void __exit samsung_i2s_exit(void) +{ + platform_driver_unregister(&samsung_i2s_driver); +} +module_exit(samsung_i2s_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); +MODULE_DESCRIPTION("Samsung I2S Interface"); +MODULE_ALIAS("platform:samsung-i2s"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h new file mode 100644 index 0000000..8e15f6a --- /dev/null +++ b/sound/soc/samsung/i2s.h @@ -0,0 +1,29 @@ +/* sound/soc/samsung/i2s.h + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh <jassi.brar@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __SND_SOC_SAMSUNG_I2S_H +#define __SND_SOC_SAMSUNG_I2S_H + +/* + * Maximum number of I2S blocks that any SoC can have. + * The secondary interface of a CPU dai(if there exists any), + * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF] + */ +#define SAMSUNG_I2S_SECOFF 4 + +#define SAMSUNG_I2S_DIV_BCLK 1 + +#define SAMSUNG_I2S_RCLKSRC_0 0 +#define SAMSUNG_I2S_RCLKSRC_1 1 +#define SAMSUNG_I2S_CDCLK 2 + +#endif /* __SND_SOC_SAMSUNG_I2S_H */ diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 49605cd..0880252 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/jive_wm8750.c +/* sound/soc/samsung/jive_wm8750.c * * Copyright 2007,2008 Simtec Electronics * @@ -21,11 +21,10 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c2412-i2s.h" #include "../codecs/wm8750.h" @@ -111,18 +110,19 @@ static struct snd_soc_ops jive_ops = { static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* These endpoints are not being used. */ - snd_soc_dapm_nc_pin(codec, "LINPUT2"); - snd_soc_dapm_nc_pin(codec, "RINPUT2"); - snd_soc_dapm_nc_pin(codec, "LINPUT3"); - snd_soc_dapm_nc_pin(codec, "RINPUT3"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONO"); + snd_soc_dapm_nc_pin(dapm, "LINPUT2"); + snd_soc_dapm_nc_pin(dapm, "RINPUT2"); + snd_soc_dapm_nc_pin(dapm, "LINPUT3"); + snd_soc_dapm_nc_pin(dapm, "RINPUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONO"); /* Add jive specific widgets */ - err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); if (err) { printk(KERN_ERR "%s: failed to add widgets (%d)\n", @@ -130,8 +130,8 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) return err; } - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_sync(dapm); return 0; } @@ -141,7 +141,7 @@ static struct snd_soc_dai_link jive_dai = { .stream_name = "WM8750", .cpu_dai_name = "s3c2412-i2s", .codec_dai_name = "wm8750-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8750-codec.0-0x1a", .init = jive_wm8750_init, .ops = &jive_ops, diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/samsung/lm4857.h index 0cf5b70..0cf5b70 100644 --- a/sound/soc/s3c24xx/lm4857.h +++ b/sound/soc/samsung/lm4857.h diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c index abe64ab..a2bb34d 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/samsung/ln2440sbc_alc650.c @@ -21,10 +21,9 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> -#include "s3c-dma.h" -#include "s3c-ac97.h" +#include "dma.h" +#include "ac97.h" static struct snd_soc_card ln2440sbc; @@ -32,10 +31,10 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "s3c-ac97", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c index e97bdf1..920e8d1 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/samsung/neo1973_gta02_wm8753.c @@ -22,7 +22,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/mach-types.h> @@ -32,7 +31,7 @@ #include <asm/io.h> #include <mach/gta02.h> #include "../codecs/wm8753.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" static struct snd_soc_card neo1973_gta02; @@ -333,16 +332,17 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "OUT4"); - snd_soc_dapm_nc_pin(codec, "LINE1"); - snd_soc_dapm_nc_pin(codec, "LINE2"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); /* Add neo1973 gta02 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, ARRAY_SIZE(wm8753_dapm_widgets)); /* add neo1973 gta02 specific controls */ @@ -353,25 +353,25 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) return err; /* set up neo1973 gta02 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* set endpoints to default off mode */ - snd_soc_dapm_disable_pin(codec, "Stereo Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Handset Mic"); - snd_soc_dapm_disable_pin(codec, "Handset Spk"); + snd_soc_dapm_disable_pin(dapm, "Stereo Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Spk"); /* allow audio paths from the GSM modem to run during suspend */ - snd_soc_dapm_ignore_suspend(codec, "Stereo Out"); - snd_soc_dapm_ignore_suspend(codec, "GSM Line Out"); - snd_soc_dapm_ignore_suspend(codec, "GSM Line In"); - snd_soc_dapm_ignore_suspend(codec, "Headset Mic"); - snd_soc_dapm_ignore_suspend(codec, "Handset Mic"); - snd_soc_dapm_ignore_suspend(codec, "Handset Spk"); + snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = { .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "wm8753-hifi", .init = neo1973_gta02_wm8753_init, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8753-codec.0-0x1a", .ops = &neo1973_gta02_hifi_ops, }, @@ -411,7 +411,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = { .codec_dai_name = "wm8753-voice", .ops = &neo1973_gta02_voice_ops, .codec_name = "wm8753-codec.0-0x1a", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index f4f2ee7..c7a2451 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -21,7 +21,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/tlv.h> #include <asm/mach-types.h> @@ -36,7 +35,7 @@ #include "../codecs/wm8753.h" #include "lm4857.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" /* define the scenarios */ @@ -237,81 +236,83 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + pr_debug("Entered %s\n", __func__); switch (neo1973_scenario) { case NEO_AUDIO_OFF: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_HANDSET: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_HEADSET: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; default: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -502,20 +503,21 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; pr_debug("Entered %s\n", __func__); /* set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "LOUT2"); - snd_soc_dapm_nc_pin(codec, "ROUT2"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "OUT4"); - snd_soc_dapm_nc_pin(codec, "LINE1"); - snd_soc_dapm_nc_pin(codec, "LINE2"); + snd_soc_dapm_nc_pin(dapm, "LOUT2"); + snd_soc_dapm_nc_pin(dapm, "ROUT2"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); /* Add neo1973 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, ARRAY_SIZE(wm8753_dapm_widgets)); /* set endpoints to default mode */ @@ -528,10 +530,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) return err; /* set up neo1973 specific audio routes */ - err = snd_soc_dapm_add_routes(codec, dapm_routes, + err = snd_soc_dapm_add_routes(dapm, dapm_routes, ARRAY_SIZE(dapm_routes)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -556,7 +558,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", .stream_name = "WM8753 HiFi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "wm8753-hifi", .codec_name = "wm8753-codec.0-0x1a", @@ -566,7 +568,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Voice via BT */ .name = "Bluetooth", .stream_name = "Voice", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "bluetooth-dai", .codec_dai_name = "wm8753-voice", .codec_name = "wm8753-codec.0-0x1a", diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/samsung/pcm.c index 2e020e1..48d0b75 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/samsung/pcm.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c-pcm.c +/* sound/soc/samsung/pcm.c * * ALSA SoC Audio Layer - S3C PCM-Controller driver * @@ -29,8 +29,8 @@ #include <plat/audio.h> #include <plat/dma.h> -#include "s3c-dma.h" -#include "s3c-pcm.h" +#include "dma.h" +#include "pcm.h" static struct s3c2410_dma_client s3c_pcm_dma_client_out = { .name = "PCM Stereo out" diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/samsung/pcm.h index f60baa1..03393dc 100644 --- a/sound/soc/s3c24xx/s3c-pcm.h +++ b/sound/soc/samsung/pcm.h @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c-pcm.h +/* sound/soc/samsung/pcm.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h index 5e5e568..5e5e568 100644 --- a/sound/soc/s3c24xx/regs-i2s-v2.h +++ b/sound/soc/samsung/regs-i2s-v2.h diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 468cc11..5a4587e 100644 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -25,7 +25,6 @@ #include <linux/clk.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/uda1380.h> #include <sound/jack.h> @@ -35,7 +34,7 @@ #include <asm/mach-types.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "../codecs/uda1380.h" @@ -95,7 +94,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "uda1380-hifi", .init = rx1950_uda1380_init, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "uda1380-codec.0-001a", .ops = &rx1950_ops, }, @@ -228,26 +227,27 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Add rx1950 specific widgets */ - err = snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, ARRAY_SIZE(uda1380_dapm_widgets)); if (err) return err; /* Set up rx1950 specific audio path audio_mapnects */ - err = snd_soc_dapm_add_routes(codec, audio_map, + err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (err) return err; - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &hp_jack); diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index b3866d5..094f36e 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c-i2c-v2.c +/* sound/soc/samsung/s3c-i2c-v2.c * * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. * @@ -28,7 +28,7 @@ #include "regs-i2s-v2.h" #include "s3c-i2s-v2.h" -#include "s3c-dma.h" +#include "dma.h" #undef S3C_IIS_V2_SUPPORTED diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h index d458301..f8297d9 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.h +++ b/sound/soc/samsung/s3c-i2s-v2.h @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c-i2s-v2.h +/* sound/soc/samsung/s3c-i2s-v2.h * * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver * diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 4a861cf..7ea8378 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c2412-i2s.c +/* sound/soc/samsung/s3c2412-i2s.c * * ALSA Soc Audio Layer - S3C2412 I2S driver * @@ -35,7 +35,7 @@ #include <mach/regs-gpio.h> #include <mach/dma.h> -#include "s3c-dma.h" +#include "dma.h" #include "regs-i2s-v2.h" #include "s3c2412-i2s.h" diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h index 01a0471..02ad579 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.h +++ b/sound/soc/samsung/s3c2412-i2s.h @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c2412-i2s.c +/* sound/soc/samsung/s3c2412-i2s.c * * ALSA Soc Audio Layer - S3C2412 I2S driver * diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index e060daa..13e41ed 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -38,7 +38,7 @@ #include <plat/regs-iis.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" static struct s3c2410_dma_client s3c24xx_dma_client_out = { diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h index f9ca04e..f9ca04e 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.h +++ b/sound/soc/samsung/s3c24xx-i2s.h diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index c4c1114..a434032d 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec.c +/* sound/soc/samsung/s3c24xx_simtec.c * * Copyright 2009 Simtec Electronics * @@ -17,11 +17,10 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <plat/audio-simtec.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h index e63d5ff..8270748 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.h +++ b/sound/soc/samsung/s3c24xx_simtec.h @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec.h +/* sound/soc/samsung/s3c24xx_simtec.h * * Copyright 2009 Simtec Electronics * diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index f884537..0083aff 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +/* sound/soc/samsung/s3c24xx_simtec_hermes.c * * Copyright 2009 Simtec Electronics * @@ -14,11 +14,10 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <plat/audio-simtec.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" @@ -76,19 +75,20 @@ static const struct snd_soc_dapm_route base_map[] = { static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, dapm_widgets, + snd_soc_dapm_new_controls(dapm, dapm_widgets, ARRAY_SIZE(dapm_widgets)); - snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); simtec_audio_init(rtd); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -99,7 +99,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = { .codec_name = "tlv320aic3x-codec.0-0x1a", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .init = simtec_hermes_init, }; diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index c096759..fbba4e3 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c * * Copyright 2009 Simtec Electronics * @@ -14,11 +14,10 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <plat/audio-simtec.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" @@ -65,19 +64,20 @@ static const struct snd_soc_dapm_route base_map[] = { static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, dapm_widgets, + snd_soc_dapm_new_controls(dapm, dapm_widgets, ARRAY_SIZE(dapm_widgets)); - snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); simtec_audio_init(rtd); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -88,7 +88,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = { .codec_name = "tlv320aic3x-codec.0-0x1a", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .init = simtec_tlv320aic23_init, }; diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index bd48ffb..cdc8ecb 100644 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -18,13 +18,12 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/s3c24xx_uda134x.h> #include <sound/uda134x.h> #include <plat/regs-iis.h> -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "../codecs/uda134x.h" @@ -231,7 +230,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { .codec_dai_name = "uda134x-hifi", .cpu_dai_name = "s3c24xx-i2s", .ops = &s3c24xx_uda134x_ops, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }; static struct snd_soc_card snd_soc_s3c24xx_uda134x = { diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index dd20ca7..d6a340b8 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/smartq_wm8987.c +/* sound/soc/samsung/smartq_wm8987.c * * Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com> * @@ -19,13 +19,13 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/jack.h> #include <asm/mach-types.h> -#include "s3c-dma.h" -#include "s3c64xx-i2s.h" +#include "dma.h" +#include "i2s.h" #include "../codecs/wm8750.h" @@ -41,13 +41,9 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - struct s3c_i2sv2_rate_calc div; unsigned int clk = 0; int ret; - s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), - s3c_i2sv2_get_clock(cpu_dai)); - switch (params_rate(params)) { case 8000: case 16000: @@ -78,20 +74,21 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); + /* Use PCLK for I2S signal generation */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div); + /* Gate the RCLK output on PAD */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, - div.clk_div - 1); + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, + SND_SOC_CLOCK_IN); if (ret < 0) return ret; @@ -158,10 +155,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int smartq_wm8987_init(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int err = 0; /* Add SmartQ specific widgets */ - snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets, ARRAY_SIZE(wm8987_dapm_widgets)); /* add SmartQ specific controls */ @@ -172,20 +170,20 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec) return err; /* setup SmartQ specific audio path */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "LINPUT1"); - snd_soc_dapm_nc_pin(codec, "RINPUT1"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "ROUT1"); + snd_soc_dapm_nc_pin(dapm, "LINPUT1"); + snd_soc_dapm_nc_pin(dapm, "RINPUT1"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "ROUT1"); /* set endpoints to default off mode */ - snd_soc_dapm_enable_pin(codec, "Internal Speaker"); - snd_soc_dapm_enable_pin(codec, "Internal Mic"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Internal Speaker"); + snd_soc_dapm_enable_pin(dapm, "Internal Mic"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - err = snd_soc_dapm_sync(codec); + err = snd_soc_dapm_sync(dapm); if (err) return err; @@ -211,9 +209,9 @@ static struct snd_soc_dai_link smartq_dai[] = { { .name = "wm8987", .stream_name = "SmartQ Hi-Fi", - .cpu_dai_name = "s3c64xx-i2s.0", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8750-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8750-codec.0-0x1a", .init = smartq_wm8987_init, .ops = &smartq_hifi_ops, diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c index 4613288..3be7e7e 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/samsung/smdk2443_wm9710.c @@ -17,10 +17,9 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> -#include "s3c-dma.h" -#include "s3c-ac97.h" +#include "dma.h" +#include "ac97.h" static struct snd_soc_card smdk2443; @@ -28,10 +27,10 @@ static struct snd_soc_dai_link smdk2443_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "s3c-ac97", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index c8bd904..cd29da0 100644 --- a/sound/soc/s3c24xx/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -18,7 +18,7 @@ #include <sound/soc.h> -#include "s3c-dma.h" +#include "dma.h" #include "spdif.h" /* Audio clock settings are belonged to board specific part. Every @@ -157,7 +157,7 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "S/PDIF", .stream_name = "S/PDIF PCM Playback", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "samsung-spdif", .codec_dai_name = "dit-hifi", .codec_name = "spdif-dit", diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 052e499..0ae3d57 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -1,5 +1,5 @@ /* - * smdk64xx_wm8580.c + * smdk_wm8580.c * * Copyright (c) 2009 Samsung Electronics Co. Ltd * Author: Jaswinder Singh <jassi.brar@samsung.com> @@ -16,11 +16,12 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> + +#include <asm/mach-types.h> #include "../codecs/wm8580.h" -#include "s3c-dma.h" -#include "s3c64xx-i2s.h" +#include "dma.h" +#include "i2s.h" /* * Default CFG switch settings to use this driver: @@ -28,10 +29,10 @@ * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On */ -/* SMDK64XX has a 12MHZ crystal attached to WM8580 */ -#define SMDK64XX_WM8580_FREQ 12000000 +/* SMDK has a 12MHZ crystal attached to WM8580 */ +#define SMDK_WM8580_FREQ 12000000 -static int smdk64xx_hw_params(struct snd_pcm_substream *substream, +static int smdk_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -96,17 +97,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* We use PCLK for basic ops in SoC-Slave mode */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - /* Set WM8580 to drive MCLK from its PLLA */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, WM8580_CLKSRC_PLLA); @@ -114,7 +104,7 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream, return ret; ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, - SMDK64XX_WM8580_FREQ, pll_out); + SMDK_WM8580_FREQ, pll_out); if (ret < 0) return ret; @@ -123,32 +113,24 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs); - if (ret < 0) - return ret; - return 0; } /* - * SMDK64XX WM8580 DAI operations. + * SMDK WM8580 DAI operations. */ -static struct snd_soc_ops smdk64xx_ops = { - .hw_params = smdk64xx_hw_params, +static struct snd_soc_ops smdk_ops = { + .hw_params = smdk_hw_params, }; -/* SMDK64xx Playback widgets */ +/* SMDK Playback widgets */ static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { SND_SOC_DAPM_HP("Front", NULL), SND_SOC_DAPM_HP("Center+Sub", NULL), SND_SOC_DAPM_HP("Rear", NULL), }; -/* SMDK64xx Capture widgets */ +/* SMDK Capture widgets */ static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { SND_SOC_DAPM_MIC("MicIn", NULL), SND_SOC_DAPM_LINE("LineIn", NULL), @@ -179,94 +161,125 @@ static const struct snd_soc_dapm_route audio_map_rx[] = { {"Rear", NULL, "VOUT3R"}, }; -static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) +static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - /* Add smdk64xx specific Capture widgets */ - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt, + /* Add smdk specific Capture widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, ARRAY_SIZE(wm8580_dapm_widgets_cpt)); /* Set up PAIFTX audio path */ - snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx)); + snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); /* Enabling the microphone requires the fitting of a 0R * resistor to connect the line from the microphone jack. */ - snd_soc_dapm_disable_pin(codec, "MicIn"); + snd_soc_dapm_disable_pin(dapm, "MicIn"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } -static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) +static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - /* Add smdk64xx specific Playback widgets */ - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk, + /* Add smdk specific Playback widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, ARRAY_SIZE(wm8580_dapm_widgets_pbk)); /* Set up PAIFRX audio path */ - snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx)); + snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } -static struct snd_soc_dai_link smdk64xx_dai[] = { -{ /* Primary Playback i/f */ - .name = "WM8580 PAIF RX", - .stream_name = "Playback", - .cpu_dai_name = "s3c64xx-iis-v4", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk64xx_wm8580_init_paifrx, - .ops = &smdk64xx_ops, -}, -{ /* Primary Capture i/f */ - .name = "WM8580 PAIF TX", - .stream_name = "Capture", - .cpu_dai_name = "s3c64xx-iis-v4", - .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk64xx_wm8580_init_paiftx, - .ops = &smdk64xx_ops, -}, +enum { + PRI_PLAYBACK = 0, + PRI_CAPTURE, + SEC_PLAYBACK, +}; + +static struct snd_soc_dai_link smdk_dai[] = { + [PRI_PLAYBACK] = { /* Primary Playback i/f */ + .name = "WM8580 PAIF RX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, + [PRI_CAPTURE] = { /* Primary Capture i/f */ + .name = "WM8580 PAIF TX", + .stream_name = "Capture", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paiftx, + .ops = &smdk_ops, + }, + [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ + .name = "Sec_FIFO TX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.x", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, }; -static struct snd_soc_card smdk64xx = { - .name = "SMDK64xx 5.1", - .dai_link = smdk64xx_dai, - .num_links = ARRAY_SIZE(smdk64xx_dai), +static struct snd_soc_card smdk = { + .name = "SMDK-I2S", + .dai_link = smdk_dai, + .num_links = 2, }; -static struct platform_device *smdk64xx_snd_device; +static struct platform_device *smdk_snd_device; -static int __init smdk64xx_audio_init(void) +static int __init smdk_audio_init(void) { int ret; + char *str; + + if (machine_is_smdkc100()) { + smdk.num_links = 3; + /* S5PC100 has I2S0 as v5 */ + str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0'; + str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; + str[strlen(str) - 1] = '0'; + /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ + str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF; + } - smdk64xx_snd_device = platform_device_alloc("soc-audio", -1); - if (!smdk64xx_snd_device) + smdk_snd_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_device) return -ENOMEM; - platform_set_drvdata(smdk64xx_snd_device, &smdk64xx); - ret = platform_device_add(smdk64xx_snd_device); + platform_set_drvdata(smdk_snd_device, &smdk); + ret = platform_device_add(smdk_snd_device); if (ret) - platform_device_put(smdk64xx_snd_device); + platform_device_put(smdk_snd_device); return ret; } -module_init(smdk64xx_audio_init); +module_init(smdk_audio_init); MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); -MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580"); +MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 33ba8fd..7ce2430 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -15,8 +15,8 @@ #include <linux/device.h> #include <sound/soc.h> -#include "s3c-dma.h" -#include "s3c-ac97.h" +#include "dma.h" +#include "ac97.h" static struct snd_soc_card smdk; @@ -45,8 +45,8 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "AC97", .stream_name = "AC97 PCM", - .platform_name = "s3c24xx-pcm-audio", - .cpu_dai_name = "s3c-ac97", + .platform_name = "samsung-audio", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "wm9713-hifi", .codec_name = "wm9713-codec", }; diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/samsung/spdif.c index ce554e9..f081640 100644 --- a/sound/soc/s3c24xx/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/spdif.c +/* sound/soc/samsung/spdif.c * * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver * @@ -20,7 +20,7 @@ #include <plat/audio.h> #include <mach/dma.h> -#include "s3c-dma.h" +#include "dma.h" #include "spdif.h" /* Registers */ diff --git a/sound/soc/s3c24xx/spdif.h b/sound/soc/samsung/spdif.h index 3ed5559..4f72cb4 100644 --- a/sound/soc/s3c24xx/spdif.h +++ b/sound/soc/samsung/spdif.h @@ -1,4 +1,4 @@ -/* sound/soc/s3c24xx/spdif.h +/* sound/soc/samsung/spdif.h * * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver * diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index ac6c49c..df13338 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -20,7 +20,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include "../codecs/wm8978.h" #include "siu.h" @@ -140,11 +139,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, migor_dapm_widgets, + snd_soc_dapm_new_controls(dapm, migor_dapm_widgets, ARRAY_SIZE(migor_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index f8e0ab8..917d3ce 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -12,7 +12,6 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <asm/io.h> #define IPSEL 0xFE400034 @@ -23,7 +22,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform; static int machine_init(struct snd_soc_pcm_runtime *rtd) { - snd_soc_dapm_sync(rtd->codec); + snd_soc_dapm_sync(&rtd->codec->dapm); return 0; } diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h index 9f4dcb9..83c3430 100644 --- a/sound/soc/sh/siu.h +++ b/sound/soc/sh/siu.h @@ -75,7 +75,7 @@ struct siu_firmware { #include <sound/core.h> #include <sound/pcm.h> -#include <sound/soc-dai.h> +#include <sound/soc.h> #define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */ #define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index af53b64..4973c29 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -28,7 +28,7 @@ #include <asm/siu.h> #include <sound/control.h> -#include <sound/soc-dai.h> +#include <sound/soc.h> #include "siu.h" diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index ed29c9e..a423bab 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -29,7 +29,7 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> -#include <sound/soc-dai.h> +#include <sound/soc.h> #include <asm/siu.h> diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index d214f02..6c0589e 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -14,27 +14,34 @@ #include <linux/i2c.h> #include <linux/spi/spi.h> #include <sound/soc.h> +#include <linux/lzo.h> +#include <linux/bitmap.h> +#include <linux/rbtree.h> static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[2]; int ret; @@ -42,16 +49,17 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, data[1] = value & 0x00ff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -94,23 +102,27 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data, static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[2]; int ret; @@ -118,16 +130,17 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, data[1] = value & 0x00ff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -170,24 +183,25 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data, static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u8 *cache = codec->reg_cache; u8 data[2]; + int ret; reg &= 0xff; data[0] = reg; data[1] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; else @@ -197,7 +211,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + int ret; + unsigned int val; reg &= 0xff; if (reg >= codec->driver->reg_cache_size || @@ -205,10 +220,14 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } #if defined(CONFIG_SPI_MASTER) @@ -244,24 +263,25 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data, static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *reg_cache = codec->reg_cache; u8 data[3]; + int ret; data[0] = reg; data[1] = (value >> 8) & 0xff; data[2] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - reg_cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - if (codec->hw_write(codec->control_data, data, 3) == 3) return 0; else @@ -271,17 +291,22 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); - } else { - return cache[reg]; } + + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } #if defined(CONFIG_SPI_MASTER) @@ -420,7 +445,8 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + int ret; + unsigned int val; reg &= 0xff; if (reg >= codec->driver->reg_cache_size || @@ -428,16 +454,19 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u8 *cache = codec->reg_cache; u8 data[3]; int ret; @@ -447,16 +476,17 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, reg &= 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 3); if (ret == 3) return 0; @@ -534,23 +564,28 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + + return val; } static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[4]; int ret; @@ -560,16 +595,17 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, data[3] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 4); if (ret == 4) return 0; @@ -724,3 +760,883 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, return 0; } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); + +struct snd_soc_rbtree_node { + struct rb_node node; + unsigned int reg; + unsigned int value; + unsigned int defval; +} __attribute__ ((packed)); + +struct snd_soc_rbtree_ctx { + struct rb_root root; +}; + +static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup( + struct rb_root *root, unsigned int reg) +{ + struct rb_node *node; + struct snd_soc_rbtree_node *rbnode; + + node = root->rb_node; + while (node) { + rbnode = container_of(node, struct snd_soc_rbtree_node, node); + if (rbnode->reg < reg) + node = node->rb_left; + else if (rbnode->reg > reg) + node = node->rb_right; + else + return rbnode; + } + + return NULL; +} + + +static int snd_soc_rbtree_insert(struct rb_root *root, + struct snd_soc_rbtree_node *rbnode) +{ + struct rb_node **new, *parent; + struct snd_soc_rbtree_node *rbnode_tmp; + + parent = NULL; + new = &root->rb_node; + while (*new) { + rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node, + node); + parent = *new; + if (rbnode_tmp->reg < rbnode->reg) + new = &((*new)->rb_left); + else if (rbnode_tmp->reg > rbnode->reg) + new = &((*new)->rb_right); + else + return 0; + } + + /* insert the node into the rbtree */ + rb_link_node(&rbnode->node, parent, new); + rb_insert_color(&rbnode->node, root); + + return 1; +} + +static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct rb_node *node; + struct snd_soc_rbtree_node *rbnode; + unsigned int val; + + rbtree_ctx = codec->reg_cache; + for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { + rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); + if (rbnode->value == rbnode->defval) + continue; + snd_soc_cache_read(codec, rbnode->reg, &val); + snd_soc_write(codec, rbnode->reg, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + rbnode->reg, val); + } + + return 0; +} + +static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbnode; + + rbtree_ctx = codec->reg_cache; + rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); + if (rbnode) { + if (rbnode->value == value) + return 0; + rbnode->value = value; + } else { + /* bail out early, no need to create the rbnode yet */ + if (!value) + return 0; + /* + * for uninitialized registers whose value is changed + * from the default zero, create an rbnode and insert + * it into the tree. + */ + rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); + if (!rbnode) + return -ENOMEM; + rbnode->reg = reg; + rbnode->value = value; + snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode); + } + + return 0; +} + +static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbnode; + + rbtree_ctx = codec->reg_cache; + rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); + if (rbnode) { + *value = rbnode->value; + } else { + /* uninitialized registers default to 0 */ + *value = 0; + } + + return 0; +} + +static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec) +{ + struct rb_node *next; + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbtree_node; + + /* if we've already been called then just return */ + rbtree_ctx = codec->reg_cache; + if (!rbtree_ctx) + return 0; + + /* free up the rbtree */ + next = rb_first(&rbtree_ctx->root); + while (next) { + rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node); + next = rb_next(&rbtree_node->node); + rb_erase(&rbtree_node->node, &rbtree_ctx->root); + kfree(rbtree_node); + } + + /* release the resources */ + kfree(codec->reg_cache); + codec->reg_cache = NULL; + + return 0; +} + +static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + + codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); + if (!codec->reg_cache) + return -ENOMEM; + + rbtree_ctx = codec->reg_cache; + rbtree_ctx->root = RB_ROOT; + + if (!codec->driver->reg_cache_default) + return 0; + +/* + * populate the rbtree with the initialized registers. All other + * registers will be inserted into the tree when they are first written. + * + * The reasoning behind this, is that we need to step through and + * dereference the cache in u8/u16 increments without sacrificing + * portability. This could also be done using memcpy() but that would + * be slightly more cryptic. + */ +#define snd_soc_rbtree_populate(cache) \ +({ \ + int ret, i; \ + struct snd_soc_rbtree_node *rbtree_node; \ + \ + ret = 0; \ + cache = codec->driver->reg_cache_default; \ + for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ + if (!cache[i]) \ + continue; \ + rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \ + if (!rbtree_node) { \ + ret = -ENOMEM; \ + snd_soc_cache_exit(codec); \ + break; \ + } \ + rbtree_node->reg = i; \ + rbtree_node->value = cache[i]; \ + rbtree_node->defval = cache[i]; \ + snd_soc_rbtree_insert(&rbtree_ctx->root, \ + rbtree_node); \ + } \ + ret; \ +}) + + switch (codec->driver->reg_word_size) { + case 1: { + const u8 *cache; + + return snd_soc_rbtree_populate(cache); + } + case 2: { + const u16 *cache; + + return snd_soc_rbtree_populate(cache); + } + default: + BUG(); + } + + return 0; +} + +struct snd_soc_lzo_ctx { + void *wmem; + void *dst; + const void *src; + size_t src_len; + size_t dst_len; + size_t decompressed_size; + unsigned long *sync_bmp; + int sync_bmp_nbits; +}; + +#define LZO_BLOCK_NUM 8 +static int snd_soc_lzo_block_count(void) +{ + return LZO_BLOCK_NUM; +} + +static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx) +{ + lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + if (!lzo_ctx->wmem) + return -ENOMEM; + return 0; +} + +static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx) +{ + size_t compress_size; + int ret; + + ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len, + lzo_ctx->dst, &compress_size, lzo_ctx->wmem); + if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len) + return -EINVAL; + lzo_ctx->dst_len = compress_size; + return 0; +} + +static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx) +{ + size_t dst_len; + int ret; + + dst_len = lzo_ctx->dst_len; + ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len, + lzo_ctx->dst, &dst_len); + if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len) + return -EINVAL; + return 0; +} + +static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec, + struct snd_soc_lzo_ctx *lzo_ctx) +{ + int ret; + + lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE); + lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); + if (!lzo_ctx->dst) { + lzo_ctx->dst_len = 0; + return -ENOMEM; + } + + ret = snd_soc_lzo_compress(lzo_ctx); + if (ret < 0) + return ret; + return 0; +} + +static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec, + struct snd_soc_lzo_ctx *lzo_ctx) +{ + int ret; + + lzo_ctx->dst_len = lzo_ctx->decompressed_size; + lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); + if (!lzo_ctx->dst) { + lzo_ctx->dst_len = 0; + return -ENOMEM; + } + + ret = snd_soc_lzo_decompress(lzo_ctx); + if (ret < 0) + return ret; + return 0; +} + +static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, + unsigned int reg) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return (reg * codec_drv->reg_word_size) / + DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); +} + +static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, + unsigned int reg) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) / + codec_drv->reg_word_size); +} + +static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); +} + +static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + unsigned int val; + int i; + + lzo_blocks = codec->reg_cache; + for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { + snd_soc_cache_read(codec, i, &val); + snd_soc_write(codec, i, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + i, val); + } + + return 0; +} + +static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; + int ret, blkindex, blkpos; + size_t blksize, tmp_dst_len; + void *tmp_dst; + + /* index of the compressed lzo block */ + blkindex = snd_soc_lzo_get_blkindex(codec, reg); + /* register index within the decompressed block */ + blkpos = snd_soc_lzo_get_blkpos(codec, reg); + /* size of the compressed block */ + blksize = snd_soc_lzo_get_blksize(codec); + lzo_blocks = codec->reg_cache; + lzo_block = lzo_blocks[blkindex]; + + /* save the pointer and length of the compressed block */ + tmp_dst = lzo_block->dst; + tmp_dst_len = lzo_block->dst_len; + + /* prepare the source to be the compressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* decompress the block */ + ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); + if (ret < 0) { + kfree(lzo_block->dst); + goto out; + } + + /* write the new value to the cache */ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + cache = lzo_block->dst; + if (cache[blkpos] == value) { + kfree(lzo_block->dst); + goto out; + } + cache[blkpos] = value; + } + break; + case 2: { + u16 *cache; + cache = lzo_block->dst; + if (cache[blkpos] == value) { + kfree(lzo_block->dst); + goto out; + } + cache[blkpos] = value; + } + break; + default: + BUG(); + } + + /* prepare the source to be the decompressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* compress the block */ + ret = snd_soc_lzo_compress_cache_block(codec, lzo_block); + if (ret < 0) { + kfree(lzo_block->dst); + kfree(lzo_block->src); + goto out; + } + + /* set the bit so we know we have to sync this register */ + set_bit(reg, lzo_block->sync_bmp); + kfree(tmp_dst); + kfree(lzo_block->src); + return 0; +out: + lzo_block->dst = tmp_dst; + lzo_block->dst_len = tmp_dst_len; + return ret; +} + +static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; + int ret, blkindex, blkpos; + size_t blksize, tmp_dst_len; + void *tmp_dst; + + *value = 0; + /* index of the compressed lzo block */ + blkindex = snd_soc_lzo_get_blkindex(codec, reg); + /* register index within the decompressed block */ + blkpos = snd_soc_lzo_get_blkpos(codec, reg); + /* size of the compressed block */ + blksize = snd_soc_lzo_get_blksize(codec); + lzo_blocks = codec->reg_cache; + lzo_block = lzo_blocks[blkindex]; + + /* save the pointer and length of the compressed block */ + tmp_dst = lzo_block->dst; + tmp_dst_len = lzo_block->dst_len; + + /* prepare the source to be the compressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* decompress the block */ + ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); + if (ret >= 0) { + /* fetch the value from the cache */ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + cache = lzo_block->dst; + *value = cache[blkpos]; + } + break; + case 2: { + u16 *cache; + cache = lzo_block->dst; + *value = cache[blkpos]; + } + break; + default: + BUG(); + } + } + + kfree(lzo_block->dst); + /* restore the pointer and length of the compressed block */ + lzo_block->dst = tmp_dst; + lzo_block->dst_len = tmp_dst_len; + return 0; +} + +static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + int i, blkcount; + + lzo_blocks = codec->reg_cache; + if (!lzo_blocks) + return 0; + + blkcount = snd_soc_lzo_block_count(); + /* + * the pointer to the bitmap used for syncing the cache + * is shared amongst all lzo_blocks. Ensure it is freed + * only once. + */ + if (lzo_blocks[0]) + kfree(lzo_blocks[0]->sync_bmp); + for (i = 0; i < blkcount; ++i) { + if (lzo_blocks[i]) { + kfree(lzo_blocks[i]->wmem); + kfree(lzo_blocks[i]->dst); + } + /* each lzo_block is a pointer returned by kmalloc or NULL */ + kfree(lzo_blocks[i]); + } + kfree(lzo_blocks); + codec->reg_cache = NULL; + return 0; +} + +static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + size_t reg_size, bmp_size; + struct snd_soc_codec_driver *codec_drv; + int ret, tofree, i, blksize, blkcount; + const char *p, *end; + unsigned long *sync_bmp; + + ret = 0; + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + + /* + * If we have not been given a default register cache + * then allocate a dummy zero-ed out region, compress it + * and remember to free it afterwards. + */ + tofree = 0; + if (!codec_drv->reg_cache_default) + tofree = 1; + + if (!codec_drv->reg_cache_default) { + codec_drv->reg_cache_default = kzalloc(reg_size, + GFP_KERNEL); + if (!codec_drv->reg_cache_default) + return -ENOMEM; + } + + blkcount = snd_soc_lzo_block_count(); + codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks, + GFP_KERNEL); + if (!codec->reg_cache) { + ret = -ENOMEM; + goto err_tofree; + } + lzo_blocks = codec->reg_cache; + + /* + * allocate a bitmap to be used when syncing the cache with + * the hardware. Each time a register is modified, the corresponding + * bit is set in the bitmap, so we know that we have to sync + * that register. + */ + bmp_size = codec_drv->reg_cache_size; + sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof (long), + GFP_KERNEL); + if (!sync_bmp) { + ret = -ENOMEM; + goto err; + } + bitmap_zero(sync_bmp, reg_size); + + /* allocate the lzo blocks and initialize them */ + for (i = 0; i < blkcount; ++i) { + lzo_blocks[i] = kzalloc(sizeof **lzo_blocks, + GFP_KERNEL); + if (!lzo_blocks[i]) { + kfree(sync_bmp); + ret = -ENOMEM; + goto err; + } + lzo_blocks[i]->sync_bmp = sync_bmp; + lzo_blocks[i]->sync_bmp_nbits = reg_size; + /* alloc the working space for the compressed block */ + ret = snd_soc_lzo_prepare(lzo_blocks[i]); + if (ret < 0) + goto err; + } + + blksize = snd_soc_lzo_get_blksize(codec); + p = codec_drv->reg_cache_default; + end = codec_drv->reg_cache_default + reg_size; + /* compress the register map and fill the lzo blocks */ + for (i = 0; i < blkcount; ++i, p += blksize) { + lzo_blocks[i]->src = p; + if (p + blksize > end) + lzo_blocks[i]->src_len = end - p; + else + lzo_blocks[i]->src_len = blksize; + ret = snd_soc_lzo_compress_cache_block(codec, + lzo_blocks[i]); + if (ret < 0) + goto err; + lzo_blocks[i]->decompressed_size = + lzo_blocks[i]->src_len; + } + + if (tofree) + kfree(codec_drv->reg_cache_default); + return 0; +err: + snd_soc_cache_exit(codec); +err_tofree: + if (tofree) + kfree(codec_drv->reg_cache_default); + return ret; +} + +static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) +{ + int i; + struct snd_soc_codec_driver *codec_drv; + unsigned int val; + + codec_drv = codec->driver; + for (i = 0; i < codec_drv->reg_cache_size; ++i) { + snd_soc_cache_read(codec, i, &val); + if (codec_drv->reg_cache_default) { + switch (codec_drv->reg_word_size) { + case 1: { + const u8 *cache; + + cache = codec_drv->reg_cache_default; + if (cache[i] == val) + continue; + } + break; + case 2: { + const u16 *cache; + + cache = codec_drv->reg_cache_default; + if (cache[i] == val) + continue; + } + break; + default: + BUG(); + } + } + snd_soc_write(codec, i, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + i, val); + } + return 0; +} + +static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + + cache = codec->reg_cache; + cache[reg] = value; + } + break; + case 2: { + u16 *cache; + + cache = codec->reg_cache; + cache[reg] = value; + } + break; + default: + BUG(); + } + + return 0; +} + +static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + + cache = codec->reg_cache; + *value = cache[reg]; + } + break; + case 2: { + u16 *cache; + + cache = codec->reg_cache; + *value = cache[reg]; + } + break; + default: + BUG(); + } + + return 0; +} + +static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec) +{ + if (!codec->reg_cache) + return 0; + kfree(codec->reg_cache); + codec->reg_cache = NULL; + return 0; +} + +static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + + if (codec_drv->reg_cache_default) + codec->reg_cache = kmemdup(codec_drv->reg_cache_default, + reg_size, GFP_KERNEL); + else + codec->reg_cache = kzalloc(reg_size, GFP_KERNEL); + if (!codec->reg_cache) + return -ENOMEM; + + return 0; +} + +/* an array of all supported compression types */ +static const struct snd_soc_cache_ops cache_types[] = { + { + .id = SND_SOC_NO_COMPRESSION, + .init = snd_soc_flat_cache_init, + .exit = snd_soc_flat_cache_exit, + .read = snd_soc_flat_cache_read, + .write = snd_soc_flat_cache_write, + .sync = snd_soc_flat_cache_sync + }, + { + .id = SND_SOC_LZO_COMPRESSION, + .init = snd_soc_lzo_cache_init, + .exit = snd_soc_lzo_cache_exit, + .read = snd_soc_lzo_cache_read, + .write = snd_soc_lzo_cache_write, + .sync = snd_soc_lzo_cache_sync + }, + { + .id = SND_SOC_RBTREE_COMPRESSION, + .init = snd_soc_rbtree_cache_init, + .exit = snd_soc_rbtree_cache_exit, + .read = snd_soc_rbtree_cache_read, + .write = snd_soc_rbtree_cache_write, + .sync = snd_soc_rbtree_cache_sync + } +}; + +int snd_soc_cache_init(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_types); ++i) + if (cache_types[i].id == codec->driver->compress_type) + break; + if (i == ARRAY_SIZE(cache_types)) { + dev_err(codec->dev, "Could not match compress type: %d\n", + codec->driver->compress_type); + return -EINVAL; + } + + mutex_init(&codec->cache_rw_mutex); + codec->cache_ops = &cache_types[i]; + + if (codec->cache_ops->init) + return codec->cache_ops->init(codec); + return -EINVAL; +} + +/* + * NOTE: keep in mind that this function might be called + * multiple times. + */ +int snd_soc_cache_exit(struct snd_soc_codec *codec) +{ + if (codec->cache_ops && codec->cache_ops->exit) + return codec->cache_ops->exit(codec); + return -EINVAL; +} + +/** + * snd_soc_cache_read: Fetch the value of a given register from the cache. + * + * @codec: CODEC to configure. + * @reg: The register index. + * @value: The value to be returned. + */ +int snd_soc_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + int ret; + + mutex_lock(&codec->cache_rw_mutex); + + if (value && codec->cache_ops && codec->cache_ops->read) { + ret = codec->cache_ops->read(codec, reg, value); + mutex_unlock(&codec->cache_rw_mutex); + return ret; + } + + mutex_unlock(&codec->cache_rw_mutex); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_read); + +/** + * snd_soc_cache_write: Set the value of a given register in the cache. + * + * @codec: CODEC to configure. + * @reg: The register index. + * @value: The new register value. + */ +int snd_soc_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + mutex_lock(&codec->cache_rw_mutex); + + if (codec->cache_ops && codec->cache_ops->write) { + ret = codec->cache_ops->write(codec, reg, value); + mutex_unlock(&codec->cache_rw_mutex); + return ret; + } + + mutex_unlock(&codec->cache_rw_mutex); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_write); + +/** + * snd_soc_cache_sync: Sync the register cache with the hardware. + * + * @codec: CODEC to configure. + * + * Any registers that should not be synced should be marked as + * volatile. In general drivers can choose not to use the provided + * syncing functionality if they so require. + */ +int snd_soc_cache_sync(struct snd_soc_codec *codec) +{ + int ret; + + if (!codec->cache_sync) { + return 0; + } + + if (codec->cache_ops && codec->cache_ops->sync) { + ret = codec->cache_ops->sync(codec); + if (!ret) + codec->cache_sync = 0; + return ret; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_sync); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285a..c8d8dde 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -36,9 +36,11 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <sound/initval.h> +#define CREATE_TRACE_POINTS +#include <trace/events/asoc.h> + #define NAME_SIZE 32 static DEFINE_MUTEX(pcm_mutex); @@ -238,8 +240,10 @@ static const struct file_operations codec_reg_fops = { static void soc_init_codec_debugfs(struct snd_soc_codec *codec) { - codec->debugfs_codec_root = debugfs_create_dir(codec->name , - debugfs_root); + struct dentry *debugfs_card_root = codec->card->debugfs_card_root; + + codec->debugfs_codec_root = debugfs_create_dir(codec->name, + debugfs_card_root); if (!codec->debugfs_codec_root) { printk(KERN_WARNING "ASoC: Failed to create codec debugfs directory\n"); @@ -253,20 +257,13 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) printk(KERN_WARNING "ASoC: Failed to create codec register debugfs file\n"); - codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, - codec->debugfs_codec_root, - &codec->pop_time); - if (!codec->debugfs_pop_time) - printk(KERN_WARNING - "Failed to create pop time debugfs file\n"); - - codec->debugfs_dapm = debugfs_create_dir("dapm", + codec->dapm.debugfs_dapm = debugfs_create_dir("dapm", codec->debugfs_codec_root); - if (!codec->debugfs_dapm) + if (!codec->dapm.debugfs_dapm) printk(KERN_WARNING "Failed to create DAPM debugfs directory\n"); - snd_soc_dapm_debugfs_init(codec); + snd_soc_dapm_debugfs_init(&codec->dapm); } static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) @@ -374,6 +371,29 @@ static const struct file_operations platform_list_fops = { .llseek = default_llseek,/* read accesses f_pos */ }; +static void soc_init_card_debugfs(struct snd_soc_card *card) +{ + card->debugfs_card_root = debugfs_create_dir(card->name, + debugfs_root); + if (!card->debugfs_card_root) { + dev_warn(card->dev, + "ASoC: Failed to create codec debugfs directory\n"); + return; + } + + card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, + card->debugfs_card_root, + &card->pop_time); + if (!card->debugfs_pop_time) + dev_warn(card->dev, + "Failed to create pop time debugfs file\n"); +} + +static void soc_cleanup_card_debugfs(struct snd_soc_card *card) +{ + debugfs_remove_recursive(card->debugfs_card_root); +} + #else static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) @@ -383,6 +403,14 @@ static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) { } + +static inline void soc_init_card_debugfs(struct snd_soc_card *card) +{ +} + +static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) +{ +} #endif #ifdef CONFIG_SND_SOC_AC97_BUS @@ -1017,7 +1045,7 @@ static int soc_suspend(struct device *dev) /* close any waiting streams and save state */ for (i = 0; i < card->num_rtd; i++) { run_delayed_work(&card->rtd[i].delayed_work); - card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level; + card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level; } for (i = 0; i < card->num_rtd; i++) { @@ -1041,7 +1069,7 @@ static int soc_suspend(struct device *dev) /* If there are paths active then the CODEC will be held with * bias _ON and should not be suspended. */ if (!codec->suspended && codec->driver->suspend) { - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: codec->driver->suspend(codec, PMSG_SUSPEND); @@ -1110,7 +1138,7 @@ static void soc_resume_deferred(struct work_struct *work) * resume. Otherwise the suspend was suppressed. */ if (codec->driver->resume && codec->suspended) { - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: codec->driver->resume(codec); @@ -1346,7 +1374,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(codec); + snd_soc_dapm_free(&codec->dapm); soc_cleanup_codec_debugfs(codec); device_remove_file(&rtd->dev, &dev_attr_codec_reg); @@ -1368,6 +1396,23 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } } +static void soc_set_name_prefix(struct snd_soc_card *card, + struct snd_soc_codec *codec) +{ + int i; + + if (card->prefix_map == NULL) + return; + + for (i = 0; i < card->num_prefixes; i++) { + struct snd_soc_prefix_map *map = &card->prefix_map[i]; + if (map->dev_name && !strcmp(codec->name, map->dev_name)) { + codec->name_prefix = map->name_prefix; + break; + } + } +} + static void rtd_release(struct device *dev) {} static int soc_probe_dai_link(struct snd_soc_card *card, int num) @@ -1377,6 +1422,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; + const char *temp; int ret; dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); @@ -1410,6 +1456,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* probe the CODEC */ if (!codec->probed) { + codec->dapm.card = card; + soc_set_name_prefix(card, codec); if (codec->driver->probe) { ret = codec->driver->probe(codec); if (ret < 0) { @@ -1462,16 +1510,20 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* now that all clients have probed, initialise the DAI link */ if (dai_link->init) { + /* machine controls, routes and widgets are not prefixed */ + temp = rtd->codec->name_prefix; + rtd->codec->name_prefix = NULL; ret = dai_link->init(rtd); if (ret < 0) { printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name); return ret; } + rtd->codec->name_prefix = temp; } /* Make sure all DAPM widgets are instantiated */ - snd_soc_dapm_new_widgets(codec); - snd_soc_dapm_sync(codec); + snd_soc_dapm_new_widgets(&codec->dapm); + snd_soc_dapm_sync(&codec->dapm); /* register the rtd device */ rtd->dev.release = rtd_release; @@ -1667,6 +1719,8 @@ static int soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&card->codec_dev_list); INIT_LIST_HEAD(&card->platform_dev_list); + soc_init_card_debugfs(card); + ret = snd_soc_register_card(card); if (ret != 0) { dev_err(&pdev->dev, "Failed to register card\n"); @@ -1694,6 +1748,8 @@ static int soc_remove(struct platform_device *pdev) for (i = 0; i < card->num_rtd; i++) soc_remove_dai_link(card, i); + soc_cleanup_card_debugfs(card); + /* remove the card */ if (card->remove) card->remove(pdev); @@ -1877,6 +1933,27 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); +unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) +{ + unsigned int ret; + + ret = codec->driver->read(codec, reg); + dev_dbg(codec->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_reg_read(codec, reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_read); + +unsigned int snd_soc_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val) +{ + dev_dbg(codec->dev, "write %x = %x\n", reg, val); + trace_snd_soc_reg_write(codec, reg, val); + return codec->driver->write(codec, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_write); + /** * snd_soc_update_bits - update codec register bits * @codec: audio codec @@ -2017,14 +2094,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls) { struct snd_card *card = codec->card->snd_card; + char prefixed_name[44], *name; int err, i; for (i = 0; i < num_controls; i++) { const struct snd_kcontrol_new *control = &controls[i]; - err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); + if (codec->name_prefix) { + snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", + codec->name_prefix, control->name); + name = prefixed_name; + } else { + name = control->name; + } + err = snd_ctl_add(card, snd_soc_cnew(control, codec, name)); if (err < 0) { dev_err(codec->dev, "%s: Failed to add %s: %d\n", - codec->name, control->name, err); + codec->name, name, err); return err; } } @@ -3219,30 +3304,25 @@ int snd_soc_register_codec(struct device *dev, return -ENOMEM; } - /* allocate CODEC register cache */ - if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { - - if (codec_drv->reg_cache_default) - codec->reg_cache = kmemdup(codec_drv->reg_cache_default, - codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL); - else - codec->reg_cache = kzalloc(codec_drv->reg_cache_size * - codec_drv->reg_word_size, GFP_KERNEL); - - if (codec->reg_cache == NULL) { - kfree(codec->name); - kfree(codec); - return -ENOMEM; - } - } - + INIT_LIST_HEAD(&codec->dapm.widgets); + INIT_LIST_HEAD(&codec->dapm.paths); + codec->dapm.bias_level = SND_SOC_BIAS_OFF; + codec->dapm.dev = dev; + codec->dapm.codec = codec; codec->dev = dev; codec->driver = codec_drv; - codec->bias_level = SND_SOC_BIAS_OFF; codec->num_dai = num_dai; mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); + + /* allocate CODEC register cache */ + if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { + ret = snd_soc_cache_init(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache compression type: %d\n", + ret); + goto error_cache; + } + } for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); @@ -3253,7 +3333,7 @@ int snd_soc_register_codec(struct device *dev, if (num_dai) { ret = snd_soc_register_dais(dev, dai_drv, num_dai); if (ret < 0) - goto error; + goto error_dais; } mutex_lock(&client_mutex); @@ -3264,9 +3344,9 @@ int snd_soc_register_codec(struct device *dev, pr_debug("Registered codec '%s'\n", codec->name); return 0; -error: - if (codec->reg_cache) - kfree(codec->reg_cache); +error_dais: + snd_soc_cache_exit(codec); +error_cache: kfree(codec->name); kfree(codec); return ret; @@ -3300,8 +3380,7 @@ found: pr_debug("Unregistered codec '%s'\n", codec->name); - if (codec->reg_cache) - kfree(codec->reg_cache); + snd_soc_cache_exit(codec); kfree(codec->name); kfree(codec); } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 75ed649..6a29d59 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -42,9 +42,11 @@ #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> -#include <sound/soc-dapm.h> +#include <sound/soc.h> #include <sound/initval.h> +#include <trace/events/asoc.h> + /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { [snd_soc_dapm_pre] = 0, @@ -90,17 +92,24 @@ static void pop_wait(u32 pop_time) schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); } -static void pop_dbg(u32 pop_time, const char *fmt, ...) +static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) { va_list args; + char *buf; - va_start(args, fmt); + if (!pop_time) + return; - if (pop_time) { - vprintk(fmt, args); - } + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf == NULL) + return; + va_start(args, fmt); + vsnprintf(buf, PAGE_SIZE, fmt, args); + dev_info(dev, buf); va_end(args); + + kfree(buf); } /* create a new dapm widget */ @@ -120,37 +129,42 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( * Returns 0 for success else error. */ static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, - struct snd_soc_codec *codec, enum snd_soc_bias_level level) + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) { int ret = 0; switch (level) { case SND_SOC_BIAS_ON: - dev_dbg(codec->dev, "Setting full bias\n"); + dev_dbg(dapm->dev, "Setting full bias\n"); break; case SND_SOC_BIAS_PREPARE: - dev_dbg(codec->dev, "Setting bias prepare\n"); + dev_dbg(dapm->dev, "Setting bias prepare\n"); break; case SND_SOC_BIAS_STANDBY: - dev_dbg(codec->dev, "Setting standby bias\n"); + dev_dbg(dapm->dev, "Setting standby bias\n"); break; case SND_SOC_BIAS_OFF: - dev_dbg(codec->dev, "Setting bias off\n"); + dev_dbg(dapm->dev, "Setting bias off\n"); break; default: - dev_err(codec->dev, "Setting invalid bias %d\n", level); + dev_err(dapm->dev, "Setting invalid bias %d\n", level); return -EINVAL; } + trace_snd_soc_bias_level_start(card, level); + if (card && card->set_bias_level) ret = card->set_bias_level(card, level); if (ret == 0) { - if (codec->driver->set_bias_level) - ret = codec->driver->set_bias_level(codec, level); + if (dapm->codec && dapm->codec->driver->set_bias_level) + ret = dapm->codec->driver->set_bias_level(dapm->codec, level); else - codec->bias_level = level; + dapm->bias_level = level; } + trace_snd_soc_bias_level_done(card, level); + return ret; } @@ -241,7 +255,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, } /* connect mux widget to its interconnecting audio paths */ -static int dapm_connect_mux(struct snd_soc_codec *codec, +static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name, const struct snd_kcontrol_new *kcontrol) @@ -251,7 +265,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec, for (i = 0; i < e->max; i++) { if (!(strcmp(control_name, e->texts[i]))) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = (char*)e->texts[i]; @@ -264,7 +278,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec, } /* connect mixer widget to its interconnecting audio paths */ -static int dapm_connect_mixer(struct snd_soc_codec *codec, +static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name) { @@ -273,7 +287,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec, /* search for mixer kcontrol */ for (i = 0; i < dest->num_kcontrols; i++) { if (!strcmp(control_name, dest->kcontrols[i].name)) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = dest->kcontrols[i].name; @@ -290,6 +304,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) int change, power; unsigned int old, new; struct snd_soc_codec *codec = widget->codec; + struct snd_soc_dapm_context *dapm = widget->dapm; + struct snd_soc_card *card = dapm->card; /* check for valid widgets */ if (widget->reg < 0 || widget->id == snd_soc_dapm_input || @@ -309,24 +325,26 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) change = old != new; if (change) { - pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", + pop_dbg(dapm->dev, card->pop_time, + "pop test %s : %s in %d ms\n", widget->name, widget->power ? "on" : "off", - codec->pop_time); - pop_wait(codec->pop_time); + card->pop_time); + pop_wait(card->pop_time); snd_soc_write(codec, widget->reg, new); } - pr_debug("reg %x old %x new %x change %d\n", widget->reg, - old, new, change); + dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, + old, new, change); return change; } /* create new dapm mixer control */ -static int dapm_new_mixer(struct snd_soc_codec *codec, +static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { int i, ret = 0; size_t name_len; struct snd_soc_dapm_path *path; + struct snd_card *card = dapm->codec->card->snd_card; /* add kcontrol */ for (i = 0; i < w->num_kcontrols; i++) { @@ -368,11 +386,11 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, path->long_name); - ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); + ret = snd_ctl_add(card, path->kcontrol); if (ret < 0) { - printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", - path->long_name, - ret); + dev_err(dapm->dev, + "asoc: failed to add dapm kcontrol %s: %d\n", + path->long_name, ret); kfree(path->long_name); path->long_name = NULL; return ret; @@ -383,20 +401,22 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, } /* create new dapm mux control */ -static int dapm_new_mux(struct snd_soc_codec *codec, +static int dapm_new_mux(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { struct snd_soc_dapm_path *path = NULL; struct snd_kcontrol *kcontrol; + struct snd_card *card = dapm->codec->card->snd_card; int ret = 0; if (!w->num_kcontrols) { - printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); + dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name); return -EINVAL; } kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); - ret = snd_ctl_add(codec->card->snd_card, kcontrol); + ret = snd_ctl_add(card, kcontrol); + if (ret < 0) goto err; @@ -406,26 +426,27 @@ static int dapm_new_mux(struct snd_soc_codec *codec, return ret; err: - printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); + dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name); return ret; } /* create new dapm volume control */ -static int dapm_new_pga(struct snd_soc_codec *codec, +static int dapm_new_pga(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { if (w->num_kcontrols) - pr_err("asoc: PGA controls not supported: '%s'\n", w->name); + dev_err(w->dapm->dev, + "asoc: PGA controls not supported: '%s'\n", w->name); return 0; } /* reset 'walked' bit for each dapm path */ -static inline void dapm_clear_walk(struct snd_soc_codec *codec) +static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &codec->dapm_paths, list) + list_for_each_entry(p, &dapm->paths, list) p->walked = 0; } @@ -435,13 +456,14 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec) */ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) { - int level = snd_power_get_state(widget->codec->card->snd_card); + int level = snd_power_get_state(widget->dapm->codec->card->snd_card); switch (level) { case SNDRV_CTL_POWER_D3hot: case SNDRV_CTL_POWER_D3cold: if (widget->ignore_suspend) - pr_debug("%s ignoring suspend\n", widget->name); + dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", + widget->name); return widget->ignore_suspend; default: return 1; @@ -572,7 +594,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) /* call any power change event handlers */ if (w->event) - pr_debug("power %s event for %s flags %x\n", + dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n", w->power ? "on" : "off", w->name, w->event_flags); @@ -621,9 +643,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) int in, out; in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return out != 0 && in != 0; } @@ -634,7 +656,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) if (w->active) { in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return in != 0; } else { return dapm_generic_check_power(w); @@ -648,7 +670,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) if (w->active) { out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return out != 0; } else { return dapm_generic_check_power(w); @@ -674,7 +696,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) } } - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return power; } @@ -687,8 +709,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a, return sort[a->id] - sort[b->id]; if (a->reg != b->reg) return a->reg - b->reg; - if (a->codec != b->codec) - return (unsigned long)a->codec - (unsigned long)b->codec; + if (a->dapm != b->dapm) + return (unsigned long)a->dapm - (unsigned long)b->dapm; return 0; } @@ -709,12 +731,57 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, list_add_tail(&new_widget->power_list, list); } +static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, + struct snd_soc_dapm_widget *w, int event) +{ + struct snd_soc_card *card = dapm->card; + const char *ev_name; + int power, ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ev_name = "PRE_PMU"; + power = 1; + break; + case SND_SOC_DAPM_POST_PMU: + ev_name = "POST_PMU"; + power = 1; + break; + case SND_SOC_DAPM_PRE_PMD: + ev_name = "PRE_PMD"; + power = 0; + break; + case SND_SOC_DAPM_POST_PMD: + ev_name = "POST_PMD"; + power = 0; + break; + default: + BUG(); + return; + } + + if (w->power != power) + return; + + if (w->event && (w->event_flags & event)) { + pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n", + w->name, ev_name); + trace_snd_soc_dapm_widget_event_start(w, event); + ret = w->event(w, NULL, event); + trace_snd_soc_dapm_widget_event_done(w, event); + if (ret < 0) + pr_err("%s: %s event failed: %d\n", + ev_name, w->name, ret); + } +} + /* Apply the coalesced changes from a DAPM sequence */ -static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, +static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, struct list_head *pending) { + struct snd_soc_card *card = dapm->card; struct snd_soc_dapm_widget *w; - int reg, power, ret; + int reg, power; unsigned int value = 0; unsigned int mask = 0; unsigned int cur_mask; @@ -735,64 +802,26 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, if (power) value |= cur_mask; - pop_dbg(codec->pop_time, + pop_dbg(dapm->dev, card->pop_time, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); - /* power up pre event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n", - w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - pr_err("%s: pre event failed: %d\n", - w->name, ret); - } - - /* power down pre event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n", - w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - pr_err("%s: pre event failed: %d\n", - w->name, ret); - } + /* Check for events */ + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU); + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD); } if (reg >= 0) { - pop_dbg(codec->pop_time, + pop_dbg(dapm->dev, card->pop_time, "pop test : Applying 0x%x/0x%x to %x in %dms\n", - value, mask, reg, codec->pop_time); - pop_wait(codec->pop_time); - snd_soc_update_bits(codec, reg, mask, value); + value, mask, reg, card->pop_time); + pop_wait(card->pop_time); + snd_soc_update_bits(dapm->codec, reg, mask, value); } list_for_each_entry(w, pending, power_list) { - /* power up post event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n", - w->name); - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - pr_err("%s: post event failed: %d\n", - w->name, ret); - } - - /* power down post event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n", - w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - pr_err("%s: post event failed: %d\n", - w->name, ret); - } + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU); + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD); } } @@ -804,8 +833,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, * Currently anything that requires more than a single write is not * handled. */ -static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, - int event, int sort[]) +static void dapm_seq_run(struct snd_soc_dapm_context *dapm, + struct list_head *list, int event, int sort[]) { struct snd_soc_dapm_widget *w, *n; LIST_HEAD(pending); @@ -819,7 +848,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, /* Do we need to apply any queued changes? */ if (sort[w->id] != cur_sort || w->reg != cur_reg) { if (!list_empty(&pending)) - dapm_seq_run_coalesced(codec, &pending); + dapm_seq_run_coalesced(dapm, &pending); INIT_LIST_HEAD(&pending); cur_sort = -1; @@ -872,12 +901,12 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, } if (ret < 0) - pr_err("Failed to apply widget power: %d\n", - ret); + dev_err(w->dapm->dev, + "Failed to apply widget power: %d\n", ret); } if (!list_empty(&pending)) - dapm_seq_run_coalesced(codec, &pending); + dapm_seq_run_coalesced(dapm, &pending); } /* @@ -889,9 +918,9 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, * o Input pin to Output pin (bypass, sidetone) * o DAC to ADC (loopback). */ -static int dapm_power_widgets(struct snd_soc_codec *codec, int event) +static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) { - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = dapm->codec->card; struct snd_soc_dapm_widget *w; LIST_HEAD(up_list); LIST_HEAD(down_list); @@ -899,10 +928,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) int power; int sys_power = 0; + trace_snd_soc_dapm_start(card); + /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { switch (w->id) { case snd_soc_dapm_pre: dapm_seq_insert(w, &down_list, dapm_down_seq); @@ -925,6 +956,8 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) if (w->power == power) continue; + trace_snd_soc_dapm_widget_power(w, power); + if (power) dapm_seq_insert(w, &up_list, dapm_up_seq); else @@ -938,7 +971,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) /* If there are no DAPM widgets then try to figure out power from the * event type. */ - if (list_empty(&codec->dapm_widgets)) { + if (list_empty(&dapm->widgets)) { switch (event) { case SND_SOC_DAPM_STREAM_START: case SND_SOC_DAPM_STREAM_RESUME: @@ -948,7 +981,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) sys_power = 0; break; case SND_SOC_DAPM_STREAM_NOP: - switch (codec->bias_level) { + switch (dapm->bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: sys_power = 0; @@ -963,52 +996,59 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) } } - if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { - ret = snd_soc_dapm_set_bias_level(card, codec, + if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - pr_err("Failed to turn on bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to turn on bias: %d\n", ret); } /* If we're changing to all on or all off then prepare */ - if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || - (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); + if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) || + (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE); if (ret != 0) - pr_err("Failed to prepare bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to prepare bias: %d\n", ret); } /* Power down widgets first; try to avoid amplifying pops. */ - dapm_seq_run(codec, &down_list, event, dapm_down_seq); + dapm_seq_run(dapm, &down_list, event, dapm_down_seq); /* Now power up. */ - dapm_seq_run(codec, &up_list, event, dapm_up_seq); + dapm_seq_run(dapm, &up_list, event, dapm_up_seq); /* If we just powered the last thing off drop to standby bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); + if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - pr_err("Failed to apply standby bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to apply standby bias: %d\n", ret); } /* If we're in standby and can support bias off then do that */ - if (codec->bias_level == SND_SOC_BIAS_STANDBY && - codec->idle_bias_off) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); + if (dapm->bias_level == SND_SOC_BIAS_STANDBY && + dapm->idle_bias_off) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); if (ret != 0) - pr_err("Failed to turn off bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to turn off bias: %d\n", ret); } /* If we just powered up then move to active bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); + if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON); if (ret != 0) - pr_err("Failed to apply active bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to apply active bias: %d\n", ret); } - pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", - codec->pop_time); - pop_wait(codec->pop_time); + pop_dbg(dapm->dev, card->pop_time, + "DAPM sequencing finished, waiting %dms\n", card->pop_time); + pop_wait(card->pop_time); + + trace_snd_soc_dapm_done(card); return 0; } @@ -1035,9 +1075,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, return -ENOMEM; in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", w->name, w->power ? "On" : "Off", in, out); @@ -1087,29 +1127,29 @@ static const struct file_operations dapm_widget_power_fops = { .llseek = default_llseek, }; -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; struct dentry *d; - if (!codec->debugfs_dapm) + if (!dapm->debugfs_dapm) return; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!w->name) continue; d = debugfs_create_file(w->name, 0444, - codec->debugfs_dapm, w, + dapm->debugfs_dapm, w, &dapm_widget_power_fops); if (!d) - printk(KERN_WARNING - "ASoC: Failed to create %s debugfs file\n", - w->name); + dev_warn(w->dapm->dev, + "ASoC: Failed to create %s debugfs file\n", + w->name); } } #else -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) { } #endif @@ -1130,7 +1170,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, return 0; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1146,7 +1186,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, } if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } @@ -1164,7 +1204,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, return -ENODEV; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1175,7 +1215,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, } if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } @@ -1191,7 +1231,7 @@ static ssize_t dapm_widget_show(struct device *dev, int count = 0; char *state = "not set"; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &codec->dapm.widgets, list) { /* only display widgets that burnm power */ switch (w->id) { @@ -1215,7 +1255,7 @@ static ssize_t dapm_widget_show(struct device *dev, } } - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_ON: state = "On"; break; @@ -1247,31 +1287,33 @@ static void snd_soc_dapm_sys_remove(struct device *dev) } /* free all dapm widgets and resources */ -static void dapm_free_widgets(struct snd_soc_codec *codec) +static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w, *next_w; struct snd_soc_dapm_path *p, *next_p; - list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { + list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { list_del(&w->list); + kfree(w->name); kfree(w); } - list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { + list_for_each_entry_safe(p, next_p, &dapm->paths, list) { list_del(&p->list); kfree(p->long_name); kfree(p); } } -static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, +static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, const char *pin, int status) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", codec->name, pin); + dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", + pin, status); w->connected = status; /* Allow disabling of forced pins */ if (status == 0) @@ -1280,37 +1322,51 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, } } - pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } /** * snd_soc_dapm_sync - scan and power dapm paths - * @codec: audio codec + * @dapm: DAPM context * * Walks all dapm audio paths and powers widgets according to their * stream or path usage. * * Returns 0 for success. */ -int snd_soc_dapm_sync(struct snd_soc_codec *codec) +int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) { - return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); -static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, +static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route) { struct snd_soc_dapm_path *path; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; - const char *sink = route->sink; + const char *sink; const char *control = route->control; - const char *source = route->source; + const char *source; + char prefixed_sink[80]; + char prefixed_source[80]; int ret = 0; + if (dapm->codec->name_prefix) { + snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", + dapm->codec->name_prefix, route->sink); + sink = prefixed_sink; + snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", + dapm->codec->name_prefix, route->source); + source = prefixed_source; + } else { + sink = route->sink; + source = route->source; + } + /* find src and dest widgets */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!wsink && !(strcmp(w->name, sink))) { wsink = w; @@ -1353,7 +1409,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, /* connect static paths */ if (control == NULL) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; @@ -1374,14 +1430,14 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; return 0; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: - ret = dapm_connect_mux(codec, wsource, wsink, path, control, + ret = dapm_connect_mux(dapm, wsource, wsink, path, control, &wsink->kcontrols[0]); if (ret != 0) goto err; @@ -1389,7 +1445,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_switch: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: - ret = dapm_connect_mixer(codec, wsource, wsink, path, control); + ret = dapm_connect_mixer(dapm, wsource, wsink, path, control); if (ret != 0) goto err; break; @@ -1397,7 +1453,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_mic: case snd_soc_dapm_line: case snd_soc_dapm_spk: - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 0; @@ -1406,15 +1462,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, return 0; err: - printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, - control, sink); + dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", + source, control, sink); kfree(path); return ret; } /** * snd_soc_dapm_add_routes - Add routes between DAPM widgets - * @codec: codec + * @dapm: DAPM context * @route: audio routes * @num: number of routes * @@ -1425,17 +1481,16 @@ err: * Returns 0 for success else error. On error all resources can be freed * with a call to snd_soc_card_free(). */ -int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, +int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num) { int i, ret; for (i = 0; i < num; i++) { - ret = snd_soc_dapm_add_route(codec, route); + ret = snd_soc_dapm_add_route(dapm, route); if (ret < 0) { - printk(KERN_ERR "Failed to add route %s->%s\n", - route->source, - route->sink); + dev_err(dapm->dev, "Failed to add route %s->%s\n", + route->source, route->sink); return ret; } route++; @@ -1447,17 +1502,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); /** * snd_soc_dapm_new_widgets - add new dapm widgets - * @codec: audio codec + * @dapm: DAPM context * * Checks the codec for any new dapm widgets and creates them if found. * * Returns 0 for success. */ -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) +int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) + list_for_each_entry(w, &dapm->widgets, list) { if (w->new) continue; @@ -1467,12 +1522,12 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: w->power_check = dapm_generic_check_power; - dapm_new_mixer(codec, w); + dapm_new_mixer(dapm, w); break; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: w->power_check = dapm_generic_check_power; - dapm_new_mux(codec, w); + dapm_new_mux(dapm, w); break; case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: @@ -1484,7 +1539,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) break; case snd_soc_dapm_pga: w->power_check = dapm_generic_check_power; - dapm_new_pga(codec, w); + dapm_new_pga(dapm, w); break; case snd_soc_dapm_input: case snd_soc_dapm_output: @@ -1505,7 +1560,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) w->new = 1; } - dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); @@ -1889,7 +1944,7 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, mutex_lock(&codec->mutex); ucontrol->value.integer.value[0] = - snd_soc_dapm_get_pin_status(codec, pin); + snd_soc_dapm_get_pin_status(&codec->dapm, pin); mutex_unlock(&codec->mutex); @@ -1912,11 +1967,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, mutex_lock(&codec->mutex); if (ucontrol->value.integer.value[0]) - snd_soc_dapm_enable_pin(codec, pin); + snd_soc_dapm_enable_pin(&codec->dapm, pin); else - snd_soc_dapm_disable_pin(codec, pin); + snd_soc_dapm_disable_pin(&codec->dapm, pin); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); mutex_unlock(&codec->mutex); @@ -1926,26 +1981,42 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); /** * snd_soc_dapm_new_control - create new dapm control - * @codec: audio codec + * @dapm: DAPM context * @widget: widget template * * Creates a new dapm control based upon the template. * * Returns 0 for success else error. */ -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, +int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) { struct snd_soc_dapm_widget *w; + size_t name_len; if ((w = dapm_cnew_widget(widget)) == NULL) return -ENOMEM; - w->codec = codec; + name_len = strlen(widget->name) + 1; + if (dapm->codec->name_prefix) + name_len += 1 + strlen(dapm->codec->name_prefix); + w->name = kmalloc(name_len, GFP_KERNEL); + if (w->name == NULL) { + kfree(w); + return -ENOMEM; + } + if (dapm->codec->name_prefix) + snprintf(w->name, name_len, "%s %s", + dapm->codec->name_prefix, widget->name); + else + snprintf(w->name, name_len, "%s", widget->name); + + w->dapm = dapm; + w->codec = dapm->codec; INIT_LIST_HEAD(&w->sources); INIT_LIST_HEAD(&w->sinks); INIT_LIST_HEAD(&w->list); - list_add(&w->list, &codec->dapm_widgets); + list_add(&w->list, &dapm->widgets); /* machine layer set ups unconnected pins and insertions */ w->connected = 1; @@ -1955,7 +2026,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); /** * snd_soc_dapm_new_controls - create new dapm controls - * @codec: audio codec + * @dapm: DAPM context * @widget: widget array * @num: number of widgets * @@ -1963,18 +2034,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); * * Returns 0 for success else error. */ -int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, +int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget, int num) { int i, ret; for (i = 0; i < num; i++) { - ret = snd_soc_dapm_new_control(codec, widget); + ret = snd_soc_dapm_new_control(dapm, widget); if (ret < 0) { - printk(KERN_ERR - "ASoC: Failed to create DAPM control %s: %d\n", - widget->name, ret); + dev_err(dapm->dev, + "ASoC: Failed to create DAPM control %s: %d\n", + widget->name, ret); return ret; } widget++; @@ -1983,34 +2054,17 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); - -/** - * snd_soc_dapm_stream_event - send a stream event to the dapm core - * @codec: audio codec - * @stream: stream name - * @event: stream event - * - * Sends a stream event to the dapm core. The core then makes any - * necessary widget power changes. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, +static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, const char *stream, int event) { - struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_widget *w; - if (stream == NULL) - return 0; - - mutex_lock(&codec->mutex); - list_for_each_entry(w, &codec->dapm_widgets, list) + list_for_each_entry(w, &dapm->widgets, list) { if (!w->sname) continue; - pr_debug("widget %s\n %s stream %s event %d\n", - w->name, w->sname, stream, event); + dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", + w->name, w->sname, stream, event); if (strstr(w->sname, stream)) { switch(event) { case SND_SOC_DAPM_STREAM_START: @@ -2028,7 +2082,30 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, } } - dapm_power_widgets(codec, event); + dapm_power_widgets(dapm, event); +} + +/** + * snd_soc_dapm_stream_event - send a stream event to the dapm core + * @rtd: PCM runtime data + * @stream: stream name + * @event: stream event + * + * Sends a stream event to the dapm core. The core then makes any + * necessary widget power changes. + * + * Returns 0 for success else error. + */ +int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, + const char *stream, int event) +{ + struct snd_soc_codec *codec = rtd->codec; + + if (stream == NULL) + return 0; + + mutex_lock(&codec->mutex); + soc_dapm_stream_event(&codec->dapm, stream, event); mutex_unlock(&codec->mutex); return 0; } @@ -2036,7 +2113,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); /** * snd_soc_dapm_enable_pin - enable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Enables input/output pin and its parents or children widgets iff there is @@ -2044,15 +2121,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 1); + return snd_soc_dapm_set_pin(dapm, pin, 1); } EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); /** * snd_soc_dapm_force_enable_pin - force a pin to be enabled - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Enables input/output pin regardless of any other state. This is @@ -2062,42 +2139,45 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", codec->name, pin); + dev_dbg(w->dapm->dev, + "dapm: force enable pin %s\n", pin); w->connected = 1; w->force = 1; return 0; } } - pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); /** * snd_soc_dapm_disable_pin - disable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Disables input/output pin and its parents or children widgets. * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, + const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 0); + return snd_soc_dapm_set_pin(dapm, pin, 0); } EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); /** * snd_soc_dapm_nc_pin - permanently disable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Marks the specified pin as being not connected, disabling it along @@ -2109,26 +2189,27 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 0); + return snd_soc_dapm_set_pin(dapm, pin, 0); } EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); /** * snd_soc_dapm_get_pin_status - get audio pin status - * @codec: audio codec + * @dapm: DAPM context * @pin: audio signal pin endpoint (or start point) * * Get audio pin status - connected or disconnected. * * Returns 1 for connected otherwise 0. */ -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) return w->connected; } @@ -2139,7 +2220,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); /** * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint - * @codec: audio codec + * @dapm: DAPM context * @pin: audio signal pin endpoint (or start point) * * Mark the given endpoint or pin as ignoring suspend. When the @@ -2148,18 +2229,19 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); * normal means at suspend time, it will not be turned on if it was not * already enabled. */ -int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { w->ignore_suspend = 1; return 0; } } - pr_err("Unknown DAPM pin: %s\n", pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); @@ -2170,20 +2252,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); * * Free all dapm widgets and resources. */ -void snd_soc_dapm_free(struct snd_soc_codec *codec) +void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) { - snd_soc_dapm_sys_remove(codec->dev); - dapm_free_widgets(codec); + snd_soc_dapm_sys_remove(dapm->dev); + dapm_free_widgets(dapm); } EXPORT_SYMBOL_GPL(snd_soc_dapm_free); -static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) +static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; LIST_HEAD(down_list); int powerdown = 0; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (w->power) { dapm_seq_insert(w, &down_list, dapm_down_seq); w->power = 0; @@ -2195,9 +2277,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) * standby. */ if (powerdown) { - snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); - dapm_seq_run(codec, &down_list, 0, dapm_down_seq); - snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); + dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); + snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); } } @@ -2208,10 +2290,10 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { struct snd_soc_codec *codec; - list_for_each_entry(codec, &card->codec_dev_list, list) - soc_dapm_shutdown_codec(codec); - - snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); + list_for_each_entry(codec, &card->codec_dev_list, list) { + soc_dapm_shutdown_codec(&codec->dapm); + snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); + } } /* Module information */ diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 8a0a920..0e9b071 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -13,7 +13,6 @@ #include <sound/jack.h> #include <sound/soc.h> -#include <sound/soc-dapm.h> #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/workqueue.h> @@ -60,6 +59,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new); void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) { struct snd_soc_codec *codec; + struct snd_soc_dapm_context *dapm; struct snd_soc_jack_pin *pin; int enable; int oldstatus; @@ -68,6 +68,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) return; codec = jack->codec; + dapm = &codec->dapm; mutex_lock(&codec->mutex); @@ -88,15 +89,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) enable = !enable; if (enable) - snd_soc_dapm_enable_pin(codec, pin->pin); + snd_soc_dapm_enable_pin(dapm, pin->pin); else - snd_soc_dapm_disable_pin(codec, pin->pin); + snd_soc_dapm_disable_pin(dapm, pin->pin); } /* Report before the DAPM sync to help users updating micbias status */ blocking_notifier_call_chain(&jack->notifier, status, NULL); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_jack_report(jack->jack, status); @@ -207,6 +208,10 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) static irqreturn_t gpio_handler(int irq, void *data) { struct snd_soc_jack_gpio *gpio = data; + struct device *dev = gpio->jack->codec->card->dev; + + if (device_may_wakeup(dev)) + pm_wakeup_event(dev, gpio->debounce_time + 50); schedule_delayed_work(&gpio->work, msecs_to_jiffies(gpio->debounce_time)); @@ -263,11 +268,12 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, INIT_DELAYED_WORK(&gpios[i].work, gpio_work); gpios[i].jack = jack; - ret = request_irq(gpio_to_irq(gpios[i].gpio), - gpio_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - jack->codec->dev->driver->name, - &gpios[i]); + ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio), + gpio_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + jack->codec->dev->driver->name, + &gpios[i]); if (ret) goto err; |