tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / sound / soc / sprd / vbc-r2p0-sprd-codec-v3.h
1 /*
2  * sound/soc/sprd/vbc-r2p0-sprd-codec-v3.h
3  *
4  * Copyright (C) 2013 SpreadTrum Ltd.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15
16 static const struct snd_kcontrol_new vbc_r2p0_codec_v3_controls[] = {
17         BOARD_CODEC_FUNC("Speaker Function", BOARD_FUNC_SPKL),
18         BOARD_CODEC_FUNC("Speaker2 Function", BOARD_FUNC_SPKR),
19         BOARD_CODEC_FUNC("Earpiece Function", BOARD_FUNC_EAR),
20         BOARD_CODEC_FUNC("HeadPhone Function", BOARD_FUNC_HP),
21         BOARD_CODEC_FUNC("Line Function", BOARD_FUNC_LINE),
22         BOARD_CODEC_FUNC("Mic Function", BOARD_FUNC_MIC),
23         BOARD_CODEC_FUNC("Aux Mic Function", BOARD_FUNC_AUXMIC),
24         BOARD_CODEC_FUNC("HP Mic Function", BOARD_FUNC_HP_MIC),
25         BOARD_CODEC_FUNC("DMic Function", BOARD_FUNC_DMIC),
26         BOARD_CODEC_FUNC("DMic1 Function", BOARD_FUNC_DMIC1),
27         BOARD_CODEC_FUNC("Digital FM Function", BOARD_FUNC_DFM),
28
29         BOARD_CODEC_MUTE("Speaker Mute", BOARD_FUNC_SPKL),
30         BOARD_CODEC_MUTE("Speaker2 Mute", BOARD_FUNC_SPKR),
31         BOARD_CODEC_MUTE("Earpiece Mute", BOARD_FUNC_EAR),
32         BOARD_CODEC_MUTE("HeadPhone Mute", BOARD_FUNC_HP),
33 };
34
35 /* board supported audio map */
36 static const struct snd_soc_dapm_route vbc_r2p0_codec_v3_map[] = {
37         {"HeadPhone Jack", NULL, "HEAD_P_L"},
38         {"HeadPhone Jack", NULL, "HEAD_P_R"},
39         {"Ext Spk", NULL, "AOL"},
40         {"Ext Spk2", NULL, "AOR"},
41         {"Ext Ear", NULL, "EAR"},
42         {"MIC", NULL, "Mic Jack"},
43         {"AUXMIC", NULL, "Aux Mic Jack"},
44         {"HPMIC", NULL, "HP Mic Jack"},
45         {"AIL", NULL, "Line Jack"},
46         {"AIR", NULL, "Line Jack"},
47         {"DMIC", NULL, "DMic Jack"},
48         {"DMIC1", NULL, "DMic1 Jack"},
49
50         {"inter HP PA", NULL, "HP PA"},
51         {"inter Spk PA", NULL, "Spk PA"},
52
53         /* VBC -- SPRD-CODEC */
54         {"Aud input", NULL, "AD Clk"},
55         {"Aud1 input", NULL, "AD Clk"},
56
57         {"Aud input", NULL, "Digital ADCL Switch"},
58         {"Aud input", NULL, "Digital ADCR Switch"},
59
60         {"Aud1 input", NULL, "Digital ADC1L Switch"},
61         {"Aud1 input", NULL, "Digital ADC1R Switch"},
62
63 };
64
65 extern struct sprd_dfm_priv dfm;
66 static int dfm_rate(struct snd_pcm_hw_params *params)
67 {
68 #ifdef CONFIG_SND_SOC_VBC_SRC_SAMPLE_RATE
69        dfm.hw_rate = CONFIG_SND_SOC_VBC_SRC_SAMPLE_RATE;
70 #else
71        dfm.hw_rate = params_rate(params);
72 #endif
73
74         if (dfm.hw_rate == 8000)
75                 dfm.sample_rate = 8000;
76         else {
77 #ifdef CONFIG_SND_SOC_SPRD_VBC_SRC_OPEN
78                 dfm.sample_rate = 44100;
79 #else
80                 dfm.sample_rate = params_rate(params);
81 #endif
82         }
83         sp_asoc_pr_dbg("%s: hw_rate:%d,  sample_rate:%d \n",
84                        __func__, dfm.hw_rate, dfm.sample_rate);
85
86         if (dfm.hw_rate != dfm.sample_rate) {
87                 struct snd_interval *rate =
88                     hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
89                 struct snd_interval dfm_rates;
90                 dfm_rates.min = dfm.sample_rate;
91                 dfm_rates.max = dfm.sample_rate;
92                 dfm_rates.openmin = dfm_rates.openmax = 0;
93                 dfm_rates.integer = 0;
94
95                 return snd_interval_refine(rate, &dfm_rates);
96         }
97         return 0;
98 }
99
100 static int dfm_params(struct snd_pcm_substream *substream,
101                       struct snd_pcm_hw_params *params)
102 {
103
104         sp_asoc_pr_dbg("%s \n", __func__);
105         dfm_rate(params);
106         return 0;
107 }
108
109 static const struct snd_soc_ops dfm_ops = {
110         .hw_params = dfm_params,
111 };
112
113 static struct snd_soc_dai_link vbc_r2p0_codec_v3_dai[] = {
114         {
115          .name = "vbc(r2)-codec(v3)-ap",
116          .stream_name = "HiFi",
117
118          .codec_name = "sprd-codec-v3",
119          .platform_name = "sprd-pcm-audio",
120          .cpu_dai_name = "vbc-r2p0",
121          .codec_dai_name = "sprd-codec-v3-i2s",
122          },
123 #ifdef CONFIG_SND_SOC_SPRD_VAUDIO
124         {
125          .name = "vbc(r2)-codec(v3)-dsp",
126          .stream_name = "Voice",
127
128          .codec_name = "sprd-codec-v3",
129          .platform_name = "sprd-pcm-audio",
130          .cpu_dai_name = "vaudio",
131          .codec_dai_name = "sprd-codec-v3-vaudio",
132          },
133 #endif
134         {
135          .name = "aux-captrue",
136          .stream_name = "AuxRecord",
137
138          .codec_name = "sprd-codec-v3",
139          .platform_name = "sprd-pcm-audio",
140          .cpu_dai_name = "vbc-r2p0-ad23",
141          .codec_dai_name = "codec-i2s-ext",
142          },
143 #ifdef CONFIG_SND_SOC_SPRD_VAUDIO
144         {
145          .name = "aux-dsp-captrue",
146          .stream_name = "AuxDSPCaptrue",
147
148          .codec_name = "sprd-codec-v3",
149          .platform_name = "sprd-pcm-audio",
150          .cpu_dai_name = "vaudio-ad23",
151          .codec_dai_name = "codec-vaudio-ext",
152          },
153 #endif
154         {
155          .name = "vbc(r2)-dfm",
156          .stream_name = "Dfm",
157
158          .codec_name = "sprd-codec-v3",
159          .platform_name = "sprd-pcm-audio",
160          .cpu_dai_name = "vbc-dfm",
161          .codec_dai_name = "sprd-codec-v3-fm",
162          .ops = &dfm_ops,
163          },
164 };
165
166 static struct snd_soc_card vbc_r2p0_codec_v3_card = {
167         .name = "sprdphone",
168         .dai_link = vbc_r2p0_codec_v3_dai,
169         .num_links = ARRAY_SIZE(vbc_r2p0_codec_v3_dai),
170         .owner = THIS_MODULE,
171
172         .controls = vbc_r2p0_codec_v3_controls,
173         .num_controls = ARRAY_SIZE(vbc_r2p0_codec_v3_controls),
174         .dapm_widgets = sprd_codec_dapm_widgets,
175         .num_dapm_widgets = ARRAY_SIZE(sprd_codec_dapm_widgets),
176         .dapm_routes = vbc_r2p0_codec_v3_map,
177         .num_dapm_routes = ARRAY_SIZE(vbc_r2p0_codec_v3_map),
178         .late_probe = board_late_probe,
179 };
180
181 static int vbc_r2p0_codec_v3_probe(struct platform_device *pdev)
182 {
183         return sprd_asoc_probe(pdev, &vbc_r2p0_codec_v3_card);
184 }
185
186 #ifdef CONFIG_OF
187 static const struct of_device_id vbc_r2p0_codec_v3_of_match[] = {
188         {.compatible = "sprd,vbc-r2p0-sprd-codec-v3",},
189         {},
190 };
191
192 MODULE_DEVICE_TABLE(of, vbc_r2p0_codec_v3_of_match);
193 #endif
194
195 static struct platform_driver vbc_r2p0_codec_v3_driver = {
196         .driver = {
197                    .name = "vbc-r2p0-sprd-codec-v3",
198                    .owner = THIS_MODULE,
199                    .pm = &snd_soc_pm_ops,
200                    .of_match_table = of_match_ptr(vbc_r2p0_codec_v3_of_match),
201                    },
202         .probe = vbc_r2p0_codec_v3_probe,
203         .remove = sprd_asoc_remove,
204         .shutdown = sprd_asoc_shutdown,
205 };
206
207 module_platform_driver(vbc_r2p0_codec_v3_driver);