diff --git a/Documentation/devicetree/bindings/sound/everest,es7134.txt b/Documentation/devicetree/bindings/sound/everest,es7134.txt new file mode 100644 index 000000000000..5495a3cb8b7b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/everest,es7134.txt @@ -0,0 +1,10 @@ +ES7134 i2s DA converter + +Required properties: +- compatible : "everest,es7134" or "everest,es7144" + +Example: + +i2s_codec: external-codec { + compatible = "everest,es7134"; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index e3e6f39d14e8..70decab5e985 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -74,6 +74,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DMIC select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C + select SND_SOC_ES7134 select SND_SOC_GTM601 select SND_SOC_HDAC_HDMI select SND_SOC_ICS43432 @@ -537,6 +538,9 @@ config SND_SOC_HDMI_CODEC select SND_PCM_IEC958 select HDMI +config SND_SOC_ES7134 + tristate "Everest Semi ES7134 CODEC" + config SND_SOC_ES8328 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 2c596d84fa3e..bbef31ec1f80 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -64,6 +64,7 @@ snd-soc-da7219-objs := da7219.o da7219-aad.o snd-soc-da732x-objs := da732x.o snd-soc-da9055-objs := da9055.o snd-soc-dmic-objs := dmic.o +snd-soc-es7134-objs := es7134.o snd-soc-es8328-objs := es8328.o snd-soc-es8328-i2c-objs := es8328-i2c.o snd-soc-es8328-spi-objs := es8328-spi.o @@ -296,6 +297,7 @@ obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o +obj-$(CONFIG_SND_SOC_ES7134) += snd-soc-es7134.o obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o diff --git a/sound/soc/codecs/es7134.c b/sound/soc/codecs/es7134.c new file mode 100644 index 000000000000..25ede825d349 --- /dev/null +++ b/sound/soc/codecs/es7134.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017 BayLibre, SAS. + * Author: Jerome Brunet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + */ + +#include +#include + +/* + * The everest 7134 is a very simple DA converter with no register + */ + +static int es7134_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK | + SND_SOC_DAIFMT_MASTER_MASK); + + if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS)) { + dev_err(codec_dai->dev, "Invalid DAI format\n"); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops es7134_dai_ops = { + .set_fmt = es7134_set_fmt, +}; + +static struct snd_soc_dai_driver es7134_dai = { + .name = "es7134-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = (SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S18_3LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_S24_LE), + }, + .ops = &es7134_dai_ops, +}; + +static const struct snd_soc_dapm_widget es7134_dapm_widgets[] = { + SND_SOC_DAPM_OUTPUT("AOUTL"), + SND_SOC_DAPM_OUTPUT("AOUTR"), + SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route es7134_dapm_routes[] = { + { "AOUTL", NULL, "DAC" }, + { "AOUTR", NULL, "DAC" }, +}; + +static struct snd_soc_codec_driver es7134_codec_driver = { + .component_driver = { + .dapm_widgets = es7134_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(es7134_dapm_widgets), + .dapm_routes = es7134_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(es7134_dapm_routes), + }, +}; + +static int es7134_probe(struct platform_device *pdev) +{ + return snd_soc_register_codec(&pdev->dev, + &es7134_codec_driver, + &es7134_dai, 1); +} + +static int es7134_remove(struct platform_device *pdev) +{ + snd_soc_unregister_codec(&pdev->dev); + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id es7134_ids[] = { + { .compatible = "everest,es7134", }, + { .compatible = "everest,es7144", }, + { } +}; +MODULE_DEVICE_TABLE(of, es7134_ids); +#endif + +static struct platform_driver es7134_driver = { + .driver = { + .name = "es7134", + .of_match_table = of_match_ptr(es7134_ids), + }, + .probe = es7134_probe, + .remove = es7134_remove, +}; + +module_platform_driver(es7134_driver); + +MODULE_DESCRIPTION("ASoC ES7134 audio codec driver"); +MODULE_AUTHOR("Jerome Brunet "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c index 3f84fbd071e2..ed7cc42d1ee2 100644 --- a/sound/soc/codecs/es8328.c +++ b/sound/soc/codecs/es8328.c @@ -69,14 +69,10 @@ static const char * const supply_names[ES8328_SUPPLY_NUM] = { "HPVDD", }; -#define ES8328_RATES (SNDRV_PCM_RATE_96000 | \ - SNDRV_PCM_RATE_48000 | \ - SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_22050 | \ - SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_11025 | \ - SNDRV_PCM_RATE_8000) +#define ES8328_RATES (SNDRV_PCM_RATE_192000 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_8000_48000) #define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S18_3LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \ @@ -91,6 +87,7 @@ struct es8328_priv { int mclkdiv2; const struct snd_pcm_hw_constraint_list *sysclk_constraints; const int *mclk_ratios; + bool master; struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; }; @@ -469,7 +466,7 @@ static int es8328_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); - if (es8328->sysclk_constraints) + if (es8328->master && es8328->sysclk_constraints) snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, es8328->sysclk_constraints); @@ -488,27 +485,34 @@ static int es8328_hw_params(struct snd_pcm_substream *substream, int wl; int ratio; - if (!es8328->sysclk_constraints) { - dev_err(codec->dev, "No MCLK configured\n"); - return -EINVAL; - } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = ES8328_DACCONTROL2; else reg = ES8328_ADCCONTROL5; - for (i = 0; i < es8328->sysclk_constraints->count; i++) - if (es8328->sysclk_constraints->list[i] == params_rate(params)) - break; + if (es8328->master) { + if (!es8328->sysclk_constraints) { + dev_err(codec->dev, "No MCLK configured\n"); + return -EINVAL; + } - if (i == es8328->sysclk_constraints->count) { - dev_err(codec->dev, "LRCLK %d unsupported with current clock\n", - params_rate(params)); - return -EINVAL; + for (i = 0; i < es8328->sysclk_constraints->count; i++) + if (es8328->sysclk_constraints->list[i] == + params_rate(params)) + break; + + if (i == es8328->sysclk_constraints->count) { + dev_err(codec->dev, + "LRCLK %d unsupported with current clock\n", + params_rate(params)); + return -EINVAL; + } + ratio = es8328->mclk_ratios[i]; + } else { + ratio = 0; + es8328->mclkdiv2 = 0; } - ratio = es8328->mclk_ratios[i]; snd_soc_update_bits(codec, ES8328_MASTERMODE, ES8328_MASTERMODE_MCLKDIV2, es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0); @@ -586,6 +590,7 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); u8 dac_mode = 0; u8 adc_mode = 0; @@ -595,11 +600,13 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, snd_soc_update_bits(codec, ES8328_MASTERMODE, ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC); + es8328->master = true; break; case SND_SOC_DAIFMT_CBS_CFS: /* Slave serial port mode */ snd_soc_update_bits(codec, ES8328_MASTERMODE, ES8328_MASTERMODE_MSC, 0); + es8328->master = false; break; default: return -EINVAL; diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 883087f2b092..84ef6385736c 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c @@ -64,7 +64,7 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops eukrea_tlv320_snd_ops = { +static const struct snd_soc_ops eukrea_tlv320_snd_ops = { .hw_params = eukrea_tlv320_hw_params, }; diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index dc30d780f874..282d841840b1 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -76,7 +76,7 @@ static int fsl_asrc_dma_prepare_and_submit(struct snd_pcm_substream *substream) pair->dma_chan[!dir], runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), - dir == OUT ? DMA_TO_DEVICE : DMA_FROM_DEVICE, flags); + dir == OUT ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, flags); if (!pair->desc[!dir]) { dev_err(dev, "failed to prepare slave DMA for Front-End\n"); return -ENOMEM; diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 38bfd46f4ad8..809a069d490b 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -19,7 +19,6 @@ #include "fsl_esai.h" #include "imx-pcm.h" -#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000 #define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ SNDRV_PCM_FMTBIT_S16_LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \ @@ -647,14 +646,14 @@ static struct snd_soc_dai_driver fsl_esai_dai = { .stream_name = "CPU-Playback", .channels_min = 1, .channels_max = 12, - .rates = FSL_ESAI_RATES, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = FSL_ESAI_FORMATS, }, .capture = { .stream_name = "CPU-Capture", .channels_min = 1, .channels_max = 8, - .rates = FSL_ESAI_RATES, + .rates = SNDRV_PCM_RATE_8000_192000, .formats = FSL_ESAI_FORMATS, }, .ops = &fsl_esai_dai_ops, diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c index bb0459018b45..9d19b808f634 100644 --- a/sound/soc/fsl/imx-mc13783.c +++ b/sound/soc/fsl/imx-mc13783.c @@ -48,7 +48,7 @@ static int imx_mc13783_hifi_hw_params(struct snd_pcm_substream *substream, return snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 2, 16); } -static struct snd_soc_ops imx_mc13783_hifi_ops = { +static const struct snd_soc_ops imx_mc13783_hifi_ops = { .hw_params = imx_mc13783_hifi_hw_params, }; diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index dac6688540dc..92410f7ca1fa 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -282,7 +282,7 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static int ssi_irq = 0; +static int ssi_irq; static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) { diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index ddf49f30b23f..a639b52c16f6 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -174,7 +174,7 @@ static int mpc8610_hpcd_machine_remove(struct snd_soc_card *card) /** * mpc8610_hpcd_ops: ASoC machine driver operations */ -static struct snd_soc_ops mpc8610_hpcd_ops = { +static const struct snd_soc_ops mpc8610_hpcd_ops = { .startup = mpc8610_hpcd_startup, }; diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c index 198eeb3f3f7a..d7ec3d20065c 100644 --- a/sound/soc/fsl/mx27vis-aic32x4.c +++ b/sound/soc/fsl/mx27vis-aic32x4.c @@ -73,7 +73,7 @@ static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { +static const struct snd_soc_ops mx27vis_aic32x4_snd_ops = { .hw_params = mx27vis_aic32x4_hw_params, }; diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index a1f780ecadf5..41c623c55c16 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -184,7 +184,7 @@ static int p1022_ds_machine_remove(struct snd_soc_card *card) /** * p1022_ds_ops: ASoC machine driver operations */ -static struct snd_soc_ops p1022_ds_ops = { +static const struct snd_soc_ops p1022_ds_ops = { .startup = p1022_ds_startup, }; diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c index d4d88a8cb9c0..4afbdd610bfa 100644 --- a/sound/soc/fsl/p1022_rdk.c +++ b/sound/soc/fsl/p1022_rdk.c @@ -188,7 +188,7 @@ static int p1022_rdk_machine_remove(struct snd_soc_card *card) /** * p1022_rdk_ops: ASoC machine driver operations */ -static struct snd_soc_ops p1022_rdk_ops = { +static const struct snd_soc_ops p1022_rdk_ops = { .startup = p1022_rdk_startup, }; diff --git a/sound/soc/fsl/phycore-ac97.c b/sound/soc/fsl/phycore-ac97.c index ae403c29688f..66fb6c4614d2 100644 --- a/sound/soc/fsl/phycore-ac97.c +++ b/sound/soc/fsl/phycore-ac97.c @@ -23,7 +23,7 @@ static struct snd_soc_card imx_phycore; -static struct snd_soc_ops imx_phycore_hifi_ops = { +static const struct snd_soc_ops imx_phycore_hifi_ops = { }; static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { diff --git a/sound/soc/fsl/wm1133-ev1.c b/sound/soc/fsl/wm1133-ev1.c index b454972dce35..cdaf16367b47 100644 --- a/sound/soc/fsl/wm1133-ev1.c +++ b/sound/soc/fsl/wm1133-ev1.c @@ -139,7 +139,7 @@ static int wm1133_ev1_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops wm1133_ev1_ops = { +static const struct snd_soc_ops wm1133_ev1_ops = { .hw_params = wm1133_ev1_hw_params, };