linux/sound/soc/davinci/davinci-evm.c
<<
>>
Prefs
   1/*
   2 * ASoC driver for TI DAVINCI EVM platform
   3 *
   4 * Author:      Vladimir Barinov, <vbarinov@embeddedalley.com>
   5 * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
   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
  12#include <linux/module.h>
  13#include <linux/moduleparam.h>
  14#include <linux/timer.h>
  15#include <linux/interrupt.h>
  16#include <linux/platform_device.h>
  17#include <linux/platform_data/edma.h>
  18#include <linux/i2c.h>
  19#include <sound/core.h>
  20#include <sound/pcm.h>
  21#include <sound/soc.h>
  22
  23#include <asm/dma.h>
  24#include <asm/mach-types.h>
  25
  26#include "davinci-pcm.h"
  27#include "davinci-i2s.h"
  28#include "davinci-mcasp.h"
  29
  30#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
  31                SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
  32static int evm_hw_params(struct snd_pcm_substream *substream,
  33                         struct snd_pcm_hw_params *params)
  34{
  35        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  36        struct snd_soc_dai *codec_dai = rtd->codec_dai;
  37        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  38        int ret = 0;
  39        unsigned sysclk;
  40
  41        /* ASP1 on DM355 EVM is clocked by an external oscillator */
  42        if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
  43            machine_is_davinci_dm365_evm())
  44                sysclk = 27000000;
  45
  46        /* ASP0 in DM6446 EVM is clocked by U55, as configured by
  47         * board-dm644x-evm.c using GPIOs from U18.  There are six
  48         * options; here we "know" we use a 48 KHz sample rate.
  49         */
  50        else if (machine_is_davinci_evm())
  51                sysclk = 12288000;
  52
  53        else if (machine_is_davinci_da830_evm() ||
  54                                machine_is_davinci_da850_evm())
  55                sysclk = 24576000;
  56
  57        else
  58                return -EINVAL;
  59
  60        /* set codec DAI configuration */
  61        ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
  62        if (ret < 0)
  63                return ret;
  64
  65        /* set cpu DAI configuration */
  66        ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
  67        if (ret < 0)
  68                return ret;
  69
  70        /* set the codec system clock */
  71        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
  72        if (ret < 0)
  73                return ret;
  74
  75        /* set the CPU system clock */
  76        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
  77        if (ret < 0)
  78                return ret;
  79
  80        return 0;
  81}
  82
  83static int evm_spdif_hw_params(struct snd_pcm_substream *substream,
  84                                struct snd_pcm_hw_params *params)
  85{
  86        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  87        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  88
  89        /* set cpu DAI configuration */
  90        return snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
  91}
  92
  93static struct snd_soc_ops evm_ops = {
  94        .hw_params = evm_hw_params,
  95};
  96
  97static struct snd_soc_ops evm_spdif_ops = {
  98        .hw_params = evm_spdif_hw_params,
  99};
 100
 101/* davinci-evm machine dapm widgets */
 102static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
 103        SND_SOC_DAPM_HP("Headphone Jack", NULL),
 104        SND_SOC_DAPM_LINE("Line Out", NULL),
 105        SND_SOC_DAPM_MIC("Mic Jack", NULL),
 106        SND_SOC_DAPM_LINE("Line In", NULL),
 107};
 108
 109/* davinci-evm machine audio_mapnections to the codec pins */
 110static const struct snd_soc_dapm_route audio_map[] = {
 111        /* Headphone connected to HPLOUT, HPROUT */
 112        {"Headphone Jack", NULL, "HPLOUT"},
 113        {"Headphone Jack", NULL, "HPROUT"},
 114
 115        /* Line Out connected to LLOUT, RLOUT */
 116        {"Line Out", NULL, "LLOUT"},
 117        {"Line Out", NULL, "RLOUT"},
 118
 119        /* Mic connected to (MIC3L | MIC3R) */
 120        {"MIC3L", NULL, "Mic Bias"},
 121        {"MIC3R", NULL, "Mic Bias"},
 122        {"Mic Bias", NULL, "Mic Jack"},
 123
 124        /* Line In connected to (LINE1L | LINE2L), (LINE1R | LINE2R) */
 125        {"LINE1L", NULL, "Line In"},
 126        {"LINE2L", NULL, "Line In"},
 127        {"LINE1R", NULL, "Line In"},
 128        {"LINE2R", NULL, "Line In"},
 129};
 130
 131/* Logic for a aic3x as connected on a davinci-evm */
 132static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 133{
 134        struct snd_soc_codec *codec = rtd->codec;
 135        struct snd_soc_dapm_context *dapm = &codec->dapm;
 136
 137        /* Add davinci-evm specific widgets */
 138        snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
 139                                  ARRAY_SIZE(aic3x_dapm_widgets));
 140
 141        /* Set up davinci-evm specific audio path audio_map */
 142        snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
 143
 144        /* not connected */
 145        snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
 146        snd_soc_dapm_disable_pin(dapm, "HPLCOM");
 147        snd_soc_dapm_disable_pin(dapm, "HPRCOM");
 148
 149        /* always connected */
 150        snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
 151        snd_soc_dapm_enable_pin(dapm, "Line Out");
 152        snd_soc_dapm_enable_pin(dapm, "Mic Jack");
 153        snd_soc_dapm_enable_pin(dapm, "Line In");
 154
 155        return 0;
 156}
 157
 158/* davinci-evm digital audio interface glue - connects codec <--> CPU */
 159static struct snd_soc_dai_link dm6446_evm_dai = {
 160        .name = "TLV320AIC3X",
 161        .stream_name = "AIC3X",
 162        .cpu_dai_name = "davinci-mcbsp",
 163        .codec_dai_name = "tlv320aic3x-hifi",
 164        .codec_name = "tlv320aic3x-codec.1-001b",
 165        .platform_name = "davinci-mcbsp",
 166        .init = evm_aic3x_init,
 167        .ops = &evm_ops,
 168};
 169
 170static struct snd_soc_dai_link dm355_evm_dai = {
 171        .name = "TLV320AIC3X",
 172        .stream_name = "AIC3X",
 173        .cpu_dai_name = "davinci-mcbsp.1",
 174        .codec_dai_name = "tlv320aic3x-hifi",
 175        .codec_name = "tlv320aic3x-codec.1-001b",
 176        .platform_name = "davinci-mcbsp.1",
 177        .init = evm_aic3x_init,
 178        .ops = &evm_ops,
 179};
 180
 181static struct snd_soc_dai_link dm365_evm_dai = {
 182#ifdef CONFIG_SND_DM365_AIC3X_CODEC
 183        .name = "TLV320AIC3X",
 184        .stream_name = "AIC3X",
 185        .cpu_dai_name = "davinci-mcbsp",
 186        .codec_dai_name = "tlv320aic3x-hifi",
 187        .init = evm_aic3x_init,
 188        .codec_name = "tlv320aic3x-codec.1-0018",
 189        .ops = &evm_ops,
 190        .platform_name = "davinci-mcbsp",
 191#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
 192        .name = "Voice Codec - CQ93VC",
 193        .stream_name = "CQ93",
 194        .cpu_dai_name = "davinci-vcif",
 195        .codec_dai_name = "cq93vc-hifi",
 196        .codec_name = "cq93vc-codec",
 197        .platform_name = "davinci-vcif",
 198#endif
 199};
 200
 201static struct snd_soc_dai_link dm6467_evm_dai[] = {
 202        {
 203                .name = "TLV320AIC3X",
 204                .stream_name = "AIC3X",
 205                .cpu_dai_name= "davinci-mcasp.0",
 206                .codec_dai_name = "tlv320aic3x-hifi",
 207                .platform_name = "davinci-mcasp.0",
 208                .codec_name = "tlv320aic3x-codec.0-001a",
 209                .init = evm_aic3x_init,
 210                .ops = &evm_ops,
 211        },
 212        {
 213                .name = "McASP",
 214                .stream_name = "spdif",
 215                .cpu_dai_name= "davinci-mcasp.1",
 216                .codec_dai_name = "dit-hifi",
 217                .codec_name = "spdif_dit",
 218                .platform_name = "davinci-mcasp.1",
 219                .ops = &evm_spdif_ops,
 220        },
 221};
 222
 223static struct snd_soc_dai_link da830_evm_dai = {
 224        .name = "TLV320AIC3X",
 225        .stream_name = "AIC3X",
 226        .cpu_dai_name = "davinci-mcasp.1",
 227        .codec_dai_name = "tlv320aic3x-hifi",
 228        .codec_name = "tlv320aic3x-codec.1-0018",
 229        .platform_name = "davinci-mcasp.1",
 230        .init = evm_aic3x_init,
 231        .ops = &evm_ops,
 232};
 233
 234static struct snd_soc_dai_link da850_evm_dai = {
 235        .name = "TLV320AIC3X",
 236        .stream_name = "AIC3X",
 237        .cpu_dai_name= "davinci-mcasp.0",
 238        .codec_dai_name = "tlv320aic3x-hifi",
 239        .codec_name = "tlv320aic3x-codec.1-0018",
 240        .platform_name = "davinci-mcasp.0",
 241        .init = evm_aic3x_init,
 242        .ops = &evm_ops,
 243};
 244
 245/* davinci dm6446 evm audio machine driver */
 246static struct snd_soc_card dm6446_snd_soc_card_evm = {
 247        .name = "DaVinci DM6446 EVM",
 248        .owner = THIS_MODULE,
 249        .dai_link = &dm6446_evm_dai,
 250        .num_links = 1,
 251};
 252
 253/* davinci dm355 evm audio machine driver */
 254static struct snd_soc_card dm355_snd_soc_card_evm = {
 255        .name = "DaVinci DM355 EVM",
 256        .owner = THIS_MODULE,
 257        .dai_link = &dm355_evm_dai,
 258        .num_links = 1,
 259};
 260
 261/* davinci dm365 evm audio machine driver */
 262static struct snd_soc_card dm365_snd_soc_card_evm = {
 263        .name = "DaVinci DM365 EVM",
 264        .owner = THIS_MODULE,
 265        .dai_link = &dm365_evm_dai,
 266        .num_links = 1,
 267};
 268
 269/* davinci dm6467 evm audio machine driver */
 270static struct snd_soc_card dm6467_snd_soc_card_evm = {
 271        .name = "DaVinci DM6467 EVM",
 272        .owner = THIS_MODULE,
 273        .dai_link = dm6467_evm_dai,
 274        .num_links = ARRAY_SIZE(dm6467_evm_dai),
 275};
 276
 277static struct snd_soc_card da830_snd_soc_card = {
 278        .name = "DA830/OMAP-L137 EVM",
 279        .owner = THIS_MODULE,
 280        .dai_link = &da830_evm_dai,
 281        .num_links = 1,
 282};
 283
 284static struct snd_soc_card da850_snd_soc_card = {
 285        .name = "DA850/OMAP-L138 EVM",
 286        .owner = THIS_MODULE,
 287        .dai_link = &da850_evm_dai,
 288        .num_links = 1,
 289};
 290
 291static struct platform_device *evm_snd_device;
 292
 293static int __init evm_init(void)
 294{
 295        struct snd_soc_card *evm_snd_dev_data;
 296        int index;
 297        int ret;
 298
 299        if (machine_is_davinci_evm()) {
 300                evm_snd_dev_data = &dm6446_snd_soc_card_evm;
 301                index = 0;
 302        } else if (machine_is_davinci_dm355_evm()) {
 303                evm_snd_dev_data = &dm355_snd_soc_card_evm;
 304                index = 1;
 305        } else if (machine_is_davinci_dm365_evm()) {
 306                evm_snd_dev_data = &dm365_snd_soc_card_evm;
 307                index = 0;
 308        } else if (machine_is_davinci_dm6467_evm()) {
 309                evm_snd_dev_data = &dm6467_snd_soc_card_evm;
 310                index = 0;
 311        } else if (machine_is_davinci_da830_evm()) {
 312                evm_snd_dev_data = &da830_snd_soc_card;
 313                index = 1;
 314        } else if (machine_is_davinci_da850_evm()) {
 315                evm_snd_dev_data = &da850_snd_soc_card;
 316                index = 0;
 317        } else
 318                return -EINVAL;
 319
 320        evm_snd_device = platform_device_alloc("soc-audio", index);
 321        if (!evm_snd_device)
 322                return -ENOMEM;
 323
 324        platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
 325        ret = platform_device_add(evm_snd_device);
 326        if (ret)
 327                platform_device_put(evm_snd_device);
 328
 329        return ret;
 330}
 331
 332static void __exit evm_exit(void)
 333{
 334        platform_device_unregister(evm_snd_device);
 335}
 336
 337module_init(evm_init);
 338module_exit(evm_exit);
 339
 340MODULE_AUTHOR("Vladimir Barinov");
 341MODULE_DESCRIPTION("TI DAVINCI EVM ASoC driver");
 342MODULE_LICENSE("GPL");
 343