/* * Sample Au12x0/Au1550 PSC AC97 sound machine. * * Copyright (c) 2007-2008 Manuel Lauss * * This program is free software; you can redistribute it and/or modify * it under the terms outlined in the file COPYING at the root of this * source archive. * * This is a very generic AC97 sound machine driver for boards which * have (AC97) audio at PSC1 (e.g. DB1200 demoboards). */ #include #include #include #include #include #include #include #include #include #include #include #include #include "../codecs/ac97.h" #include "psc.h" static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec) { snd_soc_dapm_sync(codec); return 0; } static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = { .name = "AC97", .stream_name = "AC97 HiFi", .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */ .codec_dai = &ac97_dai, /* see codecs/ac97.c */ .init = au1xpsc_sample_ac97_init, .ops = NULL, }; static struct snd_soc_card au1xpsc_sample_ac97_machine = { .name = "Au1xxx PSC AC97 Audio", .dai_link = &au1xpsc_sample_ac97_dai, .num_links = 1, }; static struct snd_soc_device au1xpsc_sample_ac97_devdata = { .card = &au1xpsc_sample_ac97_machine, .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ .codec_dev = &soc_codec_dev_ac97, }; static struct resource au1xpsc_psc1_res[] = { [0] = { .start = CPHYSADDR(PSC1_BASE_ADDR), .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff, .flags = IORESOURCE_MEM, }, [1] = { #ifdef CONFIG_SOC_AU1200 .start = AU1200_PSC1_INT, .end = AU1200_PSC1_INT, #elif defined(CONFIG_SOC_AU1550) .start = AU1550_PSC1_INT, .end = AU1550_PSC1_INT, #endif .flags = IORESOURCE_IRQ, }, [2] = { .start = DSCR_CMD0_PSC1_TX, .end = DSCR_CMD0_PSC1_TX, .flags = IORESOURCE_DMA, }, [3] = { .start = DSCR_CMD0_PSC1_RX, .end = DSCR_CMD0_PSC1_RX, .flags = IORESOURCE_DMA, }, }; static struct platform_device *au1xpsc_sample_ac97_dev; static int __init au1xpsc_sample_ac97_load(void) { int ret; #ifdef CONFIG_SOC_AU1200 unsigned long io; /* modify sys_pinfunc for AC97 on PSC1 */ io = au_readl(SYS_PINFUNC); io |= SYS_PINFUNC_P1C; io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B); au_writel(io, SYS_PINFUNC); au_sync(); #endif ret = -ENOMEM; /* setup PSC clock source for AC97 part: external clock provided * by codec. The psc-ac97.c driver depends on this setting! */ au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET); au_sync(); au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1); if (!au1xpsc_sample_ac97_dev) goto out; au1xpsc_sample_ac97_dev->resource = kmemdup(au1xpsc_psc1_res, sizeof(struct resource) * ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL); au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res); au1xpsc_sample_ac97_dev->id = 1; platform_set_drvdata(au1xpsc_sample_ac97_dev, &au1xpsc_sample_ac97_devdata); au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev; ret = platform_device_add(au1xpsc_sample_ac97_dev); if (ret) { platform_device_put(au1xpsc_sample_ac97_dev); au1xpsc_sample_ac97_dev = NULL; } out: return ret; } static void __exit au1xpsc_sample_ac97_exit(void) { platform_device_unregister(au1xpsc_sample_ac97_dev); } module_init(au1xpsc_sample_ac97_load); module_exit(au1xpsc_sample_ac97_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine"); MODULE_AUTHOR("Manuel Lauss ");