2 * tavorevb3.c -- SoC audio for Tavor EVB3
4 * Copyright (C) 2010 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/module.h>
13 #include <linux/moduleparam.h>
14 #include <linux/device.h>
15 #include <linux/clk.h>
16 #include <linux/i2c.h>
17 #include <sound/core.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/jack.h>
23 #include <asm/mach-types.h>
25 #include "../codecs/88pm860x-codec.h"
28 static int evb3_pm860x_init(struct snd_soc_pcm_runtime
*rtd
);
30 static struct platform_device
*evb3_snd_device
;
32 static struct snd_soc_jack hs_jack
, mic_jack
;
34 static struct snd_soc_jack_pin hs_jack_pins
[] = {
35 { .pin
= "Headset Stereophone", .mask
= SND_JACK_HEADPHONE
, },
38 static struct snd_soc_jack_pin mic_jack_pins
[] = {
39 { .pin
= "Headset Mic 2", .mask
= SND_JACK_MICROPHONE
, },
42 /* tavorevb3 machine dapm widgets */
43 static const struct snd_soc_dapm_widget evb3_dapm_widgets
[] = {
44 SND_SOC_DAPM_HP("Headset Stereophone", NULL
),
45 SND_SOC_DAPM_LINE("Lineout Out 1", NULL
),
46 SND_SOC_DAPM_LINE("Lineout Out 2", NULL
),
47 SND_SOC_DAPM_SPK("Ext Speaker", NULL
),
48 SND_SOC_DAPM_MIC("Ext Mic 1", NULL
),
49 SND_SOC_DAPM_MIC("Headset Mic 2", NULL
),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL
),
53 /* tavorevb3 machine audio map */
54 static const struct snd_soc_dapm_route evb3_audio_map
[] = {
55 {"Headset Stereophone", NULL
, "HS1"},
56 {"Headset Stereophone", NULL
, "HS2"},
58 {"Ext Speaker", NULL
, "LSP"},
59 {"Ext Speaker", NULL
, "LSN"},
61 {"Lineout Out 1", NULL
, "LINEOUT1"},
62 {"Lineout Out 2", NULL
, "LINEOUT2"},
64 {"MIC1P", NULL
, "Mic1 Bias"},
65 {"MIC1N", NULL
, "Mic1 Bias"},
66 {"Mic1 Bias", NULL
, "Ext Mic 1"},
68 {"MIC2P", NULL
, "Mic1 Bias"},
69 {"MIC2N", NULL
, "Mic1 Bias"},
70 {"Mic1 Bias", NULL
, "Headset Mic 2"},
72 {"MIC3P", NULL
, "Mic3 Bias"},
73 {"MIC3N", NULL
, "Mic3 Bias"},
74 {"Mic3 Bias", NULL
, "Ext Mic 3"},
77 static int evb3_i2s_hw_params(struct snd_pcm_substream
*substream
,
78 struct snd_pcm_hw_params
*params
)
80 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
81 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
82 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
83 int width
= snd_pcm_format_physical_width(params_format(params
));
86 ret
= snd_soc_dai_set_sysclk(cpu_dai
, PXA_SSP_CLK_NET_PLL
, 0,
91 ret
= snd_soc_dai_set_sysclk(codec_dai
, 0, 0, PM860X_CLK_DIR_OUT
);
95 ret
= snd_soc_dai_set_tdm_slot(cpu_dai
, 3, 3, 2, width
);
99 static struct snd_soc_ops evb3_i2s_ops
= {
100 .hw_params
= evb3_i2s_hw_params
,
103 static struct snd_soc_dai_link evb3_dai
[] = {
105 .name
= "88PM860x I2S",
106 .stream_name
= "I2S Audio",
107 .cpu_dai_name
= "pxa-ssp-dai.1",
108 .codec_dai_name
= "88pm860x-i2s",
109 .platform_name
= "pxa-pcm-audio",
110 .codec_name
= "88pm860x-codec",
111 .init
= evb3_pm860x_init
,
112 .dai_fmt
= SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
|
113 SND_SOC_DAIFMT_CBM_CFM
,
114 .ops
= &evb3_i2s_ops
,
118 static struct snd_soc_card snd_soc_card_evb3
= {
119 .name
= "Tavor EVB3",
120 .owner
= THIS_MODULE
,
121 .dai_link
= evb3_dai
,
122 .num_links
= ARRAY_SIZE(evb3_dai
),
124 .dapm_widgets
= evb3_dapm_widgets
,
125 .num_dapm_widgets
= ARRAY_SIZE(evb3_dapm_widgets
),
126 .dapm_routes
= evb3_audio_map
,
127 .num_dapm_routes
= ARRAY_SIZE(evb3_audio_map
),
130 static int evb3_pm860x_init(struct snd_soc_pcm_runtime
*rtd
)
132 struct snd_soc_codec
*codec
= rtd
->codec
;
133 struct snd_soc_dapm_context
*dapm
= &codec
->dapm
;
136 snd_soc_dapm_enable_pin(dapm
, "Ext Speaker");
137 snd_soc_dapm_enable_pin(dapm
, "Ext Mic 1");
138 snd_soc_dapm_enable_pin(dapm
, "Ext Mic 3");
139 snd_soc_dapm_disable_pin(dapm
, "Headset Mic 2");
140 snd_soc_dapm_disable_pin(dapm
, "Headset Stereophone");
142 /* Headset jack detection */
143 snd_soc_jack_new(codec
, "Headphone Jack", SND_JACK_HEADPHONE
144 | SND_JACK_BTN_0
| SND_JACK_BTN_1
| SND_JACK_BTN_2
,
146 snd_soc_jack_add_pins(&hs_jack
, ARRAY_SIZE(hs_jack_pins
),
148 snd_soc_jack_new(codec
, "Microphone Jack", SND_JACK_MICROPHONE
,
150 snd_soc_jack_add_pins(&mic_jack
, ARRAY_SIZE(mic_jack_pins
),
153 /* headphone, microphone detection & headset short detection */
154 pm860x_hs_jack_detect(codec
, &hs_jack
, SND_JACK_HEADPHONE
,
155 SND_JACK_BTN_0
, SND_JACK_BTN_1
, SND_JACK_BTN_2
);
156 pm860x_mic_jack_detect(codec
, &hs_jack
, SND_JACK_MICROPHONE
);
160 static int __init
tavorevb3_init(void)
164 if (!machine_is_tavorevb3())
166 evb3_snd_device
= platform_device_alloc("soc-audio", -1);
167 if (!evb3_snd_device
)
170 platform_set_drvdata(evb3_snd_device
, &snd_soc_card_evb3
);
172 ret
= platform_device_add(evb3_snd_device
);
174 platform_device_put(evb3_snd_device
);
179 static void __exit
tavorevb3_exit(void)
181 platform_device_unregister(evb3_snd_device
);
184 module_init(tavorevb3_init
);
185 module_exit(tavorevb3_exit
);
187 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
188 MODULE_DESCRIPTION("ALSA SoC 88PM860x Tavor EVB3");
189 MODULE_LICENSE("GPL");