1b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra/* 2b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * igep0020.c -- SoC audio for IGEP v2 3b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 4b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * Based on sound/soc/omap/overo.c by Steve Sakoman 5b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 6b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * This program is free software; you can redistribute it and/or 7b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * modify it under the terms of the GNU General Public License 8b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * version 2 as published by the Free Software Foundation. 9b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 10b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * This program is distributed in the hope that it will be useful, but 11b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * WITHOUT ANY WARRANTY; without even the implied warranty of 12b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * General Public License for more details. 14b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 15b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * You should have received a copy of the GNU General Public License 16b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * along with this program; if not, write to the Free Software 17b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 02110-1301 USA 19b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra * 20b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra */ 21b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 22b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <linux/clk.h> 23b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <linux/platform_device.h> 24b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <sound/core.h> 25b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <sound/pcm.h> 26b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <sound/soc.h> 27b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 28b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <asm/mach-types.h> 29b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <mach/hardware.h> 30b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <mach/gpio.h> 31b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include <plat/mcbsp.h> 32b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 33b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include "omap-mcbsp.h" 34b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra#include "omap-pcm.h" 35b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 36b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic int igep2_hw_params(struct snd_pcm_substream *substream, 37b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra struct snd_pcm_hw_params *params) 38b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra{ 39b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra struct snd_soc_pcm_runtime *rtd = substream->private_data; 40f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood struct snd_soc_dai *codec_dai = rtd->codec_dai; 41f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 42b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra int ret; 43b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 44b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra /* Set codec DAI configuration */ 45b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra ret = snd_soc_dai_set_fmt(codec_dai, 46b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_I2S | 47b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_NB_NF | 48b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_CBM_CFM); 49b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra if (ret < 0) { 50b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_ERR "can't set codec DAI configuration\n"); 51b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return ret; 52b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra } 53b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 54b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra /* Set cpu DAI configuration */ 55b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra ret = snd_soc_dai_set_fmt(cpu_dai, 56b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_I2S | 57b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_NB_NF | 58b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_DAIFMT_CBM_CFM); 59b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra if (ret < 0) { 60b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_ERR "can't set cpu DAI configuration\n"); 61b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return ret; 62b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra } 63b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 64b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra /* Set the codec system clock for DAC and ADC */ 65b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, 66b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra SND_SOC_CLOCK_IN); 67b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra if (ret < 0) { 68b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_ERR "can't set codec system clock\n"); 69b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return ret; 70b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra } 71b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 72b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return 0; 73b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra} 74b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 75b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic struct snd_soc_ops igep2_ops = { 76b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .hw_params = igep2_hw_params, 77b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra}; 78b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 79b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra/* Digital audio interface glue - connects codec <--> CPU */ 80b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic struct snd_soc_dai_link igep2_dai = { 81b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .name = "TWL4030", 82b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .stream_name = "TWL4030", 83f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood .cpu_dai_name = "omap-mcbsp-dai.1", 84f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood .codec_dai_name = "twl4030-hifi", 85f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood .platform_name = "omap-pcm-audio", 86f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood .codec_name = "twl4030-codec", 87b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .ops = &igep2_ops, 88b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra}; 89b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 90b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra/* Audio machine driver */ 91b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic struct snd_soc_card snd_soc_card_igep2 = { 92b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .name = "igep2", 93b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .dai_link = &igep2_dai, 94b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra .num_links = 1, 95b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra}; 96b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 97b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic struct platform_device *igep2_snd_device; 98b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 99b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic int __init igep2_soc_init(void) 100b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra{ 101b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra int ret; 102b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 103ec588ae6c21ae20a22ce13a287728a220935b8eeJarkko Nikula if (!machine_is_igep0020()) 104b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return -ENODEV; 105b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_INFO "IGEP v2 SoC init\n"); 106b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 107b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra igep2_snd_device = platform_device_alloc("soc-audio", -1); 108b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra if (!igep2_snd_device) { 109b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_ERR "Platform device allocation failed\n"); 110b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return -ENOMEM; 111b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra } 112b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 113f0fba2ad1b6b53d5360125c41953b7afcd6deff0Liam Girdwood platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2); 114b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 115b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra ret = platform_device_add(igep2_snd_device); 116b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra if (ret) 117b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra goto err1; 118b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 119b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return 0; 120b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 121b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serraerr1: 122b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra printk(KERN_ERR "Unable to add platform device\n"); 123b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra platform_device_put(igep2_snd_device); 124b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 125b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra return ret; 126b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra} 127b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serramodule_init(igep2_soc_init); 128b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 129b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serrastatic void __exit igep2_soc_exit(void) 130b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra{ 131b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra platform_device_unregister(igep2_snd_device); 132b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra} 133b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serramodule_exit(igep2_soc_exit); 134b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i Serra 135b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i SerraMODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>"); 136b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i SerraMODULE_DESCRIPTION("ALSA SoC IGEP v2"); 137b2a2236d1f5e7c09c8e74b61f13d8ba3fe82f7beEnric Balletbò i SerraMODULE_LICENSE("GPL"); 138