Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/arch/arm/mach-omap1/mcbsp.c
0004  *
0005  * Copyright (C) 2008 Instituto Nokia de Tecnologia
0006  * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
0007  *
0008  * Multichannel mode not supported.
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      * On 1510, 1610 and 1710, McBSP1 and McBSP3
0039      * are DSP public peripherals.
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                  * DSP external peripheral reset
0051                  * FIXME: This should be moved to dsp code
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);