blob: 4eab4b491dee4e9143894dd80dc1f85115b6842f [file] [log] [blame]
Misael Lopez Cruz44515822008-11-24 22:21:23 -06001/*
2 * sdp3430.c -- SoC audio for TI OMAP3430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * Based on:
7 * Author: Steve Sakoman <steve@sakoman.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/clk.h>
26#include <linux/platform_device.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33#include <mach/hardware.h>
34#include <mach/gpio.h>
35#include <mach/mcbsp.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39#include "../codecs/twl4030.h"
40
41static int sdp3430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops sdp3430_ops = {
81 .hw_params = sdp3430_hw_params,
82};
83
Lopez Cruz, Misael979c0362009-03-04 11:39:07 -060084/* SDP3430 machine DAPM */
85static const struct snd_soc_dapm_widget sdp3430_twl4030_dapm_widgets[] = {
86 SND_SOC_DAPM_MIC("Ext Mic", NULL),
87 SND_SOC_DAPM_SPK("Ext Spk", NULL),
88 SND_SOC_DAPM_HP("Headset Jack", NULL),
89};
90
91static const struct snd_soc_dapm_route audio_map[] = {
92 /* External Mics: MAINMIC, SUBMIC with bias*/
93 {"MAINMIC", NULL, "Mic Bias 1"},
94 {"SUBMIC", NULL, "Mic Bias 2"},
95 {"Mic Bias 1", NULL, "Ext Mic"},
96 {"Mic Bias 2", NULL, "Ext Mic"},
97
98 /* External Speakers: HFL, HFR */
99 {"Ext Spk", NULL, "HFL"},
100 {"Ext Spk", NULL, "HFR"},
101
102 /* Headset: HSMIC (with bias), HSOL, HSOR */
103 {"Headset Jack", NULL, "HSOL"},
104 {"Headset Jack", NULL, "HSOR"},
105 {"HSMIC", NULL, "Headset Mic Bias"},
106 {"Headset Mic Bias", NULL, "Headset Jack"},
107};
108
109static int sdp3430_twl4030_init(struct snd_soc_codec *codec)
110{
111 int ret;
112
113 /* Add SDP3430 specific widgets */
114 ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets,
115 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
116 if (ret)
117 return ret;
118
119 /* Set up SDP3430 specific audio path audio_map */
120 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
121
122 /* SDP3430 connected pins */
123 snd_soc_dapm_enable_pin(codec, "Ext Mic");
124 snd_soc_dapm_enable_pin(codec, "Ext Spk");
125 snd_soc_dapm_enable_pin(codec, "Headset Jack");
126
127 /* TWL4030 not connected pins */
128 snd_soc_dapm_nc_pin(codec, "AUXL");
129 snd_soc_dapm_nc_pin(codec, "AUXR");
130 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
131 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
132 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
133
134 snd_soc_dapm_nc_pin(codec, "OUTL");
135 snd_soc_dapm_nc_pin(codec, "OUTR");
136 snd_soc_dapm_nc_pin(codec, "EARPIECE");
137 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
138 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
139 snd_soc_dapm_nc_pin(codec, "CARKITL");
140 snd_soc_dapm_nc_pin(codec, "CARKITR");
141
142 ret = snd_soc_dapm_sync(codec);
143
144 return ret;
145}
146
Misael Lopez Cruz44515822008-11-24 22:21:23 -0600147/* Digital audio interface glue - connects codec <--> CPU */
148static struct snd_soc_dai_link sdp3430_dai = {
149 .name = "TWL4030",
150 .stream_name = "TWL4030",
151 .cpu_dai = &omap_mcbsp_dai[0],
152 .codec_dai = &twl4030_dai,
Lopez Cruz, Misael979c0362009-03-04 11:39:07 -0600153 .init = sdp3430_twl4030_init,
Misael Lopez Cruz44515822008-11-24 22:21:23 -0600154 .ops = &sdp3430_ops,
155};
156
157/* Audio machine driver */
Lopez Cruz, Misael272edb02009-02-10 02:05:07 -0600158static struct snd_soc_card snd_soc_sdp3430 = {
Misael Lopez Cruz44515822008-11-24 22:21:23 -0600159 .name = "SDP3430",
Mark Brown87689d52008-12-02 16:01:14 +0000160 .platform = &omap_soc_platform,
Misael Lopez Cruz44515822008-11-24 22:21:23 -0600161 .dai_link = &sdp3430_dai,
162 .num_links = 1,
163};
164
165/* Audio subsystem */
166static struct snd_soc_device sdp3430_snd_devdata = {
Lopez Cruz, Misael272edb02009-02-10 02:05:07 -0600167 .card = &snd_soc_sdp3430,
Misael Lopez Cruz44515822008-11-24 22:21:23 -0600168 .codec_dev = &soc_codec_dev_twl4030,
169};
170
171static struct platform_device *sdp3430_snd_device;
172
173static int __init sdp3430_soc_init(void)
174{
175 int ret;
176
177 if (!machine_is_omap_3430sdp()) {
178 pr_debug("Not SDP3430!\n");
179 return -ENODEV;
180 }
181 printk(KERN_INFO "SDP3430 SoC init\n");
182
183 sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
184 if (!sdp3430_snd_device) {
185 printk(KERN_ERR "Platform device allocation failed\n");
186 return -ENOMEM;
187 }
188
189 platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata);
190 sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
191 *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */
192
193 ret = platform_device_add(sdp3430_snd_device);
194 if (ret)
195 goto err1;
196
197 return 0;
198
199err1:
200 printk(KERN_ERR "Unable to add platform device\n");
201 platform_device_put(sdp3430_snd_device);
202
203 return ret;
204}
205module_init(sdp3430_soc_init);
206
207static void __exit sdp3430_soc_exit(void)
208{
209 platform_device_unregister(sdp3430_snd_device);
210}
211module_exit(sdp3430_soc_exit);
212
213MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
214MODULE_DESCRIPTION("ALSA SoC SDP3430");
215MODULE_LICENSE("GPL");
216