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