diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/arm/mach-omap2/mcbsp.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'arch/arm/mach-omap2/mcbsp.c')
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 330 |
1 files changed, 123 insertions, 207 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 467aae245781..4a6ef6ab8458 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -22,234 +22,150 @@ | |||
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 "mux.h" | 28 | #include "control.h" |
27 | 29 | ||
28 | static void omap2_mcbsp2_mux_setup(void) | 30 | /* McBSP internal signal muxing functions */ |
31 | |||
32 | void omap2_mcbsp1_mux_clkr_src(u8 mux) | ||
29 | { | 33 | { |
30 | omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA); | 34 | u32 v; |
31 | omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA); | 35 | |
32 | omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA); | 36 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); |
33 | omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA); | 37 | if (mux == CLKR_SRC_CLKR) |
34 | omap_mux_init_gpio(117, OMAP_PULL_ENA); | 38 | v &= ~OMAP2_MCBSP1_CLKR_MASK; |
35 | /* | 39 | else if (mux == CLKR_SRC_CLKX) |
36 | * TODO: Need to add MUX settings for OMAP 2430 SDP | 40 | v |= OMAP2_MCBSP1_CLKR_MASK; |
37 | */ | 41 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); |
38 | } | 42 | } |
43 | EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src); | ||
39 | 44 | ||
40 | static void omap2_mcbsp_request(unsigned int id) | 45 | void omap2_mcbsp1_mux_fsr_src(u8 mux) |
41 | { | 46 | { |
42 | if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) | 47 | u32 v; |
43 | omap2_mcbsp2_mux_setup(); | 48 | |
49 | v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); | ||
50 | if (mux == FSR_SRC_FSR) | ||
51 | v &= ~OMAP2_MCBSP1_FSR_MASK; | ||
52 | else if (mux == FSR_SRC_FSX) | ||
53 | v |= OMAP2_MCBSP1_FSR_MASK; | ||
54 | omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); | ||
44 | } | 55 | } |
56 | EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); | ||
45 | 57 | ||
46 | static struct omap_mcbsp_ops omap2_mcbsp_ops = { | 58 | /* McBSP CLKS source switching function */ |
47 | .request = omap2_mcbsp_request, | ||
48 | }; | ||
49 | 59 | ||
50 | #ifdef CONFIG_ARCH_OMAP2420 | 60 | int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id) |
51 | static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { | 61 | { |
52 | { | 62 | struct omap_mcbsp *mcbsp; |
53 | .phys_base = OMAP24XX_MCBSP1_BASE, | 63 | struct clk *fck_src; |
54 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | 64 | char *fck_src_name; |
55 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | 65 | int r; |
56 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | 66 | |
57 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | 67 | if (!omap_mcbsp_check_valid_id(id)) { |
58 | .ops = &omap2_mcbsp_ops, | 68 | pr_err("%s: Invalid id (%d)\n", __func__, id + 1); |
59 | }, | 69 | return -EINVAL; |
60 | { | 70 | } |
61 | .phys_base = OMAP24XX_MCBSP2_BASE, | 71 | mcbsp = id_to_mcbsp_ptr(id); |
62 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | 72 | |
63 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | 73 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) |
64 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | 74 | fck_src_name = "pad_fck"; |
65 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | 75 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) |
66 | .ops = &omap2_mcbsp_ops, | 76 | fck_src_name = "prcm_fck"; |
67 | }, | 77 | else |
68 | }; | 78 | return -EINVAL; |
69 | #define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) | 79 | |
70 | #define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | 80 | fck_src = clk_get(mcbsp->dev, fck_src_name); |
71 | #else | 81 | if (IS_ERR_OR_NULL(fck_src)) { |
72 | #define omap2420_mcbsp_pdata NULL | 82 | pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks", |
73 | #define OMAP2420_MCBSP_PDATA_SZ 0 | 83 | fck_src_name); |
74 | #define OMAP2420_MCBSP_REG_NUM 0 | 84 | return -EINVAL; |
75 | #endif | 85 | } |
76 | 86 | ||
77 | #ifdef CONFIG_ARCH_OMAP2430 | 87 | pm_runtime_put_sync(mcbsp->dev); |
78 | static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { | 88 | |
79 | { | 89 | r = clk_set_parent(mcbsp->fclk, fck_src); |
80 | .phys_base = OMAP24XX_MCBSP1_BASE, | 90 | if (IS_ERR_VALUE(r)) { |
81 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | 91 | pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n", |
82 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | 92 | "clks", fck_src_name); |
83 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | 93 | clk_put(fck_src); |
84 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | 94 | return -EINVAL; |
85 | .ops = &omap2_mcbsp_ops, | 95 | } |
86 | }, | 96 | |
87 | { | 97 | pm_runtime_get_sync(mcbsp->dev); |
88 | .phys_base = OMAP24XX_MCBSP2_BASE, | 98 | |
89 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | 99 | clk_put(fck_src); |
90 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | 100 | |
91 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | 101 | return 0; |
92 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | 102 | } |
93 | .ops = &omap2_mcbsp_ops, | 103 | EXPORT_SYMBOL(omap2_mcbsp_set_clks_src); |
94 | }, | 104 | |
95 | { | 105 | struct omap_device_pm_latency omap2_mcbsp_latency[] = { |
96 | .phys_base = OMAP2430_MCBSP3_BASE, | ||
97 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, | ||
98 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | ||
99 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | ||
100 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | ||
101 | .ops = &omap2_mcbsp_ops, | ||
102 | }, | ||
103 | { | ||
104 | .phys_base = OMAP2430_MCBSP4_BASE, | ||
105 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | ||
106 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | ||
107 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | ||
108 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | ||
109 | .ops = &omap2_mcbsp_ops, | ||
110 | }, | ||
111 | { | ||
112 | .phys_base = OMAP2430_MCBSP5_BASE, | ||
113 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | ||
114 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | ||
115 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | ||
116 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | ||
117 | .ops = &omap2_mcbsp_ops, | ||
118 | }, | ||
119 | }; | ||
120 | #define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) | ||
121 | #define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
122 | #else | ||
123 | #define omap2430_mcbsp_pdata NULL | ||
124 | #define OMAP2430_MCBSP_PDATA_SZ 0 | ||
125 | #define OMAP2430_MCBSP_REG_NUM 0 | ||
126 | #endif | ||
127 | |||
128 | #ifdef CONFIG_ARCH_OMAP3 | ||
129 | static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | ||
130 | { | ||
131 | .phys_base = OMAP34XX_MCBSP1_BASE, | ||
132 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
133 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
134 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
135 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
136 | .ops = &omap2_mcbsp_ops, | ||
137 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
138 | }, | ||
139 | { | ||
140 | .phys_base = OMAP34XX_MCBSP2_BASE, | ||
141 | .phys_base_st = OMAP34XX_MCBSP2_ST_BASE, | ||
142 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
143 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
144 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
145 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
146 | .ops = &omap2_mcbsp_ops, | ||
147 | .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ | ||
148 | }, | ||
149 | { | ||
150 | .phys_base = OMAP34XX_MCBSP3_BASE, | ||
151 | .phys_base_st = OMAP34XX_MCBSP3_ST_BASE, | ||
152 | .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, | ||
153 | .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, | ||
154 | .rx_irq = INT_24XX_MCBSP3_IRQ_RX, | ||
155 | .tx_irq = INT_24XX_MCBSP3_IRQ_TX, | ||
156 | .ops = &omap2_mcbsp_ops, | ||
157 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
158 | }, | ||
159 | { | ||
160 | .phys_base = OMAP34XX_MCBSP4_BASE, | ||
161 | .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, | ||
162 | .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, | ||
163 | .rx_irq = INT_24XX_MCBSP4_IRQ_RX, | ||
164 | .tx_irq = INT_24XX_MCBSP4_IRQ_TX, | ||
165 | .ops = &omap2_mcbsp_ops, | ||
166 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
167 | }, | ||
168 | { | ||
169 | .phys_base = OMAP34XX_MCBSP5_BASE, | ||
170 | .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, | ||
171 | .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, | ||
172 | .rx_irq = INT_24XX_MCBSP5_IRQ_RX, | ||
173 | .tx_irq = INT_24XX_MCBSP5_IRQ_TX, | ||
174 | .ops = &omap2_mcbsp_ops, | ||
175 | .buffer_size = 0x80, /* The FIFO has 128 locations */ | ||
176 | }, | ||
177 | }; | ||
178 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | ||
179 | #define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
180 | #else | ||
181 | #define omap34xx_mcbsp_pdata NULL | ||
182 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | ||
183 | #define OMAP34XX_MCBSP_REG_NUM 0 | ||
184 | #endif | ||
185 | |||
186 | static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { | ||
187 | { | ||
188 | .phys_base = OMAP44XX_MCBSP1_BASE, | ||
189 | .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, | ||
190 | .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, | ||
191 | .tx_irq = OMAP44XX_IRQ_MCBSP1, | ||
192 | .ops = &omap2_mcbsp_ops, | ||
193 | }, | ||
194 | { | ||
195 | .phys_base = OMAP44XX_MCBSP2_BASE, | ||
196 | .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, | ||
197 | .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, | ||
198 | .tx_irq = OMAP44XX_IRQ_MCBSP2, | ||
199 | .ops = &omap2_mcbsp_ops, | ||
200 | }, | ||
201 | { | ||
202 | .phys_base = OMAP44XX_MCBSP3_BASE, | ||
203 | .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, | ||
204 | .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, | ||
205 | .tx_irq = OMAP44XX_IRQ_MCBSP3, | ||
206 | .ops = &omap2_mcbsp_ops, | ||
207 | }, | ||
208 | { | 106 | { |
209 | .phys_base = OMAP44XX_MCBSP4_BASE, | 107 | .deactivate_func = omap_device_idle_hwmods, |
210 | .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, | 108 | .activate_func = omap_device_enable_hwmods, |
211 | .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, | 109 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, |
212 | .tx_irq = OMAP44XX_IRQ_MCBSP4, | ||
213 | .ops = &omap2_mcbsp_ops, | ||
214 | }, | 110 | }, |
215 | }; | 111 | }; |
216 | #define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) | ||
217 | #define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) | ||
218 | 112 | ||
219 | static int __init omap2_mcbsp_init(void) | 113 | static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) |
220 | { | 114 | { |
221 | if (cpu_is_omap2420()) { | 115 | int id, count = 1; |
222 | omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; | 116 | char *name = "omap-mcbsp"; |
223 | omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16); | 117 | struct omap_hwmod *oh_device[2]; |
224 | } else if (cpu_is_omap2430()) { | 118 | struct omap_mcbsp_platform_data *pdata = NULL; |
225 | omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; | 119 | struct omap_device *od; |
226 | omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32); | 120 | |
227 | } else if (cpu_is_omap34xx()) { | 121 | sscanf(oh->name, "mcbsp%d", &id); |
228 | omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; | 122 | |
229 | omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32); | 123 | pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); |
230 | } else if (cpu_is_omap44xx()) { | 124 | if (!pdata) { |
231 | omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; | 125 | pr_err("%s: No memory for mcbsp\n", __func__); |
232 | omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32); | 126 | return -ENOMEM; |
127 | } | ||
128 | |||
129 | pdata->mcbsp_config_type = oh->class->rev; | ||
130 | |||
131 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | ||
132 | if (id == 2) | ||
133 | /* The FIFO has 1024 + 256 locations */ | ||
134 | pdata->buffer_size = 0x500; | ||
135 | else | ||
136 | /* The FIFO has 128 locations */ | ||
137 | pdata->buffer_size = 0x80; | ||
138 | } | ||
139 | |||
140 | oh_device[0] = oh; | ||
141 | |||
142 | if (oh->dev_attr) { | ||
143 | oh_device[1] = omap_hwmod_lookup(( | ||
144 | (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); | ||
145 | count++; | ||
233 | } | 146 | } |
147 | od = omap_device_build_ss(name, id, oh_device, count, pdata, | ||
148 | sizeof(*pdata), omap2_mcbsp_latency, | ||
149 | ARRAY_SIZE(omap2_mcbsp_latency), false); | ||
150 | kfree(pdata); | ||
151 | if (IS_ERR(od)) { | ||
152 | pr_err("%s: Can't 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 | } | ||
159 | |||
160 | static int __init omap2_mcbsp_init(void) | ||
161 | { | ||
162 | omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); | ||
234 | 163 | ||
235 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), | 164 | mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), |
236 | GFP_KERNEL); | 165 | GFP_KERNEL); |
237 | if (!mcbsp_ptr) | 166 | if (!mcbsp_ptr) |
238 | return -ENOMEM; | 167 | return -ENOMEM; |
239 | 168 | ||
240 | if (cpu_is_omap2420()) | ||
241 | omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, | ||
242 | OMAP2420_MCBSP_PDATA_SZ); | ||
243 | if (cpu_is_omap2430()) | ||
244 | omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, | ||
245 | OMAP2430_MCBSP_PDATA_SZ); | ||
246 | if (cpu_is_omap34xx()) | ||
247 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | ||
248 | OMAP34XX_MCBSP_PDATA_SZ); | ||
249 | if (cpu_is_omap44xx()) | ||
250 | omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, | ||
251 | OMAP44XX_MCBSP_PDATA_SZ); | ||
252 | |||
253 | return omap_mcbsp_init(); | 169 | return omap_mcbsp_init(); |
254 | } | 170 | } |
255 | arch_initcall(omap2_mcbsp_init); | 171 | arch_initcall(omap2_mcbsp_init); |