linux/arch/arm/mach-omap1/mcbsp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * linux/arch/arm/mach-omap1/mcbsp.c
   4 *
   5 * Copyright (C) 2008 Instituto Nokia de Tecnologia
   6 * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
   7 *
   8 * Multichannel mode not supported.
   9 */
  10#include <linux/ioport.h>
  11#include <linux/module.h>
  12#include <linux/init.h>
  13#include <linux/clk.h>
  14#include <linux/err.h>
  15#include <linux/io.h>
  16#include <linux/platform_device.h>
  17#include <linux/slab.h>
  18
  19#include <linux/omap-dma.h>
  20#include <mach/mux.h>
  21#include "soc.h"
  22#include <linux/platform_data/asoc-ti-mcbsp.h>
  23
  24#include <mach/irqs.h>
  25
  26#include "iomap.h"
  27
  28#define DPS_RSTCT2_PER_EN       (1 << 0)
  29#define DSP_RSTCT2_WD_PER_EN    (1 << 1)
  30
  31static int dsp_use;
  32static struct clk *api_clk;
  33static struct clk *dsp_clk;
  34static struct platform_device **omap_mcbsp_devices;
  35
  36static void omap1_mcbsp_request(unsigned int id)
  37{
  38        /*
  39         * On 1510, 1610 and 1710, McBSP1 and McBSP3
  40         * are DSP public peripherals.
  41         */
  42        if (id == 0 || id == 2) {
  43                if (dsp_use++ == 0) {
  44                        api_clk = clk_get(NULL, "api_ck");
  45                        dsp_clk = clk_get(NULL, "dsp_ck");
  46                        if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
  47                                clk_enable(api_clk);
  48                                clk_enable(dsp_clk);
  49
  50                                /*
  51                                 * DSP external peripheral reset
  52                                 * FIXME: This should be moved to dsp code
  53                                 */
  54                                __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
  55                                                DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
  56                        }
  57                }
  58        }
  59}
  60
  61static void omap1_mcbsp_free(unsigned int id)
  62{
  63        if (id == 0 || id == 2) {
  64                if (--dsp_use == 0) {
  65                        if (!IS_ERR(api_clk)) {
  66                                clk_disable(api_clk);
  67                                clk_put(api_clk);
  68                        }
  69                        if (!IS_ERR(dsp_clk)) {
  70                                clk_disable(dsp_clk);
  71                                clk_put(dsp_clk);
  72                        }
  73                }
  74        }
  75}
  76
  77static struct omap_mcbsp_ops omap1_mcbsp_ops = {
  78        .request        = omap1_mcbsp_request,
  79        .free           = omap1_mcbsp_free,
  80};
  81
  82#define OMAP7XX_MCBSP1_BASE     0xfffb1000
  83#define OMAP7XX_MCBSP2_BASE     0xfffb1800
  84
  85#define OMAP1510_MCBSP1_BASE    0xe1011800
  86#define OMAP1510_MCBSP2_BASE    0xfffb1000
  87#define OMAP1510_MCBSP3_BASE    0xe1017000
  88
  89#define OMAP1610_MCBSP1_BASE    0xe1011800
  90#define OMAP1610_MCBSP2_BASE    0xfffb1000
  91#define OMAP1610_MCBSP3_BASE    0xe1017000
  92
  93#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
  94struct resource omap7xx_mcbsp_res[][6] = {
  95        {
  96                {
  97                        .start = OMAP7XX_MCBSP1_BASE,
  98                        .end   = OMAP7XX_MCBSP1_BASE + SZ_256,
  99                        .flags = IORESOURCE_MEM,
 100                },
 101                {
 102                        .name  = "rx",
 103                        .start = INT_7XX_McBSP1RX,
 104                        .flags = IORESOURCE_IRQ,
 105                },
 106                {
 107                        .name  = "tx",
 108                        .start = INT_7XX_McBSP1TX,
 109                        .flags = IORESOURCE_IRQ,
 110                },
 111                {
 112                        .name  = "rx",
 113                        .start = 9,
 114                        .flags = IORESOURCE_DMA,
 115                },
 116                {
 117                        .name  = "tx",
 118                        .start = 8,
 119                        .flags = IORESOURCE_DMA,
 120                },
 121        },
 122        {
 123                {
 124                        .start = OMAP7XX_MCBSP2_BASE,
 125                        .end   = OMAP7XX_MCBSP2_BASE + SZ_256,
 126                        .flags = IORESOURCE_MEM,
 127                },
 128                {
 129                        .name  = "rx",
 130                        .start = INT_7XX_McBSP2RX,
 131                        .flags = IORESOURCE_IRQ,
 132                },
 133                {
 134                        .name  = "tx",
 135                        .start = INT_7XX_McBSP2TX,
 136                        .flags = IORESOURCE_IRQ,
 137                },
 138                {
 139                        .name  = "rx",
 140                        .start = 11,
 141                        .flags = IORESOURCE_DMA,
 142                },
 143                {
 144                        .name  = "tx",
 145                        .start = 10,
 146                        .flags = IORESOURCE_DMA,
 147                },
 148        },
 149};
 150
 151#define omap7xx_mcbsp_res_0             omap7xx_mcbsp_res[0]
 152
 153static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
 154        {
 155                .ops            = &omap1_mcbsp_ops,
 156        },
 157        {
 158                .ops            = &omap1_mcbsp_ops,
 159        },
 160};
 161#define OMAP7XX_MCBSP_RES_SZ            ARRAY_SIZE(omap7xx_mcbsp_res[1])
 162#define OMAP7XX_MCBSP_COUNT             ARRAY_SIZE(omap7xx_mcbsp_res)
 163#else
 164#define omap7xx_mcbsp_res_0             NULL
 165#define omap7xx_mcbsp_pdata             NULL
 166#define OMAP7XX_MCBSP_RES_SZ            0
 167#define OMAP7XX_MCBSP_COUNT             0
 168#endif
 169
 170#ifdef CONFIG_ARCH_OMAP15XX
 171struct resource omap15xx_mcbsp_res[][6] = {
 172        {
 173                {
 174                        .start = OMAP1510_MCBSP1_BASE,
 175                        .end   = OMAP1510_MCBSP1_BASE + SZ_256,
 176                        .flags = IORESOURCE_MEM,
 177                },
 178                {
 179                        .name  = "rx",
 180                        .start = INT_McBSP1RX,
 181                        .flags = IORESOURCE_IRQ,
 182                },
 183                {
 184                        .name  = "tx",
 185                        .start = INT_McBSP1TX,
 186                        .flags = IORESOURCE_IRQ,
 187                },
 188                {
 189                        .name  = "rx",
 190                        .start = 9,
 191                        .flags = IORESOURCE_DMA,
 192                },
 193                {
 194                        .name  = "tx",
 195                        .start = 8,
 196                        .flags = IORESOURCE_DMA,
 197                },
 198        },
 199        {
 200                {
 201                        .start = OMAP1510_MCBSP2_BASE,
 202                        .end   = OMAP1510_MCBSP2_BASE + SZ_256,
 203                        .flags = IORESOURCE_MEM,
 204                },
 205                {
 206                        .name  = "rx",
 207                        .start = INT_1510_SPI_RX,
 208                        .flags = IORESOURCE_IRQ,
 209                },
 210                {
 211                        .name  = "tx",
 212                        .start = INT_1510_SPI_TX,
 213                        .flags = IORESOURCE_IRQ,
 214                },
 215                {
 216                        .name  = "rx",
 217                        .start = 17,
 218                        .flags = IORESOURCE_DMA,
 219                },
 220                {
 221                        .name  = "tx",
 222                        .start = 16,
 223                        .flags = IORESOURCE_DMA,
 224                },
 225        },
 226        {
 227                {
 228                        .start = OMAP1510_MCBSP3_BASE,
 229                        .end   = OMAP1510_MCBSP3_BASE + SZ_256,
 230                        .flags = IORESOURCE_MEM,
 231                },
 232                {
 233                        .name  = "rx",
 234                        .start = INT_McBSP3RX,
 235                        .flags = IORESOURCE_IRQ,
 236                },
 237                {
 238                        .name  = "tx",
 239                        .start = INT_McBSP3TX,
 240                        .flags = IORESOURCE_IRQ,
 241                },
 242                {
 243                        .name  = "rx",
 244                        .start = 11,
 245                        .flags = IORESOURCE_DMA,
 246                },
 247                {
 248                        .name  = "tx",
 249                        .start = 10,
 250                        .flags = IORESOURCE_DMA,
 251                },
 252        },
 253};
 254
 255#define omap15xx_mcbsp_res_0            omap15xx_mcbsp_res[0]
 256
 257static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
 258        {
 259                .ops            = &omap1_mcbsp_ops,
 260        },
 261        {
 262                .ops            = &omap1_mcbsp_ops,
 263        },
 264        {
 265                .ops            = &omap1_mcbsp_ops,
 266        },
 267};
 268#define OMAP15XX_MCBSP_RES_SZ           ARRAY_SIZE(omap15xx_mcbsp_res[1])
 269#define OMAP15XX_MCBSP_COUNT            ARRAY_SIZE(omap15xx_mcbsp_res)
 270#else
 271#define omap15xx_mcbsp_res_0            NULL
 272#define omap15xx_mcbsp_pdata            NULL
 273#define OMAP15XX_MCBSP_RES_SZ           0
 274#define OMAP15XX_MCBSP_COUNT            0
 275#endif
 276
 277#ifdef CONFIG_ARCH_OMAP16XX
 278struct resource omap16xx_mcbsp_res[][6] = {
 279        {
 280                {
 281                        .start = OMAP1610_MCBSP1_BASE,
 282                        .end   = OMAP1610_MCBSP1_BASE + SZ_256,
 283                        .flags = IORESOURCE_MEM,
 284                },
 285                {
 286                        .name  = "rx",
 287                        .start = INT_McBSP1RX,
 288                        .flags = IORESOURCE_IRQ,
 289                },
 290                {
 291                        .name  = "tx",
 292                        .start = INT_McBSP1TX,
 293                        .flags = IORESOURCE_IRQ,
 294                },
 295                {
 296                        .name  = "rx",
 297                        .start = 9,
 298                        .flags = IORESOURCE_DMA,
 299                },
 300                {
 301                        .name  = "tx",
 302                        .start = 8,
 303                        .flags = IORESOURCE_DMA,
 304                },
 305        },
 306        {
 307                {
 308                        .start = OMAP1610_MCBSP2_BASE,
 309                        .end   = OMAP1610_MCBSP2_BASE + SZ_256,
 310                        .flags = IORESOURCE_MEM,
 311                },
 312                {
 313                        .name  = "rx",
 314                        .start = INT_1610_McBSP2_RX,
 315                        .flags = IORESOURCE_IRQ,
 316                },
 317                {
 318                        .name  = "tx",
 319                        .start = INT_1610_McBSP2_TX,
 320                        .flags = IORESOURCE_IRQ,
 321                },
 322                {
 323                        .name  = "rx",
 324                        .start = 17,
 325                        .flags = IORESOURCE_DMA,
 326                },
 327                {
 328                        .name  = "tx",
 329                        .start = 16,
 330                        .flags = IORESOURCE_DMA,
 331                },
 332        },
 333        {
 334                {
 335                        .start = OMAP1610_MCBSP3_BASE,
 336                        .end   = OMAP1610_MCBSP3_BASE + SZ_256,
 337                        .flags = IORESOURCE_MEM,
 338                },
 339                {
 340                        .name  = "rx",
 341                        .start = INT_McBSP3RX,
 342                        .flags = IORESOURCE_IRQ,
 343                },
 344                {
 345                        .name  = "tx",
 346                        .start = INT_McBSP3TX,
 347                        .flags = IORESOURCE_IRQ,
 348                },
 349                {
 350                        .name  = "rx",
 351                        .start = 11,
 352                        .flags = IORESOURCE_DMA,
 353                },
 354                {
 355                        .name  = "tx",
 356                        .start = 10,
 357                        .flags = IORESOURCE_DMA,
 358                },
 359        },
 360};
 361
 362#define omap16xx_mcbsp_res_0            omap16xx_mcbsp_res[0]
 363
 364static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
 365        {
 366                .ops            = &omap1_mcbsp_ops,
 367        },
 368        {
 369                .ops            = &omap1_mcbsp_ops,
 370        },
 371        {
 372                .ops            = &omap1_mcbsp_ops,
 373        },
 374};
 375#define OMAP16XX_MCBSP_RES_SZ           ARRAY_SIZE(omap16xx_mcbsp_res[1])
 376#define OMAP16XX_MCBSP_COUNT            ARRAY_SIZE(omap16xx_mcbsp_res)
 377#else
 378#define omap16xx_mcbsp_res_0            NULL
 379#define omap16xx_mcbsp_pdata            NULL
 380#define OMAP16XX_MCBSP_RES_SZ           0
 381#define OMAP16XX_MCBSP_COUNT            0
 382#endif
 383
 384static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
 385                        struct omap_mcbsp_platform_data *config, int size)
 386{
 387        int i;
 388
 389        omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *),
 390                                     GFP_KERNEL);
 391        if (!omap_mcbsp_devices) {
 392                printk(KERN_ERR "Could not register McBSP devices\n");
 393                return;
 394        }
 395
 396        for (i = 0; i < size; i++) {
 397                struct platform_device *new_mcbsp;
 398                int ret;
 399
 400                new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
 401                if (!new_mcbsp)
 402                        continue;
 403                platform_device_add_resources(new_mcbsp, &res[i * res_count],
 404                                        res_count);
 405                config[i].reg_size = 2;
 406                config[i].reg_step = 2;
 407                new_mcbsp->dev.platform_data = &config[i];
 408                ret = platform_device_add(new_mcbsp);
 409                if (ret) {
 410                        platform_device_put(new_mcbsp);
 411                        continue;
 412                }
 413                omap_mcbsp_devices[i] = new_mcbsp;
 414        }
 415}
 416
 417static int __init omap1_mcbsp_init(void)
 418{
 419        if (!cpu_class_is_omap1())
 420                return -ENODEV;
 421
 422        if (cpu_is_omap7xx())
 423                omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
 424                                        OMAP7XX_MCBSP_RES_SZ,
 425                                        omap7xx_mcbsp_pdata,
 426                                        OMAP7XX_MCBSP_COUNT);
 427
 428        if (cpu_is_omap15xx())
 429                omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
 430                                        OMAP15XX_MCBSP_RES_SZ,
 431                                        omap15xx_mcbsp_pdata,
 432                                        OMAP15XX_MCBSP_COUNT);
 433
 434        if (cpu_is_omap16xx())
 435                omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
 436                                        OMAP16XX_MCBSP_RES_SZ,
 437                                        omap16xx_mcbsp_pdata,
 438                                        OMAP16XX_MCBSP_COUNT);
 439
 440        return 0;
 441}
 442
 443arch_initcall(omap1_mcbsp_init);
 444