2 * saarb.c -- SoC audio for saarb
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 saarb_pm860x_init(struct snd_soc_pcm_runtime
*rtd
);
30 static struct platform_device
*saarb_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 /* saarb machine dapm widgets */
43 static const struct snd_soc_dapm_widget saarb_dapm_widgets
[] = {
44 SND_SOC_DAPM_HP("Headphone 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", NULL
),
50 SND_SOC_DAPM_MIC("Ext Mic 3", NULL
),
53 /* saarb machine audio map */
54 static const struct snd_soc_dapm_route saarb_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 saarb_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
);
100 static struct snd_soc_ops saarb_i2s_ops
= {
101 .hw_params
= saarb_i2s_hw_params
,
104 static struct snd_soc_dai_link saarb_dai
[] = {
106 .name
= "88PM860x I2S",
107 .stream_name
= "I2S Audio",
108 .cpu_dai_name
= "pxa-ssp-dai.1",
109 .codec_dai_name
= "88pm860x-i2s",
110 .platform_name
= "pxa-pcm-audio",
111 .codec_name
= "88pm860x-codec",
112 .init
= saarb_pm860x_init
,
113 .dai_fmt
= SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
|
114 SND_SOC_DAIFMT_CBM_CFM
,
115 .ops
= &saarb_i2s_ops
,
119 static struct snd_soc_card snd_soc_card_saarb
= {
121 .owner
= THIS_MODULE
,
122 .dai_link
= saarb_dai
,
123 .num_links
= ARRAY_SIZE(saarb_dai
),
125 .dapm_widgets
= saarb_dapm_widgets
,
126 .num_dapm_widgets
= ARRAY_SIZE(saarb_dapm_widgets
),
127 .dapm_routes
= saarb_audio_map
,
128 .num_dapm_routes
= ARRAY_SIZE(saarb_audio_map
),
131 static int saarb_pm860x_init(struct snd_soc_pcm_runtime
*rtd
)
133 struct snd_soc_codec
*codec
= rtd
->codec
;
134 struct snd_soc_dapm_context
*dapm
= &codec
->dapm
;
137 snd_soc_dapm_enable_pin(dapm
, "Ext Speaker");
138 snd_soc_dapm_enable_pin(dapm
, "Ext Mic 1");
139 snd_soc_dapm_enable_pin(dapm
, "Ext Mic 3");
140 snd_soc_dapm_disable_pin(dapm
, "Headset Mic 2");
141 snd_soc_dapm_disable_pin(dapm
, "Headset Stereophone");
143 /* Headset jack detection */
144 snd_soc_jack_new(codec
, "Headphone Jack", SND_JACK_HEADPHONE
145 | SND_JACK_BTN_0
| SND_JACK_BTN_1
| SND_JACK_BTN_2
,
147 snd_soc_jack_add_pins(&hs_jack
, ARRAY_SIZE(hs_jack_pins
),
149 snd_soc_jack_new(codec
, "Microphone Jack", SND_JACK_MICROPHONE
,
151 snd_soc_jack_add_pins(&mic_jack
, ARRAY_SIZE(mic_jack_pins
),
154 /* headphone, microphone detection & headset short detection */
155 pm860x_hs_jack_detect(codec
, &hs_jack
, SND_JACK_HEADPHONE
,
156 SND_JACK_BTN_0
, SND_JACK_BTN_1
, SND_JACK_BTN_2
);
157 pm860x_mic_jack_detect(codec
, &hs_jack
, SND_JACK_MICROPHONE
);
161 static int __init
saarb_init(void)
165 if (!machine_is_saarb())
167 saarb_snd_device
= platform_device_alloc("soc-audio", -1);
168 if (!saarb_snd_device
)
171 platform_set_drvdata(saarb_snd_device
, &snd_soc_card_saarb
);
173 ret
= platform_device_add(saarb_snd_device
);
175 platform_device_put(saarb_snd_device
);
180 static void __exit
saarb_exit(void)
182 platform_device_unregister(saarb_snd_device
);
185 module_init(saarb_init
);
186 module_exit(saarb_exit
);
188 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
189 MODULE_DESCRIPTION("ALSA SoC 88PM860x Saarb");
190 MODULE_LICENSE("GPL");