diff options
| -rw-r--r-- | sound/arm/aaci.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 21ff6296d16..24d3013c023 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 | */ |
| @@ -64,8 +66,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
| 64 | unsigned short val) | 66 | unsigned short val) |
| 65 | { | 67 | { |
| 66 | struct aaci *aaci = ac97->private_data; | 68 | struct aaci *aaci = ac97->private_data; |
| 69 | int timeout; | ||
| 67 | u32 v; | 70 | u32 v; |
| 68 | int timeout = 5000; | ||
| 69 | 71 | ||
| 70 | if (ac97->num >= 4) | 72 | if (ac97->num >= 4) |
| 71 | return; | 73 | return; |
| @@ -81,10 +83,13 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
| 81 | writel(val << 4, aaci->base + AACI_SL2TX); | 83 | writel(val << 4, aaci->base + AACI_SL2TX); |
| 82 | writel(reg << 12, aaci->base + AACI_SL1TX); | 84 | writel(reg << 12, aaci->base + AACI_SL1TX); |
| 83 | 85 | ||
| 84 | /* | 86 | /* Initially, wait one frame period */ |
| 85 | * Wait for the transmission of both slots to complete. | 87 | udelay(FRAME_PERIOD_US); |
| 86 | */ | 88 | |
| 89 | /* And then wait an additional eight frame periods for it to be sent */ | ||
| 90 | timeout = FRAME_PERIOD_US * 8; | ||
| 87 | do { | 91 | do { |
| 92 | udelay(1); | ||
| 88 | v = readl(aaci->base + AACI_SLFR); | 93 | v = readl(aaci->base + AACI_SLFR); |
| 89 | } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); | 94 | } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); |
| 90 | 95 | ||
| @@ -101,9 +106,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
| 101 | static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | 106 | static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) |
| 102 | { | 107 | { |
| 103 | struct aaci *aaci = ac97->private_data; | 108 | struct aaci *aaci = ac97->private_data; |
| 109 | int timeout, retries = 10; | ||
| 104 | u32 v; | 110 | u32 v; |
| 105 | int timeout = 5000; | ||
| 106 | int retries = 10; | ||
| 107 | 111 | ||
| 108 | if (ac97->num >= 4) | 112 | if (ac97->num >= 4) |
| 109 | return ~0; | 113 | return ~0; |
| @@ -117,10 +121,13 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
| 117 | */ | 121 | */ |
| 118 | writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); | 122 | writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); |
| 119 | 123 | ||
| 120 | /* | 124 | /* Initially, wait one frame period */ |
| 121 | * Wait for the transmission to complete. | 125 | udelay(FRAME_PERIOD_US); |
| 122 | */ | 126 | |
| 127 | /* And then wait an additional eight frame periods for it to be sent */ | ||
| 128 | timeout = FRAME_PERIOD_US * 8; | ||
| 123 | do { | 129 | do { |
| 130 | udelay(1); | ||
| 124 | v = readl(aaci->base + AACI_SLFR); | 131 | v = readl(aaci->base + AACI_SLFR); |
| 125 | } while ((v & SLFR_1TXB) && --timeout); | 132 | } while ((v & SLFR_1TXB) && --timeout); |
| 126 | 133 | ||
| @@ -130,17 +137,13 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
| 130 | goto out; | 137 | goto out; |
| 131 | } | 138 | } |
| 132 | 139 | ||
| 133 | /* | 140 | /* Now wait for the response frame */ |
| 134 | * Give the AC'97 codec more than enough time | 141 | udelay(FRAME_PERIOD_US); |
| 135 | * to respond. (42us = ~2 frames at 48kHz.) | ||
| 136 | */ | ||
| 137 | udelay(42); | ||
| 138 | 142 | ||
| 139 | /* | 143 | /* And then wait an additional eight frame periods for data */ |
| 140 | * Wait for slot 2 to indicate data. | 144 | timeout = FRAME_PERIOD_US * 8; |
| 141 | */ | ||
| 142 | timeout = 5000; | ||
| 143 | do { | 145 | do { |
| 146 | udelay(1); | ||
| 144 | cond_resched(); | 147 | cond_resched(); |
| 145 | v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); | 148 | v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); |
| 146 | } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); | 149 | } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); |
| @@ -179,6 +182,7 @@ aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask) | |||
| 179 | int timeout = 5000; | 182 | int timeout = 5000; |
| 180 | 183 | ||
| 181 | do { | 184 | do { |
| 185 | udelay(1); | ||
| 182 | val = readl(aacirun->base + AACI_SR); | 186 | val = readl(aacirun->base + AACI_SR); |
| 183 | } while (val & mask && timeout--); | 187 | } while (val & mask && timeout--); |
| 184 | } | 188 | } |
| @@ -874,7 +878,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) | |||
| 874 | * Give the AC'97 codec more than enough time | 878 | * Give the AC'97 codec more than enough time |
| 875 | * to wake up. (42us = ~2 frames at 48kHz.) | 879 | * to wake up. (42us = ~2 frames at 48kHz.) |
| 876 | */ | 880 | */ |
| 877 | udelay(42); | 881 | udelay(FRAME_PERIOD_US * 2); |
| 878 | 882 | ||
| 879 | ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); | 883 | ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); |
| 880 | if (ret) | 884 | if (ret) |
