diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 19:19:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 19:19:22 -0500 |
commit | f1dd6ad599732fc89f36fdd65a2c2cf3c63a8711 (patch) | |
tree | 5092207128e47cba99dc0fe373fff6a36f4cb4b8 /sound | |
parent | 8d37a371b6869920e6c40c495c68eabba1ef3909 (diff) | |
parent | e10b234b3c4e255d3300a486c4ac15b43253ac6d (diff) |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (141 commits)
MIPS: Alchemy: defconfig updates
MIPS: Alchemy: Fix Au1100 ethernet build failure
MIPS: Alchemy: Repair db1500/bosporus builds
MIPS: ARC: Cleanup unused definitions from sgialib.h
MIPS: Cobalt: convert legacy port addresses to GT-64111 bus addresses
MIPS: Alchemy: use 36bit addresses for PCMCIA resources.
MIPS: Cobalt: Fix theoretical port aliasing issue
MIPS: Use ALIGN(x, bytes) instead of __ALIGN_MASK(x, bytes - 1)
MIPS: Crazy spinlock speed test.
MIPS: Optimize spinlocks.
MIPS: Alchemy: devboard PM needs to save CPLD registers.
MIPS: PowerTV: Eliminate duplicate opcode definition macros
MIPS: Lemote 2F: Move printks out of port_access_lock.
MIPS: PNX833x: Convert IRQ controller locks to raw spinlocks.
MIPS: Octeon: Replace spinlock with raw_spinlocks in dma-octeon.c.
MIPS: Octeon: Replace rwlocks in irq_chip handlers with raw_spinlocks.
MIPS: Octeon: Convert octeon_irq_msi_lock to raw spinlock.
MIPS: Loongson: Remove pointless sample_lock from oprofile code.
MIPS: SNI: Convert sni_rm200_i8259A_lock to raw spinlock.
MIPS: i8259: Convert IRQ controller lock to raw spinlock.
...
Diffstat (limited to 'sound')
-rw-r--r-- | sound/oss/au1550_ac97.c | 16 | ||||
-rw-r--r-- | sound/soc/au1x/Kconfig | 10 | ||||
-rw-r--r-- | sound/soc/au1x/Makefile | 4 | ||||
-rw-r--r-- | sound/soc/au1x/db1200.c | 141 | ||||
-rw-r--r-- | sound/soc/au1x/dbdma2.c | 14 | ||||
-rw-r--r-- | sound/soc/au1x/sample-ac97.c | 144 |
6 files changed, 165 insertions, 164 deletions
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index 4191acccbcdb..c1070e33b32f 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c | |||
@@ -614,7 +614,8 @@ start_adc(struct au1550_state *s) | |||
614 | /* Put two buffers on the ring to get things started. | 614 | /* Put two buffers on the ring to get things started. |
615 | */ | 615 | */ |
616 | for (i=0; i<2; i++) { | 616 | for (i=0; i<2; i++) { |
617 | au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize); | 617 | au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn), |
618 | db->dma_fragsize, DDMA_FLAGS_IE); | ||
618 | 619 | ||
619 | db->nextIn += db->dma_fragsize; | 620 | db->nextIn += db->dma_fragsize; |
620 | if (db->nextIn >= db->rawbuf + db->dmasize) | 621 | if (db->nextIn >= db->rawbuf + db->dmasize) |
@@ -732,8 +733,9 @@ static void dac_dma_interrupt(int irq, void *dev_id) | |||
732 | db->dma_qcount--; | 733 | db->dma_qcount--; |
733 | 734 | ||
734 | if (db->count >= db->fragsize) { | 735 | if (db->count >= db->fragsize) { |
735 | if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, | 736 | if (au1xxx_dbdma_put_source(db->dmanr, |
736 | db->fragsize) == 0) { | 737 | virt_to_phys(db->nextOut), db->fragsize, |
738 | DDMA_FLAGS_IE) == 0) { | ||
737 | err("qcount < 2 and no ring room!"); | 739 | err("qcount < 2 and no ring room!"); |
738 | } | 740 | } |
739 | db->nextOut += db->fragsize; | 741 | db->nextOut += db->fragsize; |
@@ -777,7 +779,8 @@ static void adc_dma_interrupt(int irq, void *dev_id) | |||
777 | 779 | ||
778 | /* Put a new empty buffer on the destination DMA. | 780 | /* Put a new empty buffer on the destination DMA. |
779 | */ | 781 | */ |
780 | au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize); | 782 | au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn), |
783 | dp->dma_fragsize, DDMA_FLAGS_IE); | ||
781 | 784 | ||
782 | dp->nextIn += dp->dma_fragsize; | 785 | dp->nextIn += dp->dma_fragsize; |
783 | if (dp->nextIn >= dp->rawbuf + dp->dmasize) | 786 | if (dp->nextIn >= dp->rawbuf + dp->dmasize) |
@@ -1177,8 +1180,9 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) | |||
1177 | * we know the dma has stopped. | 1180 | * we know the dma has stopped. |
1178 | */ | 1181 | */ |
1179 | while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { | 1182 | while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { |
1180 | if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut, | 1183 | if (au1xxx_dbdma_put_source(db->dmanr, |
1181 | db->fragsize) == 0) { | 1184 | virt_to_phys(db->nextOut), db->fragsize, |
1185 | DDMA_FLAGS_IE) == 0) { | ||
1182 | err("qcount < 2 and no ring room!"); | 1186 | err("qcount < 2 and no ring room!"); |
1183 | } | 1187 | } |
1184 | db->nextOut += db->fragsize; | 1188 | db->nextOut += db->fragsize; |
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig index 410a893aa66b..4b67140fdec3 100644 --- a/sound/soc/au1x/Kconfig +++ b/sound/soc/au1x/Kconfig | |||
@@ -22,11 +22,13 @@ config SND_SOC_AU1XPSC_AC97 | |||
22 | ## | 22 | ## |
23 | ## Boards | 23 | ## Boards |
24 | ## | 24 | ## |
25 | config SND_SOC_SAMPLE_PSC_AC97 | 25 | config SND_SOC_DB1200 |
26 | tristate "Sample Au12x0/Au1550 PSC AC97 sound machine" | 26 | tristate "DB1200 AC97+I2S audio support" |
27 | depends on SND_SOC_AU1XPSC | 27 | depends on SND_SOC_AU1XPSC |
28 | select SND_SOC_AU1XPSC_AC97 | 28 | select SND_SOC_AU1XPSC_AC97 |
29 | select SND_SOC_AC97_CODEC | 29 | select SND_SOC_AC97_CODEC |
30 | select SND_SOC_AU1XPSC_I2S | ||
31 | select SND_SOC_WM8731 | ||
30 | help | 32 | help |
31 | This is a sample AC97 sound machine for use in Au12x0/Au1550 | 33 | Select this option to enable audio (AC97 or I2S) on the |
32 | based systems which have audio on PSC1 (e.g. Db1200 demoboard). | 34 | Alchemy/AMD/RMI DB1200 demoboard. |
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile index 6c6950b8003a..16873076e8c4 100644 --- a/sound/soc/au1x/Makefile +++ b/sound/soc/au1x/Makefile | |||
@@ -8,6 +8,6 @@ obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o | |||
8 | obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o | 8 | obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o |
9 | 9 | ||
10 | # Boards | 10 | # Boards |
11 | snd-soc-sample-ac97-objs := sample-ac97.o | 11 | snd-soc-db1200-objs := db1200.o |
12 | 12 | ||
13 | obj-$(CONFIG_SND_SOC_SAMPLE_PSC_AC97) += snd-soc-sample-ac97.o | 13 | obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o |
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c new file mode 100644 index 000000000000..cdf7be1b9b91 --- /dev/null +++ b/sound/soc/au1x/db1200.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * DB1200 ASoC audio fabric support code. | ||
3 | * | ||
4 | * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/moduleparam.h> | ||
10 | #include <linux/timer.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <sound/core.h> | ||
14 | #include <sound/pcm.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/soc-dapm.h> | ||
17 | #include <asm/mach-au1x00/au1000.h> | ||
18 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
19 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
20 | #include <asm/mach-db1x00/bcsr.h> | ||
21 | |||
22 | #include "../codecs/ac97.h" | ||
23 | #include "../codecs/wm8731.h" | ||
24 | #include "psc.h" | ||
25 | |||
26 | /*------------------------- AC97 PART ---------------------------*/ | ||
27 | |||
28 | static struct snd_soc_dai_link db1200_ac97_dai = { | ||
29 | .name = "AC97", | ||
30 | .stream_name = "AC97 HiFi", | ||
31 | .cpu_dai = &au1xpsc_ac97_dai, | ||
32 | .codec_dai = &ac97_dai, | ||
33 | }; | ||
34 | |||
35 | static struct snd_soc_card db1200_ac97_machine = { | ||
36 | .name = "DB1200_AC97", | ||
37 | .dai_link = &db1200_ac97_dai, | ||
38 | .num_links = 1, | ||
39 | .platform = &au1xpsc_soc_platform, | ||
40 | }; | ||
41 | |||
42 | static struct snd_soc_device db1200_ac97_devdata = { | ||
43 | .card = &db1200_ac97_machine, | ||
44 | .codec_dev = &soc_codec_dev_ac97, | ||
45 | }; | ||
46 | |||
47 | /*------------------------- I2S PART ---------------------------*/ | ||
48 | |||
49 | static int db1200_i2s_startup(struct snd_pcm_substream *substream) | ||
50 | { | ||
51 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
52 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; | ||
53 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | ||
54 | int ret; | ||
55 | |||
56 | /* WM8731 has its own 12MHz crystal */ | ||
57 | snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, | ||
58 | 12000000, SND_SOC_CLOCK_IN); | ||
59 | |||
60 | /* codec is bitclock and lrclk master */ | ||
61 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | | ||
62 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
63 | if (ret < 0) | ||
64 | goto out; | ||
65 | |||
66 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J | | ||
67 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
68 | if (ret < 0) | ||
69 | goto out; | ||
70 | |||
71 | ret = 0; | ||
72 | out: | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | static struct snd_soc_ops db1200_i2s_wm8731_ops = { | ||
77 | .startup = db1200_i2s_startup, | ||
78 | }; | ||
79 | |||
80 | static struct snd_soc_dai_link db1200_i2s_dai = { | ||
81 | .name = "WM8731", | ||
82 | .stream_name = "WM8731 PCM", | ||
83 | .cpu_dai = &au1xpsc_i2s_dai, | ||
84 | .codec_dai = &wm8731_dai, | ||
85 | .ops = &db1200_i2s_wm8731_ops, | ||
86 | }; | ||
87 | |||
88 | static struct snd_soc_card db1200_i2s_machine = { | ||
89 | .name = "DB1200_I2S", | ||
90 | .dai_link = &db1200_i2s_dai, | ||
91 | .num_links = 1, | ||
92 | .platform = &au1xpsc_soc_platform, | ||
93 | }; | ||
94 | |||
95 | static struct snd_soc_device db1200_i2s_devdata = { | ||
96 | .card = &db1200_i2s_machine, | ||
97 | .codec_dev = &soc_codec_dev_wm8731, | ||
98 | }; | ||
99 | |||
100 | /*------------------------- COMMON PART ---------------------------*/ | ||
101 | |||
102 | static struct platform_device *db1200_asoc_dev; | ||
103 | |||
104 | static int __init db1200_audio_load(void) | ||
105 | { | ||
106 | int ret; | ||
107 | |||
108 | ret = -ENOMEM; | ||
109 | db1200_asoc_dev = platform_device_alloc("soc-audio", -1); | ||
110 | if (!db1200_asoc_dev) | ||
111 | goto out; | ||
112 | |||
113 | /* DB1200 board setup set PSC1MUX to preferred audio device */ | ||
114 | if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) | ||
115 | platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata); | ||
116 | else | ||
117 | platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata); | ||
118 | |||
119 | db1200_ac97_devdata.dev = &db1200_asoc_dev->dev; | ||
120 | db1200_i2s_devdata.dev = &db1200_asoc_dev->dev; | ||
121 | ret = platform_device_add(db1200_asoc_dev); | ||
122 | |||
123 | if (ret) { | ||
124 | platform_device_put(db1200_asoc_dev); | ||
125 | db1200_asoc_dev = NULL; | ||
126 | } | ||
127 | out: | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | static void __exit db1200_audio_unload(void) | ||
132 | { | ||
133 | platform_device_unregister(db1200_asoc_dev); | ||
134 | } | ||
135 | |||
136 | module_init(db1200_audio_load); | ||
137 | module_exit(db1200_audio_unload); | ||
138 | |||
139 | MODULE_LICENSE("GPL"); | ||
140 | MODULE_DESCRIPTION("DB1200 ASoC audio support"); | ||
141 | MODULE_AUTHOR("Manuel Lauss"); | ||
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 19e4d37eba1c..6d9f4c624949 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
@@ -51,8 +51,8 @@ struct au1xpsc_audio_dmadata { | |||
51 | struct snd_pcm_substream *substream; | 51 | struct snd_pcm_substream *substream; |
52 | unsigned long curr_period; /* current segment DDMA is working on */ | 52 | unsigned long curr_period; /* current segment DDMA is working on */ |
53 | unsigned long q_period; /* queue period(s) */ | 53 | unsigned long q_period; /* queue period(s) */ |
54 | unsigned long dma_area; /* address of queued DMA area */ | 54 | dma_addr_t dma_area; /* address of queued DMA area */ |
55 | unsigned long dma_area_s; /* start address of DMA area */ | 55 | dma_addr_t dma_area_s; /* start address of DMA area */ |
56 | unsigned long pos; /* current byte position being played */ | 56 | unsigned long pos; /* current byte position being played */ |
57 | unsigned long periods; /* number of SG segments in total */ | 57 | unsigned long periods; /* number of SG segments in total */ |
58 | unsigned long period_bytes; /* size in bytes of one SG segment */ | 58 | unsigned long period_bytes; /* size in bytes of one SG segment */ |
@@ -94,8 +94,7 @@ static const struct snd_pcm_hardware au1xpsc_pcm_hardware = { | |||
94 | 94 | ||
95 | static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) | 95 | static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) |
96 | { | 96 | { |
97 | au1xxx_dbdma_put_source_flags(cd->ddma_chan, | 97 | au1xxx_dbdma_put_source(cd->ddma_chan, cd->dma_area, |
98 | (void *)phys_to_virt(cd->dma_area), | ||
99 | cd->period_bytes, DDMA_FLAGS_IE); | 98 | cd->period_bytes, DDMA_FLAGS_IE); |
100 | 99 | ||
101 | /* update next-to-queue period */ | 100 | /* update next-to-queue period */ |
@@ -109,9 +108,8 @@ static void au1x_pcm_queue_tx(struct au1xpsc_audio_dmadata *cd) | |||
109 | 108 | ||
110 | static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) | 109 | static void au1x_pcm_queue_rx(struct au1xpsc_audio_dmadata *cd) |
111 | { | 110 | { |
112 | au1xxx_dbdma_put_dest_flags(cd->ddma_chan, | 111 | au1xxx_dbdma_put_dest(cd->ddma_chan, cd->dma_area, |
113 | (void *)phys_to_virt(cd->dma_area), | 112 | cd->period_bytes, DDMA_FLAGS_IE); |
114 | cd->period_bytes, DDMA_FLAGS_IE); | ||
115 | 113 | ||
116 | /* update next-to-queue period */ | 114 | /* update next-to-queue period */ |
117 | ++cd->q_period; | 115 | ++cd->q_period; |
@@ -233,7 +231,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
233 | pcd->substream = substream; | 231 | pcd->substream = substream; |
234 | pcd->period_bytes = params_period_bytes(params); | 232 | pcd->period_bytes = params_period_bytes(params); |
235 | pcd->periods = params_periods(params); | 233 | pcd->periods = params_periods(params); |
236 | pcd->dma_area_s = pcd->dma_area = (unsigned long)runtime->dma_addr; | 234 | pcd->dma_area_s = pcd->dma_area = runtime->dma_addr; |
237 | pcd->q_period = 0; | 235 | pcd->q_period = 0; |
238 | pcd->curr_period = 0; | 236 | pcd->curr_period = 0; |
239 | pcd->pos = 0; | 237 | pcd->pos = 0; |
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c deleted file mode 100644 index 27683eb7905e..000000000000 --- a/sound/soc/au1x/sample-ac97.c +++ /dev/null | |||
@@ -1,144 +0,0 @@ | |||
1 | /* | ||
2 | * Sample Au12x0/Au1550 PSC AC97 sound machine. | ||
3 | * | ||
4 | * Copyright (c) 2007-2008 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms outlined in the file COPYING at the root of this | ||
8 | * source archive. | ||
9 | * | ||
10 | * This is a very generic AC97 sound machine driver for boards which | ||
11 | * have (AC97) audio at PSC1 (e.g. DB1200 demoboards). | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/timer.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <sound/core.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/soc.h> | ||
22 | #include <sound/soc-dapm.h> | ||
23 | #include <asm/mach-au1x00/au1000.h> | ||
24 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
25 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
26 | |||
27 | #include "../codecs/ac97.h" | ||
28 | #include "psc.h" | ||
29 | |||
30 | static int au1xpsc_sample_ac97_init(struct snd_soc_codec *codec) | ||
31 | { | ||
32 | snd_soc_dapm_sync(codec); | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = { | ||
37 | .name = "AC97", | ||
38 | .stream_name = "AC97 HiFi", | ||
39 | .cpu_dai = &au1xpsc_ac97_dai, /* see psc-ac97.c */ | ||
40 | .codec_dai = &ac97_dai, /* see codecs/ac97.c */ | ||
41 | .init = au1xpsc_sample_ac97_init, | ||
42 | .ops = NULL, | ||
43 | }; | ||
44 | |||
45 | static struct snd_soc_card au1xpsc_sample_ac97_machine = { | ||
46 | .name = "Au1xxx PSC AC97 Audio", | ||
47 | .dai_link = &au1xpsc_sample_ac97_dai, | ||
48 | .num_links = 1, | ||
49 | }; | ||
50 | |||
51 | static struct snd_soc_device au1xpsc_sample_ac97_devdata = { | ||
52 | .card = &au1xpsc_sample_ac97_machine, | ||
53 | .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ | ||
54 | .codec_dev = &soc_codec_dev_ac97, | ||
55 | }; | ||
56 | |||
57 | static struct resource au1xpsc_psc1_res[] = { | ||
58 | [0] = { | ||
59 | .start = CPHYSADDR(PSC1_BASE_ADDR), | ||
60 | .end = CPHYSADDR(PSC1_BASE_ADDR) + 0x000fffff, | ||
61 | .flags = IORESOURCE_MEM, | ||
62 | }, | ||
63 | [1] = { | ||
64 | #ifdef CONFIG_SOC_AU1200 | ||
65 | .start = AU1200_PSC1_INT, | ||
66 | .end = AU1200_PSC1_INT, | ||
67 | #elif defined(CONFIG_SOC_AU1550) | ||
68 | .start = AU1550_PSC1_INT, | ||
69 | .end = AU1550_PSC1_INT, | ||
70 | #endif | ||
71 | .flags = IORESOURCE_IRQ, | ||
72 | }, | ||
73 | [2] = { | ||
74 | .start = DSCR_CMD0_PSC1_TX, | ||
75 | .end = DSCR_CMD0_PSC1_TX, | ||
76 | .flags = IORESOURCE_DMA, | ||
77 | }, | ||
78 | [3] = { | ||
79 | .start = DSCR_CMD0_PSC1_RX, | ||
80 | .end = DSCR_CMD0_PSC1_RX, | ||
81 | .flags = IORESOURCE_DMA, | ||
82 | }, | ||
83 | }; | ||
84 | |||
85 | static struct platform_device *au1xpsc_sample_ac97_dev; | ||
86 | |||
87 | static int __init au1xpsc_sample_ac97_load(void) | ||
88 | { | ||
89 | int ret; | ||
90 | |||
91 | #ifdef CONFIG_SOC_AU1200 | ||
92 | unsigned long io; | ||
93 | |||
94 | /* modify sys_pinfunc for AC97 on PSC1 */ | ||
95 | io = au_readl(SYS_PINFUNC); | ||
96 | io |= SYS_PINFUNC_P1C; | ||
97 | io &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B); | ||
98 | au_writel(io, SYS_PINFUNC); | ||
99 | au_sync(); | ||
100 | #endif | ||
101 | |||
102 | ret = -ENOMEM; | ||
103 | |||
104 | /* setup PSC clock source for AC97 part: external clock provided | ||
105 | * by codec. The psc-ac97.c driver depends on this setting! | ||
106 | */ | ||
107 | au_writel(PSC_SEL_CLK_SERCLK, PSC1_BASE_ADDR + PSC_SEL_OFFSET); | ||
108 | au_sync(); | ||
109 | |||
110 | au1xpsc_sample_ac97_dev = platform_device_alloc("soc-audio", -1); | ||
111 | if (!au1xpsc_sample_ac97_dev) | ||
112 | goto out; | ||
113 | |||
114 | au1xpsc_sample_ac97_dev->resource = | ||
115 | kmemdup(au1xpsc_psc1_res, sizeof(struct resource) * | ||
116 | ARRAY_SIZE(au1xpsc_psc1_res), GFP_KERNEL); | ||
117 | au1xpsc_sample_ac97_dev->num_resources = ARRAY_SIZE(au1xpsc_psc1_res); | ||
118 | au1xpsc_sample_ac97_dev->id = 1; | ||
119 | |||
120 | platform_set_drvdata(au1xpsc_sample_ac97_dev, | ||
121 | &au1xpsc_sample_ac97_devdata); | ||
122 | au1xpsc_sample_ac97_devdata.dev = &au1xpsc_sample_ac97_dev->dev; | ||
123 | ret = platform_device_add(au1xpsc_sample_ac97_dev); | ||
124 | |||
125 | if (ret) { | ||
126 | platform_device_put(au1xpsc_sample_ac97_dev); | ||
127 | au1xpsc_sample_ac97_dev = NULL; | ||
128 | } | ||
129 | |||
130 | out: | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static void __exit au1xpsc_sample_ac97_exit(void) | ||
135 | { | ||
136 | platform_device_unregister(au1xpsc_sample_ac97_dev); | ||
137 | } | ||
138 | |||
139 | module_init(au1xpsc_sample_ac97_load); | ||
140 | module_exit(au1xpsc_sample_ac97_exit); | ||
141 | |||
142 | MODULE_LICENSE("GPL"); | ||
143 | MODULE_DESCRIPTION("Au1xxx PSC sample AC97 machine"); | ||
144 | MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); | ||