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