diff options
Diffstat (limited to 'arch/arm/mach-omap2/mcbsp.c')
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 231 |
1 files changed, 53 insertions, 178 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 0526b758bdcc..565b9064a328 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -22,10 +22,11 @@ | |||
22 | #include <plat/dma.h> | 22 | #include <plat/dma.h> |
23 | #include <plat/cpu.h> | 23 | #include <plat/cpu.h> |
24 | #include <plat/mcbsp.h> | 24 | #include <plat/mcbsp.h> |
25 | #include <plat/omap_device.h> | ||
26 | #include <linux/pm_runtime.h> | ||
25 | 27 | ||
26 | #include "control.h" | 28 | #include "control.h" |
27 | 29 | ||
28 | |||
29 | /* McBSP internal signal muxing functions */ | 30 | /* McBSP internal signal muxing functions */ |
30 | 31 | ||
31 | void omap2_mcbsp1_mux_clkr_src(u8 mux) | 32 | void omap2_mcbsp1_mux_clkr_src(u8 mux) |
@@ -83,7 +84,7 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) | |||
83 | return -EINVAL; | 84 | return -EINVAL; |
84 | } | 85 | } |
85 | 86 | ||
86 | clk_disable(mcbsp->fclk); | 87 | pm_runtime_put_sync(mcbsp->dev); |
87 | 88 | ||
88 | r = clk_set_parent(mcbsp->fclk, fck_src); | 89 | r = clk_set_parent(mcbsp->fclk, fck_src); |
89 | if (IS_ERR_VALUE(r)) { | 90 | if (IS_ERR_VALUE(r)) { |
@@ -93,7 +94,7 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) | |||
93 | return -EINVAL; | 94 | return -EINVAL; |
94 | } | 95 | } |
95 | 96 | ||
96 | clk_enable(mcbsp->fclk); | 97 | pm_runtime_get_sync(mcbsp->dev); |
97 | 98 | ||
98 | clk_put(fck_src); | 99 | clk_put(fck_src); |
99 | 100 | ||
@@ -101,196 +102,70 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) | |||
101 | } | 102 | } |
102 | EXPORT_SYMBOL(omap2_mcbsp_set_clks_src); | 103 | EXPORT_SYMBOL(omap2_mcbsp_set_clks_src); |
103 | 104 | ||
104 | 105 | struct omap_device_pm_latency omap2_mcbsp_latency[] = { | |
105 | /* Platform data */ | ||
106 | |||
107 | #ifdef CONFIG_SOC_OMAP2420 | ||
108 | static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { | ||
109 | { | 106 | { |
110 | .phys_base = OMAP24XX_MCBSP1_BASE, | 107 | .deactivate_func = omap_device_idle_hwmods, |
111 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | 108 | .activate_func = omap_device_enable_hwmods, |
112 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | 109 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, |
113 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
114 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
115 | }, | ||
116 | { | ||
117 | .phys_base = OMAP24XX_MCBSP2_BASE, | ||
118 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
119 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
120 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
121 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
122 | }, | 110 | }, |
123 | }; | 111 | }; |
124 | #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) | ||
125 | #define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
126 | #else | ||
127 | #define omap2420_mcbsp_pdata NULL | ||
128 | #define OMAP2420_MCBSP_PDATA_SZ 0 | ||
129 | #define OMAP2420_MCBSP_REG_NUM 0 | ||
130 | #endif | ||
131 | 112 | ||
132 | #ifdef CONFIG_SOC_OMAP2430 | 113 | static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) |
133 | static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { | 114 | { |
134 | { | 115 | int id, count = 1; |
135 | .phys_base = OMAP24XX_MCBSP1_BASE, | 116 | char *name = "omap-mcbsp"; |
136 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | 117 | struct omap_hwmod *oh_device[2]; |
137 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | 118 | struct omap_mcbsp_platform_data *pdata = NULL; |
138 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | 119 | struct omap_device *od; |
139 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
140 | }, | ||
141 | { | ||
142 | .phys_base = OMAP24XX_MCBSP2_BASE, | ||
143 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
144 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
145 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
146 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
147 | }, | ||
148 | { | ||
149 | .phys_base = OMAP2430_MCBSP3_BASE, | ||
150 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, | ||
151 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | ||
152 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | ||
153 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | ||
154 | }, | ||
155 | { | ||
156 | .phys_base = OMAP2430_MCBSP4_BASE, | ||
157 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | ||
158 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | ||
159 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | ||
160 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | ||
161 | }, | ||
162 | { | ||
163 | .phys_base = OMAP2430_MCBSP5_BASE, | ||
164 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | ||
165 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | ||
166 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | ||
167 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | ||
168 | }, | ||
169 | }; | ||
170 | #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) | ||
171 | #define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
172 | #else | ||
173 | #define omap2430_mcbsp_pdata NULL | ||
174 | #define OMAP2430_MCBSP_PDATA_SZ 0 | ||
175 | #define OMAP2430_MCBSP_REG_NUM 0 | ||
176 | #endif | ||
177 | 120 | ||
178 | #ifdef CONFIG_ARCH_OMAP3 | 121 | sscanf(oh->name, "mcbsp%d", &id); |
179 | static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | ||
180 | { | ||
181 | .phys_base = OMAP34XX_MCBSP1_BASE, | ||
182 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
183 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
184 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
185 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
186 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
187 | }, | ||
188 | { | ||
189 | .phys_base = OMAP34XX_MCBSP2_BASE, | ||
190 | .phys_base_st = OMAP34XX_MCBSP2_ST_BASE, | ||
191 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
192 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
193 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
194 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
195 | .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ | ||
196 | }, | ||
197 | { | ||
198 | .phys_base = OMAP34XX_MCBSP3_BASE, | ||
199 | .phys_base_st = OMAP34XX_MCBSP3_ST_BASE, | ||
200 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, | ||
201 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | ||
202 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | ||
203 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | ||
204 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
205 | }, | ||
206 | { | ||
207 | .phys_base = OMAP34XX_MCBSP4_BASE, | ||
208 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | ||
209 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | ||
210 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | ||
211 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | ||
212 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
213 | }, | ||
214 | { | ||
215 | .phys_base = OMAP34XX_MCBSP5_BASE, | ||
216 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | ||
217 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | ||
218 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | ||
219 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | ||
220 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
221 | }, | ||
222 | }; | ||
223 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | ||
224 | #define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
225 | #else | ||
226 | #define omap34xx_mcbsp_pdata NULL | ||
227 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | ||
228 | #define OMAP34XX_MCBSP_REG_NUM 0 | ||
229 | #endif | ||
230 | 122 | ||
231 | static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { | 123 | pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); |
232 | { | 124 | if (!pdata) { |
233 | .phys_base = OMAP44XX_MCBSP1_BASE, | 125 | pr_err("%s: No memory for mcbsp\n", __func__); |
234 | .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, | 126 | return -ENOMEM; |
235 | .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, | 127 | } |
236 | .tx_irq = OMAP44XX_IRQ_MCBSP1, | 128 | |
237 | }, | 129 | pdata->mcbsp_config_type = oh->class->rev; |
238 | { | 130 | |
239 | .phys_base = OMAP44XX_MCBSP2_BASE, | 131 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { |
240 | .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, | 132 | if (id == 2) |
241 | .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, | 133 | /* The FIFO has 1024 + 256 locations */ |
242 | .tx_irq = OMAP44XX_IRQ_MCBSP2, | 134 | pdata->buffer_size = 0x500; |
243 | }, | 135 | else |
244 | { | 136 | /* The FIFO has 128 locations */ |
245 | .phys_base = OMAP44XX_MCBSP3_BASE, | 137 | pdata->buffer_size = 0x80; |
246 | .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, | 138 | } |
247 | .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, | 139 | |
248 | .tx_irq = OMAP44XX_IRQ_MCBSP3, | 140 | oh_device[0] = oh; |
249 | }, | 141 | |
250 | { | 142 | if (oh->dev_attr) { |
251 | .phys_base = OMAP44XX_MCBSP4_BASE, | 143 | oh_device[1] = omap_hwmod_lookup(( |
252 | .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, | 144 | (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); |
253 | .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, | 145 | count++; |
254 | .tx_irq = OMAP44XX_IRQ_MCBSP4, | 146 | } |
255 | }, | 147 | od = omap_device_build_ss(name, id, oh_device, count, pdata, |
256 | }; | 148 | sizeof(*pdata), omap2_mcbsp_latency, |
257 | #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) | 149 | ARRAY_SIZE(omap2_mcbsp_latency), false); |
258 | #define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | 150 | kfree(pdata); |
151 | if (IS_ERR(od)) { | ||
152 | pr_err("%s: Cant build omap_device for %s:%s.\n", __func__, | ||
153 | name, oh->name); | ||
154 | return PTR_ERR(od); | ||
155 | } | ||
156 | omap_mcbsp_count++; | ||
157 | return 0; | ||
158 | } | ||
259 | 159 | ||
260 | static int __init omap2_mcbsp_init(void) | 160 | static int __init omap2_mcbsp_init(void) |
261 | { | 161 | { |
262 | if (cpu_is_omap2420()) { | 162 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); |
263 | omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; | ||
264 | omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16); | ||
265 | } else if (cpu_is_omap2430()) { | ||
266 | omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; | ||
267 | omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32); | ||
268 | } else if (cpu_is_omap34xx()) { | ||
269 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; | ||
270 | omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32); | ||
271 | } else if (cpu_is_omap44xx()) { | ||
272 | omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; | ||
273 | omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32); | ||
274 | } | ||
275 | 163 | ||
276 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | 164 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), |
277 | GFP_KERNEL); | 165 | GFP_KERNEL); |
278 | if (!mcbsp_ptr) | 166 | if (!mcbsp_ptr) |
279 | return -ENOMEM; | 167 | return -ENOMEM; |
280 | 168 | ||
281 | if (cpu_is_omap2420()) | ||
282 | omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, | ||
283 | OMAP2420_MCBSP_PDATA_SZ); | ||
284 | if (cpu_is_omap2430()) | ||
285 | omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, | ||
286 | OMAP2430_MCBSP_PDATA_SZ); | ||
287 | if (cpu_is_omap34xx()) | ||
288 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | ||
289 | OMAP34XX_MCBSP_PDATA_SZ); | ||
290 | if (cpu_is_omap44xx()) | ||
291 | omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, | ||
292 | OMAP44XX_MCBSP_PDATA_SZ); | ||
293 | |||
294 | return omap_mcbsp_init(); | 169 | return omap_mcbsp_init(); |
295 | } | 170 | } |
296 | arch_initcall(omap2_mcbsp_init); | 171 | arch_initcall(omap2_mcbsp_init); |