1/* 2 * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM 3 * 4 * Author: Anuj Aggarwal <anuj.aggarwal@ti.com> 5 * 6 * Based on sound/soc/omap/beagle.c by Steve Sakoman 7 * 8 * Copyright (C) 2009 Texas Instruments Incorporated 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation version 2. 13 * 14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, 15 * whether express or implied; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 */ 19 20#include <linux/clk.h> 21#include <linux/platform_device.h> 22#include <linux/module.h> 23#include <sound/core.h> 24#include <sound/pcm.h> 25#include <sound/soc.h> 26 27#include <asm/mach-types.h> 28#include <linux/platform_data/asoc-ti-mcbsp.h> 29 30#include "omap-mcbsp.h" 31 32#include "../codecs/tlv320aic23.h" 33 34#define CODEC_CLOCK 12000000 35 36static int am3517evm_hw_params(struct snd_pcm_substream *substream, 37 struct snd_pcm_hw_params *params) 38{ 39 struct snd_soc_pcm_runtime *rtd = substream->private_data; 40 struct snd_soc_dai *codec_dai = rtd->codec_dai; 41 int ret; 42 43 /* Set the codec system clock for DAC and ADC */ 44 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 45 CODEC_CLOCK, SND_SOC_CLOCK_IN); 46 if (ret < 0) 47 printk(KERN_ERR "can't set codec system clock\n"); 48 49 return ret; 50} 51 52static struct snd_soc_ops am3517evm_ops = { 53 .hw_params = am3517evm_hw_params, 54}; 55 56/* am3517evm machine dapm widgets */ 57static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { 58 SND_SOC_DAPM_HP("Line Out", NULL), 59 SND_SOC_DAPM_LINE("Line In", NULL), 60 SND_SOC_DAPM_MIC("Mic In", NULL), 61}; 62 63static const struct snd_soc_dapm_route audio_map[] = { 64 /* Line Out connected to LLOUT, RLOUT */ 65 {"Line Out", NULL, "LOUT"}, 66 {"Line Out", NULL, "ROUT"}, 67 68 {"LLINEIN", NULL, "Line In"}, 69 {"RLINEIN", NULL, "Line In"}, 70 71 {"MICIN", NULL, "Mic In"}, 72}; 73 74/* Digital audio interface glue - connects codec <--> CPU */ 75static struct snd_soc_dai_link am3517evm_dai = { 76 .name = "TLV320AIC23", 77 .stream_name = "AIC23", 78 .cpu_dai_name = "omap-mcbsp.1", 79 .codec_dai_name = "tlv320aic23-hifi", 80 .platform_name = "omap-mcbsp.1", 81 .codec_name = "tlv320aic23-codec.2-001a", 82 .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | 83 SND_SOC_DAIFMT_CBM_CFM, 84 .ops = &am3517evm_ops, 85}; 86 87/* Audio machine driver */ 88static struct snd_soc_card snd_soc_am3517evm = { 89 .name = "am3517evm", 90 .owner = THIS_MODULE, 91 .dai_link = &am3517evm_dai, 92 .num_links = 1, 93 94 .dapm_widgets = tlv320aic23_dapm_widgets, 95 .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), 96 .dapm_routes = audio_map, 97 .num_dapm_routes = ARRAY_SIZE(audio_map), 98}; 99 100static struct platform_device *am3517evm_snd_device; 101 102static int __init am3517evm_soc_init(void) 103{ 104 int ret; 105 106 if (!machine_is_omap3517evm()) 107 return -ENODEV; 108 pr_info("OMAP3517 / AM3517 EVM SoC init\n"); 109 110 am3517evm_snd_device = platform_device_alloc("soc-audio", -1); 111 if (!am3517evm_snd_device) { 112 printk(KERN_ERR "Platform device allocation failed\n"); 113 return -ENOMEM; 114 } 115 116 platform_set_drvdata(am3517evm_snd_device, &snd_soc_am3517evm); 117 118 ret = platform_device_add(am3517evm_snd_device); 119 if (ret) 120 goto err1; 121 122 return 0; 123 124err1: 125 printk(KERN_ERR "Unable to add platform device\n"); 126 platform_device_put(am3517evm_snd_device); 127 128 return ret; 129} 130 131static void __exit am3517evm_soc_exit(void) 132{ 133 platform_device_unregister(am3517evm_snd_device); 134} 135 136module_init(am3517evm_soc_init); 137module_exit(am3517evm_soc_exit); 138 139MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); 140MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM"); 141MODULE_LICENSE("GPL v2"); 142