* [PATCH 00/10] Add support for Imagination Technologies audio controllers
@ 2015-09-30 15:08 Damien Horsley
2015-09-30 15:08 ` [PATCH 01/10] ASoC: img: Add binding document for I2S input controller Damien Horsley
` (9 more replies)
0 siblings, 10 replies; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add drivers and binding documents for the following Imagination Technologies audio controllers:
I2S Input Controller
I2S Output Controller
Parallel Output Controller
SPDIF Input Controller
SPDIF Output Controller
These controllers are used in Pistachio SoC
Damien.Horsley (10):
ASoC: img: Add binding document for I2S input controller
ASoC: img: Add driver for I2S input controller
ASoC: img: Add binding document for I2S output controller
ASoC: img: Add driver for I2S output controller
ASoC: img: Add binding document for parallel output controller
ASoC: img: Add driver for parallel output controller
ASoC: img: Add binding document for SPDIF input controller
ASoC: img: Add driver for SPDIF input controller
ASoC: img: Add binding document for SPDIF output controller
ASoC: img: Add driver for SPDIF output controller
.../devicetree/bindings/sound/img,i2s-in.txt | 45 ++
.../devicetree/bindings/sound/img,i2s-out.txt | 49 ++
.../devicetree/bindings/sound/img,parallel-out.txt | 44 ++
.../devicetree/bindings/sound/img,spdif-in.txt | 41 ++
.../devicetree/bindings/sound/img,spdif-out.txt | 44 ++
sound/soc/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/img/Kconfig | 44 ++
sound/soc/img/Makefile | 5 +
sound/soc/img/img-i2s-in.c | 506 +++++++++++++
sound/soc/img/img-i2s-out.c | 555 ++++++++++++++
sound/soc/img/img-parallel-out.c | 372 ++++++++++
sound/soc/img/img-spdif-in.c | 797 +++++++++++++++++++++
sound/soc/img/img-spdif-out.c | 432 +++++++++++
14 files changed, 2936 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,i2s-in.txt
create mode 100644 Documentation/devicetree/bindings/sound/img,i2s-out.txt
create mode 100644 Documentation/devicetree/bindings/sound/img,parallel-out.txt
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-in.txt
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-out.txt
create mode 100644 sound/soc/img/Kconfig
create mode 100644 sound/soc/img/Makefile
create mode 100644 sound/soc/img/img-i2s-in.c
create mode 100644 sound/soc/img/img-i2s-out.c
create mode 100644 sound/soc/img/img-parallel-out.c
create mode 100644 sound/soc/img/img-spdif-in.c
create mode 100644 sound/soc/img/img-spdif-out.c
--
2.1.4
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/10] ASoC: img: Add binding document for I2S input controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:08 ` [PATCH 02/10] ASoC: img: Add driver " Damien Horsley
` (8 subsequent siblings)
9 siblings, 0 replies; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add a binding document for Imagination Technologies I2S input
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
.../devicetree/bindings/sound/img,i2s-in.txt | 45 ++++++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,i2s-in.txt
diff --git a/Documentation/devicetree/bindings/sound/img,i2s-in.txt b/Documentation/devicetree/bindings/sound/img,i2s-in.txt
new file mode 100644
index 0000000..a9e3c86
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,i2s-in.txt
@@ -0,0 +1,45 @@
+Imagination Technologies I2S Input Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,i2s-in"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - clocks : Contains an entry for each entry in clock-names
+
+ - clock-names : Must include the following entry:
+ "sys" The system clock
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "rx" Single DMA channel used by all active I2S channels
+
+ - img,i2s-channels : Number of I2S channels instantiated in the I2S in block
+
+Optional Properties:
+
+ - interrupts : Contains the I2S in interrupts. Depending on
+ the configuration, there may be no interrupts, one interrupt,
+ or an interrupt per I2S channel
+
+ - resets: Contains a phandle to the I2S in reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Example:
+
+i2s_in: i2s-in@18100800 {
+ compatible = "img,i2s-in";
+ reg = <0x18100800 0x200>;
+ interrupts = <GIC_SHARED 7 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 30 0xffffffff 0>;
+ dma-names = "rx";
+ clocks = <&cr_periph SYS_CLK_I2S_IN>;
+ clock-names = "sys";
+ img,i2s-channels = <6>;
+ #sound-dai-cells = <0>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/10] ASoC: img: Add driver for I2S input controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
2015-09-30 15:08 ` [PATCH 01/10] ASoC: img: Add binding document for I2S input controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:36 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 03/10] ASoC: img: Add binding document for I2S output controller Damien Horsley
` (7 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add driver for Imagination Technologies I2S input
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
sound/soc/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/img/Kconfig | 12 ++
sound/soc/img/Makefile | 1 +
sound/soc/img/img-i2s-in.c | 507 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 522 insertions(+)
create mode 100644 sound/soc/img/Kconfig
create mode 100644 sound/soc/img/Makefile
create mode 100644 sound/soc/img/img-i2s-in.c
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 7de792b..f9984db 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/jz4740/Kconfig"
source "sound/soc/nuc900/Kconfig"
source "sound/soc/omap/Kconfig"
source "sound/soc/kirkwood/Kconfig"
+source "sound/soc/img/Kconfig"
source "sound/soc/intel/Kconfig"
source "sound/soc/mediatek/Kconfig"
source "sound/soc/mxs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index af0a571..7ba9de9 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SND_SOC) += davinci/
obj-$(CONFIG_SND_SOC) += dwc/
obj-$(CONFIG_SND_SOC) += fsl/
obj-$(CONFIG_SND_SOC) += jz4740/
+obj-$(CONFIG_SND_SOC) += img/
obj-$(CONFIG_SND_SOC) += intel/
obj-$(CONFIG_SND_SOC) += mediatek/
obj-$(CONFIG_SND_SOC) += mxs/
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
new file mode 100644
index 0000000..f9f73d0
--- /dev/null
+++ b/sound/soc/img/Kconfig
@@ -0,0 +1,12 @@
+config SND_SOC_IMG
+ bool "Audio support for Imagination Technologies designs"
+ help
+ Audio support for Imagination Technologies audio hardware
+
+config SND_SOC_IMG_I2S_IN
+ tristate "Imagination I2S Input Device Driver"
+ depends on SND_SOC_IMG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for I2S in driver for
+ Imagination Technologies I2S in device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
new file mode 100644
index 0000000..fe8426b
--- /dev/null
+++ b/sound/soc/img/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
new file mode 100644
index 0000000..ebc59c4
--- /dev/null
+++ b/sound/soc/img/img-i2s-in.c
@@ -0,0 +1,507 @@
+/*
+ * IMG I2S input controller driver
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ *
+ * Author: Damien Horsley <Damien.Horsley@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IMG_I2S_IN_RX_FIFO 0x0
+
+#define IMG_I2S_IN_CTL 0x4
+#define IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK 0xfffffffc
+#define IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT 2
+#define IMG_I2S_IN_CTL_16PACK_MASK BIT(1)
+#define IMG_I2S_IN_CTL_ME_MASK BIT(0)
+
+#define IMG_I2S_IN_CH_CTL 0x4
+#define IMG_I2S_IN_CH_CTL_CCDEL_MASK 0x38000
+#define IMG_I2S_IN_CH_CTL_CCDEL_SHIFT 15
+#define IMG_I2S_IN_CH_CTL_FEN_MASK BIT(14)
+#define IMG_I2S_IN_CH_CTL_FMODE_MASK BIT(13)
+#define IMG_I2S_IN_CH_CTL_16PACK_MASK BIT(12)
+#define IMG_I2S_IN_CH_CTL_JUST_MASK BIT(10)
+#define IMG_I2S_IN_CH_CTL_PACKH_MASK BIT(9)
+#define IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK BIT(8)
+#define IMG_I2S_IN_CH_CTL_BLKP_MASK BIT(7)
+#define IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK BIT(6)
+#define IMG_I2S_IN_CH_CTL_LRD_MASK BIT(3)
+#define IMG_I2S_IN_CH_CTL_FW_MASK BIT(2)
+#define IMG_I2S_IN_CH_CTL_SW_MASK BIT(1)
+#define IMG_I2S_IN_CH_CTL_ME_MASK BIT(0)
+
+#define IMG_I2S_IN_CH_STRIDE 0x20
+
+struct img_i2s_in {
+ void __iomem *base;
+ struct clk *clk_sys;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct device *dev;
+ unsigned int max_i2s_chan;
+ void __iomem *channel_base;
+ unsigned int active_channels;
+ struct snd_soc_dai_driver dai_driver;
+};
+
+static inline void img_i2s_in_writel(struct img_i2s_in *i2s, u32 val, u32 reg)
+{
+ writel(val, i2s->base + reg);
+}
+
+static inline u32 img_i2s_in_readl(struct img_i2s_in *i2s, u32 reg)
+{
+ return readl(i2s->base + reg);
+}
+
+static inline void img_i2s_in_ch_writel(struct img_i2s_in *i2s, u32 chan,
+ u32 val, u32 reg)
+{
+ writel(val, i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
+}
+
+static inline u32 img_i2s_in_ch_readl(struct img_i2s_in *i2s, u32 chan,
+ u32 reg)
+{
+ return readl(i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg);
+}
+
+static inline u32 img_i2s_in_ch_disable(struct img_i2s_in *i2s, u32 chan)
+{
+ u32 reg;
+
+ reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL);
+ reg &= ~IMG_I2S_IN_CH_CTL_ME_MASK;
+ img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
+
+ return reg;
+}
+
+static inline void img_i2s_in_ch_enable(struct img_i2s_in *i2s, u32 chan,
+ u32 reg)
+{
+ reg |= IMG_I2S_IN_CH_CTL_ME_MASK;
+ img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL);
+}
+
+static inline void img_i2s_in_flush(struct img_i2s_in *i2s)
+{
+ int i;
+ u32 reg;
+
+ for (i = 0; i < i2s->active_channels; i++) {
+ reg = img_i2s_in_ch_disable(i2s, i);
+ reg |= IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg &= ~IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ img_i2s_in_ch_enable(i2s, i, reg);
+ }
+}
+
+static int img_i2s_in_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
+ u32 reg;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
+ reg |= IMG_I2S_IN_CTL_ME_MASK;
+ img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
+ reg &= ~IMG_I2S_IN_CTL_ME_MASK;
+ img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
+ img_i2s_in_flush(i2s);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int img_i2s_in_check_rate(struct img_i2s_in *i2s,
+ unsigned int sample_rate, unsigned int frame_size,
+ unsigned int *bclk_filter_enable,
+ unsigned int *bclk_filter_value)
+{
+ unsigned int bclk_freq, cur_freq;
+
+ bclk_freq = sample_rate * frame_size;
+
+ cur_freq = clk_get_rate(i2s->clk_sys);
+
+ if (cur_freq >= bclk_freq * 8) {
+ *bclk_filter_enable = 1;
+ *bclk_filter_value = 0;
+ } else if (cur_freq >= bclk_freq * 7) {
+ *bclk_filter_enable = 1;
+ *bclk_filter_value = 1;
+ } else if (cur_freq >= bclk_freq * 6) {
+ *bclk_filter_enable = 0;
+ *bclk_filter_value = 0;
+ } else {
+ dev_err(i2s->dev,
+ "Sys clock rate %u insufficient for sample rate %u\n",
+ cur_freq, sample_rate);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int img_i2s_in_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
+ unsigned int rate, channels, format, i2s_channels, frame_size;
+ unsigned int bclk_filter_enable, bclk_filter_value;
+ int i, ret = 0;
+ u32 reg, control_reg, control_mask, chan_control_mask;
+ u32 control_set = 0, chan_control_set = 0;
+
+ rate = params_rate(params);
+ format = params_format(params);
+ channels = params_channels(params);
+ i2s_channels = channels / 2;
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ frame_size = 64;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ frame_size = 64;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ frame_size = 32;
+ control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
+ chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if ((channels < 2) ||
+ (channels > (i2s->max_i2s_chan * 2)) ||
+ (channels % 2))
+ return -EINVAL;
+
+ control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);
+
+ ret = img_i2s_in_check_rate(i2s, rate, frame_size,
+ &bclk_filter_enable, &bclk_filter_value);
+ if (ret < 0)
+ return ret;
+
+ if (bclk_filter_enable)
+ chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;
+
+ if (bclk_filter_value)
+ chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;
+
+ control_mask = ~IMG_I2S_IN_CTL_16PACK_MASK &
+ ~IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;
+
+ chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
+ ~IMG_I2S_IN_CH_CTL_FEN_MASK &
+ ~IMG_I2S_IN_CH_CTL_FMODE_MASK &
+ ~IMG_I2S_IN_CH_CTL_SW_MASK &
+ ~IMG_I2S_IN_CH_CTL_FW_MASK &
+ ~IMG_I2S_IN_CH_CTL_PACKH_MASK;
+
+ control_reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
+ control_reg = (control_reg & control_mask) | control_set;
+ img_i2s_in_writel(i2s, control_reg, IMG_I2S_IN_CTL);
+
+ for (i = 0; i < i2s_channels; i++) {
+ reg = img_i2s_in_ch_disable(i2s, i);
+ reg = (reg & chan_control_mask) | chan_control_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ img_i2s_in_ch_enable(i2s, i, reg);
+ }
+ for (; i < i2s->max_i2s_chan; i++) {
+ reg = img_i2s_in_ch_disable(i2s, i);
+ reg = (reg & chan_control_mask) | chan_control_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ }
+
+ i2s->active_channels = i2s_channels;
+
+ return 0;
+}
+
+static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
+ int i;
+ u32 chan_control_mask, lrd_set = 0, blkp_set = 0, chan_control_set = 0;
+ u32 reg;
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ lrd_set |= IMG_I2S_IN_CH_CTL_LRD_MASK;
+ blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ blkp_set |= IMG_I2S_IN_CH_CTL_BLKP_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ chan_control_set |= IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ chan_control_mask = ~IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
+
+ /*
+ * BLKP and LRD must be set during separate register writes
+ */
+ for (i = 0; i < i2s->active_channels; i++) {
+ reg = img_i2s_in_ch_disable(i2s, i);
+ reg = (reg & chan_control_mask) | chan_control_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg = (reg & ~IMG_I2S_IN_CH_CTL_BLKP_MASK) | blkp_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg = (reg & ~IMG_I2S_IN_CH_CTL_LRD_MASK) | lrd_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ img_i2s_in_ch_enable(i2s, i, reg);
+ }
+
+ for (; i < i2s->max_i2s_chan; i++) {
+ reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL);
+ reg = (reg & chan_control_mask) | chan_control_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg = (reg & ~IMG_I2S_IN_CH_CTL_BLKP_MASK) | blkp_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg = (reg & ~IMG_I2S_IN_CH_CTL_LRD_MASK) | lrd_set;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops img_i2s_in_dai_ops = {
+ .trigger = img_i2s_in_trigger,
+ .hw_params = img_i2s_in_hw_params,
+ .set_fmt = img_i2s_in_set_fmt
+};
+
+static int img_i2s_in_dai_probe(struct snd_soc_dai *dai)
+{
+ struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_init_dma_data(dai, NULL, &i2s->dma_data);
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver img_i2s_in_component = {
+ .name = "img-i2s-in"
+};
+
+static int img_i2s_in_dma_prepare_slave_config(struct snd_pcm_substream *st,
+ struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
+{
+ unsigned int i2s_channels = params_channels(params) / 2;
+ struct snd_soc_pcm_runtime *rtd = st->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ int ret;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
+
+ ret = snd_hwparams_to_dma_slave_config(st, params, sc);
+ if (ret)
+ return ret;
+
+ sc->src_addr = dma_data->addr;
+ sc->src_addr_width = dma_data->addr_width;
+ sc->src_maxburst = 4 * i2s_channels;
+
+ return 0;
+}
+
+static const struct snd_dmaengine_pcm_config img_i2s_in_dma_config = {
+ .prepare_slave_config = img_i2s_in_dma_prepare_slave_config
+};
+
+static int img_i2s_in_probe(struct platform_device *pdev)
+{
+ struct img_i2s_in *i2s;
+ struct resource *res;
+ void __iomem *base;
+ int ret, i;
+ struct reset_control *rst;
+ u32 reg;
+ unsigned int max_i2s_chan_pow_2;
+ struct device *dev = &pdev->dev;
+
+ i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
+ if (!i2s)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, i2s);
+
+ i2s->dev = dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ i2s->base = base;
+
+ if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
+ &i2s->max_i2s_chan)) {
+ dev_err(dev, "No img,i2s-channels property\n");
+ return -EINVAL;
+ }
+
+ max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
+
+ i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
+
+ i2s->clk_sys = devm_clk_get(dev, "sys");
+ if (IS_ERR(i2s->clk_sys))
+ return PTR_ERR(i2s->clk_sys);
+
+ ret = clk_prepare_enable(i2s->clk_sys);
+ if (ret)
+ return ret;
+
+ i2s->active_channels = 1;
+ i2s->dma_data.addr = res->start + IMG_I2S_IN_RX_FIFO;
+ i2s->dma_data.addr_width = 4;
+
+ i2s->dai_driver.probe = img_i2s_in_dai_probe;
+ i2s->dai_driver.capture.channels_min = 2;
+ i2s->dai_driver.capture.channels_max = i2s->max_i2s_chan * 2;
+ i2s->dai_driver.capture.rates = SNDRV_PCM_RATE_8000_192000;
+ i2s->dai_driver.capture.formats = SNDRV_PCM_FMTBIT_S32_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE;
+ i2s->dai_driver.ops = &img_i2s_in_dai_ops;
+
+ rst = devm_reset_control_get(dev, "rst");
+ if (IS_ERR(rst)) {
+ dev_dbg(dev, "No top level reset found\n");
+
+ reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL);
+ reg &= ~IMG_I2S_IN_CTL_ME_MASK;
+ img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL);
+
+ for (i = 0; i < i2s->max_i2s_chan; i++) {
+ reg = img_i2s_in_ch_disable(i2s, i);
+ reg |= IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ reg &= ~IMG_I2S_IN_CH_CTL_FIFO_FLUSH_MASK;
+ img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL);
+ }
+ } else {
+ reset_control_assert(rst);
+ reset_control_deassert(rst);
+ }
+
+ img_i2s_in_writel(i2s, 0, IMG_I2S_IN_CTL);
+
+ for (i = 0; i < i2s->max_i2s_chan; i++)
+ img_i2s_in_ch_writel(i2s, i,
+ (4 << IMG_I2S_IN_CH_CTL_CCDEL_SHIFT) |
+ IMG_I2S_IN_CH_CTL_JUST_MASK |
+ IMG_I2S_IN_CH_CTL_FW_MASK, IMG_I2S_IN_CH_CTL);
+
+ ret = devm_snd_soc_register_component(dev, &img_i2s_in_component,
+ &i2s->dai_driver, 1);
+ if (ret)
+ goto err_clk_disable;
+
+ ret = devm_snd_dmaengine_pcm_register(dev, &img_i2s_in_dma_config, 0);
+ if (ret)
+ goto err_clk_disable;
+
+ return 0;
+
+err_clk_disable:
+ clk_disable_unprepare(i2s->clk_sys);
+
+ return ret;
+}
+
+static int img_i2s_in_dev_remove(struct platform_device *pdev)
+{
+ struct img_i2s_in *i2s = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(i2s->clk_sys);
+
+ return 0;
+}
+
+static const struct of_device_id img_i2s_in_of_match[] = {
+ { .compatible = "img,i2s-in" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, img_i2s_in_of_match);
+
+static struct platform_driver img_i2s_in_driver = {
+ .driver = {
+ .name = "img-i2s-in",
+ .of_match_table = img_i2s_in_of_match
+ },
+ .probe = img_i2s_in_probe,
+ .remove = img_i2s_in_dev_remove
+};
+module_platform_driver(img_i2s_in_driver);
+
+MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
+MODULE_DESCRIPTION("IMG I2S Input Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/10] ASoC: img: Add binding document for I2S output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
2015-09-30 15:08 ` [PATCH 01/10] ASoC: img: Add binding document for I2S input controller Damien Horsley
2015-09-30 15:08 ` [PATCH 02/10] ASoC: img: Add driver " Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:08 ` [PATCH 04/10] ASoC: img: Add driver " Damien Horsley
` (6 subsequent siblings)
9 siblings, 0 replies; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add binding document for Imagination Technologies I2S output
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
.../devicetree/bindings/sound/img,i2s-out.txt | 49 ++++++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,i2s-out.txt
diff --git a/Documentation/devicetree/bindings/sound/img,i2s-out.txt b/Documentation/devicetree/bindings/sound/img,i2s-out.txt
new file mode 100644
index 0000000..dc110ce
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,i2s-out.txt
@@ -0,0 +1,49 @@
+Imagination Technologies I2S Output Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,i2s-out"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - clocks : Contains an entry for each entry in clock-names
+
+ - clock-names : Must include the following entries:
+ "sys" The system clock
+ "ref" The reference clock
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "tx" Single DMA channel used by all active I2S channels
+
+ - img,i2s-channels : Number of I2S channels instantiated in the I2S out block
+
+ - resets: Contains a phandle to the I2S out reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Optional Properties:
+
+ - interrupts : Contains the I2S out interrupts. Depending on
+ the configuration, there may be no interrupts, one interrupt,
+ or an interrupt per I2S channel
+
+Example:
+
+i2s_out: i2s-out@18100A00 {
+ compatible = "img,i2s-out";
+ reg = <0x18100A00 0x200>;
+ interrupts = <GIC_SHARED 13 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 23 0xffffffff 0>;
+ dma-names = "tx";
+ clocks = <&cr_periph SYS_CLK_I2S_OUT>,
+ <&clk_core CLK_I2S>;
+ clock-names = "sys", "ref";
+ img,i2s-channels = <6>;
+ resets = <&pistachio_reset PISTACHIO_RESET_I2S_OUT>;
+ reset-names = "rst";
+ #sound-dai-cells = <0>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/10] ASoC: img: Add driver for I2S output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (2 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 03/10] ASoC: img: Add binding document for I2S output controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:42 ` kbuild test robot
` (2 more replies)
2015-09-30 15:08 ` [PATCH 05/10] ASoC: img: Add binding document for parallel " Damien Horsley
` (5 subsequent siblings)
9 siblings, 3 replies; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add driver for Imagination Technologies I2S output
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
sound/soc/img/Kconfig | 8 +
sound/soc/img/Makefile | 1 +
sound/soc/img/img-i2s-out.c | 551 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 560 insertions(+)
create mode 100644 sound/soc/img/img-i2s-out.c
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
index f9f73d0..fe83c8e 100644
--- a/sound/soc/img/Kconfig
+++ b/sound/soc/img/Kconfig
@@ -10,3 +10,11 @@ config SND_SOC_IMG_I2S_IN
help
Say Y or M if you want to add support for I2S in driver for
Imagination Technologies I2S in device.
+
+config SND_SOC_IMG_I2S_OUT
+ tristate "Imagination I2S Output Device Driver"
+ depends on SND_SOC_IMG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for I2S out driver for
+ Imagination Technologies I2S out device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
index fe8426b..c41a4af 100644
--- a/sound/soc/img/Makefile
+++ b/sound/soc/img/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
+obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
diff --git a/sound/soc/img/img-i2s-out.c b/sound/soc/img/img-i2s-out.c
new file mode 100644
index 0000000..c23e4f8
--- /dev/null
+++ b/sound/soc/img/img-i2s-out.c
@@ -0,0 +1,551 @@
+/*
+ * IMG I2S output controller driver
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ *
+ * Author: Damien Horsley <Damien.Horsley@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IMG_I2S_OUT_TX_FIFO 0x0
+
+#define IMG_I2S_OUT_CTL 0x4
+#define IMG_I2S_OUT_CTL_DATA_EN_MASK BIT(24)
+#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK 0xffe000
+#define IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT 13
+#define IMG_I2S_OUT_CTL_FRM_SIZE_MASK BIT(8)
+#define IMG_I2S_OUT_CTL_MASTER_MASK BIT(6)
+#define IMG_I2S_OUT_CTL_CLK_MASK BIT(5)
+#define IMG_I2S_OUT_CTL_CLK_EN_MASK BIT(4)
+#define IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK BIT(3)
+#define IMG_I2S_OUT_CTL_BCLK_POL_MASK BIT(2)
+#define IMG_I2S_OUT_CTL_ME_MASK BIT(0)
+
+#define IMG_I2S_OUT_CH_CTL 0x4
+#define IMG_I2S_OUT_CHAN_CTL_CH_MASK BIT(11)
+#define IMG_I2S_OUT_CHAN_CTL_LT_MASK BIT(10)
+#define IMG_I2S_OUT_CHAN_CTL_FMT_MASK 0xf0
+#define IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT 4
+#define IMG_I2S_OUT_CHAN_CTL_JUST_MASK BIT(3)
+#define IMG_I2S_OUT_CHAN_CTL_CLKT_MASK BIT(1)
+#define IMG_I2S_OUT_CHAN_CTL_ME_MASK BIT(0)
+
+#define IMG_I2S_OUT_CH_STRIDE 0x20
+
+struct img_i2s_out {
+ void __iomem *base;
+ struct clk *clk_sys;
+ struct clk *clk_ref;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct device *dev;
+ unsigned int max_i2s_chan;
+ void __iomem *channel_base;
+ bool force_clk_active;
+ unsigned int active_channels;
+ struct reset_control *rst;
+ struct snd_soc_dai_driver dai_driver;
+};
+
+static int img_i2s_out_suspend(struct device *dev)
+{
+ struct img_i2s_out *i2s = dev_get_drvdata(dev);
+
+ if (!i2s->force_clk_active)
+ clk_disable_unprepare(i2s->clk_ref);
+
+ return 0;
+}
+
+static int img_i2s_out_resume(struct device *dev)
+{
+ struct img_i2s_out *i2s = dev_get_drvdata(dev);
+ int ret;
+
+ if (!i2s->force_clk_active) {
+ ret = clk_prepare_enable(i2s->clk_ref);
+ if (ret) {
+ dev_err(dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
+ u32 reg)
+{
+ writel(val, i2s->base + reg);
+}
+
+static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
+{
+ return readl(i2s->base + reg);
+}
+
+static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
+ u32 chan, u32 val, u32 reg)
+{
+ writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
+}
+
+static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
+ u32 reg)
+{
+ return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
+}
+
+static inline u32 img_i2s_out_ch_disable(struct img_i2s_out *i2s, u32 chan)
+{
+ u32 reg;
+
+ reg = img_i2s_out_ch_readl(i2s, chan, IMG_I2S_OUT_CH_CTL);
+ reg &= ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
+ img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
+
+ return reg;
+}
+
+static inline void img_i2s_out_ch_enable(struct img_i2s_out *i2s, u32 chan,
+ u32 reg)
+{
+ reg |= IMG_I2S_OUT_CHAN_CTL_ME_MASK;
+ img_i2s_out_ch_writel(i2s, chan, reg, IMG_I2S_OUT_CH_CTL);
+}
+
+static inline u32 img_i2s_out_disable(struct img_i2s_out *i2s)
+{
+ u32 reg;
+
+ reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
+ reg &= ~IMG_I2S_OUT_CTL_ME_MASK;
+ img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
+
+ return reg;
+}
+
+static inline void img_i2s_out_enable(struct img_i2s_out *i2s, u32 reg)
+{
+ reg |= IMG_I2S_OUT_CTL_ME_MASK;
+ img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
+}
+
+static void img_i2s_out_reset(struct img_i2s_out *i2s)
+{
+ int i;
+ u32 core_ctl, chan_ctl;
+
+ core_ctl = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL) &
+ ~IMG_I2S_OUT_CTL_ME_MASK &
+ ~IMG_I2S_OUT_CTL_DATA_EN_MASK;
+
+ if (!i2s->force_clk_active)
+ core_ctl &= ~IMG_I2S_OUT_CTL_CLK_EN_MASK;
+
+ chan_ctl = img_i2s_out_ch_readl(i2s, 0, IMG_I2S_OUT_CH_CTL) &
+ ~IMG_I2S_OUT_CHAN_CTL_ME_MASK;
+
+ reset_control_assert(i2s->rst);
+ reset_control_deassert(i2s->rst);
+
+ for (i = 0; i < i2s->max_i2s_chan; i++)
+ img_i2s_out_ch_writel(i2s, i, chan_ctl, IMG_I2S_OUT_CH_CTL);
+
+ for (i = 0; i < i2s->active_channels; i++)
+ img_i2s_out_ch_enable(i2s, i, chan_ctl);
+
+ img_i2s_out_writel(i2s, core_ctl, IMG_I2S_OUT_CTL);
+ img_i2s_out_enable(i2s, core_ctl);
+}
+
+static int img_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
+ u32 reg;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ reg = img_i2s_out_readl(i2s, IMG_I2S_OUT_CTL);
+ if (!i2s->force_clk_active)
+ reg |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
+ reg |= IMG_I2S_OUT_CTL_DATA_EN_MASK;
+ img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ img_i2s_out_reset(i2s);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int img_i2s_out_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
+ unsigned int channels, i2s_channels, format;
+ long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
+ int i;
+ u32 reg, control_reg, control_mask, control_set = 0;
+
+ rate = params_rate(params);
+ format = params_format(params);
+ channels = params_channels(params);
+ i2s_channels = channels / 2;
+
+ if (format != SNDRV_PCM_FORMAT_S32_LE)
+ return -EINVAL;
+
+ if ((channels < 2) ||
+ (channels > (i2s->max_i2s_chan * 2)) ||
+ (channels % 2))
+ return -EINVAL;
+
+ pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
+ if (pre_div_a < 0)
+ return pre_div_a;
+ pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
+ if (pre_div_b < 0)
+ return pre_div_b;
+
+ diff_a = abs((pre_div_a / 256) - rate);
+ diff_b = abs((pre_div_b / 384) - rate);
+
+ /* If diffs are equal, use lower clock rate */
+ if (diff_a > diff_b)
+ clk_set_rate(i2s->clk_ref, pre_div_b);
+ else
+ clk_set_rate(i2s->clk_ref, pre_div_a);
+
+ /*
+ * Another driver (eg alsa machine driver) may have rejected the above
+ * change. Get the current rate and set the register bit according to
+ * the new minimum diff
+ */
+ clk_rate = clk_get_rate(i2s->clk_ref);
+
+ diff_a = abs((clk_rate / 256) - rate);
+ diff_b = abs((clk_rate / 384) - rate);
+
+ if (diff_a > diff_b)
+ control_set |= IMG_I2S_OUT_CTL_CLK_MASK;
+
+ control_set |= (((i2s_channels - 1) <<
+ IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
+ IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK);
+
+ control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
+ ~IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
+
+ control_reg = img_i2s_out_disable(i2s);
+ control_reg = (control_reg & control_mask) | control_set;
+ img_i2s_out_writel(i2s, control_reg, IMG_I2S_OUT_CTL);
+
+ for (i = 0; i < i2s_channels; i++) {
+ reg = img_i2s_out_ch_readl(i2s, i, IMG_I2S_OUT_CH_CTL);
+ img_i2s_out_ch_enable(i2s, i, reg);
+ }
+
+ for (; i < i2s->max_i2s_chan; i++)
+ img_i2s_out_ch_disable(i2s, i);
+
+ img_i2s_out_enable(i2s, control_reg);
+
+ i2s->active_channels = i2s_channels;
+
+ return 0;
+}
+
+static int img_i2s_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
+ int i, ret = 0;
+ bool force_clk_active;
+ u32 chan_control_mask, control_mask, chan_control_set = 0;
+ u32 reg, control_reg, control_set = 0;
+
+ force_clk_active = ((fmt & SND_SOC_DAIFMT_CLOCK_MASK) ==
+ SND_SOC_DAIFMT_CONT);
+
+ if (force_clk_active)
+ control_set |= IMG_I2S_OUT_CTL_CLK_EN_MASK;
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ control_set |= IMG_I2S_OUT_CTL_MASTER_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ control_set |= IMG_I2S_OUT_CTL_BCLK_POL_MASK;
+ control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ control_set |= IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ chan_control_set |= IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ control_mask = ~IMG_I2S_OUT_CTL_CLK_EN_MASK &
+ ~IMG_I2S_OUT_CTL_MASTER_MASK &
+ ~IMG_I2S_OUT_CTL_BCLK_POL_MASK &
+ ~IMG_I2S_OUT_CTL_FRM_CLK_POL_MASK;
+
+ chan_control_mask = ~IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
+
+ control_reg = img_i2s_out_disable(i2s);
+ control_reg = (control_reg & control_mask) | control_set;
+ img_i2s_out_writel(i2s, control_reg, IMG_I2S_OUT_CTL);
+
+ for (i = 0; i < i2s->active_channels; i++) {
+ reg = img_i2s_out_ch_disable(i2s, i);
+ reg = (reg & chan_control_mask) | chan_control_set;
+ img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
+ img_i2s_out_ch_enable(i2s, i, reg);
+ }
+
+ for (; i < i2s->max_i2s_chan; i++)
+ img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
+
+ img_i2s_out_enable(i2s, control_reg);
+
+ i2s->force_clk_active = force_clk_active;
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops img_i2s_out_dai_ops = {
+ .trigger = img_i2s_out_trigger,
+ .hw_params = img_i2s_out_hw_params,
+ .set_fmt = img_i2s_out_set_fmt
+};
+
+static int img_i2s_out_dai_probe(struct snd_soc_dai *dai)
+{
+ struct img_i2s_out *i2s = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_init_dma_data(dai, &i2s->dma_data, NULL);
+
+ return 0;
+}
+
+static const struct snd_soc_component_driver img_i2s_out_component = {
+ .name = "img-i2s-out"
+};
+
+static int img_i2s_out_dma_prepare_slave_config(struct snd_pcm_substream *st,
+ struct snd_pcm_hw_params *params, struct dma_slave_config *sc)
+{
+ unsigned int i2s_channels = params_channels(params) / 2;
+ struct snd_soc_pcm_runtime *rtd = st->private_data;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ int ret;
+
+ dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, st);
+
+ ret = snd_hwparams_to_dma_slave_config(st, params, sc);
+ if (ret)
+ return ret;
+
+ sc->dst_addr = dma_data->addr;
+ sc->dst_addr_width = dma_data->addr_width;
+ sc->dst_maxburst = 4 * i2s_channels;
+
+ return 0;
+}
+
+static const struct snd_dmaengine_pcm_config img_i2s_out_dma_config = {
+ .prepare_slave_config = img_i2s_out_dma_prepare_slave_config
+};
+
+static int img_i2s_out_probe(struct platform_device *pdev)
+{
+ struct img_i2s_out *i2s;
+ struct resource *res;
+ void __iomem *base;
+ int i, ret;
+ unsigned int max_i2s_chan_pow_2;
+ u32 reg;
+
+ i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
+ if (!i2s)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, i2s);
+
+ i2s->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ i2s->base = base;
+
+ if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels",
+ &i2s->max_i2s_chan)) {
+ dev_err(&pdev->dev, "No img,i2s-channels property\n");
+ return -EINVAL;
+ }
+
+ max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan);
+
+ i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20);
+
+ i2s->rst = devm_reset_control_get(&pdev->dev, "rst");
+ if (IS_ERR(i2s->rst)) {
+ dev_err(&pdev->dev, "No top level reset found\n");
+ return PTR_ERR(i2s->rst);
+ }
+
+ i2s->clk_sys = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(i2s->clk_sys))
+ return PTR_ERR(i2s->clk_sys);
+
+ i2s->clk_ref = devm_clk_get(&pdev->dev, "ref");
+ if (IS_ERR(i2s->clk_ref))
+ return PTR_ERR(i2s->clk_ref);
+
+ ret = clk_prepare_enable(i2s->clk_sys);
+ if (ret)
+ return ret;
+
+ reg = IMG_I2S_OUT_CTL_FRM_SIZE_MASK;
+ img_i2s_out_writel(i2s, reg, IMG_I2S_OUT_CTL);
+
+ reg = IMG_I2S_OUT_CHAN_CTL_JUST_MASK |
+ IMG_I2S_OUT_CHAN_CTL_LT_MASK |
+ IMG_I2S_OUT_CHAN_CTL_CH_MASK |
+ (8 << IMG_I2S_OUT_CHAN_CTL_FMT_SHIFT);
+
+ for (i = 0; i < i2s->max_i2s_chan; i++)
+ img_i2s_out_ch_writel(i2s, i, reg, IMG_I2S_OUT_CH_CTL);
+
+ img_i2s_out_reset(i2s);
+
+ pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev)) {
+ ret = img_i2s_out_resume(&pdev->dev);
+ if (ret)
+ goto err_pm_disable;
+ }
+
+ i2s->active_channels = 1;
+ i2s->dma_data.addr = res->start + IMG_I2S_OUT_TX_FIFO;
+ i2s->dma_data.addr_width = 4;
+ i2s->dma_data.maxburst = 4;
+
+ i2s->dai_driver.probe = img_i2s_out_dai_probe;
+ i2s->dai_driver.playback.channels_min = 2;
+ i2s->dai_driver.playback.channels_max = i2s->max_i2s_chan * 2;
+ i2s->dai_driver.playback.rates = SNDRV_PCM_RATE_8000_192000;
+ i2s->dai_driver.playback.formats = SNDRV_PCM_FMTBIT_S32_LE;
+ i2s->dai_driver.ops = &img_i2s_out_dai_ops;
+
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &img_i2s_out_component, &i2s->dai_driver, 1);
+ if (ret)
+ goto err_suspend;
+
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
+ &img_i2s_out_dma_config, 0);
+ if (ret)
+ goto err_suspend;
+
+ return 0;
+
+err_suspend:
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_i2s_out_suspend(&pdev->dev);
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(i2s->clk_sys);
+
+ return ret;
+}
+
+static int img_i2s_out_dev_remove(struct platform_device *pdev)
+{
+ struct img_i2s_out *i2s = platform_get_drvdata(pdev);
+
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_i2s_out_suspend(&pdev->dev);
+
+ clk_disable_unprepare(i2s->clk_sys);
+
+ return 0;
+}
+
+static const struct of_device_id img_i2s_out_of_match[] = {
+ { .compatible = "img,i2s-out" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, img_i2s_out_of_match);
+
+static const struct dev_pm_ops img_i2s_out_pm_ops = {
+ SET_RUNTIME_PM_OPS(img_i2s_out_suspend,
+ img_i2s_out_resume, NULL)
+};
+
+static struct platform_driver img_i2s_out_driver = {
+ .driver = {
+ .name = "img-i2s-out",
+ .of_match_table = img_i2s_out_of_match,
+ .pm = &img_i2s_out_pm_ops
+ },
+ .probe = img_i2s_out_probe,
+ .remove = img_i2s_out_dev_remove
+};
+module_platform_driver(img_i2s_out_driver);
+
+MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
+MODULE_DESCRIPTION("IMG I2S Output Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/10] ASoC: img: Add binding document for parallel output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (3 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 04/10] ASoC: img: Add driver " Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for parallel output controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 06/10] ASoC: img: Add driver for parallel output controller Damien Horsley
` (4 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add binding document for Imagination Technologies parallel
output controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
.../devicetree/bindings/sound/img,parallel-out.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,parallel-out.txt
diff --git a/Documentation/devicetree/bindings/sound/img,parallel-out.txt b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
new file mode 100644
index 0000000..a3015d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
@@ -0,0 +1,44 @@
+Imagination Technologies Parallel Output Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,parallel-out".
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device.
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "tx"
+
+ - clocks : Contains an entry for each entry in clock-names.
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+ "ref" The reference clock
+
+ - resets: Contains a phandle to the parallel out reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Optional Properties:
+
+ - interrupts : Contains the parallel out interrupt, if present
+
+Example:
+
+parallel_out: parallel-out@18100C00 {
+ compatible = "img,parallel-out";
+ reg = <0x18100C00 0x100>;
+ interrupts = <GIC_SHARED 19 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 16 0xffffffff 0>;
+ dma-names = "tx";
+ clocks = <&cr_periph SYS_CLK_PAUD_OUT>,
+ <&clk_core CLK_AUDIO_DAC>;
+ clock-names = "sys", "ref";
+ resets = <&pistachio_reset PISTACHIO_RESET_PRL_OUT>;
+ reset-names = "rst";
+ #sound-dai-cells = <0>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/10] ASoC: img: Add driver for parallel output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (4 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 05/10] ASoC: img: Add binding document for parallel " Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:48 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 07/10] ASoC: img: Add binding document for SPDIF input controller Damien Horsley
` (3 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add driver for Imagination Technologies parallel output
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
sound/soc/img/Kconfig | 8 +
sound/soc/img/Makefile | 1 +
sound/soc/img/img-parallel-out.c | 372 +++++++++++++++++++++++++++++++++++++++
3 files changed, 381 insertions(+)
create mode 100644 sound/soc/img/img-parallel-out.c
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
index fe83c8e..3bb507e 100644
--- a/sound/soc/img/Kconfig
+++ b/sound/soc/img/Kconfig
@@ -18,3 +18,11 @@ config SND_SOC_IMG_I2S_OUT
help
Say Y or M if you want to add support for I2S out driver for
Imagination Technologies I2S out device.
+
+config SND_SOC_IMG_PARALLEL_OUT
+ tristate "Imagination Parallel Output Device Driver"
+ depends on SND_SOC_IMG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for parallel out driver for
+ Imagination Technologies parallel out device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
index c41a4af..da89763 100644
--- a/sound/soc/img/Makefile
+++ b/sound/soc/img/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
+obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c
new file mode 100644
index 0000000..44a61ec
--- /dev/null
+++ b/sound/soc/img/img-parallel-out.c
@@ -0,0 +1,372 @@
+/*
+ * IMG parallel output controller driver
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ *
+ * Author: Damien Horsley <Damien.Horsley@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IMG_PRL_OUT_TX_FIFO 0
+
+#define IMG_PRL_OUT_CTL 0x4
+#define IMG_PRL_OUT_CTL_CH_MASK BIT(4)
+#define IMG_PRL_OUT_CTL_PACKH_MASK BIT(3)
+#define IMG_PRL_OUT_CTL_EDGE_MASK BIT(2)
+#define IMG_PRL_OUT_CTL_ME_MASK BIT(1)
+#define IMG_PRL_OUT_CTL_SRST_MASK BIT(0)
+
+static const char *const img_prl_out_edge_names[] = { "Rising", "Falling" };
+
+struct img_prl_out {
+ spinlock_t lock;
+ void __iomem *base;
+ struct clk *clk_sys;
+ struct clk *clk_ref;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct device *dev;
+ bool active;
+ struct reset_control *rst;
+};
+
+static int img_prl_out_suspend(struct device *dev)
+{
+ struct img_prl_out *prl = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(prl->clk_ref);
+
+ return 0;
+}
+
+static int img_prl_out_resume(struct device *dev)
+{
+ struct img_prl_out *prl = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(prl->clk_ref);
+ if (ret) {
+ dev_err(dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline void img_prl_out_writel(struct img_prl_out *prl,
+ u32 val, u32 reg)
+{
+ writel(val, prl->base + reg);
+}
+
+static inline u32 img_prl_out_readl(struct img_prl_out *prl, u32 reg)
+{
+ return readl(prl->base + reg);
+}
+
+static void img_prl_out_reset(struct img_prl_out *prl)
+{
+ u32 ctl;
+
+ ctl = img_prl_out_readl(prl, IMG_PRL_OUT_CTL) &
+ ~IMG_PRL_OUT_CTL_ME_MASK;
+
+ reset_control_assert(prl->rst);
+ reset_control_deassert(prl->rst);
+
+ img_prl_out_writel(prl, ctl, IMG_PRL_OUT_CTL);
+}
+
+static int img_prl_out_edge_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ return snd_ctl_enum_info(uinfo, 1, 2, img_prl_out_edge_names);
+}
+
+static int img_prl_out_get_edge(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_prl_out *prl = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&prl->lock, flags);
+ reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
+ ucontrol->value.integer.value[0] = !!(reg & IMG_PRL_OUT_CTL_EDGE_MASK);
+ spin_unlock_irqrestore(&prl->lock, flags);
+
+ return 0;
+}
+
+static int img_prl_out_set_edge(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_prl_out *prl = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags;
+ int ret = 0;
+ u32 reg;
+
+ spin_lock_irqsave(&prl->lock, flags);
+ if (prl->active) {
+ ret = -EBUSY;
+ } else {
+ reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
+ if (ucontrol->value.integer.value[0])
+ reg |= IMG_PRL_OUT_CTL_EDGE_MASK;
+ else
+ reg &= ~IMG_PRL_OUT_CTL_EDGE_MASK;
+ img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
+ }
+ spin_unlock_irqrestore(&prl->lock, flags);
+
+ return ret;
+}
+
+static struct snd_kcontrol_new img_prl_out_controls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "Parallel Out Edge Falling",
+ .info = img_prl_out_edge_info,
+ .get = img_prl_out_get_edge,
+ .put = img_prl_out_set_edge
+ }
+};
+
+static int img_prl_out_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
+ unsigned long flags;
+ int ret = 0;
+ u32 reg;
+
+ spin_lock_irqsave(&prl->lock, flags);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
+ reg |= IMG_PRL_OUT_CTL_ME_MASK;
+ img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
+ prl->active = true;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ img_prl_out_reset(prl);
+ prl->active = false;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&prl->lock, flags);
+
+ return ret;
+}
+
+static int img_prl_out_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
+ unsigned int rate, format, channels;
+ u32 reg, reg_set = 0;
+ unsigned long flags;
+
+ rate = params_rate(params);
+ format = params_format(params);
+ channels = params_channels(params);
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ reg_set |= IMG_PRL_OUT_CTL_PACKH_MASK;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (channels != 2)
+ return -EINVAL;
+
+ clk_set_rate(prl->clk_ref, rate * 256);
+
+ spin_lock_irqsave(&prl->lock, flags);
+ reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
+ reg = (reg & ~IMG_PRL_OUT_CTL_PACKH_MASK) | reg_set;
+ img_prl_out_writel(prl, reg, IMG_PRL_OUT_CTL);
+ spin_unlock_irqrestore(&prl->lock, flags);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops img_prl_out_dai_ops = {
+ .trigger = img_prl_out_trigger,
+ .hw_params = img_prl_out_hw_params
+};
+
+static int img_prl_out_dai_probe(struct snd_soc_dai *dai)
+{
+ struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_init_dma_data(dai, &prl->dma_data, NULL);
+
+ snd_soc_add_dai_controls(dai, img_prl_out_controls,
+ ARRAY_SIZE(img_prl_out_controls));
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver img_prl_out_dai = {
+ .probe = img_prl_out_dai_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE
+ },
+ .ops = &img_prl_out_dai_ops
+};
+
+static const struct snd_soc_component_driver img_prl_out_component = {
+ .name = "img-prl-out"
+};
+
+static int img_prl_out_probe(struct platform_device *pdev)
+{
+ struct img_prl_out *prl;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ prl = devm_kzalloc(&pdev->dev, sizeof(*prl), GFP_KERNEL);
+ if (!prl)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, prl);
+
+ prl->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ prl->base = base;
+
+ prl->rst = devm_reset_control_get(&pdev->dev, "rst");
+ if (IS_ERR(prl->rst)) {
+ dev_err(&pdev->dev, "No top level reset found\n");
+ return PTR_ERR(prl->rst);
+ }
+
+ prl->clk_sys = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(prl->clk_sys))
+ return PTR_ERR(prl->clk_sys);
+
+ prl->clk_ref = devm_clk_get(&pdev->dev, "ref");
+ if (IS_ERR(prl->clk_ref))
+ return PTR_ERR(prl->clk_ref);
+
+ ret = clk_prepare_enable(prl->clk_sys);
+ if (ret)
+ return ret;
+
+ img_prl_out_writel(prl, IMG_PRL_OUT_CTL_EDGE_MASK, IMG_PRL_OUT_CTL);
+ img_prl_out_reset(prl);
+
+ pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev)) {
+ ret = img_prl_out_resume(&pdev->dev);
+ if (ret)
+ goto err_pm_disable;
+ }
+
+ spin_lock_init(&prl->lock);
+
+ prl->dma_data.addr = res->start + IMG_PRL_OUT_TX_FIFO;
+ prl->dma_data.addr_width = 4;
+ prl->dma_data.maxburst = 4;
+
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &img_prl_out_component,
+ &img_prl_out_dai, 1);
+ if (ret)
+ goto err_suspend;
+
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+ if (ret)
+ goto err_suspend;
+
+ return 0;
+
+err_suspend:
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_prl_out_suspend(&pdev->dev);
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(prl->clk_sys);
+
+ return ret;
+}
+
+static int img_prl_out_dev_remove(struct platform_device *pdev)
+{
+ struct img_prl_out *prl = platform_get_drvdata(pdev);
+
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_prl_out_suspend(&pdev->dev);
+
+ clk_disable_unprepare(prl->clk_sys);
+
+ return 0;
+}
+
+static const struct of_device_id img_prl_out_of_match[] = {
+ { .compatible = "img,parallel-out" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, img_prl_out_of_match);
+
+static const struct dev_pm_ops img_prl_out_pm_ops = {
+ SET_RUNTIME_PM_OPS(img_prl_out_suspend,
+ img_prl_out_resume, NULL)
+};
+
+static struct platform_driver img_prl_out_driver = {
+ .driver = {
+ .name = "img-parallel-out",
+ .of_match_table = img_prl_out_of_match,
+ .pm = &img_prl_out_pm_ops
+ },
+ .probe = img_prl_out_probe,
+ .remove = img_prl_out_dev_remove
+};
+module_platform_driver(img_prl_out_driver);
+
+MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
+MODULE_DESCRIPTION("IMG Parallel Output Driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/10] ASoC: img: Add binding document for SPDIF input controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (5 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 06/10] ASoC: img: Add driver for parallel output controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for SPDIF input controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller Damien Horsley
` (2 subsequent siblings)
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add binding document for Imagination Technologies SPDIF
input controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
.../devicetree/bindings/sound/img,spdif-in.txt | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-in.txt
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-in.txt b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
new file mode 100644
index 0000000..aab9a81
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
@@ -0,0 +1,41 @@
+Imagination Technologies SPDIF Input Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,spdif-in"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "rx"
+
+ - clocks : Contains an entry for each entry in clock-names
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+
+Optional Properties:
+
+ - resets: Should contain a phandle to the spdif in reset signal, if any
+
+ - reset-names: Should contain the reset signal name "rst", if a
+ reset phandle is given
+
+ - interrupts : Contains the spdif in interrupt, if present
+
+Example:
+
+spdif_in: spdif-in@18100E00 {
+ compatible = "img,spdif-in";
+ reg = <0x18100E00 0x100>;
+ interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 15 0xffffffff 0>;
+ dma-names = "rx";
+ clocks = <&cr_periph SYS_CLK_SPDIF_IN>;
+ clock-names = "sys";
+ #sound-dai-cells = <0>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (6 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 07/10] ASoC: img: Add binding document for SPDIF input controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-09-30 15:53 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 09/10] ASoC: img: Add binding document for SPDIF output controller Damien Horsley
2015-09-30 15:08 ` [PATCH 10/10] ASoC: img: Add driver for SPDIF output controller Damien Horsley
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add driver for Imagination Technologies SDPIF input
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
sound/soc/img/Kconfig | 8 +
sound/soc/img/Makefile | 1 +
sound/soc/img/img-spdif-in.c | 798 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 807 insertions(+)
create mode 100644 sound/soc/img/img-spdif-in.c
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
index 3bb507e..161ce90 100644
--- a/sound/soc/img/Kconfig
+++ b/sound/soc/img/Kconfig
@@ -26,3 +26,11 @@ config SND_SOC_IMG_PARALLEL_OUT
help
Say Y or M if you want to add support for parallel out driver for
Imagination Technologies parallel out device.
+
+config SND_SOC_IMG_SPDIF_IN
+ tristate "Imagination SPDIF Input Device Driver"
+ depends on SND_SOC_IMG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for SPDIF input driver for
+ Imagination Technologies SPDIF input device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
index da89763..85ded5e 100644
--- a/sound/soc/img/Makefile
+++ b/sound/soc/img/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
+obj-$(CONFIG_SND_SOC_IMG_SPDIF_IN) += img-spdif-in.o
diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
new file mode 100644
index 0000000..e86aeea
--- /dev/null
+++ b/sound/soc/img/img-spdif-in.c
@@ -0,0 +1,798 @@
+/*
+ * IMG SPDIF input controller driver
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ *
+ * Author: Damien Horsley <Damien.Horsley@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IMG_SPDIF_IN_RX_FIFO_OFFSET 0
+
+#define IMG_SPDIF_IN_CTL 0x4
+#define IMG_SPDIF_IN_CTL_LOCKLO_MASK 0xff
+#define IMG_SPDIF_IN_CTL_LOCKLO_SHIFT 0
+#define IMG_SPDIF_IN_CTL_LOCKHI_MASK 0xff00
+#define IMG_SPDIF_IN_CTL_LOCKHI_SHIFT 8
+#define IMG_SPDIF_IN_CTL_TRK_MASK 0xff0000
+#define IMG_SPDIF_IN_CTL_TRK_SHIFT 16
+#define IMG_SPDIF_IN_CTL_SRD_MASK 0x70000000
+#define IMG_SPDIF_IN_CTL_SRD_SHIFT 28
+#define IMG_SPDIF_IN_CTL_SRT_MASK BIT(31)
+
+#define IMG_SPDIF_IN_STATUS 0x8
+#define IMG_SPDIF_IN_STATUS_SAM_MASK 0x7000
+#define IMG_SPDIF_IN_STATUS_SAM_SHIFT 12
+#define IMG_SPDIF_IN_STATUS_LOCK_MASK BIT(15)
+#define IMG_SPDIF_IN_STATUS_LOCK_SHIFT 15
+
+#define IMG_SPDIF_IN_CLKGEN 0x1c
+#define IMG_SPDIF_IN_CLKGEN_NOM_MASK 0x3ff
+#define IMG_SPDIF_IN_CLKGEN_NOM_SHIFT 0
+#define IMG_SPDIF_IN_CLKGEN_HLD_MASK 0x3ff0000
+#define IMG_SPDIF_IN_CLKGEN_HLD_SHIFT 16
+
+#define IMG_SPDIF_IN_CSL 0x20
+
+#define IMG_SPDIF_IN_CSH 0x24
+#define IMG_SPDIF_IN_CSH_MASK 0xff
+#define IMG_SPDIF_IN_CSH_SHIFT 0
+
+#define IMG_SPDIF_IN_SOFT_RESET 0x28
+#define IMG_SPDIF_IN_SOFT_RESET_MASK BIT(0)
+
+#define IMG_SPDIF_IN_ACLKGEN_START 0x2c
+#define IMG_SPDIF_IN_ACLKGEN_NOM_MASK 0x3ff
+#define IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT 0
+#define IMG_SPDIF_IN_ACLKGEN_HLD_MASK 0xffc00
+#define IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT 10
+#define IMG_SPDIF_IN_ACLKGEN_TRK_MASK 0xff00000
+#define IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT 20
+
+#define IMG_SPDIF_IN_NUM_ACLKGEN 4
+
+struct img_spdif_in {
+ spinlock_t lock;
+ void __iomem *base;
+ struct clk *clk_sys;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct device *dev;
+ unsigned int trk;
+ bool multi_freq;
+ int lock_acquire;
+ int lock_release;
+ unsigned int single_freq;
+ unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
+ bool active;
+
+ /* Write-only registers */
+ unsigned int aclkgen_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
+};
+
+static inline void img_spdif_in_writel(struct img_spdif_in *spdif,
+ u32 val, u32 reg)
+{
+ writel(val, spdif->base + reg);
+}
+
+static inline u32 img_spdif_in_readl(struct img_spdif_in *spdif, u32 reg)
+{
+ return readl(spdif->base + reg);
+}
+
+static inline void img_spdif_in_aclkgen_writel(struct img_spdif_in *spdif,
+ u32 index)
+{
+ img_spdif_in_writel(spdif, spdif->aclkgen_regs[index],
+ IMG_SPDIF_IN_ACLKGEN_START + (index * 0x4));
+}
+
+static int img_spdif_in_check_max_rate(struct img_spdif_in *spdif,
+ unsigned int sample_rate, unsigned long *actual_freq)
+{
+ unsigned long min_freq, freq_t;
+
+ /* Clock rate must be at least 24x the bit rate */
+ min_freq = sample_rate * 2 * 32 * 24;
+
+ freq_t = clk_get_rate(spdif->clk_sys);
+
+ if (freq_t < min_freq)
+ return -EINVAL;
+
+ *actual_freq = freq_t;
+
+ return 0;
+}
+
+static int img_spdif_in_do_clkgen_calc(unsigned int rate, unsigned int *pnom,
+ unsigned int *phld, unsigned long clk_rate)
+{
+ unsigned int ori, nom, hld;
+
+ /*
+ * Calculate oversampling ratio, nominal phase increment and hold
+ * increment for the given rate / frequency
+ */
+
+ if (!rate)
+ return -EINVAL;
+
+ ori = clk_rate / (rate * 64);
+
+ if (!ori)
+ return -EINVAL;
+
+ nom = (4096 / ori) + 1;
+ do
+ hld = 4096 - (--nom * (ori - 1));
+ while (hld < 120);
+
+ *pnom = nom;
+ *phld = hld;
+
+ return 0;
+}
+
+static int img_spdif_in_do_clkgen_single(struct img_spdif_in *spdif,
+ unsigned int rate)
+{
+ unsigned int nom, hld;
+ unsigned long flags, clk_rate;
+ int ret = 0;
+ u32 reg;
+
+ ret = img_spdif_in_check_max_rate(spdif, rate, &clk_rate);
+ if (ret)
+ return ret;
+
+ ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
+ if (ret)
+ return ret;
+
+ reg = (nom << IMG_SPDIF_IN_CLKGEN_NOM_SHIFT) &
+ IMG_SPDIF_IN_CLKGEN_NOM_MASK;
+ reg |= (hld << IMG_SPDIF_IN_CLKGEN_HLD_SHIFT) &
+ IMG_SPDIF_IN_CLKGEN_HLD_MASK;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CLKGEN);
+
+ spdif->single_freq = rate;
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_do_clkgen_multi(struct img_spdif_in *spdif,
+ unsigned int multi_freqs[])
+{
+ unsigned int nom, hld, rate, max_rate = 0;
+ unsigned long flags, clk_rate;
+ int i, ret = 0;
+ u32 reg, trk_reg, temp_regs[IMG_SPDIF_IN_NUM_ACLKGEN];
+
+ for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++)
+ if (multi_freqs[i] > max_rate)
+ max_rate = multi_freqs[i];
+
+ ret = img_spdif_in_check_max_rate(spdif, max_rate, &clk_rate);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
+ rate = multi_freqs[i];
+
+ ret = img_spdif_in_do_clkgen_calc(rate, &nom, &hld, clk_rate);
+ if (ret)
+ return ret;
+
+ reg = (nom << IMG_SPDIF_IN_ACLKGEN_NOM_SHIFT) &
+ IMG_SPDIF_IN_ACLKGEN_NOM_MASK;
+ reg |= (hld << IMG_SPDIF_IN_ACLKGEN_HLD_SHIFT) &
+ IMG_SPDIF_IN_ACLKGEN_HLD_MASK;
+ temp_regs[i] = reg;
+ }
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ trk_reg = spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT;
+
+ for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
+ spdif->aclkgen_regs[i] = temp_regs[i] | trk_reg;
+ img_spdif_in_aclkgen_writel(spdif, i);
+ }
+
+ spdif->multi_freq = true;
+ spdif->multi_freqs[0] = multi_freqs[0];
+ spdif->multi_freqs[1] = multi_freqs[1];
+ spdif->multi_freqs[2] = multi_freqs[2];
+ spdif->multi_freqs[3] = multi_freqs[3];
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_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 img_spdif_in_get_status_mask(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.iec958.status[0] = 0xff;
+ ucontrol->value.iec958.status[1] = 0xff;
+ ucontrol->value.iec958.status[2] = 0xff;
+ ucontrol->value.iec958.status[3] = 0xff;
+ ucontrol->value.iec958.status[4] = 0xff;
+
+ return 0;
+}
+
+static int img_spdif_in_get_status(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 reg;
+
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSL);
+ ucontrol->value.iec958.status[0] = reg & 0xff;
+ ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
+ ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
+ ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSH);
+ ucontrol->value.iec958.status[4] = (reg & IMG_SPDIF_IN_CSH_MASK)
+ >> IMG_SPDIF_IN_CSH_SHIFT;
+
+ return 0;
+}
+
+static int img_spdif_in_info_multi_freq(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = IMG_SPDIF_IN_NUM_ACLKGEN;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = LONG_MAX;
+
+ return 0;
+}
+
+static int img_spdif_in_get_multi_freq(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+ if (spdif->multi_freq) {
+ ucontrol->value.integer.value[0] = spdif->multi_freqs[0];
+ ucontrol->value.integer.value[1] = spdif->multi_freqs[1];
+ ucontrol->value.integer.value[2] = spdif->multi_freqs[2];
+ ucontrol->value.integer.value[3] = spdif->multi_freqs[3];
+ } else {
+ ucontrol->value.integer.value[0] = 0;
+ ucontrol->value.integer.value[1] = 0;
+ ucontrol->value.integer.value[2] = 0;
+ ucontrol->value.integer.value[3] = 0;
+ }
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_set_multi_freq(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned int multi_freqs[IMG_SPDIF_IN_NUM_ACLKGEN];
+ bool multi_freq;
+ unsigned long flags;
+
+ if ((ucontrol->value.integer.value[0] == 0) &&
+ (ucontrol->value.integer.value[1] == 0) &&
+ (ucontrol->value.integer.value[2] == 0) &&
+ (ucontrol->value.integer.value[3] == 0)) {
+ multi_freq = false;
+ } else {
+ multi_freqs[0] = ucontrol->value.integer.value[0];
+ multi_freqs[1] = ucontrol->value.integer.value[1];
+ multi_freqs[2] = ucontrol->value.integer.value[2];
+ multi_freqs[3] = ucontrol->value.integer.value[3];
+ multi_freq = true;
+ }
+
+ if (multi_freq)
+ return img_spdif_in_do_clkgen_multi(spdif, multi_freqs);
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ spdif->multi_freq = false;
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_info_lock_freq(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = LONG_MAX;
+
+ return 0;
+}
+
+static int img_spdif_in_get_lock_freq(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *uc)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 reg;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_STATUS);
+ if (reg & IMG_SPDIF_IN_STATUS_LOCK_MASK) {
+ if (spdif->multi_freq) {
+ i = ((reg & IMG_SPDIF_IN_STATUS_SAM_MASK) >>
+ IMG_SPDIF_IN_STATUS_SAM_SHIFT) - 1;
+ uc->value.integer.value[0] = spdif->multi_freqs[i];
+ } else {
+ uc->value.integer.value[0] = spdif->single_freq;
+ }
+ } else {
+ uc->value.integer.value[0] = 0;
+ }
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_info_trk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 255;
+
+ return 0;
+}
+
+static int img_spdif_in_get_trk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+
+ ucontrol->value.integer.value[0] = spdif->trk;
+
+ return 0;
+}
+
+static int img_spdif_in_set_trk(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags;
+ int i;
+ u32 reg;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ spdif->trk = ucontrol->value.integer.value[0];
+
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
+ reg &= ~IMG_SPDIF_IN_CTL_TRK_MASK;
+ reg |= spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+
+ for (i = 0; i < IMG_SPDIF_IN_NUM_ACLKGEN; i++) {
+ spdif->aclkgen_regs[i] = (spdif->aclkgen_regs[i] &
+ ~IMG_SPDIF_IN_ACLKGEN_TRK_MASK) |
+ (spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT);
+
+ img_spdif_in_aclkgen_writel(spdif, i);
+ }
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_info_lock(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = -128;
+ uinfo->value.integer.max = 127;
+
+ return 0;
+}
+
+static int img_spdif_in_get_lock_acquire(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+
+ ucontrol->value.integer.value[0] = spdif->lock_acquire;
+
+ return 0;
+}
+
+static int img_spdif_in_set_lock_acquire(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ spdif->lock_acquire = ucontrol->value.integer.value[0];
+
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
+ reg &= ~IMG_SPDIF_IN_CTL_LOCKHI_MASK;
+ reg |= (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
+ IMG_SPDIF_IN_CTL_LOCKHI_MASK;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_in_get_lock_release(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+
+ ucontrol->value.integer.value[0] = spdif->lock_release;
+
+ return 0;
+}
+
+static int img_spdif_in_set_lock_release(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ if (spdif->active) {
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ return -EBUSY;
+ }
+
+ spdif->lock_release = ucontrol->value.integer.value[0];
+
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
+ reg &= ~IMG_SPDIF_IN_CTL_LOCKLO_MASK;
+ reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
+ IMG_SPDIF_IN_CTL_LOCKLO_MASK;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static struct snd_kcontrol_new img_spdif_in_controls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK),
+ .info = img_spdif_in_iec958_info,
+ .get = img_spdif_in_get_status_mask
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
+ .info = img_spdif_in_iec958_info,
+ .get = img_spdif_in_get_status
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "SPDIF In Multi Frequency Acquire",
+ .info = img_spdif_in_info_multi_freq,
+ .get = img_spdif_in_get_multi_freq,
+ .put = img_spdif_in_set_multi_freq
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "SPDIF In Lock Frequency",
+ .info = img_spdif_in_info_lock_freq,
+ .get = img_spdif_in_get_lock_freq
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "SPDIF In Lock TRK",
+ .info = img_spdif_in_info_trk,
+ .get = img_spdif_in_get_trk,
+ .put = img_spdif_in_set_trk
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "SPDIF In Lock Acquire Threshold",
+ .info = img_spdif_in_info_lock,
+ .get = img_spdif_in_get_lock_acquire,
+ .put = img_spdif_in_set_lock_acquire
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "SPDIF In Lock Release Threshold",
+ .info = img_spdif_in_info_lock,
+ .get = img_spdif_in_get_lock_release,
+ .put = img_spdif_in_set_lock_release
+ }
+};
+
+static int img_spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ unsigned long flags;
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
+ int ret = 0;
+ u32 reg;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
+ if (spdif->multi_freq)
+ reg &= ~IMG_SPDIF_IN_CTL_SRD_MASK;
+ else
+ reg |= (1UL << IMG_SPDIF_IN_CTL_SRD_SHIFT);
+ reg |= IMG_SPDIF_IN_CTL_SRT_MASK;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+ spdif->active = true;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL);
+ reg &= ~IMG_SPDIF_IN_CTL_SRT_MASK;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+ spdif->active = false;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return ret;
+}
+
+static int img_spdif_in_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
+ unsigned int rate, channels, format;
+
+ rate = params_rate(params);
+ channels = params_channels(params);
+ format = params_format(params);
+
+ if (format != SNDRV_PCM_FORMAT_S32_LE)
+ return -EINVAL;
+
+ if (channels != 2)
+ return -EINVAL;
+
+ return img_spdif_in_do_clkgen_single(spdif, rate);
+}
+
+static const struct snd_soc_dai_ops img_spdif_in_dai_ops = {
+ .trigger = img_spdif_in_trigger,
+ .hw_params = img_spdif_in_hw_params
+};
+
+static int img_spdif_in_dai_probe(struct snd_soc_dai *dai)
+{
+ struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_init_dma_data(dai, NULL, &spdif->dma_data);
+
+ snd_soc_add_dai_controls(dai, img_spdif_in_controls,
+ ARRAY_SIZE(img_spdif_in_controls));
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver img_spdif_in_dai = {
+ .probe = img_spdif_in_dai_probe,
+ .capture = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE
+ },
+ .ops = &img_spdif_in_dai_ops
+};
+
+static const struct snd_soc_component_driver img_spdif_in_component = {
+ .name = "img-spdif-in"
+};
+
+static int img_spdif_in_probe(struct platform_device *pdev)
+{
+ struct img_spdif_in *spdif;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+ struct reset_control *rst;
+ u32 reg;
+
+ spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
+ if (!spdif)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, spdif);
+
+ spdif->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ spdif->base = base;
+
+ spdif->clk_sys = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(spdif->clk_sys))
+ return PTR_ERR(spdif->clk_sys);
+
+ ret = clk_prepare_enable(spdif->clk_sys);
+ if (ret)
+ return ret;
+
+ rst = devm_reset_control_get(&pdev->dev, "rst");
+ if (IS_ERR(rst)) {
+ dev_dbg(&pdev->dev,
+ "No top level reset found\n");
+ img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK,
+ IMG_SPDIF_IN_SOFT_RESET);
+ img_spdif_in_writel(spdif, 0, IMG_SPDIF_IN_SOFT_RESET);
+ } else {
+ reset_control_assert(rst);
+ reset_control_deassert(rst);
+ }
+
+ spin_lock_init(&spdif->lock);
+
+ spdif->dma_data.addr = res->start + IMG_SPDIF_IN_RX_FIFO_OFFSET;
+ spdif->dma_data.addr_width = 4;
+ spdif->dma_data.maxburst = 4;
+ spdif->trk = 0x80;
+ spdif->lock_acquire = 4;
+ spdif->lock_release = -128;
+
+ reg = (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) &
+ IMG_SPDIF_IN_CTL_LOCKHI_MASK;
+ reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) &
+ IMG_SPDIF_IN_CTL_LOCKLO_MASK;
+ reg |= (spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT) &
+ IMG_SPDIF_IN_CTL_TRK_MASK;
+ img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL);
+
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &img_spdif_in_component, &img_spdif_in_dai, 1);
+ if (ret)
+ goto err_clk_disable;
+
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+ if (ret)
+ goto err_clk_disable;
+
+ return 0;
+
+err_clk_disable:
+ clk_disable_unprepare(spdif->clk_sys);
+
+ return ret;
+}
+
+static int img_spdif_in_dev_remove(struct platform_device *pdev)
+{
+ struct img_spdif_in *spdif = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(spdif->clk_sys);
+
+ return 0;
+}
+
+static const struct of_device_id img_spdif_in_of_match[] = {
+ { .compatible = "img,spdif-in" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, img_spdif_in_of_match);
+
+static struct platform_driver img_spdif_in_driver = {
+ .driver = {
+ .name = "img-spdif-in",
+ .of_match_table = img_spdif_in_of_match
+ },
+ .probe = img_spdif_in_probe,
+ .remove = img_spdif_in_dev_remove
+};
+module_platform_driver(img_spdif_in_driver);
+
+MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
+MODULE_DESCRIPTION("IMG SPDIF Input driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/10] ASoC: img: Add binding document for SPDIF output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (7 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for SPDIF output controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 10/10] ASoC: img: Add driver for SPDIF output controller Damien Horsley
9 siblings, 1 reply; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add binding document for Imagination Technologies SPDIF
ouput controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
.../devicetree/bindings/sound/img,spdif-out.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-out.txt
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-out.txt b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
new file mode 100644
index 0000000..470a519
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
@@ -0,0 +1,44 @@
+Imagination Technologies SPDIF Output Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,spdif-out"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "tx"
+
+ - clocks : Contains an entry for each entry in clock-names.
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+ "ref" The reference clock
+
+ - resets: Contains a phandle to the spdif out reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Optional Properties:
+
+ - interrupts : Contains the parallel out interrupt, if present
+
+Example:
+
+spdif_out: spdif-out@18100D00 {
+ compatible = "img,spdif-out";
+ reg = <0x18100D00 0x100>;
+ interrupts = <GIC_SHARED 21 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 14 0xffffffff 0>;
+ dma-names = "tx";
+ clocks = <&cr_periph SYS_CLK_SPDIF_OUT>,
+ <&clk_core CLK_SPDIF>;
+ clock-names = "sys", "ref";
+ resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>;
+ reset-names = "rst";
+ #sound-dai-cells = <0>;
+};
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/10] ASoC: img: Add driver for SPDIF output controller
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
` (8 preceding siblings ...)
2015-09-30 15:08 ` [PATCH 09/10] ASoC: img: Add binding document for SPDIF output controller Damien Horsley
@ 2015-09-30 15:08 ` Damien Horsley
9 siblings, 0 replies; 26+ messages in thread
From: Damien Horsley @ 2015-09-30 15:08 UTC (permalink / raw)
To: alsa-devel
Cc: Mark Rutland, devicetree, Pawel Moll, Ian Campbell, linux-kernel,
Mark Brown, Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Add driver for Imagination Technologies SPDIF output
controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
---
sound/soc/img/Kconfig | 8 +
sound/soc/img/Makefile | 1 +
sound/soc/img/img-spdif-out.c | 432 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 441 insertions(+)
create mode 100644 sound/soc/img/img-spdif-out.c
diff --git a/sound/soc/img/Kconfig b/sound/soc/img/Kconfig
index 161ce90..d08537e 100644
--- a/sound/soc/img/Kconfig
+++ b/sound/soc/img/Kconfig
@@ -34,3 +34,11 @@ config SND_SOC_IMG_SPDIF_IN
help
Say Y or M if you want to add support for SPDIF input driver for
Imagination Technologies SPDIF input device.
+
+config SND_SOC_IMG_SPDIF_OUT
+ tristate "Imagination SPDIF Output Device Driver"
+ depends on SND_SOC_IMG
+ select SND_SOC_GENERIC_DMAENGINE_PCM
+ help
+ Say Y or M if you want to add support for SPDIF out driver for
+ Imagination Technologies SPDIF out device.
diff --git a/sound/soc/img/Makefile b/sound/soc/img/Makefile
index 85ded5e..1a44fb4 100644
--- a/sound/soc/img/Makefile
+++ b/sound/soc/img/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_IMG_I2S_IN) += img-i2s-in.o
obj-$(CONFIG_SND_SOC_IMG_I2S_OUT) += img-i2s-out.o
obj-$(CONFIG_SND_SOC_IMG_PARALLEL_OUT) += img-parallel-out.o
obj-$(CONFIG_SND_SOC_IMG_SPDIF_IN) += img-spdif-in.o
+obj-$(CONFIG_SND_SOC_IMG_SPDIF_OUT) += img-spdif-out.o
diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c
new file mode 100644
index 0000000..efddf5a
--- /dev/null
+++ b/sound/soc/img/img-spdif-out.c
@@ -0,0 +1,432 @@
+/*
+ * IMG SPDIF output controller driver
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ *
+ * Author: Damien Horsley <Damien.Horsley@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <sound/core.h>
+#include <sound/dmaengine_pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IMG_SPDIF_OUT_TX_FIFO 0x0
+
+#define IMG_SPDIF_OUT_CTL 0x4
+#define IMG_SPDIF_OUT_CTL_FS_MASK BIT(4)
+#define IMG_SPDIF_OUT_CTL_CLK_MASK BIT(2)
+#define IMG_SPDIF_OUT_CTL_SRT_MASK BIT(0)
+
+#define IMG_SPDIF_OUT_CSL 0x14
+
+#define IMG_SPDIF_OUT_CSH_UV 0x18
+#define IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT 0
+#define IMG_SPDIF_OUT_CSH_UV_CSH_MASK 0xff
+
+struct img_spdif_out {
+ spinlock_t lock;
+ void __iomem *base;
+ struct clk *clk_sys;
+ struct clk *clk_ref;
+ struct snd_dmaengine_dai_dma_data dma_data;
+ struct device *dev;
+ struct reset_control *rst;
+};
+
+static int img_spdif_out_suspend(struct device *dev)
+{
+ struct img_spdif_out *spdif = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(spdif->clk_ref);
+
+ return 0;
+}
+
+static int img_spdif_out_resume(struct device *dev)
+{
+ struct img_spdif_out *spdif = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(spdif->clk_ref);
+ if (ret) {
+ dev_err(dev, "clk_enable failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static inline void img_spdif_out_writel(struct img_spdif_out *spdif, u32 val,
+ u32 reg)
+{
+ writel(val, spdif->base + reg);
+}
+
+static inline u32 img_spdif_out_readl(struct img_spdif_out *spdif, u32 reg)
+{
+ return readl(spdif->base + reg);
+}
+
+static void img_spdif_out_reset(struct img_spdif_out *spdif)
+{
+ u32 ctl, status_low, status_high;
+
+ ctl = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL) &
+ ~IMG_SPDIF_OUT_CTL_SRT_MASK;
+ status_low = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
+ status_high = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
+
+ reset_control_assert(spdif->rst);
+ reset_control_deassert(spdif->rst);
+
+ img_spdif_out_writel(spdif, ctl, IMG_SPDIF_OUT_CTL);
+ img_spdif_out_writel(spdif, status_low, IMG_SPDIF_OUT_CSL);
+ img_spdif_out_writel(spdif, status_high, IMG_SPDIF_OUT_CSH_UV);
+}
+
+static int img_spdif_out_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 img_spdif_out_get_status_mask(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.iec958.status[0] = 0xff;
+ ucontrol->value.iec958.status[1] = 0xff;
+ ucontrol->value.iec958.status[2] = 0xff;
+ ucontrol->value.iec958.status[3] = 0xff;
+ ucontrol->value.iec958.status[4] = 0xff;
+
+ return 0;
+}
+
+static int img_spdif_out_get_status(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSL);
+ ucontrol->value.iec958.status[0] = reg & 0xff;
+ ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff;
+ ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff;
+ ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff;
+
+ reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
+ ucontrol->value.iec958.status[4] =
+ (reg & IMG_SPDIF_OUT_CSH_UV_CSH_MASK) >>
+ IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static int img_spdif_out_set_status(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+ struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(cpu_dai);
+ u32 reg;
+ unsigned long flags;
+
+ reg = ((u32)ucontrol->value.iec958.status[3] << 24);
+ reg |= ((u32)ucontrol->value.iec958.status[2] << 16);
+ reg |= ((u32)ucontrol->value.iec958.status[1] << 8);
+ reg |= (u32)ucontrol->value.iec958.status[0];
+
+ spin_lock_irqsave(&spdif->lock, flags);
+
+ img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSL);
+
+ reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CSH_UV);
+ reg &= ~IMG_SPDIF_OUT_CSH_UV_CSH_MASK;
+ reg |= (u32)ucontrol->value.iec958.status[4] <<
+ IMG_SPDIF_OUT_CSH_UV_CSH_SHIFT;
+ img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CSH_UV);
+
+ spin_unlock_irqrestore(&spdif->lock, flags);
+
+ return 0;
+}
+
+static struct snd_kcontrol_new img_spdif_out_controls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
+ .info = img_spdif_out_info,
+ .get = img_spdif_out_get_status_mask
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .info = img_spdif_out_info,
+ .get = img_spdif_out_get_status,
+ .put = img_spdif_out_set_status
+ }
+};
+
+static int img_spdif_out_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
+ u32 reg;
+ unsigned long flags;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
+ reg |= IMG_SPDIF_OUT_CTL_SRT_MASK;
+ img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ spin_lock_irqsave(&spdif->lock, flags);
+ img_spdif_out_reset(spdif);
+ spin_unlock_irqrestore(&spdif->lock, flags);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int img_spdif_out_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
+ unsigned int format, channels;
+ long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
+ u32 reg;
+
+ rate = params_rate(params);
+ format = params_format(params);
+ channels = params_channels(params);
+
+ dev_dbg(spdif->dev, "hw_params rate %ld channels %u format %u\n",
+ rate, channels, format);
+
+ if (format != SNDRV_PCM_FORMAT_S32_LE)
+ return -EINVAL;
+
+ if (channels != 2)
+ return -EINVAL;
+
+ pre_div_a = clk_round_rate(spdif->clk_ref, rate * 256);
+ if (pre_div_a < 0)
+ return pre_div_a;
+ pre_div_b = clk_round_rate(spdif->clk_ref, rate * 384);
+ if (pre_div_b < 0)
+ return pre_div_b;
+
+ diff_a = abs((pre_div_a / 256) - rate);
+ diff_b = abs((pre_div_b / 384) - rate);
+
+ /* If diffs are equal, use lower clock rate */
+ if (diff_a > diff_b)
+ clk_set_rate(spdif->clk_ref, pre_div_b);
+ else
+ clk_set_rate(spdif->clk_ref, pre_div_a);
+
+ /*
+ * Another driver (eg machine driver) may have rejected the above
+ * change. Get the current rate and set the register bit according to
+ * the new min diff
+ */
+ clk_rate = clk_get_rate(spdif->clk_ref);
+
+ diff_a = abs((clk_rate / 256) - rate);
+ diff_b = abs((clk_rate / 384) - rate);
+
+ reg = img_spdif_out_readl(spdif, IMG_SPDIF_OUT_CTL);
+ if (diff_a <= diff_b)
+ reg &= ~IMG_SPDIF_OUT_CTL_CLK_MASK;
+ else
+ reg |= IMG_SPDIF_OUT_CTL_CLK_MASK;
+ img_spdif_out_writel(spdif, reg, IMG_SPDIF_OUT_CTL);
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops img_spdif_out_dai_ops = {
+ .trigger = img_spdif_out_trigger,
+ .hw_params = img_spdif_out_hw_params
+};
+
+static int img_spdif_out_dai_probe(struct snd_soc_dai *dai)
+{
+ struct img_spdif_out *spdif = snd_soc_dai_get_drvdata(dai);
+
+ snd_soc_dai_init_dma_data(dai, &spdif->dma_data, NULL);
+
+ snd_soc_add_dai_controls(dai, img_spdif_out_controls,
+ ARRAY_SIZE(img_spdif_out_controls));
+
+ return 0;
+}
+
+static struct snd_soc_dai_driver img_spdif_out_dai = {
+ .probe = img_spdif_out_dai_probe,
+ .playback = {
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE
+ },
+ .ops = &img_spdif_out_dai_ops
+};
+
+static const struct snd_soc_component_driver img_spdif_out_component = {
+ .name = "img-spdif-out"
+};
+
+static int img_spdif_out_probe(struct platform_device *pdev)
+{
+ struct img_spdif_out *spdif;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
+ if (!spdif)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, spdif);
+
+ spdif->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ spdif->base = base;
+
+ spdif->rst = devm_reset_control_get(&pdev->dev, "rst");
+ if (IS_ERR(spdif->rst)) {
+ dev_err(&pdev->dev, "No top level reset found\n");
+ return PTR_ERR(spdif->rst);
+ }
+
+ spdif->clk_sys = devm_clk_get(&pdev->dev, "sys");
+ if (IS_ERR(spdif->clk_sys))
+ return PTR_ERR(spdif->clk_sys);
+
+ spdif->clk_ref = devm_clk_get(&pdev->dev, "ref");
+ if (IS_ERR(spdif->clk_ref))
+ return PTR_ERR(spdif->clk_ref);
+
+ ret = clk_prepare_enable(spdif->clk_sys);
+ if (ret)
+ return ret;
+
+ img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK,
+ IMG_SPDIF_OUT_CTL);
+
+ img_spdif_out_reset(spdif);
+
+ pm_runtime_enable(&pdev->dev);
+ if (!pm_runtime_enabled(&pdev->dev)) {
+ ret = img_spdif_out_resume(&pdev->dev);
+ if (ret)
+ goto err_pm_disable;
+ }
+
+ spin_lock_init(&spdif->lock);
+
+ spdif->dma_data.addr = res->start + IMG_SPDIF_OUT_TX_FIFO;
+ spdif->dma_data.addr_width = 4;
+ spdif->dma_data.maxburst = 4;
+
+ ret = devm_snd_soc_register_component(&pdev->dev,
+ &img_spdif_out_component,
+ &img_spdif_out_dai, 1);
+ if (ret)
+ goto err_suspend;
+
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
+ if (ret)
+ goto err_suspend;
+
+ dev_dbg(&pdev->dev, "Probe successful\n");
+
+ return 0;
+
+err_suspend:
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_spdif_out_suspend(&pdev->dev);
+err_pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ clk_disable_unprepare(spdif->clk_sys);
+
+ return ret;
+}
+
+static int img_spdif_out_dev_remove(struct platform_device *pdev)
+{
+ struct img_spdif_out *spdif = platform_get_drvdata(pdev);
+
+ pm_runtime_disable(&pdev->dev);
+ if (!pm_runtime_status_suspended(&pdev->dev))
+ img_spdif_out_suspend(&pdev->dev);
+
+ clk_disable_unprepare(spdif->clk_sys);
+
+ return 0;
+}
+
+static const struct of_device_id img_spdif_out_of_match[] = {
+ { .compatible = "img,spdif-out" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, img_spdif_out_of_match);
+
+static const struct dev_pm_ops img_spdif_out_pm_ops = {
+ SET_RUNTIME_PM_OPS(img_spdif_out_suspend,
+ img_spdif_out_resume, NULL)
+};
+
+static struct platform_driver img_spdif_out_driver = {
+ .driver = {
+ .name = "img-spdif-out",
+ .of_match_table = img_spdif_out_of_match,
+ .pm = &img_spdif_out_pm_ops
+ },
+ .probe = img_spdif_out_probe,
+ .remove = img_spdif_out_dev_remove
+};
+module_platform_driver(img_spdif_out_driver);
+
+MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>");
+MODULE_DESCRIPTION("IMG SPDIF Output driver");
+MODULE_LICENSE("GPL v2");
--
2.1.4
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 02/10] ASoC: img: Add driver for I2S input controller
2015-09-30 15:08 ` [PATCH 02/10] ASoC: img: Add driver " Damien Horsley
@ 2015-09-30 15:36 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:36 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 4662 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: x86_64-allmodconfig (attached as .config)
reproduce:
git checkout 4cccb3ee5a59803694ffb4e45054f3981e02aa4c
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-in.c:191:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-in.c:191:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-in.c:191:16: got restricted snd_pcm_format_t
sound/soc/img/img-i2s-in.c:196:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:202:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:207:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_hw_params':
>> sound/soc/img/img-i2s-in.c:237:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
^
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_set_fmt':
sound/soc/img/img-i2s-in.c:306:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
^
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-i2s-in.c:191:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-in.c:191:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-in.c:191:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-i2s-in.c:196:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:202:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:207:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_hw_params':
sound/soc/img/img-i2s-in.c:237:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
^
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_set_fmt':
sound/soc/img/img-i2s-in.c:306:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
^
vim +237 sound/soc/img/img-i2s-in.c
185 unsigned int bclk_filter_enable, bclk_filter_value;
186 int i, ret = 0;
187 u32 reg, control_reg, control_mask, chan_control_mask;
188 u32 control_set = 0, chan_control_set = 0;
189
190 rate = params_rate(params);
> 191 format = params_format(params);
192 channels = params_channels(params);
193 i2s_channels = channels / 2;
194
195 switch (format) {
> 196 case SNDRV_PCM_FORMAT_S32_LE:
197 frame_size = 64;
198 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
199 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
200 chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
201 break;
202 case SNDRV_PCM_FORMAT_S24_LE:
203 frame_size = 64;
204 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
205 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
206 break;
207 case SNDRV_PCM_FORMAT_S16_LE:
208 frame_size = 32;
209 control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
210 chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
211 break;
212 default:
213 return -EINVAL;
214 }
215
216 if ((channels < 2) ||
217 (channels > (i2s->max_i2s_chan * 2)) ||
218 (channels % 2))
219 return -EINVAL;
220
221 control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);
222
223 ret = img_i2s_in_check_rate(i2s, rate, frame_size,
224 &bclk_filter_enable, &bclk_filter_value);
225 if (ret < 0)
226 return ret;
227
228 if (bclk_filter_enable)
229 chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;
230
231 if (bclk_filter_value)
232 chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;
233
234 control_mask = ~IMG_I2S_IN_CTL_16PACK_MASK &
235 ~IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;
236
> 237 chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
238 ~IMG_I2S_IN_CH_CTL_FEN_MASK &
239 ~IMG_I2S_IN_CH_CTL_FMODE_MASK &
240 ~IMG_I2S_IN_CH_CTL_SW_MASK &
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 50068 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 02/10] ASoC: img: Add driver for I2S input controller
@ 2015-09-30 15:36 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:36 UTC (permalink / raw)
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 4662 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: x86_64-allmodconfig (attached as .config)
reproduce:
git checkout 4cccb3ee5a59803694ffb4e45054f3981e02aa4c
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-in.c:191:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-in.c:191:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-in.c:191:16: got restricted snd_pcm_format_t
sound/soc/img/img-i2s-in.c:196:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:202:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:207:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_hw_params':
>> sound/soc/img/img-i2s-in.c:237:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
^
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_set_fmt':
sound/soc/img/img-i2s-in.c:306:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
^
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-i2s-in.c:191:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-in.c:191:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-in.c:191:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-i2s-in.c:196:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:202:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c:207:14: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_hw_params':
sound/soc/img/img-i2s-in.c:237:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
^
sound/soc/img/img-i2s-in.c: In function 'img_i2s_in_set_fmt':
sound/soc/img/img-i2s-in.c:306:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
^
vim +237 sound/soc/img/img-i2s-in.c
185 unsigned int bclk_filter_enable, bclk_filter_value;
186 int i, ret = 0;
187 u32 reg, control_reg, control_mask, chan_control_mask;
188 u32 control_set = 0, chan_control_set = 0;
189
190 rate = params_rate(params);
> 191 format = params_format(params);
192 channels = params_channels(params);
193 i2s_channels = channels / 2;
194
195 switch (format) {
> 196 case SNDRV_PCM_FORMAT_S32_LE:
197 frame_size = 64;
198 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
199 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
200 chan_control_set |= IMG_I2S_IN_CH_CTL_PACKH_MASK;
201 break;
202 case SNDRV_PCM_FORMAT_S24_LE:
203 frame_size = 64;
204 chan_control_set |= IMG_I2S_IN_CH_CTL_SW_MASK;
205 chan_control_set |= IMG_I2S_IN_CH_CTL_FW_MASK;
206 break;
207 case SNDRV_PCM_FORMAT_S16_LE:
208 frame_size = 32;
209 control_set |= IMG_I2S_IN_CTL_16PACK_MASK;
210 chan_control_set |= IMG_I2S_IN_CH_CTL_16PACK_MASK;
211 break;
212 default:
213 return -EINVAL;
214 }
215
216 if ((channels < 2) ||
217 (channels > (i2s->max_i2s_chan * 2)) ||
218 (channels % 2))
219 return -EINVAL;
220
221 control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT);
222
223 ret = img_i2s_in_check_rate(i2s, rate, frame_size,
224 &bclk_filter_enable, &bclk_filter_value);
225 if (ret < 0)
226 return ret;
227
228 if (bclk_filter_enable)
229 chan_control_set |= IMG_I2S_IN_CH_CTL_FEN_MASK;
230
231 if (bclk_filter_value)
232 chan_control_set |= IMG_I2S_IN_CH_CTL_FMODE_MASK;
233
234 control_mask = ~IMG_I2S_IN_CTL_16PACK_MASK &
235 ~IMG_I2S_IN_CTL_ACTIVE_CHAN_MASK;
236
> 237 chan_control_mask = ~IMG_I2S_IN_CH_CTL_16PACK_MASK &
238 ~IMG_I2S_IN_CH_CTL_FEN_MASK &
239 ~IMG_I2S_IN_CH_CTL_FMODE_MASK &
240 ~IMG_I2S_IN_CH_CTL_SW_MASK &
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 50068 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 15:42 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:42 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 4572 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: x86_64-allmodconfig (attached as .config)
reproduce:
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c:218:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-out.c:218:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-out.c:218:16: got restricted snd_pcm_format_t
sound/soc/img/img-i2s-out.c:222:23: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_hw_params':
>> sound/soc/img/img-i2s-out.c:263:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
^
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
sound/soc/img/img-i2s-out.c:336:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_EN_MASK &
^
sound/soc/img/img-i2s-out.c:341:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
^
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-i2s-out.c:218:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-out.c:218:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-out.c:218:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-i2s-out.c:222:23: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_hw_params':
sound/soc/img/img-i2s-out.c:263:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
^
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
sound/soc/img/img-i2s-out.c:336:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_EN_MASK &
^
sound/soc/img/img-i2s-out.c:341:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
^
vim +263 sound/soc/img/img-i2s-out.c
212 unsigned int channels, i2s_channels, format;
213 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
214 int i;
215 u32 reg, control_reg, control_mask, control_set = 0;
216
217 rate = params_rate(params);
> 218 format = params_format(params);
219 channels = params_channels(params);
220 i2s_channels = channels / 2;
221
> 222 if (format != SNDRV_PCM_FORMAT_S32_LE)
223 return -EINVAL;
224
225 if ((channels < 2) ||
226 (channels > (i2s->max_i2s_chan * 2)) ||
227 (channels % 2))
228 return -EINVAL;
229
230 pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
231 if (pre_div_a < 0)
232 return pre_div_a;
233 pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
234 if (pre_div_b < 0)
235 return pre_div_b;
236
237 diff_a = abs((pre_div_a / 256) - rate);
238 diff_b = abs((pre_div_b / 384) - rate);
239
240 /* If diffs are equal, use lower clock rate */
241 if (diff_a > diff_b)
242 clk_set_rate(i2s->clk_ref, pre_div_b);
243 else
244 clk_set_rate(i2s->clk_ref, pre_div_a);
245
246 /*
247 * Another driver (eg alsa machine driver) may have rejected the above
248 * change. Get the current rate and set the register bit according to
249 * the new minimum diff
250 */
251 clk_rate = clk_get_rate(i2s->clk_ref);
252
253 diff_a = abs((clk_rate / 256) - rate);
254 diff_b = abs((clk_rate / 384) - rate);
255
256 if (diff_a > diff_b)
257 control_set |= IMG_I2S_OUT_CTL_CLK_MASK;
258
259 control_set |= (((i2s_channels - 1) <<
260 IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
261 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK);
262
> 263 control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
264 ~IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
265
266 control_reg = img_i2s_out_disable(i2s);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 50074 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 15:42 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:42 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
Ian Campbell, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown,
Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 4572 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: x86_64-allmodconfig (attached as .config)
reproduce:
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c:218:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-out.c:218:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-out.c:218:16: got restricted snd_pcm_format_t
sound/soc/img/img-i2s-out.c:222:23: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_hw_params':
>> sound/soc/img/img-i2s-out.c:263:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
^
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
sound/soc/img/img-i2s-out.c:336:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_EN_MASK &
^
sound/soc/img/img-i2s-out.c:341:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
^
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-i2s-out.c:218:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-i2s-out.c:218:16: expected unsigned int [unsigned] format
sound/soc/img/img-i2s-out.c:218:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-i2s-out.c:222:23: sparse: restricted snd_pcm_format_t degrades to integer
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_hw_params':
sound/soc/img/img-i2s-out.c:263:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
^
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
sound/soc/img/img-i2s-out.c:336:17: warning: large integer implicitly truncated to unsigned type [-Woverflow]
control_mask = ~IMG_I2S_OUT_CTL_CLK_EN_MASK &
^
sound/soc/img/img-i2s-out.c:341:22: warning: large integer implicitly truncated to unsigned type [-Woverflow]
chan_control_mask = ~IMG_I2S_OUT_CHAN_CTL_CLKT_MASK;
^
vim +263 sound/soc/img/img-i2s-out.c
212 unsigned int channels, i2s_channels, format;
213 long pre_div_a, pre_div_b, diff_a, diff_b, rate, clk_rate;
214 int i;
215 u32 reg, control_reg, control_mask, control_set = 0;
216
217 rate = params_rate(params);
> 218 format = params_format(params);
219 channels = params_channels(params);
220 i2s_channels = channels / 2;
221
> 222 if (format != SNDRV_PCM_FORMAT_S32_LE)
223 return -EINVAL;
224
225 if ((channels < 2) ||
226 (channels > (i2s->max_i2s_chan * 2)) ||
227 (channels % 2))
228 return -EINVAL;
229
230 pre_div_a = clk_round_rate(i2s->clk_ref, rate * 256);
231 if (pre_div_a < 0)
232 return pre_div_a;
233 pre_div_b = clk_round_rate(i2s->clk_ref, rate * 384);
234 if (pre_div_b < 0)
235 return pre_div_b;
236
237 diff_a = abs((pre_div_a / 256) - rate);
238 diff_b = abs((pre_div_b / 384) - rate);
239
240 /* If diffs are equal, use lower clock rate */
241 if (diff_a > diff_b)
242 clk_set_rate(i2s->clk_ref, pre_div_b);
243 else
244 clk_set_rate(i2s->clk_ref, pre_div_a);
245
246 /*
247 * Another driver (eg alsa machine driver) may have rejected the above
248 * change. Get the current rate and set the register bit according to
249 * the new minimum diff
250 */
251 clk_rate = clk_get_rate(i2s->clk_ref);
252
253 diff_a = abs((clk_rate / 256) - rate);
254 diff_b = abs((clk_rate / 384) - rate);
255
256 if (diff_a > diff_b)
257 control_set |= IMG_I2S_OUT_CTL_CLK_MASK;
258
259 control_set |= (((i2s_channels - 1) <<
260 IMG_I2S_OUT_CTL_ACTIVE_CHAN_SHIFT) &
261 IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK);
262
> 263 control_mask = ~IMG_I2S_OUT_CTL_CLK_MASK &
264 ~IMG_I2S_OUT_CTL_ACTIVE_CHAN_MASK;
265
266 control_reg = img_i2s_out_disable(i2s);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 50074 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 06/10] ASoC: img: Add driver for parallel output controller
@ 2015-09-30 15:48 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:48 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-parallel-out.c:198:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-parallel-out.c:198:16: expected unsigned int [unsigned] format
sound/soc/img/img-parallel-out.c:198:16: got restricted snd_pcm_format_t
vim +198 sound/soc/img/img-parallel-out.c
182 }
183
184 spin_unlock_irqrestore(&prl->lock, flags);
185
186 return ret;
187 }
188
189 static int img_prl_out_hw_params(struct snd_pcm_substream *substream,
190 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
191 {
192 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
193 unsigned int rate, format, channels;
194 u32 reg, reg_set = 0;
195 unsigned long flags;
196
197 rate = params_rate(params);
> 198 format = params_format(params);
199 channels = params_channels(params);
200
201 switch (params_format(params)) {
202 case SNDRV_PCM_FORMAT_S32_LE:
203 reg_set |= IMG_PRL_OUT_CTL_PACKH_MASK;
204 break;
205 case SNDRV_PCM_FORMAT_S24_LE:
206 break;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 06/10] ASoC: img: Add driver for parallel output controller
@ 2015-09-30 15:48 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:48 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
Ian Campbell, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown,
Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-parallel-out.c:198:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-parallel-out.c:198:16: expected unsigned int [unsigned] format
sound/soc/img/img-parallel-out.c:198:16: got restricted snd_pcm_format_t
vim +198 sound/soc/img/img-parallel-out.c
182 }
183
184 spin_unlock_irqrestore(&prl->lock, flags);
185
186 return ret;
187 }
188
189 static int img_prl_out_hw_params(struct snd_pcm_substream *substream,
190 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
191 {
192 struct img_prl_out *prl = snd_soc_dai_get_drvdata(dai);
193 unsigned int rate, format, channels;
194 u32 reg, reg_set = 0;
195 unsigned long flags;
196
197 rate = params_rate(params);
> 198 format = params_format(params);
199 channels = params_channels(params);
200
201 switch (params_format(params)) {
202 case SNDRV_PCM_FORMAT_S32_LE:
203 reg_set |= IMG_PRL_OUT_CTL_PACKH_MASK;
204 break;
205 case SNDRV_PCM_FORMAT_S24_LE:
206 break;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller
2015-09-30 15:08 ` [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller Damien Horsley
@ 2015-09-30 15:53 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:53 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-spdif-in.c:650:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-spdif-in.c:650:16: expected unsigned int [unsigned] format
sound/soc/img/img-spdif-in.c:650:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-spdif-in.c:652:23: sparse: restricted snd_pcm_format_t degrades to integer
vim +650 sound/soc/img/img-spdif-in.c
644 {
645 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
646 unsigned int rate, channels, format;
647
648 rate = params_rate(params);
649 channels = params_channels(params);
> 650 format = params_format(params);
651
> 652 if (format != SNDRV_PCM_FORMAT_S32_LE)
653 return -EINVAL;
654
655 if (channels != 2)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller
@ 2015-09-30 15:53 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 15:53 UTC (permalink / raw)
Cc: Mark Rutland, devicetree, alsa-devel, Pawel Moll, Ian Campbell,
Liam Girdwood, linux-kernel, Rob Herring, Takashi Iwai,
Mark Brown, kbuild-all, Kumar Gala, Damien.Horsley
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
>> sound/soc/img/img-spdif-in.c:650:16: sparse: incorrect type in assignment (different base types)
sound/soc/img/img-spdif-in.c:650:16: expected unsigned int [unsigned] format
sound/soc/img/img-spdif-in.c:650:16: got restricted snd_pcm_format_t
>> sound/soc/img/img-spdif-in.c:652:23: sparse: restricted snd_pcm_format_t degrades to integer
vim +650 sound/soc/img/img-spdif-in.c
644 {
645 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai);
646 unsigned int rate, channels, format;
647
648 rate = params_rate(params);
649 channels = params_channels(params);
> 650 format = params_format(params);
651
> 652 if (format != SNDRV_PCM_FORMAT_S32_LE)
653 return -EINVAL;
654
655 if (channels != 2)
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 18:13 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 18:13 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 1807 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: sh-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make.cross ARCH=sh
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
>> sound/soc/img/img-i2s-out.c:108:2: warning: 'reg' may be used uninitialized in this function [-Wuninitialized]
sound/soc/img/img-i2s-out.c:291:6: note: 'reg' was declared here
vim +/reg +108 sound/soc/img/img-i2s-out.c
92 }
93
94 static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
95 u32 reg)
96 {
97 writel(val, i2s->base + reg);
98 }
99
100 static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
101 {
102 return readl(i2s->base + reg);
103 }
104
105 static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
106 u32 chan, u32 val, u32 reg)
107 {
> 108 writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
109 }
110
111 static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
112 u32 reg)
113 {
114 return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
115 }
116
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37263 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 18:13 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 18:13 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
Ian Campbell, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown,
Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 1807 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: sh-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make.cross ARCH=sh
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
>> sound/soc/img/img-i2s-out.c:108:2: warning: 'reg' may be used uninitialized in this function [-Wuninitialized]
sound/soc/img/img-i2s-out.c:291:6: note: 'reg' was declared here
vim +/reg +108 sound/soc/img/img-i2s-out.c
92 }
93
94 static inline void img_i2s_out_writel(struct img_i2s_out *i2s, u32 val,
95 u32 reg)
96 {
97 writel(val, i2s->base + reg);
98 }
99
100 static inline u32 img_i2s_out_readl(struct img_i2s_out *i2s, u32 reg)
101 {
102 return readl(i2s->base + reg);
103 }
104
105 static inline void img_i2s_out_ch_writel(struct img_i2s_out *i2s,
106 u32 chan, u32 val, u32 reg)
107 {
> 108 writel(val, i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
109 }
110
111 static inline u32 img_i2s_out_ch_readl(struct img_i2s_out *i2s, u32 chan,
112 u32 reg)
113 {
114 return readl(i2s->channel_base + (chan * IMG_I2S_OUT_CH_STRIDE) + reg);
115 }
116
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37263 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 18:34 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 18:34 UTC (permalink / raw)
To: Damien Horsley
Cc: kbuild-all, alsa-devel, Mark Rutland, devicetree, Pawel Moll,
Ian Campbell, linux-kernel, Mark Brown, Takashi Iwai,
Liam Girdwood, Rob Herring, Kumar Gala, Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 2820 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: blackfin-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make.cross ARCH=blackfin
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
>> include/asm-generic/io.h:163:2: warning: 'reg' may be used uninitialized in this function [-Wuninitialized]
sound/soc/img/img-i2s-out.c:291:6: note: 'reg' was declared here
vim +/reg +163 include/asm-generic/io.h
9216efaf Thierry Reding 2014-10-01 147 __raw_writeb(value, addr);
3f7e212d Arnd Bergmann 2009-05-13 148 }
9216efaf Thierry Reding 2014-10-01 149 #endif
3f7e212d Arnd Bergmann 2009-05-13 150
9216efaf Thierry Reding 2014-10-01 151 #ifndef writew
9216efaf Thierry Reding 2014-10-01 152 #define writew writew
9216efaf Thierry Reding 2014-10-01 153 static inline void writew(u16 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 154 {
9216efaf Thierry Reding 2014-10-01 155 __raw_writew(cpu_to_le16(value), addr);
3f7e212d Arnd Bergmann 2009-05-13 156 }
9216efaf Thierry Reding 2014-10-01 157 #endif
3f7e212d Arnd Bergmann 2009-05-13 158
9216efaf Thierry Reding 2014-10-01 159 #ifndef writel
9216efaf Thierry Reding 2014-10-01 160 #define writel writel
9216efaf Thierry Reding 2014-10-01 161 static inline void writel(u32 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 162 {
9216efaf Thierry Reding 2014-10-01 @163 __raw_writel(__cpu_to_le32(value), addr);
3f7e212d Arnd Bergmann 2009-05-13 164 }
9216efaf Thierry Reding 2014-10-01 165 #endif
3f7e212d Arnd Bergmann 2009-05-13 166
9216efaf Thierry Reding 2014-10-01 167 #ifdef CONFIG_64BIT
9216efaf Thierry Reding 2014-10-01 168 #ifndef writeq
9216efaf Thierry Reding 2014-10-01 169 #define writeq writeq
9216efaf Thierry Reding 2014-10-01 170 static inline void writeq(u64 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 171 {
:::::: The code at line 163 was first introduced by commit
:::::: 9216efafc52ff99e9351ef60de5fcafc2bc8adb6 asm-generic/io.h: Reconcile I/O accessor overrides
:::::: TO: Thierry Reding <treding@nvidia.com>
:::::: CC: Thierry Reding <treding@nvidia.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37945 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [alsa-devel] [PATCH 04/10] ASoC: img: Add driver for I2S output controller
@ 2015-09-30 18:34 ` kbuild test robot
0 siblings, 0 replies; 26+ messages in thread
From: kbuild test robot @ 2015-09-30 18:34 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA, Pawel Moll,
Ian Campbell, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Brown,
Takashi Iwai, Liam Girdwood, Rob Herring, Kumar Gala,
Damien.Horsley
[-- Attachment #1: Type: text/plain, Size: 2878 bytes --]
Hi Damien.Horsley,
[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]
config: blackfin-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 5037c15dd47c86ab337b73c7f9ffcabe1bb86f3b
# save the attached .config to linux build tree
make.cross ARCH=blackfin
Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings
All warnings (new ones prefixed by >>):
sound/soc/img/img-i2s-out.c: In function 'img_i2s_out_set_fmt':
>> include/asm-generic/io.h:163:2: warning: 'reg' may be used uninitialized in this function [-Wuninitialized]
sound/soc/img/img-i2s-out.c:291:6: note: 'reg' was declared here
vim +/reg +163 include/asm-generic/io.h
9216efaf Thierry Reding 2014-10-01 147 __raw_writeb(value, addr);
3f7e212d Arnd Bergmann 2009-05-13 148 }
9216efaf Thierry Reding 2014-10-01 149 #endif
3f7e212d Arnd Bergmann 2009-05-13 150
9216efaf Thierry Reding 2014-10-01 151 #ifndef writew
9216efaf Thierry Reding 2014-10-01 152 #define writew writew
9216efaf Thierry Reding 2014-10-01 153 static inline void writew(u16 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 154 {
9216efaf Thierry Reding 2014-10-01 155 __raw_writew(cpu_to_le16(value), addr);
3f7e212d Arnd Bergmann 2009-05-13 156 }
9216efaf Thierry Reding 2014-10-01 157 #endif
3f7e212d Arnd Bergmann 2009-05-13 158
9216efaf Thierry Reding 2014-10-01 159 #ifndef writel
9216efaf Thierry Reding 2014-10-01 160 #define writel writel
9216efaf Thierry Reding 2014-10-01 161 static inline void writel(u32 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 162 {
9216efaf Thierry Reding 2014-10-01 @163 __raw_writel(__cpu_to_le32(value), addr);
3f7e212d Arnd Bergmann 2009-05-13 164 }
9216efaf Thierry Reding 2014-10-01 165 #endif
3f7e212d Arnd Bergmann 2009-05-13 166
9216efaf Thierry Reding 2014-10-01 167 #ifdef CONFIG_64BIT
9216efaf Thierry Reding 2014-10-01 168 #ifndef writeq
9216efaf Thierry Reding 2014-10-01 169 #define writeq writeq
9216efaf Thierry Reding 2014-10-01 170 static inline void writeq(u64 value, volatile void __iomem *addr)
3f7e212d Arnd Bergmann 2009-05-13 171 {
:::::: The code at line 163 was first introduced by commit
:::::: 9216efafc52ff99e9351ef60de5fcafc2bc8adb6 asm-generic/io.h: Reconcile I/O accessor overrides
:::::: TO: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
:::::: CC: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37945 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Applied "ASoC: img: Add binding document for SPDIF output controller" to the asoc tree
2015-09-30 15:08 ` [PATCH 09/10] ASoC: img: Add binding document for SPDIF output controller Damien Horsley
@ 2015-11-04 14:59 ` Mark Brown
0 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2015-11-04 14:59 UTC (permalink / raw)
To: Damien.Horsley, Mark Brown; +Cc: alsa-devel
The patch
ASoC: img: Add binding document for SPDIF output controller
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 65189dbb82fe666e1dbdf06734e89d0d975ad487 Mon Sep 17 00:00:00 2001
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Date: Wed, 4 Nov 2015 14:40:56 +0000
Subject: [PATCH] ASoC: img: Add binding document for SPDIF output controller
Add binding document for Imagination Technologies SPDIF
ouput controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/sound/img,spdif-out.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-out.txt
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-out.txt b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
new file mode 100644
index 0000000..470a519
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-out.txt
@@ -0,0 +1,44 @@
+Imagination Technologies SPDIF Output Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,spdif-out"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "tx"
+
+ - clocks : Contains an entry for each entry in clock-names.
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+ "ref" The reference clock
+
+ - resets: Contains a phandle to the spdif out reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Optional Properties:
+
+ - interrupts : Contains the parallel out interrupt, if present
+
+Example:
+
+spdif_out: spdif-out@18100D00 {
+ compatible = "img,spdif-out";
+ reg = <0x18100D00 0x100>;
+ interrupts = <GIC_SHARED 21 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 14 0xffffffff 0>;
+ dma-names = "tx";
+ clocks = <&cr_periph SYS_CLK_SPDIF_OUT>,
+ <&clk_core CLK_SPDIF>;
+ clock-names = "sys", "ref";
+ resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>;
+ reset-names = "rst";
+ #sound-dai-cells = <0>;
+};
--
2.6.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Applied "ASoC: img: Add binding document for SPDIF input controller" to the asoc tree
2015-09-30 15:08 ` [PATCH 07/10] ASoC: img: Add binding document for SPDIF input controller Damien Horsley
@ 2015-11-04 14:59 ` Mark Brown
0 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2015-11-04 14:59 UTC (permalink / raw)
To: Damien.Horsley, Mark Brown; +Cc: alsa-devel
The patch
ASoC: img: Add binding document for SPDIF input controller
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 6ef44cda2506d82b35c16e7b22299c7c2ab12df0 Mon Sep 17 00:00:00 2001
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Date: Wed, 4 Nov 2015 14:40:53 +0000
Subject: [PATCH] ASoC: img: Add binding document for SPDIF input controller
Add binding document for Imagination Technologies SPDIF
input controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/sound/img,spdif-in.txt | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,spdif-in.txt
diff --git a/Documentation/devicetree/bindings/sound/img,spdif-in.txt b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
new file mode 100644
index 0000000..aab9a81
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,spdif-in.txt
@@ -0,0 +1,41 @@
+Imagination Technologies SPDIF Input Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,spdif-in"
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "rx"
+
+ - clocks : Contains an entry for each entry in clock-names
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+
+Optional Properties:
+
+ - resets: Should contain a phandle to the spdif in reset signal, if any
+
+ - reset-names: Should contain the reset signal name "rst", if a
+ reset phandle is given
+
+ - interrupts : Contains the spdif in interrupt, if present
+
+Example:
+
+spdif_in: spdif-in@18100E00 {
+ compatible = "img,spdif-in";
+ reg = <0x18100E00 0x100>;
+ interrupts = <GIC_SHARED 20 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 15 0xffffffff 0>;
+ dma-names = "rx";
+ clocks = <&cr_periph SYS_CLK_SPDIF_IN>;
+ clock-names = "sys";
+ #sound-dai-cells = <0>;
+};
--
2.6.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Applied "ASoC: img: Add binding document for parallel output controller" to the asoc tree
2015-09-30 15:08 ` [PATCH 05/10] ASoC: img: Add binding document for parallel " Damien Horsley
@ 2015-11-04 14:59 ` Mark Brown
0 siblings, 0 replies; 26+ messages in thread
From: Mark Brown @ 2015-11-04 14:59 UTC (permalink / raw)
To: Damien.Horsley, Mark Brown; +Cc: alsa-devel
The patch
ASoC: img: Add binding document for parallel output controller
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 20959eede6da7d9175f216b2f86e77a6e5b1ef2f Mon Sep 17 00:00:00 2001
From: "Damien.Horsley" <Damien.Horsley@imgtec.com>
Date: Wed, 4 Nov 2015 14:40:51 +0000
Subject: [PATCH] ASoC: img: Add binding document for parallel output
controller
Add binding document for Imagination Technologies parallel
output controller
Signed-off-by: Damien.Horsley <Damien.Horsley@imgtec.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/sound/img,parallel-out.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/img,parallel-out.txt
diff --git a/Documentation/devicetree/bindings/sound/img,parallel-out.txt b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
new file mode 100644
index 0000000..a3015d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/img,parallel-out.txt
@@ -0,0 +1,44 @@
+Imagination Technologies Parallel Output Controller
+
+Required Properties:
+
+ - compatible : Compatible list, must contain "img,parallel-out".
+
+ - #sound-dai-cells : Must be equal to 0
+
+ - reg : Offset and length of the register set for the device.
+
+ - dmas: Contains an entry for each entry in dma-names.
+
+ - dma-names: Must include the following entry:
+ "tx"
+
+ - clocks : Contains an entry for each entry in clock-names.
+
+ - clock-names : Includes the following entries:
+ "sys" The system clock
+ "ref" The reference clock
+
+ - resets: Contains a phandle to the parallel out reset signal
+
+ - reset-names: Contains the reset signal name "rst"
+
+Optional Properties:
+
+ - interrupts : Contains the parallel out interrupt, if present
+
+Example:
+
+parallel_out: parallel-out@18100C00 {
+ compatible = "img,parallel-out";
+ reg = <0x18100C00 0x100>;
+ interrupts = <GIC_SHARED 19 IRQ_TYPE_LEVEL_HIGH>;
+ dmas = <&mdc 16 0xffffffff 0>;
+ dma-names = "tx";
+ clocks = <&cr_periph SYS_CLK_PAUD_OUT>,
+ <&clk_core CLK_AUDIO_DAC>;
+ clock-names = "sys", "ref";
+ resets = <&pistachio_reset PISTACHIO_RESET_PRL_OUT>;
+ reset-names = "rst";
+ #sound-dai-cells = <0>;
+};
--
2.6.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
end of thread, other threads:[~2015-11-04 14:59 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-30 15:08 [PATCH 00/10] Add support for Imagination Technologies audio controllers Damien Horsley
2015-09-30 15:08 ` [PATCH 01/10] ASoC: img: Add binding document for I2S input controller Damien Horsley
2015-09-30 15:08 ` [PATCH 02/10] ASoC: img: Add driver " Damien Horsley
2015-09-30 15:36 ` [alsa-devel] " kbuild test robot
2015-09-30 15:36 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 03/10] ASoC: img: Add binding document for I2S output controller Damien Horsley
2015-09-30 15:08 ` [PATCH 04/10] ASoC: img: Add driver " Damien Horsley
2015-09-30 15:42 ` [alsa-devel] " kbuild test robot
2015-09-30 15:42 ` kbuild test robot
2015-09-30 18:13 ` kbuild test robot
2015-09-30 18:13 ` kbuild test robot
2015-09-30 18:34 ` kbuild test robot
2015-09-30 18:34 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 05/10] ASoC: img: Add binding document for parallel " Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for parallel output controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 06/10] ASoC: img: Add driver for parallel output controller Damien Horsley
2015-09-30 15:48 ` [alsa-devel] " kbuild test robot
2015-09-30 15:48 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 07/10] ASoC: img: Add binding document for SPDIF input controller Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for SPDIF input controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 08/10] ASoC: img: Add driver for SPDIF input controller Damien Horsley
2015-09-30 15:53 ` [alsa-devel] " kbuild test robot
2015-09-30 15:53 ` kbuild test robot
2015-09-30 15:08 ` [PATCH 09/10] ASoC: img: Add binding document for SPDIF output controller Damien Horsley
2015-11-04 14:59 ` Applied "ASoC: img: Add binding document for SPDIF output controller" to the asoc tree Mark Brown
2015-09-30 15:08 ` [PATCH 10/10] ASoC: img: Add driver for SPDIF output controller Damien Horsley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.