Merge branch 'fix/asoc' into for-linus
This commit is contained in:
commit
842a209700
7 changed files with 55 additions and 68 deletions
|
@ -27,42 +27,38 @@ ASoC Codec driver breakdown
|
||||||
|
|
||||||
1 - Codec DAI and PCM configuration
|
1 - Codec DAI and PCM configuration
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
Each codec driver must have a struct snd_soc_codec_dai to define its DAI and
|
Each codec driver must have a struct snd_soc_dai_driver to define its DAI and
|
||||||
PCM capabilities and operations. This struct is exported so that it can be
|
PCM capabilities and operations. This struct is exported so that it can be
|
||||||
registered with the core by your machine driver.
|
registered with the core by your machine driver.
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
struct snd_soc_codec_dai wm8731_dai = {
|
static struct snd_soc_dai_ops wm8731_dai_ops = {
|
||||||
.name = "WM8731",
|
.prepare = wm8731_pcm_prepare,
|
||||||
/* playback capabilities */
|
.hw_params = wm8731_hw_params,
|
||||||
|
.shutdown = wm8731_shutdown,
|
||||||
|
.digital_mute = wm8731_mute,
|
||||||
|
.set_sysclk = wm8731_set_dai_sysclk,
|
||||||
|
.set_fmt = wm8731_set_dai_fmt,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct snd_soc_dai_driver wm8731_dai = {
|
||||||
|
.name = "wm8731-hifi",
|
||||||
.playback = {
|
.playback = {
|
||||||
.stream_name = "Playback",
|
.stream_name = "Playback",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
.channels_max = 2,
|
.channels_max = 2,
|
||||||
.rates = WM8731_RATES,
|
.rates = WM8731_RATES,
|
||||||
.formats = WM8731_FORMATS,},
|
.formats = WM8731_FORMATS,},
|
||||||
/* capture capabilities */
|
|
||||||
.capture = {
|
.capture = {
|
||||||
.stream_name = "Capture",
|
.stream_name = "Capture",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
.channels_max = 2,
|
.channels_max = 2,
|
||||||
.rates = WM8731_RATES,
|
.rates = WM8731_RATES,
|
||||||
.formats = WM8731_FORMATS,},
|
.formats = WM8731_FORMATS,},
|
||||||
/* pcm operations - see section 4 below */
|
.ops = &wm8731_dai_ops,
|
||||||
.ops = {
|
.symmetric_rates = 1,
|
||||||
.prepare = wm8731_pcm_prepare,
|
|
||||||
.hw_params = wm8731_hw_params,
|
|
||||||
.shutdown = wm8731_shutdown,
|
|
||||||
},
|
|
||||||
/* DAI operations - see DAI.txt */
|
|
||||||
.dai_ops = {
|
|
||||||
.digital_mute = wm8731_mute,
|
|
||||||
.set_sysclk = wm8731_set_dai_sysclk,
|
|
||||||
.set_fmt = wm8731_set_dai_fmt,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(wm8731_dai);
|
|
||||||
|
|
||||||
|
|
||||||
2 - Codec control IO
|
2 - Codec control IO
|
||||||
|
@ -186,13 +182,14 @@ when the mute is applied or freed.
|
||||||
|
|
||||||
i.e.
|
i.e.
|
||||||
|
|
||||||
static int wm8974_mute(struct snd_soc_codec *codec,
|
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
|
||||||
struct snd_soc_codec_dai *dai, int mute)
|
|
||||||
{
|
{
|
||||||
u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf;
|
struct snd_soc_codec *codec = dai->codec;
|
||||||
if(mute)
|
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
|
||||||
wm8974_write(codec, WM8974_DAC, mute_reg | 0x40);
|
|
||||||
|
if (mute)
|
||||||
|
snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
|
||||||
else
|
else
|
||||||
wm8974_write(codec, WM8974_DAC, mute_reg);
|
snd_soc_write(codec, WM8974_DAC, mute_reg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ the following struct:-
|
||||||
struct snd_soc_card {
|
struct snd_soc_card {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
int (*probe)(struct platform_device *pdev);
|
int (*probe)(struct platform_device *pdev);
|
||||||
int (*remove)(struct platform_device *pdev);
|
int (*remove)(struct platform_device *pdev);
|
||||||
|
|
||||||
|
@ -22,12 +24,13 @@ struct snd_soc_card {
|
||||||
int (*resume_pre)(struct platform_device *pdev);
|
int (*resume_pre)(struct platform_device *pdev);
|
||||||
int (*resume_post)(struct platform_device *pdev);
|
int (*resume_post)(struct platform_device *pdev);
|
||||||
|
|
||||||
/* machine stream operations */
|
...
|
||||||
struct snd_soc_ops *ops;
|
|
||||||
|
|
||||||
/* CPU <--> Codec DAI links */
|
/* CPU <--> Codec DAI links */
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
int num_links;
|
int num_links;
|
||||||
|
|
||||||
|
...
|
||||||
};
|
};
|
||||||
|
|
||||||
probe()/remove()
|
probe()/remove()
|
||||||
|
@ -42,11 +45,6 @@ of any machine audio tasks that have to be done before or after the codec, DAIs
|
||||||
and DMA is suspended and resumed. Optional.
|
and DMA is suspended and resumed. Optional.
|
||||||
|
|
||||||
|
|
||||||
Machine operations
|
|
||||||
------------------
|
|
||||||
The machine specific audio operations can be set here. Again this is optional.
|
|
||||||
|
|
||||||
|
|
||||||
Machine DAI Configuration
|
Machine DAI Configuration
|
||||||
-------------------------
|
-------------------------
|
||||||
The machine DAI configuration glues all the codec and CPU DAIs together. It can
|
The machine DAI configuration glues all the codec and CPU DAIs together. It can
|
||||||
|
@ -61,8 +59,10 @@ struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.
|
||||||
static struct snd_soc_dai_link corgi_dai = {
|
static struct snd_soc_dai_link corgi_dai = {
|
||||||
.name = "WM8731",
|
.name = "WM8731",
|
||||||
.stream_name = "WM8731",
|
.stream_name = "WM8731",
|
||||||
.cpu_dai = &pxa_i2s_dai,
|
.cpu_dai_name = "pxa-is2-dai",
|
||||||
.codec_dai = &wm8731_dai,
|
.codec_dai_name = "wm8731-hifi",
|
||||||
|
.platform_name = "pxa-pcm-audio",
|
||||||
|
.codec_name = "wm8713-codec.0-001a",
|
||||||
.init = corgi_wm8731_init,
|
.init = corgi_wm8731_init,
|
||||||
.ops = &corgi_ops,
|
.ops = &corgi_ops,
|
||||||
};
|
};
|
||||||
|
@ -77,26 +77,6 @@ static struct snd_soc_card snd_soc_corgi = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Machine Audio Subsystem
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
The machine soc device glues the platform, machine and codec driver together.
|
|
||||||
Private data can also be set here. e.g.
|
|
||||||
|
|
||||||
/* corgi audio private data */
|
|
||||||
static struct wm8731_setup_data corgi_wm8731_setup = {
|
|
||||||
.i2c_address = 0x1b,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* corgi audio subsystem */
|
|
||||||
static struct snd_soc_device corgi_snd_devdata = {
|
|
||||||
.machine = &snd_soc_corgi,
|
|
||||||
.platform = &pxa2xx_soc_platform,
|
|
||||||
.codec_dev = &soc_codec_dev_wm8731,
|
|
||||||
.codec_data = &corgi_wm8731_setup,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Machine Power Map
|
Machine Power Map
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,10 @@ struct snd_soc_ops {
|
||||||
int (*trigger)(struct snd_pcm_substream *, int);
|
int (*trigger)(struct snd_pcm_substream *, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
The platform driver exports its DMA functionality via struct snd_soc_platform:-
|
The platform driver exports its DMA functionality via struct
|
||||||
|
snd_soc_platform_driver:-
|
||||||
|
|
||||||
struct snd_soc_platform {
|
struct snd_soc_platform_driver {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
int (*probe)(struct platform_device *pdev);
|
int (*probe)(struct platform_device *pdev);
|
||||||
|
@ -34,6 +35,13 @@ struct snd_soc_platform {
|
||||||
int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *);
|
int (*pcm_new)(struct snd_card *, struct snd_soc_codec_dai *, struct snd_pcm *);
|
||||||
void (*pcm_free)(struct snd_pcm *);
|
void (*pcm_free)(struct snd_pcm *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For platform caused delay reporting.
|
||||||
|
* Optional.
|
||||||
|
*/
|
||||||
|
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
|
||||||
|
struct snd_soc_dai *);
|
||||||
|
|
||||||
/* platform stream ops */
|
/* platform stream ops */
|
||||||
struct snd_pcm_ops *pcm_ops;
|
struct snd_pcm_ops *pcm_ops;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
config SND_BF5XX_I2S
|
config SND_BF5XX_I2S
|
||||||
tristate "SoC I2S Audio for the ADI BF5xx chip"
|
tristate "SoC I2S Audio for the ADI BF5xx chip"
|
||||||
depends on BLACKFIN
|
depends on BLACKFIN
|
||||||
|
select SND_BF5XX_SOC_SPORT
|
||||||
help
|
help
|
||||||
Say Y or M if you want to add support for codecs attached to
|
Say Y or M if you want to add support for codecs attached to
|
||||||
the Blackfin SPORT (synchronous serial ports) interface in I2S
|
the Blackfin SPORT (synchronous serial ports) interface in I2S
|
||||||
|
@ -35,6 +36,7 @@ config SND_BFIN_AD73311_SE
|
||||||
config SND_BF5XX_TDM
|
config SND_BF5XX_TDM
|
||||||
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
|
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
|
||||||
depends on (BLACKFIN && SND_SOC)
|
depends on (BLACKFIN && SND_SOC)
|
||||||
|
select SND_BF5XX_SOC_SPORT
|
||||||
help
|
help
|
||||||
Say Y or M if you want to add support for codecs attached to
|
Say Y or M if you want to add support for codecs attached to
|
||||||
the Blackfin SPORT (synchronous serial ports) interface in TDM
|
the Blackfin SPORT (synchronous serial ports) interface in TDM
|
||||||
|
@ -61,6 +63,10 @@ config SND_BF5XX_SOC_AD193X
|
||||||
config SND_BF5XX_AC97
|
config SND_BF5XX_AC97
|
||||||
tristate "SoC AC97 Audio for the ADI BF5xx chip"
|
tristate "SoC AC97 Audio for the ADI BF5xx chip"
|
||||||
depends on BLACKFIN
|
depends on BLACKFIN
|
||||||
|
select AC97_BUS
|
||||||
|
select SND_SOC_AC97_BUS
|
||||||
|
select SND_BF5XX_SOC_SPORT
|
||||||
|
select SND_BF5XX_SOC_AC97
|
||||||
help
|
help
|
||||||
Say Y or M if you want to add support for codecs attached to
|
Say Y or M if you want to add support for codecs attached to
|
||||||
the Blackfin SPORT (synchronous serial ports) interface in slot 16
|
the Blackfin SPORT (synchronous serial ports) interface in slot 16
|
||||||
|
@ -122,17 +128,12 @@ config SND_BF5XX_SOC_SPORT
|
||||||
|
|
||||||
config SND_BF5XX_SOC_I2S
|
config SND_BF5XX_SOC_I2S
|
||||||
tristate
|
tristate
|
||||||
select SND_BF5XX_SOC_SPORT
|
|
||||||
|
|
||||||
config SND_BF5XX_SOC_TDM
|
config SND_BF5XX_SOC_TDM
|
||||||
tristate
|
tristate
|
||||||
select SND_BF5XX_SOC_SPORT
|
|
||||||
|
|
||||||
config SND_BF5XX_SOC_AC97
|
config SND_BF5XX_SOC_AC97
|
||||||
tristate
|
tristate
|
||||||
select AC97_BUS
|
|
||||||
select SND_SOC_AC97_BUS
|
|
||||||
select SND_BF5XX_SOC_SPORT
|
|
||||||
|
|
||||||
config SND_BF5XX_SPORT_NUM
|
config SND_BF5XX_SPORT_NUM
|
||||||
int "Set a SPORT for Sound chip"
|
int "Set a SPORT for Sound chip"
|
||||||
|
|
|
@ -260,9 +260,9 @@ static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
|
||||||
pr_debug("%s : sport %d\n", __func__, dai->id);
|
pr_debug("%s : sport %d\n", __func__, dai->id);
|
||||||
if (!dai->active)
|
if (!dai->active)
|
||||||
return 0;
|
return 0;
|
||||||
if (dai->capture.active)
|
if (dai->capture_active)
|
||||||
sport_rx_stop(sport);
|
sport_rx_stop(sport);
|
||||||
if (dai->playback.active)
|
if (dai->playback_active)
|
||||||
sport_tx_stop(sport);
|
sport_tx_stop(sport);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,7 +210,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
|
static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct sport_device *sport = dai->private_data;
|
struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
|
||||||
|
|
||||||
if (!dai->active)
|
if (!dai->active)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -235,13 +235,13 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sport_config_rx(sport, IRFS, 0x1F, 0, 0);
|
ret = sport_config_rx(sport, 0, 0x1F, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("SPORT is busy!\n");
|
pr_err("SPORT is busy!\n");
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sport_config_tx(sport, ITFS, 0x1F, 0, 0);
|
ret = sport_config_tx(sport, 0, 0x1F, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("SPORT is busy!\n");
|
pr_err("SPORT is busy!\n");
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -303,14 +303,14 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
|
||||||
goto sport_config_err;
|
goto sport_config_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sport_config_rx(sport_handle, IRFS, 0x1F, 0, 0);
|
ret = sport_config_rx(sport_handle, 0, 0x1F, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("SPORT is busy!\n");
|
pr_err("SPORT is busy!\n");
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto sport_config_err;
|
goto sport_config_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sport_config_tx(sport_handle, ITFS, 0x1F, 0, 0);
|
ret = sport_config_tx(sport_handle, 0, 0x1F, 0, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("SPORT is busy!\n");
|
pr_err("SPORT is busy!\n");
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
|
|
@ -104,6 +104,7 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
|
||||||
.name = "hsdet-gpio",
|
.name = "hsdet-gpio",
|
||||||
.report = SND_JACK_HEADSET,
|
.report = SND_JACK_HEADSET,
|
||||||
.debounce_time = 200,
|
.debounce_time = 200,
|
||||||
|
.invert = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,7 +193,7 @@ static struct snd_soc_dai_link z2_dai = {
|
||||||
.cpu_dai_name = "pxa2xx-i2s",
|
.cpu_dai_name = "pxa2xx-i2s",
|
||||||
.codec_dai_name = "wm8750-hifi",
|
.codec_dai_name = "wm8750-hifi",
|
||||||
.platform_name = "pxa-pcm-audio",
|
.platform_name = "pxa-pcm-audio",
|
||||||
.codec_name = "wm8750-codec.0-001a",
|
.codec_name = "wm8750-codec.0-001b",
|
||||||
.init = z2_wm8750_init,
|
.init = z2_wm8750_init,
|
||||||
.ops = &z2_ops,
|
.ops = &z2_ops,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue