1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2e0690385SOla Lilja /*
3e0690385SOla Lilja * Copyright (C) ST-Ericsson SA 2012
4e0690385SOla Lilja *
5e0690385SOla Lilja * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
6e0690385SOla Lilja * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>
7e0690385SOla Lilja * for ST-Ericsson.
8e0690385SOla Lilja */
9e0690385SOla Lilja
10e0690385SOla Lilja #include <linux/module.h>
11e0690385SOla Lilja #include <linux/device.h>
12e0690385SOla Lilja #include <linux/io.h>
13e0690385SOla Lilja #include <linux/clk.h>
14a130243bSFabio Baltieri #include <linux/mutex.h>
15e0690385SOla Lilja
16e0690385SOla Lilja #include <sound/soc.h>
17e0690385SOla Lilja #include <sound/soc-dapm.h>
18e0690385SOla Lilja #include <sound/pcm.h>
19e0690385SOla Lilja #include <sound/pcm_params.h>
20e0690385SOla Lilja
21e0690385SOla Lilja #include "ux500_pcm.h"
22e0690385SOla Lilja #include "ux500_msp_dai.h"
2306b9671eSFabio Baltieri #include "mop500_ab8500.h"
24e0690385SOla Lilja #include "../codecs/ab8500-codec.h"
25e0690385SOla Lilja
26e0690385SOla Lilja #define TX_SLOT_MONO 0x0008
27e0690385SOla Lilja #define TX_SLOT_STEREO 0x000a
28e0690385SOla Lilja #define RX_SLOT_MONO 0x0001
29e0690385SOla Lilja #define RX_SLOT_STEREO 0x0003
30e0690385SOla Lilja #define TX_SLOT_8CH 0x00FF
31e0690385SOla Lilja #define RX_SLOT_8CH 0x00FF
32e0690385SOla Lilja
33e0690385SOla Lilja #define DEF_TX_SLOTS TX_SLOT_STEREO
34e0690385SOla Lilja #define DEF_RX_SLOTS RX_SLOT_MONO
35e0690385SOla Lilja
36e0690385SOla Lilja #define DRIVERMODE_NORMAL 0
37e0690385SOla Lilja #define DRIVERMODE_CODEC_ONLY 1
38e0690385SOla Lilja
39e0690385SOla Lilja /* Slot configuration */
40e0690385SOla Lilja static unsigned int tx_slots = DEF_TX_SLOTS;
41e0690385SOla Lilja static unsigned int rx_slots = DEF_RX_SLOTS;
42e0690385SOla Lilja
43a130243bSFabio Baltieri /* Configuration consistency parameters */
44a130243bSFabio Baltieri static DEFINE_MUTEX(mop500_ab8500_params_lock);
45a130243bSFabio Baltieri static unsigned long mop500_ab8500_usage;
46a130243bSFabio Baltieri static int mop500_ab8500_rate;
47a130243bSFabio Baltieri static int mop500_ab8500_channels;
48a130243bSFabio Baltieri
49e0690385SOla Lilja /* Clocks */
50e0690385SOla Lilja static const char * const enum_mclk[] = {
51e0690385SOla Lilja "SYSCLK",
52e0690385SOla Lilja "ULPCLK"
53e0690385SOla Lilja };
54e0690385SOla Lilja enum mclk {
55e0690385SOla Lilja MCLK_SYSCLK,
56e0690385SOla Lilja MCLK_ULPCLK,
57e0690385SOla Lilja };
58e0690385SOla Lilja
59e0690385SOla Lilja static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk);
60e0690385SOla Lilja
61e0690385SOla Lilja /* Private data for machine-part MOP500<->AB8500 */
62e0690385SOla Lilja struct mop500_ab8500_drvdata {
63e0690385SOla Lilja /* Clocks */
64e0690385SOla Lilja enum mclk mclk_sel;
65e0690385SOla Lilja struct clk *clk_ptr_intclk;
66e0690385SOla Lilja struct clk *clk_ptr_sysclk;
67e0690385SOla Lilja struct clk *clk_ptr_ulpclk;
68e0690385SOla Lilja };
69e0690385SOla Lilja
get_mclk_str(enum mclk mclk_sel)70e0690385SOla Lilja static inline const char *get_mclk_str(enum mclk mclk_sel)
71e0690385SOla Lilja {
72e0690385SOla Lilja switch (mclk_sel) {
73e0690385SOla Lilja case MCLK_SYSCLK:
74e0690385SOla Lilja return "SYSCLK";
75e0690385SOla Lilja case MCLK_ULPCLK:
76e0690385SOla Lilja return "ULPCLK";
77e0690385SOla Lilja default:
78e0690385SOla Lilja return "Unknown";
79e0690385SOla Lilja }
80e0690385SOla Lilja }
81e0690385SOla Lilja
mop500_ab8500_set_mclk(struct device * dev,struct mop500_ab8500_drvdata * drvdata)82e0690385SOla Lilja static int mop500_ab8500_set_mclk(struct device *dev,
83e0690385SOla Lilja struct mop500_ab8500_drvdata *drvdata)
84e0690385SOla Lilja {
85e0690385SOla Lilja int status;
86e0690385SOla Lilja struct clk *clk_ptr;
87e0690385SOla Lilja
88e0690385SOla Lilja if (IS_ERR(drvdata->clk_ptr_intclk)) {
89e0690385SOla Lilja dev_err(dev,
90e0690385SOla Lilja "%s: ERROR: intclk not initialized!\n", __func__);
91e0690385SOla Lilja return -EIO;
92e0690385SOla Lilja }
93e0690385SOla Lilja
94e0690385SOla Lilja switch (drvdata->mclk_sel) {
95e0690385SOla Lilja case MCLK_SYSCLK:
96e0690385SOla Lilja clk_ptr = drvdata->clk_ptr_sysclk;
97e0690385SOla Lilja break;
98e0690385SOla Lilja case MCLK_ULPCLK:
99e0690385SOla Lilja clk_ptr = drvdata->clk_ptr_ulpclk;
100e0690385SOla Lilja break;
101e0690385SOla Lilja default:
102e0690385SOla Lilja return -EINVAL;
103e0690385SOla Lilja }
104e0690385SOla Lilja
105e0690385SOla Lilja if (IS_ERR(clk_ptr)) {
106e0690385SOla Lilja dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
107e0690385SOla Lilja get_mclk_str(drvdata->mclk_sel));
108e0690385SOla Lilja return -EIO;
109e0690385SOla Lilja }
110e0690385SOla Lilja
111e0690385SOla Lilja status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
112e0690385SOla Lilja if (status)
113e0690385SOla Lilja dev_err(dev,
114e0690385SOla Lilja "%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
115e0690385SOla Lilja __func__, get_mclk_str(drvdata->mclk_sel), status);
116e0690385SOla Lilja else
117e0690385SOla Lilja dev_dbg(dev,
118e0690385SOla Lilja "%s: intclk parent changed to %s.\n",
119e0690385SOla Lilja __func__, get_mclk_str(drvdata->mclk_sel));
120e0690385SOla Lilja
121e0690385SOla Lilja return status;
122e0690385SOla Lilja }
123e0690385SOla Lilja
124e0690385SOla Lilja /*
125e0690385SOla Lilja * Control-events
126e0690385SOla Lilja */
127e0690385SOla Lilja
mclk_input_control_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)128e0690385SOla Lilja static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
129e0690385SOla Lilja struct snd_ctl_elem_value *ucontrol)
130e0690385SOla Lilja {
131f656df65SFabio Baltieri struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
132e0690385SOla Lilja struct mop500_ab8500_drvdata *drvdata =
133f656df65SFabio Baltieri snd_soc_card_get_drvdata(card);
134e0690385SOla Lilja
135e0690385SOla Lilja ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
136e0690385SOla Lilja
137e0690385SOla Lilja return 0;
138e0690385SOla Lilja }
139e0690385SOla Lilja
mclk_input_control_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)140e0690385SOla Lilja static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
141e0690385SOla Lilja struct snd_ctl_elem_value *ucontrol)
142e0690385SOla Lilja {
143f656df65SFabio Baltieri struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
144e0690385SOla Lilja struct mop500_ab8500_drvdata *drvdata =
145f656df65SFabio Baltieri snd_soc_card_get_drvdata(card);
146e0690385SOla Lilja unsigned int val = ucontrol->value.enumerated.item[0];
147e0690385SOla Lilja
148e0690385SOla Lilja if (val > (unsigned int)MCLK_ULPCLK)
149e0690385SOla Lilja return -EINVAL;
150e0690385SOla Lilja if (drvdata->mclk_sel == val)
151e0690385SOla Lilja return 0;
152e0690385SOla Lilja
153e0690385SOla Lilja drvdata->mclk_sel = val;
154e0690385SOla Lilja
155e0690385SOla Lilja return 1;
156e0690385SOla Lilja }
157e0690385SOla Lilja
158e0690385SOla Lilja /*
159e0690385SOla Lilja * Controls
160e0690385SOla Lilja */
161e0690385SOla Lilja
162e0690385SOla Lilja static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
163e0690385SOla Lilja SOC_ENUM_EXT("Master Clock Select",
164e0690385SOla Lilja soc_enum_mclk,
165e0690385SOla Lilja mclk_input_control_get, mclk_input_control_put),
166e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Headset Left"),
167e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Headset Right"),
168e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Earpiece"),
169e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Speaker Left"),
170e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Speaker Right"),
171e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("LineOut Left"),
172e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("LineOut Right"),
173e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Vibra 1"),
174e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Vibra 2"),
175e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Mic 1"),
176e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("Mic 2"),
177e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("LineIn Left"),
178e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("LineIn Right"),
179e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 1"),
180e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 2"),
181e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 3"),
182e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 4"),
183e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 5"),
184e0690385SOla Lilja SOC_DAPM_PIN_SWITCH("DMic 6"),
185e0690385SOla Lilja };
186e0690385SOla Lilja
187e0690385SOla Lilja /* ASoC */
188e0690385SOla Lilja
mop500_ab8500_startup(struct snd_pcm_substream * substream)189cdeecac4SLars-Peter Clausen static int mop500_ab8500_startup(struct snd_pcm_substream *substream)
190e0690385SOla Lilja {
1913e44c479SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
192e0690385SOla Lilja
193e0690385SOla Lilja /* Set audio-clock source */
194e0690385SOla Lilja return mop500_ab8500_set_mclk(rtd->card->dev,
195e0690385SOla Lilja snd_soc_card_get_drvdata(rtd->card));
196e0690385SOla Lilja }
197e0690385SOla Lilja
mop500_ab8500_shutdown(struct snd_pcm_substream * substream)198cdeecac4SLars-Peter Clausen static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
199e0690385SOla Lilja {
2003e44c479SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
201e0690385SOla Lilja struct device *dev = rtd->card->dev;
202e0690385SOla Lilja
203e0690385SOla Lilja dev_dbg(dev, "%s: Enter\n", __func__);
204e0690385SOla Lilja
205e0690385SOla Lilja /* Reset slots configuration to default(s) */
206e0690385SOla Lilja if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
207e0690385SOla Lilja tx_slots = DEF_TX_SLOTS;
208e0690385SOla Lilja else
209e0690385SOla Lilja rx_slots = DEF_RX_SLOTS;
210e0690385SOla Lilja }
211e0690385SOla Lilja
mop500_ab8500_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)212cdeecac4SLars-Peter Clausen static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
213e0690385SOla Lilja struct snd_pcm_hw_params *params)
214e0690385SOla Lilja {
2153e44c479SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
21699396e38SKuninori Morimoto struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
21799396e38SKuninori Morimoto struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
218e0690385SOla Lilja struct device *dev = rtd->card->dev;
219e0690385SOla Lilja unsigned int fmt;
220e0690385SOla Lilja int channels, ret = 0, driver_mode, slots;
221e0690385SOla Lilja unsigned int sw_codec, sw_cpu;
222e0690385SOla Lilja bool is_playback;
223e0690385SOla Lilja
224e0690385SOla Lilja dev_dbg(dev, "%s: Enter\n", __func__);
225e0690385SOla Lilja
226e0690385SOla Lilja dev_dbg(dev, "%s: substream->pcm->name = %s\n"
227e0690385SOla Lilja "substream->pcm->id = %s.\n"
228e0690385SOla Lilja "substream->name = %s.\n"
229e0690385SOla Lilja "substream->number = %d.\n",
230e0690385SOla Lilja __func__,
231e0690385SOla Lilja substream->pcm->name,
232e0690385SOla Lilja substream->pcm->id,
233e0690385SOla Lilja substream->name,
234e0690385SOla Lilja substream->number);
235e0690385SOla Lilja
236a130243bSFabio Baltieri /* Ensure configuration consistency between DAIs */
237a130243bSFabio Baltieri mutex_lock(&mop500_ab8500_params_lock);
238a130243bSFabio Baltieri if (mop500_ab8500_usage) {
239a130243bSFabio Baltieri if (mop500_ab8500_rate != params_rate(params) ||
240a130243bSFabio Baltieri mop500_ab8500_channels != params_channels(params)) {
241a130243bSFabio Baltieri mutex_unlock(&mop500_ab8500_params_lock);
242a130243bSFabio Baltieri return -EBUSY;
243a130243bSFabio Baltieri }
244a130243bSFabio Baltieri } else {
245a130243bSFabio Baltieri mop500_ab8500_rate = params_rate(params);
246a130243bSFabio Baltieri mop500_ab8500_channels = params_channels(params);
247a130243bSFabio Baltieri }
248a130243bSFabio Baltieri __set_bit(cpu_dai->id, &mop500_ab8500_usage);
249a130243bSFabio Baltieri mutex_unlock(&mop500_ab8500_params_lock);
250a130243bSFabio Baltieri
251e0690385SOla Lilja channels = params_channels(params);
252e0690385SOla Lilja
253e0690385SOla Lilja switch (params_format(params)) {
254e0690385SOla Lilja case SNDRV_PCM_FORMAT_S32_LE:
255e0690385SOla Lilja sw_cpu = 32;
256e0690385SOla Lilja break;
257e0690385SOla Lilja
258e0690385SOla Lilja case SNDRV_PCM_FORMAT_S16_LE:
259e0690385SOla Lilja sw_cpu = 16;
260e0690385SOla Lilja break;
261e0690385SOla Lilja
262e0690385SOla Lilja default:
263e0690385SOla Lilja return -EINVAL;
264e0690385SOla Lilja }
265e0690385SOla Lilja
266e0690385SOla Lilja /* Setup codec depending on driver-mode */
267e0690385SOla Lilja if (channels == 8)
268e0690385SOla Lilja driver_mode = DRIVERMODE_CODEC_ONLY;
269e0690385SOla Lilja else
270e0690385SOla Lilja driver_mode = DRIVERMODE_NORMAL;
271e0690385SOla Lilja dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
272e0690385SOla Lilja (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
273e0690385SOla Lilja
274e0690385SOla Lilja /* Setup format */
275e0690385SOla Lilja
276e0690385SOla Lilja if (driver_mode == DRIVERMODE_NORMAL) {
277e0690385SOla Lilja fmt = SND_SOC_DAIFMT_DSP_A |
278e0690385SOla Lilja SND_SOC_DAIFMT_CBM_CFM |
279e0690385SOla Lilja SND_SOC_DAIFMT_NB_NF |
280e0690385SOla Lilja SND_SOC_DAIFMT_CONT;
281e0690385SOla Lilja } else {
282e0690385SOla Lilja fmt = SND_SOC_DAIFMT_DSP_A |
283e0690385SOla Lilja SND_SOC_DAIFMT_CBM_CFM |
284e0690385SOla Lilja SND_SOC_DAIFMT_NB_NF |
285e0690385SOla Lilja SND_SOC_DAIFMT_GATED;
286e0690385SOla Lilja }
287e0690385SOla Lilja
288c853679aSLars-Peter Clausen ret = snd_soc_runtime_set_dai_fmt(rtd, fmt);
289c853679aSLars-Peter Clausen if (ret)
290e0690385SOla Lilja return ret;
291e0690385SOla Lilja
292e0690385SOla Lilja /* Setup TDM-slots */
293e0690385SOla Lilja
294e0690385SOla Lilja is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
295e0690385SOla Lilja switch (channels) {
296e0690385SOla Lilja case 1:
297e0690385SOla Lilja slots = 16;
298e0690385SOla Lilja tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
299e0690385SOla Lilja rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
300e0690385SOla Lilja break;
301e0690385SOla Lilja case 2:
302e0690385SOla Lilja slots = 16;
303e0690385SOla Lilja tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
304e0690385SOla Lilja rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
305e0690385SOla Lilja break;
306e0690385SOla Lilja case 8:
307e0690385SOla Lilja slots = 16;
308e0690385SOla Lilja tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
309e0690385SOla Lilja rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
310e0690385SOla Lilja break;
311e0690385SOla Lilja default:
312e0690385SOla Lilja return -EINVAL;
313e0690385SOla Lilja }
314e0690385SOla Lilja
315e0690385SOla Lilja if (driver_mode == DRIVERMODE_NORMAL)
316e0690385SOla Lilja sw_codec = sw_cpu;
317e0690385SOla Lilja else
318e0690385SOla Lilja sw_codec = 20;
319e0690385SOla Lilja
320e0690385SOla Lilja dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
321e0690385SOla Lilja tx_slots, rx_slots);
322e0690385SOla Lilja ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
323e0690385SOla Lilja sw_cpu);
324e0690385SOla Lilja if (ret)
325e0690385SOla Lilja return ret;
326e0690385SOla Lilja
327e0690385SOla Lilja dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
328e0690385SOla Lilja tx_slots, rx_slots);
329e0690385SOla Lilja ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
330e0690385SOla Lilja sw_codec);
331e0690385SOla Lilja if (ret)
332e0690385SOla Lilja return ret;
333e0690385SOla Lilja
334e0690385SOla Lilja return 0;
335e0690385SOla Lilja }
336e0690385SOla Lilja
mop500_ab8500_hw_free(struct snd_pcm_substream * substream)337a130243bSFabio Baltieri static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream)
338a130243bSFabio Baltieri {
3393e44c479SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
34099396e38SKuninori Morimoto struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
341a130243bSFabio Baltieri
342a130243bSFabio Baltieri mutex_lock(&mop500_ab8500_params_lock);
343a130243bSFabio Baltieri __clear_bit(cpu_dai->id, &mop500_ab8500_usage);
344a130243bSFabio Baltieri mutex_unlock(&mop500_ab8500_params_lock);
345a130243bSFabio Baltieri
346a130243bSFabio Baltieri return 0;
347a130243bSFabio Baltieri }
348a130243bSFabio Baltieri
349*2831b719SRikard Falkeborn const struct snd_soc_ops mop500_ab8500_ops[] = {
350e0690385SOla Lilja {
351e0690385SOla Lilja .hw_params = mop500_ab8500_hw_params,
352a130243bSFabio Baltieri .hw_free = mop500_ab8500_hw_free,
353e0690385SOla Lilja .startup = mop500_ab8500_startup,
354e0690385SOla Lilja .shutdown = mop500_ab8500_shutdown,
355e0690385SOla Lilja }
356e0690385SOla Lilja };
357e0690385SOla Lilja
mop500_ab8500_machine_init(struct snd_soc_pcm_runtime * rtd)358e0690385SOla Lilja int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
359e0690385SOla Lilja {
3605cf57f0fSLars-Peter Clausen struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
361e0690385SOla Lilja struct device *dev = rtd->card->dev;
362e0690385SOla Lilja struct mop500_ab8500_drvdata *drvdata;
363e0690385SOla Lilja int ret;
364e0690385SOla Lilja
365e0690385SOla Lilja dev_dbg(dev, "%s Enter.\n", __func__);
366e0690385SOla Lilja
367e0690385SOla Lilja /* Create driver private-data struct */
368e0690385SOla Lilja drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata),
369e0690385SOla Lilja GFP_KERNEL);
37072f0095eSRajan Vaja
37172f0095eSRajan Vaja if (!drvdata)
37272f0095eSRajan Vaja return -ENOMEM;
37372f0095eSRajan Vaja
374e0690385SOla Lilja snd_soc_card_set_drvdata(rtd->card, drvdata);
375e0690385SOla Lilja
376e0690385SOla Lilja /* Setup clocks */
377e0690385SOla Lilja
378e0690385SOla Lilja drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk");
379e0690385SOla Lilja if (IS_ERR(drvdata->clk_ptr_sysclk))
380e0690385SOla Lilja dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n",
381e0690385SOla Lilja __func__);
382e0690385SOla Lilja drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk");
383e0690385SOla Lilja if (IS_ERR(drvdata->clk_ptr_ulpclk))
384e0690385SOla Lilja dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n",
385e0690385SOla Lilja __func__);
386e0690385SOla Lilja drvdata->clk_ptr_intclk = clk_get(dev, "intclk");
387e0690385SOla Lilja if (IS_ERR(drvdata->clk_ptr_intclk))
388e0690385SOla Lilja dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n",
389e0690385SOla Lilja __func__);
390e0690385SOla Lilja
391e0690385SOla Lilja /* Set intclk default parent to ulpclk */
392e0690385SOla Lilja drvdata->mclk_sel = MCLK_ULPCLK;
393e0690385SOla Lilja ret = mop500_ab8500_set_mclk(dev, drvdata);
394e0690385SOla Lilja if (ret < 0)
395e0690385SOla Lilja dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n",
396e0690385SOla Lilja __func__);
397e0690385SOla Lilja
398e0690385SOla Lilja drvdata->mclk_sel = MCLK_ULPCLK;
399e0690385SOla Lilja
400e0690385SOla Lilja /* Add controls */
40155bc8253SLars-Peter Clausen ret = snd_soc_add_card_controls(rtd->card, mop500_ab8500_ctrls,
402e0690385SOla Lilja ARRAY_SIZE(mop500_ab8500_ctrls));
403e0690385SOla Lilja if (ret < 0) {
404e0690385SOla Lilja pr_err("%s: Failed to add machine-controls (%d)!\n",
405e0690385SOla Lilja __func__, ret);
406e0690385SOla Lilja return ret;
407e0690385SOla Lilja }
408e0690385SOla Lilja
4095cf57f0fSLars-Peter Clausen ret = snd_soc_dapm_disable_pin(dapm, "Earpiece");
4105cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Left");
4115cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Speaker Right");
4125cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Left");
4135cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "LineOut Right");
4145cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 1");
4155cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Vibra 2");
4165cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Mic 1");
4175cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "Mic 2");
4185cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Left");
4195cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "LineIn Right");
4205cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 1");
4215cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 2");
4225cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 3");
4235cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 4");
4245cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 5");
4255cf57f0fSLars-Peter Clausen ret |= snd_soc_dapm_disable_pin(dapm, "DMic 6");
426e0690385SOla Lilja
427e0690385SOla Lilja return ret;
428e0690385SOla Lilja }
429e0690385SOla Lilja
mop500_ab8500_remove(struct snd_soc_card * card)430e0690385SOla Lilja void mop500_ab8500_remove(struct snd_soc_card *card)
431e0690385SOla Lilja {
432e0690385SOla Lilja struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card);
433e0690385SOla Lilja
434e0690385SOla Lilja clk_put(drvdata->clk_ptr_sysclk);
435e0690385SOla Lilja clk_put(drvdata->clk_ptr_ulpclk);
436e0690385SOla Lilja clk_put(drvdata->clk_ptr_intclk);
437e0690385SOla Lilja
438e0690385SOla Lilja snd_soc_card_set_drvdata(card, drvdata);
439e0690385SOla Lilja }
440