diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 22:52:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-03 22:52:22 -0400 |
commit | 1286da8bc009cb2aee7f285e94623fc974c0c983 (patch) | |
tree | 51ec0a79c3de63fa809b831ae0cbb5b85e44482f /sound/soc/ux500 | |
parent | 9e220385c4eb8b7e66174a60ea0e15b6b296f228 (diff) | |
parent | 1ba65ae4bdbd43265c51ee4c30ff21a48124b6d8 (diff) |
Merge tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"A relative calm release at this time with a flat diffstat. The only
significant change in the ALSA core side is the support for more than
32 card instances, configurable via kconfig. Other than that, in both
ASoC and other parts, mostly some improvements and fixes on the driver
side.
- hda: More quirks for ALC269-variants on Dell & co, VIA codec fixes
- hda: Haswell HDMI audio fixes, runtime PM improvements
- hda: Intel BayTrail support, ALC5505 DSP support
- es1968: MediaForte M56VAP support
- usb-audio: Improved support for Yamaha/Roland devices
- usb-audio: M2Tech hiFace, Audio Advantage Micro II support
- hdspm: wordclock fixes
- ASoC: Pending fixes for WM8962
- ASoC: Cleanups and fixes for Blackfin, SGTL5000 and UX500
- ASoC: Generalisation of the Bluetooth and HDMI stub drivers
- ASoC: SSM2518 and RT5640 codec drivers.
- ASoC: Tegra CPUs with RT5640 machine driver
- ASoC: AC'97 refactoring bug fixes
- ASoC: ADAU1701 driver fixes
- Clean up of *_set_drvdata() in a wide range of drivers"
* tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (284 commits)
ALSA: vmaster: Fix the regression of missing vmaster hook call
ALSA: hda - Add Dell SSID to support Headset Mic recording
ASoC: adau1701: remove control_data assignment
ASoC: adau1701: more direct regmap usage
ASoC: ac97: fixup multi-platform AC'97 module build failure
ASoC: pxa2xx: fixup multi-platform AC'97 build failures
ASoC: tegra20-ac97: Remove unused variable
ASoC: tegra20-ac97: Remove duplicate error message
ALSA: usb-audio: Add Audio Advantage Micro II
ASoC: tas5086: fix Mid-Z implementation
ASoC: tas5086: fix TAS5086_CLOCK_CONTROL register size
ALSA: Replace the magic number 44 with const
ALSA: hda - Fix the max length of control name in generic parser
ALSA: hda - Guess what, it's two more Dell headset mic quirks
ALSA: hda - Yet another Dell headset mic quirk
ALSA: hda - Add support for ALC5505 DSP power-save mode
ASoC: mfld: Remove unused variable
ALSA: usb-audio: add quirks for Roland QUAD/OCTO-CAPTURE
ALSA: usb-audio: claim autodetected PCM interfaces all at once
ALSA: usb-audio: remove superfluous Roland quirks
...
Diffstat (limited to 'sound/soc/ux500')
-rw-r--r-- | sound/soc/ux500/mop500.c | 2 | ||||
-rw-r--r-- | sound/soc/ux500/mop500_ab8500.c | 62 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.c | 11 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.h | 4 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.c | 88 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_msp_i2s.h | 74 | ||||
-rw-r--r-- | sound/soc/ux500/ux500_pcm.c | 30 |
7 files changed, 100 insertions, 171 deletions
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 204b899c2311..8f5cd00a6e46 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include "mop500_ab8500.h" | 27 | #include "mop500_ab8500.h" |
28 | 28 | ||
29 | /* Define the whole MOP500 soundcard, linking platform to the codec-drivers */ | 29 | /* Define the whole MOP500 soundcard, linking platform to the codec-drivers */ |
30 | struct snd_soc_dai_link mop500_dai_links[] = { | 30 | static struct snd_soc_dai_link mop500_dai_links[] = { |
31 | { | 31 | { |
32 | .name = "ab8500_0", | 32 | .name = "ab8500_0", |
33 | .stream_name = "ab8500_0", | 33 | .stream_name = "ab8500_0", |
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index 892ad9a05c9f..7e923ecf8901 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/mutex.h> | ||
19 | 20 | ||
20 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
21 | #include <sound/soc-dapm.h> | 22 | #include <sound/soc-dapm.h> |
@@ -24,6 +25,7 @@ | |||
24 | 25 | ||
25 | #include "ux500_pcm.h" | 26 | #include "ux500_pcm.h" |
26 | #include "ux500_msp_dai.h" | 27 | #include "ux500_msp_dai.h" |
28 | #include "mop500_ab8500.h" | ||
27 | #include "../codecs/ab8500-codec.h" | 29 | #include "../codecs/ab8500-codec.h" |
28 | 30 | ||
29 | #define TX_SLOT_MONO 0x0008 | 31 | #define TX_SLOT_MONO 0x0008 |
@@ -43,6 +45,12 @@ | |||
43 | static unsigned int tx_slots = DEF_TX_SLOTS; | 45 | static unsigned int tx_slots = DEF_TX_SLOTS; |
44 | static unsigned int rx_slots = DEF_RX_SLOTS; | 46 | static unsigned int rx_slots = DEF_RX_SLOTS; |
45 | 47 | ||
48 | /* Configuration consistency parameters */ | ||
49 | static DEFINE_MUTEX(mop500_ab8500_params_lock); | ||
50 | static unsigned long mop500_ab8500_usage; | ||
51 | static int mop500_ab8500_rate; | ||
52 | static int mop500_ab8500_channels; | ||
53 | |||
46 | /* Clocks */ | 54 | /* Clocks */ |
47 | static const char * const enum_mclk[] = { | 55 | static const char * const enum_mclk[] = { |
48 | "SYSCLK", | 56 | "SYSCLK", |
@@ -125,9 +133,9 @@ static int mop500_ab8500_set_mclk(struct device *dev, | |||
125 | static int mclk_input_control_get(struct snd_kcontrol *kcontrol, | 133 | static int mclk_input_control_get(struct snd_kcontrol *kcontrol, |
126 | struct snd_ctl_elem_value *ucontrol) | 134 | struct snd_ctl_elem_value *ucontrol) |
127 | { | 135 | { |
128 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 136 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
129 | struct mop500_ab8500_drvdata *drvdata = | 137 | struct mop500_ab8500_drvdata *drvdata = |
130 | snd_soc_card_get_drvdata(codec->card); | 138 | snd_soc_card_get_drvdata(card); |
131 | 139 | ||
132 | ucontrol->value.enumerated.item[0] = drvdata->mclk_sel; | 140 | ucontrol->value.enumerated.item[0] = drvdata->mclk_sel; |
133 | 141 | ||
@@ -137,9 +145,9 @@ static int mclk_input_control_get(struct snd_kcontrol *kcontrol, | |||
137 | static int mclk_input_control_put(struct snd_kcontrol *kcontrol, | 145 | static int mclk_input_control_put(struct snd_kcontrol *kcontrol, |
138 | struct snd_ctl_elem_value *ucontrol) | 146 | struct snd_ctl_elem_value *ucontrol) |
139 | { | 147 | { |
140 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 148 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
141 | struct mop500_ab8500_drvdata *drvdata = | 149 | struct mop500_ab8500_drvdata *drvdata = |
142 | snd_soc_card_get_drvdata(codec->card); | 150 | snd_soc_card_get_drvdata(card); |
143 | unsigned int val = ucontrol->value.enumerated.item[0]; | 151 | unsigned int val = ucontrol->value.enumerated.item[0]; |
144 | 152 | ||
145 | if (val > (unsigned int)MCLK_ULPCLK) | 153 | if (val > (unsigned int)MCLK_ULPCLK) |
@@ -160,16 +168,6 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = { | |||
160 | SOC_ENUM_EXT("Master Clock Select", | 168 | SOC_ENUM_EXT("Master Clock Select", |
161 | soc_enum_mclk, | 169 | soc_enum_mclk, |
162 | mclk_input_control_get, mclk_input_control_put), | 170 | mclk_input_control_get, mclk_input_control_put), |
163 | /* Digital interface - Clocks */ | ||
164 | SOC_SINGLE("Digital Interface Master Generator Switch", | ||
165 | AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN, | ||
166 | 1, 0), | ||
167 | SOC_SINGLE("Digital Interface 0 Bit-clock Switch", | ||
168 | AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0, | ||
169 | 1, 0), | ||
170 | SOC_SINGLE("Digital Interface 1 Bit-clock Switch", | ||
171 | AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1, | ||
172 | 1, 0), | ||
173 | SOC_DAPM_PIN_SWITCH("Headset Left"), | 171 | SOC_DAPM_PIN_SWITCH("Headset Left"), |
174 | SOC_DAPM_PIN_SWITCH("Headset Right"), | 172 | SOC_DAPM_PIN_SWITCH("Headset Right"), |
175 | SOC_DAPM_PIN_SWITCH("Earpiece"), | 173 | SOC_DAPM_PIN_SWITCH("Earpiece"), |
@@ -193,7 +191,7 @@ static struct snd_kcontrol_new mop500_ab8500_ctrls[] = { | |||
193 | 191 | ||
194 | /* ASoC */ | 192 | /* ASoC */ |
195 | 193 | ||
196 | int mop500_ab8500_startup(struct snd_pcm_substream *substream) | 194 | static int mop500_ab8500_startup(struct snd_pcm_substream *substream) |
197 | { | 195 | { |
198 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 196 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
199 | 197 | ||
@@ -202,7 +200,7 @@ int mop500_ab8500_startup(struct snd_pcm_substream *substream) | |||
202 | snd_soc_card_get_drvdata(rtd->card)); | 200 | snd_soc_card_get_drvdata(rtd->card)); |
203 | } | 201 | } |
204 | 202 | ||
205 | void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) | 203 | static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) |
206 | { | 204 | { |
207 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 205 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
208 | struct device *dev = rtd->card->dev; | 206 | struct device *dev = rtd->card->dev; |
@@ -216,7 +214,7 @@ void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) | |||
216 | rx_slots = DEF_RX_SLOTS; | 214 | rx_slots = DEF_RX_SLOTS; |
217 | } | 215 | } |
218 | 216 | ||
219 | int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, | 217 | static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, |
220 | struct snd_pcm_hw_params *params) | 218 | struct snd_pcm_hw_params *params) |
221 | { | 219 | { |
222 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 220 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -240,6 +238,21 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, | |||
240 | substream->name, | 238 | substream->name, |
241 | substream->number); | 239 | substream->number); |
242 | 240 | ||
241 | /* Ensure configuration consistency between DAIs */ | ||
242 | mutex_lock(&mop500_ab8500_params_lock); | ||
243 | if (mop500_ab8500_usage) { | ||
244 | if (mop500_ab8500_rate != params_rate(params) || | ||
245 | mop500_ab8500_channels != params_channels(params)) { | ||
246 | mutex_unlock(&mop500_ab8500_params_lock); | ||
247 | return -EBUSY; | ||
248 | } | ||
249 | } else { | ||
250 | mop500_ab8500_rate = params_rate(params); | ||
251 | mop500_ab8500_channels = params_channels(params); | ||
252 | } | ||
253 | __set_bit(cpu_dai->id, &mop500_ab8500_usage); | ||
254 | mutex_unlock(&mop500_ab8500_params_lock); | ||
255 | |||
243 | channels = params_channels(params); | 256 | channels = params_channels(params); |
244 | 257 | ||
245 | switch (params_format(params)) { | 258 | switch (params_format(params)) { |
@@ -338,9 +351,22 @@ int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, | |||
338 | return 0; | 351 | return 0; |
339 | } | 352 | } |
340 | 353 | ||
354 | static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream) | ||
355 | { | ||
356 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
357 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
358 | |||
359 | mutex_lock(&mop500_ab8500_params_lock); | ||
360 | __clear_bit(cpu_dai->id, &mop500_ab8500_usage); | ||
361 | mutex_unlock(&mop500_ab8500_params_lock); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
341 | struct snd_soc_ops mop500_ab8500_ops[] = { | 366 | struct snd_soc_ops mop500_ab8500_ops[] = { |
342 | { | 367 | { |
343 | .hw_params = mop500_ab8500_hw_params, | 368 | .hw_params = mop500_ab8500_hw_params, |
369 | .hw_free = mop500_ab8500_hw_free, | ||
344 | .startup = mop500_ab8500_startup, | 370 | .startup = mop500_ab8500_startup, |
345 | .shutdown = mop500_ab8500_shutdown, | 371 | .shutdown = mop500_ab8500_shutdown, |
346 | } | 372 | } |
@@ -385,7 +411,7 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) | |||
385 | drvdata->mclk_sel = MCLK_ULPCLK; | 411 | drvdata->mclk_sel = MCLK_ULPCLK; |
386 | 412 | ||
387 | /* Add controls */ | 413 | /* Add controls */ |
388 | ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls, | 414 | ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls, |
389 | ARRAY_SIZE(mop500_ab8500_ctrls)); | 415 | ARRAY_SIZE(mop500_ab8500_ctrls)); |
390 | if (ret < 0) { | 416 | if (ret < 0) { |
391 | pr_err("%s: Failed to add machine-controls (%d)!\n", | 417 | pr_err("%s: Failed to add machine-controls (%d)!\n", |
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 7d5fc1328523..c6fb5cce980e 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -658,14 +658,11 @@ static int ux500_msp_dai_probe(struct snd_soc_dai *dai) | |||
658 | { | 658 | { |
659 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); | 659 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); |
660 | 660 | ||
661 | drvdata->playback_dma_data.dma_cfg = drvdata->msp->dma_cfg_tx; | 661 | dai->playback_dma_data = &drvdata->msp->playback_dma_data; |
662 | drvdata->capture_dma_data.dma_cfg = drvdata->msp->dma_cfg_rx; | 662 | dai->capture_dma_data = &drvdata->msp->capture_dma_data; |
663 | 663 | ||
664 | dai->playback_dma_data = &drvdata->playback_dma_data; | 664 | drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; |
665 | dai->capture_dma_data = &drvdata->capture_dma_data; | 665 | drvdata->msp->capture_dma_data.data_size = drvdata->slot_width; |
666 | |||
667 | drvdata->playback_dma_data.data_size = drvdata->slot_width; | ||
668 | drvdata->capture_dma_data.data_size = drvdata->slot_width; | ||
669 | 666 | ||
670 | return 0; | 667 | return 0; |
671 | } | 668 | } |
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h index f53104359f15..312ae535e351 100644 --- a/sound/soc/ux500/ux500_msp_dai.h +++ b/sound/soc/ux500/ux500_msp_dai.h | |||
@@ -51,15 +51,11 @@ enum ux500_msp_clock_id { | |||
51 | struct ux500_msp_i2s_drvdata { | 51 | struct ux500_msp_i2s_drvdata { |
52 | struct ux500_msp *msp; | 52 | struct ux500_msp *msp; |
53 | struct regulator *reg_vape; | 53 | struct regulator *reg_vape; |
54 | struct ux500_msp_dma_params playback_dma_data; | ||
55 | struct ux500_msp_dma_params capture_dma_data; | ||
56 | unsigned int fmt; | 54 | unsigned int fmt; |
57 | unsigned int tx_mask; | 55 | unsigned int tx_mask; |
58 | unsigned int rx_mask; | 56 | unsigned int rx_mask; |
59 | int slots; | 57 | int slots; |
60 | int slot_width; | 58 | int slot_width; |
61 | u8 configured; | ||
62 | int data_delay; | ||
63 | 59 | ||
64 | /* Clocks */ | 60 | /* Clocks */ |
65 | unsigned int master_clk; | 61 | unsigned int master_clk; |
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index f2db6c90a9e2..1ca8b08ae993 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/pinctrl/consumer.h> | ||
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/io.h> | 20 | #include <linux/io.h> |
@@ -26,9 +25,6 @@ | |||
26 | 25 | ||
27 | #include "ux500_msp_i2s.h" | 26 | #include "ux500_msp_i2s.h" |
28 | 27 | ||
29 | /* MSP1/3 Tx/Rx usage protection */ | ||
30 | static DEFINE_SPINLOCK(msp_rxtx_lock); | ||
31 | |||
32 | /* Protocol desciptors */ | 28 | /* Protocol desciptors */ |
33 | static const struct msp_protdesc prot_descs[] = { | 29 | static const struct msp_protdesc prot_descs[] = { |
34 | { /* I2S */ | 30 | { /* I2S */ |
@@ -356,24 +352,8 @@ static int configure_multichannel(struct ux500_msp *msp, | |||
356 | 352 | ||
357 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) | 353 | static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) |
358 | { | 354 | { |
359 | int status = 0, retval = 0; | 355 | int status = 0; |
360 | u32 reg_val_DMACR, reg_val_GCR; | 356 | u32 reg_val_DMACR, reg_val_GCR; |
361 | unsigned long flags; | ||
362 | |||
363 | /* Check msp state whether in RUN or CONFIGURED Mode */ | ||
364 | if (msp->msp_state == MSP_STATE_IDLE) { | ||
365 | spin_lock_irqsave(&msp_rxtx_lock, flags); | ||
366 | if (msp->pinctrl_rxtx_ref == 0 && | ||
367 | !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) { | ||
368 | retval = pinctrl_select_state(msp->pinctrl_p, | ||
369 | msp->pinctrl_def); | ||
370 | if (retval) | ||
371 | pr_err("could not set MSP defstate\n"); | ||
372 | } | ||
373 | if (!retval) | ||
374 | msp->pinctrl_rxtx_ref++; | ||
375 | spin_unlock_irqrestore(&msp_rxtx_lock, flags); | ||
376 | } | ||
377 | 357 | ||
378 | /* Configure msp with protocol dependent settings */ | 358 | /* Configure msp with protocol dependent settings */ |
379 | configure_protocol(msp, config); | 359 | configure_protocol(msp, config); |
@@ -387,12 +367,14 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) | |||
387 | } | 367 | } |
388 | 368 | ||
389 | /* Make sure the correct DMA-directions are configured */ | 369 | /* Make sure the correct DMA-directions are configured */ |
390 | if ((config->direction & MSP_DIR_RX) && (!msp->dma_cfg_rx)) { | 370 | if ((config->direction & MSP_DIR_RX) && |
371 | !msp->capture_dma_data.dma_cfg) { | ||
391 | dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!", | 372 | dev_err(msp->dev, "%s: ERROR: MSP RX-mode is not configured!", |
392 | __func__); | 373 | __func__); |
393 | return -EINVAL; | 374 | return -EINVAL; |
394 | } | 375 | } |
395 | if ((config->direction == MSP_DIR_TX) && (!msp->dma_cfg_tx)) { | 376 | if ((config->direction == MSP_DIR_TX) && |
377 | !msp->playback_dma_data.dma_cfg) { | ||
396 | dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!", | 378 | dev_err(msp->dev, "%s: ERROR: MSP TX-mode is not configured!", |
397 | __func__); | 379 | __func__); |
398 | return -EINVAL; | 380 | return -EINVAL; |
@@ -630,8 +612,7 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction) | |||
630 | 612 | ||
631 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | 613 | int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) |
632 | { | 614 | { |
633 | int status = 0, retval = 0; | 615 | int status = 0; |
634 | unsigned long flags; | ||
635 | 616 | ||
636 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); | 617 | dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); |
637 | 618 | ||
@@ -643,18 +624,6 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) | |||
643 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), | 624 | (~(FRAME_GEN_ENABLE | SRG_ENABLE))), |
644 | msp->registers + MSP_GCR); | 625 | msp->registers + MSP_GCR); |
645 | 626 | ||
646 | spin_lock_irqsave(&msp_rxtx_lock, flags); | ||
647 | WARN_ON(!msp->pinctrl_rxtx_ref); | ||
648 | msp->pinctrl_rxtx_ref--; | ||
649 | if (msp->pinctrl_rxtx_ref == 0 && | ||
650 | !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) { | ||
651 | retval = pinctrl_select_state(msp->pinctrl_p, | ||
652 | msp->pinctrl_sleep); | ||
653 | if (retval) | ||
654 | pr_err("could not set MSP sleepstate\n"); | ||
655 | } | ||
656 | spin_unlock_irqrestore(&msp_rxtx_lock, flags); | ||
657 | |||
658 | writel(0, msp->registers + MSP_GCR); | 627 | writel(0, msp->registers + MSP_GCR); |
659 | writel(0, msp->registers + MSP_TCF); | 628 | writel(0, msp->registers + MSP_TCF); |
660 | writel(0, msp->registers + MSP_RCF); | 629 | writel(0, msp->registers + MSP_RCF); |
@@ -682,7 +651,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
682 | struct msp_i2s_platform_data *platform_data) | 651 | struct msp_i2s_platform_data *platform_data) |
683 | { | 652 | { |
684 | struct resource *res = NULL; | 653 | struct resource *res = NULL; |
685 | struct i2s_controller *i2s_cont; | ||
686 | struct device_node *np = pdev->dev.of_node; | 654 | struct device_node *np = pdev->dev.of_node; |
687 | struct ux500_msp *msp; | 655 | struct ux500_msp *msp; |
688 | 656 | ||
@@ -707,8 +675,8 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
707 | 675 | ||
708 | msp->id = platform_data->id; | 676 | msp->id = platform_data->id; |
709 | msp->dev = &pdev->dev; | 677 | msp->dev = &pdev->dev; |
710 | msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; | 678 | msp->playback_dma_data.dma_cfg = platform_data->msp_i2s_dma_tx; |
711 | msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; | 679 | msp->capture_dma_data.dma_cfg = platform_data->msp_i2s_dma_rx; |
712 | 680 | ||
713 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 681 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
714 | if (res == NULL) { | 682 | if (res == NULL) { |
@@ -717,6 +685,9 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
717 | return -ENOMEM; | 685 | return -ENOMEM; |
718 | } | 686 | } |
719 | 687 | ||
688 | msp->playback_dma_data.tx_rx_addr = res->start + MSP_DR; | ||
689 | msp->capture_dma_data.tx_rx_addr = res->start + MSP_DR; | ||
690 | |||
720 | msp->registers = devm_ioremap(&pdev->dev, res->start, | 691 | msp->registers = devm_ioremap(&pdev->dev, res->start, |
721 | resource_size(res)); | 692 | resource_size(res)); |
722 | if (msp->registers == NULL) { | 693 | if (msp->registers == NULL) { |
@@ -727,41 +698,6 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev, | |||
727 | msp->msp_state = MSP_STATE_IDLE; | 698 | msp->msp_state = MSP_STATE_IDLE; |
728 | msp->loopback_enable = 0; | 699 | msp->loopback_enable = 0; |
729 | 700 | ||
730 | /* I2S-controller is allocated and added in I2S controller class. */ | ||
731 | i2s_cont = devm_kzalloc(&pdev->dev, sizeof(*i2s_cont), GFP_KERNEL); | ||
732 | if (!i2s_cont) { | ||
733 | dev_err(&pdev->dev, | ||
734 | "%s: ERROR: Failed to allocate I2S-controller!\n", | ||
735 | __func__); | ||
736 | return -ENOMEM; | ||
737 | } | ||
738 | i2s_cont->dev.parent = &pdev->dev; | ||
739 | i2s_cont->data = (void *)msp; | ||
740 | i2s_cont->id = (s16)msp->id; | ||
741 | snprintf(i2s_cont->name, sizeof(i2s_cont->name), "ux500-msp-i2s.%04x", | ||
742 | msp->id); | ||
743 | dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); | ||
744 | msp->i2s_cont = i2s_cont; | ||
745 | |||
746 | msp->pinctrl_p = pinctrl_get(msp->dev); | ||
747 | if (IS_ERR(msp->pinctrl_p)) | ||
748 | dev_err(&pdev->dev, "could not get MSP pinctrl\n"); | ||
749 | else { | ||
750 | msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p, | ||
751 | PINCTRL_STATE_DEFAULT); | ||
752 | if (IS_ERR(msp->pinctrl_def)) { | ||
753 | dev_err(&pdev->dev, | ||
754 | "could not get MSP defstate (%li)\n", | ||
755 | PTR_ERR(msp->pinctrl_def)); | ||
756 | } | ||
757 | msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p, | ||
758 | PINCTRL_STATE_SLEEP); | ||
759 | if (IS_ERR(msp->pinctrl_sleep)) | ||
760 | dev_err(&pdev->dev, | ||
761 | "could not get MSP idlestate (%li)\n", | ||
762 | PTR_ERR(msp->pinctrl_def)); | ||
763 | } | ||
764 | |||
765 | return 0; | 701 | return 0; |
766 | } | 702 | } |
767 | 703 | ||
@@ -769,8 +705,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, | |||
769 | struct ux500_msp *msp) | 705 | struct ux500_msp *msp) |
770 | { | 706 | { |
771 | dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); | 707 | dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); |
772 | |||
773 | device_unregister(&msp->i2s_cont->dev); | ||
774 | } | 708 | } |
775 | 709 | ||
776 | MODULE_LICENSE("GPL v2"); | 710 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index e5cd105c90f9..258d0bcee0bd 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define UX500_MSP_I2S_H | 16 | #define UX500_MSP_I2S_H |
17 | 17 | ||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/platform_data/asoc-ux500-msp.h> | ||
19 | 20 | ||
20 | #define MSP_INPUT_FREQ_APB 48000000 | 21 | #define MSP_INPUT_FREQ_APB 48000000 |
21 | 22 | ||
@@ -341,11 +342,6 @@ enum msp_compress_mode { | |||
341 | MSP_COMPRESS_MODE_A_LAW = 3 | 342 | MSP_COMPRESS_MODE_A_LAW = 3 |
342 | }; | 343 | }; |
343 | 344 | ||
344 | enum msp_spi_burst_mode { | ||
345 | MSP_SPI_BURST_MODE_DISABLE = 0, | ||
346 | MSP_SPI_BURST_MODE_ENABLE = 1 | ||
347 | }; | ||
348 | |||
349 | enum msp_expand_mode { | 345 | enum msp_expand_mode { |
350 | MSP_EXPAND_MODE_LINEAR = 0, | 346 | MSP_EXPAND_MODE_LINEAR = 0, |
351 | MSP_EXPAND_MODE_LINEAR_SIGNED = 1, | 347 | MSP_EXPAND_MODE_LINEAR_SIGNED = 1, |
@@ -370,13 +366,6 @@ enum msp_protocol { | |||
370 | */ | 366 | */ |
371 | #define MAX_MSP_BACKUP_REGS 36 | 367 | #define MAX_MSP_BACKUP_REGS 36 |
372 | 368 | ||
373 | enum enum_i2s_controller { | ||
374 | MSP_0_I2S_CONTROLLER = 0, | ||
375 | MSP_1_I2S_CONTROLLER, | ||
376 | MSP_2_I2S_CONTROLLER, | ||
377 | MSP_3_I2S_CONTROLLER, | ||
378 | }; | ||
379 | |||
380 | enum i2s_direction_t { | 369 | enum i2s_direction_t { |
381 | MSP_DIR_TX = 0x01, | 370 | MSP_DIR_TX = 0x01, |
382 | MSP_DIR_RX = 0x02, | 371 | MSP_DIR_RX = 0x02, |
@@ -454,32 +443,6 @@ struct msp_protdesc { | |||
454 | u32 clocks_per_frame; | 443 | u32 clocks_per_frame; |
455 | }; | 444 | }; |
456 | 445 | ||
457 | struct i2s_message { | ||
458 | enum i2s_direction_t i2s_direction; | ||
459 | void *txdata; | ||
460 | void *rxdata; | ||
461 | size_t txbytes; | ||
462 | size_t rxbytes; | ||
463 | int dma_flag; | ||
464 | int tx_offset; | ||
465 | int rx_offset; | ||
466 | bool cyclic_dma; | ||
467 | dma_addr_t buf_addr; | ||
468 | size_t buf_len; | ||
469 | size_t period_len; | ||
470 | }; | ||
471 | |||
472 | struct i2s_controller { | ||
473 | struct module *owner; | ||
474 | unsigned int id; | ||
475 | unsigned int class; | ||
476 | const struct i2s_algorithm *algo; /* the algorithm to access the bus */ | ||
477 | void *data; | ||
478 | struct mutex bus_lock; | ||
479 | struct device dev; /* the controller device */ | ||
480 | char name[48]; | ||
481 | }; | ||
482 | |||
483 | struct ux500_msp_config { | 446 | struct ux500_msp_config { |
484 | unsigned int f_inputclk; | 447 | unsigned int f_inputclk; |
485 | unsigned int rx_clk_sel; | 448 | unsigned int rx_clk_sel; |
@@ -491,8 +454,6 @@ struct ux500_msp_config { | |||
491 | unsigned int tx_fsync_sel; | 454 | unsigned int tx_fsync_sel; |
492 | unsigned int rx_fifo_config; | 455 | unsigned int rx_fifo_config; |
493 | unsigned int tx_fifo_config; | 456 | unsigned int tx_fifo_config; |
494 | unsigned int spi_clk_mode; | ||
495 | unsigned int spi_burst_mode; | ||
496 | unsigned int loopback_enable; | 457 | unsigned int loopback_enable; |
497 | unsigned int tx_data_enable; | 458 | unsigned int tx_data_enable; |
498 | unsigned int default_protdesc; | 459 | unsigned int default_protdesc; |
@@ -502,43 +463,28 @@ struct ux500_msp_config { | |||
502 | unsigned int direction; | 463 | unsigned int direction; |
503 | unsigned int protocol; | 464 | unsigned int protocol; |
504 | unsigned int frame_freq; | 465 | unsigned int frame_freq; |
505 | unsigned int frame_size; | ||
506 | enum msp_data_size data_size; | 466 | enum msp_data_size data_size; |
507 | unsigned int def_elem_len; | 467 | unsigned int def_elem_len; |
508 | unsigned int iodelay; | 468 | unsigned int iodelay; |
509 | void (*handler) (void *data); | 469 | }; |
510 | void *tx_callback_data; | 470 | |
511 | void *rx_callback_data; | 471 | struct ux500_msp_dma_params { |
472 | unsigned int data_size; | ||
473 | dma_addr_t tx_rx_addr; | ||
474 | struct stedma40_chan_cfg *dma_cfg; | ||
512 | }; | 475 | }; |
513 | 476 | ||
514 | struct ux500_msp { | 477 | struct ux500_msp { |
515 | enum enum_i2s_controller id; | 478 | enum msp_i2s_id id; |
516 | void __iomem *registers; | 479 | void __iomem *registers; |
517 | struct device *dev; | 480 | struct device *dev; |
518 | struct i2s_controller *i2s_cont; | 481 | struct ux500_msp_dma_params playback_dma_data; |
519 | struct stedma40_chan_cfg *dma_cfg_rx; | 482 | struct ux500_msp_dma_params capture_dma_data; |
520 | struct stedma40_chan_cfg *dma_cfg_tx; | ||
521 | struct dma_chan *tx_pipeid; | ||
522 | struct dma_chan *rx_pipeid; | ||
523 | enum msp_state msp_state; | 483 | enum msp_state msp_state; |
524 | int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); | ||
525 | struct timer_list notify_timer; | ||
526 | int def_elem_len; | 484 | int def_elem_len; |
527 | unsigned int dir_busy; | 485 | unsigned int dir_busy; |
528 | int loopback_enable; | 486 | int loopback_enable; |
529 | u32 backup_regs[MAX_MSP_BACKUP_REGS]; | ||
530 | unsigned int f_bitclk; | 487 | unsigned int f_bitclk; |
531 | /* Pin modes */ | ||
532 | struct pinctrl *pinctrl_p; | ||
533 | struct pinctrl_state *pinctrl_def; | ||
534 | struct pinctrl_state *pinctrl_sleep; | ||
535 | /* Reference Count */ | ||
536 | int pinctrl_rxtx_ref; | ||
537 | }; | ||
538 | |||
539 | struct ux500_msp_dma_params { | ||
540 | unsigned int data_size; | ||
541 | struct stedma40_chan_cfg *dma_cfg; | ||
542 | }; | 488 | }; |
543 | 489 | ||
544 | struct msp_i2s_platform_data; | 490 | struct msp_i2s_platform_data; |
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index 31f9bbc74521..ce554de5d9dc 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -103,10 +103,40 @@ static struct dma_chan *ux500_pcm_request_chan(struct snd_soc_pcm_runtime *rtd, | |||
103 | return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg); | 103 | return snd_dmaengine_pcm_request_channel(stedma40_filter, dma_cfg); |
104 | } | 104 | } |
105 | 105 | ||
106 | static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream, | ||
107 | struct snd_pcm_hw_params *params, | ||
108 | struct dma_slave_config *slave_config) | ||
109 | { | ||
110 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
111 | struct ux500_msp_dma_params *dma_params; | ||
112 | struct stedma40_chan_cfg *dma_cfg; | ||
113 | int ret; | ||
114 | |||
115 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
116 | dma_cfg = dma_params->dma_cfg; | ||
117 | |||
118 | ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config); | ||
119 | if (ret) | ||
120 | return ret; | ||
121 | |||
122 | slave_config->dst_maxburst = 4; | ||
123 | slave_config->dst_addr_width = dma_cfg->dst_info.data_width; | ||
124 | slave_config->src_maxburst = 4; | ||
125 | slave_config->src_addr_width = dma_cfg->src_info.data_width; | ||
126 | |||
127 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
128 | slave_config->dst_addr = dma_params->tx_rx_addr; | ||
129 | else | ||
130 | slave_config->src_addr = dma_params->tx_rx_addr; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
106 | static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { | 135 | static const struct snd_dmaengine_pcm_config ux500_dmaengine_pcm_config = { |
107 | .pcm_hardware = &ux500_pcm_hw, | 136 | .pcm_hardware = &ux500_pcm_hw, |
108 | .compat_request_channel = ux500_pcm_request_chan, | 137 | .compat_request_channel = ux500_pcm_request_chan, |
109 | .prealloc_buffer_size = 128 * 1024, | 138 | .prealloc_buffer_size = 128 * 1024, |
139 | .prepare_slave_config = ux500_pcm_prepare_slave_config, | ||
110 | }; | 140 | }; |
111 | 141 | ||
112 | int ux500_pcm_register_platform(struct platform_device *pdev) | 142 | int ux500_pcm_register_platform(struct platform_device *pdev) |