aboutsummaryrefslogtreecommitdiffstats
path: root/sound/arm/aaci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/arm/aaci.c')
-rw-r--r--sound/arm/aaci.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 91acc9a243ec..7c1fc64cb53d 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -30,6 +30,8 @@
30 30
31#define DRIVER_NAME "aaci-pl041" 31#define DRIVER_NAME "aaci-pl041"
32 32
33#define FRAME_PERIOD_US 21
34
33/* 35/*
34 * PM support is not complete. Turn it off. 36 * PM support is not complete. Turn it off.
35 */ 37 */
@@ -48,7 +50,11 @@ static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
48 if (v & SLFR_1RXV) 50 if (v & SLFR_1RXV)
49 readl(aaci->base + AACI_SL1RX); 51 readl(aaci->base + AACI_SL1RX);
50 52
51 writel(maincr, aaci->base + AACI_MAINCR); 53 if (maincr != readl(aaci->base + AACI_MAINCR)) {
54 writel(maincr, aaci->base + AACI_MAINCR);
55 readl(aaci->base + AACI_MAINCR);
56 udelay(1);
57 }
52} 58}
53 59
54/* 60/*
@@ -64,8 +70,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
64 unsigned short val) 70 unsigned short val)
65{ 71{
66 struct aaci *aaci = ac97->private_data; 72 struct aaci *aaci = ac97->private_data;
73 int timeout;
67 u32 v; 74 u32 v;
68 int timeout = 5000;
69 75
70 if (ac97->num >= 4) 76 if (ac97->num >= 4)
71 return; 77 return;
@@ -81,14 +87,17 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
81 writel(val << 4, aaci->base + AACI_SL2TX); 87 writel(val << 4, aaci->base + AACI_SL2TX);
82 writel(reg << 12, aaci->base + AACI_SL1TX); 88 writel(reg << 12, aaci->base + AACI_SL1TX);
83 89
84 /* 90 /* Initially, wait one frame period */
85 * Wait for the transmission of both slots to complete. 91 udelay(FRAME_PERIOD_US);
86 */ 92
93 /* And then wait an additional eight frame periods for it to be sent */
94 timeout = FRAME_PERIOD_US * 8;
87 do { 95 do {
96 udelay(1);
88 v = readl(aaci->base + AACI_SLFR); 97 v = readl(aaci->base + AACI_SLFR);
89 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); 98 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
90 99
91 if (!timeout) 100 if (v & (SLFR_1TXB|SLFR_2TXB))
92 dev_err(&aaci->dev->dev, 101 dev_err(&aaci->dev->dev,
93 "timeout waiting for write to complete\n"); 102 "timeout waiting for write to complete\n");
94 103
@@ -101,9 +110,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
101static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) 110static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
102{ 111{
103 struct aaci *aaci = ac97->private_data; 112 struct aaci *aaci = ac97->private_data;
113 int timeout, retries = 10;
104 u32 v; 114 u32 v;
105 int timeout = 5000;
106 int retries = 10;
107 115
108 if (ac97->num >= 4) 116 if (ac97->num >= 4)
109 return ~0; 117 return ~0;
@@ -117,35 +125,34 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
117 */ 125 */
118 writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); 126 writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
119 127
120 /* 128 /* Initially, wait one frame period */
121 * Wait for the transmission to complete. 129 udelay(FRAME_PERIOD_US);
122 */ 130
131 /* And then wait an additional eight frame periods for it to be sent */
132 timeout = FRAME_PERIOD_US * 8;
123 do { 133 do {
134 udelay(1);
124 v = readl(aaci->base + AACI_SLFR); 135 v = readl(aaci->base + AACI_SLFR);
125 } while ((v & SLFR_1TXB) && --timeout); 136 } while ((v & SLFR_1TXB) && --timeout);
126 137
127 if (!timeout) { 138 if (v & SLFR_1TXB) {
128 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n"); 139 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
129 v = ~0; 140 v = ~0;
130 goto out; 141 goto out;
131 } 142 }
132 143
133 /* 144 /* Now wait for the response frame */
134 * Give the AC'97 codec more than enough time 145 udelay(FRAME_PERIOD_US);
135 * to respond. (42us = ~2 frames at 48kHz.)
136 */
137 udelay(42);
138 146
139 /* 147 /* And then wait an additional eight frame periods for data */
140 * Wait for slot 2 to indicate data. 148 timeout = FRAME_PERIOD_US * 8;
141 */
142 timeout = 5000;
143 do { 149 do {
150 udelay(1);
144 cond_resched(); 151 cond_resched();
145 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); 152 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
146 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); 153 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
147 154
148 if (!timeout) { 155 if (v != (SLFR_1RXV|SLFR_2RXV)) {
149 dev_err(&aaci->dev->dev, "timeout on RX valid\n"); 156 dev_err(&aaci->dev->dev, "timeout on RX valid\n");
150 v = ~0; 157 v = ~0;
151 goto out; 158 goto out;
@@ -179,6 +186,7 @@ aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
179 int timeout = 5000; 186 int timeout = 5000;
180 187
181 do { 188 do {
189 udelay(1);
182 val = readl(aacirun->base + AACI_SR); 190 val = readl(aacirun->base + AACI_SR);
183 } while (val & mask && timeout--); 191 } while (val & mask && timeout--);
184} 192}
@@ -874,7 +882,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
874 * Give the AC'97 codec more than enough time 882 * Give the AC'97 codec more than enough time
875 * to wake up. (42us = ~2 frames at 48kHz.) 883 * to wake up. (42us = ~2 frames at 48kHz.)
876 */ 884 */
877 udelay(42); 885 udelay(FRAME_PERIOD_US * 2);
878 886
879 ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); 887 ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
880 if (ret) 888 if (ret)
@@ -989,6 +997,8 @@ static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
989 * disabling the channel doesn't clear the FIFO. 997 * disabling the channel doesn't clear the FIFO.
990 */ 998 */
991 writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR); 999 writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR);
1000 readl(aaci->base + AACI_MAINCR);
1001 udelay(1);
992 writel(aaci->maincr, aaci->base + AACI_MAINCR); 1002 writel(aaci->maincr, aaci->base + AACI_MAINCR);
993 1003
994 /* 1004 /*