[PATCH] ASoC: sti: sti_uniperif: Remove driver
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com --- I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
.../bindings/sound/st,sti-asoc-card.txt | 164 -- MAINTAINERS | 7 - sound/soc/sti/Kconfig | 12 - sound/soc/sti/Makefile | 5 - sound/soc/sti/sti_uniperif.c | 506 ------ sound/soc/sti/uniperif.h | 1416 ----------------- sound/soc/sti/uniperif_player.c | 1148 ------------- sound/soc/sti/uniperif_reader.c | 436 ----- 8 files changed, 3694 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt delete mode 100644 sound/soc/sti/Kconfig delete mode 100644 sound/soc/sti/Makefile delete mode 100644 sound/soc/sti/sti_uniperif.c delete mode 100644 sound/soc/sti/uniperif.h delete mode 100644 sound/soc/sti/uniperif_player.c delete mode 100644 sound/soc/sti/uniperif_reader.c
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt deleted file mode 100644 index a6ffcdec6f6a..000000000000 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ /dev/null @@ -1,164 +0,0 @@ -STMicroelectronics sti ASoC cards - -The sti ASoC Sound Card can be used, for all sti SoCs using internal sti-sas -codec or external codecs. - -sti sound drivers allows to expose sti SoC audio interface through the -generic ASoC simple card. For details about sound card declaration please refer to -Documentation/devicetree/bindings/sound/simple-card.yaml. - -1) sti-uniperiph-dai: audio dai device. ---------------------------------------- - -Required properties: - - compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out", - "st,stih407-uni-player-dac", "st,stih407-uni-player-spdif", - "st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi", - - - st,syscfg: phandle to boot-device system configuration registers - - - clock-names: name of the clocks listed in clocks property in the same order - - - reg: CPU DAI IP Base address and size entries, listed in same - order than the CPU_DAI properties. - - - reg-names: names of the mapped memory regions listed in regs property in - the same order. - - - interrupts: CPU_DAI interrupt line, listed in the same order than the - CPU_DAI properties. - - - dma: CPU_DAI DMA controller phandle and DMA request line, listed in the same - order than the CPU_DAI properties. - - - dma-names: identifier string for each DMA request line in the dmas property. - "tx" for "st,sti-uni-player" compatibility - "rx" for "st,sti-uni-reader" compatibility - -Required properties ("st,sti-uni-player" compatibility only): - - clocks: CPU_DAI IP clock source, listed in the same order than the - CPU_DAI properties. - -Optional properties: - - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for - external codecs connection. - - - pinctrl-names: should contain only one value - "default". - - - st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs. - Only compartible with IPs in charge of the external I2S/TDM bus. - Should be declared depending on associated codec. - -Example: - - sti_uni_player1: sti-uni-player@8d81000 { - compatible = "st,stih407-uni-player-hdmi"; - #sound-dai-cells = <0>; - st,syscfg = <&syscfg_core>; - clocks = <&clk_s_d0_flexgen CLK_PCM_1>; - reg = <0x8D81000 0x158>; - interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>; - dmas = <&fdma0 3 0 1>; - dma-names = "tx"; - st,tdm-mode = <1>; - }; - - sti_uni_player2: sti-uni-player@8d82000 { - compatible = "st,stih407-uni-player-pcm-out"; - #sound-dai-cells = <0>; - st,syscfg = <&syscfg_core>; - clocks = <&clk_s_d0_flexgen CLK_PCM_2>; - reg = <0x8D82000 0x158>; - interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>; - dmas = <&fdma0 4 0 1>; - dma-names = "tx"; - }; - - sti_uni_player3: sti-uni-player@8d85000 { - compatible = "st,stih407-uni-player-spdif"; - #sound-dai-cells = <0>; - st,syscfg = <&syscfg_core>; - clocks = <&clk_s_d0_flexgen CLK_SPDIFF>; - reg = <0x8D85000 0x158>; - interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>; - dmas = <&fdma0 7 0 1>; - dma-names = "tx"; - }; - - sti_uni_reader1: sti-uni-reader@8d84000 { - compatible = "st,stih407-uni-reader-hdmi"; - #sound-dai-cells = <0>; - st,syscfg = <&syscfg_core>; - reg = <0x8D84000 0x158>; - interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>; - dmas = <&fdma0 6 0 1>; - dma-names = "rx"; - }; - -2) sti-sas-codec: internal audio codec IPs driver -------------------------------------------------- - -Required properties: - - compatible: "st,sti<chip>-sas-codec" . - Should be chip "st,stih416-sas-codec" or "st,stih407-sas-codec" - - - st,syscfg: phandle to boot-device system configuration registers. - - - pinctrl-0: SPDIF PIO description. - - - pinctrl-names: should contain only one value - "default". - -Example: - sti_sas_codec: sti-sas-codec { - compatible = "st,stih407-sas-codec"; - #sound-dai-cells = <1>; - st,reg_audio = <&syscfg_core>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_spdif_out >; - }; - -Example of audio card declaration: - sound { - compatible = "simple-audio-card"; - simple-audio-card,name = "sti audio card"; - - simple-audio-card,dai-link@0 { - /* DAC */ - format = "i2s"; - dai-tdm-slot-width = <32>; - cpu { - sound-dai = <&sti_uni_player2>; - }; - - codec { - sound-dai = <&sti_sasg_codec 1>; - }; - }; - simple-audio-card,dai-link@1 { - /* SPDIF */ - format = "left_j"; - cpu { - sound-dai = <&sti_uni_player3>; - }; - - codec { - sound-dai = <&sti_sasg_codec 0>; - }; - }; - simple-audio-card,dai-link@2 { - /* TDM playback */ - format = "left_j"; - frame-inversion = <1>; - cpu { - sound-dai = <&sti_uni_player1>; - dai-tdm-slot-num = <16>; - dai-tdm-slot-width = <16>; - dai-tdm-slot-tx-mask = - <1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1>; - }; - - codec { - sound-dai = <&sti_sasg_codec 3>; - }; - }; - }; diff --git a/MAINTAINERS b/MAINTAINERS index e127c2fb08a7..9dede78d02c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18465,13 +18465,6 @@ F: include/linux/static_call*.h F: kernel/jump_label.c F: kernel/static_call.c
-STI AUDIO (ASoC) DRIVERS -M: Arnaud Pouliquen arnaud.pouliquen@foss.st.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt -F: sound/soc/sti/ - STI CEC DRIVER M: Alain Volmat alain.volmat@foss.st.com S: Maintained diff --git a/sound/soc/sti/Kconfig b/sound/soc/sti/Kconfig deleted file mode 100644 index f881da4b6aea..000000000000 --- a/sound/soc/sti/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# STM SoC audio configuration -# -menuconfig SND_SOC_STI - tristate "SoC Audio support for STI System-On-Chip" - depends on SND_SOC - depends on ARCH_STI || COMPILE_TEST - select SND_SOC_GENERIC_DMAENGINE_PCM - help - Say Y if you want to enable ASoC-support for - any of the STI platforms (e.g. STIH416). diff --git a/sound/soc/sti/Makefile b/sound/soc/sti/Makefile deleted file mode 100644 index 787ccb521298..000000000000 --- a/sound/soc/sti/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# STI platform support -snd-soc-sti-objs := sti_uniperif.o uniperif_player.o uniperif_reader.o - -obj-$(CONFIG_SND_SOC_STI) += snd-soc-sti.o diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c deleted file mode 100644 index 34668fe3909d..000000000000 --- a/sound/soc/sti/sti_uniperif.c +++ /dev/null @@ -1,506 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) STMicroelectronics SA 2015 - * Authors: Arnaud Pouliquen arnaud.pouliquen@st.com - * for STMicroelectronics. - */ - -#include <linux/module.h> -#include <linux/pinctrl/consumer.h> -#include <linux/delay.h> - -#include "uniperif.h" - -/* - * User frame size shall be 2, 4, 6 or 8 32-bits words length - * (i.e. 8, 16, 24 or 32 bytes) - * This constraint comes from allowed values for - * UNIPERIF_I2S_FMT_NUM_CH register - */ -#define UNIPERIF_MAX_FRAME_SZ 0x20 -#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ) - -struct sti_uniperiph_dev_data { - unsigned int id; /* Nb available player instances */ - unsigned int version; /* player IP version */ - unsigned int stream; - const char *dai_names; - enum uniperif_type type; -}; - -static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = { - .id = 0, - .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, - .stream = SNDRV_PCM_STREAM_PLAYBACK, - .dai_names = "Uni Player #0 (HDMI)", - .type = SND_ST_UNIPERIF_TYPE_HDMI -}; - -static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = { - .id = 1, - .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, - .stream = SNDRV_PCM_STREAM_PLAYBACK, - .dai_names = "Uni Player #1 (PCM OUT)", - .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, -}; - -static const struct sti_uniperiph_dev_data sti_uniplayer_dac = { - .id = 2, - .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, - .stream = SNDRV_PCM_STREAM_PLAYBACK, - .dai_names = "Uni Player #2 (DAC)", - .type = SND_ST_UNIPERIF_TYPE_PCM, -}; - -static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = { - .id = 3, - .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0, - .stream = SNDRV_PCM_STREAM_PLAYBACK, - .dai_names = "Uni Player #3 (SPDIF)", - .type = SND_ST_UNIPERIF_TYPE_SPDIF -}; - -static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = { - .id = 0, - .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, - .stream = SNDRV_PCM_STREAM_CAPTURE, - .dai_names = "Uni Reader #0 (PCM IN)", - .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM, -}; - -static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = { - .id = 1, - .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, - .stream = SNDRV_PCM_STREAM_CAPTURE, - .dai_names = "Uni Reader #1 (HDMI IN)", - .type = SND_ST_UNIPERIF_TYPE_PCM, -}; - -static const struct of_device_id snd_soc_sti_match[] = { - { .compatible = "st,stih407-uni-player-hdmi", - .data = &sti_uniplayer_hdmi - }, - { .compatible = "st,stih407-uni-player-pcm-out", - .data = &sti_uniplayer_pcm_out - }, - { .compatible = "st,stih407-uni-player-dac", - .data = &sti_uniplayer_dac - }, - { .compatible = "st,stih407-uni-player-spdif", - .data = &sti_uniplayer_spdif - }, - { .compatible = "st,stih407-uni-reader-pcm_in", - .data = &sti_unireader_pcm_in - }, - { .compatible = "st,stih407-uni-reader-hdmi", - .data = &sti_unireader_hdmi_in - }, - {}, -}; -MODULE_DEVICE_TABLE(of, snd_soc_sti_match); - -int sti_uniperiph_reset(struct uniperif *uni) -{ - int count = 10; - - /* Reset uniperipheral uni */ - SET_UNIPERIF_SOFT_RST_SOFT_RST(uni); - - if (uni->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) { - while (GET_UNIPERIF_SOFT_RST_SOFT_RST(uni) && count) { - udelay(5); - count--; - } - } - - if (!count) { - dev_err(uni->dev, "Failed to reset uniperif\n"); - return -EIO; - } - - return 0; -} - -int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, - unsigned int rx_mask, int slots, - int slot_width) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *uni = priv->dai_data.uni; - int i, frame_size, avail_slots; - - if (!UNIPERIF_TYPE_IS_TDM(uni)) { - dev_err(uni->dev, "cpu dai not in tdm mode\n"); - return -EINVAL; - } - - /* store info in unip context */ - uni->tdm_slot.slots = slots; - uni->tdm_slot.slot_width = slot_width; - /* unip is unidirectionnal */ - uni->tdm_slot.mask = (tx_mask != 0) ? tx_mask : rx_mask; - - /* number of available timeslots */ - for (i = 0, avail_slots = 0; i < uni->tdm_slot.slots; i++) { - if ((uni->tdm_slot.mask >> i) & 0x01) - avail_slots++; - } - uni->tdm_slot.avail_slots = avail_slots; - - /* frame size in bytes */ - frame_size = uni->tdm_slot.avail_slots * uni->tdm_slot.slot_width / 8; - - /* check frame size is allowed */ - if ((frame_size > UNIPERIF_MAX_FRAME_SZ) || - (frame_size & ~(int)UNIPERIF_ALLOWED_FRAME_SZ)) { - dev_err(uni->dev, "frame size not allowed: %d bytes\n", - frame_size); - return -EINVAL; - } - - return 0; -} - -int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct uniperif *uni = rule->private; - struct snd_interval t; - - t.min = uni->tdm_slot.avail_slots; - t.max = uni->tdm_slot.avail_slots; - t.openmin = 0; - t.openmax = 0; - t.integer = 0; - - return snd_interval_refine(hw_param_interval(params, rule->var), &t); -} - -int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct uniperif *uni = rule->private; - struct snd_mask *maskp = hw_param_mask(params, rule->var); - u64 format; - - switch (uni->tdm_slot.slot_width) { - case 16: - format = SNDRV_PCM_FMTBIT_S16_LE; - break; - case 32: - format = SNDRV_PCM_FMTBIT_S32_LE; - break; - default: - dev_err(uni->dev, "format not supported: %d bits\n", - uni->tdm_slot.slot_width); - return -EINVAL; - } - - maskp->bits[0] &= (u_int32_t)format; - maskp->bits[1] &= (u_int32_t)(format >> 32); - /* clear remaining indexes */ - memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX - 64) / 8); - - if (!maskp->bits[0] && !maskp->bits[1]) - return -EINVAL; - - return 0; -} - -int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni, - unsigned int *word_pos) -{ - int slot_width = uni->tdm_slot.slot_width / 8; - int slots_num = uni->tdm_slot.slots; - unsigned int slots_mask = uni->tdm_slot.mask; - int i, j, k; - unsigned int word16_pos[4]; - - /* word16_pos: - * word16_pos[0] = WORDX_LSB - * word16_pos[1] = WORDX_MSB, - * word16_pos[2] = WORDX+1_LSB - * word16_pos[3] = WORDX+1_MSB - */ - - /* set unip word position */ - for (i = 0, j = 0, k = 0; (i < slots_num) && (k < WORD_MAX); i++) { - if ((slots_mask >> i) & 0x01) { - word16_pos[j] = i * slot_width; - - if (slot_width == 4) { - word16_pos[j + 1] = word16_pos[j] + 2; - j++; - } - j++; - - if (j > 3) { - word_pos[k] = word16_pos[1] | - (word16_pos[0] << 8) | - (word16_pos[3] << 16) | - (word16_pos[2] << 24); - j = 0; - k++; - } - } - } - - return 0; -} - -/* - * sti_uniperiph_dai_create_ctrl - * This function is used to create Ctrl associated to DAI but also pcm device. - * Request is done by front end to associate ctrl with pcm device id - */ -static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *uni = priv->dai_data.uni; - struct snd_kcontrol_new *ctrl; - int i; - - if (!uni->num_ctrls) - return 0; - - for (i = 0; i < uni->num_ctrls; i++) { - /* - * Several Control can have same name. Controls are indexed on - * Uniperipheral instance ID - */ - ctrl = &uni->snd_ctrls[i]; - ctrl->index = uni->id; - ctrl->device = uni->id; - } - - return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls); -} - -/* - * DAI - */ -int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *uni = priv->dai_data.uni; - struct snd_dmaengine_dai_dma_data *dma_data; - int transfer_size; - - if (uni->type == SND_ST_UNIPERIF_TYPE_TDM) - /* transfer size = user frame size (in 32-bits FIFO cell) */ - transfer_size = snd_soc_params_to_frame_size(params) / 32; - else - transfer_size = params_channels(params) * UNIPERIF_FIFO_FRAMES; - - dma_data = snd_soc_dai_get_dma_data(dai, substream); - dma_data->maxburst = transfer_size; - - return 0; -} - -int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - - priv->dai_data.uni->daifmt = fmt; - - return 0; -} - -static int sti_uniperiph_suspend(struct snd_soc_component *component) -{ - struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component); - struct uniperif *uni = priv->dai_data.uni; - int ret; - - /* The uniperipheral should be in stopped state */ - if (uni->state != UNIPERIF_STATE_STOPPED) { - dev_err(uni->dev, "%s: invalid uni state( %d)\n", - __func__, (int)uni->state); - return -EBUSY; - } - - /* Pinctrl: switch pinstate to sleep */ - ret = pinctrl_pm_select_sleep_state(uni->dev); - if (ret) - dev_err(uni->dev, "%s: failed to select pinctrl state\n", - __func__); - - return ret; -} - -static int sti_uniperiph_resume(struct snd_soc_component *component) -{ - struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component); - struct uniperif *uni = priv->dai_data.uni; - int ret; - - if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = uni_player_resume(uni); - if (ret) - return ret; - } - - /* pinctrl: switch pinstate to default */ - ret = pinctrl_pm_select_default_state(uni->dev); - if (ret) - dev_err(uni->dev, "%s: failed to select pinctrl state\n", - __func__); - - return ret; -} - -static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct sti_uniperiph_dai *dai_data = &priv->dai_data; - - /* DMA settings*/ - if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL); - else - snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data); - - dai_data->dma_data.addr = dai_data->uni->fifo_phys_address; - dai_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - - return sti_uniperiph_dai_create_ctrl(dai); -} - -static const struct snd_soc_dai_driver sti_uniperiph_dai_template = { - .probe = sti_uniperiph_dai_probe, -}; - -static const struct snd_soc_component_driver sti_uniperiph_dai_component = { - .name = "sti_cpu_dai", - .suspend = sti_uniperiph_suspend, - .resume = sti_uniperiph_resume -}; - -static int sti_uniperiph_cpu_dai_of(struct device_node *node, - struct sti_uniperiph_data *priv) -{ - struct device *dev = &priv->pdev->dev; - struct sti_uniperiph_dai *dai_data = &priv->dai_data; - struct snd_soc_dai_driver *dai = priv->dai; - struct snd_soc_pcm_stream *stream; - struct uniperif *uni; - const struct of_device_id *of_id; - const struct sti_uniperiph_dev_data *dev_data; - const char *mode; - int ret; - - /* Populate data structure depending on compatibility */ - of_id = of_match_node(snd_soc_sti_match, node); - if (!of_id->data) { - dev_err(dev, "data associated to device is missing\n"); - return -EINVAL; - } - dev_data = (struct sti_uniperiph_dev_data *)of_id->data; - - uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL); - if (!uni) - return -ENOMEM; - - uni->id = dev_data->id; - uni->ver = dev_data->version; - - *dai = sti_uniperiph_dai_template; - dai->name = dev_data->dai_names; - - /* Get resources and base address */ - uni->base = devm_platform_get_and_ioremap_resource(priv->pdev, 0, &uni->mem_region); - if (IS_ERR(uni->base)) - return PTR_ERR(uni->base); - - uni->fifo_phys_address = uni->mem_region->start + - UNIPERIF_FIFO_DATA_OFFSET(uni); - - uni->irq = platform_get_irq(priv->pdev, 0); - if (uni->irq < 0) - return -ENXIO; - - uni->type = dev_data->type; - - /* check if player should be configured for tdm */ - if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) { - if (!of_property_read_string(node, "st,tdm-mode", &mode)) - uni->type = SND_ST_UNIPERIF_TYPE_TDM; - else - uni->type = SND_ST_UNIPERIF_TYPE_PCM; - } - - dai_data->uni = uni; - dai_data->stream = dev_data->stream; - - if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) { - ret = uni_player_init(priv->pdev, uni); - stream = &dai->playback; - } else { - ret = uni_reader_init(priv->pdev, uni); - stream = &dai->capture; - } - if (ret < 0) - return ret; - - dai->ops = uni->dai_ops; - - stream->stream_name = dai->name; - stream->channels_min = uni->hw->channels_min; - stream->channels_max = uni->hw->channels_max; - stream->rates = uni->hw->rates; - stream->formats = uni->hw->formats; - - return 0; -} - -static const struct snd_dmaengine_pcm_config dmaengine_pcm_config = { - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, -}; - -static int sti_uniperiph_probe(struct platform_device *pdev) -{ - struct sti_uniperiph_data *priv; - struct device_node *node = pdev->dev.of_node; - int ret; - - /* Allocate the private data and the CPU_DAI array */ - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL); - if (!priv->dai) - return -ENOMEM; - - priv->pdev = pdev; - - ret = sti_uniperiph_cpu_dai_of(node, priv); - if (ret < 0) - return ret; - - dev_set_drvdata(&pdev->dev, priv); - - ret = devm_snd_soc_register_component(&pdev->dev, - &sti_uniperiph_dai_component, - priv->dai, 1); - if (ret < 0) - return ret; - - return devm_snd_dmaengine_pcm_register(&pdev->dev, - &dmaengine_pcm_config, 0); -} - -static struct platform_driver sti_uniperiph_driver = { - .driver = { - .name = "sti-uniperiph-dai", - .of_match_table = snd_soc_sti_match, - }, - .probe = sti_uniperiph_probe, -}; -module_platform_driver(sti_uniperiph_driver); - -MODULE_DESCRIPTION("uniperipheral DAI driver"); -MODULE_AUTHOR("Arnaud Pouliquen arnaud.pouliquen@st.com"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h deleted file mode 100644 index 2a5de328501c..000000000000 --- a/sound/soc/sti/uniperif.h +++ /dev/null @@ -1,1416 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) STMicroelectronics SA 2015 - * Authors: Arnaud Pouliquen arnaud.pouliquen@st.com - * for STMicroelectronics. - */ - -#ifndef __SND_ST_AUD_UNIPERIF_H -#define __SND_ST_AUD_UNIPERIF_H - -#include <linux/regmap.h> - -#include <sound/dmaengine_pcm.h> - -/* - * Register access macros - */ - -#define GET_UNIPERIF_REG(ip, offset, shift, mask) \ - ((readl_relaxed(ip->base + offset) >> shift) & mask) -#define SET_UNIPERIF_REG(ip, offset, shift, mask, value) \ - writel_relaxed(((readl_relaxed(ip->base + offset) & \ - ~(mask << shift)) | (((value) & mask) << shift)), ip->base + offset) -#define SET_UNIPERIF_BIT_REG(ip, offset, shift, mask, value) \ - writel_relaxed((((value) & mask) << shift), ip->base + offset) - -/* - * UNIPERIF_SOFT_RST reg - */ - -#define UNIPERIF_SOFT_RST_OFFSET(ip) 0x0000 -#define GET_UNIPERIF_SOFT_RST(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - readl_relaxed(ip->base + UNIPERIF_SOFT_RST_OFFSET(ip)) : 0) -#define SET_UNIPERIF_SOFT_RST(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_SOFT_RST_OFFSET(ip)) - -/* SOFT_RST */ -#define UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip) 0x0 -#define UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip) 0x1 -#define SET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \ - SET_UNIPERIF_BIT_REG(ip, \ - UNIPERIF_SOFT_RST_OFFSET(ip), \ - UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \ - UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip), 1) -#define GET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_SOFT_RST_OFFSET(ip), \ - UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \ - UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip)) - -/* - * UNIPERIF_FIFO_DATA reg - */ - -#define UNIPERIF_FIFO_DATA_OFFSET(ip) 0x0004 -#define SET_UNIPERIF_DATA(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_FIFO_DATA_OFFSET(ip)) - -/* - * UNIPERIF_CHANNEL_STA_REGN reg - */ - -#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n)) -#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \ - writel_relaxed(value, ip->base + \ - UNIPERIF_CHANNEL_STA_REGN(ip, n)) - -#define UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip) 0x0060 -#define GET_UNIPERIF_CHANNEL_STA_REG0(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG0(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip)) - -#define UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip) 0x0064 -#define GET_UNIPERIF_CHANNEL_STA_REG1(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG1(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip)) - -#define UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip) 0x0068 -#define GET_UNIPERIF_CHANNEL_STA_REG2(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG2(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip)) - -#define UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip) 0x006C -#define GET_UNIPERIF_CHANNEL_STA_REG3(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG3(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip)) - -#define UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip) 0x0070 -#define GET_UNIPERIF_CHANNEL_STA_REG4(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG4(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip)) - -#define UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip) 0x0074 -#define GET_UNIPERIF_CHANNEL_STA_REG5(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip)) -#define SET_UNIPERIF_CHANNEL_STA_REG5(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip)) - -/* - * UNIPERIF_ITS reg - */ - -#define UNIPERIF_ITS_OFFSET(ip) 0x000C -#define GET_UNIPERIF_ITS(ip) \ - readl_relaxed(ip->base + UNIPERIF_ITS_OFFSET(ip)) - -/* MEM_BLK_READ */ -#define UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITS_MEM_BLK_READ_MASK(ip) \ - (BIT(UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip))) - -/* FIFO_ERROR */ -#define UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8) -#define UNIPERIF_ITS_FIFO_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip))) - -/* DMA_ERROR */ -#define UNIPERIF_ITS_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITS_DMA_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITS_DMA_ERROR_SHIFT(ip))) - -/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12) -#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip)))) - -/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13) -#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip)))) - -/* - * UNIPERIF_ITS_BCLR reg - */ - -/* FIFO_ERROR */ -#define UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8) -#define UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip))) -#define SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(ip) \ - SET_UNIPERIF_ITS_BCLR(ip, \ - UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip)) - -#define UNIPERIF_ITS_BCLR_OFFSET(ip) 0x0010 -#define SET_UNIPERIF_ITS_BCLR(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_ITS_BCLR_OFFSET(ip)) - -/* - * UNIPERIF_ITM reg - */ - -#define UNIPERIF_ITM_OFFSET(ip) 0x0018 -#define GET_UNIPERIF_ITM(ip) \ - readl_relaxed(ip->base + UNIPERIF_ITM_OFFSET(ip)) - -/* FIFO_ERROR */ -#define UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8) -#define UNIPERIF_ITM_FIFO_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip))) - -/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12) -#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip)))) - -/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13) -#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip)))) - -/* - * UNIPERIF_ITM_BCLR reg - */ - -#define UNIPERIF_ITM_BCLR_OFFSET(ip) 0x001c -#define SET_UNIPERIF_ITM_BCLR(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_ITM_BCLR_OFFSET(ip)) - -/* FIFO_ERROR */ -#define UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8) -#define UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip))) -#define SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(ip) \ - SET_UNIPERIF_ITM_BCLR(ip, \ - UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip)) - -/* DMA_ERROR */ -#define UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip))) -#define SET_UNIPERIF_ITM_BCLR_DMA_ERROR(ip) \ - SET_UNIPERIF_ITM_BCLR(ip, \ - UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip)) - -/* - * UNIPERIF_ITM_BSET reg - */ - -#define UNIPERIF_ITM_BSET_OFFSET(ip) 0x0020 -#define SET_UNIPERIF_ITM_BSET(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_ITM_BSET_OFFSET(ip)) - -/* FIFO_ERROR */ -#define UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8) -#define UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip))) -#define SET_UNIPERIF_ITM_BSET_FIFO_ERROR(ip) \ - SET_UNIPERIF_ITM_BSET(ip, \ - UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip)) - -/* MEM_BLK_READ */ -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip) \ - (BIT(UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip))) -#define SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(ip) \ - SET_UNIPERIF_ITM_BSET(ip, \ - UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip)) - -/* DMA_ERROR */ -#define UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip) \ - (BIT(UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip))) -#define SET_UNIPERIF_ITM_BSET_DMA_ERROR(ip) \ - SET_UNIPERIF_ITM_BSET(ip, \ - UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip)) - -/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12) -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip)))) -#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(ip) \ - SET_UNIPERIF_ITM_BSET(ip, \ - UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip)) - -/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13) -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \ - 0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip)))) -#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(ip) \ - SET_UNIPERIF_ITM_BSET(ip, \ - UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip)) - -/* - * UNIPERIF_CONFIG reg - */ - -#define UNIPERIF_CONFIG_OFFSET(ip) 0x0040 -#define GET_UNIPERIF_CONFIG(ip) \ - readl_relaxed(ip->base + UNIPERIF_CONFIG_OFFSET(ip)) -#define SET_UNIPERIF_CONFIG(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CONFIG_OFFSET(ip)) - -/* PARITY_CNTR */ -#define UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip) 0 -#define UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_PARITY_CNTR(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip)) -#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_SW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 1) - -/* CHANNEL_STA_CNTR */ -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip) 1 -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip)) -#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_SW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 1) - -/* USER_DAT_CNTR */ -#define UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip) 2 -#define UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_USER_DAT_CNTR(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip)) -#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 1) -#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_SW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 0) - -/* VALIDITY_DAT_CNTR */ -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip) 3 -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip)) -#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_SW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \ - UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 1) - -/* ONE_BIT_AUD_SUPPORT */ -#define UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip) 4 -#define UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_ONE_BIT_AUD(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip)) -#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \ - UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 1) - -/* MEMORY_FMT */ -#define UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip) 5 -#define UNIPERIF_CONFIG_MEM_FMT_MASK(ip) 0x1 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) 0 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) 1 -#define GET_UNIPERIF_CONFIG_MEM_FMT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \ - UNIPERIF_CONFIG_MEM_FMT_MASK(ip)) -#define SET_UNIPERIF_CONFIG_MEM_FMT(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \ - UNIPERIF_CONFIG_MEM_FMT_MASK(ip), value) -#define SET_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) \ - SET_UNIPERIF_CONFIG_MEM_FMT(ip, \ - VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip)) -#define SET_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) \ - SET_UNIPERIF_CONFIG_MEM_FMT(ip, \ - VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip)) - -/* REPEAT_CHL_STS */ -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip) 6 -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_REPEAT_CHL_STS(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip)) -#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \ - UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 1) - -/* BACK_STALL_REQ */ -#define UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 7 : -1) -#define UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_BACK_STALL_REQ(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip)) -#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \ - UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 1) - -/* FDMA_TRIGGER_LIMIT */ -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip) 8 -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip) 0x7F -#define GET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \ - UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip)) -#define SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \ - UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip), value) - -/* CHL_STS_UPDATE */ -#define UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1) -#define UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \ - UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip)) -#define SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \ - UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip), 1) - -/* IDLE_MOD */ -#define UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip) 18 -#define UNIPERIF_CONFIG_IDLE_MOD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_IDLE_MOD(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_MASK(ip)) -#define SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 0) -#define SET_UNIPERIF_CONFIG_IDLE_MOD_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \ - UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 1) - -/* SUBFRAME_SELECTION */ -#define UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip) 19 -#define UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SUBFRAME_SEL(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip)) -#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 1) -#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF0_SUBF1(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \ - UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 0) - -/* FULL_SW_CONTROL */ -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip) 20 -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SPDIF_SW_CTRL(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip)) -#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 1) -#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \ - UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 0) - -/* MASTER_CLKEDGE */ -#define UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 24 : -1) -#define UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_MSTR_CLKEDGE(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip)) -#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_FALLING(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 1) -#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_RISING(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CONFIG_OFFSET(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \ - UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 0) - -/* - * UNIPERIF_CTRL reg - */ - -#define UNIPERIF_CTRL_OFFSET(ip) 0x0044 -#define GET_UNIPERIF_CTRL(ip) \ - readl_relaxed(ip->base + UNIPERIF_CTRL_OFFSET(ip)) -#define SET_UNIPERIF_CTRL(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_CTRL_OFFSET(ip)) - -/* OPERATION */ -#define UNIPERIF_CTRL_OPERATION_SHIFT(ip) 0 -#define UNIPERIF_CTRL_OPERATION_MASK(ip) 0x7 -#define GET_UNIPERIF_CTRL_OPERATION(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip) 0 -#define SET_UNIPERIF_CTRL_OPERATION_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 1 : -1) -#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 2 : -1) -#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip)) -/* This is the same as above! */ -#define VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) 4 -#define SET_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 5 : -1) -#define SET_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip)) -#define VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 7) -#define SET_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_OPERATION_SHIFT(ip), \ - UNIPERIF_CTRL_OPERATION_MASK(ip), \ - VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip)) - -/* EXIT_STBY_ON_EOBLOCK */ -#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 3) -#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip)) -#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 0) -#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \ - UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 1) - -/* ROUNDING */ -#define UNIPERIF_CTRL_ROUNDING_SHIFT(ip) 4 -#define UNIPERIF_CTRL_ROUNDING_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ROUNDING(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \ - UNIPERIF_CTRL_ROUNDING_MASK(ip)) -#define SET_UNIPERIF_CTRL_ROUNDING_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \ - UNIPERIF_CTRL_ROUNDING_MASK(ip), 0) -#define SET_UNIPERIF_CTRL_ROUNDING_ON(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \ - UNIPERIF_CTRL_ROUNDING_MASK(ip), 1) - -/* DIVIDER */ -#define UNIPERIF_CTRL_DIVIDER_SHIFT(ip) 5 -#define UNIPERIF_CTRL_DIVIDER_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_DIVIDER(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \ - UNIPERIF_CTRL_DIVIDER_MASK(ip)) -#define SET_UNIPERIF_CTRL_DIVIDER(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \ - UNIPERIF_CTRL_DIVIDER_MASK(ip), value) - -/* BYTE_SWAP */ -#define UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 13 : -1) -#define UNIPERIF_CTRL_BYTE_SWP_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_BYTE_SWP(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \ - UNIPERIF_CTRL_BYTE_SWP_MASK(ip)) -#define SET_UNIPERIF_CTRL_BYTE_SWP_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \ - UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 0) -#define SET_UNIPERIF_CTRL_BYTE_SWP_ON(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \ - UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 1) - -/* ZERO_STUFFING_HW_SW */ -#define UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 14 : -1) -#define UNIPERIF_CTRL_ZERO_STUFF_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ZERO_STUFF(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_MASK(ip)) -#define SET_UNIPERIF_CTRL_ZERO_STUFF_HW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 1) -#define SET_UNIPERIF_CTRL_ZERO_STUFF_SW(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \ - UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 0) - -/* SPDIF_LAT */ -#define UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1) -#define UNIPERIF_CTRL_SPDIF_LAT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_LAT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_MASK(ip)) -#define SET_UNIPERIF_CTRL_SPDIF_LAT_ON(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 1) -#define SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 0) - -/* EN_SPDIF_FORMATTING */ -#define UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip) 17 -#define UNIPERIF_CTRL_SPDIF_FMT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_FMT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_MASK(ip)) -#define SET_UNIPERIF_CTRL_SPDIF_FMT_ON(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 1) -#define SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \ - UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 0) - -/* READER_OUT_SELECT */ -#define UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 18 : -1) -#define UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_READER_OUT_SEL(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip)) -#define SET_UNIPERIF_CTRL_READER_OUT_SEL_IN_MEM(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 0) -#define SET_UNIPERIF_CTRL_READER_OUT_SEL_ON_I2S_LINE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \ - UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 1) - -/* UNDERFLOW_REC_WINDOW */ -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip) 20 -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \ - UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip)) -#define SET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_CTRL_OFFSET(ip), \ - UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \ - UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip), value) - -/* - * UNIPERIF_I2S_FMT a.k.a UNIPERIF_FORMAT reg - */ - -#define UNIPERIF_I2S_FMT_OFFSET(ip) 0x0048 -#define GET_UNIPERIF_I2S_FMT(ip) \ - readl_relaxed(ip->base + UNIPERIF_I2S_FMT_OFFSET(ip)) -#define SET_UNIPERIF_I2S_FMT(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_I2S_FMT_OFFSET(ip)) - -/* NBIT */ -#define UNIPERIF_I2S_FMT_NBIT_SHIFT(ip) 0 -#define UNIPERIF_I2S_FMT_NBIT_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_NBIT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NBIT_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_NBIT_32(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NBIT_MASK(ip), 0) -#define SET_UNIPERIF_I2S_FMT_NBIT_16(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NBIT_MASK(ip), 1) - -/* DATA_SIZE */ -#define UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip) 1 -#define UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_DATA_SIZE(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 0) -#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_18(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 1) -#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_20(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 2) -#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 3) -#define SET_UNIPERIF_I2S_FMTL_DATA_SIZE_28(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 4) -#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 5) - -/* LR_POL */ -#define UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip) 4 -#define UNIPERIF_I2S_FMT_LR_POL_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_LR_POL(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \ - UNIPERIF_I2S_FMT_LR_POL_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_LR_POL(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \ - UNIPERIF_I2S_FMT_LR_POL_MASK(ip), value) -#define SET_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) \ - SET_UNIPERIF_I2S_FMT_LR_POL(ip, \ - VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip)) -#define SET_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) \ - SET_UNIPERIF_I2S_FMT_LR_POL(ip, \ - VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip)) - -/* SCLK_EDGE */ -#define UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip) 5 -#define UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_SCLK_EDGE(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 0) -#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \ - UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 1) - -/* PADDING */ -#define UNIPERIF_I2S_FMT_PADDING_SHIFT(ip) 6 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_PADDING(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \ - UNIPERIF_I2S_FMT_PADDING_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_PADDING(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \ - UNIPERIF_I2S_FMT_PADDING_MASK(ip), value) -#define SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) \ - SET_UNIPERIF_I2S_FMT_PADDING(ip, \ - VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip)) -#define SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) \ - SET_UNIPERIF_I2S_FMT_PADDING(ip, \ - VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip)) - -/* ALIGN */ -#define UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip) 7 -#define UNIPERIF_I2S_FMT_ALIGN_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ALIGN(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ALIGN_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 0) -#define SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 1) - -/* ORDER */ -#define UNIPERIF_I2S_FMT_ORDER_SHIFT(ip) 8 -#define UNIPERIF_I2S_FMT_ORDER_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ORDER(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ORDER_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_ORDER_LSB(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ORDER_MASK(ip), 0) -#define SET_UNIPERIF_I2S_FMT_ORDER_MSB(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \ - UNIPERIF_I2S_FMT_ORDER_MASK(ip), 1) - -/* NUM_CH */ -#define UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip) 9 -#define UNIPERIF_I2S_FMT_NUM_CH_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_NUM_CH(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NUM_CH_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_NUM_CH(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NUM_CH_MASK(ip), value) - -/* NO_OF_SAMPLES_TO_READ */ -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip) 12 -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip) 0xfffff -#define GET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip)) -#define SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_I2S_FMT_OFFSET(ip), \ - UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \ - UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip), value) - -/* - * UNIPERIF_BIT_CONTROL reg - */ - -#define UNIPERIF_BIT_CONTROL_OFFSET(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0x004c) -#define GET_UNIPERIF_BIT_CONTROL(ip) \ - readl_relaxed(ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip)) -#define SET_UNIPERIF_BIT_CONTROL(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip)) - -/* CLR_UNDERFLOW_DURATION */ -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip) 0 -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip) 0x1 -#define GET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_BIT_CONTROL_OFFSET(ip), \ - UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \ - UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip)) -#define SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_BIT_CONTROL_OFFSET(ip), \ - UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \ - UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip), 1) - -/* CHL_STS_UPDATE */ -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip) 1 -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_BIT_CONTROL_OFFSET(ip), \ - UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \ - UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip)) -#define SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \ - SET_UNIPERIF_BIT_REG(ip, \ - UNIPERIF_BIT_CONTROL_OFFSET(ip), \ - UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \ - UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip), 1) - -/* - * UNIPERIF_STATUS_1 reg - */ - -#define UNIPERIF_STATUS_1_OFFSET(ip) 0x0050 -#define GET_UNIPERIF_STATUS_1(ip) \ - readl_relaxed(ip->base + UNIPERIF_STATUS_1_OFFSET(ip)) -#define SET_UNIPERIF_STATUS_1(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_STATUS_1_OFFSET(ip)) - -/* UNDERFLOW_DURATION */ -#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0) -#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip) 0xff -#define GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_STATUS_1_OFFSET(ip), \ - UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \ - UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip)) -#define SET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_STATUS_1_OFFSET(ip), \ - UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \ - UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip), value) - -/* - * UNIPERIF_CHANNEL_STA_REGN reg - */ - -#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \ - readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n)) -#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \ - writel_relaxed(value, ip->base + \ - UNIPERIF_CHANNEL_STA_REGN(ip, n)) - -/* - * UNIPERIF_USER_VALIDITY reg - */ - -#define UNIPERIF_USER_VALIDITY_OFFSET(ip) 0x0090 -#define GET_UNIPERIF_USER_VALIDITY(ip) \ - readl_relaxed(ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip)) -#define SET_UNIPERIF_USER_VALIDITY(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip)) - -/* VALIDITY_LEFT_AND_RIGHT */ -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip) 0 -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip) 0x3 -#define GET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_USER_VALIDITY_OFFSET(ip), \ - UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \ - UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip)) -#define SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_USER_VALIDITY_OFFSET(ip), \ - UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \ - UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip), \ - value ? 0x3 : 0) - -/* - * UNIPERIF_DBG_STANDBY_LEFT_SP reg - */ -#define UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip) 0x0150 -#define UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0) -#define UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip) \ - ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 0xFFFFFF) -#define GET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \ - UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \ - UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip)) -#define SET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \ - UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \ - UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip), value) - -/* - * UNIPERIF_TDM_ENABLE - */ -#define UNIPERIF_TDM_ENABLE_OFFSET(ip) 0x0118 -#define GET_UNIPERIF_TDM_ENABLE(ip) \ - readl_relaxed(ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip)) -#define SET_UNIPERIF_TDM_ENABLE(ip, value) \ - writel_relaxed(value, ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip)) - -/* TDM_ENABLE */ -#define UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip) 0x1 -#define GET_UNIPERIF_TDM_ENABLE_EN_TDM(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_ENABLE_OFFSET(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip)) -#define SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_ENABLE_OFFSET(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 1) -#define SET_UNIPERIF_TDM_ENABLE_TDM_DISABLE(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_ENABLE_OFFSET(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \ - UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 0) - -/* - * UNIPERIF_TDM_FS_REF_FREQ - */ -#define UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip) 0x011c -#define GET_UNIPERIF_TDM_FS_REF_FREQ(ip) \ - readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip)) -#define SET_UNIPERIF_TDM_FS_REF_FREQ(ip, value) \ - writel_relaxed(value, ip->base + \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip)) - -/* REF_FREQ */ -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip) 0x0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) 0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) 1 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) 2 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) 3 -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip) 0x3 -#define GET_UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip)) -#define SET_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \ - VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip)) -#define SET_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \ - VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip)) -#define SET_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \ - VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip)) -#define SET_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \ - VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip)) - -/* - * UNIPERIF_TDM_FS_REF_DIV - */ -#define UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip) 0x0120 -#define GET_UNIPERIF_TDM_FS_REF_DIV(ip) \ - readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip)) -#define SET_UNIPERIF_TDM_FS_REF_DIV(ip, value) \ - writel_relaxed(value, ip->base + \ - UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip)) - -/* NUM_TIMESLOT */ -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip) 0xff -#define GET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip) \ - GET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip)) -#define SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip, value) \ - SET_UNIPERIF_REG(ip, \ - UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \ - UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \ - UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip), value) - -/* - * UNIPERIF_TDM_WORD_POS_X_Y - * 32 bits of UNIPERIF_TDM_WORD_POS_X_Y register shall be set in 1 shot - */ -#define UNIPERIF_TDM_WORD_POS_1_2_OFFSET(ip) 0x013c -#define UNIPERIF_TDM_WORD_POS_3_4_OFFSET(ip) 0x0140 -#define UNIPERIF_TDM_WORD_POS_5_6_OFFSET(ip) 0x0144 -#define UNIPERIF_TDM_WORD_POS_7_8_OFFSET(ip) 0x0148 -#define GET_UNIPERIF_TDM_WORD_POS(ip, words) \ - readl_relaxed(ip->base + UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip)) -#define SET_UNIPERIF_TDM_WORD_POS(ip, words, value) \ - writel_relaxed(value, ip->base + \ - UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip)) -/* - * uniperipheral IP capabilities - */ - -#define UNIPERIF_FIFO_SIZE 70 /* FIFO is 70 cells deep */ -#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */ - -#define UNIPERIF_TYPE_IS_HDMI(p) \ - ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI) -#define UNIPERIF_TYPE_IS_PCM(p) \ - ((p)->type == SND_ST_UNIPERIF_TYPE_PCM) -#define UNIPERIF_TYPE_IS_SPDIF(p) \ - ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF) -#define UNIPERIF_TYPE_IS_IEC958(p) \ - (UNIPERIF_TYPE_IS_HDMI(p) || \ - UNIPERIF_TYPE_IS_SPDIF(p)) -#define UNIPERIF_TYPE_IS_TDM(p) \ - ((p)->type == SND_ST_UNIPERIF_TYPE_TDM) - -/* - * Uniperipheral IP revisions - */ -enum uniperif_version { - SND_ST_UNIPERIF_VERSION_UNKNOWN, - /* SASG1 (Orly), Newman */ - SND_ST_UNIPERIF_VERSION_C6AUD0_UNI_1_0, - /* SASC1, SASG2 (Orly2) */ - SND_ST_UNIPERIF_VERSION_UNI_PLR_1_0, - /* SASC1, SASG2 (Orly2), TELSS, Cannes */ - SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0, - /* TELSS (SASC1) */ - SND_ST_UNIPERIF_VERSION_TDM_PLR_1_0, - /* Cannes/Monaco */ - SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 -}; - -enum uniperif_type { - SND_ST_UNIPERIF_TYPE_NONE = 0x00, - SND_ST_UNIPERIF_TYPE_HDMI = 0x01, - SND_ST_UNIPERIF_TYPE_PCM = 0x02, - SND_ST_UNIPERIF_TYPE_SPDIF = 0x04, - SND_ST_UNIPERIF_TYPE_TDM = 0x08 -}; - -enum uniperif_state { - UNIPERIF_STATE_STOPPED, - UNIPERIF_STATE_STARTED, - UNIPERIF_STATE_STANDBY, - UNIPERIF_STATE_UNDERFLOW, - UNIPERIF_STATE_OVERFLOW = UNIPERIF_STATE_UNDERFLOW, - UNIPERIF_STATE_XRUN -}; - -enum uniperif_iec958_encoding_mode { - UNIPERIF_IEC958_ENCODING_MODE_PCM, - UNIPERIF_IEC958_ENCODING_MODE_ENCODED -}; - -enum uniperif_word_pos { - WORD_1_2, - WORD_3_4, - WORD_5_6, - WORD_7_8, - WORD_MAX -}; - -struct uniperif_iec958_settings { - enum uniperif_iec958_encoding_mode encoding_mode; - struct snd_aes_iec958 iec958; -}; - -struct dai_tdm_slot { - unsigned int mask; - int slots; - int slot_width; - unsigned int avail_slots; -}; - -struct uniperif { - /* System information */ - enum uniperif_type type; - int underflow_enabled; /* Underflow recovery mode */ - struct device *dev; - int id; /* instance value of the uniperipheral IP */ - int ver; /* IP version, used by register access macros */ - struct regmap_field *clk_sel; - struct regmap_field *valid_sel; - spinlock_t irq_lock; /* use to prevent race condition with IRQ */ - - /* capabilities */ - const struct snd_pcm_hardware *hw; - - /* Resources */ - struct resource *mem_region; - void __iomem *base; - unsigned long fifo_phys_address; - int irq; - - /* Clocks */ - struct clk *clk; - int mclk; - int clk_adj; - - /* Runtime data */ - enum uniperif_state state; - - struct snd_pcm_substream *substream; - - /* Specific to IEC958 player */ - struct uniperif_iec958_settings stream_settings; - struct mutex ctrl_lock; /* For resource updated by stream and controls*/ - - /*alsa ctrl*/ - struct snd_kcontrol_new *snd_ctrls; - int num_ctrls; - - /* dai properties */ - unsigned int daifmt; - struct dai_tdm_slot tdm_slot; - - /* DAI callbacks */ - const struct snd_soc_dai_ops *dai_ops; -}; - -struct sti_uniperiph_dai { - int stream; - struct uniperif *uni; - struct snd_dmaengine_dai_dma_data dma_data; -}; - -struct sti_uniperiph_data { - struct platform_device *pdev; - struct snd_soc_dai_driver *dai; - struct sti_uniperiph_dai dai_data; -}; - -static __maybe_unused const struct snd_pcm_hardware uni_tdm_hw = { - .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, - - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 8000, - .rate_max = 48000, - - .channels_min = 1, - .channels_max = 32, - - .periods_min = 2, - .periods_max = 10, - - .period_bytes_min = 128, - .period_bytes_max = 64 * PAGE_SIZE, - .buffer_bytes_max = 256 * PAGE_SIZE -}; - -/* uniperiph player*/ -int uni_player_init(struct platform_device *pdev, - struct uniperif *player); -int uni_player_resume(struct uniperif *player); - -/* uniperiph reader */ -int uni_reader_init(struct platform_device *pdev, - struct uniperif *reader); - -/* common */ -int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt); - -int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai); - -static inline int sti_uniperiph_get_user_frame_size( - struct snd_pcm_runtime *runtime) -{ - return (runtime->channels * snd_pcm_format_width(runtime->format) / 8); -} - -static inline int sti_uniperiph_get_unip_tdm_frame_size(struct uniperif *uni) -{ - return (uni->tdm_slot.slots * uni->tdm_slot.slot_width / 8); -} - -int sti_uniperiph_reset(struct uniperif *uni); - -int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, - unsigned int rx_mask, int slots, - int slot_width); - -int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni, - unsigned int *word_pos); - -int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule); - -int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule); - -#endif diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c deleted file mode 100644 index 2ed92c990b97..000000000000 --- a/sound/soc/sti/uniperif_player.c +++ /dev/null @@ -1,1148 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) STMicroelectronics SA 2015 - * Authors: Arnaud Pouliquen arnaud.pouliquen@st.com - * for STMicroelectronics. - */ - -#include <linux/clk.h> -#include <linux/mfd/syscon.h> - -#include <sound/asoundef.h> -#include <sound/soc.h> - -#include "uniperif.h" - -/* - * Some hardware-related definitions - */ - -/* sys config registers definitions */ -#define SYS_CFG_AUDIO_GLUE 0xA4 - -/* - * Driver specific types. - */ - -#define UNIPERIF_PLAYER_CLK_ADJ_MIN -999999 -#define UNIPERIF_PLAYER_CLK_ADJ_MAX 1000000 -#define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX bus */ - -/* - * Note: snd_pcm_hardware is linked to DMA controller but is declared here to - * integrate DAI_CPU capability in term of rate and supported channels - */ -static const struct snd_pcm_hardware uni_player_pcm_hw = { - .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 8000, - .rate_max = 192000, - - .channels_min = 2, - .channels_max = 8, - - .periods_min = 2, - .periods_max = 48, - - .period_bytes_min = 128, - .period_bytes_max = 64 * PAGE_SIZE, - .buffer_bytes_max = 256 * PAGE_SIZE -}; - -/* - * uni_player_irq_handler - * In case of error audio stream is stopped; stop action is protected via PCM - * stream lock to avoid race condition with trigger callback. - */ -static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) -{ - irqreturn_t ret = IRQ_NONE; - struct uniperif *player = dev_id; - unsigned int status; - unsigned int tmp; - - spin_lock(&player->irq_lock); - if (!player->substream) - goto irq_spin_unlock; - - snd_pcm_stream_lock(player->substream); - if (player->state == UNIPERIF_STATE_STOPPED) - goto stream_unlock; - - /* Get interrupt status & clear them immediately */ - status = GET_UNIPERIF_ITS(player); - SET_UNIPERIF_ITS_BCLR(player, status); - - /* Check for fifo error (underrun) */ - if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) { - dev_err(player->dev, "FIFO underflow error detected\n"); - - /* Interrupt is just for information when underflow recovery */ - if (player->underflow_enabled) { - /* Update state to underflow */ - player->state = UNIPERIF_STATE_UNDERFLOW; - - } else { - /* Disable interrupt so doesn't continually fire */ - SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player); - - /* Stop the player */ - snd_pcm_stop_xrun(player->substream); - } - - ret = IRQ_HANDLED; - } - - /* Check for dma error (overrun) */ - if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) { - dev_err(player->dev, "DMA error detected\n"); - - /* Disable interrupt so doesn't continually fire */ - SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player); - - /* Stop the player */ - snd_pcm_stop_xrun(player->substream); - - ret = IRQ_HANDLED; - } - - /* Check for underflow recovery done */ - if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) { - if (!player->underflow_enabled) { - dev_err(player->dev, - "unexpected Underflow recovering\n"); - ret = -EPERM; - goto stream_unlock; - } - /* Read the underflow recovery duration */ - tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player); - dev_dbg(player->dev, "Underflow recovered (%d LR clocks max)\n", - tmp); - - /* Clear the underflow recovery duration */ - SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player); - - /* Update state to started */ - player->state = UNIPERIF_STATE_STARTED; - - ret = IRQ_HANDLED; - } - - /* Check if underflow recovery failed */ - if (unlikely(status & - UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) { - dev_err(player->dev, "Underflow recovery failed\n"); - - /* Stop the player */ - snd_pcm_stop_xrun(player->substream); - - ret = IRQ_HANDLED; - } - -stream_unlock: - snd_pcm_stream_unlock(player->substream); -irq_spin_unlock: - spin_unlock(&player->irq_lock); - - return ret; -} - -static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate) -{ - int rate_adjusted, rate_achieved, delta, ret; - int adjustment = player->clk_adj; - - /* - * a - * F = f + --------- * f = f + d - * 1000000 - * - * a - * d = --------- * f - * 1000000 - * - * where: - * f - nominal rate - * a - adjustment in ppm (parts per milion) - * F - rate to be set in synthesizer - * d - delta (difference) between f and F - */ - if (adjustment < 0) { - /* div64_64 operates on unsigned values... */ - delta = -1; - adjustment = -adjustment; - } else { - delta = 1; - } - /* 500000 ppm is 0.5, which is used to round up values */ - delta *= (int)div64_u64((uint64_t)rate * - (uint64_t)adjustment + 500000, 1000000); - rate_adjusted = rate + delta; - - /* Adjusted rate should never be == 0 */ - if (!rate_adjusted) - return -EINVAL; - - ret = clk_set_rate(player->clk, rate_adjusted); - if (ret < 0) - return ret; - - rate_achieved = clk_get_rate(player->clk); - if (!rate_achieved) - /* If value is 0 means that clock or parent not valid */ - return -EINVAL; - - /* - * Using ALSA's adjustment control, we can modify the rate to be up - * to twice as much as requested, but no more - */ - delta = rate_achieved - rate; - if (delta < 0) { - /* div64_64 operates on unsigned values... */ - delta = -delta; - adjustment = -1; - } else { - adjustment = 1; - } - /* Frequency/2 is added to round up result */ - adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2, - rate); - player->clk_adj = adjustment; - return 0; -} - -static void uni_player_set_channel_status(struct uniperif *player, - struct snd_pcm_runtime *runtime) -{ - int n; - unsigned int status; - - /* - * Some AVRs and TVs require the channel status to contain a correct - * sampling frequency. If no sample rate is already specified, then - * set one. - */ - if (runtime) { - switch (runtime->rate) { - case 22050: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_22050; - break; - case 44100: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_44100; - break; - case 88200: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_88200; - break; - case 176400: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_176400; - break; - case 24000: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_24000; - break; - case 48000: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_48000; - break; - case 96000: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_96000; - break; - case 192000: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_192000; - break; - case 32000: - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_32000; - break; - default: - /* Mark as sampling frequency not indicated */ - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_NOTID; - break; - } - } - - /* Audio mode: - * Use audio mode status to select PCM or encoded mode - */ - if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO) - player->stream_settings.encoding_mode = - UNIPERIF_IEC958_ENCODING_MODE_ENCODED; - else - player->stream_settings.encoding_mode = - UNIPERIF_IEC958_ENCODING_MODE_PCM; - - if (player->stream_settings.encoding_mode == - UNIPERIF_IEC958_ENCODING_MODE_PCM) - /* Clear user validity bits */ - SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0); - else - /* Set user validity bits */ - SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1); - - /* Program the new channel status */ - for (n = 0; n < 6; ++n) { - status = - player->stream_settings.iec958.status[0 + (n * 4)] & 0xf; - status |= - player->stream_settings.iec958.status[1 + (n * 4)] << 8; - status |= - player->stream_settings.iec958.status[2 + (n * 4)] << 16; - status |= - player->stream_settings.iec958.status[3 + (n * 4)] << 24; - SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status); - } - - /* Update the channel status */ - if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player); - else - SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player); -} - -static int uni_player_prepare_iec958(struct uniperif *player, - struct snd_pcm_runtime *runtime) -{ - int clk_div; - - clk_div = player->mclk / runtime->rate; - - /* Oversampling must be multiple of 128 as iec958 frame is 32-bits */ - if ((clk_div % 128) || (clk_div <= 0)) { - dev_err(player->dev, "%s: invalid clk_div %d\n", - __func__, clk_div); - return -EINVAL; - } - - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - /* 16/16 memory format */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player); - /* 16-bits per sub-frame */ - SET_UNIPERIF_I2S_FMT_NBIT_32(player); - /* Set 16-bit sample precision */ - SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player); - break; - case SNDRV_PCM_FORMAT_S32_LE: - /* 16/0 memory format */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player); - /* 32-bits per sub-frame */ - SET_UNIPERIF_I2S_FMT_NBIT_32(player); - /* Set 24-bit sample precision */ - SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player); - break; - default: - dev_err(player->dev, "format not supported\n"); - return -EINVAL; - } - - /* Set parity to be calculated by the hardware */ - SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player); - - /* Set channel status bits to be inserted by the hardware */ - SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player); - - /* Set user data bits to be inserted by the hardware */ - SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player); - - /* Set validity bits to be inserted by the hardware */ - SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player); - - /* Set full software control to disabled */ - SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player); - - SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player); - - mutex_lock(&player->ctrl_lock); - /* Update the channel status */ - uni_player_set_channel_status(player, runtime); - mutex_unlock(&player->ctrl_lock); - - /* Clear the user validity user bits */ - SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0); - - /* Disable one-bit audio mode */ - SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player); - - /* Enable consecutive frames repetition of Z preamble (not for HBRA) */ - SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player); - - /* Change to SUF0_SUBF1 and left/right channels swap! */ - SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player); - - /* Set data output as MSB first */ - SET_UNIPERIF_I2S_FMT_ORDER_MSB(player); - - if (player->stream_settings.encoding_mode == - UNIPERIF_IEC958_ENCODING_MODE_ENCODED) - SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player); - else - SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player); - - SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2); - - /* Set rounding to off */ - SET_UNIPERIF_CTRL_ROUNDING_OFF(player); - - /* Set clock divisor */ - SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128); - - /* Set the spdif latency to not wait before starting player */ - SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player); - - /* - * Ensure iec958 formatting is off. It will be enabled in function - * uni_player_start() at the same time as the operation - * mode is set to work around a silicon issue. - */ - if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player); - else - SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player); - - return 0; -} - -static int uni_player_prepare_pcm(struct uniperif *player, - struct snd_pcm_runtime *runtime) -{ - int output_frame_size, slot_width, clk_div; - - /* Force slot width to 32 in I2S mode (HW constraint) */ - if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == - SND_SOC_DAIFMT_I2S) - slot_width = 32; - else - slot_width = snd_pcm_format_width(runtime->format); - - output_frame_size = slot_width * runtime->channels; - - clk_div = player->mclk / runtime->rate; - /* - * For 32 bits subframe clk_div must be a multiple of 128, - * for 16 bits must be a multiple of 64 - */ - if ((slot_width == 32) && (clk_div % 128)) { - dev_err(player->dev, "%s: invalid clk_div\n", __func__); - return -EINVAL; - } - - if ((slot_width == 16) && (clk_div % 64)) { - dev_err(player->dev, "%s: invalid clk_div\n", __func__); - return -EINVAL; - } - - /* - * Number of bits per subframe (which is one channel sample) - * on output - Transfer 16 or 32 bits from FIFO - */ - switch (slot_width) { - case 32: - SET_UNIPERIF_I2S_FMT_NBIT_32(player); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player); - break; - case 16: - SET_UNIPERIF_I2S_FMT_NBIT_16(player); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player); - break; - default: - dev_err(player->dev, "subframe format not supported\n"); - return -EINVAL; - } - - /* Configure data memory format */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - /* One data word contains two samples */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player); - break; - - case SNDRV_PCM_FORMAT_S32_LE: - /* - * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits - * on the left than zeros (if less than 32 bytes)"... ;-) - */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player); - break; - - default: - dev_err(player->dev, "format not supported\n"); - return -EINVAL; - } - - /* Set rounding to off */ - SET_UNIPERIF_CTRL_ROUNDING_OFF(player); - - /* Set clock divisor */ - SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size)); - - /* Number of channelsmust be even*/ - if ((runtime->channels % 2) || (runtime->channels < 2) || - (runtime->channels > 10)) { - dev_err(player->dev, "%s: invalid nb of channels\n", __func__); - return -EINVAL; - } - - SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2); - - /* Set 1-bit audio format to disabled */ - SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player); - - SET_UNIPERIF_I2S_FMT_ORDER_MSB(player); - - /* No iec958 formatting as outputting to DAC */ - SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player); - - return 0; -} - -static int uni_player_prepare_tdm(struct uniperif *player, - struct snd_pcm_runtime *runtime) -{ - int tdm_frame_size; /* unip tdm frame size in bytes */ - int user_frame_size; /* user tdm frame size in bytes */ - /* default unip TDM_WORD_POS_X_Y */ - unsigned int word_pos[4] = { - 0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A}; - int freq, ret; - - tdm_frame_size = - sti_uniperiph_get_unip_tdm_frame_size(player); - user_frame_size = - sti_uniperiph_get_user_frame_size(runtime); - - /* fix 16/0 format */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player); - - /* number of words inserted on the TDM line */ - SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2); - - SET_UNIPERIF_I2S_FMT_ORDER_MSB(player); - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player); - - /* Enable the tdm functionality */ - SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player); - - /* number of 8 bits timeslots avail in unip tdm frame */ - SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player, tdm_frame_size); - - /* set the timeslot allocation for words in FIFO */ - sti_uniperiph_get_tdm_word_pos(player, word_pos); - SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]); - SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]); - SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]); - SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]); - - /* set unip clk rate (not done vai set_sysclk ops) */ - freq = runtime->rate * tdm_frame_size * 8; - mutex_lock(&player->ctrl_lock); - ret = uni_player_clk_set_rate(player, freq); - if (!ret) - player->mclk = freq; - mutex_unlock(&player->ctrl_lock); - - return 0; -} - -/* - * ALSA uniperipheral iec958 controls - */ -static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - - return 0; -} - -static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958; - - mutex_lock(&player->ctrl_lock); - ucontrol->value.iec958.status[0] = iec958->status[0]; - ucontrol->value.iec958.status[1] = iec958->status[1]; - ucontrol->value.iec958.status[2] = iec958->status[2]; - ucontrol->value.iec958.status[3] = iec958->status[3]; - mutex_unlock(&player->ctrl_lock); - return 0; -} - -static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958; - unsigned long flags; - - mutex_lock(&player->ctrl_lock); - iec958->status[0] = ucontrol->value.iec958.status[0]; - iec958->status[1] = ucontrol->value.iec958.status[1]; - iec958->status[2] = ucontrol->value.iec958.status[2]; - iec958->status[3] = ucontrol->value.iec958.status[3]; - - spin_lock_irqsave(&player->irq_lock, flags); - if (player->substream && player->substream->runtime) - uni_player_set_channel_status(player, - player->substream->runtime); - else - uni_player_set_channel_status(player, NULL); - - spin_unlock_irqrestore(&player->irq_lock, flags); - mutex_unlock(&player->ctrl_lock); - - return 0; -} - -static struct snd_kcontrol_new uni_player_iec958_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .info = uni_player_ctl_iec958_info, - .get = uni_player_ctl_iec958_get, - .put = uni_player_ctl_iec958_put, -}; - -/* - * uniperif rate adjustement control - */ -static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN; - uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX; - uinfo->value.integer.step = 1; - - return 0; -} - -static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - - mutex_lock(&player->ctrl_lock); - ucontrol->value.integer.value[0] = player->clk_adj; - mutex_unlock(&player->ctrl_lock); - - return 0; -} - -static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol); - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - int ret = 0; - - if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) || - (ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX)) - return -EINVAL; - - mutex_lock(&player->ctrl_lock); - player->clk_adj = ucontrol->value.integer.value[0]; - - if (player->mclk) - ret = uni_player_clk_set_rate(player, player->mclk); - mutex_unlock(&player->ctrl_lock); - - return ret; -} - -static struct snd_kcontrol_new uni_player_clk_adj_ctl = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "PCM Playback Oversampling Freq. Adjustment", - .info = snd_sti_clk_adjustment_info, - .get = snd_sti_clk_adjustment_get, - .put = snd_sti_clk_adjustment_put, -}; - -static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = { - &uni_player_clk_adj_ctl, -}; - -static struct snd_kcontrol_new *snd_sti_iec_ctl[] = { - &uni_player_iec958_ctl, - &uni_player_clk_adj_ctl, -}; - -static int uni_player_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - unsigned long flags; - int ret; - - spin_lock_irqsave(&player->irq_lock, flags); - player->substream = substream; - spin_unlock_irqrestore(&player->irq_lock, flags); - - player->clk_adj = 0; - - if (!UNIPERIF_TYPE_IS_TDM(player)) - return 0; - - /* refine hw constraint in tdm mode */ - ret = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - sti_uniperiph_fix_tdm_chan, - player, SNDRV_PCM_HW_PARAM_CHANNELS, - -1); - if (ret < 0) - return ret; - - return snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - sti_uniperiph_fix_tdm_format, - player, SNDRV_PCM_HW_PARAM_FORMAT, - -1); -} - -static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - int ret; - - if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN)) - return 0; - - if (clk_id != 0) - return -EINVAL; - - mutex_lock(&player->ctrl_lock); - ret = uni_player_clk_set_rate(player, freq); - if (!ret) - player->mclk = freq; - mutex_unlock(&player->ctrl_lock); - - return ret; -} - -static int uni_player_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - struct snd_pcm_runtime *runtime = substream->runtime; - int transfer_size, trigger_limit; - int ret; - - /* The player should be stopped */ - if (player->state != UNIPERIF_STATE_STOPPED) { - dev_err(player->dev, "%s: invalid player state %d\n", __func__, - player->state); - return -EINVAL; - } - - /* Calculate transfer size (in fifo cells and bytes) for frame count */ - if (player->type == SND_ST_UNIPERIF_TYPE_TDM) { - /* transfer size = user frame size (in 32 bits FIFO cell) */ - transfer_size = - sti_uniperiph_get_user_frame_size(runtime) / 4; - } else { - transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES; - } - - /* Calculate number of empty cells available before asserting DREQ */ - if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) { - trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size; - } else { - /* - * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 - * FDMA_TRIGGER_LIMIT also controls when the state switches - * from OFF or STANDBY to AUDIO DATA. - */ - trigger_limit = transfer_size; - } - - /* Trigger limit must be an even number */ - if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) || - (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) { - dev_err(player->dev, "invalid trigger limit %d\n", - trigger_limit); - return -EINVAL; - } - - SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit); - - /* Uniperipheral setup depends on player type */ - switch (player->type) { - case SND_ST_UNIPERIF_TYPE_HDMI: - ret = uni_player_prepare_iec958(player, runtime); - break; - case SND_ST_UNIPERIF_TYPE_PCM: - ret = uni_player_prepare_pcm(player, runtime); - break; - case SND_ST_UNIPERIF_TYPE_SPDIF: - ret = uni_player_prepare_iec958(player, runtime); - break; - case SND_ST_UNIPERIF_TYPE_TDM: - ret = uni_player_prepare_tdm(player, runtime); - break; - default: - dev_err(player->dev, "invalid player type\n"); - return -EINVAL; - } - - if (ret) - return ret; - - switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player); - break; - case SND_SOC_DAIFMT_NB_IF: - SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player); - break; - case SND_SOC_DAIFMT_IB_NF: - SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player); - break; - case SND_SOC_DAIFMT_IB_IF: - SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player); - break; - } - - switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player); - SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player); - break; - case SND_SOC_DAIFMT_LEFT_J: - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player); - SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player); - break; - case SND_SOC_DAIFMT_RIGHT_J: - SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player); - SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player); - break; - default: - dev_err(player->dev, "format not supported\n"); - return -EINVAL; - } - - SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0); - - - return sti_uniperiph_reset(player); -} - -static int uni_player_start(struct uniperif *player) -{ - int ret; - - /* The player should be stopped */ - if (player->state != UNIPERIF_STATE_STOPPED) { - dev_err(player->dev, "%s: invalid player state\n", __func__); - return -EINVAL; - } - - ret = clk_prepare_enable(player->clk); - if (ret) { - dev_err(player->dev, "%s: Failed to enable clock\n", __func__); - return ret; - } - - /* Clear any pending interrupts */ - SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player)); - - /* Set the interrupt mask */ - SET_UNIPERIF_ITM_BSET_DMA_ERROR(player); - SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player); - - /* Enable underflow recovery interrupts */ - if (player->underflow_enabled) { - SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player); - SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player); - } - - ret = sti_uniperiph_reset(player); - if (ret < 0) { - clk_disable_unprepare(player->clk); - return ret; - } - - /* - * Does not use IEC61937 features of the uniperipheral hardware. - * Instead it performs IEC61937 in software and inserts it directly - * into the audio data stream. As such, when encoded mode is selected, - * linear pcm mode is still used, but with the differences of the - * channel status bits set for encoded mode and the validity bits set. - */ - SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player); - - /* - * If iec958 formatting is required for hdmi or spdif, then it must be - * enabled after the operation mode is set. If set prior to this, it - * will not take affect and hang the player. - */ - if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - if (UNIPERIF_TYPE_IS_IEC958(player)) - SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player); - - /* Force channel status update (no update if clk disable) */ - if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player); - else - SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player); - - /* Update state to started */ - player->state = UNIPERIF_STATE_STARTED; - - return 0; -} - -static int uni_player_stop(struct uniperif *player) -{ - int ret; - - /* The player should not be in stopped state */ - if (player->state == UNIPERIF_STATE_STOPPED) { - dev_err(player->dev, "%s: invalid player state\n", __func__); - return -EINVAL; - } - - /* Turn the player off */ - SET_UNIPERIF_CTRL_OPERATION_OFF(player); - - ret = sti_uniperiph_reset(player); - if (ret < 0) - return ret; - - /* Disable interrupts */ - SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player)); - - /* Disable clock */ - clk_disable_unprepare(player->clk); - - /* Update state to stopped and return */ - player->state = UNIPERIF_STATE_STOPPED; - - return 0; -} - -int uni_player_resume(struct uniperif *player) -{ - int ret; - - /* Select the frequency synthesizer clock */ - if (player->clk_sel) { - ret = regmap_field_write(player->clk_sel, 1); - if (ret) { - dev_err(player->dev, - "%s: Failed to select freq synth clock\n", - __func__); - return ret; - } - } - - SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player); - SET_UNIPERIF_CTRL_ROUNDING_OFF(player); - SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player); - SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player); - - return 0; -} -EXPORT_SYMBOL_GPL(uni_player_resume); - -static int uni_player_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - return uni_player_start(player); - case SNDRV_PCM_TRIGGER_STOP: - return uni_player_stop(player); - case SNDRV_PCM_TRIGGER_RESUME: - return uni_player_resume(player); - default: - return -EINVAL; - } -} - -static void uni_player_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *player = priv->dai_data.uni; - unsigned long flags; - - spin_lock_irqsave(&player->irq_lock, flags); - if (player->state != UNIPERIF_STATE_STOPPED) - /* Stop the player */ - uni_player_stop(player); - - player->substream = NULL; - spin_unlock_irqrestore(&player->irq_lock, flags); -} - -static int uni_player_parse_dt_audio_glue(struct platform_device *pdev, - struct uniperif *player) -{ - struct device_node *node = pdev->dev.of_node; - struct regmap *regmap; - struct reg_field regfield[2] = { - /* PCM_CLK_SEL */ - REG_FIELD(SYS_CFG_AUDIO_GLUE, - 8 + player->id, - 8 + player->id), - /* PCMP_VALID_SEL */ - REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1) - }; - - regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg"); - - if (IS_ERR(regmap)) { - dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n"); - return PTR_ERR(regmap); - } - - player->clk_sel = regmap_field_alloc(regmap, regfield[0]); - player->valid_sel = regmap_field_alloc(regmap, regfield[1]); - - return 0; -} - -static const struct snd_soc_dai_ops uni_player_dai_ops = { - .startup = uni_player_startup, - .shutdown = uni_player_shutdown, - .prepare = uni_player_prepare, - .trigger = uni_player_trigger, - .hw_params = sti_uniperiph_dai_hw_params, - .set_fmt = sti_uniperiph_dai_set_fmt, - .set_sysclk = uni_player_set_sysclk, - .set_tdm_slot = sti_uniperiph_set_tdm_slot -}; - -int uni_player_init(struct platform_device *pdev, - struct uniperif *player) -{ - int ret = 0; - - player->dev = &pdev->dev; - player->state = UNIPERIF_STATE_STOPPED; - player->dai_ops = &uni_player_dai_ops; - - /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */ - ret = uni_player_parse_dt_audio_glue(pdev, player); - - if (ret < 0) { - dev_err(player->dev, "Failed to parse DeviceTree\n"); - return ret; - } - - /* Underflow recovery is only supported on later ip revisions */ - if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - player->underflow_enabled = 1; - - if (UNIPERIF_TYPE_IS_TDM(player)) - player->hw = &uni_tdm_hw; - else - player->hw = &uni_player_pcm_hw; - - /* Get uniperif resource */ - player->clk = of_clk_get(pdev->dev.of_node, 0); - if (IS_ERR(player->clk)) { - dev_err(player->dev, "Failed to get clock\n"); - return PTR_ERR(player->clk); - } - - /* Select the frequency synthesizer clock */ - if (player->clk_sel) { - ret = regmap_field_write(player->clk_sel, 1); - if (ret) { - dev_err(player->dev, - "%s: Failed to select freq synth clock\n", - __func__); - return ret; - } - } - - /* connect to I2S/TDM TX bus */ - if (player->valid_sel && - (player->id == UNIPERIF_PLAYER_I2S_OUT)) { - ret = regmap_field_write(player->valid_sel, player->id); - if (ret) { - dev_err(player->dev, - "%s: unable to connect to tdm bus\n", __func__); - return ret; - } - } - - ret = devm_request_irq(&pdev->dev, player->irq, - uni_player_irq_handler, IRQF_SHARED, - dev_name(&pdev->dev), player); - if (ret < 0) { - dev_err(player->dev, "unable to request IRQ %d\n", player->irq); - return ret; - } - - mutex_init(&player->ctrl_lock); - spin_lock_init(&player->irq_lock); - - /* Ensure that disabled by default */ - SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player); - SET_UNIPERIF_CTRL_ROUNDING_OFF(player); - SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player); - SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player); - - if (UNIPERIF_TYPE_IS_IEC958(player)) { - /* Set default iec958 status bits */ - - /* Consumer, PCM, copyright, 2ch, mode 0 */ - player->stream_settings.iec958.status[0] = 0x00; - /* Broadcast reception category */ - player->stream_settings.iec958.status[1] = - IEC958_AES1_CON_GENERAL; - /* Do not take into account source or channel number */ - player->stream_settings.iec958.status[2] = - IEC958_AES2_CON_SOURCE_UNSPEC; - /* Sampling frequency not indicated */ - player->stream_settings.iec958.status[3] = - IEC958_AES3_CON_FS_NOTID; - /* Max sample word 24-bit, sample word length not indicated */ - player->stream_settings.iec958.status[4] = - IEC958_AES4_CON_MAX_WORDLEN_24 | - IEC958_AES4_CON_WORDLEN_24_20; - - player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl); - player->snd_ctrls = snd_sti_iec_ctl[0]; - } else { - player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl); - player->snd_ctrls = snd_sti_pcm_ctl[0]; - } - - return 0; -} -EXPORT_SYMBOL_GPL(uni_player_init); diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c deleted file mode 100644 index 136059331211..000000000000 --- a/sound/soc/sti/uniperif_reader.c +++ /dev/null @@ -1,436 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) STMicroelectronics SA 2015 - * Authors: Arnaud Pouliquen arnaud.pouliquen@st.com - * for STMicroelectronics. - */ - -#include <sound/soc.h> - -#include "uniperif.h" - -#define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX bus */ -/* - * Note: snd_pcm_hardware is linked to DMA controller but is declared here to - * integrate unireader capability in term of rate and supported channels - */ -static const struct snd_pcm_hardware uni_reader_pcm_hw = { - .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 8000, - .rate_max = 96000, - - .channels_min = 2, - .channels_max = 8, - - .periods_min = 2, - .periods_max = 48, - - .period_bytes_min = 128, - .period_bytes_max = 64 * PAGE_SIZE, - .buffer_bytes_max = 256 * PAGE_SIZE -}; - -/* - * uni_reader_irq_handler - * In case of error audio stream is stopped; stop action is protected via PCM - * stream lock to avoid race condition with trigger callback. - */ -static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id) -{ - irqreturn_t ret = IRQ_NONE; - struct uniperif *reader = dev_id; - unsigned int status; - - spin_lock(&reader->irq_lock); - if (!reader->substream) - goto irq_spin_unlock; - - snd_pcm_stream_lock(reader->substream); - if (reader->state == UNIPERIF_STATE_STOPPED) { - /* Unexpected IRQ: do nothing */ - dev_warn(reader->dev, "unexpected IRQ\n"); - goto stream_unlock; - } - - /* Get interrupt status & clear them immediately */ - status = GET_UNIPERIF_ITS(reader); - SET_UNIPERIF_ITS_BCLR(reader, status); - - /* Check for fifo overflow error */ - if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) { - dev_err(reader->dev, "FIFO error detected\n"); - - snd_pcm_stop_xrun(reader->substream); - - ret = IRQ_HANDLED; - } - -stream_unlock: - snd_pcm_stream_unlock(reader->substream); -irq_spin_unlock: - spin_unlock(&reader->irq_lock); - - return ret; -} - -static int uni_reader_prepare_pcm(struct snd_pcm_runtime *runtime, - struct uniperif *reader) -{ - int slot_width; - - /* Force slot width to 32 in I2S mode */ - if ((reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) - == SND_SOC_DAIFMT_I2S) { - slot_width = 32; - } else { - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - slot_width = 16; - break; - default: - slot_width = 32; - break; - } - } - - /* Number of bits per subframe (i.e one channel sample) on input. */ - switch (slot_width) { - case 32: - SET_UNIPERIF_I2S_FMT_NBIT_32(reader); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader); - break; - case 16: - SET_UNIPERIF_I2S_FMT_NBIT_16(reader); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(reader); - break; - default: - dev_err(reader->dev, "subframe format not supported\n"); - return -EINVAL; - } - - /* Configure data memory format */ - switch (runtime->format) { - case SNDRV_PCM_FORMAT_S16_LE: - /* One data word contains two samples */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_16(reader); - break; - - case SNDRV_PCM_FORMAT_S32_LE: - /* - * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits - * on the MSB then zeros (if less than 32 bytes)"... - */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader); - break; - - default: - dev_err(reader->dev, "format not supported\n"); - return -EINVAL; - } - - /* Number of channels must be even */ - if ((runtime->channels % 2) || (runtime->channels < 2) || - (runtime->channels > 10)) { - dev_err(reader->dev, "%s: invalid nb of channels\n", __func__); - return -EINVAL; - } - - SET_UNIPERIF_I2S_FMT_NUM_CH(reader, runtime->channels / 2); - SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader); - - return 0; -} - -static int uni_reader_prepare_tdm(struct snd_pcm_runtime *runtime, - struct uniperif *reader) -{ - int frame_size; /* user tdm frame size in bytes */ - /* default unip TDM_WORD_POS_X_Y */ - unsigned int word_pos[4] = { - 0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A}; - - frame_size = sti_uniperiph_get_user_frame_size(runtime); - - /* fix 16/0 format */ - SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader); - SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader); - - /* number of words inserted on the TDM line */ - SET_UNIPERIF_I2S_FMT_NUM_CH(reader, frame_size / 4 / 2); - - SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader); - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader); - SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(reader); - - /* - * set the timeslots allocation for words in FIFO - * - * HW bug: (LSB word < MSB word) => this config is not possible - * So if we want (LSB word < MSB) word, then it shall be - * handled by user - */ - sti_uniperiph_get_tdm_word_pos(reader, word_pos); - SET_UNIPERIF_TDM_WORD_POS(reader, 1_2, word_pos[WORD_1_2]); - SET_UNIPERIF_TDM_WORD_POS(reader, 3_4, word_pos[WORD_3_4]); - SET_UNIPERIF_TDM_WORD_POS(reader, 5_6, word_pos[WORD_5_6]); - SET_UNIPERIF_TDM_WORD_POS(reader, 7_8, word_pos[WORD_7_8]); - - return 0; -} - -static int uni_reader_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *reader = priv->dai_data.uni; - struct snd_pcm_runtime *runtime = substream->runtime; - int transfer_size, trigger_limit, ret; - - /* The reader should be stopped */ - if (reader->state != UNIPERIF_STATE_STOPPED) { - dev_err(reader->dev, "%s: invalid reader state %d\n", __func__, - reader->state); - return -EINVAL; - } - - /* Calculate transfer size (in fifo cells and bytes) for frame count */ - if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) { - /* transfer size = unip frame size (in 32 bits FIFO cell) */ - transfer_size = - sti_uniperiph_get_user_frame_size(runtime) / 4; - } else { - transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES; - } - - /* Calculate number of empty cells available before asserting DREQ */ - if (reader->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) - trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size; - else - /* - * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 - * FDMA_TRIGGER_LIMIT also controls when the state switches - * from OFF or STANDBY to AUDIO DATA. - */ - trigger_limit = transfer_size; - - /* Trigger limit must be an even number */ - if ((!trigger_limit % 2) || - (trigger_limit != 1 && transfer_size % 2) || - (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(reader))) { - dev_err(reader->dev, "invalid trigger limit %d\n", - trigger_limit); - return -EINVAL; - } - - SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(reader, trigger_limit); - - if (UNIPERIF_TYPE_IS_TDM(reader)) - ret = uni_reader_prepare_tdm(runtime, reader); - else - ret = uni_reader_prepare_pcm(runtime, reader); - if (ret) - return ret; - - switch (reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader); - SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(reader); - break; - case SND_SOC_DAIFMT_LEFT_J: - SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader); - SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader); - break; - case SND_SOC_DAIFMT_RIGHT_J: - SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(reader); - SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader); - break; - default: - dev_err(reader->dev, "format not supported\n"); - return -EINVAL; - } - - /* Data clocking (changing) on the rising/falling edge */ - switch (reader->daifmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader); - break; - case SND_SOC_DAIFMT_NB_IF: - SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader); - break; - case SND_SOC_DAIFMT_IB_NF: - SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader); - break; - case SND_SOC_DAIFMT_IB_IF: - SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader); - SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader); - break; - } - - /* Clear any pending interrupts */ - SET_UNIPERIF_ITS_BCLR(reader, GET_UNIPERIF_ITS(reader)); - - SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(reader, 0); - - /* Set the interrupt mask */ - SET_UNIPERIF_ITM_BSET_DMA_ERROR(reader); - SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader); - SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader); - - /* Enable underflow recovery interrupts */ - if (reader->underflow_enabled) { - SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader); - SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader); - } - - /* Reset uniperipheral reader */ - return sti_uniperiph_reset(reader); -} - -static int uni_reader_start(struct uniperif *reader) -{ - /* The reader should be stopped */ - if (reader->state != UNIPERIF_STATE_STOPPED) { - dev_err(reader->dev, "%s: invalid reader state\n", __func__); - return -EINVAL; - } - - /* Enable reader interrupts (and clear possible stalled ones) */ - SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(reader); - SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader); - - /* Launch the reader */ - SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(reader); - - /* Update state to started */ - reader->state = UNIPERIF_STATE_STARTED; - return 0; -} - -static int uni_reader_stop(struct uniperif *reader) -{ - /* The reader should not be in stopped state */ - if (reader->state == UNIPERIF_STATE_STOPPED) { - dev_err(reader->dev, "%s: invalid reader state\n", __func__); - return -EINVAL; - } - - /* Turn the reader off */ - SET_UNIPERIF_CTRL_OPERATION_OFF(reader); - - /* Disable interrupts */ - SET_UNIPERIF_ITM_BCLR(reader, GET_UNIPERIF_ITM(reader)); - - /* Update state to stopped and return */ - reader->state = UNIPERIF_STATE_STOPPED; - - return 0; -} - -static int uni_reader_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *reader = priv->dai_data.uni; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - return uni_reader_start(reader); - case SNDRV_PCM_TRIGGER_STOP: - return uni_reader_stop(reader); - default: - return -EINVAL; - } -} - -static int uni_reader_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *reader = priv->dai_data.uni; - unsigned long flags; - int ret; - - spin_lock_irqsave(&reader->irq_lock, flags); - reader->substream = substream; - spin_unlock_irqrestore(&reader->irq_lock, flags); - - if (!UNIPERIF_TYPE_IS_TDM(reader)) - return 0; - - /* refine hw constraint in tdm mode */ - ret = snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_CHANNELS, - sti_uniperiph_fix_tdm_chan, - reader, SNDRV_PCM_HW_PARAM_CHANNELS, - -1); - if (ret < 0) - return ret; - - return snd_pcm_hw_rule_add(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_FORMAT, - sti_uniperiph_fix_tdm_format, - reader, SNDRV_PCM_HW_PARAM_FORMAT, - -1); -} - -static void uni_reader_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai); - struct uniperif *reader = priv->dai_data.uni; - unsigned long flags; - - spin_lock_irqsave(&reader->irq_lock, flags); - if (reader->state != UNIPERIF_STATE_STOPPED) { - /* Stop the reader */ - uni_reader_stop(reader); - } - reader->substream = NULL; - spin_unlock_irqrestore(&reader->irq_lock, flags); -} - -static const struct snd_soc_dai_ops uni_reader_dai_ops = { - .startup = uni_reader_startup, - .shutdown = uni_reader_shutdown, - .prepare = uni_reader_prepare, - .trigger = uni_reader_trigger, - .hw_params = sti_uniperiph_dai_hw_params, - .set_fmt = sti_uniperiph_dai_set_fmt, - .set_tdm_slot = sti_uniperiph_set_tdm_slot -}; - -int uni_reader_init(struct platform_device *pdev, - struct uniperif *reader) -{ - int ret = 0; - - reader->dev = &pdev->dev; - reader->state = UNIPERIF_STATE_STOPPED; - reader->dai_ops = &uni_reader_dai_ops; - - if (UNIPERIF_TYPE_IS_TDM(reader)) - reader->hw = &uni_tdm_hw; - else - reader->hw = &uni_reader_pcm_hw; - - ret = devm_request_irq(&pdev->dev, reader->irq, - uni_reader_irq_handler, IRQF_SHARED, - dev_name(&pdev->dev), reader); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to request IRQ\n"); - return -EBUSY; - } - - spin_lock_init(&reader->irq_lock); - - return 0; -} -EXPORT_SYMBOL_GPL(uni_reader_init);
On Tue, 15 Mar 2022 10:13:19 +0100, Daniel Palmer wrote:
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Mea culpa, that was an obvious deadlock I overlooked in the patch series.
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com
I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
Yeah, that looks dead.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
thanks,
Takashi
.../bindings/sound/st,sti-asoc-card.txt | 164 -- MAINTAINERS | 7 - sound/soc/sti/Kconfig | 12 - sound/soc/sti/Makefile | 5 - sound/soc/sti/sti_uniperif.c | 506 ------ sound/soc/sti/uniperif.h | 1416 ----------------- sound/soc/sti/uniperif_player.c | 1148 ------------- sound/soc/sti/uniperif_reader.c | 436 ----- 8 files changed, 3694 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt delete mode 100644 sound/soc/sti/Kconfig delete mode 100644 sound/soc/sti/Makefile delete mode 100644 sound/soc/sti/sti_uniperif.c delete mode 100644 sound/soc/sti/uniperif.h delete mode 100644 sound/soc/sti/uniperif_player.c delete mode 100644 sound/soc/sti/uniperif_reader.c
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt deleted file mode 100644 index a6ffcdec6f6a..000000000000 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ /dev/null @@ -1,164 +0,0 @@ -STMicroelectronics sti ASoC cards
-The sti ASoC Sound Card can be used, for all sti SoCs using internal sti-sas -codec or external codecs.
-sti sound drivers allows to expose sti SoC audio interface through the -generic ASoC simple card. For details about sound card declaration please refer to -Documentation/devicetree/bindings/sound/simple-card.yaml.
-1) sti-uniperiph-dai: audio dai device.
-Required properties:
- compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out",
"st,stih407-uni-player-dac", "st,stih407-uni-player-spdif",
"st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi",
- st,syscfg: phandle to boot-device system configuration registers
- clock-names: name of the clocks listed in clocks property in the same order
- reg: CPU DAI IP Base address and size entries, listed in same
order than the CPU_DAI properties.
- reg-names: names of the mapped memory regions listed in regs property in
the same order.
- interrupts: CPU_DAI interrupt line, listed in the same order than the
CPU_DAI properties.
- dma: CPU_DAI DMA controller phandle and DMA request line, listed in the same
order than the CPU_DAI properties.
- dma-names: identifier string for each DMA request line in the dmas property.
- "tx" for "st,sti-uni-player" compatibility
- "rx" for "st,sti-uni-reader" compatibility
-Required properties ("st,sti-uni-player" compatibility only):
- clocks: CPU_DAI IP clock source, listed in the same order than the
CPU_DAI properties.
-Optional properties:
- pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for
external codecs connection.
- pinctrl-names: should contain only one value - "default".
- st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs.
- Only compartible with IPs in charge of the external I2S/TDM bus.
- Should be declared depending on associated codec.
-Example:
- sti_uni_player1: sti-uni-player@8d81000 {
compatible = "st,stih407-uni-player-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
reg = <0x8D81000 0x158>;
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
dmas = <&fdma0 3 0 1>;
dma-names = "tx";
st,tdm-mode = <1>;
- };
- sti_uni_player2: sti-uni-player@8d82000 {
compatible = "st,stih407-uni-player-pcm-out";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
reg = <0x8D82000 0x158>;
interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
dmas = <&fdma0 4 0 1>;
dma-names = "tx";
- };
- sti_uni_player3: sti-uni-player@8d85000 {
compatible = "st,stih407-uni-player-spdif";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
reg = <0x8D85000 0x158>;
interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
dmas = <&fdma0 7 0 1>;
dma-names = "tx";
- };
- sti_uni_reader1: sti-uni-reader@8d84000 {
compatible = "st,stih407-uni-reader-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
reg = <0x8D84000 0x158>;
interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
dmas = <&fdma0 6 0 1>;
dma-names = "rx";
- };
-2) sti-sas-codec: internal audio codec IPs driver
-Required properties:
- compatible: "st,sti<chip>-sas-codec" .
- Should be chip "st,stih416-sas-codec" or "st,stih407-sas-codec"
- st,syscfg: phandle to boot-device system configuration registers.
- pinctrl-0: SPDIF PIO description.
- pinctrl-names: should contain only one value - "default".
-Example:
- sti_sas_codec: sti-sas-codec {
compatible = "st,stih407-sas-codec";
#sound-dai-cells = <1>;
st,reg_audio = <&syscfg_core>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdif_out >;
- };
-Example of audio card declaration:
- sound {
compatible = "simple-audio-card";
simple-audio-card,name = "sti audio card";
simple-audio-card,dai-link@0 {
/* DAC */
format = "i2s";
dai-tdm-slot-width = <32>;
cpu {
sound-dai = <&sti_uni_player2>;
};
codec {
sound-dai = <&sti_sasg_codec 1>;
};
};
simple-audio-card,dai-link@1 {
/* SPDIF */
format = "left_j";
cpu {
sound-dai = <&sti_uni_player3>;
};
codec {
sound-dai = <&sti_sasg_codec 0>;
};
};
simple-audio-card,dai-link@2 {
/* TDM playback */
format = "left_j";
frame-inversion = <1>;
cpu {
sound-dai = <&sti_uni_player1>;
dai-tdm-slot-num = <16>;
dai-tdm-slot-width = <16>;
dai-tdm-slot-tx-mask =
<1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1>;
};
codec {
sound-dai = <&sti_sasg_codec 3>;
};
};
- };
diff --git a/MAINTAINERS b/MAINTAINERS index e127c2fb08a7..9dede78d02c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18465,13 +18465,6 @@ F: include/linux/static_call*.h F: kernel/jump_label.c F: kernel/static_call.c
-STI AUDIO (ASoC) DRIVERS -M: Arnaud Pouliquen arnaud.pouliquen@foss.st.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt -F: sound/soc/sti/
STI CEC DRIVER M: Alain Volmat alain.volmat@foss.st.com S: Maintained diff --git a/sound/soc/sti/Kconfig b/sound/soc/sti/Kconfig deleted file mode 100644 index f881da4b6aea..000000000000 --- a/sound/soc/sti/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# STM SoC audio configuration -# -menuconfig SND_SOC_STI
- tristate "SoC Audio support for STI System-On-Chip"
- depends on SND_SOC
- depends on ARCH_STI || COMPILE_TEST
- select SND_SOC_GENERIC_DMAENGINE_PCM
- help
Say Y if you want to enable ASoC-support for
any of the STI platforms (e.g. STIH416).
diff --git a/sound/soc/sti/Makefile b/sound/soc/sti/Makefile deleted file mode 100644 index 787ccb521298..000000000000 --- a/sound/soc/sti/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# STI platform support -snd-soc-sti-objs := sti_uniperif.o uniperif_player.o uniperif_reader.o
-obj-$(CONFIG_SND_SOC_STI) += snd-soc-sti.o diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c deleted file mode 100644 index 34668fe3909d..000000000000 --- a/sound/soc/sti/sti_uniperif.c +++ /dev/null @@ -1,506 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <linux/module.h> -#include <linux/pinctrl/consumer.h> -#include <linux/delay.h>
-#include "uniperif.h"
-/*
- User frame size shall be 2, 4, 6 or 8 32-bits words length
- (i.e. 8, 16, 24 or 32 bytes)
- This constraint comes from allowed values for
- UNIPERIF_I2S_FMT_NUM_CH register
- */
-#define UNIPERIF_MAX_FRAME_SZ 0x20 -#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 | UNIPERIF_MAX_FRAME_SZ)
-struct sti_uniperiph_dev_data {
- unsigned int id; /* Nb available player instances */
- unsigned int version; /* player IP version */
- unsigned int stream;
- const char *dai_names;
- enum uniperif_type type;
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = {
- .id = 0,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #0 (HDMI)",
- .type = SND_ST_UNIPERIF_TYPE_HDMI
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = {
- .id = 1,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #1 (PCM OUT)",
- .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_dac = {
- .id = 2,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #2 (DAC)",
- .type = SND_ST_UNIPERIF_TYPE_PCM,
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = {
- .id = 3,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #3 (SPDIF)",
- .type = SND_ST_UNIPERIF_TYPE_SPDIF
-};
-static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = {
- .id = 0,
- .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- .stream = SNDRV_PCM_STREAM_CAPTURE,
- .dai_names = "Uni Reader #0 (PCM IN)",
- .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
-};
-static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = {
- .id = 1,
- .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- .stream = SNDRV_PCM_STREAM_CAPTURE,
- .dai_names = "Uni Reader #1 (HDMI IN)",
- .type = SND_ST_UNIPERIF_TYPE_PCM,
-};
-static const struct of_device_id snd_soc_sti_match[] = {
- { .compatible = "st,stih407-uni-player-hdmi",
.data = &sti_uniplayer_hdmi
- },
- { .compatible = "st,stih407-uni-player-pcm-out",
.data = &sti_uniplayer_pcm_out
- },
- { .compatible = "st,stih407-uni-player-dac",
.data = &sti_uniplayer_dac
- },
- { .compatible = "st,stih407-uni-player-spdif",
.data = &sti_uniplayer_spdif
- },
- { .compatible = "st,stih407-uni-reader-pcm_in",
.data = &sti_unireader_pcm_in
- },
- { .compatible = "st,stih407-uni-reader-hdmi",
.data = &sti_unireader_hdmi_in
- },
- {},
-}; -MODULE_DEVICE_TABLE(of, snd_soc_sti_match);
-int sti_uniperiph_reset(struct uniperif *uni) -{
- int count = 10;
- /* Reset uniperipheral uni */
- SET_UNIPERIF_SOFT_RST_SOFT_RST(uni);
- if (uni->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
while (GET_UNIPERIF_SOFT_RST_SOFT_RST(uni) && count) {
udelay(5);
count--;
}
- }
- if (!count) {
dev_err(uni->dev, "Failed to reset uniperif\n");
return -EIO;
- }
- return 0;
-}
-int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots,
int slot_width)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- int i, frame_size, avail_slots;
- if (!UNIPERIF_TYPE_IS_TDM(uni)) {
dev_err(uni->dev, "cpu dai not in tdm mode\n");
return -EINVAL;
- }
- /* store info in unip context */
- uni->tdm_slot.slots = slots;
- uni->tdm_slot.slot_width = slot_width;
- /* unip is unidirectionnal */
- uni->tdm_slot.mask = (tx_mask != 0) ? tx_mask : rx_mask;
- /* number of available timeslots */
- for (i = 0, avail_slots = 0; i < uni->tdm_slot.slots; i++) {
if ((uni->tdm_slot.mask >> i) & 0x01)
avail_slots++;
- }
- uni->tdm_slot.avail_slots = avail_slots;
- /* frame size in bytes */
- frame_size = uni->tdm_slot.avail_slots * uni->tdm_slot.slot_width / 8;
- /* check frame size is allowed */
- if ((frame_size > UNIPERIF_MAX_FRAME_SZ) ||
(frame_size & ~(int)UNIPERIF_ALLOWED_FRAME_SZ)) {
dev_err(uni->dev, "frame size not allowed: %d bytes\n",
frame_size);
return -EINVAL;
- }
- return 0;
-}
-int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
-{
- struct uniperif *uni = rule->private;
- struct snd_interval t;
- t.min = uni->tdm_slot.avail_slots;
- t.max = uni->tdm_slot.avail_slots;
- t.openmin = 0;
- t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
-{
- struct uniperif *uni = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
- u64 format;
- switch (uni->tdm_slot.slot_width) {
- case 16:
format = SNDRV_PCM_FMTBIT_S16_LE;
break;
- case 32:
format = SNDRV_PCM_FMTBIT_S32_LE;
break;
- default:
dev_err(uni->dev, "format not supported: %d bits\n",
uni->tdm_slot.slot_width);
return -EINVAL;
- }
- maskp->bits[0] &= (u_int32_t)format;
- maskp->bits[1] &= (u_int32_t)(format >> 32);
- /* clear remaining indexes */
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX - 64) / 8);
- if (!maskp->bits[0] && !maskp->bits[1])
return -EINVAL;
- return 0;
-}
-int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni,
unsigned int *word_pos)
-{
- int slot_width = uni->tdm_slot.slot_width / 8;
- int slots_num = uni->tdm_slot.slots;
- unsigned int slots_mask = uni->tdm_slot.mask;
- int i, j, k;
- unsigned int word16_pos[4];
- /* word16_pos:
* word16_pos[0] = WORDX_LSB
* word16_pos[1] = WORDX_MSB,
* word16_pos[2] = WORDX+1_LSB
* word16_pos[3] = WORDX+1_MSB
*/
- /* set unip word position */
- for (i = 0, j = 0, k = 0; (i < slots_num) && (k < WORD_MAX); i++) {
if ((slots_mask >> i) & 0x01) {
word16_pos[j] = i * slot_width;
if (slot_width == 4) {
word16_pos[j + 1] = word16_pos[j] + 2;
j++;
}
j++;
if (j > 3) {
word_pos[k] = word16_pos[1] |
(word16_pos[0] << 8) |
(word16_pos[3] << 16) |
(word16_pos[2] << 24);
j = 0;
k++;
}
}
- }
- return 0;
-}
-/*
- sti_uniperiph_dai_create_ctrl
- This function is used to create Ctrl associated to DAI but also pcm device.
- Request is done by front end to associate ctrl with pcm device id
- */
-static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- struct snd_kcontrol_new *ctrl;
- int i;
- if (!uni->num_ctrls)
return 0;
- for (i = 0; i < uni->num_ctrls; i++) {
/*
* Several Control can have same name. Controls are indexed on
* Uniperipheral instance ID
*/
ctrl = &uni->snd_ctrls[i];
ctrl->index = uni->id;
ctrl->device = uni->id;
- }
- return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls);
-}
-/*
- DAI
- */
-int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- struct snd_dmaengine_dai_dma_data *dma_data;
- int transfer_size;
- if (uni->type == SND_ST_UNIPERIF_TYPE_TDM)
/* transfer size = user frame size (in 32-bits FIFO cell) */
transfer_size = snd_soc_params_to_frame_size(params) / 32;
- else
transfer_size = params_channels(params) * UNIPERIF_FIFO_FRAMES;
- dma_data = snd_soc_dai_get_dma_data(dai, substream);
- dma_data->maxburst = transfer_size;
- return 0;
-}
-int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- priv->dai_data.uni->daifmt = fmt;
- return 0;
-}
-static int sti_uniperiph_suspend(struct snd_soc_component *component) -{
- struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component);
- struct uniperif *uni = priv->dai_data.uni;
- int ret;
- /* The uniperipheral should be in stopped state */
- if (uni->state != UNIPERIF_STATE_STOPPED) {
dev_err(uni->dev, "%s: invalid uni state( %d)\n",
__func__, (int)uni->state);
return -EBUSY;
- }
- /* Pinctrl: switch pinstate to sleep */
- ret = pinctrl_pm_select_sleep_state(uni->dev);
- if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
- return ret;
-}
-static int sti_uniperiph_resume(struct snd_soc_component *component) -{
- struct sti_uniperiph_data *priv = snd_soc_component_get_drvdata(component);
- struct uniperif *uni = priv->dai_data.uni;
- int ret;
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = uni_player_resume(uni);
if (ret)
return ret;
- }
- /* pinctrl: switch pinstate to default */
- ret = pinctrl_pm_select_default_state(uni->dev);
- if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
- return ret;
-}
-static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct sti_uniperiph_dai *dai_data = &priv->dai_data;
- /* DMA settings*/
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL);
- else
snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data);
- dai_data->dma_data.addr = dai_data->uni->fifo_phys_address;
- dai_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- return sti_uniperiph_dai_create_ctrl(dai);
-}
-static const struct snd_soc_dai_driver sti_uniperiph_dai_template = {
- .probe = sti_uniperiph_dai_probe,
-};
-static const struct snd_soc_component_driver sti_uniperiph_dai_component = {
- .name = "sti_cpu_dai",
- .suspend = sti_uniperiph_suspend,
- .resume = sti_uniperiph_resume
-};
-static int sti_uniperiph_cpu_dai_of(struct device_node *node,
struct sti_uniperiph_data *priv)
-{
- struct device *dev = &priv->pdev->dev;
- struct sti_uniperiph_dai *dai_data = &priv->dai_data;
- struct snd_soc_dai_driver *dai = priv->dai;
- struct snd_soc_pcm_stream *stream;
- struct uniperif *uni;
- const struct of_device_id *of_id;
- const struct sti_uniperiph_dev_data *dev_data;
- const char *mode;
- int ret;
- /* Populate data structure depending on compatibility */
- of_id = of_match_node(snd_soc_sti_match, node);
- if (!of_id->data) {
dev_err(dev, "data associated to device is missing\n");
return -EINVAL;
- }
- dev_data = (struct sti_uniperiph_dev_data *)of_id->data;
- uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL);
- if (!uni)
return -ENOMEM;
- uni->id = dev_data->id;
- uni->ver = dev_data->version;
- *dai = sti_uniperiph_dai_template;
- dai->name = dev_data->dai_names;
- /* Get resources and base address */
- uni->base = devm_platform_get_and_ioremap_resource(priv->pdev, 0, &uni->mem_region);
- if (IS_ERR(uni->base))
return PTR_ERR(uni->base);
- uni->fifo_phys_address = uni->mem_region->start +
UNIPERIF_FIFO_DATA_OFFSET(uni);
- uni->irq = platform_get_irq(priv->pdev, 0);
- if (uni->irq < 0)
return -ENXIO;
- uni->type = dev_data->type;
- /* check if player should be configured for tdm */
- if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) {
if (!of_property_read_string(node, "st,tdm-mode", &mode))
uni->type = SND_ST_UNIPERIF_TYPE_TDM;
else
uni->type = SND_ST_UNIPERIF_TYPE_PCM;
- }
- dai_data->uni = uni;
- dai_data->stream = dev_data->stream;
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = uni_player_init(priv->pdev, uni);
stream = &dai->playback;
- } else {
ret = uni_reader_init(priv->pdev, uni);
stream = &dai->capture;
- }
- if (ret < 0)
return ret;
- dai->ops = uni->dai_ops;
- stream->stream_name = dai->name;
- stream->channels_min = uni->hw->channels_min;
- stream->channels_max = uni->hw->channels_max;
- stream->rates = uni->hw->rates;
- stream->formats = uni->hw->formats;
- return 0;
-}
-static const struct snd_dmaengine_pcm_config dmaengine_pcm_config = {
- .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-};
-static int sti_uniperiph_probe(struct platform_device *pdev) -{
- struct sti_uniperiph_data *priv;
- struct device_node *node = pdev->dev.of_node;
- int ret;
- /* Allocate the private data and the CPU_DAI array */
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
return -ENOMEM;
- priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL);
- if (!priv->dai)
return -ENOMEM;
- priv->pdev = pdev;
- ret = sti_uniperiph_cpu_dai_of(node, priv);
- if (ret < 0)
return ret;
- dev_set_drvdata(&pdev->dev, priv);
- ret = devm_snd_soc_register_component(&pdev->dev,
&sti_uniperiph_dai_component,
priv->dai, 1);
- if (ret < 0)
return ret;
- return devm_snd_dmaengine_pcm_register(&pdev->dev,
&dmaengine_pcm_config, 0);
-}
-static struct platform_driver sti_uniperiph_driver = {
- .driver = {
.name = "sti-uniperiph-dai",
.of_match_table = snd_soc_sti_match,
- },
- .probe = sti_uniperiph_probe,
-}; -module_platform_driver(sti_uniperiph_driver);
-MODULE_DESCRIPTION("uniperipheral DAI driver"); -MODULE_AUTHOR("Arnaud Pouliquen arnaud.pouliquen@st.com"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h deleted file mode 100644 index 2a5de328501c..000000000000 --- a/sound/soc/sti/uniperif.h +++ /dev/null @@ -1,1416 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#ifndef __SND_ST_AUD_UNIPERIF_H -#define __SND_ST_AUD_UNIPERIF_H
-#include <linux/regmap.h>
-#include <sound/dmaengine_pcm.h>
-/*
- Register access macros
- */
-#define GET_UNIPERIF_REG(ip, offset, shift, mask) \
- ((readl_relaxed(ip->base + offset) >> shift) & mask)
-#define SET_UNIPERIF_REG(ip, offset, shift, mask, value) \
- writel_relaxed(((readl_relaxed(ip->base + offset) & \
- ~(mask << shift)) | (((value) & mask) << shift)), ip->base + offset)
-#define SET_UNIPERIF_BIT_REG(ip, offset, shift, mask, value) \
- writel_relaxed((((value) & mask) << shift), ip->base + offset)
-/*
- UNIPERIF_SOFT_RST reg
- */
-#define UNIPERIF_SOFT_RST_OFFSET(ip) 0x0000 -#define GET_UNIPERIF_SOFT_RST(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
readl_relaxed(ip->base + UNIPERIF_SOFT_RST_OFFSET(ip)) : 0)
-#define SET_UNIPERIF_SOFT_RST(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_SOFT_RST_OFFSET(ip))
-/* SOFT_RST */ -#define UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip) 0x0 -#define UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip) 0x1 -#define SET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
- SET_UNIPERIF_BIT_REG(ip, \
UNIPERIF_SOFT_RST_OFFSET(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip), 1)
-#define GET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_SOFT_RST_OFFSET(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip))
-/*
- UNIPERIF_FIFO_DATA reg
- */
-#define UNIPERIF_FIFO_DATA_OFFSET(ip) 0x0004 -#define SET_UNIPERIF_DATA(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_FIFO_DATA_OFFSET(ip))
-/*
- UNIPERIF_CHANNEL_STA_REGN reg
- */
-#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip) 0x0060 -#define GET_UNIPERIF_CHANNEL_STA_REG0(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG0(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip) 0x0064 -#define GET_UNIPERIF_CHANNEL_STA_REG1(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG1(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip) 0x0068 -#define GET_UNIPERIF_CHANNEL_STA_REG2(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG2(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip) 0x006C -#define GET_UNIPERIF_CHANNEL_STA_REG3(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG3(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip) 0x0070 -#define GET_UNIPERIF_CHANNEL_STA_REG4(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG4(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip) 0x0074 -#define GET_UNIPERIF_CHANNEL_STA_REG5(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG5(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
-/*
- UNIPERIF_ITS reg
- */
-#define UNIPERIF_ITS_OFFSET(ip) 0x000C -#define GET_UNIPERIF_ITS(ip) \
- readl_relaxed(ip->base + UNIPERIF_ITS_OFFSET(ip))
-/* MEM_BLK_READ */ -#define UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITS_MEM_BLK_READ_MASK(ip) \
- (BIT(UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip)))
-/* FIFO_ERROR */ -#define UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITS_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip)))
-/* DMA_ERROR */ -#define UNIPERIF_ITS_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITS_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_DMA_ERROR_SHIFT(ip)))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip))))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-/*
- UNIPERIF_ITS_BCLR reg
- */
-/* FIFO_ERROR */ -#define UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITS_BCLR(ip, \
UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip))
-#define UNIPERIF_ITS_BCLR_OFFSET(ip) 0x0010 -#define SET_UNIPERIF_ITS_BCLR(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITS_BCLR_OFFSET(ip))
-/*
- UNIPERIF_ITM reg
- */
-#define UNIPERIF_ITM_OFFSET(ip) 0x0018 -#define GET_UNIPERIF_ITM(ip) \
- readl_relaxed(ip->base + UNIPERIF_ITM_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip)))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip))))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-/*
- UNIPERIF_ITM_BCLR reg
- */
-#define UNIPERIF_ITM_BCLR_OFFSET(ip) 0x001c -#define SET_UNIPERIF_ITM_BCLR(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITM_BCLR_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITM_BCLR(ip, \
UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip))
-/* DMA_ERROR */ -#define UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BCLR_DMA_ERROR(ip) \
- SET_UNIPERIF_ITM_BCLR(ip, \
UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip))
-/*
- UNIPERIF_ITM_BSET reg
- */
-#define UNIPERIF_ITM_BSET_OFFSET(ip) 0x0020 -#define SET_UNIPERIF_ITM_BSET(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITM_BSET_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip))
-/* MEM_BLK_READ */ -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip))
-/* DMA_ERROR */ -#define UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_DMA_ERROR(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip))))
-#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip))
-/*
- UNIPERIF_CONFIG reg
- */
-#define UNIPERIF_CONFIG_OFFSET(ip) 0x0040 -#define GET_UNIPERIF_CONFIG(ip) \
- readl_relaxed(ip->base + UNIPERIF_CONFIG_OFFSET(ip))
-#define SET_UNIPERIF_CONFIG(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CONFIG_OFFSET(ip))
-/* PARITY_CNTR */ -#define UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip) 0 -#define UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_PARITY_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 1)
-/* CHANNEL_STA_CNTR */ -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip) 1 -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 1)
-/* USER_DAT_CNTR */ -#define UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip) 2 -#define UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_USER_DAT_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 0)
-/* VALIDITY_DAT_CNTR */ -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip) 3 -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 1)
-/* ONE_BIT_AUD_SUPPORT */ -#define UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip) 4 -#define UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_ONE_BIT_AUD(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip))
-#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 1)
-/* MEMORY_FMT */ -#define UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip) 5 -#define UNIPERIF_CONFIG_MEM_FMT_MASK(ip) 0x1 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) 0 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) 1 -#define GET_UNIPERIF_CONFIG_MEM_FMT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
UNIPERIF_CONFIG_MEM_FMT_MASK(ip))
-#define SET_UNIPERIF_CONFIG_MEM_FMT(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
UNIPERIF_CONFIG_MEM_FMT_MASK(ip), value)
-#define SET_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) \
- SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip))
-#define SET_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) \
- SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip))
-/* REPEAT_CHL_STS */ -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip) 6 -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_REPEAT_CHL_STS(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip))
-#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 1)
-/* BACK_STALL_REQ */ -#define UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 7 : -1)
-#define UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_BACK_STALL_REQ(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip))
-#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 1)
-/* FDMA_TRIGGER_LIMIT */ -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip) 8 -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip) 0x7F -#define GET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip))
-#define SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip), value)
-/* CHL_STS_UPDATE */ -#define UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
-#define UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip))
-#define SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip), 1)
-/* IDLE_MOD */ -#define UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip) 18 -#define UNIPERIF_CONFIG_IDLE_MOD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_IDLE_MOD(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip))
-#define SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_IDLE_MOD_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 1)
-/* SUBFRAME_SELECTION */ -#define UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip) 19 -#define UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SUBFRAME_SEL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip))
-#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF0_SUBF1(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 0)
-/* FULL_SW_CONTROL */ -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip) 20 -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SPDIF_SW_CTRL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip))
-#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 0)
-/* MASTER_CLKEDGE */ -#define UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 24 : -1)
-#define UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_MSTR_CLKEDGE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip))
-#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_FALLING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_RISING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 0)
-/*
- UNIPERIF_CTRL reg
- */
-#define UNIPERIF_CTRL_OFFSET(ip) 0x0044 -#define GET_UNIPERIF_CTRL(ip) \
- readl_relaxed(ip->base + UNIPERIF_CTRL_OFFSET(ip))
-#define SET_UNIPERIF_CTRL(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CTRL_OFFSET(ip))
-/* OPERATION */ -#define UNIPERIF_CTRL_OPERATION_SHIFT(ip) 0 -#define UNIPERIF_CTRL_OPERATION_MASK(ip) 0x7 -#define GET_UNIPERIF_CTRL_OPERATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip) 0 -#define SET_UNIPERIF_CTRL_OPERATION_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 1 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 2 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip))
-/* This is the same as above! */ -#define VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) 4 -#define SET_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 5 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 7)
-#define SET_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip))
-/* EXIT_STBY_ON_EOBLOCK */ -#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 3)
-#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip))
-#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 1)
-/* ROUNDING */ -#define UNIPERIF_CTRL_ROUNDING_SHIFT(ip) 4 -#define UNIPERIF_CTRL_ROUNDING_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ROUNDING(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip))
-#define SET_UNIPERIF_CTRL_ROUNDING_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_ROUNDING_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip), 1)
-/* DIVIDER */ -#define UNIPERIF_CTRL_DIVIDER_SHIFT(ip) 5 -#define UNIPERIF_CTRL_DIVIDER_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_DIVIDER(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
UNIPERIF_CTRL_DIVIDER_MASK(ip))
-#define SET_UNIPERIF_CTRL_DIVIDER(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
UNIPERIF_CTRL_DIVIDER_MASK(ip), value)
-/* BYTE_SWAP */ -#define UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 13 : -1)
-#define UNIPERIF_CTRL_BYTE_SWP_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_BYTE_SWP(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip))
-#define SET_UNIPERIF_CTRL_BYTE_SWP_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_BYTE_SWP_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 1)
-/* ZERO_STUFFING_HW_SW */ -#define UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 14 : -1)
-#define UNIPERIF_CTRL_ZERO_STUFF_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ZERO_STUFF(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip))
-#define SET_UNIPERIF_CTRL_ZERO_STUFF_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_ZERO_STUFF_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 0)
-/* SPDIF_LAT */ -#define UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
-#define UNIPERIF_CTRL_SPDIF_LAT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_LAT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip))
-#define SET_UNIPERIF_CTRL_SPDIF_LAT_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 0)
-/* EN_SPDIF_FORMATTING */ -#define UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip) 17 -#define UNIPERIF_CTRL_SPDIF_FMT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_FMT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip))
-#define SET_UNIPERIF_CTRL_SPDIF_FMT_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 0)
-/* READER_OUT_SELECT */ -#define UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 18 : -1)
-#define UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_READER_OUT_SEL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip))
-#define SET_UNIPERIF_CTRL_READER_OUT_SEL_IN_MEM(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_READER_OUT_SEL_ON_I2S_LINE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 1)
-/* UNDERFLOW_REC_WINDOW */ -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip) 20 -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip))
-#define SET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip), value)
-/*
- UNIPERIF_I2S_FMT a.k.a UNIPERIF_FORMAT reg
- */
-#define UNIPERIF_I2S_FMT_OFFSET(ip) 0x0048 -#define GET_UNIPERIF_I2S_FMT(ip) \
- readl_relaxed(ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
-#define SET_UNIPERIF_I2S_FMT(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
-/* NBIT */ -#define UNIPERIF_I2S_FMT_NBIT_SHIFT(ip) 0 -#define UNIPERIF_I2S_FMT_NBIT_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_NBIT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NBIT_32(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_NBIT_16(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip), 1)
-/* DATA_SIZE */ -#define UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip) 1 -#define UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_DATA_SIZE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_18(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 1)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_20(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 2)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 3)
-#define SET_UNIPERIF_I2S_FMTL_DATA_SIZE_28(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 4)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 5)
-/* LR_POL */ -#define UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip) 4 -#define UNIPERIF_I2S_FMT_LR_POL_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_LR_POL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
UNIPERIF_I2S_FMT_LR_POL_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_LR_POL(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
UNIPERIF_I2S_FMT_LR_POL_MASK(ip), value)
-#define SET_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) \
- SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip))
-#define SET_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) \
- SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip))
-/* SCLK_EDGE */ -#define UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip) 5 -#define UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_SCLK_EDGE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 1)
-/* PADDING */ -#define UNIPERIF_I2S_FMT_PADDING_SHIFT(ip) 6 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_PADDING(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
UNIPERIF_I2S_FMT_PADDING_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_PADDING(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
UNIPERIF_I2S_FMT_PADDING_MASK(ip), value)
-#define SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) \
- SET_UNIPERIF_I2S_FMT_PADDING(ip, \
VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip))
-#define SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) \
- SET_UNIPERIF_I2S_FMT_PADDING(ip, \
VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip))
-/* ALIGN */ -#define UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip) 7 -#define UNIPERIF_I2S_FMT_ALIGN_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ALIGN(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 1)
-/* ORDER */ -#define UNIPERIF_I2S_FMT_ORDER_SHIFT(ip) 8 -#define UNIPERIF_I2S_FMT_ORDER_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ORDER(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_ORDER_LSB(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_ORDER_MSB(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip), 1)
-/* NUM_CH */ -#define UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip) 9 -#define UNIPERIF_I2S_FMT_NUM_CH_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_NUM_CH(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
UNIPERIF_I2S_FMT_NUM_CH_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NUM_CH(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
UNIPERIF_I2S_FMT_NUM_CH_MASK(ip), value)
-/* NO_OF_SAMPLES_TO_READ */ -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip) 12 -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip) 0xfffff -#define GET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip), value)
-/*
- UNIPERIF_BIT_CONTROL reg
- */
-#define UNIPERIF_BIT_CONTROL_OFFSET(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0x004c)
-#define GET_UNIPERIF_BIT_CONTROL(ip) \
- readl_relaxed(ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
-#define SET_UNIPERIF_BIT_CONTROL(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
-/* CLR_UNDERFLOW_DURATION */ -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip) 0 -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip) 0x1 -#define GET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip))
-#define SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip), 1)
-/* CHL_STS_UPDATE */ -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip) 1 -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip))
-#define SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
- SET_UNIPERIF_BIT_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip), 1)
-/*
- UNIPERIF_STATUS_1 reg
- */
-#define UNIPERIF_STATUS_1_OFFSET(ip) 0x0050 -#define GET_UNIPERIF_STATUS_1(ip) \
- readl_relaxed(ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
-#define SET_UNIPERIF_STATUS_1(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
-/* UNDERFLOW_DURATION */ -#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
-#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip) 0xff -#define GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_STATUS_1_OFFSET(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip))
-#define SET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_STATUS_1_OFFSET(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip), value)
-/*
- UNIPERIF_CHANNEL_STA_REGN reg
- */
-#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_CHANNEL_STA_REGN(ip, n))
-/*
- UNIPERIF_USER_VALIDITY reg
- */
-#define UNIPERIF_USER_VALIDITY_OFFSET(ip) 0x0090 -#define GET_UNIPERIF_USER_VALIDITY(ip) \
- readl_relaxed(ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
-#define SET_UNIPERIF_USER_VALIDITY(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
-/* VALIDITY_LEFT_AND_RIGHT */ -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip) 0 -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip) 0x3 -#define GET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_USER_VALIDITY_OFFSET(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip))
-#define SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_USER_VALIDITY_OFFSET(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip), \
value ? 0x3 : 0)
-/*
- UNIPERIF_DBG_STANDBY_LEFT_SP reg
- */
-#define UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip) 0x0150 -#define UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
-#define UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 0xFFFFFF)
-#define GET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip))
-#define SET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip), value)
-/*
- UNIPERIF_TDM_ENABLE
- */
-#define UNIPERIF_TDM_ENABLE_OFFSET(ip) 0x0118 -#define GET_UNIPERIF_TDM_ENABLE(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip))
-#define SET_UNIPERIF_TDM_ENABLE(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip))
-/* TDM_ENABLE */ -#define UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip) 0x1 -#define GET_UNIPERIF_TDM_ENABLE_EN_TDM(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip))
-#define SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 1)
-#define SET_UNIPERIF_TDM_ENABLE_TDM_DISABLE(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 0)
-/*
- UNIPERIF_TDM_FS_REF_FREQ
- */
-#define UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip) 0x011c -#define GET_UNIPERIF_TDM_FS_REF_FREQ(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ(ip, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip))
-/* REF_FREQ */ -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip) 0x0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) 0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) 1 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) 2 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) 3 -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip) 0x3 -#define GET_UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip))
-/*
- UNIPERIF_TDM_FS_REF_DIV
- */
-#define UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip) 0x0120 -#define GET_UNIPERIF_TDM_FS_REF_DIV(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip))
-#define SET_UNIPERIF_TDM_FS_REF_DIV(ip, value) \
writel_relaxed(value, ip->base + \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip))
-/* NUM_TIMESLOT */ -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip) 0xff -#define GET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip))
-#define SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip, value) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip), value)
-/*
- UNIPERIF_TDM_WORD_POS_X_Y
- 32 bits of UNIPERIF_TDM_WORD_POS_X_Y register shall be set in 1 shot
- */
-#define UNIPERIF_TDM_WORD_POS_1_2_OFFSET(ip) 0x013c -#define UNIPERIF_TDM_WORD_POS_3_4_OFFSET(ip) 0x0140 -#define UNIPERIF_TDM_WORD_POS_5_6_OFFSET(ip) 0x0144 -#define UNIPERIF_TDM_WORD_POS_7_8_OFFSET(ip) 0x0148 -#define GET_UNIPERIF_TDM_WORD_POS(ip, words) \
- readl_relaxed(ip->base + UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip))
-#define SET_UNIPERIF_TDM_WORD_POS(ip, words, value) \
writel_relaxed(value, ip->base + \
UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip))
-/*
- uniperipheral IP capabilities
- */
-#define UNIPERIF_FIFO_SIZE 70 /* FIFO is 70 cells deep */ -#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */
-#define UNIPERIF_TYPE_IS_HDMI(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI)
-#define UNIPERIF_TYPE_IS_PCM(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_PCM)
-#define UNIPERIF_TYPE_IS_SPDIF(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF)
-#define UNIPERIF_TYPE_IS_IEC958(p) \
- (UNIPERIF_TYPE_IS_HDMI(p) || \
UNIPERIF_TYPE_IS_SPDIF(p))
-#define UNIPERIF_TYPE_IS_TDM(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_TDM)
-/*
- Uniperipheral IP revisions
- */
-enum uniperif_version {
- SND_ST_UNIPERIF_VERSION_UNKNOWN,
- /* SASG1 (Orly), Newman */
- SND_ST_UNIPERIF_VERSION_C6AUD0_UNI_1_0,
- /* SASC1, SASG2 (Orly2) */
- SND_ST_UNIPERIF_VERSION_UNI_PLR_1_0,
- /* SASC1, SASG2 (Orly2), TELSS, Cannes */
- SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- /* TELSS (SASC1) */
- SND_ST_UNIPERIF_VERSION_TDM_PLR_1_0,
- /* Cannes/Monaco */
- SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
-};
-enum uniperif_type {
- SND_ST_UNIPERIF_TYPE_NONE = 0x00,
- SND_ST_UNIPERIF_TYPE_HDMI = 0x01,
- SND_ST_UNIPERIF_TYPE_PCM = 0x02,
- SND_ST_UNIPERIF_TYPE_SPDIF = 0x04,
- SND_ST_UNIPERIF_TYPE_TDM = 0x08
-};
-enum uniperif_state {
- UNIPERIF_STATE_STOPPED,
- UNIPERIF_STATE_STARTED,
- UNIPERIF_STATE_STANDBY,
- UNIPERIF_STATE_UNDERFLOW,
- UNIPERIF_STATE_OVERFLOW = UNIPERIF_STATE_UNDERFLOW,
- UNIPERIF_STATE_XRUN
-};
-enum uniperif_iec958_encoding_mode {
- UNIPERIF_IEC958_ENCODING_MODE_PCM,
- UNIPERIF_IEC958_ENCODING_MODE_ENCODED
-};
-enum uniperif_word_pos {
- WORD_1_2,
- WORD_3_4,
- WORD_5_6,
- WORD_7_8,
- WORD_MAX
-};
-struct uniperif_iec958_settings {
- enum uniperif_iec958_encoding_mode encoding_mode;
- struct snd_aes_iec958 iec958;
-};
-struct dai_tdm_slot {
- unsigned int mask;
- int slots;
- int slot_width;
- unsigned int avail_slots;
-};
-struct uniperif {
- /* System information */
- enum uniperif_type type;
- int underflow_enabled; /* Underflow recovery mode */
- struct device *dev;
- int id; /* instance value of the uniperipheral IP */
- int ver; /* IP version, used by register access macros */
- struct regmap_field *clk_sel;
- struct regmap_field *valid_sel;
- spinlock_t irq_lock; /* use to prevent race condition with IRQ */
- /* capabilities */
- const struct snd_pcm_hardware *hw;
- /* Resources */
- struct resource *mem_region;
- void __iomem *base;
- unsigned long fifo_phys_address;
- int irq;
- /* Clocks */
- struct clk *clk;
- int mclk;
- int clk_adj;
- /* Runtime data */
- enum uniperif_state state;
- struct snd_pcm_substream *substream;
- /* Specific to IEC958 player */
- struct uniperif_iec958_settings stream_settings;
- struct mutex ctrl_lock; /* For resource updated by stream and controls*/
- /*alsa ctrl*/
- struct snd_kcontrol_new *snd_ctrls;
- int num_ctrls;
- /* dai properties */
- unsigned int daifmt;
- struct dai_tdm_slot tdm_slot;
- /* DAI callbacks */
- const struct snd_soc_dai_ops *dai_ops;
-};
-struct sti_uniperiph_dai {
- int stream;
- struct uniperif *uni;
- struct snd_dmaengine_dai_dma_data dma_data;
-};
-struct sti_uniperiph_data {
- struct platform_device *pdev;
- struct snd_soc_dai_driver *dai;
- struct sti_uniperiph_dai dai_data;
-};
-static __maybe_unused const struct snd_pcm_hardware uni_tdm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 32,
- .periods_min = 2,
- .periods_max = 10,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/* uniperiph player*/ -int uni_player_init(struct platform_device *pdev,
struct uniperif *player);
-int uni_player_resume(struct uniperif *player);
-/* uniperiph reader */ -int uni_reader_init(struct platform_device *pdev,
struct uniperif *reader);
-/* common */ -int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt);
-int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
-static inline int sti_uniperiph_get_user_frame_size(
- struct snd_pcm_runtime *runtime)
-{
- return (runtime->channels * snd_pcm_format_width(runtime->format) / 8);
-}
-static inline int sti_uniperiph_get_unip_tdm_frame_size(struct uniperif *uni) -{
- return (uni->tdm_slot.slots * uni->tdm_slot.slot_width / 8);
-}
-int sti_uniperiph_reset(struct uniperif *uni);
-int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots,
int slot_width);
-int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni,
unsigned int *word_pos);
-int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule);
-int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule);
-#endif diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c deleted file mode 100644 index 2ed92c990b97..000000000000 --- a/sound/soc/sti/uniperif_player.c +++ /dev/null @@ -1,1148 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <linux/clk.h> -#include <linux/mfd/syscon.h>
-#include <sound/asoundef.h> -#include <sound/soc.h>
-#include "uniperif.h"
-/*
- Some hardware-related definitions
- */
-/* sys config registers definitions */ -#define SYS_CFG_AUDIO_GLUE 0xA4
-/*
- Driver specific types.
- */
-#define UNIPERIF_PLAYER_CLK_ADJ_MIN -999999 -#define UNIPERIF_PLAYER_CLK_ADJ_MAX 1000000 -#define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX bus */
-/*
- Note: snd_pcm_hardware is linked to DMA controller but is declared here to
- integrate DAI_CPU capability in term of rate and supported channels
- */
-static const struct snd_pcm_hardware uni_player_pcm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 8,
- .periods_min = 2,
- .periods_max = 48,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/*
- uni_player_irq_handler
- In case of error audio stream is stopped; stop action is protected via PCM
- stream lock to avoid race condition with trigger callback.
- */
-static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) -{
- irqreturn_t ret = IRQ_NONE;
- struct uniperif *player = dev_id;
- unsigned int status;
- unsigned int tmp;
- spin_lock(&player->irq_lock);
- if (!player->substream)
goto irq_spin_unlock;
- snd_pcm_stream_lock(player->substream);
- if (player->state == UNIPERIF_STATE_STOPPED)
goto stream_unlock;
- /* Get interrupt status & clear them immediately */
- status = GET_UNIPERIF_ITS(player);
- SET_UNIPERIF_ITS_BCLR(player, status);
- /* Check for fifo error (underrun) */
- if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {
dev_err(player->dev, "FIFO underflow error detected\n");
/* Interrupt is just for information when underflow recovery */
if (player->underflow_enabled) {
/* Update state to underflow */
player->state = UNIPERIF_STATE_UNDERFLOW;
} else {
/* Disable interrupt so doesn't continually fire */
SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
}
ret = IRQ_HANDLED;
- }
- /* Check for dma error (overrun) */
- if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {
dev_err(player->dev, "DMA error detected\n");
/* Disable interrupt so doesn't continually fire */
SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
ret = IRQ_HANDLED;
- }
- /* Check for underflow recovery done */
- if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
if (!player->underflow_enabled) {
dev_err(player->dev,
"unexpected Underflow recovering\n");
ret = -EPERM;
goto stream_unlock;
}
/* Read the underflow recovery duration */
tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
dev_dbg(player->dev, "Underflow recovered (%d LR clocks max)\n",
tmp);
/* Clear the underflow recovery duration */
SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);
/* Update state to started */
player->state = UNIPERIF_STATE_STARTED;
ret = IRQ_HANDLED;
- }
- /* Check if underflow recovery failed */
- if (unlikely(status &
UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {
dev_err(player->dev, "Underflow recovery failed\n");
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
ret = IRQ_HANDLED;
- }
-stream_unlock:
- snd_pcm_stream_unlock(player->substream);
-irq_spin_unlock:
- spin_unlock(&player->irq_lock);
- return ret;
-}
-static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate) -{
- int rate_adjusted, rate_achieved, delta, ret;
- int adjustment = player->clk_adj;
- /*
* a
* F = f + --------- * f = f + d
* 1000000
*
* a
* d = --------- * f
* 1000000
*
* where:
* f - nominal rate
* a - adjustment in ppm (parts per milion)
* F - rate to be set in synthesizer
* d - delta (difference) between f and F
*/
- if (adjustment < 0) {
/* div64_64 operates on unsigned values... */
delta = -1;
adjustment = -adjustment;
- } else {
delta = 1;
- }
- /* 500000 ppm is 0.5, which is used to round up values */
- delta *= (int)div64_u64((uint64_t)rate *
(uint64_t)adjustment + 500000, 1000000);
- rate_adjusted = rate + delta;
- /* Adjusted rate should never be == 0 */
- if (!rate_adjusted)
return -EINVAL;
- ret = clk_set_rate(player->clk, rate_adjusted);
- if (ret < 0)
return ret;
- rate_achieved = clk_get_rate(player->clk);
- if (!rate_achieved)
/* If value is 0 means that clock or parent not valid */
return -EINVAL;
- /*
* Using ALSA's adjustment control, we can modify the rate to be up
* to twice as much as requested, but no more
*/
- delta = rate_achieved - rate;
- if (delta < 0) {
/* div64_64 operates on unsigned values... */
delta = -delta;
adjustment = -1;
- } else {
adjustment = 1;
- }
- /* Frequency/2 is added to round up result */
- adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,
rate);
- player->clk_adj = adjustment;
- return 0;
-}
-static void uni_player_set_channel_status(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int n;
- unsigned int status;
- /*
* Some AVRs and TVs require the channel status to contain a correct
* sampling frequency. If no sample rate is already specified, then
* set one.
*/
- if (runtime) {
switch (runtime->rate) {
case 22050:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_22050;
break;
case 44100:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_44100;
break;
case 88200:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_88200;
break;
case 176400:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_176400;
break;
case 24000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_24000;
break;
case 48000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_48000;
break;
case 96000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_96000;
break;
case 192000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_192000;
break;
case 32000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_32000;
break;
default:
/* Mark as sampling frequency not indicated */
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_NOTID;
break;
}
- }
- /* Audio mode:
* Use audio mode status to select PCM or encoded mode
*/
- if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO)
player->stream_settings.encoding_mode =
UNIPERIF_IEC958_ENCODING_MODE_ENCODED;
- else
player->stream_settings.encoding_mode =
UNIPERIF_IEC958_ENCODING_MODE_PCM;
- if (player->stream_settings.encoding_mode ==
UNIPERIF_IEC958_ENCODING_MODE_PCM)
/* Clear user validity bits */
SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
- else
/* Set user validity bits */
SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);
- /* Program the new channel status */
- for (n = 0; n < 6; ++n) {
status =
player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;
status |=
player->stream_settings.iec958.status[1 + (n * 4)] << 8;
status |=
player->stream_settings.iec958.status[2 + (n * 4)] << 16;
status |=
player->stream_settings.iec958.status[3 + (n * 4)] << 24;
SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
- }
- /* Update the channel status */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
- else
SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
-}
-static int uni_player_prepare_iec958(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int clk_div;
- clk_div = player->mclk / runtime->rate;
- /* Oversampling must be multiple of 128 as iec958 frame is 32-bits */
- if ((clk_div % 128) || (clk_div <= 0)) {
dev_err(player->dev, "%s: invalid clk_div %d\n",
__func__, clk_div);
return -EINVAL;
- }
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* 16/16 memory format */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
/* 16-bits per sub-frame */
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
/* Set 16-bit sample precision */
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/* 16/0 memory format */
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
/* 32-bits per sub-frame */
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
/* Set 24-bit sample precision */
SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- /* Set parity to be calculated by the hardware */
- SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);
- /* Set channel status bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);
- /* Set user data bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);
- /* Set validity bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);
- /* Set full software control to disabled */
- SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);
- SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
- mutex_lock(&player->ctrl_lock);
- /* Update the channel status */
- uni_player_set_channel_status(player, runtime);
- mutex_unlock(&player->ctrl_lock);
- /* Clear the user validity user bits */
- SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
- /* Disable one-bit audio mode */
- SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
- /* Enable consecutive frames repetition of Z preamble (not for HBRA) */
- SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);
- /* Change to SUF0_SUBF1 and left/right channels swap! */
- SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);
- /* Set data output as MSB first */
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- if (player->stream_settings.encoding_mode ==
UNIPERIF_IEC958_ENCODING_MODE_ENCODED)
SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);
- else
SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
- /* Set rounding to off */
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- /* Set clock divisor */
- SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);
- /* Set the spdif latency to not wait before starting player */
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- /*
* Ensure iec958 formatting is off. It will be enabled in function
* uni_player_start() at the same time as the operation
* mode is set to work around a silicon issue.
*/
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
- else
SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
- return 0;
-}
-static int uni_player_prepare_pcm(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int output_frame_size, slot_width, clk_div;
- /* Force slot width to 32 in I2S mode (HW constraint) */
- if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
SND_SOC_DAIFMT_I2S)
slot_width = 32;
- else
slot_width = snd_pcm_format_width(runtime->format);
- output_frame_size = slot_width * runtime->channels;
- clk_div = player->mclk / runtime->rate;
- /*
* For 32 bits subframe clk_div must be a multiple of 128,
* for 16 bits must be a multiple of 64
*/
- if ((slot_width == 32) && (clk_div % 128)) {
dev_err(player->dev, "%s: invalid clk_div\n", __func__);
return -EINVAL;
- }
- if ((slot_width == 16) && (clk_div % 64)) {
dev_err(player->dev, "%s: invalid clk_div\n", __func__);
return -EINVAL;
- }
- /*
* Number of bits per subframe (which is one channel sample)
* on output - Transfer 16 or 32 bits from FIFO
*/
- switch (slot_width) {
- case 32:
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
break;
- case 16:
SET_UNIPERIF_I2S_FMT_NBIT_16(player);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
break;
- default:
dev_err(player->dev, "subframe format not supported\n");
return -EINVAL;
- }
- /* Configure data memory format */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* One data word contains two samples */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/*
* Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
* on the left than zeros (if less than 32 bytes)"... ;-)
*/
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- /* Set rounding to off */
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- /* Set clock divisor */
- SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size));
- /* Number of channelsmust be even*/
- if ((runtime->channels % 2) || (runtime->channels < 2) ||
(runtime->channels > 10)) {
dev_err(player->dev, "%s: invalid nb of channels\n", __func__);
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
- /* Set 1-bit audio format to disabled */
- SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- /* No iec958 formatting as outputting to DAC */
- SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
- return 0;
-}
-static int uni_player_prepare_tdm(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int tdm_frame_size; /* unip tdm frame size in bytes */
- int user_frame_size; /* user tdm frame size in bytes */
- /* default unip TDM_WORD_POS_X_Y */
- unsigned int word_pos[4] = {
0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
- int freq, ret;
- tdm_frame_size =
sti_uniperiph_get_unip_tdm_frame_size(player);
- user_frame_size =
sti_uniperiph_get_user_frame_size(runtime);
- /* fix 16/0 format */
- SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
- SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
- /* number of words inserted on the TDM line */
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
- /* Enable the tdm functionality */
- SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player);
- /* number of 8 bits timeslots avail in unip tdm frame */
- SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player, tdm_frame_size);
- /* set the timeslot allocation for words in FIFO */
- sti_uniperiph_get_tdm_word_pos(player, word_pos);
- SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]);
- SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]);
- SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]);
- SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]);
- /* set unip clk rate (not done vai set_sysclk ops) */
- freq = runtime->rate * tdm_frame_size * 8;
- mutex_lock(&player->ctrl_lock);
- ret = uni_player_clk_set_rate(player, freq);
- if (!ret)
player->mclk = freq;
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-/*
- ALSA uniperipheral iec958 controls
- */
-static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
- mutex_lock(&player->ctrl_lock);
- ucontrol->value.iec958.status[0] = iec958->status[0];
- ucontrol->value.iec958.status[1] = iec958->status[1];
- ucontrol->value.iec958.status[2] = iec958->status[2];
- ucontrol->value.iec958.status[3] = iec958->status[3];
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
- unsigned long flags;
- mutex_lock(&player->ctrl_lock);
- iec958->status[0] = ucontrol->value.iec958.status[0];
- iec958->status[1] = ucontrol->value.iec958.status[1];
- iec958->status[2] = ucontrol->value.iec958.status[2];
- iec958->status[3] = ucontrol->value.iec958.status[3];
- spin_lock_irqsave(&player->irq_lock, flags);
- if (player->substream && player->substream->runtime)
uni_player_set_channel_status(player,
player->substream->runtime);
- else
uni_player_set_channel_status(player, NULL);
- spin_unlock_irqrestore(&player->irq_lock, flags);
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static struct snd_kcontrol_new uni_player_iec958_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = uni_player_ctl_iec958_info,
- .get = uni_player_ctl_iec958_get,
- .put = uni_player_ctl_iec958_put,
-};
-/*
- uniperif rate adjustement control
- */
-static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;
- uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
- uinfo->value.integer.step = 1;
- return 0;
-}
-static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- mutex_lock(&player->ctrl_lock);
- ucontrol->value.integer.value[0] = player->clk_adj;
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- int ret = 0;
- if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) ||
(ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX))
return -EINVAL;
- mutex_lock(&player->ctrl_lock);
- player->clk_adj = ucontrol->value.integer.value[0];
- if (player->mclk)
ret = uni_player_clk_set_rate(player, player->mclk);
- mutex_unlock(&player->ctrl_lock);
- return ret;
-}
-static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Playback Oversampling Freq. Adjustment",
- .info = snd_sti_clk_adjustment_info,
- .get = snd_sti_clk_adjustment_get,
- .put = snd_sti_clk_adjustment_put,
-};
-static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
- &uni_player_clk_adj_ctl,
-};
-static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
- &uni_player_iec958_ctl,
- &uni_player_clk_adj_ctl,
-};
-static int uni_player_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- unsigned long flags;
- int ret;
- spin_lock_irqsave(&player->irq_lock, flags);
- player->substream = substream;
- spin_unlock_irqrestore(&player->irq_lock, flags);
- player->clk_adj = 0;
- if (!UNIPERIF_TYPE_IS_TDM(player))
return 0;
- /* refine hw constraint in tdm mode */
- ret = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
sti_uniperiph_fix_tdm_chan,
player, SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
- if (ret < 0)
return ret;
- return snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
sti_uniperiph_fix_tdm_format,
player, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
-}
-static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- int ret;
- if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN))
return 0;
- if (clk_id != 0)
return -EINVAL;
- mutex_lock(&player->ctrl_lock);
- ret = uni_player_clk_set_rate(player, freq);
- if (!ret)
player->mclk = freq;
- mutex_unlock(&player->ctrl_lock);
- return ret;
-}
-static int uni_player_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int transfer_size, trigger_limit;
- int ret;
- /* The player should be stopped */
- if (player->state != UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state %d\n", __func__,
player->state);
return -EINVAL;
- }
- /* Calculate transfer size (in fifo cells and bytes) for frame count */
- if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {
/* transfer size = user frame size (in 32 bits FIFO cell) */
transfer_size =
sti_uniperiph_get_user_frame_size(runtime) / 4;
- } else {
transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
- }
- /* Calculate number of empty cells available before asserting DREQ */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
- } else {
/*
* Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
* FDMA_TRIGGER_LIMIT also controls when the state switches
* from OFF or STANDBY to AUDIO DATA.
*/
trigger_limit = transfer_size;
- }
- /* Trigger limit must be an even number */
- if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||
(trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {
dev_err(player->dev, "invalid trigger limit %d\n",
trigger_limit);
return -EINVAL;
- }
- SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);
- /* Uniperipheral setup depends on player type */
- switch (player->type) {
- case SND_ST_UNIPERIF_TYPE_HDMI:
ret = uni_player_prepare_iec958(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_PCM:
ret = uni_player_prepare_pcm(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_SPDIF:
ret = uni_player_prepare_iec958(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_TDM:
ret = uni_player_prepare_tdm(player, runtime);
break;
- default:
dev_err(player->dev, "invalid player type\n");
return -EINVAL;
- }
- if (ret)
return ret;
- switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
break;
- case SND_SOC_DAIFMT_NB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
break;
- case SND_SOC_DAIFMT_IB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
break;
- case SND_SOC_DAIFMT_IB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
break;
- }
- switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);
break;
- case SND_SOC_DAIFMT_LEFT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
break;
- case SND_SOC_DAIFMT_RIGHT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);
- return sti_uniperiph_reset(player);
-}
-static int uni_player_start(struct uniperif *player) -{
- int ret;
- /* The player should be stopped */
- if (player->state != UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state\n", __func__);
return -EINVAL;
- }
- ret = clk_prepare_enable(player->clk);
- if (ret) {
dev_err(player->dev, "%s: Failed to enable clock\n", __func__);
return ret;
- }
- /* Clear any pending interrupts */
- SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));
- /* Set the interrupt mask */
- SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);
- /* Enable underflow recovery interrupts */
- if (player->underflow_enabled) {
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
- }
- ret = sti_uniperiph_reset(player);
- if (ret < 0) {
clk_disable_unprepare(player->clk);
return ret;
- }
- /*
* Does not use IEC61937 features of the uniperipheral hardware.
* Instead it performs IEC61937 in software and inserts it directly
* into the audio data stream. As such, when encoded mode is selected,
* linear pcm mode is still used, but with the differences of the
* channel status bits set for encoded mode and the validity bits set.
*/
- SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);
- /*
* If iec958 formatting is required for hdmi or spdif, then it must be
* enabled after the operation mode is set. If set prior to this, it
* will not take affect and hang the player.
*/
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
if (UNIPERIF_TYPE_IS_IEC958(player))
SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
- /* Force channel status update (no update if clk disable) */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
- else
SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
- /* Update state to started */
- player->state = UNIPERIF_STATE_STARTED;
- return 0;
-}
-static int uni_player_stop(struct uniperif *player) -{
- int ret;
- /* The player should not be in stopped state */
- if (player->state == UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state\n", __func__);
return -EINVAL;
- }
- /* Turn the player off */
- SET_UNIPERIF_CTRL_OPERATION_OFF(player);
- ret = sti_uniperiph_reset(player);
- if (ret < 0)
return ret;
- /* Disable interrupts */
- SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));
- /* Disable clock */
- clk_disable_unprepare(player->clk);
- /* Update state to stopped and return */
- player->state = UNIPERIF_STATE_STOPPED;
- return 0;
-}
-int uni_player_resume(struct uniperif *player) -{
- int ret;
- /* Select the frequency synthesizer clock */
- if (player->clk_sel) {
ret = regmap_field_write(player->clk_sel, 1);
if (ret) {
dev_err(player->dev,
"%s: Failed to select freq synth clock\n",
__func__);
return ret;
}
- }
- SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
- return 0;
-} -EXPORT_SYMBOL_GPL(uni_player_resume);
-static int uni_player_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
return uni_player_start(player);
- case SNDRV_PCM_TRIGGER_STOP:
return uni_player_stop(player);
- case SNDRV_PCM_TRIGGER_RESUME:
return uni_player_resume(player);
- default:
return -EINVAL;
- }
-}
-static void uni_player_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- unsigned long flags;
- spin_lock_irqsave(&player->irq_lock, flags);
- if (player->state != UNIPERIF_STATE_STOPPED)
/* Stop the player */
uni_player_stop(player);
- player->substream = NULL;
- spin_unlock_irqrestore(&player->irq_lock, flags);
-}
-static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
struct uniperif *player)
-{
- struct device_node *node = pdev->dev.of_node;
- struct regmap *regmap;
- struct reg_field regfield[2] = {
/* PCM_CLK_SEL */
REG_FIELD(SYS_CFG_AUDIO_GLUE,
8 + player->id,
8 + player->id),
/* PCMP_VALID_SEL */
REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)
- };
- regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
- if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
return PTR_ERR(regmap);
- }
- player->clk_sel = regmap_field_alloc(regmap, regfield[0]);
- player->valid_sel = regmap_field_alloc(regmap, regfield[1]);
- return 0;
-}
-static const struct snd_soc_dai_ops uni_player_dai_ops = {
.startup = uni_player_startup,
.shutdown = uni_player_shutdown,
.prepare = uni_player_prepare,
.trigger = uni_player_trigger,
.hw_params = sti_uniperiph_dai_hw_params,
.set_fmt = sti_uniperiph_dai_set_fmt,
.set_sysclk = uni_player_set_sysclk,
.set_tdm_slot = sti_uniperiph_set_tdm_slot
-};
-int uni_player_init(struct platform_device *pdev,
struct uniperif *player)
-{
- int ret = 0;
- player->dev = &pdev->dev;
- player->state = UNIPERIF_STATE_STOPPED;
- player->dai_ops = &uni_player_dai_ops;
- /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg */
- ret = uni_player_parse_dt_audio_glue(pdev, player);
- if (ret < 0) {
dev_err(player->dev, "Failed to parse DeviceTree\n");
return ret;
- }
- /* Underflow recovery is only supported on later ip revisions */
- if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
player->underflow_enabled = 1;
- if (UNIPERIF_TYPE_IS_TDM(player))
player->hw = &uni_tdm_hw;
- else
player->hw = &uni_player_pcm_hw;
- /* Get uniperif resource */
- player->clk = of_clk_get(pdev->dev.of_node, 0);
- if (IS_ERR(player->clk)) {
dev_err(player->dev, "Failed to get clock\n");
return PTR_ERR(player->clk);
- }
- /* Select the frequency synthesizer clock */
- if (player->clk_sel) {
ret = regmap_field_write(player->clk_sel, 1);
if (ret) {
dev_err(player->dev,
"%s: Failed to select freq synth clock\n",
__func__);
return ret;
}
- }
- /* connect to I2S/TDM TX bus */
- if (player->valid_sel &&
(player->id == UNIPERIF_PLAYER_I2S_OUT)) {
ret = regmap_field_write(player->valid_sel, player->id);
if (ret) {
dev_err(player->dev,
"%s: unable to connect to tdm bus\n", __func__);
return ret;
}
- }
- ret = devm_request_irq(&pdev->dev, player->irq,
uni_player_irq_handler, IRQF_SHARED,
dev_name(&pdev->dev), player);
- if (ret < 0) {
dev_err(player->dev, "unable to request IRQ %d\n", player->irq);
return ret;
- }
- mutex_init(&player->ctrl_lock);
- spin_lock_init(&player->irq_lock);
- /* Ensure that disabled by default */
- SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
- if (UNIPERIF_TYPE_IS_IEC958(player)) {
/* Set default iec958 status bits */
/* Consumer, PCM, copyright, 2ch, mode 0 */
player->stream_settings.iec958.status[0] = 0x00;
/* Broadcast reception category */
player->stream_settings.iec958.status[1] =
IEC958_AES1_CON_GENERAL;
/* Do not take into account source or channel number */
player->stream_settings.iec958.status[2] =
IEC958_AES2_CON_SOURCE_UNSPEC;
/* Sampling frequency not indicated */
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_NOTID;
/* Max sample word 24-bit, sample word length not indicated */
player->stream_settings.iec958.status[4] =
IEC958_AES4_CON_MAX_WORDLEN_24 |
IEC958_AES4_CON_WORDLEN_24_20;
player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
player->snd_ctrls = snd_sti_iec_ctl[0];
- } else {
player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
player->snd_ctrls = snd_sti_pcm_ctl[0];
- }
- return 0;
-} -EXPORT_SYMBOL_GPL(uni_player_init); diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c deleted file mode 100644 index 136059331211..000000000000 --- a/sound/soc/sti/uniperif_reader.c +++ /dev/null @@ -1,436 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <sound/soc.h>
-#include "uniperif.h"
-#define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX bus */ -/*
- Note: snd_pcm_hardware is linked to DMA controller but is declared here to
- integrate unireader capability in term of rate and supported channels
- */
-static const struct snd_pcm_hardware uni_reader_pcm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 8,
- .periods_min = 2,
- .periods_max = 48,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/*
- uni_reader_irq_handler
- In case of error audio stream is stopped; stop action is protected via PCM
- stream lock to avoid race condition with trigger callback.
- */
-static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id) -{
- irqreturn_t ret = IRQ_NONE;
- struct uniperif *reader = dev_id;
- unsigned int status;
- spin_lock(&reader->irq_lock);
- if (!reader->substream)
goto irq_spin_unlock;
- snd_pcm_stream_lock(reader->substream);
- if (reader->state == UNIPERIF_STATE_STOPPED) {
/* Unexpected IRQ: do nothing */
dev_warn(reader->dev, "unexpected IRQ\n");
goto stream_unlock;
- }
- /* Get interrupt status & clear them immediately */
- status = GET_UNIPERIF_ITS(reader);
- SET_UNIPERIF_ITS_BCLR(reader, status);
- /* Check for fifo overflow error */
- if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
dev_err(reader->dev, "FIFO error detected\n");
snd_pcm_stop_xrun(reader->substream);
ret = IRQ_HANDLED;
- }
-stream_unlock:
- snd_pcm_stream_unlock(reader->substream);
-irq_spin_unlock:
- spin_unlock(&reader->irq_lock);
- return ret;
-}
-static int uni_reader_prepare_pcm(struct snd_pcm_runtime *runtime,
struct uniperif *reader)
-{
- int slot_width;
- /* Force slot width to 32 in I2S mode */
- if ((reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK)
== SND_SOC_DAIFMT_I2S) {
slot_width = 32;
- } else {
switch (runtime->format) {
case SNDRV_PCM_FORMAT_S16_LE:
slot_width = 16;
break;
default:
slot_width = 32;
break;
}
- }
- /* Number of bits per subframe (i.e one channel sample) on input. */
- switch (slot_width) {
- case 32:
SET_UNIPERIF_I2S_FMT_NBIT_32(reader);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
break;
- case 16:
SET_UNIPERIF_I2S_FMT_NBIT_16(reader);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(reader);
break;
- default:
dev_err(reader->dev, "subframe format not supported\n");
return -EINVAL;
- }
- /* Configure data memory format */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* One data word contains two samples */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(reader);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/*
* Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
* on the MSB then zeros (if less than 32 bytes)"...
*/
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
break;
- default:
dev_err(reader->dev, "format not supported\n");
return -EINVAL;
- }
- /* Number of channels must be even */
- if ((runtime->channels % 2) || (runtime->channels < 2) ||
(runtime->channels > 10)) {
dev_err(reader->dev, "%s: invalid nb of channels\n", __func__);
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NUM_CH(reader, runtime->channels / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
- return 0;
-}
-static int uni_reader_prepare_tdm(struct snd_pcm_runtime *runtime,
struct uniperif *reader)
-{
- int frame_size; /* user tdm frame size in bytes */
- /* default unip TDM_WORD_POS_X_Y */
- unsigned int word_pos[4] = {
0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
- frame_size = sti_uniperiph_get_user_frame_size(runtime);
- /* fix 16/0 format */
- SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
- SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
- /* number of words inserted on the TDM line */
- SET_UNIPERIF_I2S_FMT_NUM_CH(reader, frame_size / 4 / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
- SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
- SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(reader);
- /*
* set the timeslots allocation for words in FIFO
*
* HW bug: (LSB word < MSB word) => this config is not possible
* So if we want (LSB word < MSB) word, then it shall be
* handled by user
*/
- sti_uniperiph_get_tdm_word_pos(reader, word_pos);
- SET_UNIPERIF_TDM_WORD_POS(reader, 1_2, word_pos[WORD_1_2]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 3_4, word_pos[WORD_3_4]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 5_6, word_pos[WORD_5_6]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 7_8, word_pos[WORD_7_8]);
- return 0;
-}
-static int uni_reader_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int transfer_size, trigger_limit, ret;
- /* The reader should be stopped */
- if (reader->state != UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state %d\n", __func__,
reader->state);
return -EINVAL;
- }
- /* Calculate transfer size (in fifo cells and bytes) for frame count */
- if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) {
/* transfer size = unip frame size (in 32 bits FIFO cell) */
transfer_size =
sti_uniperiph_get_user_frame_size(runtime) / 4;
- } else {
transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
- }
- /* Calculate number of empty cells available before asserting DREQ */
- if (reader->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
- else
/*
* Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
* FDMA_TRIGGER_LIMIT also controls when the state switches
* from OFF or STANDBY to AUDIO DATA.
*/
trigger_limit = transfer_size;
- /* Trigger limit must be an even number */
- if ((!trigger_limit % 2) ||
(trigger_limit != 1 && transfer_size % 2) ||
(trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(reader))) {
dev_err(reader->dev, "invalid trigger limit %d\n",
trigger_limit);
return -EINVAL;
- }
- SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(reader, trigger_limit);
- if (UNIPERIF_TYPE_IS_TDM(reader))
ret = uni_reader_prepare_tdm(runtime, reader);
- else
ret = uni_reader_prepare_pcm(runtime, reader);
- if (ret)
return ret;
- switch (reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(reader);
break;
- case SND_SOC_DAIFMT_LEFT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
break;
- case SND_SOC_DAIFMT_RIGHT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
break;
- default:
dev_err(reader->dev, "format not supported\n");
return -EINVAL;
- }
- /* Data clocking (changing) on the rising/falling edge */
- switch (reader->daifmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
break;
- case SND_SOC_DAIFMT_NB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
break;
- case SND_SOC_DAIFMT_IB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
break;
- case SND_SOC_DAIFMT_IB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
break;
- }
- /* Clear any pending interrupts */
- SET_UNIPERIF_ITS_BCLR(reader, GET_UNIPERIF_ITS(reader));
- SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(reader, 0);
- /* Set the interrupt mask */
- SET_UNIPERIF_ITM_BSET_DMA_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader);
- /* Enable underflow recovery interrupts */
- if (reader->underflow_enabled) {
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader);
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader);
- }
- /* Reset uniperipheral reader */
- return sti_uniperiph_reset(reader);
-}
-static int uni_reader_start(struct uniperif *reader) -{
- /* The reader should be stopped */
- if (reader->state != UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state\n", __func__);
return -EINVAL;
- }
- /* Enable reader interrupts (and clear possible stalled ones) */
- SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
- /* Launch the reader */
- SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(reader);
- /* Update state to started */
- reader->state = UNIPERIF_STATE_STARTED;
- return 0;
-}
-static int uni_reader_stop(struct uniperif *reader) -{
- /* The reader should not be in stopped state */
- if (reader->state == UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state\n", __func__);
return -EINVAL;
- }
- /* Turn the reader off */
- SET_UNIPERIF_CTRL_OPERATION_OFF(reader);
- /* Disable interrupts */
- SET_UNIPERIF_ITM_BCLR(reader, GET_UNIPERIF_ITM(reader));
- /* Update state to stopped and return */
- reader->state = UNIPERIF_STATE_STOPPED;
- return 0;
-}
-static int uni_reader_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
return uni_reader_start(reader);
- case SNDRV_PCM_TRIGGER_STOP:
return uni_reader_stop(reader);
- default:
return -EINVAL;
- }
-}
-static int uni_reader_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- unsigned long flags;
- int ret;
- spin_lock_irqsave(&reader->irq_lock, flags);
- reader->substream = substream;
- spin_unlock_irqrestore(&reader->irq_lock, flags);
- if (!UNIPERIF_TYPE_IS_TDM(reader))
return 0;
- /* refine hw constraint in tdm mode */
- ret = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
sti_uniperiph_fix_tdm_chan,
reader, SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
- if (ret < 0)
return ret;
- return snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
sti_uniperiph_fix_tdm_format,
reader, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
-}
-static void uni_reader_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- unsigned long flags;
- spin_lock_irqsave(&reader->irq_lock, flags);
- if (reader->state != UNIPERIF_STATE_STOPPED) {
/* Stop the reader */
uni_reader_stop(reader);
- }
- reader->substream = NULL;
- spin_unlock_irqrestore(&reader->irq_lock, flags);
-}
-static const struct snd_soc_dai_ops uni_reader_dai_ops = {
.startup = uni_reader_startup,
.shutdown = uni_reader_shutdown,
.prepare = uni_reader_prepare,
.trigger = uni_reader_trigger,
.hw_params = sti_uniperiph_dai_hw_params,
.set_fmt = sti_uniperiph_dai_set_fmt,
.set_tdm_slot = sti_uniperiph_set_tdm_slot
-};
-int uni_reader_init(struct platform_device *pdev,
struct uniperif *reader)
-{
- int ret = 0;
- reader->dev = &pdev->dev;
- reader->state = UNIPERIF_STATE_STOPPED;
- reader->dai_ops = &uni_reader_dai_ops;
- if (UNIPERIF_TYPE_IS_TDM(reader))
reader->hw = &uni_tdm_hw;
- else
reader->hw = &uni_reader_pcm_hw;
- ret = devm_request_irq(&pdev->dev, reader->irq,
uni_reader_irq_handler, IRQF_SHARED,
dev_name(&pdev->dev), reader);
- if (ret < 0) {
dev_err(&pdev->dev, "Failed to request IRQ\n");
return -EBUSY;
- }
- spin_lock_init(&reader->irq_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(uni_reader_init);
2.35.1
Hello,
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 11:28 To: Daniel Palmer daniel@0x0f.com Cc: broonie@kernel.org; tiwai@suse.com; Arnaud POULIQUEN arnaud.pouliquen@st.com; alsa-devel@alsa-project.org; linux- kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 10:13:19 +0100, Daniel Palmer wrote:
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Mea culpa, that was an obvious deadlock I overlooked in the patch series.
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com
I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
Yeah, that looks dead.
The platform is still used for instance: https://lore.kernel.org/all/1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com...
So please do not remove the driver
The issue has not been detected because it is related to an error that occurs only when we reach the limit of the platform, with application that stop the stream at same time. So almost no chance to occur.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
Yes reverting the commit is one solution. The other is to clean-up the snd_pcm_stream_lock/ snd_pcm_stream_unlock in the Handler.
I will try to address this in few weeks
Thanks, Arnaud
thanks,
Takashi
.../bindings/sound/st,sti-asoc-card.txt | 164 -- MAINTAINERS | 7 - sound/soc/sti/Kconfig | 12 - sound/soc/sti/Makefile | 5 - sound/soc/sti/sti_uniperif.c | 506 ------ sound/soc/sti/uniperif.h | 1416 ----------------- sound/soc/sti/uniperif_player.c | 1148 ------------- sound/soc/sti/uniperif_reader.c | 436 ----- 8 files changed, 3694 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/st,sti-asoc-
card.txt
delete mode 100644 sound/soc/sti/Kconfig delete mode 100644 sound/soc/sti/Makefile delete mode 100644 sound/soc/sti/sti_uniperif.c delete mode 100644 sound/soc/sti/uniperif.h delete mode 100644 sound/soc/sti/uniperif_player.c delete mode 100644 sound/soc/sti/uniperif_reader.c
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
deleted file mode 100644 index a6ffcdec6f6a..000000000000 --- a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt +++ /dev/null @@ -1,164 +0,0 @@ -STMicroelectronics sti ASoC cards
-The sti ASoC Sound Card can be used, for all sti SoCs using internal sti-sas -codec or external codecs.
-sti sound drivers allows to expose sti SoC audio interface through the -generic ASoC simple card. For details about sound card declaration please
refer to
-Documentation/devicetree/bindings/sound/simple-card.yaml.
-1) sti-uniperiph-dai: audio dai device.
-Required properties:
- compatible: "st,stih407-uni-player-hdmi", "st,stih407-uni-player-pcm-out",
"st,stih407-uni-player-dac", "st,stih407-uni-player-spdif",
"st,stih407-uni-reader-pcm_in", "st,stih407-uni-reader-hdmi",
- st,syscfg: phandle to boot-device system configuration registers
- clock-names: name of the clocks listed in clocks property in the same
order
- reg: CPU DAI IP Base address and size entries, listed in same
order than the CPU_DAI properties.
- reg-names: names of the mapped memory regions listed in regs property
in
the same order.
- interrupts: CPU_DAI interrupt line, listed in the same order than the
CPU_DAI properties.
- dma: CPU_DAI DMA controller phandle and DMA request line, listed in
the same
order than the CPU_DAI properties.
- dma-names: identifier string for each DMA request line in the dmas
property.
- "tx" for "st,sti-uni-player" compatibility
- "rx" for "st,sti-uni-reader" compatibility
-Required properties ("st,sti-uni-player" compatibility only):
- clocks: CPU_DAI IP clock source, listed in the same order than the
CPU_DAI properties.
-Optional properties:
- pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs
for
external codecs connection.
- pinctrl-names: should contain only one value - "default".
- st,tdm-mode: to declare to set TDM mode for unireader and uniplayer IPs.
- Only compartible with IPs in charge of the external I2S/TDM bus.
- Should be declared depending on associated codec.
-Example:
- sti_uni_player1: sti-uni-player@8d81000 {
compatible = "st,stih407-uni-player-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
reg = <0x8D81000 0x158>;
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
dmas = <&fdma0 3 0 1>;
dma-names = "tx";
st,tdm-mode = <1>;
- };
- sti_uni_player2: sti-uni-player@8d82000 {
compatible = "st,stih407-uni-player-pcm-out";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
reg = <0x8D82000 0x158>;
interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
dmas = <&fdma0 4 0 1>;
dma-names = "tx";
- };
- sti_uni_player3: sti-uni-player@8d85000 {
compatible = "st,stih407-uni-player-spdif";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
reg = <0x8D85000 0x158>;
interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
dmas = <&fdma0 7 0 1>;
dma-names = "tx";
- };
- sti_uni_reader1: sti-uni-reader@8d84000 {
compatible = "st,stih407-uni-reader-hdmi";
#sound-dai-cells = <0>;
st,syscfg = <&syscfg_core>;
reg = <0x8D84000 0x158>;
interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
dmas = <&fdma0 6 0 1>;
dma-names = "rx";
- };
-2) sti-sas-codec: internal audio codec IPs driver
-Required properties:
- compatible: "st,sti<chip>-sas-codec" .
- Should be chip "st,stih416-sas-codec" or "st,stih407-sas-codec"
- st,syscfg: phandle to boot-device system configuration registers.
- pinctrl-0: SPDIF PIO description.
- pinctrl-names: should contain only one value - "default".
-Example:
- sti_sas_codec: sti-sas-codec {
compatible = "st,stih407-sas-codec";
#sound-dai-cells = <1>;
st,reg_audio = <&syscfg_core>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spdif_out >;
- };
-Example of audio card declaration:
- sound {
compatible = "simple-audio-card";
simple-audio-card,name = "sti audio card";
simple-audio-card,dai-link@0 {
/* DAC */
format = "i2s";
dai-tdm-slot-width = <32>;
cpu {
sound-dai = <&sti_uni_player2>;
};
codec {
sound-dai = <&sti_sasg_codec 1>;
};
};
simple-audio-card,dai-link@1 {
/* SPDIF */
format = "left_j";
cpu {
sound-dai = <&sti_uni_player3>;
};
codec {
sound-dai = <&sti_sasg_codec 0>;
};
};
simple-audio-card,dai-link@2 {
/* TDM playback */
format = "left_j";
frame-inversion = <1>;
cpu {
sound-dai = <&sti_uni_player1>;
dai-tdm-slot-num = <16>;
dai-tdm-slot-width = <16>;
dai-tdm-slot-tx-mask =
<1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1>;
};
codec {
sound-dai = <&sti_sasg_codec 3>;
};
};
- };
diff --git a/MAINTAINERS b/MAINTAINERS index e127c2fb08a7..9dede78d02c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18465,13 +18465,6 @@ F: include/linux/static_call*.h F: kernel/jump_label.c F: kernel/static_call.c
-STI AUDIO (ASoC) DRIVERS -M: Arnaud Pouliquen arnaud.pouliquen@foss.st.com -L: alsa-devel@alsa-project.org (moderated for non-subscribers) -S: Maintained -F: Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt -F: sound/soc/sti/
STI CEC DRIVER M: Alain Volmat alain.volmat@foss.st.com S: Maintained diff --git a/sound/soc/sti/Kconfig b/sound/soc/sti/Kconfig deleted file mode 100644 index f881da4b6aea..000000000000 --- a/sound/soc/sti/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# STM SoC audio configuration -# -menuconfig SND_SOC_STI
- tristate "SoC Audio support for STI System-On-Chip"
- depends on SND_SOC
- depends on ARCH_STI || COMPILE_TEST
- select SND_SOC_GENERIC_DMAENGINE_PCM
- help
Say Y if you want to enable ASoC-support for
any of the STI platforms (e.g. STIH416).
diff --git a/sound/soc/sti/Makefile b/sound/soc/sti/Makefile deleted file mode 100644 index 787ccb521298..000000000000 --- a/sound/soc/sti/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# STI platform support -snd-soc-sti-objs := sti_uniperif.o uniperif_player.o uniperif_reader.o
-obj-$(CONFIG_SND_SOC_STI) += snd-soc-sti.o diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c deleted file mode 100644 index 34668fe3909d..000000000000 --- a/sound/soc/sti/sti_uniperif.c +++ /dev/null @@ -1,506 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <linux/module.h> -#include <linux/pinctrl/consumer.h> -#include <linux/delay.h>
-#include "uniperif.h"
-/*
- User frame size shall be 2, 4, 6 or 8 32-bits words length
- (i.e. 8, 16, 24 or 32 bytes)
- This constraint comes from allowed values for
- UNIPERIF_I2S_FMT_NUM_CH register
- */
-#define UNIPERIF_MAX_FRAME_SZ 0x20 -#define UNIPERIF_ALLOWED_FRAME_SZ (0x08 | 0x10 | 0x18 |
UNIPERIF_MAX_FRAME_SZ)
-struct sti_uniperiph_dev_data {
- unsigned int id; /* Nb available player instances */
- unsigned int version; /* player IP version */
- unsigned int stream;
- const char *dai_names;
- enum uniperif_type type;
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_hdmi = {
- .id = 0,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #0 (HDMI)",
- .type = SND_ST_UNIPERIF_TYPE_HDMI
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_pcm_out = {
- .id = 1,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #1 (PCM OUT)",
- .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_dac = {
- .id = 2,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #2 (DAC)",
- .type = SND_ST_UNIPERIF_TYPE_PCM,
-};
-static const struct sti_uniperiph_dev_data sti_uniplayer_spdif = {
- .id = 3,
- .version = SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0,
- .stream = SNDRV_PCM_STREAM_PLAYBACK,
- .dai_names = "Uni Player #3 (SPDIF)",
- .type = SND_ST_UNIPERIF_TYPE_SPDIF
-};
-static const struct sti_uniperiph_dev_data sti_unireader_pcm_in = {
- .id = 0,
- .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- .stream = SNDRV_PCM_STREAM_CAPTURE,
- .dai_names = "Uni Reader #0 (PCM IN)",
- .type = SND_ST_UNIPERIF_TYPE_PCM | SND_ST_UNIPERIF_TYPE_TDM,
-};
-static const struct sti_uniperiph_dev_data sti_unireader_hdmi_in = {
- .id = 1,
- .version = SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- .stream = SNDRV_PCM_STREAM_CAPTURE,
- .dai_names = "Uni Reader #1 (HDMI IN)",
- .type = SND_ST_UNIPERIF_TYPE_PCM,
-};
-static const struct of_device_id snd_soc_sti_match[] = {
- { .compatible = "st,stih407-uni-player-hdmi",
.data = &sti_uniplayer_hdmi
- },
- { .compatible = "st,stih407-uni-player-pcm-out",
.data = &sti_uniplayer_pcm_out
- },
- { .compatible = "st,stih407-uni-player-dac",
.data = &sti_uniplayer_dac
- },
- { .compatible = "st,stih407-uni-player-spdif",
.data = &sti_uniplayer_spdif
- },
- { .compatible = "st,stih407-uni-reader-pcm_in",
.data = &sti_unireader_pcm_in
- },
- { .compatible = "st,stih407-uni-reader-hdmi",
.data = &sti_unireader_hdmi_in
- },
- {},
-}; -MODULE_DEVICE_TABLE(of, snd_soc_sti_match);
-int sti_uniperiph_reset(struct uniperif *uni) -{
- int count = 10;
- /* Reset uniperipheral uni */
- SET_UNIPERIF_SOFT_RST_SOFT_RST(uni);
- if (uni->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
while (GET_UNIPERIF_SOFT_RST_SOFT_RST(uni) && count) {
udelay(5);
count--;
}
- }
- if (!count) {
dev_err(uni->dev, "Failed to reset uniperif\n");
return -EIO;
- }
- return 0;
-}
-int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int
tx_mask,
unsigned int rx_mask, int slots,
int slot_width)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- int i, frame_size, avail_slots;
- if (!UNIPERIF_TYPE_IS_TDM(uni)) {
dev_err(uni->dev, "cpu dai not in tdm mode\n");
return -EINVAL;
- }
- /* store info in unip context */
- uni->tdm_slot.slots = slots;
- uni->tdm_slot.slot_width = slot_width;
- /* unip is unidirectionnal */
- uni->tdm_slot.mask = (tx_mask != 0) ? tx_mask : rx_mask;
- /* number of available timeslots */
- for (i = 0, avail_slots = 0; i < uni->tdm_slot.slots; i++) {
if ((uni->tdm_slot.mask >> i) & 0x01)
avail_slots++;
- }
- uni->tdm_slot.avail_slots = avail_slots;
- /* frame size in bytes */
- frame_size = uni->tdm_slot.avail_slots * uni->tdm_slot.slot_width / 8;
- /* check frame size is allowed */
- if ((frame_size > UNIPERIF_MAX_FRAME_SZ) ||
(frame_size & ~(int)UNIPERIF_ALLOWED_FRAME_SZ)) {
dev_err(uni->dev, "frame size not allowed: %d bytes\n",
frame_size);
return -EINVAL;
- }
- return 0;
-}
-int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
-{
- struct uniperif *uni = rule->private;
- struct snd_interval t;
- t.min = uni->tdm_slot.avail_slots;
- t.max = uni->tdm_slot.avail_slots;
- t.openmin = 0;
- t.openmax = 0;
- t.integer = 0;
- return snd_interval_refine(hw_param_interval(params, rule->var), &t);
-}
-int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
-{
- struct uniperif *uni = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
- u64 format;
- switch (uni->tdm_slot.slot_width) {
- case 16:
format = SNDRV_PCM_FMTBIT_S16_LE;
break;
- case 32:
format = SNDRV_PCM_FMTBIT_S32_LE;
break;
- default:
dev_err(uni->dev, "format not supported: %d bits\n",
uni->tdm_slot.slot_width);
return -EINVAL;
- }
- maskp->bits[0] &= (u_int32_t)format;
- maskp->bits[1] &= (u_int32_t)(format >> 32);
- /* clear remaining indexes */
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX - 64) / 8);
- if (!maskp->bits[0] && !maskp->bits[1])
return -EINVAL;
- return 0;
-}
-int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni,
unsigned int *word_pos)
-{
- int slot_width = uni->tdm_slot.slot_width / 8;
- int slots_num = uni->tdm_slot.slots;
- unsigned int slots_mask = uni->tdm_slot.mask;
- int i, j, k;
- unsigned int word16_pos[4];
- /* word16_pos:
* word16_pos[0] = WORDX_LSB
* word16_pos[1] = WORDX_MSB,
* word16_pos[2] = WORDX+1_LSB
* word16_pos[3] = WORDX+1_MSB
*/
- /* set unip word position */
- for (i = 0, j = 0, k = 0; (i < slots_num) && (k < WORD_MAX); i++) {
if ((slots_mask >> i) & 0x01) {
word16_pos[j] = i * slot_width;
if (slot_width == 4) {
word16_pos[j + 1] = word16_pos[j] + 2;
j++;
}
j++;
if (j > 3) {
word_pos[k] = word16_pos[1] |
(word16_pos[0] << 8) |
(word16_pos[3] << 16) |
(word16_pos[2] << 24);
j = 0;
k++;
}
}
- }
- return 0;
-}
-/*
- sti_uniperiph_dai_create_ctrl
- This function is used to create Ctrl associated to DAI but also pcm device.
- Request is done by front end to associate ctrl with pcm device id
- */
-static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- struct snd_kcontrol_new *ctrl;
- int i;
- if (!uni->num_ctrls)
return 0;
- for (i = 0; i < uni->num_ctrls; i++) {
/*
* Several Control can have same name. Controls are indexed
on
* Uniperipheral instance ID
*/
ctrl = &uni->snd_ctrls[i];
ctrl->index = uni->id;
ctrl->device = uni->id;
- }
- return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls);
-}
-/*
- DAI
- */
-int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *uni = priv->dai_data.uni;
- struct snd_dmaengine_dai_dma_data *dma_data;
- int transfer_size;
- if (uni->type == SND_ST_UNIPERIF_TYPE_TDM)
/* transfer size = user frame size (in 32-bits FIFO cell) */
transfer_size = snd_soc_params_to_frame_size(params) / 32;
- else
transfer_size = params_channels(params) *
UNIPERIF_FIFO_FRAMES;
- dma_data = snd_soc_dai_get_dma_data(dai, substream);
- dma_data->maxburst = transfer_size;
- return 0;
-}
-int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- priv->dai_data.uni->daifmt = fmt;
- return 0;
-}
-static int sti_uniperiph_suspend(struct snd_soc_component *component) -{
- struct sti_uniperiph_data *priv =
snd_soc_component_get_drvdata(component);
- struct uniperif *uni = priv->dai_data.uni;
- int ret;
- /* The uniperipheral should be in stopped state */
- if (uni->state != UNIPERIF_STATE_STOPPED) {
dev_err(uni->dev, "%s: invalid uni state( %d)\n",
__func__, (int)uni->state);
return -EBUSY;
- }
- /* Pinctrl: switch pinstate to sleep */
- ret = pinctrl_pm_select_sleep_state(uni->dev);
- if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
- return ret;
-}
-static int sti_uniperiph_resume(struct snd_soc_component *component) -{
- struct sti_uniperiph_data *priv =
snd_soc_component_get_drvdata(component);
- struct uniperif *uni = priv->dai_data.uni;
- int ret;
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = uni_player_resume(uni);
if (ret)
return ret;
- }
- /* pinctrl: switch pinstate to default */
- ret = pinctrl_pm_select_default_state(uni->dev);
- if (ret)
dev_err(uni->dev, "%s: failed to select pinctrl state\n",
__func__);
- return ret;
-}
-static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai) -{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct sti_uniperiph_dai *dai_data = &priv->dai_data;
- /* DMA settings*/
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK)
snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL);
- else
snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data);
- dai_data->dma_data.addr = dai_data->uni->fifo_phys_address;
- dai_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- return sti_uniperiph_dai_create_ctrl(dai);
-}
-static const struct snd_soc_dai_driver sti_uniperiph_dai_template = {
- .probe = sti_uniperiph_dai_probe,
-};
-static const struct snd_soc_component_driver sti_uniperiph_dai_component
= {
- .name = "sti_cpu_dai",
- .suspend = sti_uniperiph_suspend,
- .resume = sti_uniperiph_resume
-};
-static int sti_uniperiph_cpu_dai_of(struct device_node *node,
struct sti_uniperiph_data *priv)
-{
- struct device *dev = &priv->pdev->dev;
- struct sti_uniperiph_dai *dai_data = &priv->dai_data;
- struct snd_soc_dai_driver *dai = priv->dai;
- struct snd_soc_pcm_stream *stream;
- struct uniperif *uni;
- const struct of_device_id *of_id;
- const struct sti_uniperiph_dev_data *dev_data;
- const char *mode;
- int ret;
- /* Populate data structure depending on compatibility */
- of_id = of_match_node(snd_soc_sti_match, node);
- if (!of_id->data) {
dev_err(dev, "data associated to device is missing\n");
return -EINVAL;
- }
- dev_data = (struct sti_uniperiph_dev_data *)of_id->data;
- uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL);
- if (!uni)
return -ENOMEM;
- uni->id = dev_data->id;
- uni->ver = dev_data->version;
- *dai = sti_uniperiph_dai_template;
- dai->name = dev_data->dai_names;
- /* Get resources and base address */
- uni->base = devm_platform_get_and_ioremap_resource(priv->pdev, 0,
&uni->mem_region);
- if (IS_ERR(uni->base))
return PTR_ERR(uni->base);
- uni->fifo_phys_address = uni->mem_region->start +
UNIPERIF_FIFO_DATA_OFFSET(uni);
- uni->irq = platform_get_irq(priv->pdev, 0);
- if (uni->irq < 0)
return -ENXIO;
- uni->type = dev_data->type;
- /* check if player should be configured for tdm */
- if (dev_data->type & SND_ST_UNIPERIF_TYPE_TDM) {
if (!of_property_read_string(node, "st,tdm-mode", &mode))
uni->type = SND_ST_UNIPERIF_TYPE_TDM;
else
uni->type = SND_ST_UNIPERIF_TYPE_PCM;
- }
- dai_data->uni = uni;
- dai_data->stream = dev_data->stream;
- if (priv->dai_data.stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = uni_player_init(priv->pdev, uni);
stream = &dai->playback;
- } else {
ret = uni_reader_init(priv->pdev, uni);
stream = &dai->capture;
- }
- if (ret < 0)
return ret;
- dai->ops = uni->dai_ops;
- stream->stream_name = dai->name;
- stream->channels_min = uni->hw->channels_min;
- stream->channels_max = uni->hw->channels_max;
- stream->rates = uni->hw->rates;
- stream->formats = uni->hw->formats;
- return 0;
-}
-static const struct snd_dmaengine_pcm_config dmaengine_pcm_config = {
- .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-};
-static int sti_uniperiph_probe(struct platform_device *pdev) -{
- struct sti_uniperiph_data *priv;
- struct device_node *node = pdev->dev.of_node;
- int ret;
- /* Allocate the private data and the CPU_DAI array */
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
return -ENOMEM;
- priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL);
- if (!priv->dai)
return -ENOMEM;
- priv->pdev = pdev;
- ret = sti_uniperiph_cpu_dai_of(node, priv);
- if (ret < 0)
return ret;
- dev_set_drvdata(&pdev->dev, priv);
- ret = devm_snd_soc_register_component(&pdev->dev,
&sti_uniperiph_dai_component,
priv->dai, 1);
- if (ret < 0)
return ret;
- return devm_snd_dmaengine_pcm_register(&pdev->dev,
&dmaengine_pcm_config, 0);
-}
-static struct platform_driver sti_uniperiph_driver = {
- .driver = {
.name = "sti-uniperiph-dai",
.of_match_table = snd_soc_sti_match,
- },
- .probe = sti_uniperiph_probe,
-}; -module_platform_driver(sti_uniperiph_driver);
-MODULE_DESCRIPTION("uniperipheral DAI driver"); -MODULE_AUTHOR("Arnaud Pouliquen arnaud.pouliquen@st.com"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h deleted file mode 100644 index 2a5de328501c..000000000000 --- a/sound/soc/sti/uniperif.h +++ /dev/null @@ -1,1416 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#ifndef __SND_ST_AUD_UNIPERIF_H -#define __SND_ST_AUD_UNIPERIF_H
-#include <linux/regmap.h>
-#include <sound/dmaengine_pcm.h>
-/*
- Register access macros
- */
-#define GET_UNIPERIF_REG(ip, offset, shift, mask) \
- ((readl_relaxed(ip->base + offset) >> shift) & mask)
-#define SET_UNIPERIF_REG(ip, offset, shift, mask, value) \
- writel_relaxed(((readl_relaxed(ip->base + offset) & \
- ~(mask << shift)) | (((value) & mask) << shift)), ip->base + offset)
-#define SET_UNIPERIF_BIT_REG(ip, offset, shift, mask, value) \
- writel_relaxed((((value) & mask) << shift), ip->base + offset)
-/*
- UNIPERIF_SOFT_RST reg
- */
-#define UNIPERIF_SOFT_RST_OFFSET(ip) 0x0000 -#define GET_UNIPERIF_SOFT_RST(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
readl_relaxed(ip->base + UNIPERIF_SOFT_RST_OFFSET(ip)) : 0)
-#define SET_UNIPERIF_SOFT_RST(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_SOFT_RST_OFFSET(ip))
-/* SOFT_RST */ -#define UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip) 0x0 -#define UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip) 0x1 -#define SET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
- SET_UNIPERIF_BIT_REG(ip, \
UNIPERIF_SOFT_RST_OFFSET(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip), 1)
-#define GET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_SOFT_RST_OFFSET(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip))
-/*
- UNIPERIF_FIFO_DATA reg
- */
-#define UNIPERIF_FIFO_DATA_OFFSET(ip) 0x0004 -#define SET_UNIPERIF_DATA(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_FIFO_DATA_OFFSET(ip))
-/*
- UNIPERIF_CHANNEL_STA_REGN reg
- */
-#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip) 0x0060 -#define GET_UNIPERIF_CHANNEL_STA_REG0(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG0(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip) 0x0064 -#define GET_UNIPERIF_CHANNEL_STA_REG1(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG1(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip) 0x0068 -#define GET_UNIPERIF_CHANNEL_STA_REG2(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG2(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip) 0x006C -#define GET_UNIPERIF_CHANNEL_STA_REG3(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG3(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip) 0x0070 -#define GET_UNIPERIF_CHANNEL_STA_REG4(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG4(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
-#define UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip) 0x0074 -#define GET_UNIPERIF_CHANNEL_STA_REG5(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
-#define SET_UNIPERIF_CHANNEL_STA_REG5(ip, value) \
- writel_relaxed(value, ip->base +
UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
-/*
- UNIPERIF_ITS reg
- */
-#define UNIPERIF_ITS_OFFSET(ip) 0x000C -#define GET_UNIPERIF_ITS(ip) \
- readl_relaxed(ip->base + UNIPERIF_ITS_OFFSET(ip))
-/* MEM_BLK_READ */ -#define UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITS_MEM_BLK_READ_MASK(ip) \
- (BIT(UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip)))
-/* FIFO_ERROR */ -#define UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITS_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip)))
-/* DMA_ERROR */ -#define UNIPERIF_ITS_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITS_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_DMA_ERROR_SHIFT(ip)))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip))))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-/*
- UNIPERIF_ITS_BCLR reg
- */
-/* FIFO_ERROR */ -#define UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITS_BCLR(ip, \
UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip))
-#define UNIPERIF_ITS_BCLR_OFFSET(ip) 0x0010 -#define SET_UNIPERIF_ITS_BCLR(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITS_BCLR_OFFSET(ip))
-/*
- UNIPERIF_ITM reg
- */
-#define UNIPERIF_ITM_OFFSET(ip) 0x0018 -#define GET_UNIPERIF_ITM(ip) \
- readl_relaxed(ip->base + UNIPERIF_ITM_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip)))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip))))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-/*
- UNIPERIF_ITM_BCLR reg
- */
-#define UNIPERIF_ITM_BCLR_OFFSET(ip) 0x001c -#define SET_UNIPERIF_ITM_BCLR(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITM_BCLR_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITM_BCLR(ip, \
UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip))
-/* DMA_ERROR */ -#define UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BCLR_DMA_ERROR(ip) \
- SET_UNIPERIF_ITM_BCLR(ip, \
UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip))
-/*
- UNIPERIF_ITM_BSET reg
- */
-#define UNIPERIF_ITM_BSET_OFFSET(ip) 0x0020 -#define SET_UNIPERIF_ITM_BSET(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_ITM_BSET_OFFSET(ip))
-/* FIFO_ERROR */ -#define UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
-#define UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_FIFO_ERROR(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip))
-/* MEM_BLK_READ */ -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip) 5 -#define UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip))
-/* DMA_ERROR */ -#define UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip) 9 -#define UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip) \
- (BIT(UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip)))
-#define SET_UNIPERIF_ITM_BSET_DMA_ERROR(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip))
-/* UNDERFLOW_REC_DONE */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
-#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 :
(BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip))))
-#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip))
-/* UNDERFLOW_REC_FAILED */ -#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
-#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
0 :
(BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip))))
-#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(ip) \
- SET_UNIPERIF_ITM_BSET(ip, \
UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip))
-/*
- UNIPERIF_CONFIG reg
- */
-#define UNIPERIF_CONFIG_OFFSET(ip) 0x0040 -#define GET_UNIPERIF_CONFIG(ip) \
- readl_relaxed(ip->base + UNIPERIF_CONFIG_OFFSET(ip))
-#define SET_UNIPERIF_CONFIG(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CONFIG_OFFSET(ip))
-/* PARITY_CNTR */ -#define UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip) 0 -#define UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_PARITY_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 1)
-/* CHANNEL_STA_CNTR */ -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip) 1 -#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 1)
-/* USER_DAT_CNTR */ -#define UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip) 2 -#define UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_USER_DAT_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 0)
-/* VALIDITY_DAT_CNTR */ -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip) 3 -#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip))
-#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 1)
-/* ONE_BIT_AUD_SUPPORT */ -#define UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip) 4 -#define UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_ONE_BIT_AUD(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip))
-#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 1)
-/* MEMORY_FMT */ -#define UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip) 5 -#define UNIPERIF_CONFIG_MEM_FMT_MASK(ip) 0x1 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) 0 -#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) 1 -#define GET_UNIPERIF_CONFIG_MEM_FMT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
UNIPERIF_CONFIG_MEM_FMT_MASK(ip))
-#define SET_UNIPERIF_CONFIG_MEM_FMT(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
UNIPERIF_CONFIG_MEM_FMT_MASK(ip), value)
-#define SET_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) \
- SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip))
-#define SET_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) \
- SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip))
-/* REPEAT_CHL_STS */ -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip) 6 -#define UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_REPEAT_CHL_STS(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip))
-#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 1)
-/* BACK_STALL_REQ */ -#define UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 7 : -1)
-#define UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_BACK_STALL_REQ(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip))
-#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 1)
-/* FDMA_TRIGGER_LIMIT */ -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip) 8 -#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip) 0x7F -#define GET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip))
-#define SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip), value)
-/* CHL_STS_UPDATE */ -#define UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
-#define UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip))
-#define SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip), 1)
-/* IDLE_MOD */ -#define UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip) 18 -#define UNIPERIF_CONFIG_IDLE_MOD_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_IDLE_MOD(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip))
-#define SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 0)
-#define SET_UNIPERIF_CONFIG_IDLE_MOD_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 1)
-/* SUBFRAME_SELECTION */ -#define UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip) 19 -#define UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SUBFRAME_SEL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip))
-#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF0_SUBF1(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 0)
-/* FULL_SW_CONTROL */ -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip) 20 -#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_SPDIF_SW_CTRL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip))
-#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_ENABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 0)
-/* MASTER_CLKEDGE */ -#define UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 24 : -1)
-#define UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_CONFIG_MSTR_CLKEDGE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip))
-#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_FALLING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 1)
-#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_RISING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CONFIG_OFFSET(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 0)
-/*
- UNIPERIF_CTRL reg
- */
-#define UNIPERIF_CTRL_OFFSET(ip) 0x0044 -#define GET_UNIPERIF_CTRL(ip) \
- readl_relaxed(ip->base + UNIPERIF_CTRL_OFFSET(ip))
-#define SET_UNIPERIF_CTRL(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_CTRL_OFFSET(ip))
-/* OPERATION */ -#define UNIPERIF_CTRL_OPERATION_SHIFT(ip) 0 -#define UNIPERIF_CTRL_OPERATION_MASK(ip) 0x7 -#define GET_UNIPERIF_CTRL_OPERATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip) 0 -#define SET_UNIPERIF_CTRL_OPERATION_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 1 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 2 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip))
-/* This is the same as above! */ -#define VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) 3 -#define SET_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) 4 -#define SET_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 5 : -1)
-#define SET_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip))
-#define VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 7)
-#define SET_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
UNIPERIF_CTRL_OPERATION_MASK(ip), \
VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip))
-/* EXIT_STBY_ON_EOBLOCK */ -#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 3)
-#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip))
-#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 1)
-/* ROUNDING */ -#define UNIPERIF_CTRL_ROUNDING_SHIFT(ip) 4 -#define UNIPERIF_CTRL_ROUNDING_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ROUNDING(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip))
-#define SET_UNIPERIF_CTRL_ROUNDING_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_ROUNDING_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
UNIPERIF_CTRL_ROUNDING_MASK(ip), 1)
-/* DIVIDER */ -#define UNIPERIF_CTRL_DIVIDER_SHIFT(ip) 5 -#define UNIPERIF_CTRL_DIVIDER_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_DIVIDER(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
UNIPERIF_CTRL_DIVIDER_MASK(ip))
-#define SET_UNIPERIF_CTRL_DIVIDER(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
UNIPERIF_CTRL_DIVIDER_MASK(ip), value)
-/* BYTE_SWAP */ -#define UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 13 : -1)
-#define UNIPERIF_CTRL_BYTE_SWP_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_BYTE_SWP(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip))
-#define SET_UNIPERIF_CTRL_BYTE_SWP_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_BYTE_SWP_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 1)
-/* ZERO_STUFFING_HW_SW */ -#define UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 14 : -1)
-#define UNIPERIF_CTRL_ZERO_STUFF_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_ZERO_STUFF(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip))
-#define SET_UNIPERIF_CTRL_ZERO_STUFF_HW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_ZERO_STUFF_SW(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 0)
-/* SPDIF_LAT */ -#define UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
-#define UNIPERIF_CTRL_SPDIF_LAT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_LAT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip))
-#define SET_UNIPERIF_CTRL_SPDIF_LAT_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 0)
-/* EN_SPDIF_FORMATTING */ -#define UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip) 17 -#define UNIPERIF_CTRL_SPDIF_FMT_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_SPDIF_FMT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip))
-#define SET_UNIPERIF_CTRL_SPDIF_FMT_ON(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 1)
-#define SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 0)
-/* READER_OUT_SELECT */ -#define UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 18 : -1)
-#define UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip) 0x1 -#define GET_UNIPERIF_CTRL_READER_OUT_SEL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip))
-#define SET_UNIPERIF_CTRL_READER_OUT_SEL_IN_MEM(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 0)
-#define SET_UNIPERIF_CTRL_READER_OUT_SEL_ON_I2S_LINE(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 1)
-/* UNDERFLOW_REC_WINDOW */ -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip) 20 -#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip) 0xff -#define GET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip))
-#define SET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_CTRL_OFFSET(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip),
value)
-/*
- UNIPERIF_I2S_FMT a.k.a UNIPERIF_FORMAT reg
- */
-#define UNIPERIF_I2S_FMT_OFFSET(ip) 0x0048 -#define GET_UNIPERIF_I2S_FMT(ip) \
- readl_relaxed(ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
-#define SET_UNIPERIF_I2S_FMT(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
-/* NBIT */ -#define UNIPERIF_I2S_FMT_NBIT_SHIFT(ip) 0 -#define UNIPERIF_I2S_FMT_NBIT_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_NBIT(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NBIT_32(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_NBIT_16(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
UNIPERIF_I2S_FMT_NBIT_MASK(ip), 1)
-/* DATA_SIZE */ -#define UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip) 1 -#define UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_DATA_SIZE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_18(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 1)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_20(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 2)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 3)
-#define SET_UNIPERIF_I2S_FMTL_DATA_SIZE_28(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 4)
-#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 5)
-/* LR_POL */ -#define UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip) 4 -#define UNIPERIF_I2S_FMT_LR_POL_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_LR_POL(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
UNIPERIF_I2S_FMT_LR_POL_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_LR_POL(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
UNIPERIF_I2S_FMT_LR_POL_MASK(ip), value)
-#define SET_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) \
- SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip))
-#define SET_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) \
- SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip))
-/* SCLK_EDGE */ -#define UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip) 5 -#define UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_SCLK_EDGE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 1)
-/* PADDING */ -#define UNIPERIF_I2S_FMT_PADDING_SHIFT(ip) 6 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) 0x0 -#define VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_PADDING(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
UNIPERIF_I2S_FMT_PADDING_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_PADDING(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
UNIPERIF_I2S_FMT_PADDING_MASK(ip), value)
-#define SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) \
- SET_UNIPERIF_I2S_FMT_PADDING(ip, \
VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip))
-#define SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) \
- SET_UNIPERIF_I2S_FMT_PADDING(ip, \
VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip))
-/* ALIGN */ -#define UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip) 7 -#define UNIPERIF_I2S_FMT_ALIGN_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ALIGN(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 1)
-/* ORDER */ -#define UNIPERIF_I2S_FMT_ORDER_SHIFT(ip) 8 -#define UNIPERIF_I2S_FMT_ORDER_MASK(ip) 0x1 -#define GET_UNIPERIF_I2S_FMT_ORDER(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_ORDER_LSB(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip), 0)
-#define SET_UNIPERIF_I2S_FMT_ORDER_MSB(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
UNIPERIF_I2S_FMT_ORDER_MASK(ip), 1)
-/* NUM_CH */ -#define UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip) 9 -#define UNIPERIF_I2S_FMT_NUM_CH_MASK(ip) 0x7 -#define GET_UNIPERIF_I2S_FMT_NUM_CH(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
UNIPERIF_I2S_FMT_NUM_CH_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NUM_CH(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
UNIPERIF_I2S_FMT_NUM_CH_MASK(ip), value)
-/* NO_OF_SAMPLES_TO_READ */ -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip) 12 -#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip) 0xfffff -#define GET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip))
-#define SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_I2S_FMT_OFFSET(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip),
value)
-/*
- UNIPERIF_BIT_CONTROL reg
- */
-#define UNIPERIF_BIT_CONTROL_OFFSET(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 :
0x004c)
-#define GET_UNIPERIF_BIT_CONTROL(ip) \
- readl_relaxed(ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
-#define SET_UNIPERIF_BIT_CONTROL(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
-/* CLR_UNDERFLOW_DURATION */ -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip) 0 -#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip)
0x1
-#define GET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip))
-#define SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip), 1)
-/* CHL_STS_UPDATE */ -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip) 1 -#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip) 0x1 -#define GET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip))
-#define SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
- SET_UNIPERIF_BIT_REG(ip, \
UNIPERIF_BIT_CONTROL_OFFSET(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip), 1)
-/*
- UNIPERIF_STATUS_1 reg
- */
-#define UNIPERIF_STATUS_1_OFFSET(ip) 0x0050 -#define GET_UNIPERIF_STATUS_1(ip) \
- readl_relaxed(ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
-#define SET_UNIPERIF_STATUS_1(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
-/* UNDERFLOW_DURATION */ -#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
-#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip) 0xff -#define GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_STATUS_1_OFFSET(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip))
-#define SET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_STATUS_1_OFFSET(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip),
value)
-/*
- UNIPERIF_CHANNEL_STA_REGN reg
- */
-#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n)) -#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
- readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
-#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_CHANNEL_STA_REGN(ip, n))
-/*
- UNIPERIF_USER_VALIDITY reg
- */
-#define UNIPERIF_USER_VALIDITY_OFFSET(ip) 0x0090 -#define GET_UNIPERIF_USER_VALIDITY(ip) \
- readl_relaxed(ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
-#define SET_UNIPERIF_USER_VALIDITY(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
-/* VALIDITY_LEFT_AND_RIGHT */ -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip) 0 -#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip) 0x3 -#define GET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_USER_VALIDITY_OFFSET(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip))
-#define SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_USER_VALIDITY_OFFSET(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip), \
value ? 0x3 : 0)
-/*
- UNIPERIF_DBG_STANDBY_LEFT_SP reg
- */
-#define UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip) 0x0150 -#define UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
-#define UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip) \
- ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 :
0xFFFFFF)
-#define GET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip) \
- GET_UNIPERIF_REG(ip, \
UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip))
-#define SET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip, value) \
- SET_UNIPERIF_REG(ip, \
UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip), value)
-/*
- UNIPERIF_TDM_ENABLE
- */
-#define UNIPERIF_TDM_ENABLE_OFFSET(ip) 0x0118 -#define GET_UNIPERIF_TDM_ENABLE(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip))
-#define SET_UNIPERIF_TDM_ENABLE(ip, value) \
- writel_relaxed(value, ip->base + UNIPERIF_TDM_ENABLE_OFFSET(ip))
-/* TDM_ENABLE */ -#define UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip) 0x1 -#define GET_UNIPERIF_TDM_ENABLE_EN_TDM(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip))
-#define SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 1)
-#define SET_UNIPERIF_TDM_ENABLE_TDM_DISABLE(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_ENABLE_OFFSET(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_SHIFT(ip), \
UNIPERIF_TDM_ENABLE_EN_TDM_MASK(ip), 0)
-/*
- UNIPERIF_TDM_FS_REF_FREQ
- */
-#define UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip) 0x011c -#define GET_UNIPERIF_TDM_FS_REF_FREQ(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ(ip, value) \
- writel_relaxed(value, ip->base + \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip))
-/* REF_FREQ */ -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip) 0x0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) 0 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) 1 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) 2 -#define VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) 3 -#define UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip) 0x3 -#define GET_UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_8KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_16KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_32KHZ(ip))
-#define SET_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_FREQ_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_FREQ_REF_FREQ_MASK(ip), \
VALUE_UNIPERIF_TDM_FS_REF_FREQ_48KHZ(ip))
-/*
- UNIPERIF_TDM_FS_REF_DIV
- */
-#define UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip) 0x0120 -#define GET_UNIPERIF_TDM_FS_REF_DIV(ip) \
- readl_relaxed(ip->base + UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip))
-#define SET_UNIPERIF_TDM_FS_REF_DIV(ip, value) \
writel_relaxed(value, ip->base + \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip))
-/* NUM_TIMESLOT */ -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip) 0x0 -#define UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip) 0xff -#define GET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip) \
GET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip))
-#define SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(ip, value) \
SET_UNIPERIF_REG(ip, \
UNIPERIF_TDM_FS_REF_DIV_OFFSET(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_SHIFT(ip), \
UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT_MASK(ip),
value)
-/*
- UNIPERIF_TDM_WORD_POS_X_Y
- 32 bits of UNIPERIF_TDM_WORD_POS_X_Y register shall be set in 1 shot
- */
-#define UNIPERIF_TDM_WORD_POS_1_2_OFFSET(ip) 0x013c -#define UNIPERIF_TDM_WORD_POS_3_4_OFFSET(ip) 0x0140 -#define UNIPERIF_TDM_WORD_POS_5_6_OFFSET(ip) 0x0144 -#define UNIPERIF_TDM_WORD_POS_7_8_OFFSET(ip) 0x0148 -#define GET_UNIPERIF_TDM_WORD_POS(ip, words) \
- readl_relaxed(ip->base +
UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip))
-#define SET_UNIPERIF_TDM_WORD_POS(ip, words, value) \
writel_relaxed(value, ip->base + \
UNIPERIF_TDM_WORD_POS_##words##_OFFSET(ip))
-/*
- uniperipheral IP capabilities
- */
-#define UNIPERIF_FIFO_SIZE 70 /* FIFO is 70 cells deep */ -#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in
frames */
-#define UNIPERIF_TYPE_IS_HDMI(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_HDMI)
-#define UNIPERIF_TYPE_IS_PCM(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_PCM)
-#define UNIPERIF_TYPE_IS_SPDIF(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_SPDIF)
-#define UNIPERIF_TYPE_IS_IEC958(p) \
- (UNIPERIF_TYPE_IS_HDMI(p) || \
UNIPERIF_TYPE_IS_SPDIF(p))
-#define UNIPERIF_TYPE_IS_TDM(p) \
- ((p)->type == SND_ST_UNIPERIF_TYPE_TDM)
-/*
- Uniperipheral IP revisions
- */
-enum uniperif_version {
- SND_ST_UNIPERIF_VERSION_UNKNOWN,
- /* SASG1 (Orly), Newman */
- SND_ST_UNIPERIF_VERSION_C6AUD0_UNI_1_0,
- /* SASC1, SASG2 (Orly2) */
- SND_ST_UNIPERIF_VERSION_UNI_PLR_1_0,
- /* SASC1, SASG2 (Orly2), TELSS, Cannes */
- SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
- /* TELSS (SASC1) */
- SND_ST_UNIPERIF_VERSION_TDM_PLR_1_0,
- /* Cannes/Monaco */
- SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
-};
-enum uniperif_type {
- SND_ST_UNIPERIF_TYPE_NONE = 0x00,
- SND_ST_UNIPERIF_TYPE_HDMI = 0x01,
- SND_ST_UNIPERIF_TYPE_PCM = 0x02,
- SND_ST_UNIPERIF_TYPE_SPDIF = 0x04,
- SND_ST_UNIPERIF_TYPE_TDM = 0x08
-};
-enum uniperif_state {
- UNIPERIF_STATE_STOPPED,
- UNIPERIF_STATE_STARTED,
- UNIPERIF_STATE_STANDBY,
- UNIPERIF_STATE_UNDERFLOW,
- UNIPERIF_STATE_OVERFLOW = UNIPERIF_STATE_UNDERFLOW,
- UNIPERIF_STATE_XRUN
-};
-enum uniperif_iec958_encoding_mode {
- UNIPERIF_IEC958_ENCODING_MODE_PCM,
- UNIPERIF_IEC958_ENCODING_MODE_ENCODED
-};
-enum uniperif_word_pos {
- WORD_1_2,
- WORD_3_4,
- WORD_5_6,
- WORD_7_8,
- WORD_MAX
-};
-struct uniperif_iec958_settings {
- enum uniperif_iec958_encoding_mode encoding_mode;
- struct snd_aes_iec958 iec958;
-};
-struct dai_tdm_slot {
- unsigned int mask;
- int slots;
- int slot_width;
- unsigned int avail_slots;
-};
-struct uniperif {
- /* System information */
- enum uniperif_type type;
- int underflow_enabled; /* Underflow recovery mode */
- struct device *dev;
- int id; /* instance value of the uniperipheral IP */
- int ver; /* IP version, used by register access macros */
- struct regmap_field *clk_sel;
- struct regmap_field *valid_sel;
- spinlock_t irq_lock; /* use to prevent race condition with IRQ */
- /* capabilities */
- const struct snd_pcm_hardware *hw;
- /* Resources */
- struct resource *mem_region;
- void __iomem *base;
- unsigned long fifo_phys_address;
- int irq;
- /* Clocks */
- struct clk *clk;
- int mclk;
- int clk_adj;
- /* Runtime data */
- enum uniperif_state state;
- struct snd_pcm_substream *substream;
- /* Specific to IEC958 player */
- struct uniperif_iec958_settings stream_settings;
- struct mutex ctrl_lock; /* For resource updated by stream and
controls*/
- /*alsa ctrl*/
- struct snd_kcontrol_new *snd_ctrls;
- int num_ctrls;
- /* dai properties */
- unsigned int daifmt;
- struct dai_tdm_slot tdm_slot;
- /* DAI callbacks */
- const struct snd_soc_dai_ops *dai_ops;
-};
-struct sti_uniperiph_dai {
- int stream;
- struct uniperif *uni;
- struct snd_dmaengine_dai_dma_data dma_data;
-};
-struct sti_uniperiph_data {
- struct platform_device *pdev;
- struct snd_soc_dai_driver *dai;
- struct sti_uniperiph_dai dai_data;
-};
-static __maybe_unused const struct snd_pcm_hardware uni_tdm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 48000,
- .channels_min = 1,
- .channels_max = 32,
- .periods_min = 2,
- .periods_max = 10,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/* uniperiph player*/ -int uni_player_init(struct platform_device *pdev,
struct uniperif *player);
-int uni_player_resume(struct uniperif *player);
-/* uniperiph reader */ -int uni_reader_init(struct platform_device *pdev,
struct uniperif *reader);
-/* common */ -int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt);
-int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
-static inline int sti_uniperiph_get_user_frame_size(
- struct snd_pcm_runtime *runtime)
-{
- return (runtime->channels * snd_pcm_format_width(runtime->format)
/ 8);
-}
-static inline int sti_uniperiph_get_unip_tdm_frame_size(struct uniperif *uni) -{
- return (uni->tdm_slot.slots * uni->tdm_slot.slot_width / 8);
-}
-int sti_uniperiph_reset(struct uniperif *uni);
-int sti_uniperiph_set_tdm_slot(struct snd_soc_dai *dai, unsigned int
tx_mask,
unsigned int rx_mask, int slots,
int slot_width);
-int sti_uniperiph_get_tdm_word_pos(struct uniperif *uni,
unsigned int *word_pos);
-int sti_uniperiph_fix_tdm_chan(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule);
-int sti_uniperiph_fix_tdm_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule);
-#endif diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c deleted file mode 100644 index 2ed92c990b97..000000000000 --- a/sound/soc/sti/uniperif_player.c +++ /dev/null @@ -1,1148 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <linux/clk.h> -#include <linux/mfd/syscon.h>
-#include <sound/asoundef.h> -#include <sound/soc.h>
-#include "uniperif.h"
-/*
- Some hardware-related definitions
- */
-/* sys config registers definitions */ -#define SYS_CFG_AUDIO_GLUE 0xA4
-/*
- Driver specific types.
- */
-#define UNIPERIF_PLAYER_CLK_ADJ_MIN -999999 -#define UNIPERIF_PLAYER_CLK_ADJ_MAX 1000000 -#define UNIPERIF_PLAYER_I2S_OUT 1 /* player id connected to I2S/TDM TX
bus */
-/*
- Note: snd_pcm_hardware is linked to DMA controller but is declared here
to
- integrate DAI_CPU capability in term of rate and supported channels
- */
-static const struct snd_pcm_hardware uni_player_pcm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 192000,
- .channels_min = 2,
- .channels_max = 8,
- .periods_min = 2,
- .periods_max = 48,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/*
- uni_player_irq_handler
- In case of error audio stream is stopped; stop action is protected via PCM
- stream lock to avoid race condition with trigger callback.
- */
-static irqreturn_t uni_player_irq_handler(int irq, void *dev_id) -{
- irqreturn_t ret = IRQ_NONE;
- struct uniperif *player = dev_id;
- unsigned int status;
- unsigned int tmp;
- spin_lock(&player->irq_lock);
- if (!player->substream)
goto irq_spin_unlock;
- snd_pcm_stream_lock(player->substream);
- if (player->state == UNIPERIF_STATE_STOPPED)
goto stream_unlock;
- /* Get interrupt status & clear them immediately */
- status = GET_UNIPERIF_ITS(player);
- SET_UNIPERIF_ITS_BCLR(player, status);
- /* Check for fifo error (underrun) */
- if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {
dev_err(player->dev, "FIFO underflow error detected\n");
/* Interrupt is just for information when underflow recovery */
if (player->underflow_enabled) {
/* Update state to underflow */
player->state = UNIPERIF_STATE_UNDERFLOW;
} else {
/* Disable interrupt so doesn't continually fire */
SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
}
ret = IRQ_HANDLED;
- }
- /* Check for dma error (overrun) */
- if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {
dev_err(player->dev, "DMA error detected\n");
/* Disable interrupt so doesn't continually fire */
SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
ret = IRQ_HANDLED;
- }
- /* Check for underflow recovery done */
- if (unlikely(status &
UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
if (!player->underflow_enabled) {
dev_err(player->dev,
"unexpected Underflow recovering\n");
ret = -EPERM;
goto stream_unlock;
}
/* Read the underflow recovery duration */
tmp =
GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
dev_dbg(player->dev, "Underflow recovered (%d LR clocks
max)\n",
tmp);
/* Clear the underflow recovery duration */
SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);
/* Update state to started */
player->state = UNIPERIF_STATE_STARTED;
ret = IRQ_HANDLED;
- }
- /* Check if underflow recovery failed */
- if (unlikely(status &
UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {
dev_err(player->dev, "Underflow recovery failed\n");
/* Stop the player */
snd_pcm_stop_xrun(player->substream);
ret = IRQ_HANDLED;
- }
-stream_unlock:
- snd_pcm_stream_unlock(player->substream);
-irq_spin_unlock:
- spin_unlock(&player->irq_lock);
- return ret;
-}
-static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate) -{
- int rate_adjusted, rate_achieved, delta, ret;
- int adjustment = player->clk_adj;
- /*
* a
* F = f + --------- * f = f + d
* 1000000
*
* a
* d = --------- * f
* 1000000
*
* where:
* f - nominal rate
* a - adjustment in ppm (parts per milion)
* F - rate to be set in synthesizer
* d - delta (difference) between f and F
*/
- if (adjustment < 0) {
/* div64_64 operates on unsigned values... */
delta = -1;
adjustment = -adjustment;
- } else {
delta = 1;
- }
- /* 500000 ppm is 0.5, which is used to round up values */
- delta *= (int)div64_u64((uint64_t)rate *
(uint64_t)adjustment + 500000, 1000000);
- rate_adjusted = rate + delta;
- /* Adjusted rate should never be == 0 */
- if (!rate_adjusted)
return -EINVAL;
- ret = clk_set_rate(player->clk, rate_adjusted);
- if (ret < 0)
return ret;
- rate_achieved = clk_get_rate(player->clk);
- if (!rate_achieved)
/* If value is 0 means that clock or parent not valid */
return -EINVAL;
- /*
* Using ALSA's adjustment control, we can modify the rate to be up
* to twice as much as requested, but no more
*/
- delta = rate_achieved - rate;
- if (delta < 0) {
/* div64_64 operates on unsigned values... */
delta = -delta;
adjustment = -1;
- } else {
adjustment = 1;
- }
- /* Frequency/2 is added to round up result */
- adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,
rate);
- player->clk_adj = adjustment;
- return 0;
-}
-static void uni_player_set_channel_status(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int n;
- unsigned int status;
- /*
* Some AVRs and TVs require the channel status to contain a correct
* sampling frequency. If no sample rate is already specified, then
* set one.
*/
- if (runtime) {
switch (runtime->rate) {
case 22050:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_22050;
break;
case 44100:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_44100;
break;
case 88200:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_88200;
break;
case 176400:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_176400;
break;
case 24000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_24000;
break;
case 48000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_48000;
break;
case 96000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_96000;
break;
case 192000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_192000;
break;
case 32000:
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_32000;
break;
default:
/* Mark as sampling frequency not indicated */
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_NOTID;
break;
}
- }
- /* Audio mode:
* Use audio mode status to select PCM or encoded mode
*/
- if (player->stream_settings.iec958.status[0] &
IEC958_AES0_NONAUDIO)
player->stream_settings.encoding_mode =
UNIPERIF_IEC958_ENCODING_MODE_ENCODED;
- else
player->stream_settings.encoding_mode =
UNIPERIF_IEC958_ENCODING_MODE_PCM;
- if (player->stream_settings.encoding_mode ==
UNIPERIF_IEC958_ENCODING_MODE_PCM)
/* Clear user validity bits */
SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
- else
/* Set user validity bits */
SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);
- /* Program the new channel status */
- for (n = 0; n < 6; ++n) {
status =
player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;
status |=
player->stream_settings.iec958.status[1 + (n * 4)] << 8;
status |=
player->stream_settings.iec958.status[2 + (n * 4)] << 16;
status |=
player->stream_settings.iec958.status[3 + (n * 4)] << 24;
SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
- }
- /* Update the channel status */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
- else
SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
-}
-static int uni_player_prepare_iec958(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int clk_div;
- clk_div = player->mclk / runtime->rate;
- /* Oversampling must be multiple of 128 as iec958 frame is 32-bits */
- if ((clk_div % 128) || (clk_div <= 0)) {
dev_err(player->dev, "%s: invalid clk_div %d\n",
__func__, clk_div);
return -EINVAL;
- }
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* 16/16 memory format */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
/* 16-bits per sub-frame */
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
/* Set 16-bit sample precision */
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/* 16/0 memory format */
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
/* 32-bits per sub-frame */
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
/* Set 24-bit sample precision */
SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- /* Set parity to be calculated by the hardware */
- SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);
- /* Set channel status bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);
- /* Set user data bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);
- /* Set validity bits to be inserted by the hardware */
- SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);
- /* Set full software control to disabled */
- SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);
- SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
- mutex_lock(&player->ctrl_lock);
- /* Update the channel status */
- uni_player_set_channel_status(player, runtime);
- mutex_unlock(&player->ctrl_lock);
- /* Clear the user validity user bits */
- SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
- /* Disable one-bit audio mode */
- SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
- /* Enable consecutive frames repetition of Z preamble (not for HBRA)
*/
- SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);
- /* Change to SUF0_SUBF1 and left/right channels swap! */
- SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);
- /* Set data output as MSB first */
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- if (player->stream_settings.encoding_mode ==
UNIPERIF_IEC958_ENCODING_MODE_ENCODED)
SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);
- else
SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
- /* Set rounding to off */
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- /* Set clock divisor */
- SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);
- /* Set the spdif latency to not wait before starting player */
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- /*
* Ensure iec958 formatting is off. It will be enabled in function
* uni_player_start() at the same time as the operation
* mode is set to work around a silicon issue.
*/
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
- else
SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
- return 0;
-}
-static int uni_player_prepare_pcm(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int output_frame_size, slot_width, clk_div;
- /* Force slot width to 32 in I2S mode (HW constraint) */
- if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
SND_SOC_DAIFMT_I2S)
slot_width = 32;
- else
slot_width = snd_pcm_format_width(runtime->format);
- output_frame_size = slot_width * runtime->channels;
- clk_div = player->mclk / runtime->rate;
- /*
* For 32 bits subframe clk_div must be a multiple of 128,
* for 16 bits must be a multiple of 64
*/
- if ((slot_width == 32) && (clk_div % 128)) {
dev_err(player->dev, "%s: invalid clk_div\n", __func__);
return -EINVAL;
- }
- if ((slot_width == 16) && (clk_div % 64)) {
dev_err(player->dev, "%s: invalid clk_div\n", __func__);
return -EINVAL;
- }
- /*
* Number of bits per subframe (which is one channel sample)
* on output - Transfer 16 or 32 bits from FIFO
*/
- switch (slot_width) {
- case 32:
SET_UNIPERIF_I2S_FMT_NBIT_32(player);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
break;
- case 16:
SET_UNIPERIF_I2S_FMT_NBIT_16(player);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
break;
- default:
dev_err(player->dev, "subframe format not supported\n");
return -EINVAL;
- }
- /* Configure data memory format */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* One data word contains two samples */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/*
* Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
* on the left than zeros (if less than 32 bytes)"... ;-)
*/
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- /* Set rounding to off */
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- /* Set clock divisor */
- SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 *
output_frame_size));
- /* Number of channelsmust be even*/
- if ((runtime->channels % 2) || (runtime->channels < 2) ||
(runtime->channels > 10)) {
dev_err(player->dev, "%s: invalid nb of channels\n", __func__);
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
- /* Set 1-bit audio format to disabled */
- SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- /* No iec958 formatting as outputting to DAC */
- SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
- return 0;
-}
-static int uni_player_prepare_tdm(struct uniperif *player,
struct snd_pcm_runtime *runtime)
-{
- int tdm_frame_size; /* unip tdm frame size in bytes */
- int user_frame_size; /* user tdm frame size in bytes */
- /* default unip TDM_WORD_POS_X_Y */
- unsigned int word_pos[4] = {
0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
- int freq, ret;
- tdm_frame_size =
sti_uniperiph_get_unip_tdm_frame_size(player);
- user_frame_size =
sti_uniperiph_get_user_frame_size(runtime);
- /* fix 16/0 format */
- SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
- SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
- /* number of words inserted on the TDM line */
- SET_UNIPERIF_I2S_FMT_NUM_CH(player, user_frame_size / 4 / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
- SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
- /* Enable the tdm functionality */
- SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(player);
- /* number of 8 bits timeslots avail in unip tdm frame */
- SET_UNIPERIF_TDM_FS_REF_DIV_NUM_TIMESLOT(player,
tdm_frame_size);
- /* set the timeslot allocation for words in FIFO */
- sti_uniperiph_get_tdm_word_pos(player, word_pos);
- SET_UNIPERIF_TDM_WORD_POS(player, 1_2, word_pos[WORD_1_2]);
- SET_UNIPERIF_TDM_WORD_POS(player, 3_4, word_pos[WORD_3_4]);
- SET_UNIPERIF_TDM_WORD_POS(player, 5_6, word_pos[WORD_5_6]);
- SET_UNIPERIF_TDM_WORD_POS(player, 7_8, word_pos[WORD_7_8]);
- /* set unip clk rate (not done vai set_sysclk ops) */
- freq = runtime->rate * tdm_frame_size * 8;
- mutex_lock(&player->ctrl_lock);
- ret = uni_player_clk_set_rate(player, freq);
- if (!ret)
player->mclk = freq;
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-/*
- ALSA uniperipheral iec958 controls
- */
-static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
- uinfo->count = 1;
- return 0;
-}
-static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
- mutex_lock(&player->ctrl_lock);
- ucontrol->value.iec958.status[0] = iec958->status[0];
- ucontrol->value.iec958.status[1] = iec958->status[1];
- ucontrol->value.iec958.status[2] = iec958->status[2];
- ucontrol->value.iec958.status[3] = iec958->status[3];
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
- unsigned long flags;
- mutex_lock(&player->ctrl_lock);
- iec958->status[0] = ucontrol->value.iec958.status[0];
- iec958->status[1] = ucontrol->value.iec958.status[1];
- iec958->status[2] = ucontrol->value.iec958.status[2];
- iec958->status[3] = ucontrol->value.iec958.status[3];
- spin_lock_irqsave(&player->irq_lock, flags);
- if (player->substream && player->substream->runtime)
uni_player_set_channel_status(player,
player->substream->runtime);
- else
uni_player_set_channel_status(player, NULL);
- spin_unlock_irqrestore(&player->irq_lock, flags);
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static struct snd_kcontrol_new uni_player_iec958_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
- .info = uni_player_ctl_iec958_info,
- .get = uni_player_ctl_iec958_get,
- .put = uni_player_ctl_iec958_put,
-};
-/*
- uniperif rate adjustement control
- */
-static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;
- uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
- uinfo->value.integer.step = 1;
- return 0;
-}
-static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- mutex_lock(&player->ctrl_lock);
- ucontrol->value.integer.value[0] = player->clk_adj;
- mutex_unlock(&player->ctrl_lock);
- return 0;
-}
-static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- int ret = 0;
- if ((ucontrol->value.integer.value[0] <
UNIPERIF_PLAYER_CLK_ADJ_MIN) ||
(ucontrol->value.integer.value[0] >
UNIPERIF_PLAYER_CLK_ADJ_MAX))
return -EINVAL;
- mutex_lock(&player->ctrl_lock);
- player->clk_adj = ucontrol->value.integer.value[0];
- if (player->mclk)
ret = uni_player_clk_set_rate(player, player->mclk);
- mutex_unlock(&player->ctrl_lock);
- return ret;
-}
-static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
- .name = "PCM Playback Oversampling Freq. Adjustment",
- .info = snd_sti_clk_adjustment_info,
- .get = snd_sti_clk_adjustment_get,
- .put = snd_sti_clk_adjustment_put,
-};
-static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
- &uni_player_clk_adj_ctl,
-};
-static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
- &uni_player_iec958_ctl,
- &uni_player_clk_adj_ctl,
-};
-static int uni_player_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- unsigned long flags;
- int ret;
- spin_lock_irqsave(&player->irq_lock, flags);
- player->substream = substream;
- spin_unlock_irqrestore(&player->irq_lock, flags);
- player->clk_adj = 0;
- if (!UNIPERIF_TYPE_IS_TDM(player))
return 0;
- /* refine hw constraint in tdm mode */
- ret = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
sti_uniperiph_fix_tdm_chan,
player,
SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
- if (ret < 0)
return ret;
- return snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
sti_uniperiph_fix_tdm_format,
player, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
-}
-static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,
unsigned int freq, int dir)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- int ret;
- if (UNIPERIF_TYPE_IS_TDM(player) || (dir == SND_SOC_CLOCK_IN))
return 0;
- if (clk_id != 0)
return -EINVAL;
- mutex_lock(&player->ctrl_lock);
- ret = uni_player_clk_set_rate(player, freq);
- if (!ret)
player->mclk = freq;
- mutex_unlock(&player->ctrl_lock);
- return ret;
-}
-static int uni_player_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int transfer_size, trigger_limit;
- int ret;
- /* The player should be stopped */
- if (player->state != UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state %d\n", __func__,
player->state);
return -EINVAL;
- }
- /* Calculate transfer size (in fifo cells and bytes) for frame count */
- if (player->type == SND_ST_UNIPERIF_TYPE_TDM) {
/* transfer size = user frame size (in 32 bits FIFO cell) */
transfer_size =
sti_uniperiph_get_user_frame_size(runtime) / 4;
- } else {
transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
- }
- /* Calculate number of empty cells available before asserting DREQ */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
- } else {
/*
* Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
* FDMA_TRIGGER_LIMIT also controls when the state switches
* from OFF or STANDBY to AUDIO DATA.
*/
trigger_limit = transfer_size;
- }
- /* Trigger limit must be an even number */
- if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||
(trigger_limit >
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {
dev_err(player->dev, "invalid trigger limit %d\n",
trigger_limit);
return -EINVAL;
- }
- SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);
- /* Uniperipheral setup depends on player type */
- switch (player->type) {
- case SND_ST_UNIPERIF_TYPE_HDMI:
ret = uni_player_prepare_iec958(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_PCM:
ret = uni_player_prepare_pcm(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_SPDIF:
ret = uni_player_prepare_iec958(player, runtime);
break;
- case SND_ST_UNIPERIF_TYPE_TDM:
ret = uni_player_prepare_tdm(player, runtime);
break;
- default:
dev_err(player->dev, "invalid player type\n");
return -EINVAL;
- }
- if (ret)
return ret;
- switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
break;
- case SND_SOC_DAIFMT_NB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
break;
- case SND_SOC_DAIFMT_IB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
break;
- case SND_SOC_DAIFMT_IB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
break;
- }
- switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);
break;
- case SND_SOC_DAIFMT_LEFT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
break;
- case SND_SOC_DAIFMT_RIGHT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
break;
- default:
dev_err(player->dev, "format not supported\n");
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);
- return sti_uniperiph_reset(player);
-}
-static int uni_player_start(struct uniperif *player) -{
- int ret;
- /* The player should be stopped */
- if (player->state != UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state\n", __func__);
return -EINVAL;
- }
- ret = clk_prepare_enable(player->clk);
- if (ret) {
dev_err(player->dev, "%s: Failed to enable clock\n", __func__);
return ret;
- }
- /* Clear any pending interrupts */
- SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));
- /* Set the interrupt mask */
- SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);
- /* Enable underflow recovery interrupts */
- if (player->underflow_enabled) {
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
- }
- ret = sti_uniperiph_reset(player);
- if (ret < 0) {
clk_disable_unprepare(player->clk);
return ret;
- }
- /*
* Does not use IEC61937 features of the uniperipheral hardware.
* Instead it performs IEC61937 in software and inserts it directly
* into the audio data stream. As such, when encoded mode is selected,
* linear pcm mode is still used, but with the differences of the
* channel status bits set for encoded mode and the validity bits set.
*/
- SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);
- /*
* If iec958 formatting is required for hdmi or spdif, then it must be
* enabled after the operation mode is set. If set prior to this, it
* will not take affect and hang the player.
*/
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
if (UNIPERIF_TYPE_IS_IEC958(player))
SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
- /* Force channel status update (no update if clk disable) */
- if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
- else
SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
- /* Update state to started */
- player->state = UNIPERIF_STATE_STARTED;
- return 0;
-}
-static int uni_player_stop(struct uniperif *player) -{
- int ret;
- /* The player should not be in stopped state */
- if (player->state == UNIPERIF_STATE_STOPPED) {
dev_err(player->dev, "%s: invalid player state\n", __func__);
return -EINVAL;
- }
- /* Turn the player off */
- SET_UNIPERIF_CTRL_OPERATION_OFF(player);
- ret = sti_uniperiph_reset(player);
- if (ret < 0)
return ret;
- /* Disable interrupts */
- SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));
- /* Disable clock */
- clk_disable_unprepare(player->clk);
- /* Update state to stopped and return */
- player->state = UNIPERIF_STATE_STOPPED;
- return 0;
-}
-int uni_player_resume(struct uniperif *player) -{
- int ret;
- /* Select the frequency synthesizer clock */
- if (player->clk_sel) {
ret = regmap_field_write(player->clk_sel, 1);
if (ret) {
dev_err(player->dev,
"%s: Failed to select freq synth clock\n",
__func__);
return ret;
}
- }
- SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
- return 0;
-} -EXPORT_SYMBOL_GPL(uni_player_resume);
-static int uni_player_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
return uni_player_start(player);
- case SNDRV_PCM_TRIGGER_STOP:
return uni_player_stop(player);
- case SNDRV_PCM_TRIGGER_RESUME:
return uni_player_resume(player);
- default:
return -EINVAL;
- }
-}
-static void uni_player_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *player = priv->dai_data.uni;
- unsigned long flags;
- spin_lock_irqsave(&player->irq_lock, flags);
- if (player->state != UNIPERIF_STATE_STOPPED)
/* Stop the player */
uni_player_stop(player);
- player->substream = NULL;
- spin_unlock_irqrestore(&player->irq_lock, flags);
-}
-static int uni_player_parse_dt_audio_glue(struct platform_device *pdev,
struct uniperif *player)
-{
- struct device_node *node = pdev->dev.of_node;
- struct regmap *regmap;
- struct reg_field regfield[2] = {
/* PCM_CLK_SEL */
REG_FIELD(SYS_CFG_AUDIO_GLUE,
8 + player->id,
8 + player->id),
/* PCMP_VALID_SEL */
REG_FIELD(SYS_CFG_AUDIO_GLUE, 0, 1)
- };
- regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
- if (IS_ERR(regmap)) {
dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
return PTR_ERR(regmap);
- }
- player->clk_sel = regmap_field_alloc(regmap, regfield[0]);
- player->valid_sel = regmap_field_alloc(regmap, regfield[1]);
- return 0;
-}
-static const struct snd_soc_dai_ops uni_player_dai_ops = {
.startup = uni_player_startup,
.shutdown = uni_player_shutdown,
.prepare = uni_player_prepare,
.trigger = uni_player_trigger,
.hw_params = sti_uniperiph_dai_hw_params,
.set_fmt = sti_uniperiph_dai_set_fmt,
.set_sysclk = uni_player_set_sysclk,
.set_tdm_slot = sti_uniperiph_set_tdm_slot
-};
-int uni_player_init(struct platform_device *pdev,
struct uniperif *player)
-{
- int ret = 0;
- player->dev = &pdev->dev;
- player->state = UNIPERIF_STATE_STOPPED;
- player->dai_ops = &uni_player_dai_ops;
- /* Get PCM_CLK_SEL & PCMP_VALID_SEL from audio-glue-ctrl SoC reg
*/
- ret = uni_player_parse_dt_audio_glue(pdev, player);
- if (ret < 0) {
dev_err(player->dev, "Failed to parse DeviceTree\n");
return ret;
- }
- /* Underflow recovery is only supported on later ip revisions */
- if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
player->underflow_enabled = 1;
- if (UNIPERIF_TYPE_IS_TDM(player))
player->hw = &uni_tdm_hw;
- else
player->hw = &uni_player_pcm_hw;
- /* Get uniperif resource */
- player->clk = of_clk_get(pdev->dev.of_node, 0);
- if (IS_ERR(player->clk)) {
dev_err(player->dev, "Failed to get clock\n");
return PTR_ERR(player->clk);
- }
- /* Select the frequency synthesizer clock */
- if (player->clk_sel) {
ret = regmap_field_write(player->clk_sel, 1);
if (ret) {
dev_err(player->dev,
"%s: Failed to select freq synth clock\n",
__func__);
return ret;
}
- }
- /* connect to I2S/TDM TX bus */
- if (player->valid_sel &&
(player->id == UNIPERIF_PLAYER_I2S_OUT)) {
ret = regmap_field_write(player->valid_sel, player->id);
if (ret) {
dev_err(player->dev,
"%s: unable to connect to tdm bus\n",
__func__);
return ret;
}
- }
- ret = devm_request_irq(&pdev->dev, player->irq,
uni_player_irq_handler, IRQF_SHARED,
dev_name(&pdev->dev), player);
- if (ret < 0) {
dev_err(player->dev, "unable to request IRQ %d\n", player-
irq);
return ret;
- }
- mutex_init(&player->ctrl_lock);
- spin_lock_init(&player->irq_lock);
- /* Ensure that disabled by default */
- SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
- SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
- SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
- SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
- if (UNIPERIF_TYPE_IS_IEC958(player)) {
/* Set default iec958 status bits */
/* Consumer, PCM, copyright, 2ch, mode 0 */
player->stream_settings.iec958.status[0] = 0x00;
/* Broadcast reception category */
player->stream_settings.iec958.status[1] =
IEC958_AES1_CON_GENERAL;
/* Do not take into account source or channel number */
player->stream_settings.iec958.status[2] =
IEC958_AES2_CON_SOURCE_UNSPEC;
/* Sampling frequency not indicated */
player->stream_settings.iec958.status[3] =
IEC958_AES3_CON_FS_NOTID;
/* Max sample word 24-bit, sample word length not indicated
*/
player->stream_settings.iec958.status[4] =
IEC958_AES4_CON_MAX_WORDLEN_24 |
IEC958_AES4_CON_WORDLEN_24_20;
player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
player->snd_ctrls = snd_sti_iec_ctl[0];
- } else {
player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
player->snd_ctrls = snd_sti_pcm_ctl[0];
- }
- return 0;
-} -EXPORT_SYMBOL_GPL(uni_player_init); diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c deleted file mode 100644 index 136059331211..000000000000 --- a/sound/soc/sti/uniperif_reader.c +++ /dev/null @@ -1,436 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/*
- Copyright (C) STMicroelectronics SA 2015
- Authors: Arnaud Pouliquen arnaud.pouliquen@st.com
for STMicroelectronics.
- */
-#include <sound/soc.h>
-#include "uniperif.h"
-#define UNIPERIF_READER_I2S_IN 0 /* reader id connected to I2S/TDM TX
bus */
-/*
- Note: snd_pcm_hardware is linked to DMA controller but is declared here
to
- integrate unireader capability in term of rate and supported channels
- */
-static const struct snd_pcm_hardware uni_reader_pcm_hw = {
- .info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
- .formats = SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_CONTINUOUS,
- .rate_min = 8000,
- .rate_max = 96000,
- .channels_min = 2,
- .channels_max = 8,
- .periods_min = 2,
- .periods_max = 48,
- .period_bytes_min = 128,
- .period_bytes_max = 64 * PAGE_SIZE,
- .buffer_bytes_max = 256 * PAGE_SIZE
-};
-/*
- uni_reader_irq_handler
- In case of error audio stream is stopped; stop action is protected via PCM
- stream lock to avoid race condition with trigger callback.
- */
-static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id) -{
- irqreturn_t ret = IRQ_NONE;
- struct uniperif *reader = dev_id;
- unsigned int status;
- spin_lock(&reader->irq_lock);
- if (!reader->substream)
goto irq_spin_unlock;
- snd_pcm_stream_lock(reader->substream);
- if (reader->state == UNIPERIF_STATE_STOPPED) {
/* Unexpected IRQ: do nothing */
dev_warn(reader->dev, "unexpected IRQ\n");
goto stream_unlock;
- }
- /* Get interrupt status & clear them immediately */
- status = GET_UNIPERIF_ITS(reader);
- SET_UNIPERIF_ITS_BCLR(reader, status);
- /* Check for fifo overflow error */
- if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
dev_err(reader->dev, "FIFO error detected\n");
snd_pcm_stop_xrun(reader->substream);
ret = IRQ_HANDLED;
- }
-stream_unlock:
- snd_pcm_stream_unlock(reader->substream);
-irq_spin_unlock:
- spin_unlock(&reader->irq_lock);
- return ret;
-}
-static int uni_reader_prepare_pcm(struct snd_pcm_runtime *runtime,
struct uniperif *reader)
-{
- int slot_width;
- /* Force slot width to 32 in I2S mode */
- if ((reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK)
== SND_SOC_DAIFMT_I2S) {
slot_width = 32;
- } else {
switch (runtime->format) {
case SNDRV_PCM_FORMAT_S16_LE:
slot_width = 16;
break;
default:
slot_width = 32;
break;
}
- }
- /* Number of bits per subframe (i.e one channel sample) on input. */
- switch (slot_width) {
- case 32:
SET_UNIPERIF_I2S_FMT_NBIT_32(reader);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
break;
- case 16:
SET_UNIPERIF_I2S_FMT_NBIT_16(reader);
SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(reader);
break;
- default:
dev_err(reader->dev, "subframe format not supported\n");
return -EINVAL;
- }
- /* Configure data memory format */
- switch (runtime->format) {
- case SNDRV_PCM_FORMAT_S16_LE:
/* One data word contains two samples */
SET_UNIPERIF_CONFIG_MEM_FMT_16_16(reader);
break;
- case SNDRV_PCM_FORMAT_S32_LE:
/*
* Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
* on the MSB then zeros (if less than 32 bytes)"...
*/
SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
break;
- default:
dev_err(reader->dev, "format not supported\n");
return -EINVAL;
- }
- /* Number of channels must be even */
- if ((runtime->channels % 2) || (runtime->channels < 2) ||
(runtime->channels > 10)) {
dev_err(reader->dev, "%s: invalid nb of channels\n", __func__);
return -EINVAL;
- }
- SET_UNIPERIF_I2S_FMT_NUM_CH(reader, runtime->channels / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
- return 0;
-}
-static int uni_reader_prepare_tdm(struct snd_pcm_runtime *runtime,
struct uniperif *reader)
-{
- int frame_size; /* user tdm frame size in bytes */
- /* default unip TDM_WORD_POS_X_Y */
- unsigned int word_pos[4] = {
0x04060002, 0x0C0E080A, 0x14161012, 0x1C1E181A};
- frame_size = sti_uniperiph_get_user_frame_size(runtime);
- /* fix 16/0 format */
- SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
- SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
- /* number of words inserted on the TDM line */
- SET_UNIPERIF_I2S_FMT_NUM_CH(reader, frame_size / 4 / 2);
- SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
- SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
- SET_UNIPERIF_TDM_ENABLE_TDM_ENABLE(reader);
- /*
* set the timeslots allocation for words in FIFO
*
* HW bug: (LSB word < MSB word) => this config is not possible
* So if we want (LSB word < MSB) word, then it shall be
* handled by user
*/
- sti_uniperiph_get_tdm_word_pos(reader, word_pos);
- SET_UNIPERIF_TDM_WORD_POS(reader, 1_2, word_pos[WORD_1_2]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 3_4, word_pos[WORD_3_4]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 5_6, word_pos[WORD_5_6]);
- SET_UNIPERIF_TDM_WORD_POS(reader, 7_8, word_pos[WORD_7_8]);
- return 0;
-}
-static int uni_reader_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- struct snd_pcm_runtime *runtime = substream->runtime;
- int transfer_size, trigger_limit, ret;
- /* The reader should be stopped */
- if (reader->state != UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state %d\n",
__func__,
reader->state);
return -EINVAL;
- }
- /* Calculate transfer size (in fifo cells and bytes) for frame count */
- if (reader->type == SND_ST_UNIPERIF_TYPE_TDM) {
/* transfer size = unip frame size (in 32 bits FIFO cell) */
transfer_size =
sti_uniperiph_get_user_frame_size(runtime) / 4;
- } else {
transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
- }
- /* Calculate number of empty cells available before asserting DREQ */
- if (reader->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
- else
/*
* Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
* FDMA_TRIGGER_LIMIT also controls when the state switches
* from OFF or STANDBY to AUDIO DATA.
*/
trigger_limit = transfer_size;
- /* Trigger limit must be an even number */
- if ((!trigger_limit % 2) ||
(trigger_limit != 1 && transfer_size % 2) ||
(trigger_limit >
UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(reader))) {
dev_err(reader->dev, "invalid trigger limit %d\n",
trigger_limit);
return -EINVAL;
- }
- SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(reader, trigger_limit);
- if (UNIPERIF_TYPE_IS_TDM(reader))
ret = uni_reader_prepare_tdm(runtime, reader);
- else
ret = uni_reader_prepare_pcm(runtime, reader);
- if (ret)
return ret;
- switch (reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
- case SND_SOC_DAIFMT_I2S:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(reader);
break;
- case SND_SOC_DAIFMT_LEFT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
break;
- case SND_SOC_DAIFMT_RIGHT_J:
SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(reader);
SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
break;
- default:
dev_err(reader->dev, "format not supported\n");
return -EINVAL;
- }
- /* Data clocking (changing) on the rising/falling edge */
- switch (reader->daifmt & SND_SOC_DAIFMT_INV_MASK) {
- case SND_SOC_DAIFMT_NB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
break;
- case SND_SOC_DAIFMT_NB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
break;
- case SND_SOC_DAIFMT_IB_NF:
SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
break;
- case SND_SOC_DAIFMT_IB_IF:
SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(reader);
break;
- }
- /* Clear any pending interrupts */
- SET_UNIPERIF_ITS_BCLR(reader, GET_UNIPERIF_ITS(reader));
- SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(reader, 0);
- /* Set the interrupt mask */
- SET_UNIPERIF_ITM_BSET_DMA_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader);
- /* Enable underflow recovery interrupts */
- if (reader->underflow_enabled) {
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader);
SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader);
- }
- /* Reset uniperipheral reader */
- return sti_uniperiph_reset(reader);
-}
-static int uni_reader_start(struct uniperif *reader) -{
- /* The reader should be stopped */
- if (reader->state != UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state\n", __func__);
return -EINVAL;
- }
- /* Enable reader interrupts (and clear possible stalled ones) */
- SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(reader);
- SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
- /* Launch the reader */
- SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(reader);
- /* Update state to started */
- reader->state = UNIPERIF_STATE_STARTED;
- return 0;
-}
-static int uni_reader_stop(struct uniperif *reader) -{
- /* The reader should not be in stopped state */
- if (reader->state == UNIPERIF_STATE_STOPPED) {
dev_err(reader->dev, "%s: invalid reader state\n", __func__);
return -EINVAL;
- }
- /* Turn the reader off */
- SET_UNIPERIF_CTRL_OPERATION_OFF(reader);
- /* Disable interrupts */
- SET_UNIPERIF_ITM_BCLR(reader, GET_UNIPERIF_ITM(reader));
- /* Update state to stopped and return */
- reader->state = UNIPERIF_STATE_STOPPED;
- return 0;
-}
-static int uni_reader_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
return uni_reader_start(reader);
- case SNDRV_PCM_TRIGGER_STOP:
return uni_reader_stop(reader);
- default:
return -EINVAL;
- }
-}
-static int uni_reader_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- unsigned long flags;
- int ret;
- spin_lock_irqsave(&reader->irq_lock, flags);
- reader->substream = substream;
- spin_unlock_irqrestore(&reader->irq_lock, flags);
- if (!UNIPERIF_TYPE_IS_TDM(reader))
return 0;
- /* refine hw constraint in tdm mode */
- ret = snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
sti_uniperiph_fix_tdm_chan,
reader,
SNDRV_PCM_HW_PARAM_CHANNELS,
-1);
- if (ret < 0)
return ret;
- return snd_pcm_hw_rule_add(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
sti_uniperiph_fix_tdm_format,
reader, SNDRV_PCM_HW_PARAM_FORMAT,
-1);
-}
-static void uni_reader_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-{
- struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
- struct uniperif *reader = priv->dai_data.uni;
- unsigned long flags;
- spin_lock_irqsave(&reader->irq_lock, flags);
- if (reader->state != UNIPERIF_STATE_STOPPED) {
/* Stop the reader */
uni_reader_stop(reader);
- }
- reader->substream = NULL;
- spin_unlock_irqrestore(&reader->irq_lock, flags);
-}
-static const struct snd_soc_dai_ops uni_reader_dai_ops = {
.startup = uni_reader_startup,
.shutdown = uni_reader_shutdown,
.prepare = uni_reader_prepare,
.trigger = uni_reader_trigger,
.hw_params = sti_uniperiph_dai_hw_params,
.set_fmt = sti_uniperiph_dai_set_fmt,
.set_tdm_slot = sti_uniperiph_set_tdm_slot
-};
-int uni_reader_init(struct platform_device *pdev,
struct uniperif *reader)
-{
- int ret = 0;
- reader->dev = &pdev->dev;
- reader->state = UNIPERIF_STATE_STOPPED;
- reader->dai_ops = &uni_reader_dai_ops;
- if (UNIPERIF_TYPE_IS_TDM(reader))
reader->hw = &uni_tdm_hw;
- else
reader->hw = &uni_reader_pcm_hw;
- ret = devm_request_irq(&pdev->dev, reader->irq,
uni_reader_irq_handler, IRQF_SHARED,
dev_name(&pdev->dev), reader);
- if (ret < 0) {
dev_err(&pdev->dev, "Failed to request IRQ\n");
return -EBUSY;
- }
- spin_lock_init(&reader->irq_lock);
- return 0;
-}
-EXPORT_SYMBOL_GPL(uni_reader_init);
2.35.1
Hi Arnaud,
On Tue, 15 Mar 2022 at 22:15, Arnaud POULIQUEN arnaud.pouliquen@st.com wrote:
Yeah, that looks dead.
The platform is still used for instance: https://lore.kernel.org/all/1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com...
So please do not remove the driver
The issue has not been detected because it is related to an error that occurs only when we reach the limit of the platform, with application that stop the stream at same time. So almost no chance to occur.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
Yes reverting the commit is one solution. The other is to clean-up the snd_pcm_stream_lock/ snd_pcm_stream_unlock in the Handler.
I will try to address this in few weeks
Feel free to ignore my patch then. I couldn't find anything that used it's DT compatible etc and assumed it was orphaned.
Cheers,
Daniel
On Tue, 15 Mar 2022 14:15:20 +0100, Arnaud POULIQUEN wrote:
Hello,
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 11:28 To: Daniel Palmer daniel@0x0f.com Cc: broonie@kernel.org; tiwai@suse.com; Arnaud POULIQUEN arnaud.pouliquen@st.com; alsa-devel@alsa-project.org; linux- kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 10:13:19 +0100, Daniel Palmer wrote:
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Mea culpa, that was an obvious deadlock I overlooked in the patch series.
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com
I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
Yeah, that looks dead.
The platform is still used for instance: https://lore.kernel.org/all/1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss.st.com...
So please do not remove the driver
Ah, it's always good to see a vital sign!
The issue has not been detected because it is related to an error that occurs only when we reach the limit of the platform, with application that stop the stream at same time. So almost no chance to occur.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
Yes reverting the commit is one solution. The other is to clean-up the snd_pcm_stream_lock/ snd_pcm_stream_unlock in the Handler.
That would work, but maybe it's safer to keep that lock, as the state change isn't protected by irq_lock but only implicitly by stream lock in start/stop callbacks.
thanks,
Takashi
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 15:35 To: Arnaud POULIQUEN arnaud.pouliquen@st.com Cc: Daniel Palmer daniel@0x0f.com; broonie@kernel.org; tiwai@suse.com; alsa-devel@alsa-project.org; linux-kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 14:15:20 +0100, Arnaud POULIQUEN wrote:
Hello,
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 11:28 To: Daniel Palmer daniel@0x0f.com Cc: broonie@kernel.org; tiwai@suse.com; Arnaud POULIQUEN arnaud.pouliquen@st.com; alsa-devel@alsa-project.org; linux- kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 10:13:19 +0100, Daniel Palmer wrote:
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Mea culpa, that was an obvious deadlock I overlooked in the patch series.
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com
I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
Yeah, that looks dead.
The platform is still used for instance: https://lore.kernel.org/all/1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss. st.com/
So please do not remove the driver
Ah, it's always good to see a vital sign!
The issue has not been detected because it is related to an error that occurs only when we reach the limit of the platform, with application that stop the stream at same time. So almost no chance to occur.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
Yes reverting the commit is one solution. The other is to clean-up the snd_pcm_stream_lock/ snd_pcm_stream_unlock in the Handler.
That would work, but maybe it's safer to keep that lock, as the state change isn't protected by irq_lock but only implicitly by stream lock in start/stop callbacks.
You are right, trying to use the snd_pcm_stop_xrun needs deeper update that could introduce regression. It seems wiser to revert your commit dc865fb9e7c2 as you propose.
Thanks, Arnaud
thanks,
Takashi
On Tue, 15 Mar 2022 16:27:40 +0100, Arnaud POULIQUEN wrote:
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 15:35 To: Arnaud POULIQUEN arnaud.pouliquen@st.com Cc: Daniel Palmer daniel@0x0f.com; broonie@kernel.org; tiwai@suse.com; alsa-devel@alsa-project.org; linux-kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 14:15:20 +0100, Arnaud POULIQUEN wrote:
Hello,
ST Restricted
-----Original Message----- From: Takashi Iwai tiwai@suse.de Sent: mardi 15 mars 2022 11:28 To: Daniel Palmer daniel@0x0f.com Cc: broonie@kernel.org; tiwai@suse.com; Arnaud POULIQUEN arnaud.pouliquen@st.com; alsa-devel@alsa-project.org; linux- kernel@vger.kernel.org Subject: Re: [PATCH] ASoC: sti: sti_uniperif: Remove driver
On Tue, 15 Mar 2022 10:13:19 +0100, Daniel Palmer wrote:
This driver seems to be in the "only good for attracting bot generated patches" phase of it's life.
It doesn't seem like anyone actually tested the patches that have been applied in the last few years as uni_reader_irq_handler() had a dead lock added to it (it locks the stream, then calls snd_pcm_stop_xrun() which will also lock the stream).
Mea culpa, that was an obvious deadlock I overlooked in the patch series.
Seems best just to remove it.
Signed-off-by: Daniel Palmer daniel@0x0f.com
I've never used this driver, don't have the hardware etc. I just noticed that this looks broken when debugging my own driver that uses snd_pcm_stop_xrun() and was looking at other users to see if I was using it wrong and noticed this was the only place that locked the stream before calling snd_pcm_stop_xrun().
There are probably some other bits of the driver that should be removed but I didn't look that hard.
TL;DR; This driver seems broken, seems like nobody uses it. Maybe it should be deleted?
Yeah, that looks dead.
The platform is still used for instance: https://lore.kernel.org/all/1d95209f-9cb4-47a3-2696-7a93df7cdc05@foss. st.com/
So please do not remove the driver
Ah, it's always good to see a vital sign!
The issue has not been detected because it is related to an error that occurs only when we reach the limit of the platform, with application that stop the stream at same time. So almost no chance to occur.
OTOH, if anyone really wants to keep the stuff, please revert the commit dc865fb9e7c2251c9585ff6a7bf185d499db13e4.
Yes reverting the commit is one solution. The other is to clean-up the snd_pcm_stream_lock/ snd_pcm_stream_unlock in the Handler.
That would work, but maybe it's safer to keep that lock, as the state change isn't protected by irq_lock but only implicitly by stream lock in start/stop callbacks.
You are right, trying to use the snd_pcm_stop_xrun needs deeper update that could introduce regression. It seems wiser to revert your commit dc865fb9e7c2 as you propose.
OK, I'm going to submit the revert.
thanks,
Takashi
Hi Daniel,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master] [also build test ERROR on v5.17-rc8 next-20220310] [cannot apply to broonie-sound/for-next tiwai-sound/for-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Daniel-Palmer/ASoC-sti-sti_uniperif... base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 09688c0166e76ce2fb85e86b9d99be8b0084cdf9 config: x86_64-randconfig-a011-20220314 compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project a6b2f50fb47da3baeee10b1906da6e30ac5d26ec) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/7970e4bb3de4ff810c1dafb8ac38d222d90c... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Daniel-Palmer/ASoC-sti-sti_uniperif-Remove-driver/20220315-171525 git checkout 7970e4bb3de4ff810c1dafb8ac38d222d90ca071 COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64 randconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: oldconfig] Error 1 make[1]: *** [Makefile:619: oldconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'oldconfig' not remade because of errors. --
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: olddefconfig] Error 1 make[1]: *** [Makefile:619: olddefconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'olddefconfig' not remade because of errors.
vim +86 sound/soc/Kconfig
89fe5117928b2c1 Takashi Iwai 2008-05-23 25 89fe5117928b2c1 Takashi Iwai 2008-05-23 26 config SND_SOC_AC97_BUS 89fe5117928b2c1 Takashi Iwai 2008-05-23 27 bool 89fe5117928b2c1 Takashi Iwai 2008-05-23 28 28c4468b00a1e55 Lars-Peter Clausen 2013-04-15 29 config SND_SOC_GENERIC_DMAENGINE_PCM 28c4468b00a1e55 Lars-Peter Clausen 2013-04-15 30 bool b7ae6f31d8243ec Daniel Mack 2013-08-12 31 select SND_DMAENGINE_PCM 28c4468b00a1e55 Lars-Peter Clausen 2013-04-15 32 6f0c42269f000b1 Jie Yang 2015-10-13 33 config SND_SOC_COMPRESS 6f0c42269f000b1 Jie Yang 2015-10-13 34 bool 6f0c42269f000b1 Jie Yang 2015-10-13 35 select SND_COMPRESS_OFFLOAD 6f0c42269f000b1 Jie Yang 2015-10-13 36 78b50f39142612d Mark Brown 2015-08-15 37 config SND_SOC_TOPOLOGY 78b50f39142612d Mark Brown 2015-08-15 38 bool 2635c226036c1bf Peter Ujfalusi 2021-07-26 39 select SND_DYNAMIC_MINORS 78b50f39142612d Mark Brown 2015-08-15 40 b5fb388da472a69 Nico Pache 2021-04-14 41 config SND_SOC_TOPOLOGY_KUNIT_TEST d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 42 tristate "KUnit tests for SoC topology" d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 43 depends on KUNIT d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 44 depends on SND_SOC_TOPOLOGY d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 45 default KUNIT_ALL_TESTS d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 46 help d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 47 If you want to perform tests on ALSA SoC topology support say Y here. d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 48 d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 49 This builds a module which can be later manually loaded to run KUNIT d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 50 test cases against soc-topology.c API. This should be primarily used d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 51 by developers to test their changes to ASoC. d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 52 d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 53 Do note that it creates fake playback devices which do not interact d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 54 well with userspace. When running tests one may want to disable d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 55 userspace applications such as pulseaudio, to prevent unnecessary d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 56 problems. d52bbf747cfa8a2 Amadeusz Sławiński 2021-01-20 57 7feb2f786a46d34 Pierre-Louis Bossart 2017-10-12 58 config SND_SOC_ACPI 7feb2f786a46d34 Pierre-Louis Bossart 2017-10-12 59 tristate 7feb2f786a46d34 Pierre-Louis Bossart 2017-10-12 60 0b34a3d03e2fa61 Mark Brown 2008-12-16 61 # All the supported SoCs 8f2fe346822419e Lars-Peter Clausen 2013-12-06 62 source "sound/soc/adi/Kconfig" 7c31335a03b6aff Maruthi Srinivas Bayyavarapu 2016-01-08 63 source "sound/soc/amd/Kconfig" 6c7425095c9ee23 Sedji Gaouaou 2008-10-03 64 source "sound/soc/atmel/Kconfig" 4a161d235b68eb7 Manuel Lauss 2008-07-09 65 source "sound/soc/au1x/Kconfig" c6aeb7de226dd08 Florian Meier 2013-11-22 66 source "sound/soc/bcm/Kconfig" 0ed275eff31029c Alexander Shiyan 2012-08-21 67 source "sound/soc/cirrus/Kconfig" 3a9cf8efd7b64f2 Rajeev Kumar 2012-06-21 68 source "sound/soc/dwc/Kconfig" 0b34a3d03e2fa61 Mark Brown 2008-12-16 69 source "sound/soc/fsl/Kconfig" 0bf750f4cbe1406 Andy Green 2017-03-31 70 source "sound/soc/hisilicon/Kconfig" 9af8381023e48bf Mark Brown 2010-07-05 71 source "sound/soc/jz4740/Kconfig" f9b95980f87f021 apatard@mandriva.com 2010-05-31 72 source "sound/soc/kirkwood/Kconfig" 14b947d9ced4f72 Damien.Horsley 2015-11-04 73 source "sound/soc/img/Kconfig" 784cbf8ab4641c8 Jarkko Nikula 2013-11-21 74 source "sound/soc/intel/Kconfig" ee0bcaff109f36d Koro Chen 2015-06-15 75 source "sound/soc/mediatek/Kconfig" 6dc4fa179fb86d2 Jerome Brunet 2018-07-17 76 source "sound/soc/meson/Kconfig" 009ad054b71b772 Dong Aisheng 2011-07-21 77 source "sound/soc/mxs/Kconfig" 734c2d4bb7cfcca Liam Girdwood 2006-10-12 78 source "sound/soc/pxa/Kconfig" 6a328885896ef08 Kenneth Westfield 2015-03-13 79 source "sound/soc/qcom/Kconfig" 4495c89fcf2624d Jianqun Xu 2014-07-05 80 source "sound/soc/rockchip/Kconfig" 5033f43c6675429 Jassi Brar 2010-11-22 81 source "sound/soc/samsung/Kconfig" aef3b06ac69783d Manuel Lauss 2007-05-14 82 source "sound/soc/sh/Kconfig" 7e978fa37df7f77 Liam Girdwood 2019-04-12 83 source "sound/soc/sof/Kconfig" e58070ee4fdf797 Rajeev Kumar 2013-06-10 84 source "sound/soc/spear/Kconfig" 42fea318e1d19c0 Baolin Wang 2019-01-29 85 source "sound/soc/sprd/Kconfig" 1e6babb417f76bd Arnaud Pouliquen 2015-07-16 @86 source "sound/soc/sti/Kconfig" 3e086edfe0c73da olivier moysan 2017-04-10 87 source "sound/soc/stm/Kconfig" 45fb6b6f2aa3f6b Emilio López 2015-09-12 88 source "sound/soc/sunxi/Kconfig" 8b75d714a6ae644 Stephen Warren 2011-01-07 89 source "sound/soc/tegra/Kconfig" f2055e145f2975a Peter Ujfalusi 2018-12-17 90 source "sound/soc/ti/Kconfig" 3a47b1dfa291303 Katsuhiro Suzuki 2017-11-22 91 source "sound/soc/uniphier/Kconfig" 3592b7f69a54388 Ola Lilja 2012-05-08 92 source "sound/soc/ux500/Kconfig" 33f8db9a89200c1 Maruthi Srinivas Bayyavarapu 2018-12-08 93 source "sound/soc/xilinx/Kconfig" 57b7068de5d0cca Max Filippov 2014-12-26 94 source "sound/soc/xtensa/Kconfig" 8dafc0fb49b903c Frank Mandarino 2006-10-06 95
--- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Daniel,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master] [also build test ERROR on v5.17-rc8 next-20220310] [cannot apply to broonie-sound/for-next tiwai-sound/for-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Daniel-Palmer/ASoC-sti-sti_uniperif... base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 09688c0166e76ce2fb85e86b9d99be8b0084cdf9 config: powerpc-allmodconfig compiler: powerpc-linux-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/7970e4bb3de4ff810c1dafb8ac38d222d90c... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Daniel-Palmer/ASoC-sti-sti_uniperif-Remove-driver/20220315-171525 git checkout 7970e4bb3de4ff810c1dafb8ac38d222d90ca071 COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=powerpc allmodconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: allmodconfig] Error 1 make[1]: *** [Makefile:619: allmodconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'allmodconfig' not remade because of errors. --
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: oldconfig] Error 1 make[1]: *** [Makefile:619: oldconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'oldconfig' not remade because of errors. --
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: olddefconfig] Error 1 make[1]: *** [Makefile:619: olddefconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'olddefconfig' not remade because of errors.
vim +86 sound/soc/Kconfig
89fe5117928b2c Takashi Iwai 2008-05-23 25 89fe5117928b2c Takashi Iwai 2008-05-23 26 config SND_SOC_AC97_BUS 89fe5117928b2c Takashi Iwai 2008-05-23 27 bool 89fe5117928b2c Takashi Iwai 2008-05-23 28 28c4468b00a1e5 Lars-Peter Clausen 2013-04-15 29 config SND_SOC_GENERIC_DMAENGINE_PCM 28c4468b00a1e5 Lars-Peter Clausen 2013-04-15 30 bool b7ae6f31d8243e Daniel Mack 2013-08-12 31 select SND_DMAENGINE_PCM 28c4468b00a1e5 Lars-Peter Clausen 2013-04-15 32 6f0c42269f000b Jie Yang 2015-10-13 33 config SND_SOC_COMPRESS 6f0c42269f000b Jie Yang 2015-10-13 34 bool 6f0c42269f000b Jie Yang 2015-10-13 35 select SND_COMPRESS_OFFLOAD 6f0c42269f000b Jie Yang 2015-10-13 36 78b50f39142612 Mark Brown 2015-08-15 37 config SND_SOC_TOPOLOGY 78b50f39142612 Mark Brown 2015-08-15 38 bool 2635c226036c1b Peter Ujfalusi 2021-07-26 39 select SND_DYNAMIC_MINORS 78b50f39142612 Mark Brown 2015-08-15 40 b5fb388da472a6 Nico Pache 2021-04-14 41 config SND_SOC_TOPOLOGY_KUNIT_TEST d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 42 tristate "KUnit tests for SoC topology" d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 43 depends on KUNIT d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 44 depends on SND_SOC_TOPOLOGY d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 45 default KUNIT_ALL_TESTS d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 46 help d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 47 If you want to perform tests on ALSA SoC topology support say Y here. d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 48 d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 49 This builds a module which can be later manually loaded to run KUNIT d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 50 test cases against soc-topology.c API. This should be primarily used d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 51 by developers to test their changes to ASoC. d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 52 d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 53 Do note that it creates fake playback devices which do not interact d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 54 well with userspace. When running tests one may want to disable d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 55 userspace applications such as pulseaudio, to prevent unnecessary d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 56 problems. d52bbf747cfa8a Amadeusz Sławiński 2021-01-20 57 7feb2f786a46d3 Pierre-Louis Bossart 2017-10-12 58 config SND_SOC_ACPI 7feb2f786a46d3 Pierre-Louis Bossart 2017-10-12 59 tristate 7feb2f786a46d3 Pierre-Louis Bossart 2017-10-12 60 0b34a3d03e2fa6 Mark Brown 2008-12-16 61 # All the supported SoCs 8f2fe346822419 Lars-Peter Clausen 2013-12-06 62 source "sound/soc/adi/Kconfig" 7c31335a03b6af Maruthi Srinivas Bayyavarapu 2016-01-08 63 source "sound/soc/amd/Kconfig" 6c7425095c9ee2 Sedji Gaouaou 2008-10-03 64 source "sound/soc/atmel/Kconfig" 4a161d235b68eb Manuel Lauss 2008-07-09 65 source "sound/soc/au1x/Kconfig" c6aeb7de226dd0 Florian Meier 2013-11-22 66 source "sound/soc/bcm/Kconfig" 0ed275eff31029 Alexander Shiyan 2012-08-21 67 source "sound/soc/cirrus/Kconfig" 3a9cf8efd7b64f Rajeev Kumar 2012-06-21 68 source "sound/soc/dwc/Kconfig" 0b34a3d03e2fa6 Mark Brown 2008-12-16 69 source "sound/soc/fsl/Kconfig" 0bf750f4cbe140 Andy Green 2017-03-31 70 source "sound/soc/hisilicon/Kconfig" 9af8381023e48b Mark Brown 2010-07-05 71 source "sound/soc/jz4740/Kconfig" f9b95980f87f02 apatard@mandriva.com 2010-05-31 72 source "sound/soc/kirkwood/Kconfig" 14b947d9ced4f7 Damien.Horsley 2015-11-04 73 source "sound/soc/img/Kconfig" 784cbf8ab4641c Jarkko Nikula 2013-11-21 74 source "sound/soc/intel/Kconfig" ee0bcaff109f36 Koro Chen 2015-06-15 75 source "sound/soc/mediatek/Kconfig" 6dc4fa179fb86d Jerome Brunet 2018-07-17 76 source "sound/soc/meson/Kconfig" 009ad054b71b77 Dong Aisheng 2011-07-21 77 source "sound/soc/mxs/Kconfig" 734c2d4bb7cfcc Liam Girdwood 2006-10-12 78 source "sound/soc/pxa/Kconfig" 6a328885896ef0 Kenneth Westfield 2015-03-13 79 source "sound/soc/qcom/Kconfig" 4495c89fcf2624 Jianqun Xu 2014-07-05 80 source "sound/soc/rockchip/Kconfig" 5033f43c667542 Jassi Brar 2010-11-22 81 source "sound/soc/samsung/Kconfig" aef3b06ac69783 Manuel Lauss 2007-05-14 82 source "sound/soc/sh/Kconfig" 7e978fa37df7f7 Liam Girdwood 2019-04-12 83 source "sound/soc/sof/Kconfig" e58070ee4fdf79 Rajeev Kumar 2013-06-10 84 source "sound/soc/spear/Kconfig" 42fea318e1d19c Baolin Wang 2019-01-29 85 source "sound/soc/sprd/Kconfig" 1e6babb417f76b Arnaud Pouliquen 2015-07-16 @86 source "sound/soc/sti/Kconfig" 3e086edfe0c73d olivier moysan 2017-04-10 87 source "sound/soc/stm/Kconfig" 45fb6b6f2aa3f6 Emilio López 2015-09-12 88 source "sound/soc/sunxi/Kconfig" 8b75d714a6ae64 Stephen Warren 2011-01-07 89 source "sound/soc/tegra/Kconfig" f2055e145f2975 Peter Ujfalusi 2018-12-17 90 source "sound/soc/ti/Kconfig" 3a47b1dfa29130 Katsuhiro Suzuki 2017-11-22 91 source "sound/soc/uniphier/Kconfig" 3592b7f69a5438 Ola Lilja 2012-05-08 92 source "sound/soc/ux500/Kconfig" 33f8db9a89200c Maruthi Srinivas Bayyavarapu 2018-12-08 93 source "sound/soc/xilinx/Kconfig" 57b7068de5d0cc Max Filippov 2014-12-26 94 source "sound/soc/xtensa/Kconfig" 8dafc0fb49b903 Frank Mandarino 2006-10-06 95
--- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Daniel,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master] [also build test ERROR on v5.17-rc8 next-20220310] [cannot apply to broonie-sound/for-next tiwai-sound/for-next] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Daniel-Palmer/ASoC-sti-sti_uniperif... base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 09688c0166e76ce2fb85e86b9d99be8b0084cdf9 config: x86_64-rhel-8.3-kselftests compiler: gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/7970e4bb3de4ff810c1dafb8ac38d222d90c... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Daniel-Palmer/ASoC-sti-sti_uniperif-Remove-driver/20220315-171525 git checkout 7970e4bb3de4ff810c1dafb8ac38d222d90ca071 # save the config file to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=x86_64 distclean
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
scripts/Makefile.clean:15: sound/soc/sti/Makefile: No such file or directory make[4]: *** No rule to make target 'sound/soc/sti/Makefile'.
make[4]: Failed to remake makefile 'sound/soc/sti/Makefile'. make[3]: *** [scripts/Makefile.clean:68: sound/soc/sti] Error 2 make[3]: Target '__clean' not remade because of errors. make[2]: *** [scripts/Makefile.clean:68: sound/soc] Error 2 make[2]: Target '__clean' not remade because of errors. make[1]: *** [Makefile:1838: _clean_sound] Error 2 make[1]: Target 'distclean' not remade because of errors. make: *** [Makefile:219: __sub-make] Error 2 make: Target 'distclean' not remade because of errors. --
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: oldconfig] Error 1 make[1]: *** [Makefile:619: oldconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'oldconfig' not remade because of errors. --
sound/soc/Kconfig:86: can't open file "sound/soc/sti/Kconfig"
make[2]: *** [scripts/kconfig/Makefile:77: olddefconfig] Error 1 make[1]: *** [Makefile:619: olddefconfig] Error 2 make: *** [Makefile:219: __sub-make] Error 2 make: Target 'olddefconfig' not remade because of errors.
vim +15 scripts/Makefile.clean
2315c6e42278152 Sam Ravnborg 2005-07-25 12 2a691470345a002 Sam Ravnborg 2005-07-25 13 # The filename Kbuild has precedence over Makefile db8c1a7b2ca25f3 Sam Ravnborg 2005-07-27 14 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) db8c1a7b2ca25f3 Sam Ravnborg 2005-07-27 @15 include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) ^1da177e4c3f415 Linus Torvalds 2005-04-16 16
--- 0-DAY CI Kernel Test Service https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
participants (4)
-
Arnaud POULIQUEN
-
Daniel Palmer
-
kernel test robot
-
Takashi Iwai