diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 15:32:05 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 15:32:05 (GMT) |
commit | 33081adf8b89d5a716d7e1c60171768d39795b39 (patch) | |
tree | 275de58bbbb5f7ddffcdc087844cfc7fbe4315be /sound/soc/au1x | |
parent | c55960499f810357a29659b32d6ea594abee9237 (diff) | |
parent | 506ecbca71d07fa327dd986be1682e90885678ee (diff) | |
download | linux-33081adf8b89d5a716d7e1c60171768d39795b39.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (365 commits)
ALSA: hda - Disable sticky PCM stream assignment for AD codecs
ALSA: usb - Creative USB X-Fi volume knob support
ALSA: ca0106: Use card specific dac id for mute controls.
ALSA: ca0106: Allow different sound cards to use different SPI channel mappings.
ALSA: ca0106: Create a nice spot for mapping channels to dacs.
ALSA: ca0106: Move enabling of front dac out of hardcoded setup sequence.
ALSA: ca0106: Pull out dac powering routine into separate function.
ALSA: ca0106 - add Sound Blaster 5.1vx info.
ASoC: tlv320dac33: Use usleep_range for delays
ALSA: usb-audio: add Novation Launchpad support
ALSA: hda - Add workarounds for CT-IBG controllers
ALSA: hda - Fix wrong TLV mute bit for STAC/IDT codecs
ASoC: tpa6130a2: Error handling for broken chip
ASoC: max98088: Staticise m98088_eq_band
ASoC: soc-core: Fix codec->name memory leak
ALSA: hda - Apply ideapad quirk to Acer laptops with Cxt5066
ALSA: hda - Add some workarounds for Creative IBG
ALSA: hda - Fix wrong SPDIF NID assignment for CA0110
ALSA: hda - Fix codec rename rules for ALC662-compatible codecs
ALSA: hda - Add alc_init_jacks() call to other codecs
...
Diffstat (limited to 'sound/soc/au1x')
-rw-r--r-- | sound/soc/au1x/db1200.c | 39 | ||||
-rw-r--r-- | sound/soc/au1x/dbdma2.c | 95 | ||||
-rw-r--r-- | sound/soc/au1x/psc-ac97.c | 71 | ||||
-rw-r--r-- | sound/soc/au1x/psc-i2s.c | 53 | ||||
-rw-r--r-- | sound/soc/au1x/psc.h | 10 |
5 files changed, 97 insertions, 171 deletions
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index cdf7be1..b62fcd3 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -19,7 +19,6 @@ #include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-db1x00/bcsr.h> -#include "../codecs/ac97.h" #include "../codecs/wm8731.h" #include "psc.h" @@ -28,20 +27,16 @@ static struct snd_soc_dai_link db1200_ac97_dai = { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai = &au1xpsc_ac97_dai, - .codec_dai = &ac97_dai, + .codec_dai_name = "ac97-hifi", + .cpu_dai_name = "au1xpsc_ac97.1", + .platform_name = "au1xpsc-pcm.1", + .codec_name = "ac97-codec.1", }; static struct snd_soc_card db1200_ac97_machine = { .name = "DB1200_AC97", .dai_link = &db1200_ac97_dai, .num_links = 1, - .platform = &au1xpsc_soc_platform, -}; - -static struct snd_soc_device db1200_ac97_devdata = { - .card = &db1200_ac97_machine, - .codec_dev = &soc_codec_dev_ac97, }; /*------------------------- I2S PART ---------------------------*/ @@ -49,12 +44,12 @@ static struct snd_soc_device db1200_ac97_devdata = { static int db1200_i2s_startup(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 snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret; /* WM8731 has its own 12MHz crystal */ - snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, + snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, 12000000, SND_SOC_CLOCK_IN); /* codec is bitclock and lrclk master */ @@ -80,8 +75,10 @@ static struct snd_soc_ops db1200_i2s_wm8731_ops = { static struct snd_soc_dai_link db1200_i2s_dai = { .name = "WM8731", .stream_name = "WM8731 PCM", - .cpu_dai = &au1xpsc_i2s_dai, - .codec_dai = &wm8731_dai, + .codec_dai_name = "wm8731-hifi", + .cpu_dai_name = "au1xpsc_i2s.1", + .platform_name = "au1xpsc-pcm.1", + .codec_name = "wm8731-codec.0-001b", .ops = &db1200_i2s_wm8731_ops, }; @@ -89,12 +86,6 @@ static struct snd_soc_card db1200_i2s_machine = { .name = "DB1200_I2S", .dai_link = &db1200_i2s_dai, .num_links = 1, - .platform = &au1xpsc_soc_platform, -}; - -static struct snd_soc_device db1200_i2s_devdata = { - .card = &db1200_i2s_machine, - .codec_dev = &soc_codec_dev_wm8731, }; /*------------------------- COMMON PART ---------------------------*/ @@ -106,18 +97,16 @@ static int __init db1200_audio_load(void) int ret; ret = -ENOMEM; - db1200_asoc_dev = platform_device_alloc("soc-audio", -1); + db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */ if (!db1200_asoc_dev) goto out; /* DB1200 board setup set PSC1MUX to preferred audio device */ if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) - platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata); + platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine); else - platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata); + platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine); - db1200_ac97_devdata.dev = &db1200_asoc_dev->dev; - db1200_i2s_devdata.dev = &db1200_asoc_dev->dev; ret = platform_device_add(db1200_asoc_dev); if (ret) { diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 6d9f4c6..10fdd28 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -10,9 +10,6 @@ * * DMA glue for Au1x-PSC audio. * - * NOTE: all of these drivers can only work with a SINGLE instance - * of a PSC. Multiple independent audio devices are impossible - * with ASoC v1. */ @@ -61,9 +58,6 @@ struct au1xpsc_audio_dmadata { int msbits; }; -/* instance data. There can be only one, MacLeod!!!! */ -static struct au1xpsc_audio_dmadata *au1xpsc_audio_pcmdma[2]; - /* * These settings are somewhat okay, at least on my machine audio plays * almost skip-free. Especially the 64kB buffer seems to help a LOT. @@ -199,6 +193,14 @@ out: return 0; } +static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream *ss) +{ + struct snd_soc_pcm_runtime *rtd = ss->private_data; + struct au1xpsc_audio_dmadata *pcd = + snd_soc_platform_get_drvdata(rtd->platform); + return &pcd[SUBSTREAM_TYPE(ss)]; +} + static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -211,7 +213,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, goto out; stype = SUBSTREAM_TYPE(substream); - pcd = au1xpsc_audio_pcmdma[stype]; + pcd = to_dmadata(substream); DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " "runtime->min_align %d\n", @@ -249,8 +251,7 @@ static int au1xpsc_pcm_hw_free(struct snd_pcm_substream *substream) static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) { - struct au1xpsc_audio_dmadata *pcd = - au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]; + struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream); au1xxx_dbdma_reset(pcd->ddma_chan); @@ -267,7 +268,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { - u32 c = au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->ddma_chan; + u32 c = to_dmadata(substream)->ddma_chan; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -287,8 +288,7 @@ static int au1xpsc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) static snd_pcm_uframes_t au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) { - return bytes_to_frames(substream->runtime, - au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]->pos); + return bytes_to_frames(substream->runtime, to_dmadata(substream)->pos); } static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) @@ -299,7 +299,7 @@ static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) static int au1xpsc_pcm_close(struct snd_pcm_substream *substream) { - au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[SUBSTREAM_TYPE(substream)]); + au1x_pcm_dbdma_free(to_dmadata(substream)); return 0; } @@ -329,42 +329,21 @@ static int au1xpsc_pcm_new(struct snd_card *card, return 0; } -static int au1xpsc_pcm_probe(struct platform_device *pdev) -{ - if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX]) - return -ENODEV; - - return 0; -} - -static int au1xpsc_pcm_remove(struct platform_device *pdev) -{ - return 0; -} - /* au1xpsc audio platform */ -struct snd_soc_platform au1xpsc_soc_platform = { - .name = "au1xpsc-pcm-dbdma", - .probe = au1xpsc_pcm_probe, - .remove = au1xpsc_pcm_remove, - .pcm_ops = &au1xpsc_pcm_ops, +struct snd_soc_platform_driver au1xpsc_soc_platform = { + .ops = &au1xpsc_pcm_ops, .pcm_new = au1xpsc_pcm_new, .pcm_free = au1xpsc_pcm_free_dma_buffers, }; -EXPORT_SYMBOL_GPL(au1xpsc_soc_platform); static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) { + struct au1xpsc_audio_dmadata *dmadata; struct resource *r; int ret; - if (au1xpsc_audio_pcmdma[PCM_TX] || au1xpsc_audio_pcmdma[PCM_RX]) - return -EBUSY; - - /* TX DMA */ - au1xpsc_audio_pcmdma[PCM_TX] - = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); - if (!au1xpsc_audio_pcmdma[PCM_TX]) + dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); + if (!dmadata) return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -372,47 +351,33 @@ static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) ret = -ENODEV; goto out1; } - (au1xpsc_audio_pcmdma[PCM_TX])->ddma_id = r->start; + dmadata[PCM_TX].ddma_id = r->start; /* RX DMA */ - au1xpsc_audio_pcmdma[PCM_RX] - = kzalloc(sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); - if (!au1xpsc_audio_pcmdma[PCM_RX]) - return -ENOMEM; - r = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!r) { ret = -ENODEV; - goto out2; + goto out1; } - (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; + dmadata[PCM_RX].ddma_id = r->start; + + platform_set_drvdata(pdev, dmadata); - ret = snd_soc_register_platform(&au1xpsc_soc_platform); + ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); if (!ret) return ret; -out2: - kfree(au1xpsc_audio_pcmdma[PCM_RX]); - au1xpsc_audio_pcmdma[PCM_RX] = NULL; out1: - kfree(au1xpsc_audio_pcmdma[PCM_TX]); - au1xpsc_audio_pcmdma[PCM_TX] = NULL; + kfree(dmadata); return ret; } static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) { - int i; + struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev); - snd_soc_unregister_platform(&au1xpsc_soc_platform); - - for (i = 0; i < 2; i++) { - if (au1xpsc_audio_pcmdma[i]) { - au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); - kfree(au1xpsc_audio_pcmdma[i]); - au1xpsc_audio_pcmdma[i] = NULL; - } - } + snd_soc_unregister_platform(&pdev->dev); + kfree(dmadata); return 0; } @@ -428,8 +393,6 @@ static struct platform_driver au1xpsc_pcm_driver = { static int __init au1xpsc_audio_dbdma_load(void) { - au1xpsc_audio_pcmdma[PCM_TX] = NULL; - au1xpsc_audio_pcmdma[PCM_RX] = NULL; return platform_driver_register(&au1xpsc_pcm_driver); } @@ -467,7 +430,7 @@ struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev) res[1].start = res[1].end = id[1]; res[0].flags = res[1].flags = IORESOURCE_DMA; - pd = platform_device_alloc("au1xpsc-pcm", -1); + pd = platform_device_alloc("au1xpsc-pcm", pdev->id); if (!pd) goto out; diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index d14a5a9..d0db66f 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -10,9 +10,6 @@ * * Au1xxx-PSC AC97 glue. * - * NOTE: all of these drivers can only work with a SINGLE instance - * of a PSC. Multiple independent audio devices are impossible - * with ASoC v1. */ #include <linux/init.h> @@ -56,12 +53,29 @@ /* instance data. There can be only one, MacLeod!!!! */ static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; +#if 0 + +/* this could theoretically work, but ac97->bus->card->private_data can be NULL + * when snd_ac97_mixer() is called; I don't know if the rest further down the + * chain are always valid either. + */ +static inline struct au1xpsc_audio_data *ac97_to_pscdata(struct snd_ac97 *x) +{ + struct snd_soc_card *c = x->bus->card->private_data; + return snd_soc_dai_get_drvdata(c->rtd->cpu_dai); +} + +#else + +#define ac97_to_pscdata(x) au1xpsc_ac97_workdata + +#endif + /* AC97 controller reads codec register */ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); unsigned short retry, tmo; unsigned long data; @@ -102,8 +116,7 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); unsigned int tmo, retry; au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); @@ -134,8 +147,7 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, /* AC97 controller asserts a warm reset */ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); au_sync(); @@ -146,8 +158,7 @@ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); int i; /* disable PSC during cold reset */ @@ -202,8 +213,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); unsigned long r, ro, stat; int chans, t, stype = SUBSTREAM_TYPE(substream); @@ -283,8 +293,7 @@ out: static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - /* FIXME */ - struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; + struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); int ret, stype = SUBSTREAM_TYPE(substream); ret = 0; @@ -315,27 +324,19 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, return ret; } -static int au1xpsc_ac97_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) +static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) { return au1xpsc_ac97_workdata ? 0 : -ENODEV; } -static void au1xpsc_ac97_remove(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ -} - static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { .trigger = au1xpsc_ac97_trigger, .hw_params = au1xpsc_ac97_hw_params, }; -struct snd_soc_dai au1xpsc_ac97_dai = { - .name = "au1xpsc_ac97", +static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { .ac97_control = 1, .probe = au1xpsc_ac97_probe, - .remove = au1xpsc_ac97_remove, .playback = { .rates = AC97_RATES, .formats = AC97_FMTS, @@ -350,7 +351,6 @@ struct snd_soc_dai au1xpsc_ac97_dai = { }, .ops = &au1xpsc_ac97_dai_ops, }; -EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai); static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) { @@ -359,9 +359,6 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) unsigned long sel; struct au1xpsc_audio_data *wd; - if (au1xpsc_ac97_workdata) - return -EBUSY; - wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); if (!wd) return -ENOMEM; @@ -395,18 +392,24 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); au_sync(); - ret = snd_soc_register_dai(&au1xpsc_ac97_dai); + /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */ + memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template, + sizeof(struct snd_soc_dai_driver)); + wd->dai_drv.name = dev_name(&pdev->dev); + + platform_set_drvdata(pdev, wd); + + ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); if (ret) goto out1; wd->dmapd = au1xpsc_pcm_add(pdev); if (wd->dmapd) { - platform_set_drvdata(pdev, wd); - au1xpsc_ac97_workdata = wd; /* MDEV */ + au1xpsc_ac97_workdata = wd; return 0; } - snd_soc_unregister_dai(&au1xpsc_ac97_dai); + snd_soc_unregister_dai(&pdev->dev); out1: release_mem_region(r->start, resource_size(r)); out0: @@ -422,7 +425,7 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) if (wd->dmapd) au1xpsc_pcm_destroy(wd->dmapd); - snd_soc_unregister_dai(&au1xpsc_ac97_dai); + snd_soc_unregister_dai(&pdev->dev); /* disable PSC completely */ au_writel(0, AC97_CFG(wd)); diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 6083fe77..fca0912 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -10,9 +10,6 @@ * * Au1xxx-PSC I2S glue. * - * NOTE: all of these drivers can only work with a SINGLE instance - * of a PSC. Multiple independent audio devices are impossible - * with ASoC v1. * NOTE: so far only PSC slave mode (bit- and frameclock) is supported. */ @@ -54,13 +51,10 @@ ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) -/* instance data. There can be only one, MacLeod!!!! */ -static struct au1xpsc_audio_data *au1xpsc_i2s_workdata; - static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { - struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(cpu_dai); unsigned long ct; int ret; @@ -120,7 +114,7 @@ static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); int cfgbits; unsigned long stat; @@ -245,7 +239,7 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; + struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); int ret, stype = SUBSTREAM_TYPE(substream); switch (cmd) { @@ -263,27 +257,13 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, return ret; } -static int au1xpsc_i2s_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - return au1xpsc_i2s_workdata ? 0 : -ENODEV; -} - -static void au1xpsc_i2s_remove(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ -} - static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { .trigger = au1xpsc_i2s_trigger, .hw_params = au1xpsc_i2s_hw_params, .set_fmt = au1xpsc_i2s_set_fmt, }; -struct snd_soc_dai au1xpsc_i2s_dai = { - .name = "au1xpsc_i2s", - .probe = au1xpsc_i2s_probe, - .remove = au1xpsc_i2s_remove, +static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { .playback = { .rates = AU1XPSC_I2S_RATES, .formats = AU1XPSC_I2S_FMTS, @@ -298,7 +278,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = { }, .ops = &au1xpsc_i2s_dai_ops, }; -EXPORT_SYMBOL(au1xpsc_i2s_dai); static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) { @@ -307,9 +286,6 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) int ret; struct au1xpsc_audio_data *wd; - if (au1xpsc_i2s_workdata) - return -EBUSY; - wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); if (!wd) return -ENOMEM; @@ -346,19 +322,23 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) * time out. */ - ret = snd_soc_register_dai(&au1xpsc_i2s_dai); + /* name the DAI like this device instance ("au1xpsc-i2s.PSCINDEX") */ + memcpy(&wd->dai_drv, &au1xpsc_i2s_dai_template, + sizeof(struct snd_soc_dai_driver)); + wd->dai_drv.name = dev_name(&pdev->dev); + + platform_set_drvdata(pdev, wd); + + ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); if (ret) goto out1; /* finally add the DMA device for this PSC */ wd->dmapd = au1xpsc_pcm_add(pdev); - if (wd->dmapd) { - platform_set_drvdata(pdev, wd); - au1xpsc_i2s_workdata = wd; + if (wd->dmapd) return 0; - } - snd_soc_unregister_dai(&au1xpsc_i2s_dai); + snd_soc_unregister_dai(&pdev->dev); out1: release_mem_region(r->start, resource_size(r)); out0: @@ -374,7 +354,7 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) if (wd->dmapd) au1xpsc_pcm_destroy(wd->dmapd); - snd_soc_unregister_dai(&au1xpsc_i2s_dai); + snd_soc_unregister_dai(&pdev->dev); au_writel(0, I2S_CFG(wd)); au_sync(); @@ -385,8 +365,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) release_mem_region(r->start, resource_size(r)); kfree(wd); - au1xpsc_i2s_workdata = NULL; /* MDEV */ - return 0; } @@ -446,7 +424,6 @@ static struct platform_driver au1xpsc_i2s_driver = { static int __init au1xpsc_i2s_load(void) { - au1xpsc_i2s_workdata = NULL; return platform_driver_register(&au1xpsc_i2s_driver); } diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h index 093775d..b30eadd 100644 --- a/sound/soc/au1x/psc.h +++ b/sound/soc/au1x/psc.h @@ -8,19 +8,11 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * NOTE: all of these drivers can only work with a SINGLE instance - * of a PSC. Multiple independent audio devices are impossible - * with ASoC v1. */ #ifndef _AU1X_PCM_H #define _AU1X_PCM_H -extern struct snd_soc_dai au1xpsc_ac97_dai; -extern struct snd_soc_dai au1xpsc_i2s_dai; -extern struct snd_soc_platform au1xpsc_soc_platform; -extern struct snd_ac97_bus_ops soc_ac97_ops; - /* DBDMA helpers */ extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev); extern void au1xpsc_pcm_destroy(struct platform_device *dmapd); @@ -31,6 +23,8 @@ struct au1xpsc_audio_data { unsigned long cfg; unsigned long rate; + struct snd_soc_dai_driver dai_drv; + unsigned long pm[2]; struct mutex lock; struct platform_device *dmapd; |