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 <mach/irqs.h>
  23#include <plat/dma.h>
  24#include <plat/mux.h>
  25#include <plat/cpu.h>
  26#include <plat/mcbsp.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;
  34
  35static void omap1_mcbsp_request(unsigned int id)
  36{
  37        /*
  38         * On 1510, 1610 and 1710, McBSP1 and McBSP3
  39         * are DSP public peripherals.
  40         */
  41        if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
  42                if (dsp_use++ == 0) {
  43                        api_clk = clk_get(NULL, "api_ck");
  44                        dsp_clk = clk_get(NULL, "dsp_ck");
  45                        if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
  46                                clk_enable(api_clk);
  47                                clk_enable(dsp_clk);
  48
  49                                /*
  50                                 * DSP external peripheral reset
  51                                 * FIXME: This should be moved to dsp code
  52                                 */
  53                                __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
  54                                                DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
  55                        }
  56                }
  57        }
  58}
  59
  60static void omap1_mcbsp_free(unsigned int id)
  61{
  62        if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
  63                if (--dsp_use == 0) {
  64                        if (!IS_ERR(api_clk)) {
  65                                clk_disable(api_clk);
  66                                clk_put(api_clk);
  67                        }
  68                        if (!IS_ERR(dsp_clk)) {
  69                                clk_disable(dsp_clk);
  70                                clk_put(dsp_clk);
  71                        }
  72                }
  73        }
  74}
  75
  76static struct omap_mcbsp_ops omap1_mcbsp_ops = {
  77        .request        = omap1_mcbsp_request,
  78        .free           = omap1_mcbsp_free,
  79};
  80
  81#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
  82struct resource omap7xx_mcbsp_res[][6] = {
  83        {
  84                {
  85                        .start = OMAP7XX_MCBSP1_BASE,
  86                        .end   = OMAP7XX_MCBSP1_BASE + SZ_256,
  87                        .flags = IORESOURCE_MEM,
  88                },
  89                {
  90                        .name  = "rx",
  91                        .start = INT_7XX_McBSP1RX,
  92                        .flags = IORESOURCE_IRQ,
  93                },
  94                {
  95                        .name  = "tx",
  96                        .start = INT_7XX_McBSP1TX,
  97                        .flags = IORESOURCE_IRQ,
  98                },
  99                {
 100                        .name  = "rx",
 101                        .start = OMAP_DMA_MCBSP1_RX,
 102                        .flags = IORESOURCE_DMA,
 103                },
 104                {
 105                        .name  = "tx",
 106                        .start = OMAP_DMA_MCBSP1_TX,
 107                        .flags = IORESOURCE_DMA,
 108                },
 109        },
 110        {
 111                {
 112                        .start = OMAP7XX_MCBSP2_BASE,
 113                        .end   = OMAP7XX_MCBSP2_BASE + SZ_256,
 114                        .flags = IORESOURCE_MEM,
 115                },
 116                {
 117                        .name  = "rx",
 118                        .start = INT_7XX_McBSP2RX,
 119                        .flags = IORESOURCE_IRQ,
 120                },
 121                {
 122                        .name  = "tx",
 123                        .start = INT_7XX_McBSP2TX,
 124                        .flags = IORESOURCE_IRQ,
 125                },
 126                {
 127                        .name  = "rx",
 128                        .start = OMAP_DMA_MCBSP3_RX,
 129                        .flags = IORESOURCE_DMA,
 130                },
 131                {
 132                        .name  = "tx",
 133                        .start = OMAP_DMA_MCBSP3_TX,
 134                        .flags = IORESOURCE_DMA,
 135                },
 136        },
 137};
 138
 139#define omap7xx_mcbsp_res_0             omap7xx_mcbsp_res[0]
 140
 141static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
 142        {
 143                .ops            = &omap1_mcbsp_ops,
 144        },
 145        {
 146                .ops            = &omap1_mcbsp_ops,
 147        },
 148};
 149#define OMAP7XX_MCBSP_RES_SZ            ARRAY_SIZE(omap7xx_mcbsp_res[1])
 150#define OMAP7XX_MCBSP_COUNT             ARRAY_SIZE(omap7xx_mcbsp_res)
 151#else
 152#define omap7xx_mcbsp_res_0             NULL
 153#define omap7xx_mcbsp_pdata             NULL
 154#define OMAP7XX_MCBSP_RES_SZ            0
 155#define OMAP7XX_MCBSP_COUNT             0
 156#endif
 157
 158#ifdef CONFIG_ARCH_OMAP15XX
 159struct resource omap15xx_mcbsp_res[][6] = {
 160        {
 161                {
 162                        .start = OMAP1510_MCBSP1_BASE,
 163                        .end   = OMAP1510_MCBSP1_BASE + SZ_256,
 164                        .flags = IORESOURCE_MEM,
 165                },
 166                {
 167                        .name  = "rx",
 168                        .start = INT_McBSP1RX,
 169                        .flags = IORESOURCE_IRQ,
 170                },
 171                {
 172                        .name  = "tx",
 173                        .start = INT_McBSP1TX,
 174                        .flags = IORESOURCE_IRQ,
 175                },
 176                {
 177                        .name  = "rx",
 178                        .start = OMAP_DMA_MCBSP1_RX,
 179                        .flags = IORESOURCE_DMA,
 180                },
 181                {
 182                        .name  = "tx",
 183                        .start = OMAP_DMA_MCBSP1_TX,
 184                        .flags = IORESOURCE_DMA,
 185                },
 186        },
 187        {
 188                {
 189                        .start = OMAP1510_MCBSP2_BASE,
 190                        .end   = OMAP1510_MCBSP2_BASE + SZ_256,
 191                        .flags = IORESOURCE_MEM,
 192                },
 193                {
 194                        .name  = "rx",
 195                        .start = INT_1510_SPI_RX,
 196                        .flags = IORESOURCE_IRQ,
 197                },
 198                {
 199                        .name  = "tx",
 200                        .start = INT_1510_SPI_TX,
 201                        .flags = IORESOURCE_IRQ,
 202                },
 203                {
 204                        .name  = "rx",
 205                        .start = OMAP_DMA_MCBSP2_RX,
 206                        .flags = IORESOURCE_DMA,
 207                },
 208                {
 209                        .name  = "tx",
 210                        .start = OMAP_DMA_MCBSP2_TX,
 211                        .flags = IORESOURCE_DMA,
 212                },
 213        },
 214        {
 215                {
 216                        .start = OMAP1510_MCBSP3_BASE,
 217                        .end   = OMAP1510_MCBSP3_BASE + SZ_256,
 218                        .flags = IORESOURCE_MEM,
 219                },
 220                {
 221                        .name  = "rx",
 222                        .start = INT_McBSP3RX,
 223                        .flags = IORESOURCE_IRQ,
 224                },
 225                {
 226                        .name  = "tx",
 227                        .start = INT_McBSP3TX,
 228                        .flags = IORESOURCE_IRQ,
 229                },
 230                {
 231                        .name  = "rx",
 232                        .start = OMAP_DMA_MCBSP3_RX,
 233                        .flags = IORESOURCE_DMA,
 234                },
 235                {
 236                        .name  = "tx",
 237                        .start = OMAP_DMA_MCBSP3_TX,
 238                        .flags = IORESOURCE_DMA,
 239                },
 240        },
 241};
 242
 243#define omap15xx_mcbsp_res_0            omap15xx_mcbsp_res[0]
 244
 245static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
 246        {
 247                .ops            = &omap1_mcbsp_ops,
 248        },
 249        {
 250                .ops            = &omap1_mcbsp_ops,
 251        },
 252        {
 253                .ops            = &omap1_mcbsp_ops,
 254        },
 255};
 256#define OMAP15XX_MCBSP_RES_SZ           ARRAY_SIZE(omap15xx_mcbsp_res[1])
 257#define OMAP15XX_MCBSP_COUNT            ARRAY_SIZE(omap15xx_mcbsp_res)
 258#else
 259#define omap15xx_mcbsp_res_0            NULL
 260#define omap15xx_mcbsp_pdata            NULL
 261#define OMAP15XX_MCBSP_RES_SZ           0
 262#define OMAP15XX_MCBSP_COUNT            0
 263#endif
 264
 265#ifdef CONFIG_ARCH_OMAP16XX
 266struct resource omap16xx_mcbsp_res[][6] = {
 267        {
 268                {
 269                        .start = OMAP1610_MCBSP1_BASE,
 270                        .end   = OMAP1610_MCBSP1_BASE + SZ_256,
 271                        .flags = IORESOURCE_MEM,
 272                },
 273                {
 274                        .name  = "rx",
 275                        .start = INT_McBSP1RX,
 276                        .flags = IORESOURCE_IRQ,
 277                },
 278                {
 279                        .name  = "tx",
 280                        .start = INT_McBSP1TX,
 281                        .flags = IORESOURCE_IRQ,
 282                },
 283                {
 284                        .name  = "rx",
 285                        .start = OMAP_DMA_MCBSP1_RX,
 286                        .flags = IORESOURCE_DMA,
 287                },
 288                {
 289                        .name  = "tx",
 290                        .start = OMAP_DMA_MCBSP1_TX,
 291                        .flags = IORESOURCE_DMA,
 292                },
 293        },
 294        {
 295                {
 296                        .start = OMAP1610_MCBSP2_BASE,
 297                        .end   = OMAP1610_MCBSP2_BASE + SZ_256,
 298                        .flags = IORESOURCE_MEM,
 299                },
 300                {
 301                        .name  = "rx",
 302                        .start = INT_1610_McBSP2_RX,
 303                        .flags = IORESOURCE_IRQ,
 304                },
 305                {
 306                        .name  = "tx",
 307                        .start = INT_1610_McBSP2_TX,
 308                        .flags = IORESOURCE_IRQ,
 309                },
 310                {
 311                        .name  = "rx",
 312                        .start = OMAP_DMA_MCBSP2_RX,
 313                        .flags = IORESOURCE_DMA,
 314                },
 315                {
 316                        .name  = "tx",
 317                        .start = OMAP_DMA_MCBSP2_TX,
 318                        .flags = IORESOURCE_DMA,
 319                },
 320        },
 321        {
 322                {
 323                        .start = OMAP1610_MCBSP3_BASE,
 324                        .end   = OMAP1610_MCBSP3_BASE + SZ_256,
 325                        .flags = IORESOURCE_MEM,
 326                },
 327                {
 328                        .name  = "rx",
 329                        .start = INT_McBSP3RX,
 330                        .flags = IORESOURCE_IRQ,
 331                },
 332                {
 333                        .name  = "tx",
 334                        .start = INT_McBSP3TX,
 335                        .flags = IORESOURCE_IRQ,
 336                },
 337                {
 338                        .name  = "rx",
 339                        .start = OMAP_DMA_MCBSP3_RX,
 340                        .flags = IORESOURCE_DMA,
 341                },
 342                {
 343                        .name  = "tx",
 344                        .start = OMAP_DMA_MCBSP3_TX,
 345                        .flags = IORESOURCE_DMA,
 346                },
 347        },
 348};
 349
 350#define omap16xx_mcbsp_res_0            omap16xx_mcbsp_res[0]
 351
 352static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
 353        {
 354                .ops            = &omap1_mcbsp_ops,
 355        },
 356        {
 357                .ops            = &omap1_mcbsp_ops,
 358        },
 359        {
 360                .ops            = &omap1_mcbsp_ops,
 361        },
 362};
 363#define OMAP16XX_MCBSP_RES_SZ           ARRAY_SIZE(omap16xx_mcbsp_res[1])
 364#define OMAP16XX_MCBSP_COUNT            ARRAY_SIZE(omap16xx_mcbsp_res)
 365#else
 366#define omap16xx_mcbsp_res_0            NULL
 367#define omap16xx_mcbsp_pdata            NULL
 368#define OMAP16XX_MCBSP_RES_SZ           0
 369#define OMAP16XX_MCBSP_COUNT            0
 370#endif
 371
 372static int __init omap1_mcbsp_init(void)
 373{
 374        if (!cpu_class_is_omap1())
 375                return -ENODEV;
 376
 377        if (cpu_is_omap7xx())
 378                omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
 379        else if (cpu_is_omap15xx())
 380                omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
 381        else if (cpu_is_omap16xx())
 382                omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
 383
 384        mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
 385                                                                GFP_KERNEL);
 386        if (!mcbsp_ptr)
 387                return -ENOMEM;
 388
 389        if (cpu_is_omap7xx())
 390                omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
 391                                        OMAP7XX_MCBSP_RES_SZ,
 392                                        omap7xx_mcbsp_pdata,
 393                                        OMAP7XX_MCBSP_COUNT);
 394
 395        if (cpu_is_omap15xx())
 396                omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
 397                                        OMAP15XX_MCBSP_RES_SZ,
 398                                        omap15xx_mcbsp_pdata,
 399                                        OMAP15XX_MCBSP_COUNT);
 400
 401        if (cpu_is_omap16xx())
 402                omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
 403                                        OMAP16XX_MCBSP_RES_SZ,
 404                                        omap16xx_mcbsp_pdata,
 405                                        OMAP16XX_MCBSP_COUNT);
 406
 407        return omap_mcbsp_init();
 408}
 409
 410arch_initcall(omap1_mcbsp_init);
 411