1/* sound/soc/samsung/jive_wm8750.c 2 * 3 * Copyright 2007,2008 Simtec Electronics 4 * 5 * Based on sound/soc/pxa/spitz.c 6 * Copyright 2005 Wolfson Microelectronics PLC. 7 * Copyright 2005 Openedhand Ltd. 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/module.h> 15#include <sound/soc.h> 16 17#include <asm/mach-types.h> 18 19#include "s3c2412-i2s.h" 20#include "../codecs/wm8750.h" 21 22static const struct snd_soc_dapm_route audio_map[] = { 23 { "Headphone Jack", NULL, "LOUT1" }, 24 { "Headphone Jack", NULL, "ROUT1" }, 25 { "Internal Speaker", NULL, "LOUT2" }, 26 { "Internal Speaker", NULL, "ROUT2" }, 27 { "LINPUT1", NULL, "Line Input" }, 28 { "RINPUT1", NULL, "Line Input" }, 29}; 30 31static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { 32 SND_SOC_DAPM_HP("Headphone Jack", NULL), 33 SND_SOC_DAPM_SPK("Internal Speaker", NULL), 34 SND_SOC_DAPM_LINE("Line In", NULL), 35}; 36 37static int jive_hw_params(struct snd_pcm_substream *substream, 38 struct snd_pcm_hw_params *params) 39{ 40 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 struct snd_soc_dai *codec_dai = rtd->codec_dai; 42 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 43 struct s3c_i2sv2_rate_calc div; 44 unsigned int clk = 0; 45 int ret = 0; 46 47 switch (params_rate(params)) { 48 case 8000: 49 case 16000: 50 case 48000: 51 case 96000: 52 clk = 12288000; 53 break; 54 case 11025: 55 case 22050: 56 case 44100: 57 clk = 11289600; 58 break; 59 } 60 61 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), 62 s3c_i2sv2_get_clock(cpu_dai)); 63 64 /* set the codec system clock for DAC and ADC */ 65 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, 66 SND_SOC_CLOCK_IN); 67 if (ret < 0) 68 return ret; 69 70 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); 71 if (ret < 0) 72 return ret; 73 74 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, 75 div.clk_div - 1); 76 if (ret < 0) 77 return ret; 78 79 return 0; 80} 81 82static struct snd_soc_ops jive_ops = { 83 .hw_params = jive_hw_params, 84}; 85 86static struct snd_soc_dai_link jive_dai = { 87 .name = "wm8750", 88 .stream_name = "WM8750", 89 .cpu_dai_name = "s3c2412-i2s", 90 .codec_dai_name = "wm8750-hifi", 91 .platform_name = "s3c2412-i2s", 92 .codec_name = "wm8750.0-001a", 93 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 94 SND_SOC_DAIFMT_CBS_CFS, 95 .ops = &jive_ops, 96}; 97 98/* jive audio machine driver */ 99static struct snd_soc_card snd_soc_machine_jive = { 100 .name = "Jive", 101 .owner = THIS_MODULE, 102 .dai_link = &jive_dai, 103 .num_links = 1, 104 105 .dapm_widgets = wm8750_dapm_widgets, 106 .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), 107 .dapm_routes = audio_map, 108 .num_dapm_routes = ARRAY_SIZE(audio_map), 109 .fully_routed = true, 110}; 111 112static struct platform_device *jive_snd_device; 113 114static int __init jive_init(void) 115{ 116 int ret; 117 118 if (!machine_is_jive()) 119 return 0; 120 121 printk("JIVE WM8750 Audio support\n"); 122 123 jive_snd_device = platform_device_alloc("soc-audio", -1); 124 if (!jive_snd_device) 125 return -ENOMEM; 126 127 platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive); 128 ret = platform_device_add(jive_snd_device); 129 130 if (ret) 131 platform_device_put(jive_snd_device); 132 133 return ret; 134} 135 136static void __exit jive_exit(void) 137{ 138 platform_device_unregister(jive_snd_device); 139} 140 141module_init(jive_init); 142module_exit(jive_exit); 143 144MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 145MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); 146MODULE_LICENSE("GPL"); 147