linux/arch/arm/mach-exynos4/dev-audio.c
<<
>>
Prefs
   1/* linux/arch/arm/mach-exynos4/dev-audio.c
   2 *
   3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com
   5 *
   6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
   7 *      Jaswinder Singh <jassi.brar@samsung.com>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/platform_device.h>
  15#include <linux/dma-mapping.h>
  16#include <linux/gpio.h>
  17
  18#include <plat/gpio-cfg.h>
  19#include <plat/audio.h>
  20
  21#include <mach/map.h>
  22#include <mach/dma.h>
  23#include <mach/irqs.h>
  24#include <mach/regs-audss.h>
  25
  26static const char *rclksrc[] = {
  27        [0] = "busclk",
  28        [1] = "i2sclk",
  29};
  30
  31static int exynos4_cfg_i2s(struct platform_device *pdev)
  32{
  33        /* configure GPIO for i2s port */
  34        switch (pdev->id) {
  35        case 0:
  36                s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
  37                break;
  38        case 1:
  39                s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
  40                break;
  41        case 2:
  42                s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
  43                break;
  44        default:
  45                printk(KERN_ERR "Invalid Device %d\n", pdev->id);
  46                return -EINVAL;
  47        }
  48
  49        return 0;
  50}
  51
  52static struct s3c_audio_pdata i2sv5_pdata = {
  53        .cfg_gpio = exynos4_cfg_i2s,
  54        .type = {
  55                .i2s = {
  56                        .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
  57                                         | QUIRK_NEED_RSTCLR,
  58                        .src_clk = rclksrc,
  59                        .idma_addr = EXYNOS4_AUDSS_INT_MEM,
  60                },
  61        },
  62};
  63
  64static struct resource exynos4_i2s0_resource[] = {
  65        [0] = {
  66                .start  = EXYNOS4_PA_I2S0,
  67                .end    = EXYNOS4_PA_I2S0 + 0x100 - 1,
  68                .flags  = IORESOURCE_MEM,
  69        },
  70        [1] = {
  71                .start  = DMACH_I2S0_TX,
  72                .end    = DMACH_I2S0_TX,
  73                .flags  = IORESOURCE_DMA,
  74        },
  75        [2] = {
  76                .start  = DMACH_I2S0_RX,
  77                .end    = DMACH_I2S0_RX,
  78                .flags  = IORESOURCE_DMA,
  79        },
  80        [3] = {
  81                .start  = DMACH_I2S0S_TX,
  82                .end    = DMACH_I2S0S_TX,
  83                .flags  = IORESOURCE_DMA,
  84        },
  85};
  86
  87struct platform_device exynos4_device_i2s0 = {
  88        .name = "samsung-i2s",
  89        .id = 0,
  90        .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
  91        .resource = exynos4_i2s0_resource,
  92        .dev = {
  93                .platform_data = &i2sv5_pdata,
  94        },
  95};
  96
  97static const char *rclksrc_v3[] = {
  98        [0] = "sclk_i2s",
  99        [1] = "no_such_clock",
 100};
 101
 102static struct s3c_audio_pdata i2sv3_pdata = {
 103        .cfg_gpio = exynos4_cfg_i2s,
 104        .type = {
 105                .i2s = {
 106                        .quirks = QUIRK_NO_MUXPSR,
 107                        .src_clk = rclksrc_v3,
 108                },
 109        },
 110};
 111
 112static struct resource exynos4_i2s1_resource[] = {
 113        [0] = {
 114                .start  = EXYNOS4_PA_I2S1,
 115                .end    = EXYNOS4_PA_I2S1 + 0x100 - 1,
 116                .flags  = IORESOURCE_MEM,
 117        },
 118        [1] = {
 119                .start  = DMACH_I2S1_TX,
 120                .end    = DMACH_I2S1_TX,
 121                .flags  = IORESOURCE_DMA,
 122        },
 123        [2] = {
 124                .start  = DMACH_I2S1_RX,
 125                .end    = DMACH_I2S1_RX,
 126                .flags  = IORESOURCE_DMA,
 127        },
 128};
 129
 130struct platform_device exynos4_device_i2s1 = {
 131        .name = "samsung-i2s",
 132        .id = 1,
 133        .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
 134        .resource = exynos4_i2s1_resource,
 135        .dev = {
 136                .platform_data = &i2sv3_pdata,
 137        },
 138};
 139
 140static struct resource exynos4_i2s2_resource[] = {
 141        [0] = {
 142                .start  = EXYNOS4_PA_I2S2,
 143                .end    = EXYNOS4_PA_I2S2 + 0x100 - 1,
 144                .flags  = IORESOURCE_MEM,
 145        },
 146        [1] = {
 147                .start  = DMACH_I2S2_TX,
 148                .end    = DMACH_I2S2_TX,
 149                .flags  = IORESOURCE_DMA,
 150        },
 151        [2] = {
 152                .start  = DMACH_I2S2_RX,
 153                .end    = DMACH_I2S2_RX,
 154                .flags  = IORESOURCE_DMA,
 155        },
 156};
 157
 158struct platform_device exynos4_device_i2s2 = {
 159        .name = "samsung-i2s",
 160        .id = 2,
 161        .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
 162        .resource = exynos4_i2s2_resource,
 163        .dev = {
 164                .platform_data = &i2sv3_pdata,
 165        },
 166};
 167
 168/* PCM Controller platform_devices */
 169
 170static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
 171{
 172        switch (pdev->id) {
 173        case 0:
 174                s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
 175                break;
 176        case 1:
 177                s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
 178                break;
 179        case 2:
 180                s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
 181                break;
 182        default:
 183                printk(KERN_DEBUG "Invalid PCM Controller number!");
 184                return -EINVAL;
 185        }
 186
 187        return 0;
 188}
 189
 190static struct s3c_audio_pdata s3c_pcm_pdata = {
 191        .cfg_gpio = exynos4_pcm_cfg_gpio,
 192};
 193
 194static struct resource exynos4_pcm0_resource[] = {
 195        [0] = {
 196                .start  = EXYNOS4_PA_PCM0,
 197                .end    = EXYNOS4_PA_PCM0 + 0x100 - 1,
 198                .flags  = IORESOURCE_MEM,
 199        },
 200        [1] = {
 201                .start  = DMACH_PCM0_TX,
 202                .end    = DMACH_PCM0_TX,
 203                .flags  = IORESOURCE_DMA,
 204        },
 205        [2] = {
 206                .start  = DMACH_PCM0_RX,
 207                .end    = DMACH_PCM0_RX,
 208                .flags  = IORESOURCE_DMA,
 209        },
 210};
 211
 212struct platform_device exynos4_device_pcm0 = {
 213        .name = "samsung-pcm",
 214        .id = 0,
 215        .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
 216        .resource = exynos4_pcm0_resource,
 217        .dev = {
 218                .platform_data = &s3c_pcm_pdata,
 219        },
 220};
 221
 222static struct resource exynos4_pcm1_resource[] = {
 223        [0] = {
 224                .start  = EXYNOS4_PA_PCM1,
 225                .end    = EXYNOS4_PA_PCM1 + 0x100 - 1,
 226                .flags  = IORESOURCE_MEM,
 227        },
 228        [1] = {
 229                .start  = DMACH_PCM1_TX,
 230                .end    = DMACH_PCM1_TX,
 231                .flags  = IORESOURCE_DMA,
 232        },
 233        [2] = {
 234                .start  = DMACH_PCM1_RX,
 235                .end    = DMACH_PCM1_RX,
 236                .flags  = IORESOURCE_DMA,
 237        },
 238};
 239
 240struct platform_device exynos4_device_pcm1 = {
 241        .name = "samsung-pcm",
 242        .id = 1,
 243        .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
 244        .resource = exynos4_pcm1_resource,
 245        .dev = {
 246                .platform_data = &s3c_pcm_pdata,
 247        },
 248};
 249
 250static struct resource exynos4_pcm2_resource[] = {
 251        [0] = {
 252                .start  = EXYNOS4_PA_PCM2,
 253                .end    = EXYNOS4_PA_PCM2 + 0x100 - 1,
 254                .flags  = IORESOURCE_MEM,
 255        },
 256        [1] = {
 257                .start  = DMACH_PCM2_TX,
 258                .end    = DMACH_PCM2_TX,
 259                .flags  = IORESOURCE_DMA,
 260        },
 261        [2] = {
 262                .start  = DMACH_PCM2_RX,
 263                .end    = DMACH_PCM2_RX,
 264                .flags  = IORESOURCE_DMA,
 265        },
 266};
 267
 268struct platform_device exynos4_device_pcm2 = {
 269        .name = "samsung-pcm",
 270        .id = 2,
 271        .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
 272        .resource = exynos4_pcm2_resource,
 273        .dev = {
 274                .platform_data = &s3c_pcm_pdata,
 275        },
 276};
 277
 278/* AC97 Controller platform devices */
 279
 280static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
 281{
 282        return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
 283}
 284
 285static struct resource exynos4_ac97_resource[] = {
 286        [0] = {
 287                .start  = EXYNOS4_PA_AC97,
 288                .end    = EXYNOS4_PA_AC97 + 0x100 - 1,
 289                .flags  = IORESOURCE_MEM,
 290        },
 291        [1] = {
 292                .start  = DMACH_AC97_PCMOUT,
 293                .end    = DMACH_AC97_PCMOUT,
 294                .flags  = IORESOURCE_DMA,
 295        },
 296        [2] = {
 297                .start  = DMACH_AC97_PCMIN,
 298                .end    = DMACH_AC97_PCMIN,
 299                .flags  = IORESOURCE_DMA,
 300        },
 301        [3] = {
 302                .start  = DMACH_AC97_MICIN,
 303                .end    = DMACH_AC97_MICIN,
 304                .flags  = IORESOURCE_DMA,
 305        },
 306        [4] = {
 307                .start  = IRQ_AC97,
 308                .end    = IRQ_AC97,
 309                .flags  = IORESOURCE_IRQ,
 310        },
 311};
 312
 313static struct s3c_audio_pdata s3c_ac97_pdata = {
 314        .cfg_gpio = exynos4_ac97_cfg_gpio,
 315};
 316
 317static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
 318
 319struct platform_device exynos4_device_ac97 = {
 320        .name = "samsung-ac97",
 321        .id = -1,
 322        .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
 323        .resource = exynos4_ac97_resource,
 324        .dev = {
 325                .platform_data = &s3c_ac97_pdata,
 326                .dma_mask = &exynos4_ac97_dmamask,
 327                .coherent_dma_mask = DMA_BIT_MASK(32),
 328        },
 329};
 330
 331/* S/PDIF Controller platform_device */
 332
 333static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
 334{
 335        s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
 336
 337        return 0;
 338}
 339
 340static struct resource exynos4_spdif_resource[] = {
 341        [0] = {
 342                .start  = EXYNOS4_PA_SPDIF,
 343                .end    = EXYNOS4_PA_SPDIF + 0x100 - 1,
 344                .flags  = IORESOURCE_MEM,
 345        },
 346        [1] = {
 347                .start  = DMACH_SPDIF,
 348                .end    = DMACH_SPDIF,
 349                .flags  = IORESOURCE_DMA,
 350        },
 351};
 352
 353static struct s3c_audio_pdata samsung_spdif_pdata = {
 354        .cfg_gpio = exynos4_spdif_cfg_gpio,
 355};
 356
 357static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
 358
 359struct platform_device exynos4_device_spdif = {
 360        .name = "samsung-spdif",
 361        .id = -1,
 362        .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
 363        .resource = exynos4_spdif_resource,
 364        .dev = {
 365                .platform_data = &samsung_spdif_pdata,
 366                .dma_mask = &exynos4_spdif_dmamask,
 367                .coherent_dma_mask = DMA_BIT_MASK(32),
 368        },
 369};
 370