aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt155
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/codecs/Kconfig4
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/ssm2518.c9
-rw-r--r--sound/soc/codecs/sta529.c3
-rw-r--r--sound/soc/codecs/sti-sas.c628
-rw-r--r--sound/soc/sti/Kconfig11
-rw-r--r--sound/soc/sti/Makefile4
-rw-r--r--sound/soc/sti/sti_uniperif.c254
-rw-r--r--sound/soc/sti/uniperif.h1229
-rw-r--r--sound/soc/sti/uniperif_player.c1110
-rw-r--r--sound/soc/sti/uniperif_reader.c362
14 files changed, 3770 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
new file mode 100644
index 000000000000..028fa1c82f50
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
@@ -0,0 +1,155 @@
1STMicroelectronics sti ASoC cards
2
3The sti ASoC Sound Card can be used, for all sti SoCs using internal sti-sas
4codec or external codecs.
5
6sti sound drivers allows to expose sti SoC audio interface through the
7generic ASoC simple card. For details about sound card declaration please refer to
8Documentation/devicetree/bindings/sound/simple-card.txt.
9
101) sti-uniperiph-dai: audio dai device.
11---------------------------------------
12
13Required properties:
14 - compatible: "st,sti-uni-player" or "st,sti-uni-reader"
15
16 - st,syscfg: phandle to boot-device system configuration registers
17
18 - clock-names: name of the clocks listed in clocks property in the same order
19
20 - reg: CPU DAI IP Base address and size entries, listed in same
21 order than the CPU_DAI properties.
22
23 - reg-names: names of the mapped memory regions listed in regs property in
24 the same order.
25
26 - interrupts: CPU_DAI interrupt line, listed in the same order than the
27 CPU_DAI properties.
28
29 - dma: CPU_DAI DMA controller phandle and DMA request line, listed in the same
30 order than the CPU_DAI properties.
31
32 - dma-names: identifier string for each DMA request line in the dmas property.
33 "tx" for "st,sti-uni-player" compatibility
34 "rx" for "st,sti-uni-reader" compatibility
35
36 - version: IP version integrated in SOC.
37
38 - dai-name: DAI name that describes the IP.
39
40Required properties ("st,sti-uni-player" compatibility only):
41 - clocks: CPU_DAI IP clock source, listed in the same order than the
42 CPU_DAI properties.
43
44 - uniperiph-id: internal SOC IP instance ID.
45
46 - IP mode: IP working mode depending on associated codec.
47 "HDMI" connected to HDMI codec IP and IEC HDMI formats.
48 "SPDIF"connected to SPDIF codec and support SPDIF formats.
49 "PCM" PCM standard mode for I2S or TDM bus.
50
51Optional properties:
52 - pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for
53 external codecs connection.
54
55 - pinctrl-names: should contain only one value - "default".
56
57Example:
58
59 sti_uni_player2: sti-uni-player@2 {
60 compatible = "st,sti-uni-player";
61 status = "okay";
62 #sound-dai-cells = <0>;
63 st,syscfg = <&syscfg_core>;
64 clocks = <&clk_s_d0_flexgen CLK_PCM_2>;
65 reg = <0x8D82000 0x158>;
66 interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
67 dmas = <&fdma0 4 0 1>;
68 dai-name = "Uni Player #1 (DAC)";
69 dma-names = "tx";
70 uniperiph-id = <2>;
71 version = <5>;
72 mode = "PCM";
73 };
74
75 sti_uni_player3: sti-uni-player@3 {
76 compatible = "st,sti-uni-player";
77 status = "okay";
78 #sound-dai-cells = <0>;
79 st,syscfg = <&syscfg_core>;
80 clocks = <&clk_s_d0_flexgen CLK_SPDIFF>;
81 reg = <0x8D85000 0x158>;
82 interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
83 dmas = <&fdma0 7 0 1>;
84 dma-names = "tx";
85 dai-name = "Uni Player #1 (PIO)";
86 uniperiph-id = <3>;
87 version = <5>;
88 mode = "SPDIF";
89 };
90
91 sti_uni_reader1: sti-uni-reader@1 {
92 compatible = "st,sti-uni-reader";
93 status = "disabled";
94 #sound-dai-cells = <0>;
95 st,syscfg = <&syscfg_core>;
96 reg = <0x8D84000 0x158>;
97 interrupts = <GIC_SPI 88 IRQ_TYPE_NONE>;
98 dmas = <&fdma0 6 0 1>;
99 dma-names = "rx";
100 dai-name = "Uni Reader #1 (HDMI RX)";
101 version = <3>;
102 };
103
1042) sti-sas-codec: internal audio codec IPs driver
105-------------------------------------------------
106
107Required properties:
108 - compatible: "st,sti<chip>-sas-codec" .
109 Should be chip "st,stih416-sas-codec" or "st,stih407-sas-codec"
110
111 - st,syscfg: phandle to boot-device system configuration registers.
112
113 - pinctrl-0: SPDIF PIO description.
114
115 - pinctrl-names: should contain only one value - "default".
116
117Example:
118 sti_sas_codec: sti-sas-codec {
119 compatible = "st,stih407-sas-codec";
120 #sound-dai-cells = <1>;
121 st,reg_audio = <&syscfg_core>;
122 pinctrl-names = "default";
123 pinctrl-0 = <&pinctrl_spdif_out >;
124 };
125
126Example of audio card declaration:
127 sound {
128 compatible = "simple-audio-card";
129 simple-audio-card,name = "sti audio card";
130 status = "okay";
131
132 simple-audio-card,dai-link@0 {
133 /* DAC */
134 format = "i2s";
135 dai-tdm-slot-width = <32>;
136 cpu {
137 sound-dai = <&sti_uni_player2>;
138 };
139
140 codec {
141 sound-dai = <&sti_sasg_codec 1>;
142 };
143 };
144 simple-audio-card,dai-link@1 {
145 /* SPDIF */
146 format = "left_j";
147 cpu {
148 sound-dai = <&sti_uni_player3>;
149 };
150
151 codec {
152 sound-dai = <&sti_sasg_codec 0>;
153 };
154 };
155 };
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 1d651b8a8957..225bfda414e9 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -57,6 +57,7 @@ source "sound/soc/samsung/Kconfig"
57source "sound/soc/sh/Kconfig" 57source "sound/soc/sh/Kconfig"
58source "sound/soc/sirf/Kconfig" 58source "sound/soc/sirf/Kconfig"
59source "sound/soc/spear/Kconfig" 59source "sound/soc/spear/Kconfig"
60source "sound/soc/sti/Kconfig"
60source "sound/soc/tegra/Kconfig" 61source "sound/soc/tegra/Kconfig"
61source "sound/soc/txx9/Kconfig" 62source "sound/soc/txx9/Kconfig"
62source "sound/soc/ux500/Kconfig" 63source "sound/soc/ux500/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 669648b41d30..134aca150a50 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_SND_SOC) += samsung/
39obj-$(CONFIG_SND_SOC) += sh/ 39obj-$(CONFIG_SND_SOC) += sh/
40obj-$(CONFIG_SND_SOC) += sirf/ 40obj-$(CONFIG_SND_SOC) += sirf/
41obj-$(CONFIG_SND_SOC) += spear/ 41obj-$(CONFIG_SND_SOC) += spear/
42obj-$(CONFIG_SND_SOC) += sti/
42obj-$(CONFIG_SND_SOC) += tegra/ 43obj-$(CONFIG_SND_SOC) += tegra/
43obj-$(CONFIG_SND_SOC) += txx9/ 44obj-$(CONFIG_SND_SOC) += txx9/
44obj-$(CONFIG_SND_SOC) += ux500/ 45obj-$(CONFIG_SND_SOC) += ux500/
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6fd467cde101..0c9733ecd17f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -106,6 +106,7 @@ config SND_SOC_ALL_CODECS
106 select SND_SOC_STA350 if I2C 106 select SND_SOC_STA350 if I2C
107 select SND_SOC_STA529 if I2C 107 select SND_SOC_STA529 if I2C
108 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 108 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
109 select SND_SOC_STI_SAS
109 select SND_SOC_TAS2552 if I2C 110 select SND_SOC_TAS2552 if I2C
110 select SND_SOC_TAS5086 if I2C 111 select SND_SOC_TAS5086 if I2C
111 select SND_SOC_TAS571X if I2C 112 select SND_SOC_TAS571X if I2C
@@ -631,6 +632,9 @@ config SND_SOC_STA529
631config SND_SOC_STAC9766 632config SND_SOC_STAC9766
632 tristate 633 tristate
633 634
635config SND_SOC_STI_SAS
636 tristate "codec Audio support for STI SAS codec"
637
634config SND_SOC_TAS2552 638config SND_SOC_TAS2552
635 tristate "Texas Instruments TAS2552 Mono Audio amplifier" 639 tristate "Texas Instruments TAS2552 Mono Audio amplifier"
636 depends on I2C 640 depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f65bd7b0e97e..4a32077954ae 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -110,6 +110,7 @@ snd-soc-sta32x-objs := sta32x.o
110snd-soc-sta350-objs := sta350.o 110snd-soc-sta350-objs := sta350.o
111snd-soc-sta529-objs := sta529.o 111snd-soc-sta529-objs := sta529.o
112snd-soc-stac9766-objs := stac9766.o 112snd-soc-stac9766-objs := stac9766.o
113snd-soc-sti-sas-objs := sti-sas.o
113snd-soc-tas5086-objs := tas5086.o 114snd-soc-tas5086-objs := tas5086.o
114snd-soc-tas571x-objs := tas571x.o 115snd-soc-tas571x-objs := tas571x.o
115snd-soc-tfa9879-objs := tfa9879.o 116snd-soc-tfa9879-objs := tfa9879.o
@@ -297,6 +298,7 @@ obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
297obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o 298obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o
298obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o 299obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
299obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 300obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
301obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o
300obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o 302obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o
301obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 303obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
302obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o 304obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index 5d94d6c7ad33..ddb0203fc649 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -806,6 +806,14 @@ static int ssm2518_i2c_remove(struct i2c_client *client)
806 return 0; 806 return 0;
807} 807}
808 808
809#ifdef CONFIG_OF
810static const struct of_device_id ssm2518_dt_ids[] = {
811 { .compatible = "adi,ssm2518", },
812 { }
813};
814MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
815#endif
816
809static const struct i2c_device_id ssm2518_i2c_ids[] = { 817static const struct i2c_device_id ssm2518_i2c_ids[] = {
810 { "ssm2518", 0 }, 818 { "ssm2518", 0 },
811 { } 819 { }
@@ -815,6 +823,7 @@ MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
815static struct i2c_driver ssm2518_driver = { 823static struct i2c_driver ssm2518_driver = {
816 .driver = { 824 .driver = {
817 .name = "ssm2518", 825 .name = "ssm2518",
826 .of_match_table = of_match_ptr(ssm2518_dt_ids),
818 }, 827 },
819 .probe = ssm2518_i2c_probe, 828 .probe = ssm2518_i2c_probe,
820 .remove = ssm2518_i2c_remove, 829 .remove = ssm2518_i2c_remove,
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 3430f444c1ae..2cdaca943a8c 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -339,9 +339,6 @@ static int sta529_i2c_probe(struct i2c_client *i2c,
339 struct sta529 *sta529; 339 struct sta529 *sta529;
340 int ret; 340 int ret;
341 341
342 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
343 return -EINVAL;
344
345 sta529 = devm_kzalloc(&i2c->dev, sizeof(struct sta529), GFP_KERNEL); 342 sta529 = devm_kzalloc(&i2c->dev, sizeof(struct sta529), GFP_KERNEL);
346 if (!sta529) 343 if (!sta529)
347 return -ENOMEM; 344 return -ENOMEM;
diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c
new file mode 100644
index 000000000000..160d61a66204
--- /dev/null
+++ b/sound/soc/codecs/sti-sas.c
@@ -0,0 +1,628 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2015
3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
4 * for STMicroelectronics.
5 * License terms: GNU General Public License (GPL), version 2
6 */
7
8#include <linux/io.h>
9#include <linux/module.h>
10#include <linux/regmap.h>
11#include <linux/reset.h>
12#include <linux/mfd/syscon.h>
13
14#include <sound/soc.h>
15#include <sound/soc-dapm.h>
16
17/* chipID supported */
18#define CHIPID_STIH416 0
19#define CHIPID_STIH407 1
20
21/* DAC definitions */
22
23/* stih416 DAC registers */
24/* sysconf 2517: Audio-DAC-Control */
25#define STIH416_AUDIO_DAC_CTRL 0x00000814
26/* sysconf 2519: Audio-Gue-Control */
27#define STIH416_AUDIO_GLUE_CTRL 0x0000081C
28
29#define STIH416_DAC_NOT_STANDBY 0x3
30#define STIH416_DAC_SOFTMUTE 0x4
31#define STIH416_DAC_ANA_NOT_PWR 0x5
32#define STIH416_DAC_NOT_PNDBG 0x6
33
34#define STIH416_DAC_NOT_STANDBY_MASK BIT(STIH416_DAC_NOT_STANDBY)
35#define STIH416_DAC_SOFTMUTE_MASK BIT(STIH416_DAC_SOFTMUTE)
36#define STIH416_DAC_ANA_NOT_PWR_MASK BIT(STIH416_DAC_ANA_NOT_PWR)
37#define STIH416_DAC_NOT_PNDBG_MASK BIT(STIH416_DAC_NOT_PNDBG)
38
39/* stih407 DAC registers */
40/* sysconf 5041: Audio-Gue-Control */
41#define STIH407_AUDIO_GLUE_CTRL 0x000000A4
42/* sysconf 5042: Audio-DAC-Control */
43#define STIH407_AUDIO_DAC_CTRL 0x000000A8
44
45/* DAC definitions */
46#define STIH407_DAC_SOFTMUTE 0x0
47#define STIH407_DAC_STANDBY_ANA 0x1
48#define STIH407_DAC_STANDBY 0x2
49
50#define STIH407_DAC_SOFTMUTE_MASK BIT(STIH407_DAC_SOFTMUTE)
51#define STIH407_DAC_STANDBY_ANA_MASK BIT(STIH407_DAC_STANDBY_ANA)
52#define STIH407_DAC_STANDBY_MASK BIT(STIH407_DAC_STANDBY)
53
54/* SPDIF definitions */
55#define SPDIF_BIPHASE_ENABLE 0x6
56#define SPDIF_BIPHASE_IDLE 0x7
57
58#define SPDIF_BIPHASE_ENABLE_MASK BIT(SPDIF_BIPHASE_ENABLE)
59#define SPDIF_BIPHASE_IDLE_MASK BIT(SPDIF_BIPHASE_IDLE)
60
61enum {
62 STI_SAS_DAI_SPDIF_OUT,
63 STI_SAS_DAI_ANALOG_OUT,
64};
65
66static const struct reg_default stih416_sas_reg_defaults[] = {
67 { STIH407_AUDIO_GLUE_CTRL, 0x00000040 },
68 { STIH407_AUDIO_DAC_CTRL, 0x000000000 },
69};
70
71static const struct reg_default stih407_sas_reg_defaults[] = {
72 { STIH416_AUDIO_DAC_CTRL, 0x000000000 },
73 { STIH416_AUDIO_GLUE_CTRL, 0x00000040 },
74};
75
76struct sti_dac_audio {
77 struct regmap *regmap;
78 struct regmap *virt_regmap;
79 struct regmap_field **field;
80 struct reset_control *rst;
81 int mclk;
82};
83
84struct sti_spdif_audio {
85 struct regmap *regmap;
86 struct regmap_field **field;
87 int mclk;
88};
89
90/* device data structure */
91struct sti_sas_dev_data {
92 const int chipid; /* IC version */
93 const struct regmap_config *regmap;
94 const struct snd_soc_dai_ops *dac_ops; /* DAC function callbacks */
95 const struct snd_soc_dapm_widget *dapm_widgets; /* dapms declaration */
96 const int num_dapm_widgets; /* dapms declaration */
97 const struct snd_soc_dapm_route *dapm_routes; /* route declaration */
98 const int num_dapm_routes; /* route declaration */
99};
100
101/* driver data structure */
102struct sti_sas_data {
103 struct device *dev;
104 const struct sti_sas_dev_data *dev_data;
105 struct sti_dac_audio dac;
106 struct sti_spdif_audio spdif;
107};
108
109/* Read a register from the sysconf reg bank */
110static int sti_sas_read_reg(void *context, unsigned int reg,
111 unsigned int *value)
112{
113 struct sti_sas_data *drvdata = context;
114 int status;
115 u32 val;
116
117 status = regmap_read(drvdata->dac.regmap, reg, &val);
118 *value = (unsigned int)val;
119
120 return status;
121}
122
123/* Read a register from the sysconf reg bank */
124static int sti_sas_write_reg(void *context, unsigned int reg,
125 unsigned int value)
126{
127 struct sti_sas_data *drvdata = context;
128 int status;
129
130 status = regmap_write(drvdata->dac.regmap, reg, value);
131
132 return status;
133}
134
135static int sti_sas_init_sas_registers(struct snd_soc_codec *codec,
136 struct sti_sas_data *data)
137{
138 int ret;
139 /*
140 * DAC and SPDIF are activated by default
141 * put them in IDLE to save power
142 */
143
144 /* Initialise bi-phase formatter to disabled */
145 ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
146 SPDIF_BIPHASE_ENABLE_MASK, 0);
147
148 if (!ret)
149 /* Initialise bi-phase formatter idle value to 0 */
150 ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
151 SPDIF_BIPHASE_IDLE_MASK, 0);
152 if (ret < 0) {
153 dev_err(codec->dev, "Failed to update SPDIF registers");
154 return ret;
155 }
156
157 /* Init DAC configuration */
158 switch (data->dev_data->chipid) {
159 case CHIPID_STIH407:
160 /* init configuration */
161 ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
162 STIH407_DAC_STANDBY_MASK,
163 STIH407_DAC_STANDBY_MASK);
164
165 if (!ret)
166 ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
167 STIH407_DAC_STANDBY_ANA_MASK,
168 STIH407_DAC_STANDBY_ANA_MASK);
169 if (!ret)
170 ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
171 STIH407_DAC_SOFTMUTE_MASK,
172 STIH407_DAC_SOFTMUTE_MASK);
173 break;
174 case CHIPID_STIH416:
175 ret = snd_soc_update_bits(codec, STIH416_AUDIO_DAC_CTRL,
176 STIH416_DAC_NOT_STANDBY_MASK, 0);
177 if (!ret)
178 ret = snd_soc_update_bits(codec,
179 STIH416_AUDIO_DAC_CTRL,
180 STIH416_DAC_ANA_NOT_PWR, 0);
181 if (!ret)
182 ret = snd_soc_update_bits(codec,
183 STIH416_AUDIO_DAC_CTRL,
184 STIH416_DAC_NOT_PNDBG_MASK,
185 0);
186 if (!ret)
187 ret = snd_soc_update_bits(codec,
188 STIH416_AUDIO_DAC_CTRL,
189 STIH416_DAC_SOFTMUTE_MASK,
190 STIH416_DAC_SOFTMUTE_MASK);
191 break;
192 default:
193 return -EINVAL;
194 }
195
196 if (ret < 0) {
197 dev_err(codec->dev, "Failed to update DAC registers");
198 return ret;
199 }
200
201 return ret;
202}
203
204/*
205 * DAC
206 */
207static int sti_sas_dac_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
208{
209 /* Sanity check only */
210 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
211 dev_err(dai->codec->dev,
212 "%s: ERROR: Unsupporter master mask 0x%x\n",
213 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
214 return -EINVAL;
215 }
216
217 return 0;
218}
219
220static int stih416_dac_probe(struct snd_soc_dai *dai)
221{
222 struct snd_soc_codec *codec = dai->codec;
223 struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
224 struct sti_dac_audio *dac = &drvdata->dac;
225
226 /* Get reset control */
227 dac->rst = devm_reset_control_get(codec->dev, "dac_rst");
228 if (IS_ERR(dac->rst)) {
229 dev_err(dai->codec->dev,
230 "%s: ERROR: DAC reset control not defined !\n",
231 __func__);
232 dac->rst = NULL;
233 return -EFAULT;
234 }
235 /* Put the DAC into reset */
236 reset_control_assert(dac->rst);
237
238 return 0;
239}
240
241static const struct snd_soc_dapm_widget stih416_sas_dapm_widgets[] = {
242 SND_SOC_DAPM_PGA("DAC bandgap", STIH416_AUDIO_DAC_CTRL,
243 STIH416_DAC_NOT_PNDBG_MASK, 0, NULL, 0),
244 SND_SOC_DAPM_OUT_DRV("DAC standby ana", STIH416_AUDIO_DAC_CTRL,
245 STIH416_DAC_ANA_NOT_PWR, 0, NULL, 0),
246 SND_SOC_DAPM_DAC("DAC standby", "dac_p", STIH416_AUDIO_DAC_CTRL,
247 STIH416_DAC_NOT_STANDBY, 0),
248 SND_SOC_DAPM_OUTPUT("DAC Output"),
249};
250
251static const struct snd_soc_dapm_widget stih407_sas_dapm_widgets[] = {
252 SND_SOC_DAPM_OUT_DRV("DAC standby ana", STIH407_AUDIO_DAC_CTRL,
253 STIH407_DAC_STANDBY_ANA, 1, NULL, 0),
254 SND_SOC_DAPM_DAC("DAC standby", "dac_p", STIH407_AUDIO_DAC_CTRL,
255 STIH407_DAC_STANDBY, 1),
256 SND_SOC_DAPM_OUTPUT("DAC Output"),
257};
258
259static const struct snd_soc_dapm_route stih416_sas_route[] = {
260 {"DAC Output", NULL, "DAC bandgap"},
261 {"DAC Output", NULL, "DAC standby ana"},
262 {"DAC standby ana", NULL, "DAC standby"},
263};
264
265static const struct snd_soc_dapm_route stih407_sas_route[] = {
266 {"DAC Output", NULL, "DAC standby ana"},
267 {"DAC standby ana", NULL, "DAC standby"},
268};
269
270static int stih416_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream)
271{
272 struct snd_soc_codec *codec = dai->codec;
273
274 if (mute) {
275 return snd_soc_update_bits(codec, STIH416_AUDIO_DAC_CTRL,
276 STIH416_DAC_SOFTMUTE_MASK,
277 STIH416_DAC_SOFTMUTE_MASK);
278 } else {
279 return snd_soc_update_bits(codec, STIH416_AUDIO_DAC_CTRL,
280 STIH416_DAC_SOFTMUTE_MASK, 0);
281 }
282}
283
284static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream)
285{
286 struct snd_soc_codec *codec = dai->codec;
287
288 if (mute) {
289 return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
290 STIH407_DAC_SOFTMUTE_MASK,
291 STIH407_DAC_SOFTMUTE_MASK);
292 } else {
293 return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
294 STIH407_DAC_SOFTMUTE_MASK,
295 0);
296 }
297}
298
299/*
300 * SPDIF
301 */
302static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
303 unsigned int fmt)
304{
305 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
306 dev_err(dai->codec->dev,
307 "%s: ERROR: Unsupporter master mask 0x%x\n",
308 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
309 return -EINVAL;
310 }
311
312 return 0;
313}
314
315/*
316 * sti_sas_spdif_trigger:
317 * Trigger function is used to ensure that BiPhase Formater is disabled
318 * before CPU dai is stopped.
319 * This is mandatory to avoid that BPF is stalled
320 */
321static int sti_sas_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
322 struct snd_soc_dai *dai)
323{
324 struct snd_soc_codec *codec = dai->codec;
325
326 switch (cmd) {
327 case SNDRV_PCM_TRIGGER_START:
328 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
329 return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
330 SPDIF_BIPHASE_ENABLE_MASK,
331 SPDIF_BIPHASE_ENABLE_MASK);
332 case SNDRV_PCM_TRIGGER_RESUME:
333 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
334 case SNDRV_PCM_TRIGGER_STOP:
335 case SNDRV_PCM_TRIGGER_SUSPEND:
336 return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
337 SPDIF_BIPHASE_ENABLE_MASK,
338 0);
339 default:
340 return -EINVAL;
341 }
342}
343
344static bool sti_sas_volatile_register(struct device *dev, unsigned int reg)
345{
346 if (reg == STIH407_AUDIO_GLUE_CTRL)
347 return true;
348
349 return false;
350}
351
352/*
353 * CODEC DAIS
354 */
355
356/*
357 * sti_sas_set_sysclk:
358 * get MCLK input frequency to check that MCLK-FS ratio is coherent
359 */
360static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
361 unsigned int freq, int dir)
362{
363 struct snd_soc_codec *codec = dai->codec;
364 struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
365
366 if (dir == SND_SOC_CLOCK_OUT)
367 return 0;
368
369 if (clk_id != 0)
370 return -EINVAL;
371
372 switch (dai->id) {
373 case STI_SAS_DAI_SPDIF_OUT:
374 drvdata->spdif.mclk = freq;
375 break;
376
377 case STI_SAS_DAI_ANALOG_OUT:
378 drvdata->dac.mclk = freq;
379 break;
380 }
381
382 return 0;
383}
384
385static int sti_sas_prepare(struct snd_pcm_substream *substream,
386 struct snd_soc_dai *dai)
387{
388 struct snd_soc_codec *codec = dai->codec;
389 struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
390 struct snd_pcm_runtime *runtime = substream->runtime;
391
392 switch (dai->id) {
393 case STI_SAS_DAI_SPDIF_OUT:
394 if ((drvdata->spdif.mclk / runtime->rate) != 128) {
395 dev_err(codec->dev, "unexpected mclk-fs ratio");
396 return -EINVAL;
397 }
398 break;
399 case STI_SAS_DAI_ANALOG_OUT:
400 if ((drvdata->dac.mclk / runtime->rate) != 256) {
401 dev_err(codec->dev, "unexpected mclk-fs ratio");
402 return -EINVAL;
403 }
404 break;
405 }
406
407 return 0;
408}
409
410static const struct snd_soc_dai_ops stih416_dac_ops = {
411 .set_fmt = sti_sas_dac_set_fmt,
412 .mute_stream = stih416_sas_dac_mute,
413 .prepare = sti_sas_prepare,
414 .set_sysclk = sti_sas_set_sysclk,
415};
416
417static const struct snd_soc_dai_ops stih407_dac_ops = {
418 .set_fmt = sti_sas_dac_set_fmt,
419 .mute_stream = stih407_sas_dac_mute,
420 .prepare = sti_sas_prepare,
421 .set_sysclk = sti_sas_set_sysclk,
422};
423
424static const struct regmap_config stih407_sas_regmap = {
425 .reg_bits = 32,
426 .val_bits = 32,
427
428 .max_register = STIH407_AUDIO_DAC_CTRL,
429 .reg_defaults = stih407_sas_reg_defaults,
430 .num_reg_defaults = ARRAY_SIZE(stih407_sas_reg_defaults),
431 .volatile_reg = sti_sas_volatile_register,
432 .cache_type = REGCACHE_RBTREE,
433 .reg_read = sti_sas_read_reg,
434 .reg_write = sti_sas_write_reg,
435};
436
437static const struct regmap_config stih416_sas_regmap = {
438 .reg_bits = 32,
439 .val_bits = 32,
440
441 .max_register = STIH416_AUDIO_DAC_CTRL,
442 .reg_defaults = stih416_sas_reg_defaults,
443 .num_reg_defaults = ARRAY_SIZE(stih416_sas_reg_defaults),
444 .volatile_reg = sti_sas_volatile_register,
445 .cache_type = REGCACHE_RBTREE,
446 .reg_read = sti_sas_read_reg,
447 .reg_write = sti_sas_write_reg,
448};
449
450static const struct sti_sas_dev_data stih416_data = {
451 .chipid = CHIPID_STIH416,
452 .regmap = &stih416_sas_regmap,
453 .dac_ops = &stih416_dac_ops,
454 .dapm_widgets = stih416_sas_dapm_widgets,
455 .num_dapm_widgets = ARRAY_SIZE(stih416_sas_dapm_widgets),
456 .dapm_routes = stih416_sas_route,
457 .num_dapm_routes = ARRAY_SIZE(stih416_sas_route),
458};
459
460static const struct sti_sas_dev_data stih407_data = {
461 .chipid = CHIPID_STIH407,
462 .regmap = &stih407_sas_regmap,
463 .dac_ops = &stih407_dac_ops,
464 .dapm_widgets = stih407_sas_dapm_widgets,
465 .num_dapm_widgets = ARRAY_SIZE(stih407_sas_dapm_widgets),
466 .dapm_routes = stih407_sas_route,
467 .num_dapm_routes = ARRAY_SIZE(stih407_sas_route),
468};
469
470static struct snd_soc_dai_driver sti_sas_dai[] = {
471 {
472 .name = "sas-dai-spdif-out",
473 .id = STI_SAS_DAI_SPDIF_OUT,
474 .playback = {
475 .stream_name = "spdif_p",
476 .channels_min = 2,
477 .channels_max = 2,
478 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
479 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 |
480 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
481 SNDRV_PCM_RATE_192000,
482 .formats = SNDRV_PCM_FMTBIT_S16_LE |
483 SNDRV_PCM_FMTBIT_S32_LE,
484 },
485 .ops = (struct snd_soc_dai_ops[]) {
486 {
487 .set_fmt = sti_sas_spdif_set_fmt,
488 .trigger = sti_sas_spdif_trigger,
489 .set_sysclk = sti_sas_set_sysclk,
490 .prepare = sti_sas_prepare,
491 }
492 },
493 },
494 {
495 .name = "sas-dai-dac",
496 .id = STI_SAS_DAI_ANALOG_OUT,
497 .playback = {
498 .stream_name = "dac_p",
499 .channels_min = 2,
500 .channels_max = 2,
501 .rates = SNDRV_PCM_RATE_8000_48000,
502 .formats = SNDRV_PCM_FMTBIT_S16_LE |
503 SNDRV_PCM_FMTBIT_S32_LE,
504 },
505 },
506};
507
508#ifdef CONFIG_PM_SLEEP
509static int sti_sas_resume(struct snd_soc_codec *codec)
510{
511 struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
512
513 return sti_sas_init_sas_registers(codec, drvdata);
514}
515#else
516#define sti_sas_resume NULL
517#endif
518
519static int sti_sas_codec_probe(struct snd_soc_codec *codec)
520{
521 struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
522 int ret;
523
524 ret = sti_sas_init_sas_registers(codec, drvdata);
525
526 return ret;
527}
528
529static struct snd_soc_codec_driver sti_sas_driver = {
530 .probe = sti_sas_codec_probe,
531 .resume = sti_sas_resume,
532};
533
534static const struct of_device_id sti_sas_dev_match[] = {
535 {
536 .compatible = "st,stih416-sas-codec",
537 .data = &stih416_data,
538 },
539 {
540 .compatible = "st,stih407-sas-codec",
541 .data = &stih407_data,
542 },
543 {},
544};
545
546static int sti_sas_driver_probe(struct platform_device *pdev)
547{
548 struct device_node *pnode = pdev->dev.of_node;
549 struct sti_sas_data *drvdata;
550 const struct of_device_id *of_id;
551
552 /* Allocate device structure */
553 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct sti_sas_data),
554 GFP_KERNEL);
555 if (!drvdata)
556 return -ENOMEM;
557
558 /* Populate data structure depending on compatibility */
559 of_id = of_match_node(sti_sas_dev_match, pnode);
560 if (!of_id->data) {
561 dev_err(&pdev->dev, "data associated to device is missing");
562 return -EINVAL;
563 }
564
565 drvdata->dev_data = (struct sti_sas_dev_data *)of_id->data;
566
567 /* Initialise device structure */
568 drvdata->dev = &pdev->dev;
569
570 /* Request the DAC & SPDIF registers memory region */
571 drvdata->dac.virt_regmap = devm_regmap_init(&pdev->dev, NULL, drvdata,
572 drvdata->dev_data->regmap);
573 if (IS_ERR(drvdata->dac.virt_regmap)) {
574 dev_err(&pdev->dev, "audio registers not enabled\n");
575 return PTR_ERR(drvdata->dac.virt_regmap);
576 }
577
578 /* Request the syscon region */
579 drvdata->dac.regmap =
580 syscon_regmap_lookup_by_phandle(pnode, "st,syscfg");
581 if (IS_ERR(drvdata->dac.regmap)) {
582 dev_err(&pdev->dev, "syscon registers not available\n");
583 return PTR_ERR(drvdata->dac.regmap);
584 }
585 drvdata->spdif.regmap = drvdata->dac.regmap;
586
587 /* Set DAC dai probe */
588 if (drvdata->dev_data->chipid == CHIPID_STIH416)
589 sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].probe = stih416_dac_probe;
590
591 sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
592
593 /* Set dapms*/
594 sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
595 sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
596
597 sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
598 sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
599
600 /* Store context */
601 dev_set_drvdata(&pdev->dev, drvdata);
602
603 return snd_soc_register_codec(&pdev->dev, &sti_sas_driver,
604 sti_sas_dai,
605 ARRAY_SIZE(sti_sas_dai));
606}
607
608static int sti_sas_driver_remove(struct platform_device *pdev)
609{
610 snd_soc_unregister_codec(&pdev->dev);
611
612 return 0;
613}
614
615static struct platform_driver sti_sas_platform_driver = {
616 .driver = {
617 .name = "sti-sas-codec",
618 .of_match_table = sti_sas_dev_match,
619 },
620 .probe = sti_sas_driver_probe,
621 .remove = sti_sas_driver_remove,
622};
623
624module_platform_driver(sti_sas_platform_driver);
625
626MODULE_DESCRIPTION("audio codec for STMicroelectronics sti platforms");
627MODULE_AUTHOR("Arnaud.pouliquen@st.com");
628MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sti/Kconfig b/sound/soc/sti/Kconfig
new file mode 100644
index 000000000000..64a690077023
--- /dev/null
+++ b/sound/soc/sti/Kconfig
@@ -0,0 +1,11 @@
1#
2# STM SoC audio configuration
3#
4menuconfig SND_SOC_STI
5 tristate "SoC Audio support for STI System-On-Chip"
6 depends on SND_SOC
7 depends on ARCH_STI || COMPILE_TEST
8 select SND_SOC_GENERIC_DMAENGINE_PCM
9 help
10 Say Y if you want to enable ASoC-support for
11 any of the STI platforms (e.g. STIH416).
diff --git a/sound/soc/sti/Makefile b/sound/soc/sti/Makefile
new file mode 100644
index 000000000000..4b188d2d76b8
--- /dev/null
+++ b/sound/soc/sti/Makefile
@@ -0,0 +1,4 @@
1# STI platform support
2snd-soc-sti-objs := sti_uniperif.o uniperif_player.o uniperif_reader.o
3
4obj-$(CONFIG_SND_SOC_STI) += snd-soc-sti.o
diff --git a/sound/soc/sti/sti_uniperif.c b/sound/soc/sti/sti_uniperif.c
new file mode 100644
index 000000000000..39bcefe5eea0
--- /dev/null
+++ b/sound/soc/sti/sti_uniperif.c
@@ -0,0 +1,254 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2015
3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
4 * for STMicroelectronics.
5 * License terms: GNU General Public License (GPL), version 2
6 */
7
8#include <linux/module.h>
9#include <linux/pinctrl/consumer.h>
10
11#include "uniperif.h"
12
13/*
14 * sti_uniperiph_dai_create_ctrl
15 * This function is used to create Ctrl associated to DAI but also pcm device.
16 * Request is done by front end to associate ctrl with pcm device id
17 */
18static int sti_uniperiph_dai_create_ctrl(struct snd_soc_dai *dai)
19{
20 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
21 struct uniperif *uni = priv->dai_data.uni;
22 struct snd_kcontrol_new *ctrl;
23 int i;
24
25 if (!uni->num_ctrls)
26 return 0;
27
28 for (i = 0; i < uni->num_ctrls; i++) {
29 /*
30 * Several Control can have same name. Controls are indexed on
31 * Uniperipheral instance ID
32 */
33 ctrl = &uni->snd_ctrls[i];
34 ctrl->index = uni->info->id;
35 ctrl->device = uni->info->id;
36 }
37
38 return snd_soc_add_dai_controls(dai, uni->snd_ctrls, uni->num_ctrls);
39}
40
41/*
42 * DAI
43 */
44int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
45 struct snd_pcm_hw_params *params,
46 struct snd_soc_dai *dai)
47{
48 struct snd_dmaengine_dai_dma_data *dma_data;
49 int transfer_size;
50
51 transfer_size = params_channels(params) * UNIPERIF_FIFO_FRAMES;
52
53 dma_data = snd_soc_dai_get_dma_data(dai, substream);
54 dma_data->maxburst = transfer_size;
55
56 return 0;
57}
58
59int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
60{
61 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
62
63 priv->dai_data.uni->daifmt = fmt;
64
65 return 0;
66}
67
68static int sti_uniperiph_dai_suspend(struct snd_soc_dai *dai)
69{
70 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
71 struct uniperif *uni = priv->dai_data.uni;
72 int ret;
73
74 /* The uniperipheral should be in stopped state */
75 if (uni->state != UNIPERIF_STATE_STOPPED) {
76 dev_err(uni->dev, "%s: invalid uni state( %d)",
77 __func__, (int)uni->state);
78 return -EBUSY;
79 }
80
81 /* Pinctrl: switch pinstate to sleep */
82 ret = pinctrl_pm_select_sleep_state(uni->dev);
83 if (ret)
84 dev_err(uni->dev, "%s: failed to select pinctrl state",
85 __func__);
86
87 return ret;
88}
89
90static int sti_uniperiph_dai_resume(struct snd_soc_dai *dai)
91{
92 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
93 struct uniperif *uni = priv->dai_data.uni;
94 int ret;
95
96 if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player")) {
97 ret = uni_player_resume(uni);
98 if (ret)
99 return ret;
100 }
101
102 /* pinctrl: switch pinstate to default */
103 ret = pinctrl_pm_select_default_state(uni->dev);
104 if (ret)
105 dev_err(uni->dev, "%s: failed to select pinctrl state",
106 __func__);
107
108 return ret;
109}
110
111static int sti_uniperiph_dai_probe(struct snd_soc_dai *dai)
112{
113 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
114 struct sti_uniperiph_dai *dai_data = &priv->dai_data;
115
116 /* DMA settings*/
117 if (of_device_is_compatible(dai->dev->of_node, "st,sti-uni-player"))
118 snd_soc_dai_init_dma_data(dai, &dai_data->dma_data, NULL);
119 else
120 snd_soc_dai_init_dma_data(dai, NULL, &dai_data->dma_data);
121
122 dai_data->dma_data.addr = dai_data->uni->fifo_phys_address;
123 dai_data->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
124
125 return sti_uniperiph_dai_create_ctrl(dai);
126}
127
128static const struct snd_soc_dai_driver sti_uniperiph_dai_template = {
129 .probe = sti_uniperiph_dai_probe,
130 .suspend = sti_uniperiph_dai_suspend,
131 .resume = sti_uniperiph_dai_resume
132};
133
134static const struct snd_soc_component_driver sti_uniperiph_dai_component = {
135 .name = "sti_cpu_dai",
136};
137
138static int sti_uniperiph_cpu_dai_of(struct device_node *node,
139 struct sti_uniperiph_data *priv)
140{
141 const char *str;
142 int ret;
143 struct device *dev = &priv->pdev->dev;
144 struct sti_uniperiph_dai *dai_data = &priv->dai_data;
145 struct snd_soc_dai_driver *dai = priv->dai;
146 struct snd_soc_pcm_stream *stream;
147 struct uniperif *uni;
148
149 uni = devm_kzalloc(dev, sizeof(*uni), GFP_KERNEL);
150 if (!uni)
151 return -ENOMEM;
152
153 *dai = sti_uniperiph_dai_template;
154 ret = of_property_read_string(node, "dai-name", &str);
155 if (ret < 0) {
156 dev_err(dev, "%s: dai name missing.\n", __func__);
157 return -EINVAL;
158 }
159 dai->name = str;
160
161 /* Get resources */
162 uni->mem_region = platform_get_resource(priv->pdev, IORESOURCE_MEM, 0);
163
164 if (!uni->mem_region) {
165 dev_err(dev, "Failed to get memory resource");
166 return -ENODEV;
167 }
168
169 uni->base = devm_ioremap_resource(dev, uni->mem_region);
170
171 if (IS_ERR(uni->base))
172 return PTR_ERR(uni->base);
173
174 uni->fifo_phys_address = uni->mem_region->start +
175 UNIPERIF_FIFO_DATA_OFFSET(uni);
176
177 uni->irq = platform_get_irq(priv->pdev, 0);
178 if (uni->irq < 0) {
179 dev_err(dev, "Failed to get IRQ resource");
180 return -ENXIO;
181 }
182
183 dai_data->uni = uni;
184
185 if (of_device_is_compatible(node, "st,sti-uni-player")) {
186 uni_player_init(priv->pdev, uni);
187 stream = &dai->playback;
188 } else {
189 uni_reader_init(priv->pdev, uni);
190 stream = &dai->capture;
191 }
192 dai->ops = uni->dai_ops;
193
194 stream->stream_name = dai->name;
195 stream->channels_min = uni->hw->channels_min;
196 stream->channels_max = uni->hw->channels_max;
197 stream->rates = uni->hw->rates;
198 stream->formats = uni->hw->formats;
199
200 return 0;
201}
202
203static const struct snd_dmaengine_pcm_config dmaengine_pcm_config = {
204 .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
205};
206
207static int sti_uniperiph_probe(struct platform_device *pdev)
208{
209 struct sti_uniperiph_data *priv;
210 struct device_node *node = pdev->dev.of_node;
211 int ret;
212
213 /* Allocate the private data and the CPU_DAI array */
214 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
215 if (!priv)
216 return -ENOMEM;
217 priv->dai = devm_kzalloc(&pdev->dev, sizeof(*priv->dai), GFP_KERNEL);
218 if (!priv->dai)
219 return -ENOMEM;
220
221 priv->pdev = pdev;
222
223 ret = sti_uniperiph_cpu_dai_of(node, priv);
224
225 dev_set_drvdata(&pdev->dev, priv);
226
227 ret = devm_snd_soc_register_component(&pdev->dev,
228 &sti_uniperiph_dai_component,
229 priv->dai, 1);
230 if (ret < 0)
231 return ret;
232
233 return devm_snd_dmaengine_pcm_register(&pdev->dev,
234 &dmaengine_pcm_config, 0);
235}
236
237static const struct of_device_id snd_soc_sti_match[] = {
238 { .compatible = "st,sti-uni-player", },
239 { .compatible = "st,sti-uni-reader", },
240 {},
241};
242
243static struct platform_driver sti_uniperiph_driver = {
244 .driver = {
245 .name = "sti-uniperiph-dai",
246 .of_match_table = snd_soc_sti_match,
247 },
248 .probe = sti_uniperiph_probe,
249};
250module_platform_driver(sti_uniperiph_driver);
251
252MODULE_DESCRIPTION("uniperipheral DAI driver");
253MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>");
254MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sti/uniperif.h b/sound/soc/sti/uniperif.h
new file mode 100644
index 000000000000..f0fd5a9944e9
--- /dev/null
+++ b/sound/soc/sti/uniperif.h
@@ -0,0 +1,1229 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2015
3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
4 * for STMicroelectronics.
5 * License terms: GNU General Public License (GPL), version 2
6 */
7
8#ifndef __SND_ST_AUD_UNIPERIF_H
9#define __SND_ST_AUD_UNIPERIF_H
10
11#include <linux/regmap.h>
12
13#include <sound/dmaengine_pcm.h>
14
15/*
16 * Register access macros
17 */
18
19#define GET_UNIPERIF_REG(ip, offset, shift, mask) \
20 ((readl_relaxed(ip->base + offset) >> shift) & mask)
21#define SET_UNIPERIF_REG(ip, offset, shift, mask, value) \
22 writel_relaxed(((readl_relaxed(ip->base + offset) & \
23 ~(mask << shift)) | (((value) & mask) << shift)), ip->base + offset)
24#define SET_UNIPERIF_BIT_REG(ip, offset, shift, mask, value) \
25 writel_relaxed((((value) & mask) << shift), ip->base + offset)
26
27/*
28 * AUD_UNIPERIF_SOFT_RST reg
29 */
30
31#define UNIPERIF_SOFT_RST_OFFSET(ip) 0x0000
32#define GET_UNIPERIF_SOFT_RST(ip) \
33 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
34 readl_relaxed(ip->base + UNIPERIF_SOFT_RST_OFFSET(ip)) : 0)
35#define SET_UNIPERIF_SOFT_RST(ip, value) \
36 writel_relaxed(value, ip->base + UNIPERIF_SOFT_RST_OFFSET(ip))
37
38/* SOFT_RST */
39#define UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip) 0x0
40#define UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip) 0x1
41#define SET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
42 SET_UNIPERIF_BIT_REG(ip, \
43 UNIPERIF_SOFT_RST_OFFSET(ip), \
44 UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
45 UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip), 1)
46#define GET_UNIPERIF_SOFT_RST_SOFT_RST(ip) \
47 GET_UNIPERIF_REG(ip, \
48 UNIPERIF_SOFT_RST_OFFSET(ip), \
49 UNIPERIF_SOFT_RST_SOFT_RST_SHIFT(ip), \
50 UNIPERIF_SOFT_RST_SOFT_RST_MASK(ip))
51
52/*
53 * AUD_UNIPERIF_FIFO_DATA reg
54 */
55
56#define UNIPERIF_FIFO_DATA_OFFSET(ip) 0x0004
57#define SET_UNIPERIF_DATA(ip, value) \
58 writel_relaxed(value, ip->base + UNIPERIF_FIFO_DATA_OFFSET(ip))
59
60/*
61 * AUD_UNIPERIF_CHANNEL_STA_REGN reg
62 */
63
64#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n))
65#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
66 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
67#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
68 writel_relaxed(value, ip->base + \
69 UNIPERIF_CHANNEL_STA_REGN(ip, n))
70
71#define UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip) 0x0060
72#define GET_UNIPERIF_CHANNEL_STA_REG0(ip) \
73 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
74#define SET_UNIPERIF_CHANNEL_STA_REG0(ip, value) \
75 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG0_OFFSET(ip))
76
77#define UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip) 0x0064
78#define GET_UNIPERIF_CHANNEL_STA_REG1(ip) \
79 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
80#define SET_UNIPERIF_CHANNEL_STA_REG1(ip, value) \
81 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG1_OFFSET(ip))
82
83#define UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip) 0x0068
84#define GET_UNIPERIF_CHANNEL_STA_REG2(ip) \
85 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
86#define SET_UNIPERIF_CHANNEL_STA_REG2(ip, value) \
87 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG2_OFFSET(ip))
88
89#define UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip) 0x006C
90#define GET_UNIPERIF_CHANNEL_STA_REG3(ip) \
91 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
92#define SET_UNIPERIF_CHANNEL_STA_REG3(ip, value) \
93 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG3_OFFSET(ip))
94
95#define UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip) 0x0070
96#define GET_UNIPERIF_CHANNEL_STA_REG4(ip) \
97 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
98#define SET_UNIPERIF_CHANNEL_STA_REG4(ip, value) \
99 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG4_OFFSET(ip))
100
101#define UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip) 0x0074
102#define GET_UNIPERIF_CHANNEL_STA_REG5(ip) \
103 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
104#define SET_UNIPERIF_CHANNEL_STA_REG5(ip, value) \
105 writel_relaxed(value, ip->base + UNIPERIF_CHANNEL_STA_REG5_OFFSET(ip))
106
107/*
108 * AUD_UNIPERIF_ITS reg
109 */
110
111#define UNIPERIF_ITS_OFFSET(ip) 0x000C
112#define GET_UNIPERIF_ITS(ip) \
113 readl_relaxed(ip->base + UNIPERIF_ITS_OFFSET(ip))
114
115/* MEM_BLK_READ */
116#define UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip) 5
117#define UNIPERIF_ITS_MEM_BLK_READ_MASK(ip) \
118 (BIT(UNIPERIF_ITS_MEM_BLK_READ_SHIFT(ip)))
119
120/* FIFO_ERROR */
121#define UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip) \
122 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
123#define UNIPERIF_ITS_FIFO_ERROR_MASK(ip) \
124 (BIT(UNIPERIF_ITS_FIFO_ERROR_SHIFT(ip)))
125
126/* DMA_ERROR */
127#define UNIPERIF_ITS_DMA_ERROR_SHIFT(ip) 9
128#define UNIPERIF_ITS_DMA_ERROR_MASK(ip) \
129 (BIT(UNIPERIF_ITS_DMA_ERROR_SHIFT(ip)))
130
131/* UNDERFLOW_REC_DONE */
132#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip) \
133 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
134#define UNIPERIF_ITS_UNDERFLOW_REC_DONE_MASK(ip) \
135 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
136 0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_DONE_SHIFT(ip))))
137
138/* UNDERFLOW_REC_FAILED */
139#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip) \
140 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
141#define UNIPERIF_ITS_UNDERFLOW_REC_FAILED_MASK(ip) \
142 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
143 0 : (BIT(UNIPERIF_ITS_UNDERFLOW_REC_FAILED_SHIFT(ip))))
144
145/*
146 * AUD_UNIPERIF_ITS_BCLR reg
147 */
148
149/* FIFO_ERROR */
150#define UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip) \
151 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
152#define UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip) \
153 (BIT(UNIPERIF_ITS_BCLR_FIFO_ERROR_SHIFT(ip)))
154#define SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(ip) \
155 SET_UNIPERIF_ITS_BCLR(ip, \
156 UNIPERIF_ITS_BCLR_FIFO_ERROR_MASK(ip))
157
158#define UNIPERIF_ITS_BCLR_OFFSET(ip) 0x0010
159#define SET_UNIPERIF_ITS_BCLR(ip, value) \
160 writel_relaxed(value, ip->base + UNIPERIF_ITS_BCLR_OFFSET(ip))
161
162/*
163 * AUD_UNIPERIF_ITM reg
164 */
165
166#define UNIPERIF_ITM_OFFSET(ip) 0x0018
167#define GET_UNIPERIF_ITM(ip) \
168 readl_relaxed(ip->base + UNIPERIF_ITM_OFFSET(ip))
169
170/* FIFO_ERROR */
171#define UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip) \
172 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
173#define UNIPERIF_ITM_FIFO_ERROR_MASK(ip) \
174 (BIT(UNIPERIF_ITM_FIFO_ERROR_SHIFT(ip)))
175
176/* UNDERFLOW_REC_DONE */
177#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip) \
178 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
179#define UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(ip) \
180 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
181 0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_DONE_SHIFT(ip))))
182
183/* UNDERFLOW_REC_FAILED */
184#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip) \
185 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
186#define UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(ip) \
187 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
188 0 : (BIT(UNIPERIF_ITM_UNDERFLOW_REC_FAILED_SHIFT(ip))))
189
190/*
191 * AUD_UNIPERIF_ITM_BCLR reg
192 */
193
194#define UNIPERIF_ITM_BCLR_OFFSET(ip) 0x001c
195#define SET_UNIPERIF_ITM_BCLR(ip, value) \
196 writel_relaxed(value, ip->base + UNIPERIF_ITM_BCLR_OFFSET(ip))
197
198/* FIFO_ERROR */
199#define UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip) \
200 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
201#define UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip) \
202 (BIT(UNIPERIF_ITM_BCLR_FIFO_ERROR_SHIFT(ip)))
203#define SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(ip) \
204 SET_UNIPERIF_ITM_BCLR(ip, \
205 UNIPERIF_ITM_BCLR_FIFO_ERROR_MASK(ip))
206
207/* DMA_ERROR */
208#define UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip) 9
209#define UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip) \
210 (BIT(UNIPERIF_ITM_BCLR_DMA_ERROR_SHIFT(ip)))
211#define SET_UNIPERIF_ITM_BCLR_DMA_ERROR(ip) \
212 SET_UNIPERIF_ITM_BCLR(ip, \
213 UNIPERIF_ITM_BCLR_DMA_ERROR_MASK(ip))
214
215/*
216 * AUD_UNIPERIF_ITM_BSET reg
217 */
218
219#define UNIPERIF_ITM_BSET_OFFSET(ip) 0x0020
220#define SET_UNIPERIF_ITM_BSET(ip, value) \
221 writel_relaxed(value, ip->base + UNIPERIF_ITM_BSET_OFFSET(ip))
222
223/* FIFO_ERROR */
224#define UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip) \
225 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 8)
226#define UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip) \
227 (BIT(UNIPERIF_ITM_BSET_FIFO_ERROR_SHIFT(ip)))
228#define SET_UNIPERIF_ITM_BSET_FIFO_ERROR(ip) \
229 SET_UNIPERIF_ITM_BSET(ip, \
230 UNIPERIF_ITM_BSET_FIFO_ERROR_MASK(ip))
231
232/* MEM_BLK_READ */
233#define UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip) 5
234#define UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip) \
235 (BIT(UNIPERIF_ITM_BSET_MEM_BLK_READ_SHIFT(ip)))
236#define SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(ip) \
237 SET_UNIPERIF_ITM_BSET(ip, \
238 UNIPERIF_ITM_BSET_MEM_BLK_READ_MASK(ip))
239
240/* DMA_ERROR */
241#define UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip) 9
242#define UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip) \
243 (BIT(UNIPERIF_ITM_BSET_DMA_ERROR_SHIFT(ip)))
244#define SET_UNIPERIF_ITM_BSET_DMA_ERROR(ip) \
245 SET_UNIPERIF_ITM_BSET(ip, \
246 UNIPERIF_ITM_BSET_DMA_ERROR_MASK(ip))
247
248/* UNDERFLOW_REC_DONE */
249#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip) \
250 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 12)
251#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip) \
252 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
253 0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_SHIFT(ip))))
254#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(ip) \
255 SET_UNIPERIF_ITM_BSET(ip, \
256 UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE_MASK(ip))
257
258/* UNDERFLOW_REC_FAILED */
259#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip) \
260 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 13)
261#define UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip) \
262 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? \
263 0 : (BIT(UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_SHIFT(ip))))
264#define SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(ip) \
265 SET_UNIPERIF_ITM_BSET(ip, \
266 UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED_MASK(ip))
267
268/*
269 * UNIPERIF_CONFIG reg
270 */
271
272#define UNIPERIF_CONFIG_OFFSET(ip) 0x0040
273#define GET_UNIPERIF_CONFIG(ip) \
274 readl_relaxed(ip->base + UNIPERIF_CONFIG_OFFSET(ip))
275#define SET_UNIPERIF_CONFIG(ip, value) \
276 writel_relaxed(value, ip->base + UNIPERIF_CONFIG_OFFSET(ip))
277
278/* PARITY_CNTR */
279#define UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip) 0
280#define UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip) 0x1
281#define GET_UNIPERIF_CONFIG_PARITY_CNTR(ip) \
282 GET_UNIPERIF_REG(ip, \
283 UNIPERIF_CONFIG_OFFSET(ip), \
284 UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
285 UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip))
286#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(ip) \
287 SET_UNIPERIF_REG(ip, \
288 UNIPERIF_CONFIG_OFFSET(ip), \
289 UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
290 UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 0)
291#define SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_SW(ip) \
292 SET_UNIPERIF_REG(ip, \
293 UNIPERIF_CONFIG_OFFSET(ip), \
294 UNIPERIF_CONFIG_PARITY_CNTR_SHIFT(ip), \
295 UNIPERIF_CONFIG_PARITY_CNTR_MASK(ip), 1)
296
297/* CHANNEL_STA_CNTR */
298#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip) 1
299#define UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip) 0x1
300#define GET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR(ip) \
301 GET_UNIPERIF_REG(ip, \
302 UNIPERIF_CONFIG_OFFSET(ip), \
303 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
304 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip))
305#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_SW(ip) \
306 SET_UNIPERIF_REG(ip, \
307 UNIPERIF_CONFIG_OFFSET(ip), \
308 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
309 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 0)
310#define SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(ip) \
311 SET_UNIPERIF_REG(ip, \
312 UNIPERIF_CONFIG_OFFSET(ip), \
313 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_SHIFT(ip), \
314 UNIPERIF_CONFIG_CHANNEL_STA_CNTR_MASK(ip), 1)
315
316/* USER_DAT_CNTR */
317#define UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip) 2
318#define UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip) 0x1
319#define GET_UNIPERIF_CONFIG_USER_DAT_CNTR(ip) \
320 GET_UNIPERIF_REG(ip, \
321 UNIPERIF_CONFIG_OFFSET(ip), \
322 UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
323 UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip))
324#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(ip) \
325 SET_UNIPERIF_REG(ip, \
326 UNIPERIF_CONFIG_OFFSET(ip), \
327 UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
328 UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 1)
329#define SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_SW(ip) \
330 SET_UNIPERIF_REG(ip, \
331 UNIPERIF_CONFIG_OFFSET(ip), \
332 UNIPERIF_CONFIG_USER_DAT_CNTR_SHIFT(ip), \
333 UNIPERIF_CONFIG_USER_DAT_CNTR_MASK(ip), 0)
334
335/* VALIDITY_DAT_CNTR */
336#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip) 3
337#define UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip) 0x1
338#define GET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR(ip) \
339 GET_UNIPERIF_REG(ip, \
340 UNIPERIF_CONFIG_OFFSET(ip), \
341 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
342 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip))
343#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_SW(ip) \
344 SET_UNIPERIF_REG(ip, \
345 UNIPERIF_CONFIG_OFFSET(ip), \
346 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
347 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 0)
348#define SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(ip) \
349 SET_UNIPERIF_REG(ip, \
350 UNIPERIF_CONFIG_OFFSET(ip), \
351 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_SHIFT(ip), \
352 UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_MASK(ip), 1)
353
354/* ONE_BIT_AUD_SUPPORT */
355#define UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip) 4
356#define UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip) 0x1
357#define GET_UNIPERIF_CONFIG_ONE_BIT_AUD(ip) \
358 GET_UNIPERIF_REG(ip, \
359 UNIPERIF_CONFIG_OFFSET(ip), \
360 UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
361 UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip))
362#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(ip) \
363 SET_UNIPERIF_REG(ip, \
364 UNIPERIF_CONFIG_OFFSET(ip), \
365 UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
366 UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 0)
367#define SET_UNIPERIF_CONFIG_ONE_BIT_AUD_ENABLE(ip) \
368 SET_UNIPERIF_REG(ip, \
369 UNIPERIF_CONFIG_OFFSET(ip), \
370 UNIPERIF_CONFIG_ONE_BIT_AUD_SHIFT(ip), \
371 UNIPERIF_CONFIG_ONE_BIT_AUD_MASK(ip), 1)
372
373/* MEMORY_FMT */
374#define UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip) 5
375#define UNIPERIF_CONFIG_MEM_FMT_MASK(ip) 0x1
376#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) 0
377#define VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) 1
378#define GET_UNIPERIF_CONFIG_MEM_FMT(ip) \
379 GET_UNIPERIF_REG(ip, \
380 UNIPERIF_CONFIG_OFFSET(ip), \
381 UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
382 UNIPERIF_CONFIG_MEM_FMT_MASK(ip))
383#define SET_UNIPERIF_CONFIG_MEM_FMT(ip, value) \
384 SET_UNIPERIF_REG(ip, \
385 UNIPERIF_CONFIG_OFFSET(ip), \
386 UNIPERIF_CONFIG_MEM_FMT_SHIFT(ip), \
387 UNIPERIF_CONFIG_MEM_FMT_MASK(ip), value)
388#define SET_UNIPERIF_CONFIG_MEM_FMT_16_0(ip) \
389 SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
390 VALUE_UNIPERIF_CONFIG_MEM_FMT_16_0(ip))
391#define SET_UNIPERIF_CONFIG_MEM_FMT_16_16(ip) \
392 SET_UNIPERIF_CONFIG_MEM_FMT(ip, \
393 VALUE_UNIPERIF_CONFIG_MEM_FMT_16_16(ip))
394
395/* REPEAT_CHL_STS */
396#define UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip) 6
397#define UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip) 0x1
398#define GET_UNIPERIF_CONFIG_REPEAT_CHL_STS(ip) \
399 GET_UNIPERIF_REG(ip, \
400 UNIPERIF_CONFIG_OFFSET(ip), \
401 UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
402 UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip))
403#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(ip) \
404 SET_UNIPERIF_REG(ip, \
405 UNIPERIF_CONFIG_OFFSET(ip), \
406 UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
407 UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 0)
408#define SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_DISABLE(ip) \
409 SET_UNIPERIF_REG(ip, \
410 UNIPERIF_CONFIG_OFFSET(ip), \
411 UNIPERIF_CONFIG_REPEAT_CHL_STS_SHIFT(ip), \
412 UNIPERIF_CONFIG_REPEAT_CHL_STS_MASK(ip), 1)
413
414/* BACK_STALL_REQ */
415#define UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip) \
416 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 7 : -1)
417#define UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip) 0x1
418#define GET_UNIPERIF_CONFIG_BACK_STALL_REQ(ip) \
419 GET_UNIPERIF_REG(ip, \
420 UNIPERIF_CONFIG_OFFSET(ip), \
421 UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
422 UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip))
423#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(ip) \
424 SET_UNIPERIF_REG(ip, \
425 UNIPERIF_CONFIG_OFFSET(ip), \
426 UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
427 UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 0)
428#define SET_UNIPERIF_CONFIG_BACK_STALL_REQ_ENABLE(ip) \
429 SET_UNIPERIF_REG(ip, \
430 UNIPERIF_CONFIG_OFFSET(ip), \
431 UNIPERIF_CONFIG_BACK_STALL_REQ_SHIFT(ip), \
432 UNIPERIF_CONFIG_BACK_STALL_REQ_MASK(ip), 1)
433
434/* FDMA_TRIGGER_LIMIT */
435#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip) 8
436#define UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip) 0x7F
437#define GET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip) \
438 GET_UNIPERIF_REG(ip, \
439 UNIPERIF_CONFIG_OFFSET(ip), \
440 UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
441 UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip))
442#define SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(ip, value) \
443 SET_UNIPERIF_REG(ip, \
444 UNIPERIF_CONFIG_OFFSET(ip), \
445 UNIPERIF_CONFIG_DMA_TRIG_LIMIT_SHIFT(ip), \
446 UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(ip), value)
447
448/* CHL_STS_UPDATE */
449#define UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip) \
450 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
451#define UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip) 0x1
452#define GET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
453 GET_UNIPERIF_REG(ip, \
454 UNIPERIF_CONFIG_OFFSET(ip), \
455 UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
456 UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip))
457#define SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(ip) \
458 SET_UNIPERIF_REG(ip, \
459 UNIPERIF_CONFIG_OFFSET(ip), \
460 UNIPERIF_CONFIG_CHL_STS_UPDATE_SHIFT(ip), \
461 UNIPERIF_CONFIG_CHL_STS_UPDATE_MASK(ip), 1)
462
463/* IDLE_MOD */
464#define UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip) 18
465#define UNIPERIF_CONFIG_IDLE_MOD_MASK(ip) 0x1
466#define GET_UNIPERIF_CONFIG_IDLE_MOD(ip) \
467 GET_UNIPERIF_REG(ip, \
468 UNIPERIF_CONFIG_OFFSET(ip), \
469 UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
470 UNIPERIF_CONFIG_IDLE_MOD_MASK(ip))
471#define SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(ip) \
472 SET_UNIPERIF_REG(ip, \
473 UNIPERIF_CONFIG_OFFSET(ip), \
474 UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
475 UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 0)
476#define SET_UNIPERIF_CONFIG_IDLE_MOD_ENABLE(ip) \
477 SET_UNIPERIF_REG(ip, \
478 UNIPERIF_CONFIG_OFFSET(ip), \
479 UNIPERIF_CONFIG_IDLE_MOD_SHIFT(ip), \
480 UNIPERIF_CONFIG_IDLE_MOD_MASK(ip), 1)
481
482/* SUBFRAME_SELECTION */
483#define UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip) 19
484#define UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip) 0x1
485#define GET_UNIPERIF_CONFIG_SUBFRAME_SEL(ip) \
486 GET_UNIPERIF_REG(ip, \
487 UNIPERIF_CONFIG_OFFSET(ip), \
488 UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
489 UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip))
490#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(ip) \
491 SET_UNIPERIF_REG(ip, \
492 UNIPERIF_CONFIG_OFFSET(ip), \
493 UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
494 UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 1)
495#define SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF0_SUBF1(ip) \
496 SET_UNIPERIF_REG(ip, \
497 UNIPERIF_CONFIG_OFFSET(ip), \
498 UNIPERIF_CONFIG_SUBFRAME_SEL_SHIFT(ip), \
499 UNIPERIF_CONFIG_SUBFRAME_SEL_MASK(ip), 0)
500
501/* FULL_SW_CONTROL */
502#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip) 20
503#define UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip) 0x1
504#define GET_UNIPERIF_CONFIG_SPDIF_SW_CTRL(ip) \
505 GET_UNIPERIF_REG(ip, \
506 UNIPERIF_CONFIG_OFFSET(ip), \
507 UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
508 UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip))
509#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_ENABLE(ip) \
510 SET_UNIPERIF_REG(ip, \
511 UNIPERIF_CONFIG_OFFSET(ip), \
512 UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
513 UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 1)
514#define SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(ip) \
515 SET_UNIPERIF_REG(ip, \
516 UNIPERIF_CONFIG_OFFSET(ip), \
517 UNIPERIF_CONFIG_SPDIF_SW_CTRL_SHIFT(ip), \
518 UNIPERIF_CONFIG_SPDIF_SW_CTRL_MASK(ip), 0)
519
520/* MASTER_CLKEDGE */
521#define UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip) \
522 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 24 : -1)
523#define UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip) 0x1
524#define GET_UNIPERIF_CONFIG_MSTR_CLKEDGE(ip) \
525 GET_UNIPERIF_REG(ip, \
526 UNIPERIF_CONFIG_OFFSET(ip), \
527 UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
528 UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip))
529#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_FALLING(ip) \
530 SET_UNIPERIF_REG(ip, \
531 UNIPERIF_CONFIG_OFFSET(ip), \
532 UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
533 UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 1)
534#define SET_UNIPERIF_CONFIG_MSTR_CLKEDGE_RISING(ip) \
535 SET_UNIPERIF_REG(ip, \
536 UNIPERIF_CONFIG_OFFSET(ip), \
537 UNIPERIF_CONFIG_MSTR_CLKEDGE_SHIFT(ip), \
538 UNIPERIF_CONFIG_MSTR_CLKEDGE_MASK(ip), 0)
539
540/*
541 * UNIPERIF_CTRL reg
542 */
543
544#define UNIPERIF_CTRL_OFFSET(ip) 0x0044
545#define GET_UNIPERIF_CTRL(ip) \
546 readl_relaxed(ip->base + UNIPERIF_CTRL_OFFSET(ip))
547#define SET_UNIPERIF_CTRL(ip, value) \
548 writel_relaxed(value, ip->base + UNIPERIF_CTRL_OFFSET(ip))
549
550/* OPERATION */
551#define UNIPERIF_CTRL_OPERATION_SHIFT(ip) 0
552#define UNIPERIF_CTRL_OPERATION_MASK(ip) 0x7
553#define GET_UNIPERIF_CTRL_OPERATION(ip) \
554 GET_UNIPERIF_REG(ip, \
555 UNIPERIF_CTRL_OFFSET(ip), \
556 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
557 UNIPERIF_CTRL_OPERATION_MASK(ip))
558#define VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip) 0
559#define SET_UNIPERIF_CTRL_OPERATION_OFF(ip) \
560 SET_UNIPERIF_REG(ip, \
561 UNIPERIF_CTRL_OFFSET(ip), \
562 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
563 UNIPERIF_CTRL_OPERATION_MASK(ip), \
564 VALUE_UNIPERIF_CTRL_OPERATION_OFF(ip))
565#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
566 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 1 : -1)
567#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip) \
568 SET_UNIPERIF_REG(ip, \
569 UNIPERIF_CTRL_OFFSET(ip), \
570 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
571 UNIPERIF_CTRL_OPERATION_MASK(ip), \
572 VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PCM_NULL(ip))
573#define VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
574 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 2 : -1)
575#define SET_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip) \
576 SET_UNIPERIF_REG(ip, \
577 UNIPERIF_CTRL_OFFSET(ip), \
578 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
579 UNIPERIF_CTRL_OPERATION_MASK(ip), \
580 VALUE_UNIPERIF_CTRL_OPERATION_MUTE_PAUSE_BURST(ip))
581#define VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) 3
582#define SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip) \
583 SET_UNIPERIF_REG(ip, \
584 UNIPERIF_CTRL_OFFSET(ip), \
585 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
586 UNIPERIF_CTRL_OPERATION_MASK(ip), \
587 VALUE_UNIPERIF_CTRL_OPERATION_PCM_DATA(ip))
588/* This is the same as above! */
589#define VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) 3
590#define SET_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip) \
591 SET_UNIPERIF_REG(ip, \
592 UNIPERIF_CTRL_OFFSET(ip), \
593 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
594 UNIPERIF_CTRL_OPERATION_MASK(ip), \
595 VALUE_UNIPERIF_CTRL_OPERATION_AUDIO_DATA(ip))
596#define VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) 4
597#define SET_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip) \
598 SET_UNIPERIF_REG(ip, \
599 UNIPERIF_CTRL_OFFSET(ip), \
600 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
601 UNIPERIF_CTRL_OPERATION_MASK(ip), \
602 VALUE_UNIPERIF_CTRL_OPERATION_ENC_DATA(ip))
603#define VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
604 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 5 : -1)
605#define SET_UNIPERIF_CTRL_OPERATION_CD_DATA(ip) \
606 SET_UNIPERIF_REG(ip, \
607 UNIPERIF_CTRL_OFFSET(ip), \
608 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
609 UNIPERIF_CTRL_OPERATION_MASK(ip), \
610 VALUE_UNIPERIF_CTRL_OPERATION_CD_DATA(ip))
611#define VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
612 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 7)
613#define SET_UNIPERIF_CTRL_OPERATION_STANDBY(ip) \
614 SET_UNIPERIF_REG(ip, \
615 UNIPERIF_CTRL_OFFSET(ip), \
616 UNIPERIF_CTRL_OPERATION_SHIFT(ip), \
617 UNIPERIF_CTRL_OPERATION_MASK(ip), \
618 VALUE_UNIPERIF_CTRL_OPERATION_STANDBY(ip))
619
620/* EXIT_STBY_ON_EOBLOCK */
621#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip) \
622 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 3)
623#define UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip) 0x1
624#define GET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK(ip) \
625 GET_UNIPERIF_REG(ip, \
626 UNIPERIF_CTRL_OFFSET(ip), \
627 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
628 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip))
629#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(ip) \
630 SET_UNIPERIF_REG(ip, \
631 UNIPERIF_CTRL_OFFSET(ip), \
632 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
633 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 0)
634#define SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(ip) \
635 SET_UNIPERIF_REG(ip, \
636 UNIPERIF_CTRL_OFFSET(ip), \
637 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_SHIFT(ip), \
638 UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_MASK(ip), 1)
639
640/* ROUNDING */
641#define UNIPERIF_CTRL_ROUNDING_SHIFT(ip) 4
642#define UNIPERIF_CTRL_ROUNDING_MASK(ip) 0x1
643#define GET_UNIPERIF_CTRL_ROUNDING(ip) \
644 GET_UNIPERIF_REG(ip, \
645 UNIPERIF_CTRL_OFFSET(ip), \
646 UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
647 UNIPERIF_CTRL_ROUNDING_MASK(ip))
648#define SET_UNIPERIF_CTRL_ROUNDING_OFF(ip) \
649 SET_UNIPERIF_REG(ip, \
650 UNIPERIF_CTRL_OFFSET(ip), \
651 UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
652 UNIPERIF_CTRL_ROUNDING_MASK(ip), 0)
653#define SET_UNIPERIF_CTRL_ROUNDING_ON(ip) \
654 SET_UNIPERIF_REG(ip, \
655 UNIPERIF_CTRL_OFFSET(ip), \
656 UNIPERIF_CTRL_ROUNDING_SHIFT(ip), \
657 UNIPERIF_CTRL_ROUNDING_MASK(ip), 1)
658
659/* DIVIDER */
660#define UNIPERIF_CTRL_DIVIDER_SHIFT(ip) 5
661#define UNIPERIF_CTRL_DIVIDER_MASK(ip) 0xff
662#define GET_UNIPERIF_CTRL_DIVIDER(ip) \
663 GET_UNIPERIF_REG(ip, \
664 UNIPERIF_CTRL_OFFSET(ip), \
665 UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
666 UNIPERIF_CTRL_DIVIDER_MASK(ip))
667#define SET_UNIPERIF_CTRL_DIVIDER(ip, value) \
668 SET_UNIPERIF_REG(ip, \
669 UNIPERIF_CTRL_OFFSET(ip), \
670 UNIPERIF_CTRL_DIVIDER_SHIFT(ip), \
671 UNIPERIF_CTRL_DIVIDER_MASK(ip), value)
672
673/* BYTE_SWAP */
674#define UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip) \
675 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 13 : -1)
676#define UNIPERIF_CTRL_BYTE_SWP_MASK(ip) 0x1
677#define GET_UNIPERIF_CTRL_BYTE_SWP(ip) \
678 GET_UNIPERIF_REG(ip, \
679 UNIPERIF_CTRL_OFFSET(ip), \
680 UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
681 UNIPERIF_CTRL_BYTE_SWP_MASK(ip))
682#define SET_UNIPERIF_CTRL_BYTE_SWP_OFF(ip) \
683 SET_UNIPERIF_REG(ip, \
684 UNIPERIF_CTRL_OFFSET(ip), \
685 UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
686 UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 0)
687#define SET_UNIPERIF_CTRL_BYTE_SWP_ON(ip) \
688 SET_UNIPERIF_REG(ip, \
689 UNIPERIF_CTRL_OFFSET(ip), \
690 UNIPERIF_CTRL_BYTE_SWP_SHIFT(ip), \
691 UNIPERIF_CTRL_BYTE_SWP_MASK(ip), 1)
692
693/* ZERO_STUFFING_HW_SW */
694#define UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip) \
695 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 14 : -1)
696#define UNIPERIF_CTRL_ZERO_STUFF_MASK(ip) 0x1
697#define GET_UNIPERIF_CTRL_ZERO_STUFF(ip) \
698 GET_UNIPERIF_REG(ip, \
699 UNIPERIF_CTRL_OFFSET(ip), \
700 UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
701 UNIPERIF_CTRL_ZERO_STUFF_MASK(ip))
702#define SET_UNIPERIF_CTRL_ZERO_STUFF_HW(ip) \
703 SET_UNIPERIF_REG(ip, \
704 UNIPERIF_CTRL_OFFSET(ip), \
705 UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
706 UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 1)
707#define SET_UNIPERIF_CTRL_ZERO_STUFF_SW(ip) \
708 SET_UNIPERIF_REG(ip, \
709 UNIPERIF_CTRL_OFFSET(ip), \
710 UNIPERIF_CTRL_ZERO_STUFF_SHIFT(ip), \
711 UNIPERIF_CTRL_ZERO_STUFF_MASK(ip), 0)
712
713/* SPDIF_LAT */
714#define UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip) \
715 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 16 : -1)
716#define UNIPERIF_CTRL_SPDIF_LAT_MASK(ip) 0x1
717#define GET_UNIPERIF_CTRL_SPDIF_LAT(ip) \
718 GET_UNIPERIF_REG(ip, \
719 UNIPERIF_CTRL_OFFSET(ip), \
720 UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
721 UNIPERIF_CTRL_SPDIF_LAT_MASK(ip))
722#define SET_UNIPERIF_CTRL_SPDIF_LAT_ON(ip) \
723 SET_UNIPERIF_REG(ip, \
724 UNIPERIF_CTRL_OFFSET(ip), \
725 UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
726 UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 1)
727#define SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(ip) \
728 SET_UNIPERIF_REG(ip, \
729 UNIPERIF_CTRL_OFFSET(ip), \
730 UNIPERIF_CTRL_SPDIF_LAT_SHIFT(ip), \
731 UNIPERIF_CTRL_SPDIF_LAT_MASK(ip), 0)
732
733/* EN_SPDIF_FORMATTING */
734#define UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip) 17
735#define UNIPERIF_CTRL_SPDIF_FMT_MASK(ip) 0x1
736#define GET_UNIPERIF_CTRL_SPDIF_FMT(ip) \
737 GET_UNIPERIF_REG(ip, \
738 UNIPERIF_CTRL_OFFSET(ip), \
739 UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
740 UNIPERIF_CTRL_SPDIF_FMT_MASK(ip))
741#define SET_UNIPERIF_CTRL_SPDIF_FMT_ON(ip) \
742 SET_UNIPERIF_REG(ip, \
743 UNIPERIF_CTRL_OFFSET(ip), \
744 UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
745 UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 1)
746#define SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(ip) \
747 SET_UNIPERIF_REG(ip, \
748 UNIPERIF_CTRL_OFFSET(ip), \
749 UNIPERIF_CTRL_SPDIF_FMT_SHIFT(ip), \
750 UNIPERIF_CTRL_SPDIF_FMT_MASK(ip), 0)
751
752/* READER_OUT_SELECT */
753#define UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip) \
754 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 18 : -1)
755#define UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip) 0x1
756#define GET_UNIPERIF_CTRL_READER_OUT_SEL(ip) \
757 GET_UNIPERIF_REG(ip, \
758 UNIPERIF_CTRL_OFFSET(ip), \
759 UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
760 UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip))
761#define SET_UNIPERIF_CTRL_READER_OUT_SEL_IN_MEM(ip) \
762 SET_UNIPERIF_REG(ip, \
763 UNIPERIF_CTRL_OFFSET(ip), \
764 UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
765 UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 0)
766#define SET_UNIPERIF_CTRL_READER_OUT_SEL_ON_I2S_LINE(ip) \
767 SET_UNIPERIF_REG(ip, \
768 UNIPERIF_CTRL_OFFSET(ip), \
769 UNIPERIF_CTRL_READER_OUT_SEL_SHIFT(ip), \
770 CORAUD_UNIPERIF_CTRL_READER_OUT_SEL_MASK(ip), 1)
771
772/* UNDERFLOW_REC_WINDOW */
773#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip) 20
774#define UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip) 0xff
775#define GET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip) \
776 GET_UNIPERIF_REG(ip, \
777 UNIPERIF_CTRL_OFFSET(ip), \
778 UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
779 UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip))
780#define SET_UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW(ip, value) \
781 SET_UNIPERIF_REG(ip, \
782 UNIPERIF_CTRL_OFFSET(ip), \
783 UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_SHIFT(ip), \
784 UNIPERIF_CTRL_UNDERFLOW_REC_WINDOW_MASK(ip), value)
785
786/*
787 * UNIPERIF_I2S_FMT a.k.a UNIPERIF_FORMAT reg
788 */
789
790#define UNIPERIF_I2S_FMT_OFFSET(ip) 0x0048
791#define GET_UNIPERIF_I2S_FMT(ip) \
792 readl_relaxed(ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
793#define SET_UNIPERIF_I2S_FMT(ip, value) \
794 writel_relaxed(value, ip->base + UNIPERIF_I2S_FMT_OFFSET(ip))
795
796/* NBIT */
797#define UNIPERIF_I2S_FMT_NBIT_SHIFT(ip) 0
798#define UNIPERIF_I2S_FMT_NBIT_MASK(ip) 0x1
799#define GET_UNIPERIF_I2S_FMT_NBIT(ip) \
800 GET_UNIPERIF_REG(ip, \
801 UNIPERIF_I2S_FMT_OFFSET(ip), \
802 UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
803 UNIPERIF_I2S_FMT_NBIT_MASK(ip))
804#define SET_UNIPERIF_I2S_FMT_NBIT_32(ip) \
805 SET_UNIPERIF_REG(ip, \
806 UNIPERIF_I2S_FMT_OFFSET(ip), \
807 UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
808 UNIPERIF_I2S_FMT_NBIT_MASK(ip), 0)
809#define SET_UNIPERIF_I2S_FMT_NBIT_16(ip) \
810 SET_UNIPERIF_REG(ip, \
811 UNIPERIF_I2S_FMT_OFFSET(ip), \
812 UNIPERIF_I2S_FMT_NBIT_SHIFT(ip), \
813 UNIPERIF_I2S_FMT_NBIT_MASK(ip), 1)
814
815/* DATA_SIZE */
816#define UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip) 1
817#define UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip) 0x7
818#define GET_UNIPERIF_I2S_FMT_DATA_SIZE(ip) \
819 GET_UNIPERIF_REG(ip, \
820 UNIPERIF_I2S_FMT_OFFSET(ip), \
821 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
822 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip))
823#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(ip) \
824 SET_UNIPERIF_REG(ip, \
825 UNIPERIF_I2S_FMT_OFFSET(ip), \
826 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
827 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 0)
828#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_18(ip) \
829 SET_UNIPERIF_REG(ip, \
830 UNIPERIF_I2S_FMT_OFFSET(ip), \
831 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
832 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 1)
833#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_20(ip) \
834 SET_UNIPERIF_REG(ip, \
835 UNIPERIF_I2S_FMT_OFFSET(ip), \
836 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
837 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 2)
838#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(ip) \
839 SET_UNIPERIF_REG(ip, \
840 UNIPERIF_I2S_FMT_OFFSET(ip), \
841 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
842 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 3)
843#define SET_UNIPERIF_I2S_FMTL_DATA_SIZE_28(ip) \
844 SET_UNIPERIF_REG(ip, \
845 UNIPERIF_I2S_FMT_OFFSET(ip), \
846 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
847 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 4)
848#define SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(ip) \
849 SET_UNIPERIF_REG(ip, \
850 UNIPERIF_I2S_FMT_OFFSET(ip), \
851 UNIPERIF_I2S_FMT_DATA_SIZE_SHIFT(ip), \
852 UNIPERIF_I2S_FMT_DATA_SIZE_MASK(ip), 5)
853
854/* LR_POL */
855#define UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip) 4
856#define UNIPERIF_I2S_FMT_LR_POL_MASK(ip) 0x1
857#define VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) 0x0
858#define VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) 0x1
859#define GET_UNIPERIF_I2S_FMT_LR_POL(ip) \
860 GET_UNIPERIF_REG(ip, \
861 UNIPERIF_I2S_FMT_OFFSET(ip), \
862 UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
863 UNIPERIF_I2S_FMT_LR_POL_MASK(ip))
864#define SET_UNIPERIF_I2S_FMT_LR_POL(ip, value) \
865 SET_UNIPERIF_REG(ip, \
866 UNIPERIF_I2S_FMT_OFFSET(ip), \
867 UNIPERIF_I2S_FMT_LR_POL_SHIFT(ip), \
868 UNIPERIF_I2S_FMT_LR_POL_MASK(ip), value)
869#define SET_UNIPERIF_I2S_FMT_LR_POL_LOW(ip) \
870 SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
871 VALUE_UNIPERIF_I2S_FMT_LR_POL_LOW(ip))
872#define SET_UNIPERIF_I2S_FMT_LR_POL_HIG(ip) \
873 SET_UNIPERIF_I2S_FMT_LR_POL(ip, \
874 VALUE_UNIPERIF_I2S_FMT_LR_POL_HIG(ip))
875
876/* SCLK_EDGE */
877#define UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip) 5
878#define UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip) 0x1
879#define GET_UNIPERIF_I2S_FMT_SCLK_EDGE(ip) \
880 GET_UNIPERIF_REG(ip, \
881 UNIPERIF_I2S_FMT_OFFSET(ip), \
882 UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
883 UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip))
884#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(ip) \
885 SET_UNIPERIF_REG(ip, \
886 UNIPERIF_I2S_FMT_OFFSET(ip), \
887 UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
888 UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 0)
889#define SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(ip) \
890 SET_UNIPERIF_REG(ip, \
891 UNIPERIF_I2S_FMT_OFFSET(ip), \
892 UNIPERIF_I2S_FMT_SCLK_EDGE_SHIFT(ip), \
893 UNIPERIF_I2S_FMT_SCLK_EDGE_MASK(ip), 1)
894
895/* PADDING */
896#define UNIPERIF_I2S_FMT_PADDING_SHIFT(ip) 6
897#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1
898#define UNIPERIF_I2S_FMT_PADDING_MASK(ip) 0x1
899#define VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) 0x0
900#define VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) 0x1
901#define GET_UNIPERIF_I2S_FMT_PADDING(ip) \
902 GET_UNIPERIF_REG(ip, \
903 UNIPERIF_I2S_FMT_OFFSET(ip), \
904 UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
905 UNIPERIF_I2S_FMT_PADDING_MASK(ip))
906#define SET_UNIPERIF_I2S_FMT_PADDING(ip, value) \
907 SET_UNIPERIF_REG(ip, \
908 UNIPERIF_I2S_FMT_OFFSET(ip), \
909 UNIPERIF_I2S_FMT_PADDING_SHIFT(ip), \
910 UNIPERIF_I2S_FMT_PADDING_MASK(ip), value)
911#define SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip) \
912 SET_UNIPERIF_I2S_FMT_PADDING(ip, \
913 VALUE_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(ip))
914#define SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip) \
915 SET_UNIPERIF_I2S_FMT_PADDING(ip, \
916 VALUE_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(ip))
917
918/* ALIGN */
919#define UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip) 7
920#define UNIPERIF_I2S_FMT_ALIGN_MASK(ip) 0x1
921#define GET_UNIPERIF_I2S_FMT_ALIGN(ip) \
922 GET_UNIPERIF_REG(ip, \
923 UNIPERIF_I2S_FMT_OFFSET(ip), \
924 UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
925 UNIPERIF_I2S_FMT_ALIGN_MASK(ip))
926#define SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(ip) \
927 SET_UNIPERIF_REG(ip, \
928 UNIPERIF_I2S_FMT_OFFSET(ip), \
929 UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
930 UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 0)
931#define SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(ip) \
932 SET_UNIPERIF_REG(ip, \
933 UNIPERIF_I2S_FMT_OFFSET(ip), \
934 UNIPERIF_I2S_FMT_ALIGN_SHIFT(ip), \
935 UNIPERIF_I2S_FMT_ALIGN_MASK(ip), 1)
936
937/* ORDER */
938#define UNIPERIF_I2S_FMT_ORDER_SHIFT(ip) 8
939#define UNIPERIF_I2S_FMT_ORDER_MASK(ip) 0x1
940#define GET_UNIPERIF_I2S_FMT_ORDER(ip) \
941 GET_UNIPERIF_REG(ip, \
942 UNIPERIF_I2S_FMT_OFFSET(ip), \
943 UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
944 UNIPERIF_I2S_FMT_ORDER_MASK(ip))
945#define SET_UNIPERIF_I2S_FMT_ORDER_LSB(ip) \
946 SET_UNIPERIF_REG(ip, \
947 UNIPERIF_I2S_FMT_OFFSET(ip), \
948 UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
949 UNIPERIF_I2S_FMT_ORDER_MASK(ip), 0)
950#define SET_UNIPERIF_I2S_FMT_ORDER_MSB(ip) \
951 SET_UNIPERIF_REG(ip, \
952 UNIPERIF_I2S_FMT_OFFSET(ip), \
953 UNIPERIF_I2S_FMT_ORDER_SHIFT(ip), \
954 UNIPERIF_I2S_FMT_ORDER_MASK(ip), 1)
955
956/* NUM_CH */
957#define UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip) 9
958#define UNIPERIF_I2S_FMT_NUM_CH_MASK(ip) 0x7
959#define GET_UNIPERIF_I2S_FMT_NUM_CH(ip) \
960 GET_UNIPERIF_REG(ip, \
961 UNIPERIF_I2S_FMT_OFFSET(ip), \
962 UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
963 UNIPERIF_I2S_FMT_NUM_CH_MASK(ip))
964#define SET_UNIPERIF_I2S_FMT_NUM_CH(ip, value) \
965 SET_UNIPERIF_REG(ip, \
966 UNIPERIF_I2S_FMT_OFFSET(ip), \
967 UNIPERIF_I2S_FMT_NUM_CH_SHIFT(ip), \
968 UNIPERIF_I2S_FMT_NUM_CH_MASK(ip), value)
969
970/* NO_OF_SAMPLES_TO_READ */
971#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip) 12
972#define UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip) 0xfffff
973#define GET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip) \
974 GET_UNIPERIF_REG(ip, \
975 UNIPERIF_I2S_FMT_OFFSET(ip), \
976 UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
977 UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip))
978#define SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(ip, value) \
979 SET_UNIPERIF_REG(ip, \
980 UNIPERIF_I2S_FMT_OFFSET(ip), \
981 UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_SHIFT(ip), \
982 UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ_MASK(ip), value)
983
984/*
985 * UNIPERIF_BIT_CONTROL reg
986 */
987
988#define UNIPERIF_BIT_CONTROL_OFFSET(ip) \
989 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0x004c)
990#define GET_UNIPERIF_BIT_CONTROL(ip) \
991 readl_relaxed(ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
992#define SET_UNIPERIF_BIT_CONTROL(ip, value) \
993 writel_relaxed(value, ip->base + UNIPERIF_BIT_CONTROL_OFFSET(ip))
994
995/* CLR_UNDERFLOW_DURATION */
996#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip) 0
997#define UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip) 0x1
998#define GET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
999 GET_UNIPERIF_REG(ip, \
1000 UNIPERIF_BIT_CONTROL_OFFSET(ip), \
1001 UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
1002 UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip))
1003#define SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(ip) \
1004 SET_UNIPERIF_REG(ip, \
1005 UNIPERIF_BIT_CONTROL_OFFSET(ip), \
1006 UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_SHIFT(ip), \
1007 UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION_MASK(ip), 1)
1008
1009/* CHL_STS_UPDATE */
1010#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip) 1
1011#define UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip) 0x1
1012#define GET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
1013 GET_UNIPERIF_REG(ip, \
1014 UNIPERIF_BIT_CONTROL_OFFSET(ip), \
1015 UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
1016 UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip))
1017#define SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(ip) \
1018 SET_UNIPERIF_BIT_REG(ip, \
1019 UNIPERIF_BIT_CONTROL_OFFSET(ip), \
1020 UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_SHIFT(ip), \
1021 UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE_MASK(ip), 1)
1022
1023/*
1024 * UNIPERIF_STATUS_1 reg
1025 */
1026
1027#define UNIPERIF_STATUS_1_OFFSET(ip) 0x0050
1028#define GET_UNIPERIF_STATUS_1(ip) \
1029 readl_relaxed(ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
1030#define SET_UNIPERIF_STATUS_1(ip, value) \
1031 writel_relaxed(value, ip->base + UNIPERIF_STATUS_1_OFFSET(ip))
1032
1033/* UNDERFLOW_DURATION */
1034#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip) \
1035 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
1036#define UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip) 0xff
1037#define GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip) \
1038 GET_UNIPERIF_REG(ip, \
1039 UNIPERIF_STATUS_1_OFFSET(ip), \
1040 UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
1041 UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip))
1042#define SET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(ip, value) \
1043 SET_UNIPERIF_REG(ip, \
1044 UNIPERIF_STATUS_1_OFFSET(ip), \
1045 UNIPERIF_STATUS_1_UNDERFLOW_DURATION_SHIFT(ip), \
1046 UNIPERIF_STATUS_1_UNDERFLOW_DURATION_MASK(ip), value)
1047
1048/*
1049 * AUD_UNIPERIF_CHANNEL_STA_REGN reg
1050 */
1051
1052#define UNIPERIF_CHANNEL_STA_REGN(ip, n) (0x0060 + (4 * n))
1053#define GET_UNIPERIF_CHANNEL_STA_REGN(ip) \
1054 readl_relaxed(ip->base + UNIPERIF_CHANNEL_STA_REGN(ip, n))
1055#define SET_UNIPERIF_CHANNEL_STA_REGN(ip, n, value) \
1056 writel_relaxed(value, ip->base + \
1057 UNIPERIF_CHANNEL_STA_REGN(ip, n))
1058
1059/*
1060 * AUD_UNIPERIF_USER_VALIDITY reg
1061 */
1062
1063#define UNIPERIF_USER_VALIDITY_OFFSET(ip) 0x0090
1064#define GET_UNIPERIF_USER_VALIDITY(ip) \
1065 readl_relaxed(ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
1066#define SET_UNIPERIF_USER_VALIDITY(ip, value) \
1067 writel_relaxed(value, ip->base + UNIPERIF_USER_VALIDITY_OFFSET(ip))
1068
1069/* VALIDITY_LEFT_AND_RIGHT */
1070#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip) 0
1071#define UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip) 0x3
1072#define GET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip) \
1073 GET_UNIPERIF_REG(ip, \
1074 UNIPERIF_USER_VALIDITY_OFFSET(ip), \
1075 UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
1076 UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip))
1077#define SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(ip, value) \
1078 SET_UNIPERIF_REG(ip, \
1079 UNIPERIF_USER_VALIDITY_OFFSET(ip), \
1080 UNIPERIF_USER_VALIDITY_VALIDITY_LR_SHIFT(ip), \
1081 UNIPERIF_USER_VALIDITY_VALIDITY_LR_MASK(ip), \
1082 value ? 0x3 : 0)
1083
1084/*
1085 * UNIPERIF_DBG_STANDBY_LEFT_SP reg
1086 */
1087#define UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip) 0x0150
1088#define UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip) \
1089 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? -1 : 0)
1090#define UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip) \
1091 ((ip)->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0 ? 0 : 0xFFFFFF)
1092#define GET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip) \
1093 GET_UNIPERIF_REG(ip, \
1094 UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
1095 UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
1096 UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip))
1097#define SET_UNIPERIF_DBG_STANDBY_LEFT_SP(ip, value) \
1098 SET_UNIPERIF_REG(ip, \
1099 UNIPERIF_DBG_STANDBY_LEFT_SP_OFFSET(ip), \
1100 UNIPERIF_DBG_STANDBY_LEFT_SP_SHIFT(ip), \
1101 UNIPERIF_DBG_STANDBY_LEFT_SP_MASK(ip), value)
1102
1103/*
1104 * uniperipheral IP capabilities
1105 */
1106
1107#define UNIPERIF_FIFO_SIZE 70 /* FIFO is 70 cells deep */
1108#define UNIPERIF_FIFO_FRAMES 4 /* FDMA trigger limit in frames */
1109
1110/*
1111 * Uniperipheral IP revisions
1112 */
1113enum uniperif_version {
1114 SND_ST_UNIPERIF_VERSION_UNKNOWN,
1115 /* SASG1 (Orly), Newman */
1116 SND_ST_UNIPERIF_VERSION_C6AUD0_UNI_1_0,
1117 /* SASC1, SASG2 (Orly2) */
1118 SND_ST_UNIPERIF_VERSION_UNI_PLR_1_0,
1119 /* SASC1, SASG2 (Orly2), TELSS, Cannes */
1120 SND_ST_UNIPERIF_VERSION_UNI_RDR_1_0,
1121 /* TELSS (SASC1) */
1122 SND_ST_UNIPERIF_VERSION_TDM_PLR_1_0,
1123 /* Cannes/Monaco */
1124 SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
1125};
1126
1127enum uniperif_type {
1128 SND_ST_UNIPERIF_PLAYER_TYPE_NONE,
1129 SND_ST_UNIPERIF_PLAYER_TYPE_HDMI,
1130 SND_ST_UNIPERIF_PLAYER_TYPE_PCM,
1131 SND_ST_UNIPERIF_PLAYER_TYPE_SPDIF
1132};
1133
1134enum uniperif_state {
1135 UNIPERIF_STATE_STOPPED,
1136 UNIPERIF_STATE_STARTED,
1137 UNIPERIF_STATE_STANDBY,
1138 UNIPERIF_STATE_UNDERFLOW,
1139 UNIPERIF_STATE_OVERFLOW = UNIPERIF_STATE_UNDERFLOW,
1140 UNIPERIF_STATE_XRUN
1141};
1142
1143enum uniperif_iec958_encoding_mode {
1144 UNIPERIF_IEC958_ENCODING_MODE_PCM,
1145 UNIPERIF_IEC958_ENCODING_MODE_ENCODED
1146};
1147
1148struct uniperif_info {
1149 int id; /* instance value of the uniperipheral IP */
1150 enum uniperif_type player_type;
1151 int underflow_enabled; /* Underflow recovery mode */
1152};
1153
1154struct uniperif_iec958_settings {
1155 enum uniperif_iec958_encoding_mode encoding_mode;
1156 struct snd_aes_iec958 iec958;
1157};
1158
1159struct uniperif {
1160 /* System information */
1161 struct uniperif_info *info;
1162 struct device *dev;
1163 int ver; /* IP version, used by register access macros */
1164 struct regmap_field *clk_sel;
1165
1166 /* capabilities */
1167 const struct snd_pcm_hardware *hw;
1168
1169 /* Resources */
1170 struct resource *mem_region;
1171 void __iomem *base;
1172 unsigned long fifo_phys_address;
1173 int irq;
1174
1175 /* Clocks */
1176 struct clk *clk;
1177 int mclk;
1178 int clk_adj;
1179
1180 /* Runtime data */
1181 enum uniperif_state state;
1182
1183 struct snd_pcm_substream *substream;
1184
1185 /* Specific to IEC958 player */
1186 struct uniperif_iec958_settings stream_settings;
1187 struct mutex ctrl_lock; /* For resource updated by stream and controls*/
1188
1189 /*alsa ctrl*/
1190 struct snd_kcontrol_new *snd_ctrls;
1191 int num_ctrls;
1192
1193 /* dai properties */
1194 unsigned int daifmt;
1195
1196 /* DAI callbacks */
1197 const struct snd_soc_dai_ops *dai_ops;
1198};
1199
1200struct sti_uniperiph_dai {
1201 int stream;
1202 struct uniperif *uni;
1203 struct snd_dmaengine_dai_dma_data dma_data;
1204};
1205
1206struct sti_uniperiph_data {
1207 struct platform_device *pdev;
1208 struct snd_soc_dai_driver *dai;
1209 struct sti_uniperiph_dai dai_data;
1210};
1211
1212/* uniperiph player*/
1213int uni_player_init(struct platform_device *pdev,
1214 struct uniperif *uni_player);
1215int uni_player_resume(struct uniperif *player);
1216
1217/* uniperiph reader */
1218int uni_reader_init(struct platform_device *pdev,
1219 struct uniperif *uni_reader);
1220
1221/* common */
1222int sti_uniperiph_dai_set_fmt(struct snd_soc_dai *dai,
1223 unsigned int fmt);
1224
1225int sti_uniperiph_dai_hw_params(struct snd_pcm_substream *substream,
1226 struct snd_pcm_hw_params *params,
1227 struct snd_soc_dai *dai);
1228
1229#endif
diff --git a/sound/soc/sti/uniperif_player.c b/sound/soc/sti/uniperif_player.c
new file mode 100644
index 000000000000..f6eefe1b8f8f
--- /dev/null
+++ b/sound/soc/sti/uniperif_player.c
@@ -0,0 +1,1110 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2015
3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
4 * for STMicroelectronics.
5 * License terms: GNU General Public License (GPL), version 2
6 */
7
8#include <linux/clk.h>
9#include <linux/delay.h>
10#include <linux/io.h>
11#include <linux/mfd/syscon.h>
12
13#include <sound/asoundef.h>
14#include <sound/soc.h>
15
16#include "uniperif.h"
17
18/*
19 * Some hardware-related definitions
20 */
21
22/* sys config registers definitions */
23#define SYS_CFG_AUDIO_GLUE 0xA4
24#define SYS_CFG_AUDI0_GLUE_PCM_CLKX 8
25
26/*
27 * Driver specific types.
28 */
29#define UNIPERIF_PLAYER_TYPE_IS_HDMI(p) \
30 ((p)->info->player_type == SND_ST_UNIPERIF_PLAYER_TYPE_HDMI)
31#define UNIPERIF_PLAYER_TYPE_IS_PCM(p) \
32 ((p)->info->player_type == SND_ST_UNIPERIF_PLAYER_TYPE_PCM)
33#define UNIPERIF_PLAYER_TYPE_IS_SPDIF(p) \
34 ((p)->info->player_type == SND_ST_UNIPERIF_PLAYER_TYPE_SPDIF)
35#define UNIPERIF_PLAYER_TYPE_IS_IEC958(p) \
36 (UNIPERIF_PLAYER_TYPE_IS_HDMI(p) || \
37 UNIPERIF_PLAYER_TYPE_IS_SPDIF(p))
38
39#define UNIPERIF_PLAYER_CLK_ADJ_MIN -999999
40#define UNIPERIF_PLAYER_CLK_ADJ_MAX 1000000
41
42/*
43 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
44 * integrate DAI_CPU capability in term of rate and supported channels
45 */
46static const struct snd_pcm_hardware uni_player_pcm_hw = {
47 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
48 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
49 SNDRV_PCM_INFO_MMAP_VALID,
50 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
51
52 .rates = SNDRV_PCM_RATE_CONTINUOUS,
53 .rate_min = 8000,
54 .rate_max = 192000,
55
56 .channels_min = 2,
57 .channels_max = 8,
58
59 .periods_min = 2,
60 .periods_max = 48,
61
62 .period_bytes_min = 128,
63 .period_bytes_max = 64 * PAGE_SIZE,
64 .buffer_bytes_max = 256 * PAGE_SIZE
65};
66
67static inline int reset_player(struct uniperif *player)
68{
69 int count = 10;
70
71 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
72 while (GET_UNIPERIF_SOFT_RST_SOFT_RST(player) && count) {
73 udelay(5);
74 count--;
75 }
76 }
77
78 if (!count) {
79 dev_err(player->dev, "Failed to reset uniperif");
80 return -EIO;
81 }
82
83 return 0;
84}
85
86/*
87 * uni_player_irq_handler
88 * In case of error audio stream is stopped; stop action is protected via PCM
89 * stream lock to avoid race condition with trigger callback.
90 */
91static irqreturn_t uni_player_irq_handler(int irq, void *dev_id)
92{
93 irqreturn_t ret = IRQ_NONE;
94 struct uniperif *player = dev_id;
95 unsigned int status;
96 unsigned int tmp;
97
98 if (player->state == UNIPERIF_STATE_STOPPED) {
99 /* Unexpected IRQ: do nothing */
100 return IRQ_NONE;
101 }
102
103 /* Get interrupt status & clear them immediately */
104 status = GET_UNIPERIF_ITS(player);
105 SET_UNIPERIF_ITS_BCLR(player, status);
106
107 /* Check for fifo error (underrun) */
108 if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(player))) {
109 dev_err(player->dev, "FIFO underflow error detected");
110
111 /* Interrupt is just for information when underflow recovery */
112 if (player->info->underflow_enabled) {
113 /* Update state to underflow */
114 player->state = UNIPERIF_STATE_UNDERFLOW;
115
116 } else {
117 /* Disable interrupt so doesn't continually fire */
118 SET_UNIPERIF_ITM_BCLR_FIFO_ERROR(player);
119
120 /* Stop the player */
121 snd_pcm_stream_lock(player->substream);
122 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
123 snd_pcm_stream_unlock(player->substream);
124 }
125
126 ret = IRQ_HANDLED;
127 }
128
129 /* Check for dma error (overrun) */
130 if (unlikely(status & UNIPERIF_ITS_DMA_ERROR_MASK(player))) {
131 dev_err(player->dev, "DMA error detected");
132
133 /* Disable interrupt so doesn't continually fire */
134 SET_UNIPERIF_ITM_BCLR_DMA_ERROR(player);
135
136 /* Stop the player */
137 snd_pcm_stream_lock(player->substream);
138 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
139 snd_pcm_stream_unlock(player->substream);
140
141 ret = IRQ_HANDLED;
142 }
143
144 /* Check for underflow recovery done */
145 if (unlikely(status & UNIPERIF_ITM_UNDERFLOW_REC_DONE_MASK(player))) {
146 if (!player->info->underflow_enabled) {
147 dev_err(player->dev, "unexpected Underflow recovering");
148 return -EPERM;
149 }
150 /* Read the underflow recovery duration */
151 tmp = GET_UNIPERIF_STATUS_1_UNDERFLOW_DURATION(player);
152
153 /* Clear the underflow recovery duration */
154 SET_UNIPERIF_BIT_CONTROL_CLR_UNDERFLOW_DURATION(player);
155
156 /* Update state to started */
157 player->state = UNIPERIF_STATE_STARTED;
158
159 ret = IRQ_HANDLED;
160 }
161
162 /* Check if underflow recovery failed */
163 if (unlikely(status &
164 UNIPERIF_ITM_UNDERFLOW_REC_FAILED_MASK(player))) {
165 dev_err(player->dev, "Underflow recovery failed");
166
167 /* Stop the player */
168 snd_pcm_stream_lock(player->substream);
169 snd_pcm_stop(player->substream, SNDRV_PCM_STATE_XRUN);
170 snd_pcm_stream_unlock(player->substream);
171
172 ret = IRQ_HANDLED;
173 }
174
175 return ret;
176}
177
178static int uni_player_clk_set_rate(struct uniperif *player, unsigned long rate)
179{
180 int rate_adjusted, rate_achieved, delta, ret;
181 int adjustment = player->clk_adj;
182
183 /*
184 * a
185 * F = f + --------- * f = f + d
186 * 1000000
187 *
188 * a
189 * d = --------- * f
190 * 1000000
191 *
192 * where:
193 * f - nominal rate
194 * a - adjustment in ppm (parts per milion)
195 * F - rate to be set in synthesizer
196 * d - delta (difference) between f and F
197 */
198 if (adjustment < 0) {
199 /* div64_64 operates on unsigned values... */
200 delta = -1;
201 adjustment = -adjustment;
202 } else {
203 delta = 1;
204 }
205 /* 500000 ppm is 0.5, which is used to round up values */
206 delta *= (int)div64_u64((uint64_t)rate *
207 (uint64_t)adjustment + 500000, 1000000);
208 rate_adjusted = rate + delta;
209
210 /* Adjusted rate should never be == 0 */
211 if (!rate_adjusted)
212 return -EINVAL;
213
214 ret = clk_set_rate(player->clk, rate_adjusted);
215 if (ret < 0)
216 return ret;
217
218 rate_achieved = clk_get_rate(player->clk);
219 if (!rate_achieved)
220 /* If value is 0 means that clock or parent not valid */
221 return -EINVAL;
222
223 /*
224 * Using ALSA's adjustment control, we can modify the rate to be up
225 * to twice as much as requested, but no more
226 */
227 delta = rate_achieved - rate;
228 if (delta < 0) {
229 /* div64_64 operates on unsigned values... */
230 delta = -delta;
231 adjustment = -1;
232 } else {
233 adjustment = 1;
234 }
235 /* Frequency/2 is added to round up result */
236 adjustment *= (int)div64_u64((uint64_t)delta * 1000000 + rate / 2,
237 rate);
238 player->clk_adj = adjustment;
239 return 0;
240}
241
242static void uni_player_set_channel_status(struct uniperif *player,
243 struct snd_pcm_runtime *runtime)
244{
245 int n;
246 unsigned int status;
247
248 /*
249 * Some AVRs and TVs require the channel status to contain a correct
250 * sampling frequency. If no sample rate is already specified, then
251 * set one.
252 */
253 mutex_lock(&player->ctrl_lock);
254 if (runtime && (player->stream_settings.iec958.status[3]
255 == IEC958_AES3_CON_FS_NOTID)) {
256 switch (runtime->rate) {
257 case 22050:
258 player->stream_settings.iec958.status[3] =
259 IEC958_AES3_CON_FS_22050;
260 break;
261 case 44100:
262 player->stream_settings.iec958.status[3] =
263 IEC958_AES3_CON_FS_44100;
264 break;
265 case 88200:
266 player->stream_settings.iec958.status[3] =
267 IEC958_AES3_CON_FS_88200;
268 break;
269 case 176400:
270 player->stream_settings.iec958.status[3] =
271 IEC958_AES3_CON_FS_176400;
272 break;
273 case 24000:
274 player->stream_settings.iec958.status[3] =
275 IEC958_AES3_CON_FS_24000;
276 break;
277 case 48000:
278 player->stream_settings.iec958.status[3] =
279 IEC958_AES3_CON_FS_48000;
280 break;
281 case 96000:
282 player->stream_settings.iec958.status[3] =
283 IEC958_AES3_CON_FS_96000;
284 break;
285 case 192000:
286 player->stream_settings.iec958.status[3] =
287 IEC958_AES3_CON_FS_192000;
288 break;
289 case 32000:
290 player->stream_settings.iec958.status[3] =
291 IEC958_AES3_CON_FS_32000;
292 break;
293 default:
294 /* Mark as sampling frequency not indicated */
295 player->stream_settings.iec958.status[3] =
296 IEC958_AES3_CON_FS_NOTID;
297 break;
298 }
299 }
300
301 /* Audio mode:
302 * Use audio mode status to select PCM or encoded mode
303 */
304 if (player->stream_settings.iec958.status[0] & IEC958_AES0_NONAUDIO)
305 player->stream_settings.encoding_mode =
306 UNIPERIF_IEC958_ENCODING_MODE_ENCODED;
307 else
308 player->stream_settings.encoding_mode =
309 UNIPERIF_IEC958_ENCODING_MODE_PCM;
310
311 if (player->stream_settings.encoding_mode ==
312 UNIPERIF_IEC958_ENCODING_MODE_PCM)
313 /* Clear user validity bits */
314 SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
315 else
316 /* Set user validity bits */
317 SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 1);
318
319 /* Program the new channel status */
320 for (n = 0; n < 6; ++n) {
321 status =
322 player->stream_settings.iec958.status[0 + (n * 4)] & 0xf;
323 status |=
324 player->stream_settings.iec958.status[1 + (n * 4)] << 8;
325 status |=
326 player->stream_settings.iec958.status[2 + (n * 4)] << 16;
327 status |=
328 player->stream_settings.iec958.status[3 + (n * 4)] << 24;
329 SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
330 }
331 mutex_unlock(&player->ctrl_lock);
332
333 /* Update the channel status */
334 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
335 SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
336 else
337 SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
338}
339
340static int uni_player_prepare_iec958(struct uniperif *player,
341 struct snd_pcm_runtime *runtime)
342{
343 int clk_div;
344
345 clk_div = player->mclk / runtime->rate;
346
347 /* Oversampling must be multiple of 128 as iec958 frame is 32-bits */
348 if ((clk_div % 128) || (clk_div <= 0)) {
349 dev_err(player->dev, "%s: invalid clk_div %d",
350 __func__, clk_div);
351 return -EINVAL;
352 }
353
354 switch (runtime->format) {
355 case SNDRV_PCM_FORMAT_S16_LE:
356 /* 16/16 memory format */
357 SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
358 /* 16-bits per sub-frame */
359 SET_UNIPERIF_I2S_FMT_NBIT_32(player);
360 /* Set 16-bit sample precision */
361 SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
362 break;
363 case SNDRV_PCM_FORMAT_S32_LE:
364 /* 16/0 memory format */
365 SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
366 /* 32-bits per sub-frame */
367 SET_UNIPERIF_I2S_FMT_NBIT_32(player);
368 /* Set 24-bit sample precision */
369 SET_UNIPERIF_I2S_FMT_DATA_SIZE_24(player);
370 break;
371 default:
372 dev_err(player->dev, "format not supported");
373 return -EINVAL;
374 }
375
376 /* Set parity to be calculated by the hardware */
377 SET_UNIPERIF_CONFIG_PARITY_CNTR_BY_HW(player);
378
379 /* Set channel status bits to be inserted by the hardware */
380 SET_UNIPERIF_CONFIG_CHANNEL_STA_CNTR_BY_HW(player);
381
382 /* Set user data bits to be inserted by the hardware */
383 SET_UNIPERIF_CONFIG_USER_DAT_CNTR_BY_HW(player);
384
385 /* Set validity bits to be inserted by the hardware */
386 SET_UNIPERIF_CONFIG_VALIDITY_DAT_CNTR_BY_HW(player);
387
388 /* Set full software control to disabled */
389 SET_UNIPERIF_CONFIG_SPDIF_SW_CTRL_DISABLE(player);
390
391 SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
392
393 /* Update the channel status */
394 uni_player_set_channel_status(player, runtime);
395
396 /* Clear the user validity user bits */
397 SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
398
399 /* Disable one-bit audio mode */
400 SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
401
402 /* Enable consecutive frames repetition of Z preamble (not for HBRA) */
403 SET_UNIPERIF_CONFIG_REPEAT_CHL_STS_ENABLE(player);
404
405 /* Change to SUF0_SUBF1 and left/right channels swap! */
406 SET_UNIPERIF_CONFIG_SUBFRAME_SEL_SUBF1_SUBF0(player);
407
408 /* Set data output as MSB first */
409 SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
410
411 if (player->stream_settings.encoding_mode ==
412 UNIPERIF_IEC958_ENCODING_MODE_ENCODED)
413 SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_ON(player);
414 else
415 SET_UNIPERIF_CTRL_EXIT_STBY_ON_EOBLOCK_OFF(player);
416
417 SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
418
419 /* Set rounding to off */
420 SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
421
422 /* Set clock divisor */
423 SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / 128);
424
425 /* Set the spdif latency to not wait before starting player */
426 SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
427
428 /*
429 * Ensure iec958 formatting is off. It will be enabled in function
430 * uni_player_start() at the same time as the operation
431 * mode is set to work around a silicon issue.
432 */
433 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
434 SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
435 else
436 SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
437
438 return 0;
439}
440
441static int uni_player_prepare_pcm(struct uniperif *player,
442 struct snd_pcm_runtime *runtime)
443{
444 int output_frame_size, slot_width, clk_div;
445
446 /* Force slot width to 32 in I2S mode (HW constraint) */
447 if ((player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
448 SND_SOC_DAIFMT_I2S) {
449 slot_width = 32;
450 } else {
451 switch (runtime->format) {
452 case SNDRV_PCM_FORMAT_S16_LE:
453 slot_width = 16;
454 break;
455 default:
456 slot_width = 32;
457 break;
458 }
459 }
460 output_frame_size = slot_width * runtime->channels;
461
462 clk_div = player->mclk / runtime->rate;
463 /*
464 * For 32 bits subframe clk_div must be a multiple of 128,
465 * for 16 bits must be a multiple of 64
466 */
467 if ((slot_width == 32) && (clk_div % 128)) {
468 dev_err(player->dev, "%s: invalid clk_div", __func__);
469 return -EINVAL;
470 }
471
472 if ((slot_width == 16) && (clk_div % 64)) {
473 dev_err(player->dev, "%s: invalid clk_div", __func__);
474 return -EINVAL;
475 }
476
477 /*
478 * Number of bits per subframe (which is one channel sample)
479 * on output - Transfer 16 or 32 bits from FIFO
480 */
481 switch (slot_width) {
482 case 32:
483 SET_UNIPERIF_I2S_FMT_NBIT_32(player);
484 SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(player);
485 break;
486 case 16:
487 SET_UNIPERIF_I2S_FMT_NBIT_16(player);
488 SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(player);
489 break;
490 default:
491 dev_err(player->dev, "subframe format not supported");
492 return -EINVAL;
493 }
494
495 /* Configure data memory format */
496 switch (runtime->format) {
497 case SNDRV_PCM_FORMAT_S16_LE:
498 /* One data word contains two samples */
499 SET_UNIPERIF_CONFIG_MEM_FMT_16_16(player);
500 break;
501
502 case SNDRV_PCM_FORMAT_S32_LE:
503 /*
504 * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
505 * on the left than zeros (if less than 32 bytes)"... ;-)
506 */
507 SET_UNIPERIF_CONFIG_MEM_FMT_16_0(player);
508 break;
509
510 default:
511 dev_err(player->dev, "format not supported");
512 return -EINVAL;
513 }
514
515 /* Set rounding to off */
516 SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
517
518 /* Set clock divisor */
519 SET_UNIPERIF_CTRL_DIVIDER(player, clk_div / (2 * output_frame_size));
520
521 /* Number of channelsmust be even*/
522 if ((runtime->channels % 2) || (runtime->channels < 2) ||
523 (runtime->channels > 10)) {
524 dev_err(player->dev, "%s: invalid nb of channels", __func__);
525 return -EINVAL;
526 }
527
528 SET_UNIPERIF_I2S_FMT_NUM_CH(player, runtime->channels / 2);
529
530 /* Set 1-bit audio format to disabled */
531 SET_UNIPERIF_CONFIG_ONE_BIT_AUD_DISABLE(player);
532
533 SET_UNIPERIF_I2S_FMT_ORDER_MSB(player);
534 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
535
536 /* No iec958 formatting as outputting to DAC */
537 SET_UNIPERIF_CTRL_SPDIF_FMT_OFF(player);
538
539 return 0;
540}
541
542/*
543 * ALSA uniperipheral iec958 controls
544 */
545static int uni_player_ctl_iec958_info(struct snd_kcontrol *kcontrol,
546 struct snd_ctl_elem_info *uinfo)
547{
548 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
549 uinfo->count = 1;
550
551 return 0;
552}
553
554static int uni_player_ctl_iec958_get(struct snd_kcontrol *kcontrol,
555 struct snd_ctl_elem_value *ucontrol)
556{
557 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
558 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
559 struct uniperif *player = priv->dai_data.uni;
560 struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
561
562 mutex_lock(&player->ctrl_lock);
563 ucontrol->value.iec958.status[0] = iec958->status[0];
564 ucontrol->value.iec958.status[1] = iec958->status[1];
565 ucontrol->value.iec958.status[2] = iec958->status[2];
566 ucontrol->value.iec958.status[3] = iec958->status[3];
567 mutex_unlock(&player->ctrl_lock);
568 return 0;
569}
570
571static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
572 struct snd_ctl_elem_value *ucontrol)
573{
574 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
575 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
576 struct uniperif *player = priv->dai_data.uni;
577 struct snd_aes_iec958 *iec958 = &player->stream_settings.iec958;
578
579 mutex_lock(&player->ctrl_lock);
580 iec958->status[0] = ucontrol->value.iec958.status[0];
581 iec958->status[1] = ucontrol->value.iec958.status[1];
582 iec958->status[2] = ucontrol->value.iec958.status[2];
583 iec958->status[3] = ucontrol->value.iec958.status[3];
584 mutex_unlock(&player->ctrl_lock);
585
586 uni_player_set_channel_status(player, NULL);
587
588 return 0;
589}
590
591static struct snd_kcontrol_new uni_player_iec958_ctl = {
592 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
593 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
594 .info = uni_player_ctl_iec958_info,
595 .get = uni_player_ctl_iec958_get,
596 .put = uni_player_ctl_iec958_put,
597};
598
599/*
600 * uniperif rate adjustement control
601 */
602static int snd_sti_clk_adjustment_info(struct snd_kcontrol *kcontrol,
603 struct snd_ctl_elem_info *uinfo)
604{
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
606 uinfo->count = 1;
607 uinfo->value.integer.min = UNIPERIF_PLAYER_CLK_ADJ_MIN;
608 uinfo->value.integer.max = UNIPERIF_PLAYER_CLK_ADJ_MAX;
609 uinfo->value.integer.step = 1;
610
611 return 0;
612}
613
614static int snd_sti_clk_adjustment_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
616{
617 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
618 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
619 struct uniperif *player = priv->dai_data.uni;
620
621 mutex_lock(&player->ctrl_lock);
622 ucontrol->value.integer.value[0] = player->clk_adj;
623 mutex_unlock(&player->ctrl_lock);
624
625 return 0;
626}
627
628static int snd_sti_clk_adjustment_put(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_value *ucontrol)
630{
631 struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
632 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
633 struct uniperif *player = priv->dai_data.uni;
634 int ret = 0;
635
636 if ((ucontrol->value.integer.value[0] < UNIPERIF_PLAYER_CLK_ADJ_MIN) ||
637 (ucontrol->value.integer.value[0] > UNIPERIF_PLAYER_CLK_ADJ_MAX))
638 return -EINVAL;
639
640 mutex_lock(&player->ctrl_lock);
641 player->clk_adj = ucontrol->value.integer.value[0];
642
643 if (player->mclk)
644 ret = uni_player_clk_set_rate(player, player->mclk);
645 mutex_unlock(&player->ctrl_lock);
646
647 return ret;
648}
649
650static struct snd_kcontrol_new uni_player_clk_adj_ctl = {
651 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
652 .name = "PCM Playback Oversampling Freq. Adjustment",
653 .info = snd_sti_clk_adjustment_info,
654 .get = snd_sti_clk_adjustment_get,
655 .put = snd_sti_clk_adjustment_put,
656};
657
658static struct snd_kcontrol_new *snd_sti_pcm_ctl[] = {
659 &uni_player_clk_adj_ctl,
660};
661
662static struct snd_kcontrol_new *snd_sti_iec_ctl[] = {
663 &uni_player_iec958_ctl,
664 &uni_player_clk_adj_ctl,
665};
666
667static int uni_player_startup(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai)
669{
670 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
671 struct uniperif *player = priv->dai_data.uni;
672
673 player->clk_adj = 0;
674
675 return 0;
676}
677
678static int uni_player_set_sysclk(struct snd_soc_dai *dai, int clk_id,
679 unsigned int freq, int dir)
680{
681 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
682 struct uniperif *player = priv->dai_data.uni;
683 int ret;
684
685 if (dir == SND_SOC_CLOCK_IN)
686 return 0;
687
688 if (clk_id != 0)
689 return -EINVAL;
690
691 mutex_lock(&player->ctrl_lock);
692 ret = uni_player_clk_set_rate(player, freq);
693 if (!ret)
694 player->mclk = freq;
695 mutex_unlock(&player->ctrl_lock);
696
697 return ret;
698}
699
700static int uni_player_prepare(struct snd_pcm_substream *substream,
701 struct snd_soc_dai *dai)
702{
703 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
704 struct uniperif *player = priv->dai_data.uni;
705 struct snd_pcm_runtime *runtime = substream->runtime;
706 int transfer_size, trigger_limit;
707 int ret;
708
709 /* The player should be stopped */
710 if (player->state != UNIPERIF_STATE_STOPPED) {
711 dev_err(player->dev, "%s: invalid player state %d", __func__,
712 player->state);
713 return -EINVAL;
714 }
715
716 /* Calculate transfer size (in fifo cells and bytes) for frame count */
717 transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
718
719 /* Calculate number of empty cells available before asserting DREQ */
720 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0) {
721 trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
722 } else {
723 /*
724 * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
725 * FDMA_TRIGGER_LIMIT also controls when the state switches
726 * from OFF or STANDBY to AUDIO DATA.
727 */
728 trigger_limit = transfer_size;
729 }
730
731 /* Trigger limit must be an even number */
732 if ((!trigger_limit % 2) || (trigger_limit != 1 && transfer_size % 2) ||
733 (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(player))) {
734 dev_err(player->dev, "invalid trigger limit %d", trigger_limit);
735 return -EINVAL;
736 }
737
738 SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(player, trigger_limit);
739
740 /* Uniperipheral setup depends on player type */
741 switch (player->info->player_type) {
742 case SND_ST_UNIPERIF_PLAYER_TYPE_HDMI:
743 ret = uni_player_prepare_iec958(player, runtime);
744 break;
745 case SND_ST_UNIPERIF_PLAYER_TYPE_PCM:
746 ret = uni_player_prepare_pcm(player, runtime);
747 break;
748 case SND_ST_UNIPERIF_PLAYER_TYPE_SPDIF:
749 ret = uni_player_prepare_iec958(player, runtime);
750 break;
751 default:
752 dev_err(player->dev, "invalid player type");
753 return -EINVAL;
754 }
755
756 if (ret)
757 return ret;
758
759 switch (player->daifmt & SND_SOC_DAIFMT_INV_MASK) {
760 case SND_SOC_DAIFMT_NB_NF:
761 SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
762 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
763 break;
764 case SND_SOC_DAIFMT_NB_IF:
765 SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
766 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(player);
767 break;
768 case SND_SOC_DAIFMT_IB_NF:
769 SET_UNIPERIF_I2S_FMT_LR_POL_LOW(player);
770 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
771 break;
772 case SND_SOC_DAIFMT_IB_IF:
773 SET_UNIPERIF_I2S_FMT_LR_POL_HIG(player);
774 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_FALLING(player);
775 break;
776 }
777
778 switch (player->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
779 case SND_SOC_DAIFMT_I2S:
780 SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
781 SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(player);
782 break;
783 case SND_SOC_DAIFMT_LEFT_J:
784 SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(player);
785 SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
786 break;
787 case SND_SOC_DAIFMT_RIGHT_J:
788 SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(player);
789 SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(player);
790 break;
791 default:
792 dev_err(player->dev, "format not supported");
793 return -EINVAL;
794 }
795
796 SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(player, 0);
797
798 /* Reset uniperipheral player */
799 SET_UNIPERIF_SOFT_RST_SOFT_RST(player);
800
801 return reset_player(player);
802}
803
804static int uni_player_start(struct uniperif *player)
805{
806 int ret;
807
808 /* The player should be stopped */
809 if (player->state != UNIPERIF_STATE_STOPPED) {
810 dev_err(player->dev, "%s: invalid player state", __func__);
811 return -EINVAL;
812 }
813
814 ret = clk_prepare_enable(player->clk);
815 if (ret) {
816 dev_err(player->dev, "%s: Failed to enable clock", __func__);
817 return ret;
818 }
819
820 /* Clear any pending interrupts */
821 SET_UNIPERIF_ITS_BCLR(player, GET_UNIPERIF_ITS(player));
822
823 /* Set the interrupt mask */
824 SET_UNIPERIF_ITM_BSET_DMA_ERROR(player);
825 SET_UNIPERIF_ITM_BSET_FIFO_ERROR(player);
826
827 /* Enable underflow recovery interrupts */
828 if (player->info->underflow_enabled) {
829 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(player);
830 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(player);
831 }
832
833 /* Reset uniperipheral player */
834 SET_UNIPERIF_SOFT_RST_SOFT_RST(player);
835
836 ret = reset_player(player);
837 if (ret < 0)
838 return ret;
839
840 /*
841 * Does not use IEC61937 features of the uniperipheral hardware.
842 * Instead it performs IEC61937 in software and inserts it directly
843 * into the audio data stream. As such, when encoded mode is selected,
844 * linear pcm mode is still used, but with the differences of the
845 * channel status bits set for encoded mode and the validity bits set.
846 */
847 SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(player);
848
849 /*
850 * If iec958 formatting is required for hdmi or spdif, then it must be
851 * enabled after the operation mode is set. If set prior to this, it
852 * will not take affect and hang the player.
853 */
854 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
855 if (UNIPERIF_PLAYER_TYPE_IS_IEC958(player))
856 SET_UNIPERIF_CTRL_SPDIF_FMT_ON(player);
857
858 /* Force channel status update (no update if clk disable) */
859 if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
860 SET_UNIPERIF_CONFIG_CHL_STS_UPDATE(player);
861 else
862 SET_UNIPERIF_BIT_CONTROL_CHL_STS_UPDATE(player);
863
864 /* Update state to started */
865 player->state = UNIPERIF_STATE_STARTED;
866
867 return 0;
868}
869
870static int uni_player_stop(struct uniperif *player)
871{
872 int ret;
873
874 /* The player should not be in stopped state */
875 if (player->state == UNIPERIF_STATE_STOPPED) {
876 dev_err(player->dev, "%s: invalid player state", __func__);
877 return -EINVAL;
878 }
879
880 /* Turn the player off */
881 SET_UNIPERIF_CTRL_OPERATION_OFF(player);
882
883 /* Soft reset the player */
884 SET_UNIPERIF_SOFT_RST_SOFT_RST(player);
885
886 ret = reset_player(player);
887 if (ret < 0)
888 return ret;
889
890 /* Disable interrupts */
891 SET_UNIPERIF_ITM_BCLR(player, GET_UNIPERIF_ITM(player));
892
893 /* Disable clock */
894 clk_disable_unprepare(player->clk);
895
896 /* Update state to stopped and return */
897 player->state = UNIPERIF_STATE_STOPPED;
898
899 return 0;
900}
901
902int uni_player_resume(struct uniperif *player)
903{
904 int ret;
905
906 /* Select the frequency synthesizer clock */
907 if (player->clk_sel) {
908 ret = regmap_field_write(player->clk_sel, 1);
909 if (ret) {
910 dev_err(player->dev,
911 "%s: Failed to select freq synth clock",
912 __func__);
913 return ret;
914 }
915 }
916
917 SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
918 SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
919 SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
920 SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
921
922 return 0;
923}
924EXPORT_SYMBOL_GPL(uni_player_resume);
925
926static int uni_player_trigger(struct snd_pcm_substream *substream,
927 int cmd, struct snd_soc_dai *dai)
928{
929 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
930 struct uniperif *player = priv->dai_data.uni;
931
932 switch (cmd) {
933 case SNDRV_PCM_TRIGGER_START:
934 return uni_player_start(player);
935 case SNDRV_PCM_TRIGGER_STOP:
936 return uni_player_stop(player);
937 case SNDRV_PCM_TRIGGER_RESUME:
938 return uni_player_resume(player);
939 default:
940 return -EINVAL;
941 }
942}
943
944static void uni_player_shutdown(struct snd_pcm_substream *substream,
945 struct snd_soc_dai *dai)
946{
947 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
948 struct uniperif *player = priv->dai_data.uni;
949
950 if (player->state != UNIPERIF_STATE_STOPPED)
951 /* Stop the player */
952 uni_player_stop(player);
953}
954
955static int uni_player_parse_dt_clk_glue(struct platform_device *pdev,
956 struct uniperif *player)
957{
958 int bit_offset;
959 struct device_node *node = pdev->dev.of_node;
960 struct regmap *regmap;
961
962 bit_offset = SYS_CFG_AUDI0_GLUE_PCM_CLKX + player->info->id;
963
964 regmap = syscon_regmap_lookup_by_phandle(node, "st,syscfg");
965
966 if (regmap) {
967 struct reg_field regfield =
968 REG_FIELD(SYS_CFG_AUDIO_GLUE, bit_offset, bit_offset);
969
970 player->clk_sel = regmap_field_alloc(regmap, regfield);
971 } else {
972 dev_err(&pdev->dev, "sti-audio-clk-glue syscf not found\n");
973 return -EINVAL;
974 }
975
976 return 0;
977}
978
979static int uni_player_parse_dt(struct platform_device *pdev,
980 struct uniperif *player)
981{
982 struct uniperif_info *info;
983 struct device *dev = &pdev->dev;
984 struct device_node *pnode = pdev->dev.of_node;
985 const char *mode;
986
987 /* Allocate memory for the info structure */
988 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
989 if (!info)
990 return -ENOMEM;
991
992 of_property_read_u32(pnode, "version", &player->ver);
993 if (player->ver == SND_ST_UNIPERIF_VERSION_UNKNOWN) {
994 dev_err(dev, "Unknown uniperipheral version ");
995 return -EINVAL;
996 }
997 /* Underflow recovery is only supported on later ip revisions */
998 if (player->ver >= SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
999 info->underflow_enabled = 1;
1000
1001 of_property_read_u32(pnode, "uniperiph-id", &info->id);
1002
1003 /* Read the device mode property */
1004 of_property_read_string(pnode, "mode", &mode);
1005
1006 if (strcasecmp(mode, "hdmi") == 0)
1007 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_HDMI;
1008 else if (strcasecmp(mode, "pcm") == 0)
1009 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_PCM;
1010 else if (strcasecmp(mode, "spdif") == 0)
1011 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_SPDIF;
1012 else
1013 info->player_type = SND_ST_UNIPERIF_PLAYER_TYPE_NONE;
1014
1015 /* Save the info structure */
1016 player->info = info;
1017
1018 /* Get the PCM_CLK_SEL bit from audio-glue-ctrl SoC register */
1019 if (uni_player_parse_dt_clk_glue(pdev, player))
1020 return -EINVAL;
1021
1022 return 0;
1023}
1024
1025static const struct snd_soc_dai_ops uni_player_dai_ops = {
1026 .startup = uni_player_startup,
1027 .shutdown = uni_player_shutdown,
1028 .prepare = uni_player_prepare,
1029 .trigger = uni_player_trigger,
1030 .hw_params = sti_uniperiph_dai_hw_params,
1031 .set_fmt = sti_uniperiph_dai_set_fmt,
1032 .set_sysclk = uni_player_set_sysclk
1033};
1034
1035int uni_player_init(struct platform_device *pdev,
1036 struct uniperif *player)
1037{
1038 int ret = 0;
1039
1040 player->dev = &pdev->dev;
1041 player->state = UNIPERIF_STATE_STOPPED;
1042 player->hw = &uni_player_pcm_hw;
1043 player->dai_ops = &uni_player_dai_ops;
1044
1045 ret = uni_player_parse_dt(pdev, player);
1046
1047 if (ret < 0) {
1048 dev_err(player->dev, "Failed to parse DeviceTree");
1049 return ret;
1050 }
1051
1052 /* Get uniperif resource */
1053 player->clk = of_clk_get(pdev->dev.of_node, 0);
1054 if (IS_ERR(player->clk))
1055 ret = PTR_ERR(player->clk);
1056
1057 /* Select the frequency synthesizer clock */
1058 if (player->clk_sel) {
1059 ret = regmap_field_write(player->clk_sel, 1);
1060 if (ret) {
1061 dev_err(player->dev,
1062 "%s: Failed to select freq synth clock",
1063 __func__);
1064 return ret;
1065 }
1066 }
1067
1068 ret = devm_request_irq(&pdev->dev, player->irq,
1069 uni_player_irq_handler, IRQF_SHARED,
1070 dev_name(&pdev->dev), player);
1071 if (ret < 0)
1072 return ret;
1073
1074 mutex_init(&player->ctrl_lock);
1075
1076 /* Ensure that disabled by default */
1077 SET_UNIPERIF_CONFIG_BACK_STALL_REQ_DISABLE(player);
1078 SET_UNIPERIF_CTRL_ROUNDING_OFF(player);
1079 SET_UNIPERIF_CTRL_SPDIF_LAT_OFF(player);
1080 SET_UNIPERIF_CONFIG_IDLE_MOD_DISABLE(player);
1081
1082 if (UNIPERIF_PLAYER_TYPE_IS_IEC958(player)) {
1083 /* Set default iec958 status bits */
1084
1085 /* Consumer, PCM, copyright, 2ch, mode 0 */
1086 player->stream_settings.iec958.status[0] = 0x00;
1087 /* Broadcast reception category */
1088 player->stream_settings.iec958.status[1] =
1089 IEC958_AES1_CON_GENERAL;
1090 /* Do not take into account source or channel number */
1091 player->stream_settings.iec958.status[2] =
1092 IEC958_AES2_CON_SOURCE_UNSPEC;
1093 /* Sampling frequency not indicated */
1094 player->stream_settings.iec958.status[3] =
1095 IEC958_AES3_CON_FS_NOTID;
1096 /* Max sample word 24-bit, sample word length not indicated */
1097 player->stream_settings.iec958.status[4] =
1098 IEC958_AES4_CON_MAX_WORDLEN_24 |
1099 IEC958_AES4_CON_WORDLEN_24_20;
1100
1101 player->num_ctrls = ARRAY_SIZE(snd_sti_iec_ctl);
1102 player->snd_ctrls = snd_sti_iec_ctl[0];
1103 } else {
1104 player->num_ctrls = ARRAY_SIZE(snd_sti_pcm_ctl);
1105 player->snd_ctrls = snd_sti_pcm_ctl[0];
1106 }
1107
1108 return 0;
1109}
1110EXPORT_SYMBOL_GPL(uni_player_init);
diff --git a/sound/soc/sti/uniperif_reader.c b/sound/soc/sti/uniperif_reader.c
new file mode 100644
index 000000000000..c502626f339b
--- /dev/null
+++ b/sound/soc/sti/uniperif_reader.c
@@ -0,0 +1,362 @@
1/*
2 * Copyright (C) STMicroelectronics SA 2015
3 * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com>
4 * for STMicroelectronics.
5 * License terms: GNU General Public License (GPL), version 2
6 */
7
8#include <linux/clk.h>
9#include <linux/delay.h>
10#include <linux/io.h>
11
12#include <sound/soc.h>
13
14#include "uniperif.h"
15
16/*
17 * Note: snd_pcm_hardware is linked to DMA controller but is declared here to
18 * integrate unireader capability in term of rate and supported channels
19 */
20static const struct snd_pcm_hardware uni_reader_pcm_hw = {
21 .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
22 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP |
23 SNDRV_PCM_INFO_MMAP_VALID,
24 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE,
25
26 .rates = SNDRV_PCM_RATE_CONTINUOUS,
27 .rate_min = 8000,
28 .rate_max = 96000,
29
30 .channels_min = 2,
31 .channels_max = 8,
32
33 .periods_min = 2,
34 .periods_max = 48,
35
36 .period_bytes_min = 128,
37 .period_bytes_max = 64 * PAGE_SIZE,
38 .buffer_bytes_max = 256 * PAGE_SIZE
39};
40
41/*
42 * uni_reader_irq_handler
43 * In case of error audio stream is stopped; stop action is protected via PCM
44 * stream lock to avoid race condition with trigger callback.
45 */
46static irqreturn_t uni_reader_irq_handler(int irq, void *dev_id)
47{
48 irqreturn_t ret = IRQ_NONE;
49 struct uniperif *reader = dev_id;
50 unsigned int status;
51
52 if (reader->state == UNIPERIF_STATE_STOPPED) {
53 /* Unexpected IRQ: do nothing */
54 dev_warn(reader->dev, "unexpected IRQ ");
55 return IRQ_HANDLED;
56 }
57
58 /* Get interrupt status & clear them immediately */
59 status = GET_UNIPERIF_ITS(reader);
60 SET_UNIPERIF_ITS_BCLR(reader, status);
61
62 /* Check for fifo overflow error */
63 if (unlikely(status & UNIPERIF_ITS_FIFO_ERROR_MASK(reader))) {
64 dev_err(reader->dev, "FIFO error detected");
65
66 snd_pcm_stream_lock(reader->substream);
67 snd_pcm_stop(reader->substream, SNDRV_PCM_STATE_XRUN);
68 snd_pcm_stream_unlock(reader->substream);
69
70 return IRQ_HANDLED;
71 }
72
73 return ret;
74}
75
76static int uni_reader_prepare(struct snd_pcm_substream *substream,
77 struct snd_soc_dai *dai)
78{
79 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
80 struct uniperif *reader = priv->dai_data.uni;
81 struct snd_pcm_runtime *runtime = substream->runtime;
82 int transfer_size, trigger_limit;
83 int slot_width;
84 int count = 10;
85
86 /* The reader should be stopped */
87 if (reader->state != UNIPERIF_STATE_STOPPED) {
88 dev_err(reader->dev, "%s: invalid reader state %d", __func__,
89 reader->state);
90 return -EINVAL;
91 }
92
93 /* Calculate transfer size (in fifo cells and bytes) for frame count */
94 transfer_size = runtime->channels * UNIPERIF_FIFO_FRAMES;
95
96 /* Calculate number of empty cells available before asserting DREQ */
97 if (reader->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
98 trigger_limit = UNIPERIF_FIFO_SIZE - transfer_size;
99 else
100 /*
101 * Since SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0
102 * FDMA_TRIGGER_LIMIT also controls when the state switches
103 * from OFF or STANDBY to AUDIO DATA.
104 */
105 trigger_limit = transfer_size;
106
107 /* Trigger limit must be an even number */
108 if ((!trigger_limit % 2) ||
109 (trigger_limit != 1 && transfer_size % 2) ||
110 (trigger_limit > UNIPERIF_CONFIG_DMA_TRIG_LIMIT_MASK(reader))) {
111 dev_err(reader->dev, "invalid trigger limit %d", trigger_limit);
112 return -EINVAL;
113 }
114
115 SET_UNIPERIF_CONFIG_DMA_TRIG_LIMIT(reader, trigger_limit);
116
117 switch (reader->daifmt & SND_SOC_DAIFMT_INV_MASK) {
118 case SND_SOC_DAIFMT_IB_IF:
119 case SND_SOC_DAIFMT_NB_IF:
120 SET_UNIPERIF_I2S_FMT_LR_POL_HIG(reader);
121 break;
122 default:
123 SET_UNIPERIF_I2S_FMT_LR_POL_LOW(reader);
124 }
125
126 /* Force slot width to 32 in I2S mode */
127 if ((reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK)
128 == SND_SOC_DAIFMT_I2S) {
129 slot_width = 32;
130 } else {
131 switch (runtime->format) {
132 case SNDRV_PCM_FORMAT_S16_LE:
133 slot_width = 16;
134 break;
135 default:
136 slot_width = 32;
137 break;
138 }
139 }
140
141 /* Number of bits per subframe (i.e one channel sample) on input. */
142 switch (slot_width) {
143 case 32:
144 SET_UNIPERIF_I2S_FMT_NBIT_32(reader);
145 SET_UNIPERIF_I2S_FMT_DATA_SIZE_32(reader);
146 break;
147 case 16:
148 SET_UNIPERIF_I2S_FMT_NBIT_16(reader);
149 SET_UNIPERIF_I2S_FMT_DATA_SIZE_16(reader);
150 break;
151 default:
152 dev_err(reader->dev, "subframe format not supported");
153 return -EINVAL;
154 }
155
156 /* Configure data memory format */
157 switch (runtime->format) {
158 case SNDRV_PCM_FORMAT_S16_LE:
159 /* One data word contains two samples */
160 SET_UNIPERIF_CONFIG_MEM_FMT_16_16(reader);
161 break;
162
163 case SNDRV_PCM_FORMAT_S32_LE:
164 /*
165 * Actually "16 bits/0 bits" means "32/28/24/20/18/16 bits
166 * on the MSB then zeros (if less than 32 bytes)"...
167 */
168 SET_UNIPERIF_CONFIG_MEM_FMT_16_0(reader);
169 break;
170
171 default:
172 dev_err(reader->dev, "format not supported");
173 return -EINVAL;
174 }
175
176 switch (reader->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) {
177 case SND_SOC_DAIFMT_I2S:
178 SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
179 SET_UNIPERIF_I2S_FMT_PADDING_I2S_MODE(reader);
180 break;
181 case SND_SOC_DAIFMT_LEFT_J:
182 SET_UNIPERIF_I2S_FMT_ALIGN_LEFT(reader);
183 SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
184 break;
185 case SND_SOC_DAIFMT_RIGHT_J:
186 SET_UNIPERIF_I2S_FMT_ALIGN_RIGHT(reader);
187 SET_UNIPERIF_I2S_FMT_PADDING_SONY_MODE(reader);
188 break;
189 default:
190 dev_err(reader->dev, "format not supported");
191 return -EINVAL;
192 }
193
194 SET_UNIPERIF_I2S_FMT_ORDER_MSB(reader);
195
196 /* Data clocking (changing) on the rising edge */
197 SET_UNIPERIF_I2S_FMT_SCLK_EDGE_RISING(reader);
198
199 /* Number of channels must be even */
200
201 if ((runtime->channels % 2) || (runtime->channels < 2) ||
202 (runtime->channels > 10)) {
203 dev_err(reader->dev, "%s: invalid nb of channels", __func__);
204 return -EINVAL;
205 }
206
207 SET_UNIPERIF_I2S_FMT_NUM_CH(reader, runtime->channels / 2);
208
209 /* Clear any pending interrupts */
210 SET_UNIPERIF_ITS_BCLR(reader, GET_UNIPERIF_ITS(reader));
211
212 SET_UNIPERIF_I2S_FMT_NO_OF_SAMPLES_TO_READ(reader, 0);
213
214 /* Set the interrupt mask */
215 SET_UNIPERIF_ITM_BSET_DMA_ERROR(reader);
216 SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
217 SET_UNIPERIF_ITM_BSET_MEM_BLK_READ(reader);
218
219 /* Enable underflow recovery interrupts */
220 if (reader->info->underflow_enabled) {
221 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_DONE(reader);
222 SET_UNIPERIF_ITM_BSET_UNDERFLOW_REC_FAILED(reader);
223 }
224
225 /* Reset uniperipheral reader */
226 SET_UNIPERIF_SOFT_RST_SOFT_RST(reader);
227
228 while (GET_UNIPERIF_SOFT_RST_SOFT_RST(reader)) {
229 udelay(5);
230 count--;
231 }
232 if (!count) {
233 dev_err(reader->dev, "Failed to reset uniperif");
234 return -EIO;
235 }
236
237 return 0;
238}
239
240static int uni_reader_start(struct uniperif *reader)
241{
242 /* The reader should be stopped */
243 if (reader->state != UNIPERIF_STATE_STOPPED) {
244 dev_err(reader->dev, "%s: invalid reader state", __func__);
245 return -EINVAL;
246 }
247
248 /* Enable reader interrupts (and clear possible stalled ones) */
249 SET_UNIPERIF_ITS_BCLR_FIFO_ERROR(reader);
250 SET_UNIPERIF_ITM_BSET_FIFO_ERROR(reader);
251
252 /* Launch the reader */
253 SET_UNIPERIF_CTRL_OPERATION_PCM_DATA(reader);
254
255 /* Update state to started */
256 reader->state = UNIPERIF_STATE_STARTED;
257 return 0;
258}
259
260static int uni_reader_stop(struct uniperif *reader)
261{
262 /* The reader should not be in stopped state */
263 if (reader->state == UNIPERIF_STATE_STOPPED) {
264 dev_err(reader->dev, "%s: invalid reader state", __func__);
265 return -EINVAL;
266 }
267
268 /* Turn the reader off */
269 SET_UNIPERIF_CTRL_OPERATION_OFF(reader);
270
271 /* Disable interrupts */
272 SET_UNIPERIF_ITM_BCLR(reader, GET_UNIPERIF_ITM(reader));
273
274 /* Update state to stopped and return */
275 reader->state = UNIPERIF_STATE_STOPPED;
276
277 return 0;
278}
279
280static int uni_reader_trigger(struct snd_pcm_substream *substream,
281 int cmd, struct snd_soc_dai *dai)
282{
283 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
284 struct uniperif *reader = priv->dai_data.uni;
285
286 switch (cmd) {
287 case SNDRV_PCM_TRIGGER_START:
288 return uni_reader_start(reader);
289 case SNDRV_PCM_TRIGGER_STOP:
290 return uni_reader_stop(reader);
291 default:
292 return -EINVAL;
293 }
294}
295
296static void uni_reader_shutdown(struct snd_pcm_substream *substream,
297 struct snd_soc_dai *dai)
298{
299 struct sti_uniperiph_data *priv = snd_soc_dai_get_drvdata(dai);
300 struct uniperif *reader = priv->dai_data.uni;
301
302 if (reader->state != UNIPERIF_STATE_STOPPED) {
303 /* Stop the reader */
304 uni_reader_stop(reader);
305 }
306}
307
308static int uni_reader_parse_dt(struct platform_device *pdev,
309 struct uniperif *reader)
310{
311 struct uniperif_info *info;
312 struct device_node *node = pdev->dev.of_node;
313
314 /* Allocate memory for the info structure */
315 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
316 if (!info)
317 return -ENOMEM;
318
319 of_property_read_u32(node, "version", &reader->ver);
320
321 /* Save the info structure */
322 reader->info = info;
323
324 return 0;
325}
326
327static const struct snd_soc_dai_ops uni_reader_dai_ops = {
328 .shutdown = uni_reader_shutdown,
329 .prepare = uni_reader_prepare,
330 .trigger = uni_reader_trigger,
331 .hw_params = sti_uniperiph_dai_hw_params,
332 .set_fmt = sti_uniperiph_dai_set_fmt,
333};
334
335int uni_reader_init(struct platform_device *pdev,
336 struct uniperif *reader)
337{
338 int ret = 0;
339
340 reader->dev = &pdev->dev;
341 reader->state = UNIPERIF_STATE_STOPPED;
342 reader->hw = &uni_reader_pcm_hw;
343 reader->dai_ops = &uni_reader_dai_ops;
344
345 dev_err(reader->dev, "%s: enter\n", __func__);
346 ret = uni_reader_parse_dt(pdev, reader);
347 if (ret < 0) {
348 dev_err(reader->dev, "Failed to parse DeviceTree");
349 return ret;
350 }
351
352 ret = devm_request_irq(&pdev->dev, reader->irq,
353 uni_reader_irq_handler, IRQF_SHARED,
354 dev_name(&pdev->dev), reader);
355 if (ret < 0) {
356 dev_err(&pdev->dev, "Failed to request IRQ");
357 return -EBUSY;
358 }
359
360 return 0;
361}
362EXPORT_SYMBOL_GPL(uni_reader_init);