forked from Minki/linux
Merge branch 'fix/asoc' into for-linus
This commit is contained in:
commit
842a209700
@ -27,42 +27,38 @@ ASoC Codec driver breakdown
|
||||
|
||||
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
|
||||
registered with the core by your machine driver.
|
||||
|
||||
e.g.
|
||||
|
||||
struct snd_soc_codec_dai wm8731_dai = {
|
||||
.name = "WM8731",
|
||||
/* playback capabilities */
|
||||
static struct snd_soc_dai_ops wm8731_dai_ops = {
|
||||
.prepare = wm8731_pcm_prepare,
|
||||
.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 = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = WM8731_RATES,
|
||||
.formats = WM8731_FORMATS,},
|
||||
/* capture capabilities */
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = WM8731_RATES,
|
||||
.formats = WM8731_FORMATS,},
|
||||
/* pcm operations - see section 4 below */
|
||||
.ops = {
|
||||
.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,
|
||||
}
|
||||
.ops = &wm8731_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(wm8731_dai);
|
||||
|
||||
|
||||
2 - Codec control IO
|
||||
@ -186,13 +182,14 @@ when the mute is applied or freed.
|
||||
|
||||
i.e.
|
||||
|
||||
static int wm8974_mute(struct snd_soc_codec *codec,
|
||||
struct snd_soc_codec_dai *dai, int mute)
|
||||
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf;
|
||||
if(mute)
|
||||
wm8974_write(codec, WM8974_DAC, mute_reg | 0x40);
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
|
||||
|
||||
if (mute)
|
||||
snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
|
||||
else
|
||||
wm8974_write(codec, WM8974_DAC, mute_reg);
|
||||
snd_soc_write(codec, WM8974_DAC, mute_reg);
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ the following struct:-
|
||||
struct snd_soc_card {
|
||||
char *name;
|
||||
|
||||
...
|
||||
|
||||
int (*probe)(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_post)(struct platform_device *pdev);
|
||||
|
||||
/* machine stream operations */
|
||||
struct snd_soc_ops *ops;
|
||||
...
|
||||
|
||||
/* CPU <--> Codec DAI links */
|
||||
struct snd_soc_dai_link *dai_link;
|
||||
int num_links;
|
||||
|
||||
...
|
||||
};
|
||||
|
||||
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.
|
||||
|
||||
|
||||
Machine operations
|
||||
------------------
|
||||
The machine specific audio operations can be set here. Again this is optional.
|
||||
|
||||
|
||||
Machine DAI Configuration
|
||||
-------------------------
|
||||
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 = {
|
||||
.name = "WM8731",
|
||||
.stream_name = "WM8731",
|
||||
.cpu_dai = &pxa_i2s_dai,
|
||||
.codec_dai = &wm8731_dai,
|
||||
.cpu_dai_name = "pxa-is2-dai",
|
||||
.codec_dai_name = "wm8731-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm8713-codec.0-001a",
|
||||
.init = corgi_wm8731_init,
|
||||
.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
|
||||
-----------------
|
||||
|
||||
|
@ -20,9 +20,10 @@ struct snd_soc_ops {
|
||||
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;
|
||||
|
||||
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 *);
|
||||
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 */
|
||||
struct snd_pcm_ops *pcm_ops;
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
config SND_BF5XX_I2S
|
||||
tristate "SoC I2S Audio for the ADI BF5xx chip"
|
||||
depends on BLACKFIN
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
help
|
||||
Say Y or M if you want to add support for codecs attached to
|
||||
the Blackfin SPORT (synchronous serial ports) interface in I2S
|
||||
@ -35,6 +36,7 @@ config SND_BFIN_AD73311_SE
|
||||
config SND_BF5XX_TDM
|
||||
tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
|
||||
depends on (BLACKFIN && SND_SOC)
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
help
|
||||
Say Y or M if you want to add support for codecs attached to
|
||||
the Blackfin SPORT (synchronous serial ports) interface in TDM
|
||||
@ -61,6 +63,10 @@ config SND_BF5XX_SOC_AD193X
|
||||
config SND_BF5XX_AC97
|
||||
tristate "SoC AC97 Audio for the ADI BF5xx chip"
|
||||
depends on BLACKFIN
|
||||
select AC97_BUS
|
||||
select SND_SOC_AC97_BUS
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
select SND_BF5XX_SOC_AC97
|
||||
help
|
||||
Say Y or M if you want to add support for codecs attached to
|
||||
the Blackfin SPORT (synchronous serial ports) interface in slot 16
|
||||
@ -122,17 +128,12 @@ config SND_BF5XX_SOC_SPORT
|
||||
|
||||
config SND_BF5XX_SOC_I2S
|
||||
tristate
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
|
||||
config SND_BF5XX_SOC_TDM
|
||||
tristate
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
|
||||
config SND_BF5XX_SOC_AC97
|
||||
tristate
|
||||
select AC97_BUS
|
||||
select SND_SOC_AC97_BUS
|
||||
select SND_BF5XX_SOC_SPORT
|
||||
|
||||
config SND_BF5XX_SPORT_NUM
|
||||
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);
|
||||
if (!dai->active)
|
||||
return 0;
|
||||
if (dai->capture.active)
|
||||
if (dai->capture_active)
|
||||
sport_rx_stop(sport);
|
||||
if (dai->playback.active)
|
||||
if (dai->playback_active)
|
||||
sport_tx_stop(sport);
|
||||
return 0;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
|
||||
#ifdef CONFIG_PM
|
||||
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)
|
||||
return 0;
|
||||
@ -235,13 +235,13 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
ret = sport_config_rx(sport, IRFS, 0x1F, 0, 0);
|
||||
ret = sport_config_rx(sport, 0, 0x1F, 0, 0);
|
||||
if (ret) {
|
||||
pr_err("SPORT is busy!\n");
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
ret = sport_config_tx(sport, ITFS, 0x1F, 0, 0);
|
||||
ret = sport_config_tx(sport, 0, 0x1F, 0, 0);
|
||||
if (ret) {
|
||||
pr_err("SPORT is busy!\n");
|
||||
ret = -EBUSY;
|
||||
@ -303,14 +303,14 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
|
||||
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) {
|
||||
pr_err("SPORT is busy!\n");
|
||||
ret = -EBUSY;
|
||||
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) {
|
||||
pr_err("SPORT is busy!\n");
|
||||
ret = -EBUSY;
|
||||
|
@ -104,6 +104,7 @@ static struct snd_soc_jack_gpio hs_jack_gpios[] = {
|
||||
.name = "hsdet-gpio",
|
||||
.report = SND_JACK_HEADSET,
|
||||
.debounce_time = 200,
|
||||
.invert = 1,
|
||||
},
|
||||
};
|
||||
|
||||
@ -192,7 +193,7 @@ static struct snd_soc_dai_link z2_dai = {
|
||||
.cpu_dai_name = "pxa2xx-i2s",
|
||||
.codec_dai_name = "wm8750-hifi",
|
||||
.platform_name = "pxa-pcm-audio",
|
||||
.codec_name = "wm8750-codec.0-001a",
|
||||
.codec_name = "wm8750-codec.0-001b",
|
||||
.init = z2_wm8750_init,
|
||||
.ops = &z2_ops,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user