1/* 2 * DB1200 ASoC audio fabric support code. 3 * 4 * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> 5 * 6 */ 7 8#include <linux/module.h> 9#include <linux/moduleparam.h> 10#include <linux/timer.h> 11#include <linux/interrupt.h> 12#include <linux/platform_device.h> 13#include <sound/core.h> 14#include <sound/pcm.h> 15#include <sound/soc.h> 16#include <sound/soc-dapm.h> 17#include <asm/mach-au1x00/au1000.h> 18#include <asm/mach-au1x00/au1xxx_psc.h> 19#include <asm/mach-au1x00/au1xxx_dbdma.h> 20#include <asm/mach-db1x00/bcsr.h> 21 22#include "../codecs/ac97.h" 23#include "../codecs/wm8731.h" 24#include "psc.h" 25 26/*------------------------- AC97 PART ---------------------------*/ 27 28static struct snd_soc_dai_link db1200_ac97_dai = { 29 .name = "AC97", 30 .stream_name = "AC97 HiFi", 31 .cpu_dai = &au1xpsc_ac97_dai, 32 .codec_dai = &ac97_dai, 33}; 34 35static struct snd_soc_card db1200_ac97_machine = { 36 .name = "DB1200_AC97", 37 .dai_link = &db1200_ac97_dai, 38 .num_links = 1, 39 .platform = &au1xpsc_soc_platform, 40}; 41 42static struct snd_soc_device db1200_ac97_devdata = { 43 .card = &db1200_ac97_machine, 44 .codec_dev = &soc_codec_dev_ac97, 45}; 46 47/*------------------------- I2S PART ---------------------------*/ 48 49static int db1200_i2s_startup(struct snd_pcm_substream *substream) 50{ 51 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 54 int ret; 55 56 /* WM8731 has its own 12MHz crystal */ 57 snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, 58 12000000, SND_SOC_CLOCK_IN); 59 60 /* codec is bitclock and lrclk master */ 61 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | 62 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 63 if (ret < 0) 64 goto out; 65 66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J | 67 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 68 if (ret < 0) 69 goto out; 70 71 ret = 0; 72out: 73 return ret; 74} 75 76static struct snd_soc_ops db1200_i2s_wm8731_ops = { 77 .startup = db1200_i2s_startup, 78}; 79 80static struct snd_soc_dai_link db1200_i2s_dai = { 81 .name = "WM8731", 82 .stream_name = "WM8731 PCM", 83 .cpu_dai = &au1xpsc_i2s_dai, 84 .codec_dai = &wm8731_dai, 85 .ops = &db1200_i2s_wm8731_ops, 86}; 87 88static struct snd_soc_card db1200_i2s_machine = { 89 .name = "DB1200_I2S", 90 .dai_link = &db1200_i2s_dai, 91 .num_links = 1, 92 .platform = &au1xpsc_soc_platform, 93}; 94 95static struct snd_soc_device db1200_i2s_devdata = { 96 .card = &db1200_i2s_machine, 97 .codec_dev = &soc_codec_dev_wm8731, 98}; 99 100/*------------------------- COMMON PART ---------------------------*/ 101 102static struct platform_device *db1200_asoc_dev; 103 104static int __init db1200_audio_load(void) 105{ 106 int ret; 107 108 ret = -ENOMEM; 109 db1200_asoc_dev = platform_device_alloc("soc-audio", -1); 110 if (!db1200_asoc_dev) 111 goto out; 112 113 /* DB1200 board setup set PSC1MUX to preferred audio device */ 114 if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) 115 platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_devdata); 116 else 117 platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_devdata); 118 119 db1200_ac97_devdata.dev = &db1200_asoc_dev->dev; 120 db1200_i2s_devdata.dev = &db1200_asoc_dev->dev; 121 ret = platform_device_add(db1200_asoc_dev); 122 123 if (ret) { 124 platform_device_put(db1200_asoc_dev); 125 db1200_asoc_dev = NULL; 126 } 127out: 128 return ret; 129} 130 131static void __exit db1200_audio_unload(void) 132{ 133 platform_device_unregister(db1200_asoc_dev); 134} 135 136module_init(db1200_audio_load); 137module_exit(db1200_audio_unload); 138 139MODULE_LICENSE("GPL"); 140MODULE_DESCRIPTION("DB1200 ASoC audio support"); 141MODULE_AUTHOR("Manuel Lauss"); 142