Message ID | c716a6624d4227908ee879cbbc9de6d9bca1a0c0.1414495605.git.mengdong.lin@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Oct 28, 2014 at 07:30:32PM +0800, mengdong.lin@intel.com wrote: > +config SND_SOC_INTEL_CHT_BSW_RT5672_MACH > + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" > + depends on X86_INTEL_LPSS > + select SND_SOC_RT5670 > + select SND_SST_MFLD_PLATFORM > + select SND_SOC_INTEL_SST > + select SND_SST_IPC > + select SND_SST_MACHINE > + default n n is the default anyway. > +obj-$(CONFIG_SND_SST_MACHINE) += board/ It's a bit weird to have the Kconfig in the root Intel directory if the boards are getting moved into a subdirectory - why not just source a Kconfig in the board directory? > +static int cht_aif1_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; > + int ret; > + > + if (strncmp(codec_dai->name, "rt5670-aif1", 11)) > + return 0; 11 is a magic number! Why not use strlen() here (and why do we do nothing in the AIF1 hw_params() if we're working with AIF1)? > + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK, > + CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); > + if (ret < 0) { > + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); > + return ret; > + } > + > + ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1, > + params_rate(params) * 512, > + SND_SOC_CLOCK_IN); > + if (ret < 0) { > + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); > + return ret; > + } Nothing ever stops the PLL - a set_bias_level() callback with a handler for _OFF. Otherwise we're wasting power. > + snd_soc_card_cht.dev = &pdev->dev; > + ret_val = snd_soc_register_card(&snd_soc_card_cht); > + if (ret_val) { devm_snd_soc_register_card() and the removal function can go entirely.
> -----Original Message----- > From: Mark Brown [mailto:broonie@kernel.org] > Sent: Wednesday, October 29, 2014 12:48 AM > > +config SND_SOC_INTEL_CHT_BSW_RT5672_MACH > > + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with > RT5672 codec" > > + depends on X86_INTEL_LPSS > > + select SND_SOC_RT5670 > > + select SND_SST_MFLD_PLATFORM > > + select SND_SOC_INTEL_SST > > + select SND_SST_IPC > > + select SND_SST_MACHINE > > + default n > > n is the default anyway. Will remove " default n" > > +obj-$(CONFIG_SND_SST_MACHINE) += board/ > > It's a bit weird to have the Kconfig in the root Intel directory if the boards are > getting moved into a subdirectory - why not just source a Kconfig in the board > directory? Will source a Kconfig in the board directory. > > +static int cht_aif1_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; > > + int ret; > > + > > + if (strncmp(codec_dai->name, "rt5670-aif1", 11)) > > + return 0; > > 11 is a magic number! Why not use strlen() here (and why do we do nothing > in the AIF1 hw_params() if we're working with AIF1)? It not necessary. Will remove. > > > + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK, > > + CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); > > + if (ret < 0) { > > + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); > > + return ret; > > + } > > + > > + ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1, > > + params_rate(params) * 512, > > + SND_SOC_CLOCK_IN); > > + if (ret < 0) { > > + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); > > + return ret; > > + } > > Nothing ever stops the PLL - a set_bias_level() callback with a handler for _OFF. > Otherwise we're wasting power. Can we introduce a power supply widget for the platform clock used as MCLK? That widget can be added into the playback and capture path. So when idle, the platform clock can be turn off and let the codec PLL selects its internal low frequency clock only for jack detection. It's verified internally. The platform clock driver is not upstream yet, so in the widget control we can't really turn off the MCLK output to codec, but at least we can let the codec PLL no longer locked to the high frequency MCLK. Or we don't change the code at moment, until we upstream the platform clock driver at first? Which way is better? > > > + snd_soc_card_cht.dev = &pdev->dev; > > + ret_val = snd_soc_register_card(&snd_soc_card_cht); > > + if (ret_val) { > > devm_snd_soc_register_card() and the removal function can go entirely. Okay. Thanks Mengdong
On Wed, Oct 29, 2014 at 06:45:05AM +0000, Lin, Mengdong wrote: > > Nothing ever stops the PLL - a set_bias_level() callback with a handler for _OFF. > > Otherwise we're wasting power. > Can we introduce a power supply widget for the platform clock used as MCLK? > That widget can be added into the playback and capture path. > So when idle, the platform clock can be turn off and let the codec PLL selects > its internal low frequency clock only for jack detection. It's verified internally. That should be fine also, it's just usually a bit more work to add all the routes for DAPM. > Or we don't change the code at moment, until we upstream the platform clock > driver at first? > Which way is better? Well, currently the code to load the driver is also not upstream so may as well have the driver be what's wanted! But it's not a massive deal, main thing would be to get everything done as part of initial upstreaming instead of having to come back and work on it again later.
+ Liam. > -----Original Message----- > From: Mark Brown [mailto:broonie@kernel.org] > Sent: Wednesday, October 29, 2014 6:31 PM > > > Nothing ever stops the PLL - a set_bias_level() callback with a handler for > _OFF. > > > Otherwise we're wasting power. > > > Can we introduce a power supply widget for the platform clock used as > MCLK? > > That widget can be added into the playback and capture path. > > So when idle, the platform clock can be turn off and let the codec PLL > > selects its internal low frequency clock only for jack detection. It's verified > internally. > > That should be fine also, it's just usually a bit more work to add all the routes > for DAPM. > > > Or we don't change the code at moment, until we upstream the platform > > clock driver at first? > > > Which way is better? > > Well, currently the code to load the driver is also not upstream so may as well > have the driver be what's wanted! But it's not a massive deal, main thing > would be to get everything done as part of initial upstreaming instead of > having to come back and work on it again later. Now we're working with Realtek to enable runtime PM on RT5672 codec driver. With help of ACPI, - the codec will be in suspended to D3 when idle , switch to its internal clock, and BIOS will turn off the platform clock output (MCLK) to save power. - And when the codec resumes to D0, BIOS will turn on the clock at first. And hw_params will make the codec use PLL and lock to MCLK again. Thus the machine driver does not need to explicitly turn on/off the platform codec by itself. Thanks Mengdong
On Fri, Oct 31, 2014 at 12:48:26PM +0000, Lin, Mengdong wrote: > Now we're working with Realtek to enable runtime PM on RT5672 codec driver. > With help of ACPI, > - the codec will be in suspended to D3 when idle , switch to its internal clock, > and BIOS will turn off the platform clock output (MCLK) to save power. > - And when the codec resumes to D0, BIOS will turn on the clock at first. And > hw_params will make the codec use PLL and lock to MCLK again. > Thus the machine driver does not need to explicitly turn on/off the platform > codec by itself. If the machine driver has asked for the PLL to be on I'd expect the CODEC driver to be respecting that...
> -----Original Message----- > From: Mark Brown [mailto:broonie@kernel.org] > Sent: Friday, October 31, 2014 8:54 PM > On Fri, Oct 31, 2014 at 12:48:26PM +0000, Lin, Mengdong wrote: > > > Now we're working with Realtek to enable runtime PM on RT5672 codec > driver. > > With help of ACPI, > > - the codec will be in suspended to D3 when idle , switch to its > > internal clock, and BIOS will turn off the platform clock output (MCLK) to > save power. > > - And when the codec resumes to D0, BIOS will turn on the clock at > > first. And hw_params will make the codec use PLL and lock to MCLK again. > > > Thus the machine driver does not need to explicitly turn on/off the > > platform codec by itself. > > If the machine driver has asked for the PLL to be on I'd expect the CODEC > driver to be respecting that... The codec driver rt5670 defines a supply widget to control the power of PLL. So the PLL will be power on when there is active audio streaming and power off when Idle. The machine driver need not explicitly turn on/off the PLL, but only need to select PLL source to MCLK in hw_params and configure the in/out frequency. And we've verified to enable runtime PM on the codec driver and trigger ACPI method to dynamically control the MCLK output from SOC to the codec: - When codec is active (D0), BIOS will turn on MCLK at first - When codec is suspended on idle (D3), codec will switch to its internal clock, and BIOS will turn off MCLK I'll post V3 machine driver based on your comments on v2. After an internal sync, this machine driver will be moved to sound/soc/intel directory, with other existing Intel machines. Thanks Mengdong
Hi Mark, I've posted the v3 patch. Would you please have a review? There are other Intel machine drivers submitted at the same time, hope they can be integrated smoothly to avoid conflict on Kconfig and Makefile. Thanks Mengdong > -----Original Message----- > From: alsa-devel-bounces@alsa-project.org > [mailto:alsa-devel-bounces@alsa-project.org] On Behalf Of Lin, Mengdong > Sent: Monday, November 03, 2014 8:11 PM > To: Mark Brown > Cc: Koul, Vinod; alsa-devel@alsa-project.org; Prusty, Subhransu S; Girdwood, > Liam R > Subject: Re: [alsa-devel] [PATCH v2] ASoC: Intel: Add Cherrytrail & Braswell > machine driver cht_bsw_rt5672 > > > -----Original Message----- > > From: Mark Brown [mailto:broonie@kernel.org] > > Sent: Friday, October 31, 2014 8:54 PM > > > On Fri, Oct 31, 2014 at 12:48:26PM +0000, Lin, Mengdong wrote: > > > > > Now we're working with Realtek to enable runtime PM on RT5672 codec > > driver. > > > With help of ACPI, > > > - the codec will be in suspended to D3 when idle , switch to its > > > internal clock, and BIOS will turn off the platform clock output > > > (MCLK) to > > save power. > > > - And when the codec resumes to D0, BIOS will turn on the clock at > > > first. And hw_params will make the codec use PLL and lock to MCLK again. > > > > > Thus the machine driver does not need to explicitly turn on/off the > > > platform codec by itself. > > > > If the machine driver has asked for the PLL to be on I'd expect the > > CODEC driver to be respecting that... > > The codec driver rt5670 defines a supply widget to control the power of PLL. > So the PLL will be power on when there is active audio streaming and power off > when Idle. > The machine driver need not explicitly turn on/off the PLL, but only need to > select PLL source to MCLK in hw_params and configure the in/out frequency. > > And we've verified to enable runtime PM on the codec driver and trigger ACPI > method to dynamically control the MCLK output from SOC to the codec: > - When codec is active (D0), BIOS will turn on MCLK at first > - When codec is suspended on idle (D3), codec will switch to its internal clock, > and BIOS will turn off MCLK > > I'll post V3 machine driver based on your comments on v2. > After an internal sync, this machine driver will be moved to sound/soc/intel > directory, with other existing Intel machines. > > Thanks > Mengdong > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
On Tue, Nov 04, 2014 at 03:15:15PM +0530, Lin, Mengdong wrote: > Hi Mark, > > I've posted the v3 patch. Would you please have a review? > > There are other Intel machine drivers submitted at the same time, hope they > can be integrated smoothly to avoid conflict on Kconfig and Makefile. Mengdong, I am about to send v3 series of my driver changes. Should I add this driver in my series to avoid merge conflict in Kconfig?
On Tue, Nov 04, 2014 at 09:45:15AM +0000, Lin, Mengdong wrote: > Hi Mark, > > I've posted the v3 patch. Would you please have a review? You only posted it yesterday. Please allow reasonable time for review, demanding a review within a day is not reasonable and will only annoy maintainers.
> -----Original Message----- > From: Koul, Vinod > Sent: Tuesday, November 04, 2014 6:23 PM > To: Lin, Mengdong > Cc: Mark Brown; alsa-devel@alsa-project.org; Prusty, Subhransu S; Girdwood, > Liam R > Subject: Re: [PATCH v2] ASoC: Intel: Add Cherrytrail & Braswell machine driver > cht_bsw_rt5672 > > On Tue, Nov 04, 2014 at 03:15:15PM +0530, Lin, Mengdong wrote: > > Hi Mark, > > > > I've posted the v3 patch. Would you please have a review? > > > > There are other Intel machine drivers submitted at the same time, hope > > they can be integrated smoothly to avoid conflict on Kconfig and Makefile. > > Mengdong, I am about to send v3 series of my driver changes. Should I add > this driver in my series to avoid merge conflict in Kconfig? Okay, please. It will help to avoid merge conflict. Thanks Mengdong
> -----Original Message----- > From: alsa-devel-bounces@alsa-project.org > [mailto:alsa-devel-bounces@alsa-project.org] On Behalf Of Mark Brown > Sent: Tuesday, November 04, 2014 7:47 PM > To: Lin, Mengdong > Cc: Koul, Vinod; alsa-devel@alsa-project.org; Prusty, Subhransu S; Girdwood, > Liam R > Subject: Re: [alsa-devel] [PATCH v2] ASoC: Intel: Add Cherrytrail & Braswell > machine driver cht_bsw_rt5672 > > On Tue, Nov 04, 2014 at 09:45:15AM +0000, Lin, Mengdong wrote: > > Hi Mark, > > > > I've posted the v3 patch. Would you please have a review? > > You only posted it yesterday. Please allow reasonable time for review, > demanding a review within a day is not reasonable and will only annoy > maintainers. I'm sorry for this. Vinod is posting other Intel machine drivers at the same time now. He will add this machine driver in his v3 patch series to avoid conflict in Kconfig and Makefile. Thanks Mengdong
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 2a3af88..7479ce0 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig @@ -16,6 +16,9 @@ config SND_SST_MFLD_PLATFORM config SND_SST_IPC tristate +config SND_SST_MACHINE + tristate + config SND_SOC_INTEL_SST tristate "ASoC support for Intel(R) Smart Sound Technology" select SND_SOC_INTEL_SST_ACPI if ACPI @@ -76,3 +79,20 @@ config SND_SOC_INTEL_BROADWELL_MACH Ultrabook platforms. Say Y if you have such a device If unsure select "N". + +config SND_SOC_INTEL_CHT_BSW_RT5672_MACH + tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" + depends on X86_INTEL_LPSS + select SND_SOC_RT5670 + select SND_SST_MFLD_PLATFORM + select SND_SOC_INTEL_SST + select SND_SST_IPC + select SND_SST_MACHINE + default n + + help + This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell + platforms with RT5672 audio codec. + Say Y if you have such a device + If unsure select "N". + diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index 9ab43be..4069d3f 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o +obj-$(CONFIG_SND_SST_MACHINE) += board/ # DSP driver obj-$(CONFIG_SND_SST_IPC) += sst/ diff --git a/sound/soc/intel/board/Makefile b/sound/soc/intel/board/Makefile new file mode 100644 index 0000000..9ecc227 --- /dev/null +++ b/sound/soc/intel/board/Makefile @@ -0,0 +1,2 @@ +snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o +obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o diff --git a/sound/soc/intel/board/cht_bsw_rt5672.c b/sound/soc/intel/board/cht_bsw_rt5672.c new file mode 100644 index 0000000..789d1a0 --- /dev/null +++ b/sound/soc/intel/board/cht_bsw_rt5672.c @@ -0,0 +1,246 @@ +/* + * cht_bsw_rt5672.c - ASoc Machine driver for Intel Cherryview-based platforms + * Cherrytrail and Braswell, with RT5672 codec. + * + * Copyright (C) 2014 Intel Corp + * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com> + * Mengdong Lin <mengdong.lin@intel.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; version 2 of the License. + * + * 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. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include "../../codecs/rt5670.h" +#include "../sst-atom-controls.h" + +#define CHT_PLAT_CLK_3_HZ 19200000 + +static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +static const struct snd_soc_dapm_route cht_audio_map[] = { + {"IN1P", NULL, "Headset Mic"}, + {"IN1N", NULL, "Headset Mic"}, + {"DMIC L1", NULL, "Int Mic"}, + {"DMIC R1", NULL, "Int Mic"}, + {"Headphone", NULL, "HPOL"}, + {"Headphone", NULL, "HPOR"}, + {"Ext Spk", NULL, "SPOLP"}, + {"Ext Spk", NULL, "SPOLN"}, + {"Ext Spk", NULL, "SPORP"}, + {"Ext Spk", NULL, "SPORN"}, + {"AIF1 Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec_out0"}, + {"ssp2 Tx", NULL, "codec_out1"}, + {"codec_in0", NULL, "ssp2 Rx"}, + {"codec_in1", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "AIF1 Capture"}, +}; + +static const struct snd_kcontrol_new cht_mc_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Int Mic"), + SOC_DAPM_PIN_SWITCH("Ext Spk"), +}; + +static int cht_aif1_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; + int ret; + + if (strncmp(codec_dai->name, "rt5670-aif1", 11)) + return 0; + + ret = snd_soc_dai_set_pll(codec_dai, 0, RT5670_PLL1_S_MCLK, + CHT_PLAT_CLK_3_HZ, params_rate(params) * 512); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec pll: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5670_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + dev_err(rtd->dev, "can't set codec sysclk: %d\n", ret); + return ret; + } + return 0; +} + +static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) +{ + int ret; + struct snd_soc_dai *codec_dai = runtime->codec_dai; + + /* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */ + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24); + if (ret < 0) { + dev_err(runtime->dev, "can't set codec TDM slot %d\n", ret); + return ret; + } + + return 0; +} + +static int cht_codec_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct snd_interval *rate = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_RATE); + struct snd_interval *channels = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + + /* The DSP will covert the FE rate to 48k, stereo, 24bits */ + rate->min = rate->max = 48000; + channels->min = channels->max = 2; + + /* set SSP2 to 24-bit */ + snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT - + SNDRV_PCM_HW_PARAM_FIRST_MASK], + SNDRV_PCM_FORMAT_S24_LE); + return 0; +} + +static unsigned int rates_48000[] = { + 48000, +}; + +static struct snd_pcm_hw_constraint_list constraints_48000 = { + .count = ARRAY_SIZE(rates_48000), + .list = rates_48000, +}; + +static int cht_aif1_startup(struct snd_pcm_substream *substream) +{ + return snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_48000); +} + +static struct snd_soc_ops cht_aif1_ops = { + .startup = cht_aif1_startup, +}; + +static struct snd_soc_ops cht_be_ssp2_ops = { + .hw_params = cht_aif1_hw_params, +}; + +static struct snd_soc_dai_link cht_dailink[] = { + /* Front End DAI links */ + [MERR_DPCM_AUDIO] = { + .name = "Audio Port", + .stream_name = "Audio", + .cpu_dai_name = "media-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + .ignore_suspend = 1, + .dynamic = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &cht_aif1_ops, + }, + [MERR_DPCM_COMPR] = { + .name = "Compressed Port", + .stream_name = "Compress", + .cpu_dai_name = "compress-cpu-dai", + .codec_dai_name = "snd-soc-dummy-dai", + .codec_name = "snd-soc-dummy", + .platform_name = "sst-mfld-platform", + }, + + /* Back End DAI links */ + { + /* SSP2 - Codec */ + .name = "SSP2-Codec", + .be_id = 1, + .cpu_dai_name = "ssp2-port", + .platform_name = "sst-mfld-platform", + .no_pcm = 1, + .codec_dai_name = "rt5670-aif1", + .codec_name = "i2c-10EC5670:00", + .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF + | SND_SOC_DAIFMT_CBS_CFS, + .init = cht_codec_init, + .be_hw_params_fixup = cht_codec_fixup, + .ignore_suspend = 1, + .dpcm_playback = 1, + .dpcm_capture = 1, + .ops = &cht_be_ssp2_ops, + }, +}; + +/* SoC card */ +static struct snd_soc_card snd_soc_card_cht = { + .name = "cherrytrailcraudio", + .dai_link = cht_dailink, + .num_links = ARRAY_SIZE(cht_dailink), + .dapm_widgets = cht_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets), + .dapm_routes = cht_audio_map, + .num_dapm_routes = ARRAY_SIZE(cht_audio_map), + .controls = cht_mc_controls, + .num_controls = ARRAY_SIZE(cht_mc_controls), +}; + +static int snd_cht_mc_probe(struct platform_device *pdev) +{ + int ret_val = 0; + + /* register the soc card */ + snd_soc_card_cht.dev = &pdev->dev; + ret_val = snd_soc_register_card(&snd_soc_card_cht); + if (ret_val) { + dev_err(&pdev->dev, + "snd_soc_register_card failed %d\n", ret_val); + return ret_val; + } + platform_set_drvdata(pdev, &snd_soc_card_cht); + return ret_val; +} + +static int snd_cht_mc_remove(struct platform_device *pdev) +{ + struct snd_soc_card *soc_card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(soc_card); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver snd_cht_mc_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "cht-bsw-rt5672", + .pm = &snd_soc_pm_ops, + }, + .probe = snd_cht_mc_probe, + .remove = snd_cht_mc_remove, +}; + +module_platform_driver(snd_cht_mc_driver); + +MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver"); +MODULE_AUTHOR("Subhransu S. Prusty, Mengdong Lin"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cht-bsw-rt5672");