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