aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c791
1 files changed, 605 insertions, 186 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index e664b912d7bb..e1d0440fd4a8 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -23,68 +23,102 @@
23#include <linux/clk.h> 23#include <linux/clk.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/slab.h>
26 27
27#include <mach/dma.h> 28#include <plat/dma.h>
28#include <mach/mcbsp.h> 29#include <plat/mcbsp.h>
30
31#include "../mach-omap2/cm-regbits-34xx.h"
29 32
30struct omap_mcbsp **mcbsp_ptr; 33struct omap_mcbsp **mcbsp_ptr;
31int omap_mcbsp_count; 34int omap_mcbsp_count, omap_mcbsp_cache_size;
32 35
33void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val) 36void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
34{ 37{
35 if (cpu_class_is_omap1() || cpu_is_omap2420()) 38 if (cpu_class_is_omap1()) {
36 __raw_writew((u16)val, io_base + reg); 39 ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
37 else 40 __raw_writew((u16)val, mcbsp->io_base + reg);
38 __raw_writel(val, io_base + reg); 41 } else if (cpu_is_omap2420()) {
42 ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
43 __raw_writew((u16)val, mcbsp->io_base + reg);
44 } else {
45 ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
46 __raw_writel(val, mcbsp->io_base + reg);
47 }
39} 48}
40 49
41int omap_mcbsp_read(void __iomem *io_base, u16 reg) 50int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
42{ 51{
43 if (cpu_class_is_omap1() || cpu_is_omap2420()) 52 if (cpu_class_is_omap1()) {
44 return __raw_readw(io_base + reg); 53 return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
45 else 54 ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
46 return __raw_readl(io_base + reg); 55 } else if (cpu_is_omap2420()) {
56 return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
57 ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
58 } else {
59 return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
60 ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
61 }
62}
63
64#ifdef CONFIG_ARCH_OMAP3
65void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
66{
67 __raw_writel(val, mcbsp->st_data->io_base_st + reg);
47} 68}
48 69
49#define OMAP_MCBSP_READ(base, reg) \ 70int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
50 omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg) 71{
51#define OMAP_MCBSP_WRITE(base, reg, val) \ 72 return __raw_readl(mcbsp->st_data->io_base_st + reg);
52 omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val) 73}
74#endif
75
76#define MCBSP_READ(mcbsp, reg) \
77 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
78#define MCBSP_WRITE(mcbsp, reg, val) \
79 omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
80#define MCBSP_READ_CACHE(mcbsp, reg) \
81 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
53 82
54#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count) 83#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
55#define id_to_mcbsp_ptr(id) mcbsp_ptr[id]; 84#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
56 85
86#define MCBSP_ST_READ(mcbsp, reg) \
87 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
88#define MCBSP_ST_WRITE(mcbsp, reg, val) \
89 omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
90
57static void omap_mcbsp_dump_reg(u8 id) 91static void omap_mcbsp_dump_reg(u8 id)
58{ 92{
59 struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id); 93 struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
60 94
61 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id); 95 dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
62 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n", 96 dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
63 OMAP_MCBSP_READ(mcbsp->io_base, DRR2)); 97 MCBSP_READ(mcbsp, DRR2));
64 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n", 98 dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
65 OMAP_MCBSP_READ(mcbsp->io_base, DRR1)); 99 MCBSP_READ(mcbsp, DRR1));
66 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n", 100 dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
67 OMAP_MCBSP_READ(mcbsp->io_base, DXR2)); 101 MCBSP_READ(mcbsp, DXR2));
68 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n", 102 dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
69 OMAP_MCBSP_READ(mcbsp->io_base, DXR1)); 103 MCBSP_READ(mcbsp, DXR1));
70 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n", 104 dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
71 OMAP_MCBSP_READ(mcbsp->io_base, SPCR2)); 105 MCBSP_READ(mcbsp, SPCR2));
72 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n", 106 dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
73 OMAP_MCBSP_READ(mcbsp->io_base, SPCR1)); 107 MCBSP_READ(mcbsp, SPCR1));
74 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n", 108 dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
75 OMAP_MCBSP_READ(mcbsp->io_base, RCR2)); 109 MCBSP_READ(mcbsp, RCR2));
76 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n", 110 dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
77 OMAP_MCBSP_READ(mcbsp->io_base, RCR1)); 111 MCBSP_READ(mcbsp, RCR1));
78 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n", 112 dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
79 OMAP_MCBSP_READ(mcbsp->io_base, XCR2)); 113 MCBSP_READ(mcbsp, XCR2));
80 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n", 114 dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
81 OMAP_MCBSP_READ(mcbsp->io_base, XCR1)); 115 MCBSP_READ(mcbsp, XCR1));
82 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n", 116 dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
83 OMAP_MCBSP_READ(mcbsp->io_base, SRGR2)); 117 MCBSP_READ(mcbsp, SRGR2));
84 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n", 118 dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
85 OMAP_MCBSP_READ(mcbsp->io_base, SRGR1)); 119 MCBSP_READ(mcbsp, SRGR1));
86 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n", 120 dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
87 OMAP_MCBSP_READ(mcbsp->io_base, PCR0)); 121 MCBSP_READ(mcbsp, PCR0));
88 dev_dbg(mcbsp->dev, "***********************\n"); 122 dev_dbg(mcbsp->dev, "***********************\n");
89} 123}
90 124
@@ -93,15 +127,14 @@ static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
93 struct omap_mcbsp *mcbsp_tx = dev_id; 127 struct omap_mcbsp *mcbsp_tx = dev_id;
94 u16 irqst_spcr2; 128 u16 irqst_spcr2;
95 129
96 irqst_spcr2 = OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2); 130 irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
97 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2); 131 dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
98 132
99 if (irqst_spcr2 & XSYNC_ERR) { 133 if (irqst_spcr2 & XSYNC_ERR) {
100 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n", 134 dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
101 irqst_spcr2); 135 irqst_spcr2);
102 /* Writing zero to XSYNC_ERR clears the IRQ */ 136 /* Writing zero to XSYNC_ERR clears the IRQ */
103 OMAP_MCBSP_WRITE(mcbsp_tx->io_base, SPCR2, 137 MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
104 irqst_spcr2 & ~(XSYNC_ERR));
105 } else { 138 } else {
106 complete(&mcbsp_tx->tx_irq_completion); 139 complete(&mcbsp_tx->tx_irq_completion);
107 } 140 }
@@ -114,15 +147,14 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
114 struct omap_mcbsp *mcbsp_rx = dev_id; 147 struct omap_mcbsp *mcbsp_rx = dev_id;
115 u16 irqst_spcr1; 148 u16 irqst_spcr1;
116 149
117 irqst_spcr1 = OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR1); 150 irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
118 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1); 151 dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
119 152
120 if (irqst_spcr1 & RSYNC_ERR) { 153 if (irqst_spcr1 & RSYNC_ERR) {
121 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n", 154 dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
122 irqst_spcr1); 155 irqst_spcr1);
123 /* Writing zero to RSYNC_ERR clears the IRQ */ 156 /* Writing zero to RSYNC_ERR clears the IRQ */
124 OMAP_MCBSP_WRITE(mcbsp_rx->io_base, SPCR1, 157 MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
125 irqst_spcr1 & ~(RSYNC_ERR));
126 } else { 158 } else {
127 complete(&mcbsp_rx->tx_irq_completion); 159 complete(&mcbsp_rx->tx_irq_completion);
128 } 160 }
@@ -135,7 +167,7 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
135 struct omap_mcbsp *mcbsp_dma_tx = data; 167 struct omap_mcbsp *mcbsp_dma_tx = data;
136 168
137 dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n", 169 dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
138 OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); 170 MCBSP_READ(mcbsp_dma_tx, SPCR2));
139 171
140 /* We can free the channels */ 172 /* We can free the channels */
141 omap_free_dma(mcbsp_dma_tx->dma_tx_lch); 173 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
@@ -149,7 +181,7 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
149 struct omap_mcbsp *mcbsp_dma_rx = data; 181 struct omap_mcbsp *mcbsp_dma_rx = data;
150 182
151 dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n", 183 dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
152 OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); 184 MCBSP_READ(mcbsp_dma_rx, SPCR2));
153 185
154 /* We can free the channels */ 186 /* We can free the channels */
155 omap_free_dma(mcbsp_dma_rx->dma_rx_lch); 187 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
@@ -167,7 +199,6 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
167void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) 199void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
168{ 200{
169 struct omap_mcbsp *mcbsp; 201 struct omap_mcbsp *mcbsp;
170 void __iomem *io_base;
171 202
172 if (!omap_mcbsp_check_valid_id(id)) { 203 if (!omap_mcbsp_check_valid_id(id)) {
173 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 204 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -175,30 +206,280 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
175 } 206 }
176 mcbsp = id_to_mcbsp_ptr(id); 207 mcbsp = id_to_mcbsp_ptr(id);
177 208
178 io_base = mcbsp->io_base;
179 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n", 209 dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
180 mcbsp->id, mcbsp->phys_base); 210 mcbsp->id, mcbsp->phys_base);
181 211
182 /* We write the given config */ 212 /* We write the given config */
183 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); 213 MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
184 OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1); 214 MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
185 OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2); 215 MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
186 OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1); 216 MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
187 OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2); 217 MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
188 OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1); 218 MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
189 OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2); 219 MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
190 OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1); 220 MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
191 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2); 221 MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
192 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1); 222 MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
193 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0); 223 MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
194 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { 224 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
195 OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr); 225 MCBSP_WRITE(mcbsp, XCCR, config->xccr);
196 OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr); 226 MCBSP_WRITE(mcbsp, RCCR, config->rccr);
197 } 227 }
198} 228}
199EXPORT_SYMBOL(omap_mcbsp_config); 229EXPORT_SYMBOL(omap_mcbsp_config);
200 230
201#ifdef CONFIG_ARCH_OMAP34XX 231#ifdef CONFIG_ARCH_OMAP3
232static void omap_st_on(struct omap_mcbsp *mcbsp)
233{
234 unsigned int w;
235
236 /*
237 * Sidetone uses McBSP ICLK - which must not idle when sidetones
238 * are enabled or sidetones start sounding ugly.
239 */
240 w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
241 w &= ~(1 << (mcbsp->id - 2));
242 cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
243
244 /* Enable McBSP Sidetone */
245 w = MCBSP_READ(mcbsp, SSELCR);
246 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
247
248 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
249 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
250
251 /* Enable Sidetone from Sidetone Core */
252 w = MCBSP_ST_READ(mcbsp, SSELCR);
253 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
254}
255
256static void omap_st_off(struct omap_mcbsp *mcbsp)
257{
258 unsigned int w;
259
260 w = MCBSP_ST_READ(mcbsp, SSELCR);
261 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
262
263 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
264 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
265
266 w = MCBSP_READ(mcbsp, SSELCR);
267 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
268
269 w = cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
270 w |= 1 << (mcbsp->id - 2);
271 cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
272}
273
274static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
275{
276 u16 val, i;
277
278 val = MCBSP_ST_READ(mcbsp, SYSCONFIG);
279 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE));
280
281 val = MCBSP_ST_READ(mcbsp, SSELCR);
282
283 if (val & ST_COEFFWREN)
284 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
285
286 MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
287
288 for (i = 0; i < 128; i++)
289 MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
290
291 i = 0;
292
293 val = MCBSP_ST_READ(mcbsp, SSELCR);
294 while (!(val & ST_COEFFWRDONE) && (++i < 1000))
295 val = MCBSP_ST_READ(mcbsp, SSELCR);
296
297 MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
298
299 if (i == 1000)
300 dev_err(mcbsp->dev, "McBSP FIR load error!\n");
301}
302
303static void omap_st_chgain(struct omap_mcbsp *mcbsp)
304{
305 u16 w;
306 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
307
308 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
309 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
310
311 w = MCBSP_ST_READ(mcbsp, SSELCR);
312
313 MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
314 ST_CH1GAIN(st_data->ch1gain));
315}
316
317int omap_st_set_chgain(unsigned int id, int channel, s16 chgain)
318{
319 struct omap_mcbsp *mcbsp;
320 struct omap_mcbsp_st_data *st_data;
321 int ret = 0;
322
323 if (!omap_mcbsp_check_valid_id(id)) {
324 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
325 return -ENODEV;
326 }
327
328 mcbsp = id_to_mcbsp_ptr(id);
329 st_data = mcbsp->st_data;
330
331 if (!st_data)
332 return -ENOENT;
333
334 spin_lock_irq(&mcbsp->lock);
335 if (channel == 0)
336 st_data->ch0gain = chgain;
337 else if (channel == 1)
338 st_data->ch1gain = chgain;
339 else
340 ret = -EINVAL;
341
342 if (st_data->enabled)
343 omap_st_chgain(mcbsp);
344 spin_unlock_irq(&mcbsp->lock);
345
346 return ret;
347}
348EXPORT_SYMBOL(omap_st_set_chgain);
349
350int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain)
351{
352 struct omap_mcbsp *mcbsp;
353 struct omap_mcbsp_st_data *st_data;
354 int ret = 0;
355
356 if (!omap_mcbsp_check_valid_id(id)) {
357 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
358 return -ENODEV;
359 }
360
361 mcbsp = id_to_mcbsp_ptr(id);
362 st_data = mcbsp->st_data;
363
364 if (!st_data)
365 return -ENOENT;
366
367 spin_lock_irq(&mcbsp->lock);
368 if (channel == 0)
369 *chgain = st_data->ch0gain;
370 else if (channel == 1)
371 *chgain = st_data->ch1gain;
372 else
373 ret = -EINVAL;
374 spin_unlock_irq(&mcbsp->lock);
375
376 return ret;
377}
378EXPORT_SYMBOL(omap_st_get_chgain);
379
380static int omap_st_start(struct omap_mcbsp *mcbsp)
381{
382 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
383
384 if (st_data && st_data->enabled && !st_data->running) {
385 omap_st_fir_write(mcbsp, st_data->taps);
386 omap_st_chgain(mcbsp);
387
388 if (!mcbsp->free) {
389 omap_st_on(mcbsp);
390 st_data->running = 1;
391 }
392 }
393
394 return 0;
395}
396
397int omap_st_enable(unsigned int id)
398{
399 struct omap_mcbsp *mcbsp;
400 struct omap_mcbsp_st_data *st_data;
401
402 if (!omap_mcbsp_check_valid_id(id)) {
403 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
404 return -ENODEV;
405 }
406
407 mcbsp = id_to_mcbsp_ptr(id);
408 st_data = mcbsp->st_data;
409
410 if (!st_data)
411 return -ENODEV;
412
413 spin_lock_irq(&mcbsp->lock);
414 st_data->enabled = 1;
415 omap_st_start(mcbsp);
416 spin_unlock_irq(&mcbsp->lock);
417
418 return 0;
419}
420EXPORT_SYMBOL(omap_st_enable);
421
422static int omap_st_stop(struct omap_mcbsp *mcbsp)
423{
424 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
425
426 if (st_data && st_data->running) {
427 if (!mcbsp->free) {
428 omap_st_off(mcbsp);
429 st_data->running = 0;
430 }
431 }
432
433 return 0;
434}
435
436int omap_st_disable(unsigned int id)
437{
438 struct omap_mcbsp *mcbsp;
439 struct omap_mcbsp_st_data *st_data;
440 int ret = 0;
441
442 if (!omap_mcbsp_check_valid_id(id)) {
443 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
444 return -ENODEV;
445 }
446
447 mcbsp = id_to_mcbsp_ptr(id);
448 st_data = mcbsp->st_data;
449
450 if (!st_data)
451 return -ENODEV;
452
453 spin_lock_irq(&mcbsp->lock);
454 omap_st_stop(mcbsp);
455 st_data->enabled = 0;
456 spin_unlock_irq(&mcbsp->lock);
457
458 return ret;
459}
460EXPORT_SYMBOL(omap_st_disable);
461
462int omap_st_is_enabled(unsigned int id)
463{
464 struct omap_mcbsp *mcbsp;
465 struct omap_mcbsp_st_data *st_data;
466
467 if (!omap_mcbsp_check_valid_id(id)) {
468 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
469 return -ENODEV;
470 }
471
472 mcbsp = id_to_mcbsp_ptr(id);
473 st_data = mcbsp->st_data;
474
475 if (!st_data)
476 return -ENODEV;
477
478
479 return st_data->enabled;
480}
481EXPORT_SYMBOL(omap_st_is_enabled);
482
202/* 483/*
203 * omap_mcbsp_set_tx_threshold configures how to deal 484 * omap_mcbsp_set_tx_threshold configures how to deal
204 * with transmit threshold. the threshold value and handler can be 485 * with transmit threshold. the threshold value and handler can be
@@ -207,7 +488,6 @@ EXPORT_SYMBOL(omap_mcbsp_config);
207void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) 488void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
208{ 489{
209 struct omap_mcbsp *mcbsp; 490 struct omap_mcbsp *mcbsp;
210 void __iomem *io_base;
211 491
212 if (!cpu_is_omap34xx()) 492 if (!cpu_is_omap34xx())
213 return; 493 return;
@@ -217,9 +497,8 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
217 return; 497 return;
218 } 498 }
219 mcbsp = id_to_mcbsp_ptr(id); 499 mcbsp = id_to_mcbsp_ptr(id);
220 io_base = mcbsp->io_base;
221 500
222 OMAP_MCBSP_WRITE(io_base, THRSH2, threshold); 501 MCBSP_WRITE(mcbsp, THRSH2, threshold);
223} 502}
224EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold); 503EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
225 504
@@ -231,7 +510,6 @@ EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
231void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) 510void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
232{ 511{
233 struct omap_mcbsp *mcbsp; 512 struct omap_mcbsp *mcbsp;
234 void __iomem *io_base;
235 513
236 if (!cpu_is_omap34xx()) 514 if (!cpu_is_omap34xx())
237 return; 515 return;
@@ -241,9 +519,8 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
241 return; 519 return;
242 } 520 }
243 mcbsp = id_to_mcbsp_ptr(id); 521 mcbsp = id_to_mcbsp_ptr(id);
244 io_base = mcbsp->io_base;
245 522
246 OMAP_MCBSP_WRITE(io_base, THRSH1, threshold); 523 MCBSP_WRITE(mcbsp, THRSH1, threshold);
247} 524}
248EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); 525EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
249 526
@@ -298,9 +575,7 @@ int omap_mcbsp_get_dma_op_mode(unsigned int id)
298 } 575 }
299 mcbsp = id_to_mcbsp_ptr(id); 576 mcbsp = id_to_mcbsp_ptr(id);
300 577
301 spin_lock_irq(&mcbsp->lock);
302 dma_op_mode = mcbsp->dma_op_mode; 578 dma_op_mode = mcbsp->dma_op_mode;
303 spin_unlock_irq(&mcbsp->lock);
304 579
305 return dma_op_mode; 580 return dma_op_mode;
306} 581}
@@ -315,21 +590,18 @@ static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
315 if (cpu_is_omap34xx()) { 590 if (cpu_is_omap34xx()) {
316 u16 syscon; 591 u16 syscon;
317 592
318 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON); 593 syscon = MCBSP_READ(mcbsp, SYSCON);
319 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); 594 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
320 595
321 spin_lock_irq(&mcbsp->lock);
322 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { 596 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
323 syscon |= (ENAWAKEUP | SIDLEMODE(0x02) | 597 syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
324 CLOCKACTIVITY(0x02)); 598 CLOCKACTIVITY(0x02));
325 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 599 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
326 XRDYEN | RRDYEN);
327 } else { 600 } else {
328 syscon |= SIDLEMODE(0x01); 601 syscon |= SIDLEMODE(0x01);
329 } 602 }
330 spin_unlock_irq(&mcbsp->lock);
331 603
332 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); 604 MCBSP_WRITE(mcbsp, SYSCON, syscon);
333 } 605 }
334} 606}
335 607
@@ -341,7 +613,7 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
341 if (cpu_is_omap34xx()) { 613 if (cpu_is_omap34xx()) {
342 u16 syscon; 614 u16 syscon;
343 615
344 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON); 616 syscon = MCBSP_READ(mcbsp, SYSCON);
345 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); 617 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
346 /* 618 /*
347 * HW bug workaround - If no_idle mode is taken, we need to 619 * HW bug workaround - If no_idle mode is taken, we need to
@@ -349,17 +621,19 @@ static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
349 * device will not hit retention anymore. 621 * device will not hit retention anymore.
350 */ 622 */
351 syscon |= SIDLEMODE(0x02); 623 syscon |= SIDLEMODE(0x02);
352 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); 624 MCBSP_WRITE(mcbsp, SYSCON, syscon);
353 625
354 syscon &= ~(SIDLEMODE(0x03)); 626 syscon &= ~(SIDLEMODE(0x03));
355 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon); 627 MCBSP_WRITE(mcbsp, SYSCON, syscon);
356 628
357 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0); 629 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
358 } 630 }
359} 631}
360#else 632#else
361static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {} 633static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
362static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {} 634static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
635static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
636static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
363#endif 637#endif
364 638
365/* 639/*
@@ -396,6 +670,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
396int omap_mcbsp_request(unsigned int id) 670int omap_mcbsp_request(unsigned int id)
397{ 671{
398 struct omap_mcbsp *mcbsp; 672 struct omap_mcbsp *mcbsp;
673 void *reg_cache;
399 int err; 674 int err;
400 675
401 if (!omap_mcbsp_check_valid_id(id)) { 676 if (!omap_mcbsp_check_valid_id(id)) {
@@ -404,15 +679,21 @@ int omap_mcbsp_request(unsigned int id)
404 } 679 }
405 mcbsp = id_to_mcbsp_ptr(id); 680 mcbsp = id_to_mcbsp_ptr(id);
406 681
682 reg_cache = kzalloc(omap_mcbsp_cache_size, GFP_KERNEL);
683 if (!reg_cache) {
684 return -ENOMEM;
685 }
686
407 spin_lock(&mcbsp->lock); 687 spin_lock(&mcbsp->lock);
408 if (!mcbsp->free) { 688 if (!mcbsp->free) {
409 dev_err(mcbsp->dev, "McBSP%d is currently in use\n", 689 dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
410 mcbsp->id); 690 mcbsp->id);
411 spin_unlock(&mcbsp->lock); 691 err = -EBUSY;
412 return -EBUSY; 692 goto err_kfree;
413 } 693 }
414 694
415 mcbsp->free = 0; 695 mcbsp->free = 0;
696 mcbsp->reg_cache = reg_cache;
416 spin_unlock(&mcbsp->lock); 697 spin_unlock(&mcbsp->lock);
417 698
418 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) 699 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
@@ -428,8 +709,8 @@ int omap_mcbsp_request(unsigned int id)
428 * Make sure that transmitter, receiver and sample-rate generator are 709 * Make sure that transmitter, receiver and sample-rate generator are
429 * not running before activating IRQs. 710 * not running before activating IRQs.
430 */ 711 */
431 OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0); 712 MCBSP_WRITE(mcbsp, SPCR1, 0);
432 OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0); 713 MCBSP_WRITE(mcbsp, SPCR2, 0);
433 714
434 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { 715 if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
435 /* We need to get IRQs here */ 716 /* We need to get IRQs here */
@@ -440,7 +721,7 @@ int omap_mcbsp_request(unsigned int id)
440 dev_err(mcbsp->dev, "Unable to request TX IRQ %d " 721 dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
441 "for McBSP%d\n", mcbsp->tx_irq, 722 "for McBSP%d\n", mcbsp->tx_irq,
442 mcbsp->id); 723 mcbsp->id);
443 return err; 724 goto err_clk_disable;
444 } 725 }
445 726
446 init_completion(&mcbsp->rx_irq_completion); 727 init_completion(&mcbsp->rx_irq_completion);
@@ -450,18 +731,38 @@ int omap_mcbsp_request(unsigned int id)
450 dev_err(mcbsp->dev, "Unable to request RX IRQ %d " 731 dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
451 "for McBSP%d\n", mcbsp->rx_irq, 732 "for McBSP%d\n", mcbsp->rx_irq,
452 mcbsp->id); 733 mcbsp->id);
453 free_irq(mcbsp->tx_irq, (void *)mcbsp); 734 goto err_free_irq;
454 return err;
455 } 735 }
456 } 736 }
457 737
458 return 0; 738 return 0;
739err_free_irq:
740 free_irq(mcbsp->tx_irq, (void *)mcbsp);
741err_clk_disable:
742 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
743 mcbsp->pdata->ops->free(id);
744
745 /* Do procedure specific to omap34xx arch, if applicable */
746 omap34xx_mcbsp_free(mcbsp);
747
748 clk_disable(mcbsp->fclk);
749 clk_disable(mcbsp->iclk);
750
751 spin_lock(&mcbsp->lock);
752 mcbsp->free = 1;
753 mcbsp->reg_cache = NULL;
754err_kfree:
755 spin_unlock(&mcbsp->lock);
756 kfree(reg_cache);
757
758 return err;
459} 759}
460EXPORT_SYMBOL(omap_mcbsp_request); 760EXPORT_SYMBOL(omap_mcbsp_request);
461 761
462void omap_mcbsp_free(unsigned int id) 762void omap_mcbsp_free(unsigned int id)
463{ 763{
464 struct omap_mcbsp *mcbsp; 764 struct omap_mcbsp *mcbsp;
765 void *reg_cache;
465 766
466 if (!omap_mcbsp_check_valid_id(id)) { 767 if (!omap_mcbsp_check_valid_id(id)) {
467 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 768 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -484,16 +785,18 @@ void omap_mcbsp_free(unsigned int id)
484 free_irq(mcbsp->tx_irq, (void *)mcbsp); 785 free_irq(mcbsp->tx_irq, (void *)mcbsp);
485 } 786 }
486 787
487 spin_lock(&mcbsp->lock); 788 reg_cache = mcbsp->reg_cache;
488 if (mcbsp->free) {
489 dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
490 mcbsp->id);
491 spin_unlock(&mcbsp->lock);
492 return;
493 }
494 789
495 mcbsp->free = 1; 790 spin_lock(&mcbsp->lock);
791 if (mcbsp->free)
792 dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
793 else
794 mcbsp->free = 1;
795 mcbsp->reg_cache = NULL;
496 spin_unlock(&mcbsp->lock); 796 spin_unlock(&mcbsp->lock);
797
798 if (reg_cache)
799 kfree(reg_cache);
497} 800}
498EXPORT_SYMBOL(omap_mcbsp_free); 801EXPORT_SYMBOL(omap_mcbsp_free);
499 802
@@ -505,7 +808,6 @@ EXPORT_SYMBOL(omap_mcbsp_free);
505void omap_mcbsp_start(unsigned int id, int tx, int rx) 808void omap_mcbsp_start(unsigned int id, int tx, int rx)
506{ 809{
507 struct omap_mcbsp *mcbsp; 810 struct omap_mcbsp *mcbsp;
508 void __iomem *io_base;
509 int idle; 811 int idle;
510 u16 w; 812 u16 w;
511 813
@@ -514,28 +816,30 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
514 return; 816 return;
515 } 817 }
516 mcbsp = id_to_mcbsp_ptr(id); 818 mcbsp = id_to_mcbsp_ptr(id);
517 io_base = mcbsp->io_base;
518 819
519 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; 820 if (cpu_is_omap34xx())
520 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; 821 omap_st_start(mcbsp);
822
823 mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
824 mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
521 825
522 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) | 826 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
523 OMAP_MCBSP_READ(io_base, SPCR1)) & 1); 827 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
524 828
525 if (idle) { 829 if (idle) {
526 /* Start the sample generator */ 830 /* Start the sample generator */
527 w = OMAP_MCBSP_READ(io_base, SPCR2); 831 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
528 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); 832 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
529 } 833 }
530 834
531 /* Enable transmitter and receiver */ 835 /* Enable transmitter and receiver */
532 tx &= 1; 836 tx &= 1;
533 w = OMAP_MCBSP_READ(io_base, SPCR2); 837 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
534 OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx); 838 MCBSP_WRITE(mcbsp, SPCR2, w | tx);
535 839
536 rx &= 1; 840 rx &= 1;
537 w = OMAP_MCBSP_READ(io_base, SPCR1); 841 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
538 OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx); 842 MCBSP_WRITE(mcbsp, SPCR1, w | rx);
539 843
540 /* 844 /*
541 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec 845 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
@@ -547,18 +851,18 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
547 851
548 if (idle) { 852 if (idle) {
549 /* Start frame sync */ 853 /* Start frame sync */
550 w = OMAP_MCBSP_READ(io_base, SPCR2); 854 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
551 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); 855 MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
552 } 856 }
553 857
554 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 858 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
555 /* Release the transmitter and receiver */ 859 /* Release the transmitter and receiver */
556 w = OMAP_MCBSP_READ(io_base, XCCR); 860 w = MCBSP_READ_CACHE(mcbsp, XCCR);
557 w &= ~(tx ? XDISABLE : 0); 861 w &= ~(tx ? XDISABLE : 0);
558 OMAP_MCBSP_WRITE(io_base, XCCR, w); 862 MCBSP_WRITE(mcbsp, XCCR, w);
559 w = OMAP_MCBSP_READ(io_base, RCCR); 863 w = MCBSP_READ_CACHE(mcbsp, RCCR);
560 w &= ~(rx ? RDISABLE : 0); 864 w &= ~(rx ? RDISABLE : 0);
561 OMAP_MCBSP_WRITE(io_base, RCCR, w); 865 MCBSP_WRITE(mcbsp, RCCR, w);
562 } 866 }
563 867
564 /* Dump McBSP Regs */ 868 /* Dump McBSP Regs */
@@ -569,7 +873,6 @@ EXPORT_SYMBOL(omap_mcbsp_start);
569void omap_mcbsp_stop(unsigned int id, int tx, int rx) 873void omap_mcbsp_stop(unsigned int id, int tx, int rx)
570{ 874{
571 struct omap_mcbsp *mcbsp; 875 struct omap_mcbsp *mcbsp;
572 void __iomem *io_base;
573 int idle; 876 int idle;
574 u16 w; 877 u16 w;
575 878
@@ -579,36 +882,38 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
579 } 882 }
580 883
581 mcbsp = id_to_mcbsp_ptr(id); 884 mcbsp = id_to_mcbsp_ptr(id);
582 io_base = mcbsp->io_base;
583 885
584 /* Reset transmitter */ 886 /* Reset transmitter */
585 tx &= 1; 887 tx &= 1;
586 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 888 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
587 w = OMAP_MCBSP_READ(io_base, XCCR); 889 w = MCBSP_READ_CACHE(mcbsp, XCCR);
588 w |= (tx ? XDISABLE : 0); 890 w |= (tx ? XDISABLE : 0);
589 OMAP_MCBSP_WRITE(io_base, XCCR, w); 891 MCBSP_WRITE(mcbsp, XCCR, w);
590 } 892 }
591 w = OMAP_MCBSP_READ(io_base, SPCR2); 893 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
592 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx); 894 MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
593 895
594 /* Reset receiver */ 896 /* Reset receiver */
595 rx &= 1; 897 rx &= 1;
596 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 898 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
597 w = OMAP_MCBSP_READ(io_base, RCCR); 899 w = MCBSP_READ_CACHE(mcbsp, RCCR);
598 w |= (rx ? RDISABLE : 0); 900 w |= (rx ? RDISABLE : 0);
599 OMAP_MCBSP_WRITE(io_base, RCCR, w); 901 MCBSP_WRITE(mcbsp, RCCR, w);
600 } 902 }
601 w = OMAP_MCBSP_READ(io_base, SPCR1); 903 w = MCBSP_READ_CACHE(mcbsp, SPCR1);
602 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx); 904 MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
603 905
604 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) | 906 idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
605 OMAP_MCBSP_READ(io_base, SPCR1)) & 1); 907 MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
606 908
607 if (idle) { 909 if (idle) {
608 /* Reset the sample rate generator */ 910 /* Reset the sample rate generator */
609 w = OMAP_MCBSP_READ(io_base, SPCR2); 911 w = MCBSP_READ_CACHE(mcbsp, SPCR2);
610 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); 912 MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
611 } 913 }
914
915 if (cpu_is_omap34xx())
916 omap_st_stop(mcbsp);
612} 917}
613EXPORT_SYMBOL(omap_mcbsp_stop); 918EXPORT_SYMBOL(omap_mcbsp_stop);
614 919
@@ -616,7 +921,6 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
616int omap_mcbsp_pollwrite(unsigned int id, u16 buf) 921int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
617{ 922{
618 struct omap_mcbsp *mcbsp; 923 struct omap_mcbsp *mcbsp;
619 void __iomem *base;
620 924
621 if (!omap_mcbsp_check_valid_id(id)) { 925 if (!omap_mcbsp_check_valid_id(id)) {
622 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 926 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -624,28 +928,26 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
624 } 928 }
625 929
626 mcbsp = id_to_mcbsp_ptr(id); 930 mcbsp = id_to_mcbsp_ptr(id);
627 base = mcbsp->io_base;
628 931
629 writew(buf, base + OMAP_MCBSP_REG_DXR1); 932 MCBSP_WRITE(mcbsp, DXR1, buf);
630 /* if frame sync error - clear the error */ 933 /* if frame sync error - clear the error */
631 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { 934 if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
632 /* clear error */ 935 /* clear error */
633 writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR), 936 MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
634 base + OMAP_MCBSP_REG_SPCR2);
635 /* resend */ 937 /* resend */
636 return -1; 938 return -1;
637 } else { 939 } else {
638 /* wait for transmit confirmation */ 940 /* wait for transmit confirmation */
639 int attemps = 0; 941 int attemps = 0;
640 while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) { 942 while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
641 if (attemps++ > 1000) { 943 if (attemps++ > 1000) {
642 writew(readw(base + OMAP_MCBSP_REG_SPCR2) & 944 MCBSP_WRITE(mcbsp, SPCR2,
643 (~XRST), 945 MCBSP_READ_CACHE(mcbsp, SPCR2) &
644 base + OMAP_MCBSP_REG_SPCR2); 946 (~XRST));
645 udelay(10); 947 udelay(10);
646 writew(readw(base + OMAP_MCBSP_REG_SPCR2) | 948 MCBSP_WRITE(mcbsp, SPCR2,
647 (XRST), 949 MCBSP_READ_CACHE(mcbsp, SPCR2) |
648 base + OMAP_MCBSP_REG_SPCR2); 950 (XRST));
649 udelay(10); 951 udelay(10);
650 dev_err(mcbsp->dev, "Could not write to" 952 dev_err(mcbsp->dev, "Could not write to"
651 " McBSP%d Register\n", mcbsp->id); 953 " McBSP%d Register\n", mcbsp->id);
@@ -661,7 +963,6 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
661int omap_mcbsp_pollread(unsigned int id, u16 *buf) 963int omap_mcbsp_pollread(unsigned int id, u16 *buf)
662{ 964{
663 struct omap_mcbsp *mcbsp; 965 struct omap_mcbsp *mcbsp;
664 void __iomem *base;
665 966
666 if (!omap_mcbsp_check_valid_id(id)) { 967 if (!omap_mcbsp_check_valid_id(id)) {
667 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); 968 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
@@ -669,26 +970,24 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
669 } 970 }
670 mcbsp = id_to_mcbsp_ptr(id); 971 mcbsp = id_to_mcbsp_ptr(id);
671 972
672 base = mcbsp->io_base;
673 /* if frame sync error - clear the error */ 973 /* if frame sync error - clear the error */
674 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { 974 if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
675 /* clear error */ 975 /* clear error */
676 writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR), 976 MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
677 base + OMAP_MCBSP_REG_SPCR1);
678 /* resend */ 977 /* resend */
679 return -1; 978 return -1;
680 } else { 979 } else {
681 /* wait for recieve confirmation */ 980 /* wait for recieve confirmation */
682 int attemps = 0; 981 int attemps = 0;
683 while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) { 982 while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
684 if (attemps++ > 1000) { 983 if (attemps++ > 1000) {
685 writew(readw(base + OMAP_MCBSP_REG_SPCR1) & 984 MCBSP_WRITE(mcbsp, SPCR1,
686 (~RRST), 985 MCBSP_READ_CACHE(mcbsp, SPCR1) &
687 base + OMAP_MCBSP_REG_SPCR1); 986 (~RRST));
688 udelay(10); 987 udelay(10);
689 writew(readw(base + OMAP_MCBSP_REG_SPCR1) | 988 MCBSP_WRITE(mcbsp, SPCR1,
690 (RRST), 989 MCBSP_READ_CACHE(mcbsp, SPCR1) |
691 base + OMAP_MCBSP_REG_SPCR1); 990 (RRST));
692 udelay(10); 991 udelay(10);
693 dev_err(mcbsp->dev, "Could not read from" 992 dev_err(mcbsp->dev, "Could not read from"
694 " McBSP%d Register\n", mcbsp->id); 993 " McBSP%d Register\n", mcbsp->id);
@@ -696,7 +995,7 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
696 } 995 }
697 } 996 }
698 } 997 }
699 *buf = readw(base + OMAP_MCBSP_REG_DRR1); 998 *buf = MCBSP_READ(mcbsp, DRR1);
700 999
701 return 0; 1000 return 0;
702} 1001}
@@ -708,7 +1007,6 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
708void omap_mcbsp_xmit_word(unsigned int id, u32 word) 1007void omap_mcbsp_xmit_word(unsigned int id, u32 word)
709{ 1008{
710 struct omap_mcbsp *mcbsp; 1009 struct omap_mcbsp *mcbsp;
711 void __iomem *io_base;
712 omap_mcbsp_word_length word_length; 1010 omap_mcbsp_word_length word_length;
713 1011
714 if (!omap_mcbsp_check_valid_id(id)) { 1012 if (!omap_mcbsp_check_valid_id(id)) {
@@ -717,21 +1015,19 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
717 } 1015 }
718 1016
719 mcbsp = id_to_mcbsp_ptr(id); 1017 mcbsp = id_to_mcbsp_ptr(id);
720 io_base = mcbsp->io_base;
721 word_length = mcbsp->tx_word_length; 1018 word_length = mcbsp->tx_word_length;
722 1019
723 wait_for_completion(&mcbsp->tx_irq_completion); 1020 wait_for_completion(&mcbsp->tx_irq_completion);
724 1021
725 if (word_length > OMAP_MCBSP_WORD_16) 1022 if (word_length > OMAP_MCBSP_WORD_16)
726 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); 1023 MCBSP_WRITE(mcbsp, DXR2, word >> 16);
727 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); 1024 MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
728} 1025}
729EXPORT_SYMBOL(omap_mcbsp_xmit_word); 1026EXPORT_SYMBOL(omap_mcbsp_xmit_word);
730 1027
731u32 omap_mcbsp_recv_word(unsigned int id) 1028u32 omap_mcbsp_recv_word(unsigned int id)
732{ 1029{
733 struct omap_mcbsp *mcbsp; 1030 struct omap_mcbsp *mcbsp;
734 void __iomem *io_base;
735 u16 word_lsb, word_msb = 0; 1031 u16 word_lsb, word_msb = 0;
736 omap_mcbsp_word_length word_length; 1032 omap_mcbsp_word_length word_length;
737 1033
@@ -742,13 +1038,12 @@ u32 omap_mcbsp_recv_word(unsigned int id)
742 mcbsp = id_to_mcbsp_ptr(id); 1038 mcbsp = id_to_mcbsp_ptr(id);
743 1039
744 word_length = mcbsp->rx_word_length; 1040 word_length = mcbsp->rx_word_length;
745 io_base = mcbsp->io_base;
746 1041
747 wait_for_completion(&mcbsp->rx_irq_completion); 1042 wait_for_completion(&mcbsp->rx_irq_completion);
748 1043
749 if (word_length > OMAP_MCBSP_WORD_16) 1044 if (word_length > OMAP_MCBSP_WORD_16)
750 word_msb = OMAP_MCBSP_READ(io_base, DRR2); 1045 word_msb = MCBSP_READ(mcbsp, DRR2);
751 word_lsb = OMAP_MCBSP_READ(io_base, DRR1); 1046 word_lsb = MCBSP_READ(mcbsp, DRR1);
752 1047
753 return (word_lsb | (word_msb << 16)); 1048 return (word_lsb | (word_msb << 16));
754} 1049}
@@ -757,7 +1052,6 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
757int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) 1052int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
758{ 1053{
759 struct omap_mcbsp *mcbsp; 1054 struct omap_mcbsp *mcbsp;
760 void __iomem *io_base;
761 omap_mcbsp_word_length tx_word_length; 1055 omap_mcbsp_word_length tx_word_length;
762 omap_mcbsp_word_length rx_word_length; 1056 omap_mcbsp_word_length rx_word_length;
763 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 1057 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -767,7 +1061,6 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
767 return -ENODEV; 1061 return -ENODEV;
768 } 1062 }
769 mcbsp = id_to_mcbsp_ptr(id); 1063 mcbsp = id_to_mcbsp_ptr(id);
770 io_base = mcbsp->io_base;
771 tx_word_length = mcbsp->tx_word_length; 1064 tx_word_length = mcbsp->tx_word_length;
772 rx_word_length = mcbsp->rx_word_length; 1065 rx_word_length = mcbsp->rx_word_length;
773 1066
@@ -775,14 +1068,16 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
775 return -EINVAL; 1068 return -EINVAL;
776 1069
777 /* First we wait for the transmitter to be ready */ 1070 /* First we wait for the transmitter to be ready */
778 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); 1071 spcr2 = MCBSP_READ(mcbsp, SPCR2);
779 while (!(spcr2 & XRDY)) { 1072 while (!(spcr2 & XRDY)) {
780 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); 1073 spcr2 = MCBSP_READ(mcbsp, SPCR2);
781 if (attempts++ > 1000) { 1074 if (attempts++ > 1000) {
782 /* We must reset the transmitter */ 1075 /* We must reset the transmitter */
783 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); 1076 MCBSP_WRITE(mcbsp, SPCR2,
1077 MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
784 udelay(10); 1078 udelay(10);
785 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 1079 MCBSP_WRITE(mcbsp, SPCR2,
1080 MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
786 udelay(10); 1081 udelay(10);
787 dev_err(mcbsp->dev, "McBSP%d transmitter not " 1082 dev_err(mcbsp->dev, "McBSP%d transmitter not "
788 "ready\n", mcbsp->id); 1083 "ready\n", mcbsp->id);
@@ -792,18 +1087,20 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
792 1087
793 /* Now we can push the data */ 1088 /* Now we can push the data */
794 if (tx_word_length > OMAP_MCBSP_WORD_16) 1089 if (tx_word_length > OMAP_MCBSP_WORD_16)
795 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); 1090 MCBSP_WRITE(mcbsp, DXR2, word >> 16);
796 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff); 1091 MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
797 1092
798 /* We wait for the receiver to be ready */ 1093 /* We wait for the receiver to be ready */
799 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); 1094 spcr1 = MCBSP_READ(mcbsp, SPCR1);
800 while (!(spcr1 & RRDY)) { 1095 while (!(spcr1 & RRDY)) {
801 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); 1096 spcr1 = MCBSP_READ(mcbsp, SPCR1);
802 if (attempts++ > 1000) { 1097 if (attempts++ > 1000) {
803 /* We must reset the receiver */ 1098 /* We must reset the receiver */
804 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); 1099 MCBSP_WRITE(mcbsp, SPCR1,
1100 MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
805 udelay(10); 1101 udelay(10);
806 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 1102 MCBSP_WRITE(mcbsp, SPCR1,
1103 MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
807 udelay(10); 1104 udelay(10);
808 dev_err(mcbsp->dev, "McBSP%d receiver not " 1105 dev_err(mcbsp->dev, "McBSP%d receiver not "
809 "ready\n", mcbsp->id); 1106 "ready\n", mcbsp->id);
@@ -813,8 +1110,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
813 1110
814 /* Receiver is ready, let's read the dummy data */ 1111 /* Receiver is ready, let's read the dummy data */
815 if (rx_word_length > OMAP_MCBSP_WORD_16) 1112 if (rx_word_length > OMAP_MCBSP_WORD_16)
816 word_msb = OMAP_MCBSP_READ(io_base, DRR2); 1113 word_msb = MCBSP_READ(mcbsp, DRR2);
817 word_lsb = OMAP_MCBSP_READ(io_base, DRR1); 1114 word_lsb = MCBSP_READ(mcbsp, DRR1);
818 1115
819 return 0; 1116 return 0;
820} 1117}
@@ -824,7 +1121,6 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
824{ 1121{
825 struct omap_mcbsp *mcbsp; 1122 struct omap_mcbsp *mcbsp;
826 u32 clock_word = 0; 1123 u32 clock_word = 0;
827 void __iomem *io_base;
828 omap_mcbsp_word_length tx_word_length; 1124 omap_mcbsp_word_length tx_word_length;
829 omap_mcbsp_word_length rx_word_length; 1125 omap_mcbsp_word_length rx_word_length;
830 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; 1126 u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -835,7 +1131,6 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
835 } 1131 }
836 1132
837 mcbsp = id_to_mcbsp_ptr(id); 1133 mcbsp = id_to_mcbsp_ptr(id);
838 io_base = mcbsp->io_base;
839 1134
840 tx_word_length = mcbsp->tx_word_length; 1135 tx_word_length = mcbsp->tx_word_length;
841 rx_word_length = mcbsp->rx_word_length; 1136 rx_word_length = mcbsp->rx_word_length;
@@ -844,14 +1139,16 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
844 return -EINVAL; 1139 return -EINVAL;
845 1140
846 /* First we wait for the transmitter to be ready */ 1141 /* First we wait for the transmitter to be ready */
847 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); 1142 spcr2 = MCBSP_READ(mcbsp, SPCR2);
848 while (!(spcr2 & XRDY)) { 1143 while (!(spcr2 & XRDY)) {
849 spcr2 = OMAP_MCBSP_READ(io_base, SPCR2); 1144 spcr2 = MCBSP_READ(mcbsp, SPCR2);
850 if (attempts++ > 1000) { 1145 if (attempts++ > 1000) {
851 /* We must reset the transmitter */ 1146 /* We must reset the transmitter */
852 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 & (~XRST)); 1147 MCBSP_WRITE(mcbsp, SPCR2,
1148 MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
853 udelay(10); 1149 udelay(10);
854 OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); 1150 MCBSP_WRITE(mcbsp, SPCR2,
1151 MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
855 udelay(10); 1152 udelay(10);
856 dev_err(mcbsp->dev, "McBSP%d transmitter not " 1153 dev_err(mcbsp->dev, "McBSP%d transmitter not "
857 "ready\n", mcbsp->id); 1154 "ready\n", mcbsp->id);
@@ -861,18 +1158,20 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
861 1158
862 /* We first need to enable the bus clock */ 1159 /* We first need to enable the bus clock */
863 if (tx_word_length > OMAP_MCBSP_WORD_16) 1160 if (tx_word_length > OMAP_MCBSP_WORD_16)
864 OMAP_MCBSP_WRITE(io_base, DXR2, clock_word >> 16); 1161 MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
865 OMAP_MCBSP_WRITE(io_base, DXR1, clock_word & 0xffff); 1162 MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
866 1163
867 /* We wait for the receiver to be ready */ 1164 /* We wait for the receiver to be ready */
868 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); 1165 spcr1 = MCBSP_READ(mcbsp, SPCR1);
869 while (!(spcr1 & RRDY)) { 1166 while (!(spcr1 & RRDY)) {
870 spcr1 = OMAP_MCBSP_READ(io_base, SPCR1); 1167 spcr1 = MCBSP_READ(mcbsp, SPCR1);
871 if (attempts++ > 1000) { 1168 if (attempts++ > 1000) {
872 /* We must reset the receiver */ 1169 /* We must reset the receiver */
873 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 & (~RRST)); 1170 MCBSP_WRITE(mcbsp, SPCR1,
1171 MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
874 udelay(10); 1172 udelay(10);
875 OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); 1173 MCBSP_WRITE(mcbsp, SPCR1,
1174 MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
876 udelay(10); 1175 udelay(10);
877 dev_err(mcbsp->dev, "McBSP%d receiver not " 1176 dev_err(mcbsp->dev, "McBSP%d receiver not "
878 "ready\n", mcbsp->id); 1177 "ready\n", mcbsp->id);
@@ -882,8 +1181,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
882 1181
883 /* Receiver is ready, there is something for us */ 1182 /* Receiver is ready, there is something for us */
884 if (rx_word_length > OMAP_MCBSP_WORD_16) 1183 if (rx_word_length > OMAP_MCBSP_WORD_16)
885 word_msb = OMAP_MCBSP_READ(io_base, DRR2); 1184 word_msb = MCBSP_READ(mcbsp, DRR2);
886 word_lsb = OMAP_MCBSP_READ(io_base, DRR1); 1185 word_lsb = MCBSP_READ(mcbsp, DRR1);
887 1186
888 word[0] = (word_lsb | (word_msb << 16)); 1187 word[0] = (word_lsb | (word_msb << 16));
889 1188
@@ -1097,7 +1396,7 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
1097} 1396}
1098EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); 1397EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
1099 1398
1100#ifdef CONFIG_ARCH_OMAP34XX 1399#ifdef CONFIG_ARCH_OMAP3
1101#define max_thres(m) (mcbsp->pdata->buffer_size) 1400#define max_thres(m) (mcbsp->pdata->buffer_size)
1102#define valid_threshold(m, val) ((val) <= max_thres(m)) 1401#define valid_threshold(m, val) ((val) <= max_thres(m))
1103#define THRESHOLD_PROP_BUILDER(prop) \ 1402#define THRESHOLD_PROP_BUILDER(prop) \
@@ -1145,9 +1444,7 @@ static ssize_t dma_op_mode_show(struct device *dev,
1145 ssize_t len = 0; 1444 ssize_t len = 0;
1146 const char * const *s; 1445 const char * const *s;
1147 1446
1148 spin_lock_irq(&mcbsp->lock);
1149 dma_op_mode = mcbsp->dma_op_mode; 1447 dma_op_mode = mcbsp->dma_op_mode;
1150 spin_unlock_irq(&mcbsp->lock);
1151 1448
1152 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) { 1449 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
1153 if (dma_op_mode == i) 1450 if (dma_op_mode == i)
@@ -1190,6 +1487,64 @@ unlock:
1190 1487
1191static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); 1488static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1192 1489
1490static ssize_t st_taps_show(struct device *dev,
1491 struct device_attribute *attr, char *buf)
1492{
1493 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1494 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1495 ssize_t status = 0;
1496 int i;
1497
1498 spin_lock_irq(&mcbsp->lock);
1499 for (i = 0; i < st_data->nr_taps; i++)
1500 status += sprintf(&buf[status], (i ? ", %d" : "%d"),
1501 st_data->taps[i]);
1502 if (i)
1503 status += sprintf(&buf[status], "\n");
1504 spin_unlock_irq(&mcbsp->lock);
1505
1506 return status;
1507}
1508
1509static ssize_t st_taps_store(struct device *dev,
1510 struct device_attribute *attr,
1511 const char *buf, size_t size)
1512{
1513 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1514 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1515 int val, tmp, status, i = 0;
1516
1517 spin_lock_irq(&mcbsp->lock);
1518 memset(st_data->taps, 0, sizeof(st_data->taps));
1519 st_data->nr_taps = 0;
1520
1521 do {
1522 status = sscanf(buf, "%d%n", &val, &tmp);
1523 if (status < 0 || status == 0) {
1524 size = -EINVAL;
1525 goto out;
1526 }
1527 if (val < -32768 || val > 32767) {
1528 size = -EINVAL;
1529 goto out;
1530 }
1531 st_data->taps[i++] = val;
1532 buf += tmp;
1533 if (*buf != ',')
1534 break;
1535 buf++;
1536 } while (1);
1537
1538 st_data->nr_taps = i;
1539
1540out:
1541 spin_unlock_irq(&mcbsp->lock);
1542
1543 return size;
1544}
1545
1546static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
1547
1193static const struct attribute *additional_attrs[] = { 1548static const struct attribute *additional_attrs[] = {
1194 &dev_attr_max_tx_thres.attr, 1549 &dev_attr_max_tx_thres.attr,
1195 &dev_attr_max_rx_thres.attr, 1550 &dev_attr_max_rx_thres.attr,
@@ -1211,6 +1566,60 @@ static inline void __devexit omap_additional_remove(struct device *dev)
1211 sysfs_remove_group(&dev->kobj, &additional_attr_group); 1566 sysfs_remove_group(&dev->kobj, &additional_attr_group);
1212} 1567}
1213 1568
1569static const struct attribute *sidetone_attrs[] = {
1570 &dev_attr_st_taps.attr,
1571 NULL,
1572};
1573
1574static const struct attribute_group sidetone_attr_group = {
1575 .attrs = (struct attribute **)sidetone_attrs,
1576};
1577
1578int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
1579{
1580 struct omap_mcbsp_platform_data *pdata = mcbsp->pdata;
1581 struct omap_mcbsp_st_data *st_data;
1582 int err;
1583
1584 st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
1585 if (!st_data) {
1586 err = -ENOMEM;
1587 goto err1;
1588 }
1589
1590 st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K);
1591 if (!st_data->io_base_st) {
1592 err = -ENOMEM;
1593 goto err2;
1594 }
1595
1596 err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1597 if (err)
1598 goto err3;
1599
1600 mcbsp->st_data = st_data;
1601 return 0;
1602
1603err3:
1604 iounmap(st_data->io_base_st);
1605err2:
1606 kfree(st_data);
1607err1:
1608 return err;
1609
1610}
1611
1612static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
1613{
1614 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
1615
1616 if (st_data) {
1617 sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
1618 iounmap(st_data->io_base_st);
1619 kfree(st_data);
1620 }
1621}
1622
1214static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) 1623static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1215{ 1624{
1216 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; 1625 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
@@ -1224,6 +1633,12 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1224 if (omap_additional_add(mcbsp->dev)) 1633 if (omap_additional_add(mcbsp->dev))
1225 dev_warn(mcbsp->dev, 1634 dev_warn(mcbsp->dev,
1226 "Unable to create additional controls\n"); 1635 "Unable to create additional controls\n");
1636
1637 if (mcbsp->id == 2 || mcbsp->id == 3)
1638 if (omap_st_add(mcbsp))
1639 dev_warn(mcbsp->dev,
1640 "Unable to create sidetone controls\n");
1641
1227 } else { 1642 } else {
1228 mcbsp->max_tx_thres = -EINVAL; 1643 mcbsp->max_tx_thres = -EINVAL;
1229 mcbsp->max_rx_thres = -EINVAL; 1644 mcbsp->max_rx_thres = -EINVAL;
@@ -1232,13 +1647,17 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1232 1647
1233static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) 1648static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
1234{ 1649{
1235 if (cpu_is_omap34xx()) 1650 if (cpu_is_omap34xx()) {
1236 omap_additional_remove(mcbsp->dev); 1651 omap_additional_remove(mcbsp->dev);
1652
1653 if (mcbsp->id == 2 || mcbsp->id == 3)
1654 omap_st_remove(mcbsp);
1655 }
1237} 1656}
1238#else 1657#else
1239static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {} 1658static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
1240static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {} 1659static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
1241#endif /* CONFIG_ARCH_OMAP34XX */ 1660#endif /* CONFIG_ARCH_OMAP3 */
1242 1661
1243/* 1662/*
1244 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. 1663 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.