diff options
author | Chandra Shekhar <x0044955@ti.com> | 2008-10-08 03:01:39 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-10-08 03:01:39 -0400 |
commit | b4b58f5834a023dab67201db9a626bef07bb200c (patch) | |
tree | 721917a3f675ba7f55ce6d8df0fef9f0a6ed88a5 /arch/arm | |
parent | 25cef2251415cef5438e20965fec87096fe2efb0 (diff) |
ARM: OMAP: Allocate McBSP devices dynamically
Based on Chandra's earlier patches in linux-omap tree.
Note that omap1_mcbsp_check and omap2_mcbsp_check are no longer
needed as there's now omap_mcbsp_check_valid_id() defined.
Also some functions can now be marked __init.
Signed-off-by: Chandra Shekhar <x0044955@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap1/mcbsp.c | 37 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 28 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/mach/mcbsp.h | 33 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 388 |
4 files changed, 270 insertions, 216 deletions
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index afb5789f94f9..7de7c6915584 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c | |||
@@ -103,30 +103,6 @@ static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) | |||
103 | { } | 103 | { } |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | static int omap1_mcbsp_check(unsigned int id) | ||
107 | { | ||
108 | /* REVISIT: Check correctly for number of registered McBSPs */ | ||
109 | if (cpu_is_omap730()) { | ||
110 | if (id > OMAP_MAX_MCBSP_COUNT - 2) { | ||
111 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", | ||
112 | id + 1); | ||
113 | return -ENODEV; | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { | ||
119 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | ||
120 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", | ||
121 | id + 1); | ||
122 | return -ENODEV; | ||
123 | } | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | return -ENODEV; | ||
128 | } | ||
129 | |||
130 | static void omap1_mcbsp_request(unsigned int id) | 106 | static void omap1_mcbsp_request(unsigned int id) |
131 | { | 107 | { |
132 | /* | 108 | /* |
@@ -151,7 +127,6 @@ static void omap1_mcbsp_free(unsigned int id) | |||
151 | } | 127 | } |
152 | 128 | ||
153 | static struct omap_mcbsp_ops omap1_mcbsp_ops = { | 129 | static struct omap_mcbsp_ops omap1_mcbsp_ops = { |
154 | .check = omap1_mcbsp_check, | ||
155 | .request = omap1_mcbsp_request, | 130 | .request = omap1_mcbsp_request, |
156 | .free = omap1_mcbsp_free, | 131 | .free = omap1_mcbsp_free, |
157 | }; | 132 | }; |
@@ -263,6 +238,18 @@ int __init omap1_mcbsp_init(void) | |||
263 | } | 238 | } |
264 | 239 | ||
265 | if (cpu_is_omap730()) | 240 | if (cpu_is_omap730()) |
241 | omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ; | ||
242 | if (cpu_is_omap15xx()) | ||
243 | omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ; | ||
244 | if (cpu_is_omap16xx()) | ||
245 | omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ; | ||
246 | |||
247 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | ||
248 | GFP_KERNEL); | ||
249 | if (!mcbsp_ptr) | ||
250 | return -ENOMEM; | ||
251 | |||
252 | if (cpu_is_omap730()) | ||
266 | omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata, | 253 | omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata, |
267 | OMAP730_MCBSP_PDATA_SZ); | 254 | OMAP730_MCBSP_PDATA_SZ); |
268 | 255 | ||
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 709db03b9999..73f2279ef2ea 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -28,7 +28,7 @@ struct mcbsp_internal_clk { | |||
28 | int n_childs; | 28 | int n_childs; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | 31 | #if defined(CONFIG_ARCH_OMAP24XX) |
32 | static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) | 32 | static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) |
33 | { | 33 | { |
34 | const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; | 34 | const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; |
@@ -117,18 +117,8 @@ static void omap2_mcbsp_request(unsigned int id) | |||
117 | omap2_mcbsp2_mux_setup(); | 117 | omap2_mcbsp2_mux_setup(); |
118 | } | 118 | } |
119 | 119 | ||
120 | static int omap2_mcbsp_check(unsigned int id) | ||
121 | { | ||
122 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | ||
123 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct omap_mcbsp_ops omap2_mcbsp_ops = { | 120 | static struct omap_mcbsp_ops omap2_mcbsp_ops = { |
130 | .request = omap2_mcbsp_request, | 121 | .request = omap2_mcbsp_request, |
131 | .check = omap2_mcbsp_check, | ||
132 | }; | 122 | }; |
133 | 123 | ||
134 | #ifdef CONFIG_ARCH_OMAP24XX | 124 | #ifdef CONFIG_ARCH_OMAP24XX |
@@ -185,7 +175,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | |||
185 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | 175 | #define OMAP34XX_MCBSP_PDATA_SZ 0 |
186 | #endif | 176 | #endif |
187 | 177 | ||
188 | int __init omap2_mcbsp_init(void) | 178 | static int __init omap2_mcbsp_init(void) |
189 | { | 179 | { |
190 | int i; | 180 | int i; |
191 | 181 | ||
@@ -196,13 +186,19 @@ int __init omap2_mcbsp_init(void) | |||
196 | } | 186 | } |
197 | 187 | ||
198 | if (cpu_is_omap24xx()) | 188 | if (cpu_is_omap24xx()) |
189 | omap_mcbsp_count = OMAP24XX_MCBSP_PDATA_SZ; | ||
190 | if (cpu_is_omap34xx()) | ||
191 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; | ||
192 | |||
193 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | ||
194 | GFP_KERNEL); | ||
195 | if (!mcbsp_ptr) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | if (cpu_is_omap24xx()) | ||
199 | omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, | 199 | omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, |
200 | OMAP24XX_MCBSP_PDATA_SZ); | 200 | OMAP24XX_MCBSP_PDATA_SZ); |
201 | 201 | ||
202 | if (cpu_is_omap34xx()) | ||
203 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | ||
204 | OMAP34XX_MCBSP_PDATA_SZ); | ||
205 | |||
206 | return omap_mcbsp_init(); | 202 | return omap_mcbsp_init(); |
207 | } | 203 | } |
208 | arch_initcall(omap2_mcbsp_init); | 204 | arch_initcall(omap2_mcbsp_init); |
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h index a3074f2fb7ce..46898faecb16 100644 --- a/arch/arm/plat-omap/include/mach/mcbsp.h +++ b/arch/arm/plat-omap/include/mach/mcbsp.h | |||
@@ -81,9 +81,6 @@ | |||
81 | #define OMAP_MCBSP_REG_XCERG 0x3A | 81 | #define OMAP_MCBSP_REG_XCERG 0x3A |
82 | #define OMAP_MCBSP_REG_XCERH 0x3C | 82 | #define OMAP_MCBSP_REG_XCERH 0x3C |
83 | 83 | ||
84 | #define OMAP_MAX_MCBSP_COUNT 3 | ||
85 | #define MAX_MCBSP_CLOCKS 3 | ||
86 | |||
87 | #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) | 84 | #define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) |
88 | #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) | 85 | #define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) |
89 | 86 | ||
@@ -91,12 +88,14 @@ | |||
91 | #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX | 88 | #define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX |
92 | #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX | 89 | #define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX |
93 | 90 | ||
94 | #elif defined(CONFIG_ARCH_OMAP24XX) | 91 | #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) |
95 | 92 | ||
96 | #define OMAP_MCBSP_REG_DRR2 0x00 | 93 | #define OMAP_MCBSP_REG_DRR2 0x00 |
97 | #define OMAP_MCBSP_REG_DRR1 0x04 | 94 | #define OMAP_MCBSP_REG_DRR1 0x04 |
98 | #define OMAP_MCBSP_REG_DXR2 0x08 | 95 | #define OMAP_MCBSP_REG_DXR2 0x08 |
99 | #define OMAP_MCBSP_REG_DXR1 0x0C | 96 | #define OMAP_MCBSP_REG_DXR1 0x0C |
97 | #define OMAP_MCBSP_REG_DRR 0x00 | ||
98 | #define OMAP_MCBSP_REG_DXR 0x08 | ||
100 | #define OMAP_MCBSP_REG_SPCR2 0x10 | 99 | #define OMAP_MCBSP_REG_SPCR2 0x10 |
101 | #define OMAP_MCBSP_REG_SPCR1 0x14 | 100 | #define OMAP_MCBSP_REG_SPCR1 0x14 |
102 | #define OMAP_MCBSP_REG_RCR2 0x18 | 101 | #define OMAP_MCBSP_REG_RCR2 0x18 |
@@ -124,9 +123,9 @@ | |||
124 | #define OMAP_MCBSP_REG_RCERH 0x70 | 123 | #define OMAP_MCBSP_REG_RCERH 0x70 |
125 | #define OMAP_MCBSP_REG_XCERG 0x74 | 124 | #define OMAP_MCBSP_REG_XCERG 0x74 |
126 | #define OMAP_MCBSP_REG_XCERH 0x78 | 125 | #define OMAP_MCBSP_REG_XCERH 0x78 |
127 | 126 | #define OMAP_MCBSP_REG_SYSCON 0x8C | |
128 | #define OMAP_MAX_MCBSP_COUNT 2 | 127 | #define OMAP_MCBSP_REG_XCCR 0xAC |
129 | #define MAX_MCBSP_CLOCKS 2 | 128 | #define OMAP_MCBSP_REG_RCCR 0xB0 |
130 | 129 | ||
131 | #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) | 130 | #define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) |
132 | #define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) | 131 | #define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) |
@@ -137,10 +136,6 @@ | |||
137 | 136 | ||
138 | #endif | 137 | #endif |
139 | 138 | ||
140 | #define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg) | ||
141 | #define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg) | ||
142 | |||
143 | |||
144 | /************************** McBSP SPCR1 bit definitions ***********************/ | 139 | /************************** McBSP SPCR1 bit definitions ***********************/ |
145 | #define RRST 0x0001 | 140 | #define RRST 0x0001 |
146 | #define RRDY 0x0002 | 141 | #define RRDY 0x0002 |
@@ -151,6 +146,7 @@ | |||
151 | #define DXENA 0x0080 | 146 | #define DXENA 0x0080 |
152 | #define CLKSTP(value) ((value)<<11) /* bits 11:12 */ | 147 | #define CLKSTP(value) ((value)<<11) /* bits 11:12 */ |
153 | #define RJUST(value) ((value)<<13) /* bits 13:14 */ | 148 | #define RJUST(value) ((value)<<13) /* bits 13:14 */ |
149 | #define ALB 0x8000 | ||
154 | #define DLB 0x8000 | 150 | #define DLB 0x8000 |
155 | 151 | ||
156 | /************************** McBSP SPCR2 bit definitions ***********************/ | 152 | /************************** McBSP SPCR2 bit definitions ***********************/ |
@@ -228,6 +224,17 @@ | |||
228 | #define XPABLK(value) ((value)<<5) /* Bits 5:6 */ | 224 | #define XPABLK(value) ((value)<<5) /* Bits 5:6 */ |
229 | #define XPBBLK(value) ((value)<<7) /* Bits 7:8 */ | 225 | #define XPBBLK(value) ((value)<<7) /* Bits 7:8 */ |
230 | 226 | ||
227 | /*********************** McBSP XCCR bit definitions *************************/ | ||
228 | #define DILB 0x0020 | ||
229 | #define XDMAEN 0x0008 | ||
230 | #define XDISABLE 0x0001 | ||
231 | |||
232 | /********************** McBSP RCCR bit definitions *************************/ | ||
233 | #define RDMAEN 0x0008 | ||
234 | #define RDISABLE 0x0001 | ||
235 | |||
236 | /********************** McBSP SYSCONFIG bit definitions ********************/ | ||
237 | #define SOFTRST 0x0002 | ||
231 | 238 | ||
232 | /* we don't do multichannel for now */ | 239 | /* we don't do multichannel for now */ |
233 | struct omap_mcbsp_reg_cfg { | 240 | struct omap_mcbsp_reg_cfg { |
@@ -311,7 +318,6 @@ struct omap_mcbsp_spi_cfg { | |||
311 | struct omap_mcbsp_ops { | 318 | struct omap_mcbsp_ops { |
312 | void (*request)(unsigned int); | 319 | void (*request)(unsigned int); |
313 | void (*free)(unsigned int); | 320 | void (*free)(unsigned int); |
314 | int (*check)(unsigned int); | ||
315 | }; | 321 | }; |
316 | 322 | ||
317 | struct omap_mcbsp_platform_data { | 323 | struct omap_mcbsp_platform_data { |
@@ -353,6 +359,8 @@ struct omap_mcbsp { | |||
353 | struct omap_mcbsp_platform_data *pdata; | 359 | struct omap_mcbsp_platform_data *pdata; |
354 | struct clk *clk; | 360 | struct clk *clk; |
355 | }; | 361 | }; |
362 | extern struct omap_mcbsp **mcbsp_ptr; | ||
363 | extern int omap_mcbsp_count; | ||
356 | 364 | ||
357 | int omap_mcbsp_init(void); | 365 | int omap_mcbsp_init(void); |
358 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | 366 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, |
@@ -377,5 +385,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * | |||
377 | /* Polled read/write functions */ | 385 | /* Polled read/write functions */ |
378 | int omap_mcbsp_pollread(unsigned int id, u16 * buf); | 386 | int omap_mcbsp_pollread(unsigned int id, u16 * buf); |
379 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf); | 387 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf); |
388 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type); | ||
380 | 389 | ||
381 | #endif | 390 | #endif |
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index e0803a8344be..f27e641bf814 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -27,43 +27,65 @@ | |||
27 | #include <mach/dma.h> | 27 | #include <mach/dma.h> |
28 | #include <mach/mcbsp.h> | 28 | #include <mach/mcbsp.h> |
29 | 29 | ||
30 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; | 30 | struct omap_mcbsp **mcbsp_ptr; |
31 | int omap_mcbsp_count; | ||
31 | 32 | ||
32 | #define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ | 33 | void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val) |
33 | mcbsp[id].pdata->ops && \ | 34 | { |
34 | mcbsp[id].pdata->ops->check && \ | 35 | if (cpu_class_is_omap1() || cpu_is_omap2420()) |
35 | (mcbsp[id].pdata->ops->check(id) == 0)) | 36 | __raw_writew((u16)val, io_base + reg); |
37 | else | ||
38 | __raw_writel(val, io_base + reg); | ||
39 | } | ||
40 | |||
41 | int omap_mcbsp_read(void __iomem *io_base, u16 reg) | ||
42 | { | ||
43 | if (cpu_class_is_omap1() || cpu_is_omap2420()) | ||
44 | return __raw_readw(io_base + reg); | ||
45 | else | ||
46 | return __raw_readl(io_base + reg); | ||
47 | } | ||
48 | |||
49 | #define OMAP_MCBSP_READ(base, reg) \ | ||
50 | omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg) | ||
51 | #define OMAP_MCBSP_WRITE(base, reg, val) \ | ||
52 | omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val) | ||
53 | |||
54 | #define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count) | ||
55 | #define id_to_mcbsp_ptr(id) mcbsp_ptr[id]; | ||
36 | 56 | ||
37 | static void omap_mcbsp_dump_reg(u8 id) | 57 | static void omap_mcbsp_dump_reg(u8 id) |
38 | { | 58 | { |
39 | dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); | 59 | struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id); |
40 | dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", | 60 | |
41 | OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); | 61 | dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id); |
42 | dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", | 62 | dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n", |
43 | OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); | 63 | OMAP_MCBSP_READ(mcbsp->io_base, DRR2)); |
44 | dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", | 64 | dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n", |
45 | OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); | 65 | OMAP_MCBSP_READ(mcbsp->io_base, DRR1)); |
46 | dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", | 66 | dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n", |
47 | OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); | 67 | OMAP_MCBSP_READ(mcbsp->io_base, DXR2)); |
48 | dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", | 68 | dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n", |
49 | OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); | 69 | OMAP_MCBSP_READ(mcbsp->io_base, DXR1)); |
50 | dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", | 70 | dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n", |
51 | OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); | 71 | OMAP_MCBSP_READ(mcbsp->io_base, SPCR2)); |
52 | dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", | 72 | dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n", |
53 | OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); | 73 | OMAP_MCBSP_READ(mcbsp->io_base, SPCR1)); |
54 | dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", | 74 | dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n", |
55 | OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); | 75 | OMAP_MCBSP_READ(mcbsp->io_base, RCR2)); |
56 | dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", | 76 | dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n", |
57 | OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); | 77 | OMAP_MCBSP_READ(mcbsp->io_base, RCR1)); |
58 | dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", | 78 | dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n", |
59 | OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); | 79 | OMAP_MCBSP_READ(mcbsp->io_base, XCR2)); |
60 | dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", | 80 | dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n", |
61 | OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); | 81 | OMAP_MCBSP_READ(mcbsp->io_base, XCR1)); |
62 | dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", | 82 | dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n", |
63 | OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); | 83 | OMAP_MCBSP_READ(mcbsp->io_base, SRGR2)); |
64 | dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", | 84 | dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n", |
65 | OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); | 85 | OMAP_MCBSP_READ(mcbsp->io_base, SRGR1)); |
66 | dev_dbg(mcbsp[id].dev, "***********************\n"); | 86 | dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n", |
87 | OMAP_MCBSP_READ(mcbsp->io_base, PCR0)); | ||
88 | dev_dbg(mcbsp->dev, "***********************\n"); | ||
67 | } | 89 | } |
68 | 90 | ||
69 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | 91 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) |
@@ -126,16 +148,18 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) | |||
126 | */ | 148 | */ |
127 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | 149 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) |
128 | { | 150 | { |
151 | struct omap_mcbsp *mcbsp; | ||
129 | void __iomem *io_base; | 152 | void __iomem *io_base; |
130 | 153 | ||
131 | if (!omap_mcbsp_check_valid_id(id)) { | 154 | if (!omap_mcbsp_check_valid_id(id)) { |
132 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 155 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
133 | return; | 156 | return; |
134 | } | 157 | } |
158 | mcbsp = id_to_mcbsp_ptr(id); | ||
135 | 159 | ||
136 | io_base = mcbsp[id].io_base; | 160 | io_base = mcbsp->io_base; |
137 | dev_dbg(mcbsp[id].dev, "Configuring McBSP%d phys_base: 0x%08lx\n", | 161 | dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n", |
138 | mcbsp[id].id, mcbsp[id].phys_base); | 162 | mcbsp->id, mcbsp->phys_base); |
139 | 163 | ||
140 | /* We write the given config */ | 164 | /* We write the given config */ |
141 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); | 165 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); |
@@ -158,23 +182,26 @@ EXPORT_SYMBOL(omap_mcbsp_config); | |||
158 | */ | 182 | */ |
159 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | 183 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) |
160 | { | 184 | { |
185 | struct omap_mcbsp *mcbsp; | ||
186 | |||
161 | if (!omap_mcbsp_check_valid_id(id)) { | 187 | if (!omap_mcbsp_check_valid_id(id)) { |
162 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 188 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
163 | return -ENODEV; | 189 | return -ENODEV; |
164 | } | 190 | } |
191 | mcbsp = id_to_mcbsp_ptr(id); | ||
165 | 192 | ||
166 | spin_lock(&mcbsp[id].lock); | 193 | spin_lock(&mcbsp->lock); |
167 | 194 | ||
168 | if (!mcbsp[id].free) { | 195 | if (!mcbsp->free) { |
169 | dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", | 196 | dev_err(mcbsp->dev, "McBSP%d is currently in use\n", |
170 | mcbsp[id].id); | 197 | mcbsp->id); |
171 | spin_unlock(&mcbsp[id].lock); | 198 | spin_unlock(&mcbsp->lock); |
172 | return -EINVAL; | 199 | return -EINVAL; |
173 | } | 200 | } |
174 | 201 | ||
175 | mcbsp[id].io_type = io_type; | 202 | mcbsp->io_type = io_type; |
176 | 203 | ||
177 | spin_unlock(&mcbsp[id].lock); | 204 | spin_unlock(&mcbsp->lock); |
178 | 205 | ||
179 | return 0; | 206 | return 0; |
180 | } | 207 | } |
@@ -182,53 +209,55 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type); | |||
182 | 209 | ||
183 | int omap_mcbsp_request(unsigned int id) | 210 | int omap_mcbsp_request(unsigned int id) |
184 | { | 211 | { |
212 | struct omap_mcbsp *mcbsp; | ||
185 | int err; | 213 | int err; |
186 | 214 | ||
187 | if (!omap_mcbsp_check_valid_id(id)) { | 215 | if (!omap_mcbsp_check_valid_id(id)) { |
188 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 216 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
189 | return -ENODEV; | 217 | return -ENODEV; |
190 | } | 218 | } |
219 | mcbsp = id_to_mcbsp_ptr(id); | ||
191 | 220 | ||
192 | if (mcbsp[id].pdata->ops->request) | 221 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) |
193 | mcbsp[id].pdata->ops->request(id); | 222 | mcbsp->pdata->ops->request(id); |
194 | 223 | ||
195 | clk_enable(mcbsp[id].clk); | 224 | clk_enable(mcbsp->clk); |
196 | 225 | ||
197 | spin_lock(&mcbsp[id].lock); | 226 | spin_lock(&mcbsp->lock); |
198 | if (!mcbsp[id].free) { | 227 | if (!mcbsp->free) { |
199 | dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", | 228 | dev_err(mcbsp->dev, "McBSP%d is currently in use\n", |
200 | mcbsp[id].id); | 229 | mcbsp->id); |
201 | spin_unlock(&mcbsp[id].lock); | 230 | spin_unlock(&mcbsp->lock); |
202 | return -1; | 231 | return -1; |
203 | } | 232 | } |
204 | 233 | ||
205 | mcbsp[id].free = 0; | 234 | mcbsp->free = 0; |
206 | spin_unlock(&mcbsp[id].lock); | 235 | spin_unlock(&mcbsp->lock); |
207 | 236 | ||
208 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { | 237 | if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { |
209 | /* We need to get IRQs here */ | 238 | /* We need to get IRQs here */ |
210 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, | 239 | err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, |
211 | 0, "McBSP", (void *) (&mcbsp[id])); | 240 | 0, "McBSP", (void *)mcbsp); |
212 | if (err != 0) { | 241 | if (err != 0) { |
213 | dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " | 242 | dev_err(mcbsp->dev, "Unable to request TX IRQ %d " |
214 | "for McBSP%d\n", mcbsp[id].tx_irq, | 243 | "for McBSP%d\n", mcbsp->tx_irq, |
215 | mcbsp[id].id); | 244 | mcbsp->id); |
216 | return err; | 245 | return err; |
217 | } | 246 | } |
218 | 247 | ||
219 | init_completion(&(mcbsp[id].tx_irq_completion)); | 248 | init_completion(&mcbsp->tx_irq_completion); |
220 | 249 | ||
221 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, | 250 | err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler, |
222 | 0, "McBSP", (void *) (&mcbsp[id])); | 251 | 0, "McBSP", (void *)mcbsp); |
223 | if (err != 0) { | 252 | if (err != 0) { |
224 | dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " | 253 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " |
225 | "for McBSP%d\n", mcbsp[id].rx_irq, | 254 | "for McBSP%d\n", mcbsp->rx_irq, |
226 | mcbsp[id].id); | 255 | mcbsp->id); |
227 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 256 | free_irq(mcbsp->tx_irq, (void *)mcbsp); |
228 | return err; | 257 | return err; |
229 | } | 258 | } |
230 | 259 | ||
231 | init_completion(&(mcbsp[id].rx_irq_completion)); | 260 | init_completion(&mcbsp->rx_irq_completion); |
232 | } | 261 | } |
233 | 262 | ||
234 | return 0; | 263 | return 0; |
@@ -237,31 +266,34 @@ EXPORT_SYMBOL(omap_mcbsp_request); | |||
237 | 266 | ||
238 | void omap_mcbsp_free(unsigned int id) | 267 | void omap_mcbsp_free(unsigned int id) |
239 | { | 268 | { |
269 | struct omap_mcbsp *mcbsp; | ||
270 | |||
240 | if (!omap_mcbsp_check_valid_id(id)) { | 271 | if (!omap_mcbsp_check_valid_id(id)) { |
241 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 272 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
242 | return; | 273 | return; |
243 | } | 274 | } |
275 | mcbsp = id_to_mcbsp_ptr(id); | ||
244 | 276 | ||
245 | if (mcbsp[id].pdata->ops->free) | 277 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) |
246 | mcbsp[id].pdata->ops->free(id); | 278 | mcbsp->pdata->ops->free(id); |
247 | 279 | ||
248 | clk_disable(mcbsp[id].clk); | 280 | clk_disable(mcbsp->clk); |
249 | 281 | ||
250 | spin_lock(&mcbsp[id].lock); | 282 | spin_lock(&mcbsp->lock); |
251 | if (mcbsp[id].free) { | 283 | if (mcbsp->free) { |
252 | dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", | 284 | dev_err(mcbsp->dev, "McBSP%d was not reserved\n", |
253 | mcbsp[id].id); | 285 | mcbsp->id); |
254 | spin_unlock(&mcbsp[id].lock); | 286 | spin_unlock(&mcbsp->lock); |
255 | return; | 287 | return; |
256 | } | 288 | } |
257 | 289 | ||
258 | mcbsp[id].free = 1; | 290 | mcbsp->free = 1; |
259 | spin_unlock(&mcbsp[id].lock); | 291 | spin_unlock(&mcbsp->lock); |
260 | 292 | ||
261 | if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) { | 293 | if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { |
262 | /* Free IRQs */ | 294 | /* Free IRQs */ |
263 | free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id])); | 295 | free_irq(mcbsp->rx_irq, (void *)mcbsp); |
264 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 296 | free_irq(mcbsp->tx_irq, (void *)mcbsp); |
265 | } | 297 | } |
266 | } | 298 | } |
267 | EXPORT_SYMBOL(omap_mcbsp_free); | 299 | EXPORT_SYMBOL(omap_mcbsp_free); |
@@ -273,6 +305,7 @@ EXPORT_SYMBOL(omap_mcbsp_free); | |||
273 | */ | 305 | */ |
274 | void omap_mcbsp_start(unsigned int id) | 306 | void omap_mcbsp_start(unsigned int id) |
275 | { | 307 | { |
308 | struct omap_mcbsp *mcbsp; | ||
276 | void __iomem *io_base; | 309 | void __iomem *io_base; |
277 | u16 w; | 310 | u16 w; |
278 | 311 | ||
@@ -280,11 +313,11 @@ void omap_mcbsp_start(unsigned int id) | |||
280 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 313 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
281 | return; | 314 | return; |
282 | } | 315 | } |
316 | mcbsp = id_to_mcbsp_ptr(id); | ||
317 | io_base = mcbsp->io_base; | ||
283 | 318 | ||
284 | io_base = mcbsp[id].io_base; | 319 | mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; |
285 | 320 | mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; | |
286 | mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; | ||
287 | mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; | ||
288 | 321 | ||
289 | /* Start the sample generator */ | 322 | /* Start the sample generator */ |
290 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 323 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
@@ -310,6 +343,7 @@ EXPORT_SYMBOL(omap_mcbsp_start); | |||
310 | 343 | ||
311 | void omap_mcbsp_stop(unsigned int id) | 344 | void omap_mcbsp_stop(unsigned int id) |
312 | { | 345 | { |
346 | struct omap_mcbsp *mcbsp; | ||
313 | void __iomem *io_base; | 347 | void __iomem *io_base; |
314 | u16 w; | 348 | u16 w; |
315 | 349 | ||
@@ -318,7 +352,8 @@ void omap_mcbsp_stop(unsigned int id) | |||
318 | return; | 352 | return; |
319 | } | 353 | } |
320 | 354 | ||
321 | io_base = mcbsp[id].io_base; | 355 | mcbsp = id_to_mcbsp_ptr(id); |
356 | io_base = mcbsp->io_base; | ||
322 | 357 | ||
323 | /* Reset transmitter */ | 358 | /* Reset transmitter */ |
324 | w = OMAP_MCBSP_READ(io_base, SPCR2); | 359 | w = OMAP_MCBSP_READ(io_base, SPCR2); |
@@ -337,6 +372,7 @@ EXPORT_SYMBOL(omap_mcbsp_stop); | |||
337 | /* polled mcbsp i/o operations */ | 372 | /* polled mcbsp i/o operations */ |
338 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | 373 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) |
339 | { | 374 | { |
375 | struct omap_mcbsp *mcbsp; | ||
340 | void __iomem *base; | 376 | void __iomem *base; |
341 | 377 | ||
342 | if (!omap_mcbsp_check_valid_id(id)) { | 378 | if (!omap_mcbsp_check_valid_id(id)) { |
@@ -344,7 +380,9 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | |||
344 | return -ENODEV; | 380 | return -ENODEV; |
345 | } | 381 | } |
346 | 382 | ||
347 | base = mcbsp[id].io_base; | 383 | mcbsp = id_to_mcbsp_ptr(id); |
384 | base = mcbsp->io_base; | ||
385 | |||
348 | writew(buf, base + OMAP_MCBSP_REG_DXR1); | 386 | writew(buf, base + OMAP_MCBSP_REG_DXR1); |
349 | /* if frame sync error - clear the error */ | 387 | /* if frame sync error - clear the error */ |
350 | if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { | 388 | if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { |
@@ -366,8 +404,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | |||
366 | (XRST), | 404 | (XRST), |
367 | base + OMAP_MCBSP_REG_SPCR2); | 405 | base + OMAP_MCBSP_REG_SPCR2); |
368 | udelay(10); | 406 | udelay(10); |
369 | dev_err(mcbsp[id].dev, "Could not write to" | 407 | dev_err(mcbsp->dev, "Could not write to" |
370 | " McBSP%d Register\n", mcbsp[id].id); | 408 | " McBSP%d Register\n", mcbsp->id); |
371 | return -2; | 409 | return -2; |
372 | } | 410 | } |
373 | } | 411 | } |
@@ -379,14 +417,16 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite); | |||
379 | 417 | ||
380 | int omap_mcbsp_pollread(unsigned int id, u16 *buf) | 418 | int omap_mcbsp_pollread(unsigned int id, u16 *buf) |
381 | { | 419 | { |
420 | struct omap_mcbsp *mcbsp; | ||
382 | void __iomem *base; | 421 | void __iomem *base; |
383 | 422 | ||
384 | if (!omap_mcbsp_check_valid_id(id)) { | 423 | if (!omap_mcbsp_check_valid_id(id)) { |
385 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 424 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
386 | return -ENODEV; | 425 | return -ENODEV; |
387 | } | 426 | } |
427 | mcbsp = id_to_mcbsp_ptr(id); | ||
388 | 428 | ||
389 | base = mcbsp[id].io_base; | 429 | base = mcbsp->io_base; |
390 | /* if frame sync error - clear the error */ | 430 | /* if frame sync error - clear the error */ |
391 | if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { | 431 | if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { |
392 | /* clear error */ | 432 | /* clear error */ |
@@ -407,8 +447,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) | |||
407 | (RRST), | 447 | (RRST), |
408 | base + OMAP_MCBSP_REG_SPCR1); | 448 | base + OMAP_MCBSP_REG_SPCR1); |
409 | udelay(10); | 449 | udelay(10); |
410 | dev_err(mcbsp[id].dev, "Could not read from" | 450 | dev_err(mcbsp->dev, "Could not read from" |
411 | " McBSP%d Register\n", mcbsp[id].id); | 451 | " McBSP%d Register\n", mcbsp->id); |
412 | return -2; | 452 | return -2; |
413 | } | 453 | } |
414 | } | 454 | } |
@@ -424,6 +464,7 @@ EXPORT_SYMBOL(omap_mcbsp_pollread); | |||
424 | */ | 464 | */ |
425 | void omap_mcbsp_xmit_word(unsigned int id, u32 word) | 465 | void omap_mcbsp_xmit_word(unsigned int id, u32 word) |
426 | { | 466 | { |
467 | struct omap_mcbsp *mcbsp; | ||
427 | void __iomem *io_base; | 468 | void __iomem *io_base; |
428 | omap_mcbsp_word_length word_length; | 469 | omap_mcbsp_word_length word_length; |
429 | 470 | ||
@@ -432,10 +473,11 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word) | |||
432 | return; | 473 | return; |
433 | } | 474 | } |
434 | 475 | ||
435 | io_base = mcbsp[id].io_base; | 476 | mcbsp = id_to_mcbsp_ptr(id); |
436 | word_length = mcbsp[id].tx_word_length; | 477 | io_base = mcbsp->io_base; |
478 | word_length = mcbsp->tx_word_length; | ||
437 | 479 | ||
438 | wait_for_completion(&(mcbsp[id].tx_irq_completion)); | 480 | wait_for_completion(&mcbsp->tx_irq_completion); |
439 | 481 | ||
440 | if (word_length > OMAP_MCBSP_WORD_16) | 482 | if (word_length > OMAP_MCBSP_WORD_16) |
441 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); | 483 | OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16); |
@@ -445,6 +487,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word); | |||
445 | 487 | ||
446 | u32 omap_mcbsp_recv_word(unsigned int id) | 488 | u32 omap_mcbsp_recv_word(unsigned int id) |
447 | { | 489 | { |
490 | struct omap_mcbsp *mcbsp; | ||
448 | void __iomem *io_base; | 491 | void __iomem *io_base; |
449 | u16 word_lsb, word_msb = 0; | 492 | u16 word_lsb, word_msb = 0; |
450 | omap_mcbsp_word_length word_length; | 493 | omap_mcbsp_word_length word_length; |
@@ -453,11 +496,12 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
453 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 496 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
454 | return -ENODEV; | 497 | return -ENODEV; |
455 | } | 498 | } |
499 | mcbsp = id_to_mcbsp_ptr(id); | ||
456 | 500 | ||
457 | word_length = mcbsp[id].rx_word_length; | 501 | word_length = mcbsp->rx_word_length; |
458 | io_base = mcbsp[id].io_base; | 502 | io_base = mcbsp->io_base; |
459 | 503 | ||
460 | wait_for_completion(&(mcbsp[id].rx_irq_completion)); | 504 | wait_for_completion(&mcbsp->rx_irq_completion); |
461 | 505 | ||
462 | if (word_length > OMAP_MCBSP_WORD_16) | 506 | if (word_length > OMAP_MCBSP_WORD_16) |
463 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); | 507 | word_msb = OMAP_MCBSP_READ(io_base, DRR2); |
@@ -469,6 +513,7 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word); | |||
469 | 513 | ||
470 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | 514 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) |
471 | { | 515 | { |
516 | struct omap_mcbsp *mcbsp; | ||
472 | void __iomem *io_base; | 517 | void __iomem *io_base; |
473 | omap_mcbsp_word_length tx_word_length; | 518 | omap_mcbsp_word_length tx_word_length; |
474 | omap_mcbsp_word_length rx_word_length; | 519 | omap_mcbsp_word_length rx_word_length; |
@@ -478,10 +523,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
478 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 523 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
479 | return -ENODEV; | 524 | return -ENODEV; |
480 | } | 525 | } |
481 | 526 | mcbsp = id_to_mcbsp_ptr(id); | |
482 | io_base = mcbsp[id].io_base; | 527 | io_base = mcbsp->io_base; |
483 | tx_word_length = mcbsp[id].tx_word_length; | 528 | tx_word_length = mcbsp->tx_word_length; |
484 | rx_word_length = mcbsp[id].rx_word_length; | 529 | rx_word_length = mcbsp->rx_word_length; |
485 | 530 | ||
486 | if (tx_word_length != rx_word_length) | 531 | if (tx_word_length != rx_word_length) |
487 | return -EINVAL; | 532 | return -EINVAL; |
@@ -496,8 +541,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
496 | udelay(10); | 541 | udelay(10); |
497 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 542 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
498 | udelay(10); | 543 | udelay(10); |
499 | dev_err(mcbsp[id].dev, "McBSP%d transmitter not " | 544 | dev_err(mcbsp->dev, "McBSP%d transmitter not " |
500 | "ready\n", mcbsp[id].id); | 545 | "ready\n", mcbsp->id); |
501 | return -EAGAIN; | 546 | return -EAGAIN; |
502 | } | 547 | } |
503 | } | 548 | } |
@@ -517,8 +562,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
517 | udelay(10); | 562 | udelay(10); |
518 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 563 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
519 | udelay(10); | 564 | udelay(10); |
520 | dev_err(mcbsp[id].dev, "McBSP%d receiver not " | 565 | dev_err(mcbsp->dev, "McBSP%d receiver not " |
521 | "ready\n", mcbsp[id].id); | 566 | "ready\n", mcbsp->id); |
522 | return -EAGAIN; | 567 | return -EAGAIN; |
523 | } | 568 | } |
524 | } | 569 | } |
@@ -534,6 +579,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | |||
534 | 579 | ||
535 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | 580 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) |
536 | { | 581 | { |
582 | struct omap_mcbsp *mcbsp; | ||
537 | u32 clock_word = 0; | 583 | u32 clock_word = 0; |
538 | void __iomem *io_base; | 584 | void __iomem *io_base; |
539 | omap_mcbsp_word_length tx_word_length; | 585 | omap_mcbsp_word_length tx_word_length; |
@@ -545,9 +591,11 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | |||
545 | return -ENODEV; | 591 | return -ENODEV; |
546 | } | 592 | } |
547 | 593 | ||
548 | io_base = mcbsp[id].io_base; | 594 | mcbsp = id_to_mcbsp_ptr(id); |
549 | tx_word_length = mcbsp[id].tx_word_length; | 595 | io_base = mcbsp->io_base; |
550 | rx_word_length = mcbsp[id].rx_word_length; | 596 | |
597 | tx_word_length = mcbsp->tx_word_length; | ||
598 | rx_word_length = mcbsp->rx_word_length; | ||
551 | 599 | ||
552 | if (tx_word_length != rx_word_length) | 600 | if (tx_word_length != rx_word_length) |
553 | return -EINVAL; | 601 | return -EINVAL; |
@@ -562,8 +610,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | |||
562 | udelay(10); | 610 | udelay(10); |
563 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 611 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
564 | udelay(10); | 612 | udelay(10); |
565 | dev_err(mcbsp[id].dev, "McBSP%d transmitter not " | 613 | dev_err(mcbsp->dev, "McBSP%d transmitter not " |
566 | "ready\n", mcbsp[id].id); | 614 | "ready\n", mcbsp->id); |
567 | return -EAGAIN; | 615 | return -EAGAIN; |
568 | } | 616 | } |
569 | } | 617 | } |
@@ -583,8 +631,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | |||
583 | udelay(10); | 631 | udelay(10); |
584 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 632 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
585 | udelay(10); | 633 | udelay(10); |
586 | dev_err(mcbsp[id].dev, "McBSP%d receiver not " | 634 | dev_err(mcbsp->dev, "McBSP%d receiver not " |
587 | "ready\n", mcbsp[id].id); | 635 | "ready\n", mcbsp->id); |
588 | return -EAGAIN; | 636 | return -EAGAIN; |
589 | } | 637 | } |
590 | } | 638 | } |
@@ -610,6 +658,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll); | |||
610 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, | 658 | int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, |
611 | unsigned int length) | 659 | unsigned int length) |
612 | { | 660 | { |
661 | struct omap_mcbsp *mcbsp; | ||
613 | int dma_tx_ch; | 662 | int dma_tx_ch; |
614 | int src_port = 0; | 663 | int src_port = 0; |
615 | int dest_port = 0; | 664 | int dest_port = 0; |
@@ -619,50 +668,51 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, | |||
619 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 668 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
620 | return -ENODEV; | 669 | return -ENODEV; |
621 | } | 670 | } |
671 | mcbsp = id_to_mcbsp_ptr(id); | ||
622 | 672 | ||
623 | if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", | 673 | if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX", |
624 | omap_mcbsp_tx_dma_callback, | 674 | omap_mcbsp_tx_dma_callback, |
625 | &mcbsp[id], | 675 | mcbsp, |
626 | &dma_tx_ch)) { | 676 | &dma_tx_ch)) { |
627 | dev_err(mcbsp[id].dev, " Unable to request DMA channel for " | 677 | dev_err(mcbsp->dev, " Unable to request DMA channel for " |
628 | "McBSP%d TX. Trying IRQ based TX\n", | 678 | "McBSP%d TX. Trying IRQ based TX\n", |
629 | mcbsp[id].id); | 679 | mcbsp->id); |
630 | return -EAGAIN; | 680 | return -EAGAIN; |
631 | } | 681 | } |
632 | mcbsp[id].dma_tx_lch = dma_tx_ch; | 682 | mcbsp->dma_tx_lch = dma_tx_ch; |
633 | 683 | ||
634 | dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, | 684 | dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id, |
635 | dma_tx_ch); | 685 | dma_tx_ch); |
636 | 686 | ||
637 | init_completion(&(mcbsp[id].tx_dma_completion)); | 687 | init_completion(&mcbsp->tx_dma_completion); |
638 | 688 | ||
639 | if (cpu_class_is_omap1()) { | 689 | if (cpu_class_is_omap1()) { |
640 | src_port = OMAP_DMA_PORT_TIPB; | 690 | src_port = OMAP_DMA_PORT_TIPB; |
641 | dest_port = OMAP_DMA_PORT_EMIFF; | 691 | dest_port = OMAP_DMA_PORT_EMIFF; |
642 | } | 692 | } |
643 | if (cpu_class_is_omap2()) | 693 | if (cpu_class_is_omap2()) |
644 | sync_dev = mcbsp[id].dma_tx_sync; | 694 | sync_dev = mcbsp->dma_tx_sync; |
645 | 695 | ||
646 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, | 696 | omap_set_dma_transfer_params(mcbsp->dma_tx_lch, |
647 | OMAP_DMA_DATA_TYPE_S16, | 697 | OMAP_DMA_DATA_TYPE_S16, |
648 | length >> 1, 1, | 698 | length >> 1, 1, |
649 | OMAP_DMA_SYNC_ELEMENT, | 699 | OMAP_DMA_SYNC_ELEMENT, |
650 | sync_dev, 0); | 700 | sync_dev, 0); |
651 | 701 | ||
652 | omap_set_dma_dest_params(mcbsp[id].dma_tx_lch, | 702 | omap_set_dma_dest_params(mcbsp->dma_tx_lch, |
653 | src_port, | 703 | src_port, |
654 | OMAP_DMA_AMODE_CONSTANT, | 704 | OMAP_DMA_AMODE_CONSTANT, |
655 | mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1, | 705 | mcbsp->phys_base + OMAP_MCBSP_REG_DXR1, |
656 | 0, 0); | 706 | 0, 0); |
657 | 707 | ||
658 | omap_set_dma_src_params(mcbsp[id].dma_tx_lch, | 708 | omap_set_dma_src_params(mcbsp->dma_tx_lch, |
659 | dest_port, | 709 | dest_port, |
660 | OMAP_DMA_AMODE_POST_INC, | 710 | OMAP_DMA_AMODE_POST_INC, |
661 | buffer, | 711 | buffer, |
662 | 0, 0); | 712 | 0, 0); |
663 | 713 | ||
664 | omap_start_dma(mcbsp[id].dma_tx_lch); | 714 | omap_start_dma(mcbsp->dma_tx_lch); |
665 | wait_for_completion(&(mcbsp[id].tx_dma_completion)); | 715 | wait_for_completion(&mcbsp->tx_dma_completion); |
666 | 716 | ||
667 | return 0; | 717 | return 0; |
668 | } | 718 | } |
@@ -671,6 +721,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer); | |||
671 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, | 721 | int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, |
672 | unsigned int length) | 722 | unsigned int length) |
673 | { | 723 | { |
724 | struct omap_mcbsp *mcbsp; | ||
674 | int dma_rx_ch; | 725 | int dma_rx_ch; |
675 | int src_port = 0; | 726 | int src_port = 0; |
676 | int dest_port = 0; | 727 | int dest_port = 0; |
@@ -680,50 +731,51 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, | |||
680 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 731 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
681 | return -ENODEV; | 732 | return -ENODEV; |
682 | } | 733 | } |
734 | mcbsp = id_to_mcbsp_ptr(id); | ||
683 | 735 | ||
684 | if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", | 736 | if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX", |
685 | omap_mcbsp_rx_dma_callback, | 737 | omap_mcbsp_rx_dma_callback, |
686 | &mcbsp[id], | 738 | mcbsp, |
687 | &dma_rx_ch)) { | 739 | &dma_rx_ch)) { |
688 | dev_err(mcbsp[id].dev, "Unable to request DMA channel for " | 740 | dev_err(mcbsp->dev, "Unable to request DMA channel for " |
689 | "McBSP%d RX. Trying IRQ based RX\n", | 741 | "McBSP%d RX. Trying IRQ based RX\n", |
690 | mcbsp[id].id); | 742 | mcbsp->id); |
691 | return -EAGAIN; | 743 | return -EAGAIN; |
692 | } | 744 | } |
693 | mcbsp[id].dma_rx_lch = dma_rx_ch; | 745 | mcbsp->dma_rx_lch = dma_rx_ch; |
694 | 746 | ||
695 | dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, | 747 | dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id, |
696 | dma_rx_ch); | 748 | dma_rx_ch); |
697 | 749 | ||
698 | init_completion(&(mcbsp[id].rx_dma_completion)); | 750 | init_completion(&mcbsp->rx_dma_completion); |
699 | 751 | ||
700 | if (cpu_class_is_omap1()) { | 752 | if (cpu_class_is_omap1()) { |
701 | src_port = OMAP_DMA_PORT_TIPB; | 753 | src_port = OMAP_DMA_PORT_TIPB; |
702 | dest_port = OMAP_DMA_PORT_EMIFF; | 754 | dest_port = OMAP_DMA_PORT_EMIFF; |
703 | } | 755 | } |
704 | if (cpu_class_is_omap2()) | 756 | if (cpu_class_is_omap2()) |
705 | sync_dev = mcbsp[id].dma_rx_sync; | 757 | sync_dev = mcbsp->dma_rx_sync; |
706 | 758 | ||
707 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 759 | omap_set_dma_transfer_params(mcbsp->dma_rx_lch, |
708 | OMAP_DMA_DATA_TYPE_S16, | 760 | OMAP_DMA_DATA_TYPE_S16, |
709 | length >> 1, 1, | 761 | length >> 1, 1, |
710 | OMAP_DMA_SYNC_ELEMENT, | 762 | OMAP_DMA_SYNC_ELEMENT, |
711 | sync_dev, 0); | 763 | sync_dev, 0); |
712 | 764 | ||
713 | omap_set_dma_src_params(mcbsp[id].dma_rx_lch, | 765 | omap_set_dma_src_params(mcbsp->dma_rx_lch, |
714 | src_port, | 766 | src_port, |
715 | OMAP_DMA_AMODE_CONSTANT, | 767 | OMAP_DMA_AMODE_CONSTANT, |
716 | mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1, | 768 | mcbsp->phys_base + OMAP_MCBSP_REG_DRR1, |
717 | 0, 0); | 769 | 0, 0); |
718 | 770 | ||
719 | omap_set_dma_dest_params(mcbsp[id].dma_rx_lch, | 771 | omap_set_dma_dest_params(mcbsp->dma_rx_lch, |
720 | dest_port, | 772 | dest_port, |
721 | OMAP_DMA_AMODE_POST_INC, | 773 | OMAP_DMA_AMODE_POST_INC, |
722 | buffer, | 774 | buffer, |
723 | 0, 0); | 775 | 0, 0); |
724 | 776 | ||
725 | omap_start_dma(mcbsp[id].dma_rx_lch); | 777 | omap_start_dma(mcbsp->dma_rx_lch); |
726 | wait_for_completion(&(mcbsp[id].rx_dma_completion)); | 778 | wait_for_completion(&mcbsp->rx_dma_completion); |
727 | 779 | ||
728 | return 0; | 780 | return 0; |
729 | } | 781 | } |
@@ -738,12 +790,14 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer); | |||
738 | void omap_mcbsp_set_spi_mode(unsigned int id, | 790 | void omap_mcbsp_set_spi_mode(unsigned int id, |
739 | const struct omap_mcbsp_spi_cfg *spi_cfg) | 791 | const struct omap_mcbsp_spi_cfg *spi_cfg) |
740 | { | 792 | { |
793 | struct omap_mcbsp *mcbsp; | ||
741 | struct omap_mcbsp_reg_cfg mcbsp_cfg; | 794 | struct omap_mcbsp_reg_cfg mcbsp_cfg; |
742 | 795 | ||
743 | if (!omap_mcbsp_check_valid_id(id)) { | 796 | if (!omap_mcbsp_check_valid_id(id)) { |
744 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | 797 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
745 | return; | 798 | return; |
746 | } | 799 | } |
800 | mcbsp = id_to_mcbsp_ptr(id); | ||
747 | 801 | ||
748 | memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); | 802 | memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); |
749 | 803 | ||
@@ -807,6 +861,7 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | |||
807 | static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | 861 | static int __devinit omap_mcbsp_probe(struct platform_device *pdev) |
808 | { | 862 | { |
809 | struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; | 863 | struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; |
864 | struct omap_mcbsp *mcbsp; | ||
810 | int id = pdev->id - 1; | 865 | int id = pdev->id - 1; |
811 | int ret = 0; | 866 | int ret = 0; |
812 | 867 | ||
@@ -819,51 +874,58 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev) | |||
819 | 874 | ||
820 | dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); | 875 | dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); |
821 | 876 | ||
822 | if (id >= OMAP_MAX_MCBSP_COUNT) { | 877 | if (id >= omap_mcbsp_count) { |
823 | dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); | 878 | dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); |
824 | ret = -EINVAL; | 879 | ret = -EINVAL; |
825 | goto exit; | 880 | goto exit; |
826 | } | 881 | } |
827 | 882 | ||
828 | spin_lock_init(&mcbsp[id].lock); | 883 | mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL); |
829 | mcbsp[id].id = id + 1; | 884 | if (!mcbsp) { |
830 | mcbsp[id].free = 1; | 885 | ret = -ENOMEM; |
831 | mcbsp[id].dma_tx_lch = -1; | 886 | goto exit; |
832 | mcbsp[id].dma_rx_lch = -1; | 887 | } |
888 | mcbsp_ptr[id] = mcbsp; | ||
889 | |||
890 | spin_lock_init(&mcbsp->lock); | ||
891 | mcbsp->id = id + 1; | ||
892 | mcbsp->free = 1; | ||
893 | mcbsp->dma_tx_lch = -1; | ||
894 | mcbsp->dma_rx_lch = -1; | ||
833 | 895 | ||
834 | mcbsp[id].phys_base = pdata->phys_base; | 896 | mcbsp->phys_base = pdata->phys_base; |
835 | mcbsp[id].io_base = ioremap(pdata->phys_base, SZ_4K); | 897 | mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K); |
836 | if (!mcbsp[id].io_base) { | 898 | if (!mcbsp->io_base) { |
837 | ret = -ENOMEM; | 899 | ret = -ENOMEM; |
838 | goto err_ioremap; | 900 | goto err_ioremap; |
839 | } | 901 | } |
840 | 902 | ||
841 | /* Default I/O is IRQ based */ | 903 | /* Default I/O is IRQ based */ |
842 | mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; | 904 | mcbsp->io_type = OMAP_MCBSP_IRQ_IO; |
843 | mcbsp[id].tx_irq = pdata->tx_irq; | 905 | mcbsp->tx_irq = pdata->tx_irq; |
844 | mcbsp[id].rx_irq = pdata->rx_irq; | 906 | mcbsp->rx_irq = pdata->rx_irq; |
845 | mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; | 907 | mcbsp->dma_rx_sync = pdata->dma_rx_sync; |
846 | mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; | 908 | mcbsp->dma_tx_sync = pdata->dma_tx_sync; |
847 | 909 | ||
848 | if (pdata->clk_name) | 910 | if (pdata->clk_name) |
849 | mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); | 911 | mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name); |
850 | if (IS_ERR(mcbsp[id].clk)) { | 912 | if (IS_ERR(mcbsp->clk)) { |
851 | dev_err(&pdev->dev, | 913 | dev_err(&pdev->dev, |
852 | "Invalid clock configuration for McBSP%d.\n", | 914 | "Invalid clock configuration for McBSP%d.\n", |
853 | mcbsp[id].id); | 915 | mcbsp->id); |
854 | ret = PTR_ERR(mcbsp[id].clk); | 916 | ret = PTR_ERR(mcbsp->clk); |
855 | goto err_clk; | 917 | goto err_clk; |
856 | } | 918 | } |
857 | 919 | ||
858 | mcbsp[id].pdata = pdata; | 920 | mcbsp->pdata = pdata; |
859 | mcbsp[id].dev = &pdev->dev; | 921 | mcbsp->dev = &pdev->dev; |
860 | platform_set_drvdata(pdev, &mcbsp[id]); | 922 | platform_set_drvdata(pdev, mcbsp); |
861 | return 0; | 923 | return 0; |
862 | 924 | ||
863 | err_clk: | 925 | err_clk: |
864 | iounmap(mcbsp[id].io_base); | 926 | iounmap(mcbsp->io_base); |
865 | err_ioremap: | 927 | err_ioremap: |
866 | mcbsp[id].free = 0; | 928 | mcbsp->free = 0; |
867 | exit: | 929 | exit: |
868 | return ret; | 930 | return ret; |
869 | } | 931 | } |