0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/ioport.h>
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/clk.h>
0014 #include <linux/err.h>
0015 #include <linux/io.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/slab.h>
0018 #include <linux/omap-dma.h>
0019 #include <linux/soc/ti/omap1-io.h>
0020 #include <linux/platform_data/asoc-ti-mcbsp.h>
0021
0022 #include "mux.h"
0023 #include "soc.h"
0024 #include "irqs.h"
0025 #include "iomap.h"
0026
0027 #define DPS_RSTCT2_PER_EN (1 << 0)
0028 #define DSP_RSTCT2_WD_PER_EN (1 << 1)
0029
0030 static int dsp_use;
0031 static struct clk *api_clk;
0032 static struct clk *dsp_clk;
0033 static struct platform_device **omap_mcbsp_devices;
0034
0035 static void omap1_mcbsp_request(unsigned int id)
0036 {
0037
0038
0039
0040
0041 if (id == 0 || id == 2) {
0042 if (dsp_use++ == 0) {
0043 api_clk = clk_get(NULL, "api_ck");
0044 dsp_clk = clk_get(NULL, "dsp_ck");
0045 if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
0046 clk_prepare_enable(api_clk);
0047 clk_prepare_enable(dsp_clk);
0048
0049
0050
0051
0052
0053 __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
0054 DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
0055 }
0056 }
0057 }
0058 }
0059
0060 static void omap1_mcbsp_free(unsigned int id)
0061 {
0062 if (id == 0 || id == 2) {
0063 if (--dsp_use == 0) {
0064 if (!IS_ERR(api_clk)) {
0065 clk_disable_unprepare(api_clk);
0066 clk_put(api_clk);
0067 }
0068 if (!IS_ERR(dsp_clk)) {
0069 clk_disable_unprepare(dsp_clk);
0070 clk_put(dsp_clk);
0071 }
0072 }
0073 }
0074 }
0075
0076 static struct omap_mcbsp_ops omap1_mcbsp_ops = {
0077 .request = omap1_mcbsp_request,
0078 .free = omap1_mcbsp_free,
0079 };
0080
0081 #define OMAP7XX_MCBSP1_BASE 0xfffb1000
0082 #define OMAP7XX_MCBSP2_BASE 0xfffb1800
0083
0084 #define OMAP1510_MCBSP1_BASE 0xe1011800
0085 #define OMAP1510_MCBSP2_BASE 0xfffb1000
0086 #define OMAP1510_MCBSP3_BASE 0xe1017000
0087
0088 #define OMAP1610_MCBSP1_BASE 0xe1011800
0089 #define OMAP1610_MCBSP2_BASE 0xfffb1000
0090 #define OMAP1610_MCBSP3_BASE 0xe1017000
0091
0092 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
0093 struct resource omap7xx_mcbsp_res[][6] = {
0094 {
0095 {
0096 .start = OMAP7XX_MCBSP1_BASE,
0097 .end = OMAP7XX_MCBSP1_BASE + SZ_256,
0098 .flags = IORESOURCE_MEM,
0099 },
0100 {
0101 .name = "rx",
0102 .start = INT_7XX_McBSP1RX,
0103 .flags = IORESOURCE_IRQ,
0104 },
0105 {
0106 .name = "tx",
0107 .start = INT_7XX_McBSP1TX,
0108 .flags = IORESOURCE_IRQ,
0109 },
0110 {
0111 .name = "rx",
0112 .start = 9,
0113 .flags = IORESOURCE_DMA,
0114 },
0115 {
0116 .name = "tx",
0117 .start = 8,
0118 .flags = IORESOURCE_DMA,
0119 },
0120 },
0121 {
0122 {
0123 .start = OMAP7XX_MCBSP2_BASE,
0124 .end = OMAP7XX_MCBSP2_BASE + SZ_256,
0125 .flags = IORESOURCE_MEM,
0126 },
0127 {
0128 .name = "rx",
0129 .start = INT_7XX_McBSP2RX,
0130 .flags = IORESOURCE_IRQ,
0131 },
0132 {
0133 .name = "tx",
0134 .start = INT_7XX_McBSP2TX,
0135 .flags = IORESOURCE_IRQ,
0136 },
0137 {
0138 .name = "rx",
0139 .start = 11,
0140 .flags = IORESOURCE_DMA,
0141 },
0142 {
0143 .name = "tx",
0144 .start = 10,
0145 .flags = IORESOURCE_DMA,
0146 },
0147 },
0148 };
0149
0150 #define omap7xx_mcbsp_res_0 omap7xx_mcbsp_res[0]
0151
0152 static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
0153 {
0154 .ops = &omap1_mcbsp_ops,
0155 },
0156 {
0157 .ops = &omap1_mcbsp_ops,
0158 },
0159 };
0160 #define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
0161 #define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
0162 #else
0163 #define omap7xx_mcbsp_res_0 NULL
0164 #define omap7xx_mcbsp_pdata NULL
0165 #define OMAP7XX_MCBSP_RES_SZ 0
0166 #define OMAP7XX_MCBSP_COUNT 0
0167 #endif
0168
0169 #ifdef CONFIG_ARCH_OMAP15XX
0170 struct resource omap15xx_mcbsp_res[][6] = {
0171 {
0172 {
0173 .start = OMAP1510_MCBSP1_BASE,
0174 .end = OMAP1510_MCBSP1_BASE + SZ_256,
0175 .flags = IORESOURCE_MEM,
0176 },
0177 {
0178 .name = "rx",
0179 .start = INT_McBSP1RX,
0180 .flags = IORESOURCE_IRQ,
0181 },
0182 {
0183 .name = "tx",
0184 .start = INT_McBSP1TX,
0185 .flags = IORESOURCE_IRQ,
0186 },
0187 {
0188 .name = "rx",
0189 .start = 9,
0190 .flags = IORESOURCE_DMA,
0191 },
0192 {
0193 .name = "tx",
0194 .start = 8,
0195 .flags = IORESOURCE_DMA,
0196 },
0197 },
0198 {
0199 {
0200 .start = OMAP1510_MCBSP2_BASE,
0201 .end = OMAP1510_MCBSP2_BASE + SZ_256,
0202 .flags = IORESOURCE_MEM,
0203 },
0204 {
0205 .name = "rx",
0206 .start = INT_1510_SPI_RX,
0207 .flags = IORESOURCE_IRQ,
0208 },
0209 {
0210 .name = "tx",
0211 .start = INT_1510_SPI_TX,
0212 .flags = IORESOURCE_IRQ,
0213 },
0214 {
0215 .name = "rx",
0216 .start = 17,
0217 .flags = IORESOURCE_DMA,
0218 },
0219 {
0220 .name = "tx",
0221 .start = 16,
0222 .flags = IORESOURCE_DMA,
0223 },
0224 },
0225 {
0226 {
0227 .start = OMAP1510_MCBSP3_BASE,
0228 .end = OMAP1510_MCBSP3_BASE + SZ_256,
0229 .flags = IORESOURCE_MEM,
0230 },
0231 {
0232 .name = "rx",
0233 .start = INT_McBSP3RX,
0234 .flags = IORESOURCE_IRQ,
0235 },
0236 {
0237 .name = "tx",
0238 .start = INT_McBSP3TX,
0239 .flags = IORESOURCE_IRQ,
0240 },
0241 {
0242 .name = "rx",
0243 .start = 11,
0244 .flags = IORESOURCE_DMA,
0245 },
0246 {
0247 .name = "tx",
0248 .start = 10,
0249 .flags = IORESOURCE_DMA,
0250 },
0251 },
0252 };
0253
0254 #define omap15xx_mcbsp_res_0 omap15xx_mcbsp_res[0]
0255
0256 static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
0257 {
0258 .ops = &omap1_mcbsp_ops,
0259 },
0260 {
0261 .ops = &omap1_mcbsp_ops,
0262 },
0263 {
0264 .ops = &omap1_mcbsp_ops,
0265 },
0266 };
0267 #define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
0268 #define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
0269 #else
0270 #define omap15xx_mcbsp_res_0 NULL
0271 #define omap15xx_mcbsp_pdata NULL
0272 #define OMAP15XX_MCBSP_RES_SZ 0
0273 #define OMAP15XX_MCBSP_COUNT 0
0274 #endif
0275
0276 #ifdef CONFIG_ARCH_OMAP16XX
0277 struct resource omap16xx_mcbsp_res[][6] = {
0278 {
0279 {
0280 .start = OMAP1610_MCBSP1_BASE,
0281 .end = OMAP1610_MCBSP1_BASE + SZ_256,
0282 .flags = IORESOURCE_MEM,
0283 },
0284 {
0285 .name = "rx",
0286 .start = INT_McBSP1RX,
0287 .flags = IORESOURCE_IRQ,
0288 },
0289 {
0290 .name = "tx",
0291 .start = INT_McBSP1TX,
0292 .flags = IORESOURCE_IRQ,
0293 },
0294 {
0295 .name = "rx",
0296 .start = 9,
0297 .flags = IORESOURCE_DMA,
0298 },
0299 {
0300 .name = "tx",
0301 .start = 8,
0302 .flags = IORESOURCE_DMA,
0303 },
0304 },
0305 {
0306 {
0307 .start = OMAP1610_MCBSP2_BASE,
0308 .end = OMAP1610_MCBSP2_BASE + SZ_256,
0309 .flags = IORESOURCE_MEM,
0310 },
0311 {
0312 .name = "rx",
0313 .start = INT_1610_McBSP2_RX,
0314 .flags = IORESOURCE_IRQ,
0315 },
0316 {
0317 .name = "tx",
0318 .start = INT_1610_McBSP2_TX,
0319 .flags = IORESOURCE_IRQ,
0320 },
0321 {
0322 .name = "rx",
0323 .start = 17,
0324 .flags = IORESOURCE_DMA,
0325 },
0326 {
0327 .name = "tx",
0328 .start = 16,
0329 .flags = IORESOURCE_DMA,
0330 },
0331 },
0332 {
0333 {
0334 .start = OMAP1610_MCBSP3_BASE,
0335 .end = OMAP1610_MCBSP3_BASE + SZ_256,
0336 .flags = IORESOURCE_MEM,
0337 },
0338 {
0339 .name = "rx",
0340 .start = INT_McBSP3RX,
0341 .flags = IORESOURCE_IRQ,
0342 },
0343 {
0344 .name = "tx",
0345 .start = INT_McBSP3TX,
0346 .flags = IORESOURCE_IRQ,
0347 },
0348 {
0349 .name = "rx",
0350 .start = 11,
0351 .flags = IORESOURCE_DMA,
0352 },
0353 {
0354 .name = "tx",
0355 .start = 10,
0356 .flags = IORESOURCE_DMA,
0357 },
0358 },
0359 };
0360
0361 #define omap16xx_mcbsp_res_0 omap16xx_mcbsp_res[0]
0362
0363 static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
0364 {
0365 .ops = &omap1_mcbsp_ops,
0366 },
0367 {
0368 .ops = &omap1_mcbsp_ops,
0369 },
0370 {
0371 .ops = &omap1_mcbsp_ops,
0372 },
0373 };
0374 #define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
0375 #define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
0376 #else
0377 #define omap16xx_mcbsp_res_0 NULL
0378 #define omap16xx_mcbsp_pdata NULL
0379 #define OMAP16XX_MCBSP_RES_SZ 0
0380 #define OMAP16XX_MCBSP_COUNT 0
0381 #endif
0382
0383 static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
0384 struct omap_mcbsp_platform_data *config, int size)
0385 {
0386 int i;
0387
0388 omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *),
0389 GFP_KERNEL);
0390 if (!omap_mcbsp_devices) {
0391 printk(KERN_ERR "Could not register McBSP devices\n");
0392 return;
0393 }
0394
0395 for (i = 0; i < size; i++) {
0396 struct platform_device *new_mcbsp;
0397 int ret;
0398
0399 new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
0400 if (!new_mcbsp)
0401 continue;
0402 platform_device_add_resources(new_mcbsp, &res[i * res_count],
0403 res_count);
0404 config[i].reg_size = 2;
0405 config[i].reg_step = 2;
0406 new_mcbsp->dev.platform_data = &config[i];
0407 ret = platform_device_add(new_mcbsp);
0408 if (ret) {
0409 platform_device_put(new_mcbsp);
0410 continue;
0411 }
0412 omap_mcbsp_devices[i] = new_mcbsp;
0413 }
0414 }
0415
0416 static int __init omap1_mcbsp_init(void)
0417 {
0418 if (!cpu_class_is_omap1())
0419 return -ENODEV;
0420
0421 if (cpu_is_omap7xx())
0422 omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
0423 OMAP7XX_MCBSP_RES_SZ,
0424 omap7xx_mcbsp_pdata,
0425 OMAP7XX_MCBSP_COUNT);
0426
0427 if (cpu_is_omap15xx())
0428 omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
0429 OMAP15XX_MCBSP_RES_SZ,
0430 omap15xx_mcbsp_pdata,
0431 OMAP15XX_MCBSP_COUNT);
0432
0433 if (cpu_is_omap16xx())
0434 omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
0435 OMAP16XX_MCBSP_RES_SZ,
0436 omap16xx_mcbsp_pdata,
0437 OMAP16XX_MCBSP_COUNT);
0438
0439 return 0;
0440 }
0441
0442 arch_initcall(omap1_mcbsp_init);