diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/plat-omap/devices.c | 48 | ||||
-rw-r--r-- | arch/arm/plat-omap/mcbsp.c | 662 |
2 files changed, 301 insertions, 409 deletions
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 4a53f9ba6c43..81002b722da1 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/arch/mux.h> | 24 | #include <asm/arch/mux.h> |
25 | #include <asm/arch/gpio.h> | 25 | #include <asm/arch/gpio.h> |
26 | #include <asm/arch/menelaus.h> | 26 | #include <asm/arch/menelaus.h> |
27 | #include <asm/arch/mcbsp.h> | ||
27 | 28 | ||
28 | #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) | 29 | #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) |
29 | 30 | ||
@@ -145,6 +146,53 @@ static inline void omap_init_kp(void) {} | |||
145 | #endif | 146 | #endif |
146 | 147 | ||
147 | /*-------------------------------------------------------------------------*/ | 148 | /*-------------------------------------------------------------------------*/ |
149 | #if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE) | ||
150 | |||
151 | static struct platform_device **omap_mcbsp_devices; | ||
152 | |||
153 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | ||
154 | int size) | ||
155 | { | ||
156 | int i; | ||
157 | |||
158 | if (size > OMAP_MAX_MCBSP_COUNT) { | ||
159 | printk(KERN_WARNING "Registered too many McBSPs platform_data." | ||
160 | " Using maximum (%d) available.\n", | ||
161 | OMAP_MAX_MCBSP_COUNT); | ||
162 | size = OMAP_MAX_MCBSP_COUNT; | ||
163 | } | ||
164 | |||
165 | omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *), | ||
166 | GFP_KERNEL); | ||
167 | if (!omap_mcbsp_devices) { | ||
168 | printk(KERN_ERR "Could not register McBSP devices\n"); | ||
169 | return; | ||
170 | } | ||
171 | |||
172 | for (i = 0; i < size; i++) { | ||
173 | struct platform_device *new_mcbsp; | ||
174 | int ret; | ||
175 | |||
176 | new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1); | ||
177 | if (!new_mcbsp) | ||
178 | continue; | ||
179 | new_mcbsp->dev.platform_data = &config[i]; | ||
180 | ret = platform_device_add(new_mcbsp); | ||
181 | if (ret) { | ||
182 | platform_device_put(new_mcbsp); | ||
183 | continue; | ||
184 | } | ||
185 | omap_mcbsp_devices[i] = new_mcbsp; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | #else | ||
190 | void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, | ||
191 | int size) | ||
192 | { } | ||
193 | #endif | ||
194 | |||
195 | /*-------------------------------------------------------------------------*/ | ||
148 | 196 | ||
149 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) | 197 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) |
150 | 198 | ||
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index c0018b1b6673..c7f74064696c 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/platform_device.h> | ||
18 | #include <linux/wait.h> | 19 | #include <linux/wait.h> |
19 | #include <linux/completion.h> | 20 | #include <linux/completion.h> |
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
@@ -24,83 +25,53 @@ | |||
24 | #include <linux/io.h> | 25 | #include <linux/io.h> |
25 | 26 | ||
26 | #include <asm/arch/dma.h> | 27 | #include <asm/arch/dma.h> |
27 | #include <asm/arch/mux.h> | ||
28 | #include <asm/arch/irqs.h> | ||
29 | #include <asm/arch/dsp_common.h> | ||
30 | #include <asm/arch/mcbsp.h> | 28 | #include <asm/arch/mcbsp.h> |
31 | 29 | ||
32 | #ifdef CONFIG_MCBSP_DEBUG | ||
33 | #define DBG(x...) printk(x) | ||
34 | #else | ||
35 | #define DBG(x...) do { } while (0) | ||
36 | #endif | ||
37 | |||
38 | struct omap_mcbsp { | ||
39 | u32 io_base; | ||
40 | u8 id; | ||
41 | u8 free; | ||
42 | omap_mcbsp_word_length rx_word_length; | ||
43 | omap_mcbsp_word_length tx_word_length; | ||
44 | |||
45 | omap_mcbsp_io_type_t io_type; /* IRQ or poll */ | ||
46 | /* IRQ based TX/RX */ | ||
47 | int rx_irq; | ||
48 | int tx_irq; | ||
49 | |||
50 | /* DMA stuff */ | ||
51 | u8 dma_rx_sync; | ||
52 | short dma_rx_lch; | ||
53 | u8 dma_tx_sync; | ||
54 | short dma_tx_lch; | ||
55 | |||
56 | /* Completion queues */ | ||
57 | struct completion tx_irq_completion; | ||
58 | struct completion rx_irq_completion; | ||
59 | struct completion tx_dma_completion; | ||
60 | struct completion rx_dma_completion; | ||
61 | |||
62 | /* Protect the field .free, while checking if the mcbsp is in use */ | ||
63 | spinlock_t lock; | ||
64 | }; | ||
65 | |||
66 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; | 30 | static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT]; |
67 | #ifdef CONFIG_ARCH_OMAP1 | 31 | |
68 | static struct clk *mcbsp_dsp_ck; | 32 | #define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \ |
69 | static struct clk *mcbsp_api_ck; | 33 | mcbsp[id].pdata->ops && \ |
70 | static struct clk *mcbsp_dspxor_ck; | 34 | mcbsp[id].pdata->ops->check && \ |
71 | #endif | 35 | (mcbsp[id].pdata->ops->check(id) == 0)) |
72 | #ifdef CONFIG_ARCH_OMAP2 | ||
73 | static struct clk *mcbsp1_ick; | ||
74 | static struct clk *mcbsp1_fck; | ||
75 | static struct clk *mcbsp2_ick; | ||
76 | static struct clk *mcbsp2_fck; | ||
77 | #endif | ||
78 | 36 | ||
79 | static void omap_mcbsp_dump_reg(u8 id) | 37 | static void omap_mcbsp_dump_reg(u8 id) |
80 | { | 38 | { |
81 | DBG("**** MCBSP%d regs ****\n", mcbsp[id].id); | 39 | dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id); |
82 | DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); | 40 | dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n", |
83 | DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); | 41 | OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2)); |
84 | DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); | 42 | dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n", |
85 | DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); | 43 | OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1)); |
86 | DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); | 44 | dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n", |
87 | DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); | 45 | OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2)); |
88 | DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); | 46 | dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n", |
89 | DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); | 47 | OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1)); |
90 | DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); | 48 | dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n", |
91 | DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); | 49 | OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2)); |
92 | DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); | 50 | dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n", |
93 | DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); | 51 | OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1)); |
94 | DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); | 52 | dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n", |
95 | DBG("***********************\n"); | 53 | OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2)); |
54 | dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n", | ||
55 | OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1)); | ||
56 | dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n", | ||
57 | OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2)); | ||
58 | dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n", | ||
59 | OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1)); | ||
60 | dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n", | ||
61 | OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2)); | ||
62 | dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n", | ||
63 | OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1)); | ||
64 | dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n", | ||
65 | OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0)); | ||
66 | dev_dbg(mcbsp[id].dev, "***********************\n"); | ||
96 | } | 67 | } |
97 | 68 | ||
98 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | 69 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) |
99 | { | 70 | { |
100 | struct omap_mcbsp *mcbsp_tx = dev_id; | 71 | struct omap_mcbsp *mcbsp_tx = dev_id; |
101 | 72 | ||
102 | DBG("TX IRQ callback : 0x%x\n", | 73 | dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", |
103 | OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); | 74 | OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2)); |
104 | 75 | ||
105 | complete(&mcbsp_tx->tx_irq_completion); | 76 | complete(&mcbsp_tx->tx_irq_completion); |
106 | 77 | ||
@@ -111,8 +82,8 @@ static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | |||
111 | { | 82 | { |
112 | struct omap_mcbsp *mcbsp_rx = dev_id; | 83 | struct omap_mcbsp *mcbsp_rx = dev_id; |
113 | 84 | ||
114 | DBG("RX IRQ callback : 0x%x\n", | 85 | dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", |
115 | OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); | 86 | OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2)); |
116 | 87 | ||
117 | complete(&mcbsp_rx->rx_irq_completion); | 88 | complete(&mcbsp_rx->rx_irq_completion); |
118 | 89 | ||
@@ -123,8 +94,8 @@ static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data) | |||
123 | { | 94 | { |
124 | struct omap_mcbsp *mcbsp_dma_tx = data; | 95 | struct omap_mcbsp *mcbsp_dma_tx = data; |
125 | 96 | ||
126 | DBG("TX DMA callback : 0x%x\n", | 97 | dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n", |
127 | OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); | 98 | OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2)); |
128 | 99 | ||
129 | /* We can free the channels */ | 100 | /* We can free the channels */ |
130 | omap_free_dma(mcbsp_dma_tx->dma_tx_lch); | 101 | omap_free_dma(mcbsp_dma_tx->dma_tx_lch); |
@@ -137,8 +108,8 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) | |||
137 | { | 108 | { |
138 | struct omap_mcbsp *mcbsp_dma_rx = data; | 109 | struct omap_mcbsp *mcbsp_dma_rx = data; |
139 | 110 | ||
140 | DBG("RX DMA callback : 0x%x\n", | 111 | dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n", |
141 | OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); | 112 | OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2)); |
142 | 113 | ||
143 | /* We can free the channels */ | 114 | /* We can free the channels */ |
144 | omap_free_dma(mcbsp_dma_rx->dma_rx_lch); | 115 | omap_free_dma(mcbsp_dma_rx->dma_rx_lch); |
@@ -155,9 +126,16 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data) | |||
155 | */ | 126 | */ |
156 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | 127 | void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) |
157 | { | 128 | { |
158 | u32 io_base = mcbsp[id].io_base; | 129 | u32 io_base; |
159 | 130 | ||
160 | DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id + 1, io_base); | 131 | if (!omap_mcbsp_check_valid_id(id)) { |
132 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | io_base = mcbsp[id].io_base; | ||
137 | dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n", | ||
138 | mcbsp[id].id, io_base); | ||
161 | 139 | ||
162 | /* We write the given config */ | 140 | /* We write the given config */ |
163 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); | 141 | OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2); |
@@ -174,97 +152,22 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config) | |||
174 | } | 152 | } |
175 | EXPORT_SYMBOL(omap_mcbsp_config); | 153 | EXPORT_SYMBOL(omap_mcbsp_config); |
176 | 154 | ||
177 | static int omap_mcbsp_check(unsigned int id) | ||
178 | { | ||
179 | if (cpu_is_omap730()) { | ||
180 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | ||
181 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", | ||
182 | id + 1); | ||
183 | return -1; | ||
184 | } | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | if (cpu_is_omap15xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) { | ||
189 | if (id > OMAP_MAX_MCBSP_COUNT) { | ||
190 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", | ||
191 | id + 1); | ||
192 | return -1; | ||
193 | } | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | return -1; | ||
198 | } | ||
199 | |||
200 | #ifdef CONFIG_ARCH_OMAP1 | ||
201 | static void omap_mcbsp_dsp_request(void) | ||
202 | { | ||
203 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { | ||
204 | int ret; | ||
205 | |||
206 | ret = omap_dsp_request_mem(); | ||
207 | if (ret < 0) { | ||
208 | printk(KERN_ERR "Could not get dsp memory: %i\n", ret); | ||
209 | return; | ||
210 | } | ||
211 | |||
212 | clk_enable(mcbsp_dsp_ck); | ||
213 | clk_enable(mcbsp_api_ck); | ||
214 | |||
215 | /* enable 12MHz clock to mcbsp 1 & 3 */ | ||
216 | clk_enable(mcbsp_dspxor_ck); | ||
217 | |||
218 | /* | ||
219 | * DSP external peripheral reset | ||
220 | * FIXME: This should be moved to dsp code | ||
221 | */ | ||
222 | __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1, | ||
223 | DSP_RSTCT2); | ||
224 | } | ||
225 | } | ||
226 | |||
227 | static void omap_mcbsp_dsp_free(void) | ||
228 | { | ||
229 | if (cpu_is_omap15xx() || cpu_is_omap16xx()) { | ||
230 | omap_dsp_release_mem(); | ||
231 | clk_disable(mcbsp_dspxor_ck); | ||
232 | clk_disable(mcbsp_dsp_ck); | ||
233 | clk_disable(mcbsp_api_ck); | ||
234 | } | ||
235 | } | ||
236 | #endif | ||
237 | |||
238 | #ifdef CONFIG_ARCH_OMAP2 | ||
239 | static void omap2_mcbsp2_mux_setup(void) | ||
240 | { | ||
241 | if (cpu_is_omap2420()) { | ||
242 | omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); | ||
243 | omap_cfg_reg(R14_24XX_MCBSP2_FSX); | ||
244 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | ||
245 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | ||
246 | omap_cfg_reg(V14_24XX_GPIO117); | ||
247 | } | ||
248 | /* | ||
249 | * Need to add MUX settings for OMAP 2430 SDP | ||
250 | */ | ||
251 | } | ||
252 | #endif | ||
253 | |||
254 | /* | 155 | /* |
255 | * We can choose between IRQ based or polled IO. | 156 | * We can choose between IRQ based or polled IO. |
256 | * This needs to be called before omap_mcbsp_request(). | 157 | * This needs to be called before omap_mcbsp_request(). |
257 | */ | 158 | */ |
258 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) | 159 | int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type) |
259 | { | 160 | { |
260 | if (omap_mcbsp_check(id) < 0) | 161 | if (!omap_mcbsp_check_valid_id(id)) { |
261 | return -EINVAL; | 162 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
163 | return -ENODEV; | ||
164 | } | ||
262 | 165 | ||
263 | spin_lock(&mcbsp[id].lock); | 166 | spin_lock(&mcbsp[id].lock); |
264 | 167 | ||
265 | if (!mcbsp[id].free) { | 168 | if (!mcbsp[id].free) { |
266 | printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", | 169 | dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", |
267 | id + 1); | 170 | mcbsp[id].id); |
268 | spin_unlock(&mcbsp[id].lock); | 171 | spin_unlock(&mcbsp[id].lock); |
269 | return -EINVAL; | 172 | return -EINVAL; |
270 | } | 173 | } |
@@ -281,34 +184,20 @@ int omap_mcbsp_request(unsigned int id) | |||
281 | { | 184 | { |
282 | int err; | 185 | int err; |
283 | 186 | ||
284 | if (omap_mcbsp_check(id) < 0) | 187 | if (!omap_mcbsp_check_valid_id(id)) { |
285 | return -EINVAL; | 188 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
286 | 189 | return -ENODEV; | |
287 | #ifdef CONFIG_ARCH_OMAP1 | ||
288 | /* | ||
289 | * On 1510, 1610 and 1710, McBSP1 and McBSP3 | ||
290 | * are DSP public peripherals. | ||
291 | */ | ||
292 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | ||
293 | omap_mcbsp_dsp_request(); | ||
294 | #endif | ||
295 | |||
296 | #ifdef CONFIG_ARCH_OMAP2 | ||
297 | if (cpu_is_omap24xx()) { | ||
298 | if (id == OMAP_MCBSP1) { | ||
299 | clk_enable(mcbsp1_ick); | ||
300 | clk_enable(mcbsp1_fck); | ||
301 | } else { | ||
302 | clk_enable(mcbsp2_ick); | ||
303 | clk_enable(mcbsp2_fck); | ||
304 | } | ||
305 | } | 190 | } |
306 | #endif | 191 | |
192 | if (mcbsp[id].pdata->ops->request) | ||
193 | mcbsp[id].pdata->ops->request(id); | ||
194 | |||
195 | clk_enable(mcbsp[id].clk); | ||
307 | 196 | ||
308 | spin_lock(&mcbsp[id].lock); | 197 | spin_lock(&mcbsp[id].lock); |
309 | if (!mcbsp[id].free) { | 198 | if (!mcbsp[id].free) { |
310 | printk(KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", | 199 | dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n", |
311 | id + 1); | 200 | mcbsp[id].id); |
312 | spin_unlock(&mcbsp[id].lock); | 201 | spin_unlock(&mcbsp[id].lock); |
313 | return -1; | 202 | return -1; |
314 | } | 203 | } |
@@ -321,9 +210,9 @@ int omap_mcbsp_request(unsigned int id) | |||
321 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, | 210 | err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, |
322 | 0, "McBSP", (void *) (&mcbsp[id])); | 211 | 0, "McBSP", (void *) (&mcbsp[id])); |
323 | if (err != 0) { | 212 | if (err != 0) { |
324 | printk(KERN_ERR "OMAP-McBSP: Unable to " | 213 | dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d " |
325 | "request TX IRQ %d for McBSP%d\n", | 214 | "for McBSP%d\n", mcbsp[id].tx_irq, |
326 | mcbsp[id].tx_irq, mcbsp[id].id); | 215 | mcbsp[id].id); |
327 | return err; | 216 | return err; |
328 | } | 217 | } |
329 | 218 | ||
@@ -332,9 +221,9 @@ int omap_mcbsp_request(unsigned int id) | |||
332 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, | 221 | err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, |
333 | 0, "McBSP", (void *) (&mcbsp[id])); | 222 | 0, "McBSP", (void *) (&mcbsp[id])); |
334 | if (err != 0) { | 223 | if (err != 0) { |
335 | printk(KERN_ERR "OMAP-McBSP: Unable to " | 224 | dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d " |
336 | "request RX IRQ %d for McBSP%d\n", | 225 | "for McBSP%d\n", mcbsp[id].rx_irq, |
337 | mcbsp[id].rx_irq, mcbsp[id].id); | 226 | mcbsp[id].id); |
338 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); | 227 | free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id])); |
339 | return err; | 228 | return err; |
340 | } | 229 | } |
@@ -348,32 +237,20 @@ EXPORT_SYMBOL(omap_mcbsp_request); | |||
348 | 237 | ||
349 | void omap_mcbsp_free(unsigned int id) | 238 | void omap_mcbsp_free(unsigned int id) |
350 | { | 239 | { |
351 | if (omap_mcbsp_check(id) < 0) | 240 | if (!omap_mcbsp_check_valid_id(id)) { |
241 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
352 | return; | 242 | return; |
353 | |||
354 | #ifdef CONFIG_ARCH_OMAP1 | ||
355 | if (cpu_class_is_omap1()) { | ||
356 | if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) | ||
357 | omap_mcbsp_dsp_free(); | ||
358 | } | 243 | } |
359 | #endif | 244 | |
360 | 245 | if (mcbsp[id].pdata->ops->free) | |
361 | #ifdef CONFIG_ARCH_OMAP2 | 246 | mcbsp[id].pdata->ops->free(id); |
362 | if (cpu_is_omap24xx()) { | 247 | |
363 | if (id == OMAP_MCBSP1) { | 248 | clk_disable(mcbsp[id].clk); |
364 | clk_disable(mcbsp1_ick); | ||
365 | clk_disable(mcbsp1_fck); | ||
366 | } else { | ||
367 | clk_disable(mcbsp2_ick); | ||
368 | clk_disable(mcbsp2_fck); | ||
369 | } | ||
370 | } | ||
371 | #endif | ||
372 | 249 | ||
373 | spin_lock(&mcbsp[id].lock); | 250 | spin_lock(&mcbsp[id].lock); |
374 | if (mcbsp[id].free) { | 251 | if (mcbsp[id].free) { |
375 | printk(KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", | 252 | dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n", |
376 | id + 1); | 253 | mcbsp[id].id); |
377 | spin_unlock(&mcbsp[id].lock); | 254 | spin_unlock(&mcbsp[id].lock); |
378 | return; | 255 | return; |
379 | } | 256 | } |
@@ -399,8 +276,10 @@ void omap_mcbsp_start(unsigned int id) | |||
399 | u32 io_base; | 276 | u32 io_base; |
400 | u16 w; | 277 | u16 w; |
401 | 278 | ||
402 | if (omap_mcbsp_check(id) < 0) | 279 | if (!omap_mcbsp_check_valid_id(id)) { |
280 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
403 | return; | 281 | return; |
282 | } | ||
404 | 283 | ||
405 | io_base = mcbsp[id].io_base; | 284 | io_base = mcbsp[id].io_base; |
406 | 285 | ||
@@ -434,8 +313,10 @@ void omap_mcbsp_stop(unsigned int id) | |||
434 | u32 io_base; | 313 | u32 io_base; |
435 | u16 w; | 314 | u16 w; |
436 | 315 | ||
437 | if (omap_mcbsp_check(id) < 0) | 316 | if (!omap_mcbsp_check_valid_id(id)) { |
317 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
438 | return; | 318 | return; |
319 | } | ||
439 | 320 | ||
440 | io_base = mcbsp[id].io_base; | 321 | io_base = mcbsp[id].io_base; |
441 | 322 | ||
@@ -456,7 +337,14 @@ EXPORT_SYMBOL(omap_mcbsp_stop); | |||
456 | /* polled mcbsp i/o operations */ | 337 | /* polled mcbsp i/o operations */ |
457 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | 338 | int omap_mcbsp_pollwrite(unsigned int id, u16 buf) |
458 | { | 339 | { |
459 | u32 base = mcbsp[id].io_base; | 340 | u32 base; |
341 | |||
342 | if (!omap_mcbsp_check_valid_id(id)) { | ||
343 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | base = mcbsp[id].io_base; | ||
460 | writew(buf, base + OMAP_MCBSP_REG_DXR1); | 348 | writew(buf, base + OMAP_MCBSP_REG_DXR1); |
461 | /* if frame sync error - clear the error */ | 349 | /* if frame sync error - clear the error */ |
462 | if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { | 350 | if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) { |
@@ -478,8 +366,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf) | |||
478 | (XRST), | 366 | (XRST), |
479 | base + OMAP_MCBSP_REG_SPCR2); | 367 | base + OMAP_MCBSP_REG_SPCR2); |
480 | udelay(10); | 368 | udelay(10); |
481 | printk(KERN_ERR | 369 | dev_err(mcbsp[id].dev, "Could not write to" |
482 | " Could not write to McBSP Register\n"); | 370 | " McBSP%d Register\n", mcbsp[id].id); |
483 | return -2; | 371 | return -2; |
484 | } | 372 | } |
485 | } | 373 | } |
@@ -491,7 +379,14 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite); | |||
491 | 379 | ||
492 | int omap_mcbsp_pollread(unsigned int id, u16 *buf) | 380 | int omap_mcbsp_pollread(unsigned int id, u16 *buf) |
493 | { | 381 | { |
494 | u32 base = mcbsp[id].io_base; | 382 | u32 base; |
383 | |||
384 | if (!omap_mcbsp_check_valid_id(id)) { | ||
385 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
386 | return -ENODEV; | ||
387 | } | ||
388 | |||
389 | base = mcbsp[id].io_base; | ||
495 | /* if frame sync error - clear the error */ | 390 | /* if frame sync error - clear the error */ |
496 | if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { | 391 | if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) { |
497 | /* clear error */ | 392 | /* clear error */ |
@@ -512,8 +407,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf) | |||
512 | (RRST), | 407 | (RRST), |
513 | base + OMAP_MCBSP_REG_SPCR1); | 408 | base + OMAP_MCBSP_REG_SPCR1); |
514 | udelay(10); | 409 | udelay(10); |
515 | printk(KERN_ERR | 410 | dev_err(mcbsp[id].dev, "Could not read from" |
516 | " Could not read from McBSP Register\n"); | 411 | " McBSP%d Register\n", mcbsp[id].id); |
517 | return -2; | 412 | return -2; |
518 | } | 413 | } |
519 | } | 414 | } |
@@ -530,12 +425,15 @@ EXPORT_SYMBOL(omap_mcbsp_pollread); | |||
530 | void omap_mcbsp_xmit_word(unsigned int id, u32 word) | 425 | void omap_mcbsp_xmit_word(unsigned int id, u32 word) |
531 | { | 426 | { |
532 | u32 io_base; | 427 | u32 io_base; |
533 | omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length; | 428 | omap_mcbsp_word_length word_length; |
534 | 429 | ||
535 | if (omap_mcbsp_check(id) < 0) | 430 | if (!omap_mcbsp_check_valid_id(id)) { |
431 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
536 | return; | 432 | return; |
433 | } | ||
537 | 434 | ||
538 | io_base = mcbsp[id].io_base; | 435 | io_base = mcbsp[id].io_base; |
436 | word_length = mcbsp[id].tx_word_length; | ||
539 | 437 | ||
540 | wait_for_completion(&(mcbsp[id].tx_irq_completion)); | 438 | wait_for_completion(&(mcbsp[id].tx_irq_completion)); |
541 | 439 | ||
@@ -549,11 +447,14 @@ u32 omap_mcbsp_recv_word(unsigned int id) | |||
549 | { | 447 | { |
550 | u32 io_base; | 448 | u32 io_base; |
551 | u16 word_lsb, word_msb = 0; | 449 | u16 word_lsb, word_msb = 0; |
552 | omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length; | 450 | omap_mcbsp_word_length word_length; |
553 | 451 | ||
554 | if (omap_mcbsp_check(id) < 0) | 452 | if (!omap_mcbsp_check_valid_id(id)) { |
555 | return -EINVAL; | 453 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
454 | return -ENODEV; | ||
455 | } | ||
556 | 456 | ||
457 | word_length = mcbsp[id].rx_word_length; | ||
557 | io_base = mcbsp[id].io_base; | 458 | io_base = mcbsp[id].io_base; |
558 | 459 | ||
559 | wait_for_completion(&(mcbsp[id].rx_irq_completion)); | 460 | wait_for_completion(&(mcbsp[id].rx_irq_completion)); |
@@ -568,11 +469,20 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word); | |||
568 | 469 | ||
569 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | 470 | int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) |
570 | { | 471 | { |
571 | u32 io_base = mcbsp[id].io_base; | 472 | u32 io_base; |
572 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | 473 | omap_mcbsp_word_length tx_word_length; |
573 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | 474 | omap_mcbsp_word_length rx_word_length; |
574 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | 475 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; |
575 | 476 | ||
477 | if (!omap_mcbsp_check_valid_id(id)) { | ||
478 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
479 | return -ENODEV; | ||
480 | } | ||
481 | |||
482 | io_base = mcbsp[id].io_base; | ||
483 | tx_word_length = mcbsp[id].tx_word_length; | ||
484 | rx_word_length = mcbsp[id].rx_word_length; | ||
485 | |||
576 | if (tx_word_length != rx_word_length) | 486 | if (tx_word_length != rx_word_length) |
577 | return -EINVAL; | 487 | return -EINVAL; |
578 | 488 | ||
@@ -586,7 +496,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
586 | udelay(10); | 496 | udelay(10); |
587 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 497 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
588 | udelay(10); | 498 | udelay(10); |
589 | printk(KERN_ERR "McBSP transmitter not ready\n"); | 499 | dev_err(mcbsp[id].dev, "McBSP%d transmitter not " |
500 | "ready\n", mcbsp[id].id); | ||
590 | return -EAGAIN; | 501 | return -EAGAIN; |
591 | } | 502 | } |
592 | } | 503 | } |
@@ -606,7 +517,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word) | |||
606 | udelay(10); | 517 | udelay(10); |
607 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 518 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
608 | udelay(10); | 519 | udelay(10); |
609 | printk(KERN_ERR "McBSP receiver not ready\n"); | 520 | dev_err(mcbsp[id].dev, "McBSP%d receiver not " |
521 | "ready\n", mcbsp[id].id); | ||
610 | return -EAGAIN; | 522 | return -EAGAIN; |
611 | } | 523 | } |
612 | } | 524 | } |
@@ -622,11 +534,20 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll); | |||
622 | 534 | ||
623 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | 535 | int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) |
624 | { | 536 | { |
625 | u32 io_base = mcbsp[id].io_base, clock_word = 0; | 537 | u32 io_base, clock_word = 0; |
626 | omap_mcbsp_word_length tx_word_length = mcbsp[id].tx_word_length; | 538 | omap_mcbsp_word_length tx_word_length; |
627 | omap_mcbsp_word_length rx_word_length = mcbsp[id].rx_word_length; | 539 | omap_mcbsp_word_length rx_word_length; |
628 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; | 540 | u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0; |
629 | 541 | ||
542 | if (!omap_mcbsp_check_valid_id(id)) { | ||
543 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
544 | return -ENODEV; | ||
545 | } | ||
546 | |||
547 | io_base = mcbsp[id].io_base; | ||
548 | tx_word_length = mcbsp[id].tx_word_length; | ||
549 | rx_word_length = mcbsp[id].rx_word_length; | ||
550 | |||
630 | if (tx_word_length != rx_word_length) | 551 | if (tx_word_length != rx_word_length) |
631 | return -EINVAL; | 552 | return -EINVAL; |
632 | 553 | ||
@@ -640,7 +561,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | |||
640 | udelay(10); | 561 | udelay(10); |
641 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); | 562 | OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST); |
642 | udelay(10); | 563 | udelay(10); |
643 | printk(KERN_ERR "McBSP transmitter not ready\n"); | 564 | dev_err(mcbsp[id].dev, "McBSP%d transmitter not " |
565 | "ready\n", mcbsp[id].id); | ||
644 | return -EAGAIN; | 566 | return -EAGAIN; |
645 | } | 567 | } |
646 | } | 568 | } |
@@ -660,7 +582,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word) | |||
660 | udelay(10); | 582 | udelay(10); |
661 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); | 583 | OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST); |
662 | udelay(10); | 584 | udelay(10); |
663 | printk(KERN_ERR "McBSP receiver not ready\n"); | 585 | dev_err(mcbsp[id].dev, "McBSP%d receiver not " |
586 | "ready\n", mcbsp[id].id); | ||
664 | return -EAGAIN; | 587 | return -EAGAIN; |
665 | } | 588 | } |
666 | } | 589 | } |
@@ -691,20 +614,24 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, | |||
691 | int dest_port = 0; | 614 | int dest_port = 0; |
692 | int sync_dev = 0; | 615 | int sync_dev = 0; |
693 | 616 | ||
694 | if (omap_mcbsp_check(id) < 0) | 617 | if (!omap_mcbsp_check_valid_id(id)) { |
695 | return -EINVAL; | 618 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
619 | return -ENODEV; | ||
620 | } | ||
696 | 621 | ||
697 | if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", | 622 | if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", |
698 | omap_mcbsp_tx_dma_callback, | 623 | omap_mcbsp_tx_dma_callback, |
699 | &mcbsp[id], | 624 | &mcbsp[id], |
700 | &dma_tx_ch)) { | 625 | &dma_tx_ch)) { |
701 | printk(KERN_ERR "OMAP-McBSP: Unable to request DMA channel for" | 626 | dev_err(mcbsp[id].dev, " Unable to request DMA channel for " |
702 | " McBSP%d TX. Trying IRQ based TX\n", id + 1); | 627 | "McBSP%d TX. Trying IRQ based TX\n", |
628 | mcbsp[id].id); | ||
703 | return -EAGAIN; | 629 | return -EAGAIN; |
704 | } | 630 | } |
705 | mcbsp[id].dma_tx_lch = dma_tx_ch; | 631 | mcbsp[id].dma_tx_lch = dma_tx_ch; |
706 | 632 | ||
707 | DBG("TX DMA on channel %d\n", dma_tx_ch); | 633 | dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id, |
634 | dma_tx_ch); | ||
708 | 635 | ||
709 | init_completion(&(mcbsp[id].tx_dma_completion)); | 636 | init_completion(&(mcbsp[id].tx_dma_completion)); |
710 | 637 | ||
@@ -712,7 +639,7 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, | |||
712 | src_port = OMAP_DMA_PORT_TIPB; | 639 | src_port = OMAP_DMA_PORT_TIPB; |
713 | dest_port = OMAP_DMA_PORT_EMIFF; | 640 | dest_port = OMAP_DMA_PORT_EMIFF; |
714 | } | 641 | } |
715 | if (cpu_is_omap24xx()) | 642 | if (cpu_class_is_omap2()) |
716 | sync_dev = mcbsp[id].dma_tx_sync; | 643 | sync_dev = mcbsp[id].dma_tx_sync; |
717 | 644 | ||
718 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, | 645 | omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch, |
@@ -748,20 +675,24 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, | |||
748 | int dest_port = 0; | 675 | int dest_port = 0; |
749 | int sync_dev = 0; | 676 | int sync_dev = 0; |
750 | 677 | ||
751 | if (omap_mcbsp_check(id) < 0) | 678 | if (!omap_mcbsp_check_valid_id(id)) { |
752 | return -EINVAL; | 679 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); |
680 | return -ENODEV; | ||
681 | } | ||
753 | 682 | ||
754 | if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", | 683 | if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", |
755 | omap_mcbsp_rx_dma_callback, | 684 | omap_mcbsp_rx_dma_callback, |
756 | &mcbsp[id], | 685 | &mcbsp[id], |
757 | &dma_rx_ch)) { | 686 | &dma_rx_ch)) { |
758 | printk(KERN_ERR "Unable to request DMA channel for McBSP%d RX." | 687 | dev_err(mcbsp[id].dev, "Unable to request DMA channel for " |
759 | " Trying IRQ based RX\n", id + 1); | 688 | "McBSP%d RX. Trying IRQ based RX\n", |
689 | mcbsp[id].id); | ||
760 | return -EAGAIN; | 690 | return -EAGAIN; |
761 | } | 691 | } |
762 | mcbsp[id].dma_rx_lch = dma_rx_ch; | 692 | mcbsp[id].dma_rx_lch = dma_rx_ch; |
763 | 693 | ||
764 | DBG("RX DMA on channel %d\n", dma_rx_ch); | 694 | dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id, |
695 | dma_rx_ch); | ||
765 | 696 | ||
766 | init_completion(&(mcbsp[id].rx_dma_completion)); | 697 | init_completion(&(mcbsp[id].rx_dma_completion)); |
767 | 698 | ||
@@ -769,7 +700,7 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, | |||
769 | src_port = OMAP_DMA_PORT_TIPB; | 700 | src_port = OMAP_DMA_PORT_TIPB; |
770 | dest_port = OMAP_DMA_PORT_EMIFF; | 701 | dest_port = OMAP_DMA_PORT_EMIFF; |
771 | } | 702 | } |
772 | if (cpu_is_omap24xx()) | 703 | if (cpu_class_is_omap2()) |
773 | sync_dev = mcbsp[id].dma_rx_sync; | 704 | sync_dev = mcbsp[id].dma_rx_sync; |
774 | 705 | ||
775 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, | 706 | omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch, |
@@ -808,8 +739,10 @@ void omap_mcbsp_set_spi_mode(unsigned int id, | |||
808 | { | 739 | { |
809 | struct omap_mcbsp_reg_cfg mcbsp_cfg; | 740 | struct omap_mcbsp_reg_cfg mcbsp_cfg; |
810 | 741 | ||
811 | if (omap_mcbsp_check(id) < 0) | 742 | if (!omap_mcbsp_check_valid_id(id)) { |
743 | printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); | ||
812 | return; | 744 | return; |
745 | } | ||
813 | 746 | ||
814 | memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); | 747 | memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg)); |
815 | 748 | ||
@@ -870,182 +803,93 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); | |||
870 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. | 803 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. |
871 | * 730 has only 2 McBSP, and both of them are MPU peripherals. | 804 | * 730 has only 2 McBSP, and both of them are MPU peripherals. |
872 | */ | 805 | */ |
873 | struct omap_mcbsp_info { | 806 | static int __init omap_mcbsp_probe(struct platform_device *pdev) |
874 | u32 virt_base; | 807 | { |
875 | u8 dma_rx_sync, dma_tx_sync; | 808 | struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; |
876 | u16 rx_irq, tx_irq; | 809 | int id = pdev->id - 1; |
877 | }; | 810 | int ret = 0; |
878 | 811 | ||
879 | #ifdef CONFIG_ARCH_OMAP730 | 812 | if (!pdata) { |
880 | static const struct omap_mcbsp_info mcbsp_730[] = { | 813 | dev_err(&pdev->dev, "McBSP device initialized without" |
881 | [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE), | 814 | "platform data\n"); |
882 | .dma_rx_sync = OMAP_DMA_MCBSP1_RX, | 815 | ret = -EINVAL; |
883 | .dma_tx_sync = OMAP_DMA_MCBSP1_TX, | 816 | goto exit; |
884 | .rx_irq = INT_730_McBSP1RX, | 817 | } |
885 | .tx_irq = INT_730_McBSP1TX }, | 818 | |
886 | [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE), | 819 | dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id); |
887 | .dma_rx_sync = OMAP_DMA_MCBSP3_RX, | 820 | |
888 | .dma_tx_sync = OMAP_DMA_MCBSP3_TX, | 821 | if (id >= OMAP_MAX_MCBSP_COUNT) { |
889 | .rx_irq = INT_730_McBSP2RX, | 822 | dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id); |
890 | .tx_irq = INT_730_McBSP2TX }, | 823 | ret = -EINVAL; |
891 | }; | 824 | goto exit; |
892 | #endif | 825 | } |
893 | 826 | ||
894 | #ifdef CONFIG_ARCH_OMAP15XX | 827 | spin_lock_init(&mcbsp[id].lock); |
895 | static const struct omap_mcbsp_info mcbsp_1510[] = { | 828 | mcbsp[id].id = id + 1; |
896 | [0] = { .virt_base = OMAP1510_MCBSP1_BASE, | 829 | mcbsp[id].free = 1; |
897 | .dma_rx_sync = OMAP_DMA_MCBSP1_RX, | 830 | mcbsp[id].dma_tx_lch = -1; |
898 | .dma_tx_sync = OMAP_DMA_MCBSP1_TX, | 831 | mcbsp[id].dma_rx_lch = -1; |
899 | .rx_irq = INT_McBSP1RX, | 832 | |
900 | .tx_irq = INT_McBSP1TX }, | 833 | mcbsp[id].io_base = pdata->virt_base; |
901 | [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE), | 834 | /* Default I/O is IRQ based */ |
902 | .dma_rx_sync = OMAP_DMA_MCBSP2_RX, | 835 | mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO; |
903 | .dma_tx_sync = OMAP_DMA_MCBSP2_TX, | 836 | mcbsp[id].tx_irq = pdata->tx_irq; |
904 | .rx_irq = INT_1510_SPI_RX, | 837 | mcbsp[id].rx_irq = pdata->rx_irq; |
905 | .tx_irq = INT_1510_SPI_TX }, | 838 | mcbsp[id].dma_rx_sync = pdata->dma_rx_sync; |
906 | [2] = { .virt_base = OMAP1510_MCBSP3_BASE, | 839 | mcbsp[id].dma_tx_sync = pdata->dma_tx_sync; |
907 | .dma_rx_sync = OMAP_DMA_MCBSP3_RX, | 840 | |
908 | .dma_tx_sync = OMAP_DMA_MCBSP3_TX, | 841 | if (pdata->clk_name) |
909 | .rx_irq = INT_McBSP3RX, | 842 | mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name); |
910 | .tx_irq = INT_McBSP3TX }, | 843 | if (IS_ERR(mcbsp[id].clk)) { |
911 | }; | 844 | mcbsp[id].free = 0; |
912 | #endif | 845 | dev_err(&pdev->dev, |
913 | 846 | "Invalid clock configuration for McBSP%d.\n", | |
914 | #if defined(CONFIG_ARCH_OMAP16XX) | 847 | mcbsp[id].id); |
915 | static const struct omap_mcbsp_info mcbsp_1610[] = { | 848 | ret = -EINVAL; |
916 | [0] = { .virt_base = OMAP1610_MCBSP1_BASE, | 849 | goto exit; |
917 | .dma_rx_sync = OMAP_DMA_MCBSP1_RX, | 850 | } |
918 | .dma_tx_sync = OMAP_DMA_MCBSP1_TX, | 851 | |
919 | .rx_irq = INT_McBSP1RX, | 852 | mcbsp[id].pdata = pdata; |
920 | .tx_irq = INT_McBSP1TX }, | 853 | mcbsp[id].dev = &pdev->dev; |
921 | [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE), | 854 | platform_set_drvdata(pdev, &mcbsp[id]); |
922 | .dma_rx_sync = OMAP_DMA_MCBSP2_RX, | 855 | |
923 | .dma_tx_sync = OMAP_DMA_MCBSP2_TX, | 856 | exit: |
924 | .rx_irq = INT_1610_McBSP2_RX, | 857 | return ret; |
925 | .tx_irq = INT_1610_McBSP2_TX }, | 858 | } |
926 | [2] = { .virt_base = OMAP1610_MCBSP3_BASE, | ||
927 | .dma_rx_sync = OMAP_DMA_MCBSP3_RX, | ||
928 | .dma_tx_sync = OMAP_DMA_MCBSP3_TX, | ||
929 | .rx_irq = INT_McBSP3RX, | ||
930 | .tx_irq = INT_McBSP3TX }, | ||
931 | }; | ||
932 | #endif | ||
933 | |||
934 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
935 | static const struct omap_mcbsp_info mcbsp_24xx[] = { | ||
936 | [0] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), | ||
937 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
938 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
939 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
940 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
941 | }, | ||
942 | [1] = { .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), | ||
943 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
944 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
945 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
946 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
947 | }, | ||
948 | }; | ||
949 | #endif | ||
950 | 859 | ||
951 | static int __init omap_mcbsp_init(void) | 860 | static int omap_mcbsp_remove(struct platform_device *pdev) |
952 | { | 861 | { |
953 | int mcbsp_count = 0, i; | 862 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); |
954 | static const struct omap_mcbsp_info *mcbsp_info; | ||
955 | 863 | ||
956 | printk(KERN_INFO "Initializing OMAP McBSP system\n"); | 864 | platform_set_drvdata(pdev, NULL); |
865 | if (mcbsp) { | ||
957 | 866 | ||
958 | #ifdef CONFIG_ARCH_OMAP1 | 867 | if (mcbsp->pdata && mcbsp->pdata->ops && |
959 | mcbsp_dsp_ck = clk_get(0, "dsp_ck"); | 868 | mcbsp->pdata->ops->free) |
960 | if (IS_ERR(mcbsp_dsp_ck)) { | 869 | mcbsp->pdata->ops->free(mcbsp->id); |
961 | printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n"); | ||
962 | return PTR_ERR(mcbsp_dsp_ck); | ||
963 | } | ||
964 | mcbsp_api_ck = clk_get(0, "api_ck"); | ||
965 | if (IS_ERR(mcbsp_api_ck)) { | ||
966 | printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n"); | ||
967 | return PTR_ERR(mcbsp_api_ck); | ||
968 | } | ||
969 | mcbsp_dspxor_ck = clk_get(0, "dspxor_ck"); | ||
970 | if (IS_ERR(mcbsp_dspxor_ck)) { | ||
971 | printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n"); | ||
972 | return PTR_ERR(mcbsp_dspxor_ck); | ||
973 | } | ||
974 | #endif | ||
975 | #ifdef CONFIG_ARCH_OMAP2 | ||
976 | mcbsp1_ick = clk_get(0, "mcbsp1_ick"); | ||
977 | if (IS_ERR(mcbsp1_ick)) { | ||
978 | printk(KERN_ERR "mcbsp: could not acquire " | ||
979 | "mcbsp1_ick handle.\n"); | ||
980 | return PTR_ERR(mcbsp1_ick); | ||
981 | } | ||
982 | mcbsp1_fck = clk_get(0, "mcbsp1_fck"); | ||
983 | if (IS_ERR(mcbsp1_fck)) { | ||
984 | printk(KERN_ERR "mcbsp: could not acquire " | ||
985 | "mcbsp1_fck handle.\n"); | ||
986 | return PTR_ERR(mcbsp1_fck); | ||
987 | } | ||
988 | mcbsp2_ick = clk_get(0, "mcbsp2_ick"); | ||
989 | if (IS_ERR(mcbsp2_ick)) { | ||
990 | printk(KERN_ERR "mcbsp: could not acquire " | ||
991 | "mcbsp2_ick handle.\n"); | ||
992 | return PTR_ERR(mcbsp2_ick); | ||
993 | } | ||
994 | mcbsp2_fck = clk_get(0, "mcbsp2_fck"); | ||
995 | if (IS_ERR(mcbsp2_fck)) { | ||
996 | printk(KERN_ERR "mcbsp: could not acquire " | ||
997 | "mcbsp2_fck handle.\n"); | ||
998 | return PTR_ERR(mcbsp2_fck); | ||
999 | } | ||
1000 | #endif | ||
1001 | 870 | ||
1002 | #ifdef CONFIG_ARCH_OMAP730 | 871 | clk_disable(mcbsp->clk); |
1003 | if (cpu_is_omap730()) { | 872 | clk_put(mcbsp->clk); |
1004 | mcbsp_info = mcbsp_730; | 873 | |
1005 | mcbsp_count = ARRAY_SIZE(mcbsp_730); | 874 | mcbsp->clk = NULL; |
1006 | } | 875 | mcbsp->free = 0; |
1007 | #endif | 876 | mcbsp->dev = NULL; |
1008 | #ifdef CONFIG_ARCH_OMAP15XX | ||
1009 | if (cpu_is_omap15xx()) { | ||
1010 | mcbsp_info = mcbsp_1510; | ||
1011 | mcbsp_count = ARRAY_SIZE(mcbsp_1510); | ||
1012 | } | ||
1013 | #endif | ||
1014 | #if defined(CONFIG_ARCH_OMAP16XX) | ||
1015 | if (cpu_is_omap16xx()) { | ||
1016 | mcbsp_info = mcbsp_1610; | ||
1017 | mcbsp_count = ARRAY_SIZE(mcbsp_1610); | ||
1018 | } | ||
1019 | #endif | ||
1020 | #if defined(CONFIG_ARCH_OMAP24XX) | ||
1021 | if (cpu_is_omap24xx()) { | ||
1022 | mcbsp_info = mcbsp_24xx; | ||
1023 | mcbsp_count = ARRAY_SIZE(mcbsp_24xx); | ||
1024 | omap2_mcbsp2_mux_setup(); | ||
1025 | } | ||
1026 | #endif | ||
1027 | for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { | ||
1028 | if (i >= mcbsp_count) { | ||
1029 | mcbsp[i].io_base = 0; | ||
1030 | mcbsp[i].free = 0; | ||
1031 | continue; | ||
1032 | } | ||
1033 | mcbsp[i].id = i + 1; | ||
1034 | mcbsp[i].free = 1; | ||
1035 | mcbsp[i].dma_tx_lch = -1; | ||
1036 | mcbsp[i].dma_rx_lch = -1; | ||
1037 | |||
1038 | mcbsp[i].io_base = mcbsp_info[i].virt_base; | ||
1039 | /* Default I/O is IRQ based */ | ||
1040 | mcbsp[i].io_type = OMAP_MCBSP_IRQ_IO; | ||
1041 | mcbsp[i].tx_irq = mcbsp_info[i].tx_irq; | ||
1042 | mcbsp[i].rx_irq = mcbsp_info[i].rx_irq; | ||
1043 | mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync; | ||
1044 | mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync; | ||
1045 | spin_lock_init(&mcbsp[i].lock); | ||
1046 | } | 877 | } |
1047 | 878 | ||
1048 | return 0; | 879 | return 0; |
1049 | } | 880 | } |
1050 | 881 | ||
1051 | arch_initcall(omap_mcbsp_init); | 882 | static struct platform_driver omap_mcbsp_driver = { |
883 | .probe = omap_mcbsp_probe, | ||
884 | .remove = omap_mcbsp_remove, | ||
885 | .driver = { | ||
886 | .name = "omap-mcbsp", | ||
887 | }, | ||
888 | }; | ||
889 | |||
890 | int __init omap_mcbsp_init(void) | ||
891 | { | ||
892 | /* Register the McBSP driver */ | ||
893 | return platform_driver_register(&omap_mcbsp_driver); | ||
894 | } | ||
895 | |||