aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/codecs/rt286.c25
-rw-r--r--sound/soc/omap/Kconfig2
-rw-r--r--sound/soc/omap/n810.c23
-rw-r--r--sound/soc/omap/omap-hdmi-audio.c2
-rw-r--r--sound/soc/qcom/Kconfig25
-rw-r--r--sound/soc/qcom/Makefile11
-rw-r--r--sound/soc/qcom/lpass-cpu.c491
-rw-r--r--sound/soc/qcom/lpass-lpaif-ipq806x.h172
-rw-r--r--sound/soc/qcom/lpass-platform.c526
-rw-r--r--sound/soc/qcom/lpass.h51
-rw-r--r--sound/soc/qcom/storm.c162
-rw-r--r--sound/soc/sh/Kconfig6
-rw-r--r--sound/soc/sh/rcar/Makefile7
-rw-r--r--sound/soc/sh/rcar/adg.c4
-rw-r--r--sound/soc/sh/rcar/core.c262
-rw-r--r--sound/soc/sh/rcar/dma.c616
-rw-r--r--sound/soc/sh/rcar/dvc.c28
-rw-r--r--sound/soc/sh/rcar/gen.c152
-rw-r--r--sound/soc/sh/rcar/rsnd.h81
-rw-r--r--sound/soc/sh/rcar/rsrc-card.c512
-rw-r--r--sound/soc/sh/rcar/src.c233
-rw-r--r--sound/soc/sh/rcar/ssi.c56
24 files changed, 2935 insertions, 514 deletions
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index dcc79aa0236b..3ba52da18bc6 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -47,6 +47,7 @@ source "sound/soc/kirkwood/Kconfig"
47source "sound/soc/intel/Kconfig" 47source "sound/soc/intel/Kconfig"
48source "sound/soc/mxs/Kconfig" 48source "sound/soc/mxs/Kconfig"
49source "sound/soc/pxa/Kconfig" 49source "sound/soc/pxa/Kconfig"
50source "sound/soc/qcom/Kconfig"
50source "sound/soc/rockchip/Kconfig" 51source "sound/soc/rockchip/Kconfig"
51source "sound/soc/samsung/Kconfig" 52source "sound/soc/samsung/Kconfig"
52source "sound/soc/sh/Kconfig" 53source "sound/soc/sh/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 5b3c8f67c8db..974ba708b482 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
28obj-$(CONFIG_SND_SOC) += omap/ 28obj-$(CONFIG_SND_SOC) += omap/
29obj-$(CONFIG_SND_SOC) += kirkwood/ 29obj-$(CONFIG_SND_SOC) += kirkwood/
30obj-$(CONFIG_SND_SOC) += pxa/ 30obj-$(CONFIG_SND_SOC) += pxa/
31obj-$(CONFIG_SND_SOC) += qcom/
31obj-$(CONFIG_SND_SOC) += rockchip/ 32obj-$(CONFIG_SND_SOC) += rockchip/
32obj-$(CONFIG_SND_SOC) += samsung/ 33obj-$(CONFIG_SND_SOC) += samsung/
33obj-$(CONFIG_SND_SOC) += sh/ 34obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 826037090c83..0fcda35a3a93 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -397,7 +397,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
397 397
398 if (jack) { 398 if (jack) {
399 /* enable IRQ */ 399 /* enable IRQ */
400 if (rt286->jack->status | SND_JACK_HEADPHONE) 400 if (rt286->jack->status & SND_JACK_HEADPHONE)
401 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1"); 401 snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1");
402 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2); 402 regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
403 /* Send an initial empty report */ 403 /* Send an initial empty report */
@@ -1048,7 +1048,6 @@ static int rt286_probe(struct snd_soc_codec *codec)
1048 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); 1048 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
1049 1049
1050 rt286->codec = codec; 1050 rt286->codec = codec;
1051 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1052 1051
1053 if (rt286->i2c->irq) { 1052 if (rt286->i2c->irq) {
1054 regmap_update_bits(rt286->regmap, 1053 regmap_update_bits(rt286->regmap,
@@ -1220,7 +1219,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1220{ 1219{
1221 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev); 1220 struct rt286_platform_data *pdata = dev_get_platdata(&i2c->dev);
1222 struct rt286_priv *rt286; 1221 struct rt286_priv *rt286;
1223 int i, ret; 1222 int i, ret, val;
1224 1223
1225 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286), 1224 rt286 = devm_kzalloc(&i2c->dev, sizeof(*rt286),
1226 GFP_KERNEL); 1225 GFP_KERNEL);
@@ -1235,11 +1234,15 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1235 return ret; 1234 return ret;
1236 } 1235 }
1237 1236
1238 regmap_read(rt286->regmap, 1237 ret = regmap_read(rt286->regmap,
1239 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); 1238 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &val);
1240 if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) { 1239 if (ret != 0) {
1240 dev_err(&i2c->dev, "I2C error %d\n", ret);
1241 return ret;
1242 }
1243 if (val != RT286_VENDOR_ID && val != RT288_VENDOR_ID) {
1241 dev_err(&i2c->dev, 1244 dev_err(&i2c->dev,
1242 "Device with ID register %x is not rt286\n", ret); 1245 "Device with ID register %x is not rt286\n", val);
1243 return -ENODEV; 1246 return -ENODEV;
1244 } 1247 }
1245 1248
@@ -1247,6 +1250,14 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1247 rt286->i2c = i2c; 1250 rt286->i2c = i2c;
1248 i2c_set_clientdata(i2c, rt286); 1251 i2c_set_clientdata(i2c, rt286);
1249 1252
1253 /* restore codec default */
1254 for (i = 0; i < INDEX_CACHE_SIZE; i++)
1255 regmap_write(rt286->regmap, rt286->index_cache[i].reg,
1256 rt286->index_cache[i].def);
1257 for (i = 0; i < ARRAY_SIZE(rt286_reg); i++)
1258 regmap_write(rt286->regmap, rt286_reg[i].reg,
1259 rt286_reg[i].def);
1260
1250 if (pdata) 1261 if (pdata)
1251 rt286->pdata = *pdata; 1262 rt286->pdata = *pdata;
1252 1263
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index e7c78b0406b5..6768e4f7d7d0 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -105,7 +105,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
105 select SND_OMAP_SOC_MCPDM 105 select SND_OMAP_SOC_MCPDM
106 select SND_SOC_TWL6040 106 select SND_SOC_TWL6040
107 select SND_SOC_DMIC 107 select SND_SOC_DMIC
108 select COMMON_CLK_PALMAS if SOC_OMAP5 108 select COMMON_CLK_PALMAS if MFD_PALMAS
109 help 109 help
110 Say Y if you want to add support for SoC audio on OMAP boards using 110 Say Y if you want to add support for SoC audio on OMAP boards using
111 ABE and twl6040 codec. This driver currently supports: 111 ABE and twl6040 codec. This driver currently supports:
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 5d7f9cebe041..dcb5336b5698 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -98,12 +98,11 @@ static int n810_startup(struct snd_pcm_substream *substream)
98{ 98{
99 struct snd_pcm_runtime *runtime = substream->runtime; 99 struct snd_pcm_runtime *runtime = substream->runtime;
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct snd_soc_codec *codec = rtd->codec;
102 101
103 snd_pcm_hw_constraint_minmax(runtime, 102 snd_pcm_hw_constraint_minmax(runtime,
104 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 103 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
105 104
106 n810_ext_control(&codec->dapm); 105 n810_ext_control(&rtd->card->dapm);
107 return clk_prepare_enable(sys_clkout2); 106 return clk_prepare_enable(sys_clkout2);
108} 107}
109 108
@@ -255,24 +254,6 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
255 n810_get_input, n810_set_input), 254 n810_get_input, n810_set_input),
256}; 255};
257 256
258static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
259{
260 struct snd_soc_codec *codec = rtd->codec;
261 struct snd_soc_dapm_context *dapm = &codec->dapm;
262
263 /* Not connected */
264 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
265 snd_soc_dapm_nc_pin(dapm, "HPLCOM");
266 snd_soc_dapm_nc_pin(dapm, "HPRCOM");
267 snd_soc_dapm_nc_pin(dapm, "MIC3L");
268 snd_soc_dapm_nc_pin(dapm, "MIC3R");
269 snd_soc_dapm_nc_pin(dapm, "LINE1R");
270 snd_soc_dapm_nc_pin(dapm, "LINE2L");
271 snd_soc_dapm_nc_pin(dapm, "LINE2R");
272
273 return 0;
274}
275
276/* Digital audio interface glue - connects codec <--> CPU */ 257/* Digital audio interface glue - connects codec <--> CPU */
277static struct snd_soc_dai_link n810_dai = { 258static struct snd_soc_dai_link n810_dai = {
278 .name = "TLV320AIC33", 259 .name = "TLV320AIC33",
@@ -283,7 +264,6 @@ static struct snd_soc_dai_link n810_dai = {
283 .codec_dai_name = "tlv320aic3x-hifi", 264 .codec_dai_name = "tlv320aic3x-hifi",
284 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 265 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
285 SND_SOC_DAIFMT_CBM_CFM, 266 SND_SOC_DAIFMT_CBM_CFM,
286 .init = n810_aic33_init,
287 .ops = &n810_ops, 267 .ops = &n810_ops,
288}; 268};
289 269
@@ -300,6 +280,7 @@ static struct snd_soc_card snd_soc_n810 = {
300 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets), 280 .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets),
301 .dapm_routes = audio_map, 281 .dapm_routes = audio_map,
302 .num_dapm_routes = ARRAY_SIZE(audio_map), 282 .num_dapm_routes = ARRAY_SIZE(audio_map),
283 .fully_routed = true,
303}; 284};
304 285
305static struct platform_device *n810_snd_device; 286static struct platform_device *n810_snd_device;
diff --git a/sound/soc/omap/omap-hdmi-audio.c b/sound/soc/omap/omap-hdmi-audio.c
index f7eb42aa3f38..4775da4c4db5 100644
--- a/sound/soc/omap/omap-hdmi-audio.c
+++ b/sound/soc/omap/omap-hdmi-audio.c
@@ -142,8 +142,6 @@ static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
142 142
143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE; 143 iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
144 144
145 iec->status[0] |= IEC958_AES1_PRO_MODE_NOTID;
146
147 iec->status[1] = IEC958_AES1_CON_GENERAL; 145 iec->status[1] = IEC958_AES1_CON_GENERAL;
148 146
149 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC; 147 iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
new file mode 100644
index 000000000000..5f58e4f1bca9
--- /dev/null
+++ b/sound/soc/qcom/Kconfig
@@ -0,0 +1,25 @@
1config SND_SOC_QCOM
2 tristate "ASoC support for QCOM platforms"
3 help
4 Say Y or M if you want to add support to use audio devices
5 in Qualcomm Technologies SOC-based platforms.
6
7config SND_SOC_LPASS_CPU
8 tristate
9 depends on SND_SOC_QCOM
10 select REGMAP_MMIO
11
12config SND_SOC_LPASS_PLATFORM
13 tristate
14 depends on SND_SOC_QCOM
15 select REGMAP_MMIO
16
17config SND_SOC_STORM
18 tristate "ASoC I2S support for Storm boards"
19 depends on (ARCH_QCOM && SND_SOC_QCOM) || COMPILE_TEST
20 select SND_SOC_LPASS_CPU
21 select SND_SOC_LPASS_PLATFORM
22 select SND_SOC_MAX98357A
23 help
24 Say Y or M if you want add support for SoC audio on the
25 Qualcomm Technologies IPQ806X-based Storm board.
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
new file mode 100644
index 000000000000..c5ce96c761c4
--- /dev/null
+++ b/sound/soc/qcom/Makefile
@@ -0,0 +1,11 @@
1# Platform
2snd-soc-lpass-cpu-objs := lpass-cpu.o
3snd-soc-lpass-platform-objs := lpass-platform.o
4
5obj-$(CONFIG_SND_SOC_LPASS_CPU) += snd-soc-lpass-cpu.o
6obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) += snd-soc-lpass-platform.o
7
8# Machine
9snd-soc-storm-objs := storm.o
10
11obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
new file mode 100644
index 000000000000..6698d058de29
--- /dev/null
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -0,0 +1,491 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-cpu.c -- ALSA SoC CPU DAI driver for QTi LPASS
14 */
15
16#include <linux/clk.h>
17#include <linux/compiler.h>
18#include <linux/device.h>
19#include <linux/err.h>
20#include <linux/ioport.h>
21#include <linux/kernel.h>
22#include <linux/mod_devicetable.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/platform_device.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include <sound/soc-dai.h>
31#include "lpass-lpaif-ipq806x.h"
32#include "lpass.h"
33
34static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
35 unsigned int freq, int dir)
36{
37 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
38 int ret;
39
40 ret = clk_set_rate(drvdata->mi2s_osr_clk, freq);
41 if (ret)
42 dev_err(dai->dev, "%s() error setting mi2s osrclk to %u: %d\n",
43 __func__, freq, ret);
44
45 return ret;
46}
47
48static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
49 struct snd_soc_dai *dai)
50{
51 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
52 int ret;
53
54 ret = clk_prepare_enable(drvdata->mi2s_osr_clk);
55 if (ret) {
56 dev_err(dai->dev, "%s() error in enabling mi2s osr clk: %d\n",
57 __func__, ret);
58 return ret;
59 }
60
61 ret = clk_prepare_enable(drvdata->mi2s_bit_clk);
62 if (ret) {
63 dev_err(dai->dev, "%s() error in enabling mi2s bit clk: %d\n",
64 __func__, ret);
65 clk_disable_unprepare(drvdata->mi2s_osr_clk);
66 return ret;
67 }
68
69 return 0;
70}
71
72static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
73 struct snd_soc_dai *dai)
74{
75 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
76
77 clk_disable_unprepare(drvdata->mi2s_bit_clk);
78 clk_disable_unprepare(drvdata->mi2s_osr_clk);
79}
80
81static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
82 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
83{
84 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
85 snd_pcm_format_t format = params_format(params);
86 unsigned int channels = params_channels(params);
87 unsigned int rate = params_rate(params);
88 unsigned int regval;
89 int bitwidth, ret;
90
91 bitwidth = snd_pcm_format_width(format);
92 if (bitwidth < 0) {
93 dev_err(dai->dev, "%s() invalid bit width given: %d\n",
94 __func__, bitwidth);
95 return bitwidth;
96 }
97
98 regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
99 LPAIF_I2SCTL_WSSRC_INTERNAL;
100
101 switch (bitwidth) {
102 case 16:
103 regval |= LPAIF_I2SCTL_BITWIDTH_16;
104 break;
105 case 24:
106 regval |= LPAIF_I2SCTL_BITWIDTH_24;
107 break;
108 case 32:
109 regval |= LPAIF_I2SCTL_BITWIDTH_32;
110 break;
111 default:
112 dev_err(dai->dev, "%s() invalid bitwidth given: %d\n",
113 __func__, bitwidth);
114 return -EINVAL;
115 }
116
117 switch (channels) {
118 case 1:
119 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
120 regval |= LPAIF_I2SCTL_SPKMONO_MONO;
121 break;
122 case 2:
123 regval |= LPAIF_I2SCTL_SPKMODE_SD0;
124 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
125 break;
126 case 4:
127 regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
128 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
129 break;
130 case 6:
131 regval |= LPAIF_I2SCTL_SPKMODE_6CH;
132 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
133 break;
134 case 8:
135 regval |= LPAIF_I2SCTL_SPKMODE_8CH;
136 regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
137 break;
138 default:
139 dev_err(dai->dev, "%s() invalid channels given: %u\n",
140 __func__, channels);
141 return -EINVAL;
142 }
143
144 ret = regmap_write(drvdata->lpaif_map,
145 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), regval);
146 if (ret) {
147 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
148 __func__, ret);
149 return ret;
150 }
151
152 ret = clk_set_rate(drvdata->mi2s_bit_clk, rate * bitwidth * 2);
153 if (ret) {
154 dev_err(dai->dev, "%s() error setting mi2s bitclk to %u: %d\n",
155 __func__, rate * bitwidth * 2, ret);
156 return ret;
157 }
158
159 return 0;
160}
161
162static int lpass_cpu_daiops_hw_free(struct snd_pcm_substream *substream,
163 struct snd_soc_dai *dai)
164{
165 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
166 int ret;
167
168 ret = regmap_write(drvdata->lpaif_map,
169 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
170 if (ret)
171 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
172 __func__, ret);
173
174 return ret;
175}
176
177static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
178 struct snd_soc_dai *dai)
179{
180 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
181 int ret;
182
183 ret = regmap_update_bits(drvdata->lpaif_map,
184 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
185 LPAIF_I2SCTL_SPKEN_MASK, LPAIF_I2SCTL_SPKEN_ENABLE);
186 if (ret)
187 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
188 __func__, ret);
189
190 return ret;
191}
192
193static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
194 int cmd, struct snd_soc_dai *dai)
195{
196 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
197 int ret;
198
199 switch (cmd) {
200 case SNDRV_PCM_TRIGGER_START:
201 case SNDRV_PCM_TRIGGER_RESUME:
202 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
203 ret = regmap_update_bits(drvdata->lpaif_map,
204 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
205 LPAIF_I2SCTL_SPKEN_MASK,
206 LPAIF_I2SCTL_SPKEN_ENABLE);
207 if (ret)
208 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
209 __func__, ret);
210 break;
211 case SNDRV_PCM_TRIGGER_STOP:
212 case SNDRV_PCM_TRIGGER_SUSPEND:
213 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
214 ret = regmap_update_bits(drvdata->lpaif_map,
215 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S),
216 LPAIF_I2SCTL_SPKEN_MASK,
217 LPAIF_I2SCTL_SPKEN_DISABLE);
218 if (ret)
219 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
220 __func__, ret);
221 break;
222 }
223
224 return ret;
225}
226
227static struct snd_soc_dai_ops lpass_cpu_dai_ops = {
228 .set_sysclk = lpass_cpu_daiops_set_sysclk,
229 .startup = lpass_cpu_daiops_startup,
230 .shutdown = lpass_cpu_daiops_shutdown,
231 .hw_params = lpass_cpu_daiops_hw_params,
232 .hw_free = lpass_cpu_daiops_hw_free,
233 .prepare = lpass_cpu_daiops_prepare,
234 .trigger = lpass_cpu_daiops_trigger,
235};
236
237static int lpass_cpu_dai_probe(struct snd_soc_dai *dai)
238{
239 struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
240 int ret;
241
242 /* ensure audio hardware is disabled */
243 ret = regmap_write(drvdata->lpaif_map,
244 LPAIF_I2SCTL_REG(LPAIF_I2S_PORT_MI2S), 0);
245 if (ret)
246 dev_err(dai->dev, "%s() error writing to i2sctl reg: %d\n",
247 __func__, ret);
248
249 return ret;
250}
251
252static struct snd_soc_dai_driver lpass_cpu_dai_driver = {
253 .playback = {
254 .stream_name = "lpass-cpu-playback",
255 .formats = SNDRV_PCM_FMTBIT_S16 |
256 SNDRV_PCM_FMTBIT_S24 |
257 SNDRV_PCM_FMTBIT_S32,
258 .rates = SNDRV_PCM_RATE_8000 |
259 SNDRV_PCM_RATE_16000 |
260 SNDRV_PCM_RATE_32000 |
261 SNDRV_PCM_RATE_48000 |
262 SNDRV_PCM_RATE_96000,
263 .rate_min = 8000,
264 .rate_max = 96000,
265 .channels_min = 1,
266 .channels_max = 8,
267 },
268 .probe = &lpass_cpu_dai_probe,
269 .ops = &lpass_cpu_dai_ops,
270};
271
272static const struct snd_soc_component_driver lpass_cpu_comp_driver = {
273 .name = "lpass-cpu",
274};
275
276static bool lpass_cpu_regmap_writeable(struct device *dev, unsigned int reg)
277{
278 int i;
279
280 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
281 if (reg == LPAIF_I2SCTL_REG(i))
282 return true;
283
284 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
285 if (reg == LPAIF_IRQEN_REG(i))
286 return true;
287 if (reg == LPAIF_IRQCLEAR_REG(i))
288 return true;
289 }
290
291 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
292 if (reg == LPAIF_RDMACTL_REG(i))
293 return true;
294 if (reg == LPAIF_RDMABASE_REG(i))
295 return true;
296 if (reg == LPAIF_RDMABUFF_REG(i))
297 return true;
298 if (reg == LPAIF_RDMAPER_REG(i))
299 return true;
300 }
301
302 return false;
303}
304
305static bool lpass_cpu_regmap_readable(struct device *dev, unsigned int reg)
306{
307 int i;
308
309 for (i = 0; i < LPAIF_I2S_PORT_NUM; ++i)
310 if (reg == LPAIF_I2SCTL_REG(i))
311 return true;
312
313 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i) {
314 if (reg == LPAIF_IRQEN_REG(i))
315 return true;
316 if (reg == LPAIF_IRQSTAT_REG(i))
317 return true;
318 }
319
320 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i) {
321 if (reg == LPAIF_RDMACTL_REG(i))
322 return true;
323 if (reg == LPAIF_RDMABASE_REG(i))
324 return true;
325 if (reg == LPAIF_RDMABUFF_REG(i))
326 return true;
327 if (reg == LPAIF_RDMACURR_REG(i))
328 return true;
329 if (reg == LPAIF_RDMAPER_REG(i))
330 return true;
331 }
332
333 return false;
334}
335
336static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
337{
338 int i;
339
340 for (i = 0; i < LPAIF_IRQ_PORT_NUM; ++i)
341 if (reg == LPAIF_IRQSTAT_REG(i))
342 return true;
343
344 for (i = 0; i < LPAIF_RDMA_CHAN_NUM; ++i)
345 if (reg == LPAIF_RDMACURR_REG(i))
346 return true;
347
348 return false;
349}
350
351static const struct regmap_config lpass_cpu_regmap_config = {
352 .reg_bits = 32,
353 .reg_stride = 4,
354 .val_bits = 32,
355 .max_register = LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MAX),
356 .writeable_reg = lpass_cpu_regmap_writeable,
357 .readable_reg = lpass_cpu_regmap_readable,
358 .volatile_reg = lpass_cpu_regmap_volatile,
359 .cache_type = REGCACHE_FLAT,
360};
361
362static int lpass_cpu_platform_probe(struct platform_device *pdev)
363{
364 struct lpass_data *drvdata;
365 struct device_node *dsp_of_node;
366 struct resource *res;
367 int ret;
368
369 dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
370 if (dsp_of_node) {
371 dev_err(&pdev->dev, "%s() DSP exists and holds audio resources\n",
372 __func__);
373 return -EBUSY;
374 }
375
376 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct lpass_data),
377 GFP_KERNEL);
378 if (!drvdata)
379 return -ENOMEM;
380 platform_set_drvdata(pdev, drvdata);
381
382 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-lpaif");
383 if (!res) {
384 dev_err(&pdev->dev, "%s() error getting resource\n", __func__);
385 return -ENODEV;
386 }
387
388 drvdata->lpaif = devm_ioremap_resource(&pdev->dev, res);
389 if (IS_ERR((void const __force *)drvdata->lpaif)) {
390 dev_err(&pdev->dev, "%s() error mapping reg resource: %ld\n",
391 __func__,
392 PTR_ERR((void const __force *)drvdata->lpaif));
393 return PTR_ERR((void const __force *)drvdata->lpaif);
394 }
395
396 drvdata->lpaif_map = devm_regmap_init_mmio(&pdev->dev, drvdata->lpaif,
397 &lpass_cpu_regmap_config);
398 if (IS_ERR(drvdata->lpaif_map)) {
399 dev_err(&pdev->dev, "%s() error initializing regmap: %ld\n",
400 __func__, PTR_ERR(drvdata->lpaif_map));
401 return PTR_ERR(drvdata->lpaif_map);
402 }
403
404 drvdata->mi2s_osr_clk = devm_clk_get(&pdev->dev, "mi2s-osr-clk");
405 if (IS_ERR(drvdata->mi2s_osr_clk)) {
406 dev_err(&pdev->dev, "%s() error getting mi2s-osr-clk: %ld\n",
407 __func__, PTR_ERR(drvdata->mi2s_osr_clk));
408 return PTR_ERR(drvdata->mi2s_osr_clk);
409 }
410
411 drvdata->mi2s_bit_clk = devm_clk_get(&pdev->dev, "mi2s-bit-clk");
412 if (IS_ERR(drvdata->mi2s_bit_clk)) {
413 dev_err(&pdev->dev, "%s() error getting mi2s-bit-clk: %ld\n",
414 __func__, PTR_ERR(drvdata->mi2s_bit_clk));
415 return PTR_ERR(drvdata->mi2s_bit_clk);
416 }
417
418 drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
419 if (IS_ERR(drvdata->ahbix_clk)) {
420 dev_err(&pdev->dev, "%s() error getting ahbix-clk: %ld\n",
421 __func__, PTR_ERR(drvdata->ahbix_clk));
422 return PTR_ERR(drvdata->ahbix_clk);
423 }
424
425 ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
426 if (ret) {
427 dev_err(&pdev->dev, "%s() error setting rate on ahbix_clk: %d\n",
428 __func__, ret);
429 return ret;
430 }
431 dev_dbg(&pdev->dev, "%s() set ahbix_clk rate to %lu\n", __func__,
432 clk_get_rate(drvdata->ahbix_clk));
433
434 ret = clk_prepare_enable(drvdata->ahbix_clk);
435 if (ret) {
436 dev_err(&pdev->dev, "%s() error enabling ahbix_clk: %d\n",
437 __func__, ret);
438 return ret;
439 }
440
441 ret = devm_snd_soc_register_component(&pdev->dev,
442 &lpass_cpu_comp_driver, &lpass_cpu_dai_driver, 1);
443 if (ret) {
444 dev_err(&pdev->dev, "%s() error registering cpu driver: %d\n",
445 __func__, ret);
446 goto err_clk;
447 }
448
449 ret = asoc_qcom_lpass_platform_register(pdev);
450 if (ret) {
451 dev_err(&pdev->dev, "%s() error registering platform driver: %d\n",
452 __func__, ret);
453 goto err_clk;
454 }
455
456 return 0;
457
458err_clk:
459 clk_disable_unprepare(drvdata->ahbix_clk);
460 return ret;
461}
462
463static int lpass_cpu_platform_remove(struct platform_device *pdev)
464{
465 struct lpass_data *drvdata = platform_get_drvdata(pdev);
466
467 clk_disable_unprepare(drvdata->ahbix_clk);
468
469 return 0;
470}
471
472#ifdef CONFIG_OF
473static const struct of_device_id lpass_cpu_device_id[] = {
474 { .compatible = "qcom,lpass-cpu" },
475 {}
476};
477MODULE_DEVICE_TABLE(of, lpass_cpu_device_id);
478#endif
479
480static struct platform_driver lpass_cpu_platform_driver = {
481 .driver = {
482 .name = "lpass-cpu",
483 .of_match_table = of_match_ptr(lpass_cpu_device_id),
484 },
485 .probe = lpass_cpu_platform_probe,
486 .remove = lpass_cpu_platform_remove,
487};
488module_platform_driver(lpass_cpu_platform_driver);
489
490MODULE_DESCRIPTION("QTi LPASS CPU Driver");
491MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass-lpaif-ipq806x.h b/sound/soc/qcom/lpass-lpaif-ipq806x.h
new file mode 100644
index 000000000000..dc423b888842
--- /dev/null
+++ b/sound/soc/qcom/lpass-lpaif-ipq806x.h
@@ -0,0 +1,172 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-lpaif-ipq806x.h -- Definitions for the QTi LPAIF in the ipq806x LPASS
14 */
15
16#ifndef __LPASS_LPAIF_H__
17#define __LPASS_LPAIF_H__
18
19#define LPAIF_BANK_OFFSET 0x1000
20
21/* LPAIF I2S */
22
23#define LPAIF_I2SCTL_REG_BASE 0x0010
24#define LPAIF_I2SCTL_REG_STRIDE 0x4
25#define LPAIF_I2SCTL_REG_ADDR(addr, port) \
26 (LPAIF_I2SCTL_REG_BASE + (addr) + (LPAIF_I2SCTL_REG_STRIDE * (port)))
27
28enum lpaif_i2s_ports {
29 LPAIF_I2S_PORT_MIN = 0,
30
31 LPAIF_I2S_PORT_CODEC_SPK = 0,
32 LPAIF_I2S_PORT_CODEC_MIC = 1,
33 LPAIF_I2S_PORT_SEC_SPK = 2,
34 LPAIF_I2S_PORT_SEC_MIC = 3,
35 LPAIF_I2S_PORT_MI2S = 4,
36
37 LPAIF_I2S_PORT_MAX = 4,
38 LPAIF_I2S_PORT_NUM = 5,
39};
40
41#define LPAIF_I2SCTL_REG(port) LPAIF_I2SCTL_REG_ADDR(0x0, (port))
42
43#define LPAIF_I2SCTL_LOOPBACK_MASK 0x8000
44#define LPAIF_I2SCTL_LOOPBACK_SHIFT 15
45#define LPAIF_I2SCTL_LOOPBACK_DISABLE (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
46#define LPAIF_I2SCTL_LOOPBACK_ENABLE (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
47
48#define LPAIF_I2SCTL_SPKEN_MASK 0x4000
49#define LPAIF_I2SCTL_SPKEN_SHIFT 14
50#define LPAIF_I2SCTL_SPKEN_DISABLE (0 << LPAIF_I2SCTL_SPKEN_SHIFT)
51#define LPAIF_I2SCTL_SPKEN_ENABLE (1 << LPAIF_I2SCTL_SPKEN_SHIFT)
52
53#define LPAIF_I2SCTL_SPKMODE_MASK 0x3C00
54#define LPAIF_I2SCTL_SPKMODE_SHIFT 10
55#define LPAIF_I2SCTL_SPKMODE_NONE (0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
56#define LPAIF_I2SCTL_SPKMODE_SD0 (1 << LPAIF_I2SCTL_SPKMODE_SHIFT)
57#define LPAIF_I2SCTL_SPKMODE_SD1 (2 << LPAIF_I2SCTL_SPKMODE_SHIFT)
58#define LPAIF_I2SCTL_SPKMODE_SD2 (3 << LPAIF_I2SCTL_SPKMODE_SHIFT)
59#define LPAIF_I2SCTL_SPKMODE_SD3 (4 << LPAIF_I2SCTL_SPKMODE_SHIFT)
60#define LPAIF_I2SCTL_SPKMODE_QUAD01 (5 << LPAIF_I2SCTL_SPKMODE_SHIFT)
61#define LPAIF_I2SCTL_SPKMODE_QUAD23 (6 << LPAIF_I2SCTL_SPKMODE_SHIFT)
62#define LPAIF_I2SCTL_SPKMODE_6CH (7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
63#define LPAIF_I2SCTL_SPKMODE_8CH (8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
64
65#define LPAIF_I2SCTL_SPKMONO_MASK 0x0200
66#define LPAIF_I2SCTL_SPKMONO_SHIFT 9
67#define LPAIF_I2SCTL_SPKMONO_STEREO (0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
68#define LPAIF_I2SCTL_SPKMONO_MONO (1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
69
70#define LPAIF_I2SCTL_WSSRC_MASK 0x0004
71#define LPAIF_I2SCTL_WSSRC_SHIFT 2
72#define LPAIF_I2SCTL_WSSRC_INTERNAL (0 << LPAIF_I2SCTL_WSSRC_SHIFT)
73#define LPAIF_I2SCTL_WSSRC_EXTERNAL (1 << LPAIF_I2SCTL_WSSRC_SHIFT)
74
75#define LPAIF_I2SCTL_BITWIDTH_MASK 0x0003
76#define LPAIF_I2SCTL_BITWIDTH_SHIFT 0
77#define LPAIF_I2SCTL_BITWIDTH_16 (0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
78#define LPAIF_I2SCTL_BITWIDTH_24 (1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
79#define LPAIF_I2SCTL_BITWIDTH_32 (2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
80
81/* LPAIF IRQ */
82
83#define LPAIF_IRQ_REG_BASE 0x3000
84#define LPAIF_IRQ_REG_STRIDE 0x1000
85#define LPAIF_IRQ_REG_ADDR(addr, port) \
86 (LPAIF_IRQ_REG_BASE + (addr) + (LPAIF_IRQ_REG_STRIDE * (port)))
87
88enum lpaif_irq_ports {
89 LPAIF_IRQ_PORT_MIN = 0,
90
91 LPAIF_IRQ_PORT_HOST = 0,
92 LPAIF_IRQ_PORT_ADSP = 1,
93
94 LPAIF_IRQ_PORT_MAX = 2,
95 LPAIF_IRQ_PORT_NUM = 3,
96};
97
98#define LPAIF_IRQEN_REG(port) LPAIF_IRQ_REG_ADDR(0x0, (port))
99#define LPAIF_IRQSTAT_REG(port) LPAIF_IRQ_REG_ADDR(0x4, (port))
100#define LPAIF_IRQCLEAR_REG(port) LPAIF_IRQ_REG_ADDR(0xC, (port))
101
102#define LPAIF_IRQ_BITSTRIDE 3
103#define LPAIF_IRQ_PER(chan) (1 << (LPAIF_IRQ_BITSTRIDE * (chan)))
104#define LPAIF_IRQ_XRUN(chan) (2 << (LPAIF_IRQ_BITSTRIDE * (chan)))
105#define LPAIF_IRQ_ERR(chan) (4 << (LPAIF_IRQ_BITSTRIDE * (chan)))
106#define LPAIF_IRQ_ALL(chan) (7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
107
108/* LPAIF DMA */
109
110#define LPAIF_RDMA_REG_BASE 0x6000
111#define LPAIF_RDMA_REG_STRIDE 0x1000
112#define LPAIF_RDMA_REG_ADDR(addr, chan) \
113 (LPAIF_RDMA_REG_BASE + (addr) + (LPAIF_RDMA_REG_STRIDE * (chan)))
114
115enum lpaif_dma_channels {
116 LPAIF_RDMA_CHAN_MIN = 0,
117
118 LPAIF_RDMA_CHAN_MI2S = 0,
119 LPAIF_RDMA_CHAN_PCM0 = 1,
120 LPAIF_RDMA_CHAN_PCM1 = 2,
121
122 LPAIF_RDMA_CHAN_MAX = 4,
123 LPAIF_RDMA_CHAN_NUM = 5,
124};
125
126#define LPAIF_RDMACTL_REG(chan) LPAIF_RDMA_REG_ADDR(0x00, (chan))
127#define LPAIF_RDMABASE_REG(chan) LPAIF_RDMA_REG_ADDR(0x04, (chan))
128#define LPAIF_RDMABUFF_REG(chan) LPAIF_RDMA_REG_ADDR(0x08, (chan))
129#define LPAIF_RDMACURR_REG(chan) LPAIF_RDMA_REG_ADDR(0x0C, (chan))
130#define LPAIF_RDMAPER_REG(chan) LPAIF_RDMA_REG_ADDR(0x10, (chan))
131
132#define LPAIF_RDMACTL_BURSTEN_MASK 0x800
133#define LPAIF_RDMACTL_BURSTEN_SHIFT 11
134#define LPAIF_RDMACTL_BURSTEN_SINGLE (0 << LPAIF_RDMACTL_BURSTEN_SHIFT)
135#define LPAIF_RDMACTL_BURSTEN_INCR4 (1 << LPAIF_RDMACTL_BURSTEN_SHIFT)
136
137#define LPAIF_RDMACTL_WPSCNT_MASK 0x700
138#define LPAIF_RDMACTL_WPSCNT_SHIFT 8
139#define LPAIF_RDMACTL_WPSCNT_ONE (0 << LPAIF_RDMACTL_WPSCNT_SHIFT)
140#define LPAIF_RDMACTL_WPSCNT_TWO (1 << LPAIF_RDMACTL_WPSCNT_SHIFT)
141#define LPAIF_RDMACTL_WPSCNT_THREE (2 << LPAIF_RDMACTL_WPSCNT_SHIFT)
142#define LPAIF_RDMACTL_WPSCNT_FOUR (3 << LPAIF_RDMACTL_WPSCNT_SHIFT)
143#define LPAIF_RDMACTL_WPSCNT_SIX (5 << LPAIF_RDMACTL_WPSCNT_SHIFT)
144#define LPAIF_RDMACTL_WPSCNT_EIGHT (7 << LPAIF_RDMACTL_WPSCNT_SHIFT)
145
146#define LPAIF_RDMACTL_AUDINTF_MASK 0x0F0
147#define LPAIF_RDMACTL_AUDINTF_SHIFT 4
148#define LPAIF_RDMACTL_AUDINTF_NONE (0 << LPAIF_RDMACTL_AUDINTF_SHIFT)
149#define LPAIF_RDMACTL_AUDINTF_CODEC (1 << LPAIF_RDMACTL_AUDINTF_SHIFT)
150#define LPAIF_RDMACTL_AUDINTF_PCM (2 << LPAIF_RDMACTL_AUDINTF_SHIFT)
151#define LPAIF_RDMACTL_AUDINTF_SEC_I2S (3 << LPAIF_RDMACTL_AUDINTF_SHIFT)
152#define LPAIF_RDMACTL_AUDINTF_MI2S (4 << LPAIF_RDMACTL_AUDINTF_SHIFT)
153#define LPAIF_RDMACTL_AUDINTF_HDMI (5 << LPAIF_RDMACTL_AUDINTF_SHIFT)
154#define LPAIF_RDMACTL_AUDINTF_SEC_PCM (7 << LPAIF_RDMACTL_AUDINTF_SHIFT)
155
156#define LPAIF_RDMACTL_FIFOWM_MASK 0x00E
157#define LPAIF_RDMACTL_FIFOWM_SHIFT 1
158#define LPAIF_RDMACTL_FIFOWM_1 (0 << LPAIF_RDMACTL_FIFOWM_SHIFT)
159#define LPAIF_RDMACTL_FIFOWM_2 (1 << LPAIF_RDMACTL_FIFOWM_SHIFT)
160#define LPAIF_RDMACTL_FIFOWM_3 (2 << LPAIF_RDMACTL_FIFOWM_SHIFT)
161#define LPAIF_RDMACTL_FIFOWM_4 (3 << LPAIF_RDMACTL_FIFOWM_SHIFT)
162#define LPAIF_RDMACTL_FIFOWM_5 (4 << LPAIF_RDMACTL_FIFOWM_SHIFT)
163#define LPAIF_RDMACTL_FIFOWM_6 (5 << LPAIF_RDMACTL_FIFOWM_SHIFT)
164#define LPAIF_RDMACTL_FIFOWM_7 (6 << LPAIF_RDMACTL_FIFOWM_SHIFT)
165#define LPAIF_RDMACTL_FIFOWM_8 (7 << LPAIF_RDMACTL_FIFOWM_SHIFT)
166
167#define LPAIF_RDMACTL_ENABLE_MASK 0x1
168#define LPAIF_RDMACTL_ENABLE_SHIFT 0
169#define LPAIF_RDMACTL_ENABLE_OFF (0 << LPAIF_RDMACTL_ENABLE_SHIFT)
170#define LPAIF_RDMACTL_ENABLE_ON (1 << LPAIF_RDMACTL_ENABLE_SHIFT)
171
172#endif /* __LPASS_LPAIF_H__ */
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
new file mode 100644
index 000000000000..2fa6280dfb23
--- /dev/null
+++ b/sound/soc/qcom/lpass-platform.c
@@ -0,0 +1,526 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass-platform.c -- ALSA SoC platform driver for QTi LPASS
14 */
15
16#include <linux/compiler.h>
17#include <linux/device.h>
18#include <linux/dma-mapping.h>
19#include <linux/err.h>
20#include <linux/export.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/io.h>
24#include <linux/platform_device.h>
25#include <sound/memalloc.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <linux/regmap.h>
29#include <sound/soc.h>
30#include "lpass-lpaif-ipq806x.h"
31#include "lpass.h"
32
33#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024)
34#define LPASS_PLATFORM_PERIODS 2
35
36static struct snd_pcm_hardware lpass_platform_pcm_hardware = {
37 .info = SNDRV_PCM_INFO_MMAP |
38 SNDRV_PCM_INFO_MMAP_VALID |
39 SNDRV_PCM_INFO_INTERLEAVED |
40 SNDRV_PCM_INFO_PAUSE |
41 SNDRV_PCM_INFO_RESUME,
42 .formats = SNDRV_PCM_FMTBIT_S16 |
43 SNDRV_PCM_FMTBIT_S24 |
44 SNDRV_PCM_FMTBIT_S32,
45 .rates = SNDRV_PCM_RATE_8000_192000,
46 .rate_min = 8000,
47 .rate_max = 192000,
48 .channels_min = 1,
49 .channels_max = 8,
50 .buffer_bytes_max = LPASS_PLATFORM_BUFFER_SIZE,
51 .period_bytes_max = LPASS_PLATFORM_BUFFER_SIZE /
52 LPASS_PLATFORM_PERIODS,
53 .period_bytes_min = LPASS_PLATFORM_BUFFER_SIZE /
54 LPASS_PLATFORM_PERIODS,
55 .periods_min = LPASS_PLATFORM_PERIODS,
56 .periods_max = LPASS_PLATFORM_PERIODS,
57 .fifo_size = 0,
58};
59
60static int lpass_platform_pcmops_open(struct snd_pcm_substream *substream)
61{
62 struct snd_pcm_runtime *runtime = substream->runtime;
63 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
64 int ret;
65
66 snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);
67
68 runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;
69
70 ret = snd_pcm_hw_constraint_integer(runtime,
71 SNDRV_PCM_HW_PARAM_PERIODS);
72 if (ret < 0) {
73 dev_err(soc_runtime->dev, "%s() setting constraints failed: %d\n",
74 __func__, ret);
75 return -EINVAL;
76 }
77
78 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
79
80 return 0;
81}
82
83static int lpass_platform_pcmops_hw_params(struct snd_pcm_substream *substream,
84 struct snd_pcm_hw_params *params)
85{
86 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
87 struct lpass_data *drvdata =
88 snd_soc_platform_get_drvdata(soc_runtime->platform);
89 snd_pcm_format_t format = params_format(params);
90 unsigned int channels = params_channels(params);
91 unsigned int regval;
92 int bitwidth;
93 int ret;
94
95 bitwidth = snd_pcm_format_width(format);
96 if (bitwidth < 0) {
97 dev_err(soc_runtime->dev, "%s() invalid bit width given: %d\n",
98 __func__, bitwidth);
99 return bitwidth;
100 }
101
102 regval = LPAIF_RDMACTL_BURSTEN_INCR4 |
103 LPAIF_RDMACTL_AUDINTF_MI2S |
104 LPAIF_RDMACTL_FIFOWM_8;
105
106 switch (bitwidth) {
107 case 16:
108 switch (channels) {
109 case 1:
110 case 2:
111 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
112 break;
113 case 4:
114 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
115 break;
116 case 6:
117 regval |= LPAIF_RDMACTL_WPSCNT_THREE;
118 break;
119 case 8:
120 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
121 break;
122 default:
123 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
124 __func__, bitwidth, channels);
125 return -EINVAL;
126 }
127 break;
128 case 24:
129 case 32:
130 switch (channels) {
131 case 1:
132 regval |= LPAIF_RDMACTL_WPSCNT_ONE;
133 break;
134 case 2:
135 regval |= LPAIF_RDMACTL_WPSCNT_TWO;
136 break;
137 case 4:
138 regval |= LPAIF_RDMACTL_WPSCNT_FOUR;
139 break;
140 case 6:
141 regval |= LPAIF_RDMACTL_WPSCNT_SIX;
142 break;
143 case 8:
144 regval |= LPAIF_RDMACTL_WPSCNT_EIGHT;
145 break;
146 default:
147 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
148 __func__, bitwidth, channels);
149 return -EINVAL;
150 }
151 break;
152 default:
153 dev_err(soc_runtime->dev, "%s() invalid PCM config given: bw=%d, ch=%u\n",
154 __func__, bitwidth, channels);
155 return -EINVAL;
156 }
157
158 ret = regmap_write(drvdata->lpaif_map,
159 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), regval);
160 if (ret) {
161 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
162 __func__, ret);
163 return ret;
164 }
165
166 return 0;
167}
168
169static int lpass_platform_pcmops_hw_free(struct snd_pcm_substream *substream)
170{
171 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
172 struct lpass_data *drvdata =
173 snd_soc_platform_get_drvdata(soc_runtime->platform);
174 int ret;
175
176 ret = regmap_write(drvdata->lpaif_map,
177 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
178 if (ret)
179 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
180 __func__, ret);
181
182 return ret;
183}
184
185static int lpass_platform_pcmops_prepare(struct snd_pcm_substream *substream)
186{
187 struct snd_pcm_runtime *runtime = substream->runtime;
188 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
189 struct lpass_data *drvdata =
190 snd_soc_platform_get_drvdata(soc_runtime->platform);
191 int ret;
192
193 ret = regmap_write(drvdata->lpaif_map,
194 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S),
195 runtime->dma_addr);
196 if (ret) {
197 dev_err(soc_runtime->dev, "%s() error writing to rdmabase reg: %d\n",
198 __func__, ret);
199 return ret;
200 }
201
202 ret = regmap_write(drvdata->lpaif_map,
203 LPAIF_RDMABUFF_REG(LPAIF_RDMA_CHAN_MI2S),
204 (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1);
205 if (ret) {
206 dev_err(soc_runtime->dev, "%s() error writing to rdmabuff reg: %d\n",
207 __func__, ret);
208 return ret;
209 }
210
211 ret = regmap_write(drvdata->lpaif_map,
212 LPAIF_RDMAPER_REG(LPAIF_RDMA_CHAN_MI2S),
213 (snd_pcm_lib_period_bytes(substream) >> 2) - 1);
214 if (ret) {
215 dev_err(soc_runtime->dev, "%s() error writing to rdmaper reg: %d\n",
216 __func__, ret);
217 return ret;
218 }
219
220 ret = regmap_update_bits(drvdata->lpaif_map,
221 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
222 LPAIF_RDMACTL_ENABLE_MASK, LPAIF_RDMACTL_ENABLE_ON);
223 if (ret) {
224 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
225 __func__, ret);
226 return ret;
227 }
228
229 return 0;
230}
231
232static int lpass_platform_pcmops_trigger(struct snd_pcm_substream *substream,
233 int cmd)
234{
235 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
236 struct lpass_data *drvdata =
237 snd_soc_platform_get_drvdata(soc_runtime->platform);
238 int ret;
239
240 switch (cmd) {
241 case SNDRV_PCM_TRIGGER_START:
242 case SNDRV_PCM_TRIGGER_RESUME:
243 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
244 /* clear status before enabling interrupts */
245 ret = regmap_write(drvdata->lpaif_map,
246 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
247 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
248 if (ret) {
249 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
250 __func__, ret);
251 return ret;
252 }
253
254 ret = regmap_update_bits(drvdata->lpaif_map,
255 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
256 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S),
257 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S));
258 if (ret) {
259 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
260 __func__, ret);
261 return ret;
262 }
263
264 ret = regmap_update_bits(drvdata->lpaif_map,
265 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
266 LPAIF_RDMACTL_ENABLE_MASK,
267 LPAIF_RDMACTL_ENABLE_ON);
268 if (ret) {
269 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
270 __func__, ret);
271 return ret;
272 }
273 break;
274 case SNDRV_PCM_TRIGGER_STOP:
275 case SNDRV_PCM_TRIGGER_SUSPEND:
276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
277 ret = regmap_update_bits(drvdata->lpaif_map,
278 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S),
279 LPAIF_RDMACTL_ENABLE_MASK,
280 LPAIF_RDMACTL_ENABLE_OFF);
281 if (ret) {
282 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
283 __func__, ret);
284 return ret;
285 }
286
287 ret = regmap_update_bits(drvdata->lpaif_map,
288 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST),
289 LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S), 0);
290 if (ret) {
291 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
292 __func__, ret);
293 return ret;
294 }
295 break;
296 }
297
298 return 0;
299}
300
301static snd_pcm_uframes_t lpass_platform_pcmops_pointer(
302 struct snd_pcm_substream *substream)
303{
304 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
305 struct lpass_data *drvdata =
306 snd_soc_platform_get_drvdata(soc_runtime->platform);
307 unsigned int base_addr, curr_addr;
308 int ret;
309
310 ret = regmap_read(drvdata->lpaif_map,
311 LPAIF_RDMABASE_REG(LPAIF_RDMA_CHAN_MI2S), &base_addr);
312 if (ret) {
313 dev_err(soc_runtime->dev, "%s() error reading from rdmabase reg: %d\n",
314 __func__, ret);
315 return ret;
316 }
317
318 ret = regmap_read(drvdata->lpaif_map,
319 LPAIF_RDMACURR_REG(LPAIF_RDMA_CHAN_MI2S), &curr_addr);
320 if (ret) {
321 dev_err(soc_runtime->dev, "%s() error reading from rdmacurr reg: %d\n",
322 __func__, ret);
323 return ret;
324 }
325
326 return bytes_to_frames(substream->runtime, curr_addr - base_addr);
327}
328
329static int lpass_platform_pcmops_mmap(struct snd_pcm_substream *substream,
330 struct vm_area_struct *vma)
331{
332 struct snd_pcm_runtime *runtime = substream->runtime;
333
334 return dma_mmap_coherent(substream->pcm->card->dev, vma,
335 runtime->dma_area, runtime->dma_addr,
336 runtime->dma_bytes);
337}
338
339static struct snd_pcm_ops lpass_platform_pcm_ops = {
340 .open = lpass_platform_pcmops_open,
341 .ioctl = snd_pcm_lib_ioctl,
342 .hw_params = lpass_platform_pcmops_hw_params,
343 .hw_free = lpass_platform_pcmops_hw_free,
344 .prepare = lpass_platform_pcmops_prepare,
345 .trigger = lpass_platform_pcmops_trigger,
346 .pointer = lpass_platform_pcmops_pointer,
347 .mmap = lpass_platform_pcmops_mmap,
348};
349
350static irqreturn_t lpass_platform_lpaif_irq(int irq, void *data)
351{
352 struct snd_pcm_substream *substream = data;
353 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
354 struct lpass_data *drvdata =
355 snd_soc_platform_get_drvdata(soc_runtime->platform);
356 unsigned int interrupts;
357 irqreturn_t ret = IRQ_NONE;
358 int rv;
359
360 rv = regmap_read(drvdata->lpaif_map,
361 LPAIF_IRQSTAT_REG(LPAIF_IRQ_PORT_HOST), &interrupts);
362 if (rv) {
363 dev_err(soc_runtime->dev, "%s() error reading from irqstat reg: %d\n",
364 __func__, rv);
365 return IRQ_NONE;
366 }
367 interrupts &= LPAIF_IRQ_ALL(LPAIF_RDMA_CHAN_MI2S);
368
369 if (interrupts & LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S)) {
370 rv = regmap_write(drvdata->lpaif_map,
371 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
372 LPAIF_IRQ_PER(LPAIF_RDMA_CHAN_MI2S));
373 if (rv) {
374 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
375 __func__, rv);
376 return IRQ_NONE;
377 }
378 snd_pcm_period_elapsed(substream);
379 ret = IRQ_HANDLED;
380 }
381
382 if (interrupts & LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S)) {
383 rv = regmap_write(drvdata->lpaif_map,
384 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
385 LPAIF_IRQ_XRUN(LPAIF_RDMA_CHAN_MI2S));
386 if (rv) {
387 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
388 __func__, rv);
389 return IRQ_NONE;
390 }
391 dev_warn(soc_runtime->dev, "%s() xrun warning\n", __func__);
392 snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
393 ret = IRQ_HANDLED;
394 }
395
396 if (interrupts & LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S)) {
397 rv = regmap_write(drvdata->lpaif_map,
398 LPAIF_IRQCLEAR_REG(LPAIF_IRQ_PORT_HOST),
399 LPAIF_IRQ_ERR(LPAIF_RDMA_CHAN_MI2S));
400 if (rv) {
401 dev_err(soc_runtime->dev, "%s() error writing to irqclear reg: %d\n",
402 __func__, rv);
403 return IRQ_NONE;
404 }
405 dev_err(soc_runtime->dev, "%s() bus access error\n", __func__);
406 snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
407 ret = IRQ_HANDLED;
408 }
409
410 return ret;
411}
412
413static int lpass_platform_alloc_buffer(struct snd_pcm_substream *substream,
414 struct snd_soc_pcm_runtime *soc_runtime)
415{
416 struct snd_dma_buffer *buf = &substream->dma_buffer;
417 size_t size = lpass_platform_pcm_hardware.buffer_bytes_max;
418
419 buf->dev.type = SNDRV_DMA_TYPE_DEV;
420 buf->dev.dev = soc_runtime->dev;
421 buf->private_data = NULL;
422 buf->area = dma_alloc_coherent(soc_runtime->dev, size, &buf->addr,
423 GFP_KERNEL);
424 if (!buf->area) {
425 dev_err(soc_runtime->dev, "%s: Could not allocate DMA buffer\n",
426 __func__);
427 return -ENOMEM;
428 }
429 buf->bytes = size;
430
431 return 0;
432}
433
434static void lpass_platform_free_buffer(struct snd_pcm_substream *substream,
435 struct snd_soc_pcm_runtime *soc_runtime)
436{
437 struct snd_dma_buffer *buf = &substream->dma_buffer;
438
439 if (buf->area) {
440 dma_free_coherent(soc_runtime->dev, buf->bytes, buf->area,
441 buf->addr);
442 }
443 buf->area = NULL;
444}
445
446static int lpass_platform_pcm_new(struct snd_soc_pcm_runtime *soc_runtime)
447{
448 struct snd_pcm *pcm = soc_runtime->pcm;
449 struct snd_pcm_substream *substream =
450 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
451 struct lpass_data *drvdata =
452 snd_soc_platform_get_drvdata(soc_runtime->platform);
453 int ret;
454
455 soc_runtime->dev->coherent_dma_mask = DMA_BIT_MASK(32);
456 soc_runtime->dev->dma_mask = &soc_runtime->dev->coherent_dma_mask;
457
458 ret = lpass_platform_alloc_buffer(substream, soc_runtime);
459 if (ret)
460 return ret;
461
462 ret = devm_request_irq(soc_runtime->dev, drvdata->lpaif_irq,
463 lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING,
464 "lpass-irq-lpaif", substream);
465 if (ret) {
466 dev_err(soc_runtime->dev, "%s() irq request failed: %d\n",
467 __func__, ret);
468 goto err_buf;
469 }
470
471 /* ensure audio hardware is disabled */
472 ret = regmap_write(drvdata->lpaif_map,
473 LPAIF_IRQEN_REG(LPAIF_IRQ_PORT_HOST), 0);
474 if (ret) {
475 dev_err(soc_runtime->dev, "%s() error writing to irqen reg: %d\n",
476 __func__, ret);
477 return ret;
478 }
479 ret = regmap_write(drvdata->lpaif_map,
480 LPAIF_RDMACTL_REG(LPAIF_RDMA_CHAN_MI2S), 0);
481 if (ret) {
482 dev_err(soc_runtime->dev, "%s() error writing to rdmactl reg: %d\n",
483 __func__, ret);
484 return ret;
485 }
486
487 return 0;
488
489err_buf:
490 lpass_platform_free_buffer(substream, soc_runtime);
491 return ret;
492}
493
494static void lpass_platform_pcm_free(struct snd_pcm *pcm)
495{
496 struct snd_pcm_substream *substream =
497 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
498 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
499
500 lpass_platform_free_buffer(substream, soc_runtime);
501}
502
503static struct snd_soc_platform_driver lpass_platform_driver = {
504 .pcm_new = lpass_platform_pcm_new,
505 .pcm_free = lpass_platform_pcm_free,
506 .ops = &lpass_platform_pcm_ops,
507};
508
509int asoc_qcom_lpass_platform_register(struct platform_device *pdev)
510{
511 struct lpass_data *drvdata = platform_get_drvdata(pdev);
512
513 drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif");
514 if (drvdata->lpaif_irq < 0) {
515 dev_err(&pdev->dev, "%s() error getting irq handle: %d\n",
516 __func__, drvdata->lpaif_irq);
517 return -ENODEV;
518 }
519
520 return devm_snd_soc_register_platform(&pdev->dev,
521 &lpass_platform_driver);
522}
523EXPORT_SYMBOL_GPL(asoc_qcom_lpass_platform_register);
524
525MODULE_DESCRIPTION("QTi LPASS Platform Driver");
526MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
new file mode 100644
index 000000000000..5c99b3dace86
--- /dev/null
+++ b/sound/soc/qcom/lpass.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * lpass.h - Definitions for the QTi LPASS
14 */
15
16#ifndef __LPASS_H__
17#define __LPASS_H__
18
19#include <linux/clk.h>
20#include <linux/compiler.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23
24#define LPASS_AHBIX_CLOCK_FREQUENCY 131072000
25
26/* Both the CPU DAI and platform drivers will access this data */
27struct lpass_data {
28
29 /* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
30 struct clk *ahbix_clk;
31
32 /* MI2S system clock */
33 struct clk *mi2s_osr_clk;
34
35 /* MI2S bit clock (derived from system clock by a divider */
36 struct clk *mi2s_bit_clk;
37
38 /* low-power audio interface (LPAIF) registers */
39 void __iomem *lpaif;
40
41 /* regmap backed by the low-power audio interface (LPAIF) registers */
42 struct regmap *lpaif_map;
43
44 /* interrupts from the low-power audio interface (LPAIF) */
45 int lpaif_irq;
46};
47
48/* register the platform driver from the CPU DAI driver */
49int asoc_qcom_lpass_platform_register(struct platform_device *);
50
51#endif /* __LPASS_H__ */
diff --git a/sound/soc/qcom/storm.c b/sound/soc/qcom/storm.c
new file mode 100644
index 000000000000..b8bd296190ad
--- /dev/null
+++ b/sound/soc/qcom/storm.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2010-2011,2013-2015 The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * storm.c -- ALSA SoC machine driver for QTi ipq806x-based Storm board
14 */
15
16#include <linux/device.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/mod_devicetable.h>
20#include <linux/platform_device.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24
25#define STORM_SYSCLK_MULT 4
26
27static int storm_ops_hw_params(struct snd_pcm_substream *substream,
28 struct snd_pcm_hw_params *params)
29{
30 struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
31 struct snd_soc_card *card = soc_runtime->card;
32 snd_pcm_format_t format = params_format(params);
33 unsigned int rate = params_rate(params);
34 unsigned int sysclk_freq;
35 int bitwidth, ret;
36
37 bitwidth = snd_pcm_format_width(format);
38 if (bitwidth < 0) {
39 dev_err(card->dev, "%s() invalid bit width given: %d\n",
40 __func__, bitwidth);
41 return bitwidth;
42 }
43
44 /*
45 * as the CPU DAI is the I2S bus master and no system clock is needed by
46 * the MAX98357a DAC, simply set the system clock to be a constant
47 * multiple of the bit clock for the clock divider
48 */
49 sysclk_freq = rate * bitwidth * 2 * STORM_SYSCLK_MULT;
50
51 ret = snd_soc_dai_set_sysclk(soc_runtime->cpu_dai, 0, sysclk_freq, 0);
52 if (ret) {
53 dev_err(card->dev, "%s() error setting sysclk to %u: %d\n",
54 __func__, sysclk_freq, ret);
55 return ret;
56 }
57
58 return 0;
59}
60
61static struct snd_soc_ops storm_soc_ops = {
62 .hw_params = storm_ops_hw_params,
63};
64
65static struct snd_soc_dai_link storm_dai_link = {
66 .name = "Primary",
67 .stream_name = "Primary",
68 .codec_dai_name = "HiFi",
69 .ops = &storm_soc_ops,
70};
71
72static struct snd_soc_card storm_soc_card = {
73 .name = "ipq806x-storm",
74 .dev = NULL,
75};
76
77static int storm_parse_of(struct snd_soc_card *card)
78{
79 struct snd_soc_dai_link *dai_link = card->dai_link;
80 struct device_node *np = card->dev->of_node;
81
82 dai_link->cpu_of_node = of_parse_phandle(np, "cpu", 0);
83 if (!dai_link->cpu_of_node) {
84 dev_err(card->dev, "%s() error getting cpu phandle\n",
85 __func__);
86 return -EINVAL;
87 }
88 dai_link->platform_of_node = dai_link->cpu_of_node;
89
90 dai_link->codec_of_node = of_parse_phandle(np, "codec", 0);
91 if (!dai_link->codec_of_node) {
92 dev_err(card->dev, "%s() error getting codec phandle\n",
93 __func__);
94 return -EINVAL;
95 }
96
97 return 0;
98}
99
100static int storm_platform_probe(struct platform_device *pdev)
101{
102 struct snd_soc_card *card = &storm_soc_card;
103 int ret;
104
105 if (card->dev) {
106 dev_err(&pdev->dev, "%s() error, existing soundcard\n",
107 __func__);
108 return -ENODEV;
109 }
110 card->dev = &pdev->dev;
111 platform_set_drvdata(pdev, card);
112
113 ret = snd_soc_of_parse_card_name(card, "qcom,model");
114 if (ret) {
115 dev_err(&pdev->dev, "%s() error parsing card name: %d\n",
116 __func__, ret);
117 return ret;
118 }
119
120 card->dai_link = &storm_dai_link;
121 card->num_links = 1;
122
123 ret = storm_parse_of(card);
124 if (ret) {
125 dev_err(&pdev->dev, "%s() error resolving dai links: %d\n",
126 __func__, ret);
127 return ret;
128 }
129
130 ret = devm_snd_soc_register_card(&pdev->dev, card);
131 if (ret == -EPROBE_DEFER) {
132 card->dev = NULL;
133 return ret;
134 } else if (ret) {
135 dev_err(&pdev->dev, "%s() error registering soundcard: %d\n",
136 __func__, ret);
137 return ret;
138 }
139
140 return 0;
141}
142
143#ifdef CONFIG_OF
144static const struct of_device_id storm_device_id[] = {
145 { .compatible = "google,storm-audio" },
146 {},
147};
148MODULE_DEVICE_TABLE(of, storm_device_id);
149#endif
150
151static struct platform_driver storm_platform_driver = {
152 .driver = {
153 .name = "storm-audio",
154 .of_match_table =
155 of_match_ptr(storm_device_id),
156 },
157 .probe = storm_platform_probe,
158};
159module_platform_driver(storm_platform_driver);
160
161MODULE_DESCRIPTION("QTi IPQ806x-based Storm Machine Driver");
162MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 80245b6eebd6..07114b0b0dc1 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -36,11 +36,17 @@ config SND_SOC_SH4_SIU
36 36
37config SND_SOC_RCAR 37config SND_SOC_RCAR
38 tristate "R-Car series SRU/SCU/SSIU/SSI support" 38 tristate "R-Car series SRU/SCU/SSIU/SSI support"
39 depends on DMA_OF
39 select SND_SIMPLE_CARD 40 select SND_SIMPLE_CARD
40 select REGMAP_MMIO 41 select REGMAP_MMIO
41 help 42 help
42 This option enables R-Car SUR/SCU/SSIU/SSI sound support 43 This option enables R-Car SUR/SCU/SSIU/SSI sound support
43 44
45config SND_SOC_RSRC_CARD
46 tristate "Renesas Sampling Rate Convert Sound Card"
47 help
48 This option enables simple sound if you need sampling rate convert
49
44## 50##
45## Boards 51## Boards
46## 52##
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile
index 9ac536429800..f1b445173fba 100644
--- a/sound/soc/sh/rcar/Makefile
+++ b/sound/soc/sh/rcar/Makefile
@@ -1,2 +1,5 @@
1snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o 1snd-soc-rcar-objs := core.o gen.o dma.o src.o adg.o ssi.o dvc.o
2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file 2obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o
3
4snd-soc-rsrc-card-objs := rsrc-card.o
5obj-$(CONFIG_SND_SOC_RSRC_CARD) += snd-soc-rsrc-card.o
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 7ac35c9d1cb8..fefc881dbac2 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -183,6 +183,8 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,
183 183
184 rsnd_mod_bset(mod, DIV_EN, en, en); 184 rsnd_mod_bset(mod, DIV_EN, en, en);
185 185
186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);
187
186 return 0; 188 return 0;
187} 189}
188 190
@@ -432,7 +434,5 @@ int rsnd_adg_probe(struct platform_device *pdev,
432 434
433 priv->adg = adg; 435 priv->adg = adg;
434 436
435 dev_dbg(dev, "adg probed\n");
436
437 return 0; 437 return 0;
438} 438}
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 31202e95be1e..9f48d75fa992 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -94,21 +94,20 @@
94 * 94 *
95 */ 95 */
96#include <linux/pm_runtime.h> 96#include <linux/pm_runtime.h>
97#include <linux/shdma-base.h>
98#include "rsnd.h" 97#include "rsnd.h"
99 98
100#define RSND_RATES SNDRV_PCM_RATE_8000_96000 99#define RSND_RATES SNDRV_PCM_RATE_8000_96000
101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 100#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
102 101
103static struct rsnd_of_data rsnd_of_data_gen1 = { 102static const struct rsnd_of_data rsnd_of_data_gen1 = {
104 .flags = RSND_GEN1, 103 .flags = RSND_GEN1,
105}; 104};
106 105
107static struct rsnd_of_data rsnd_of_data_gen2 = { 106static const struct rsnd_of_data rsnd_of_data_gen2 = {
108 .flags = RSND_GEN2, 107 .flags = RSND_GEN2,
109}; 108};
110 109
111static struct of_device_id rsnd_of_match[] = { 110static const struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, 111 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, 112 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
114 {}, 113 {},
@@ -138,15 +137,12 @@ char *rsnd_mod_name(struct rsnd_mod *mod)
138 return mod->ops->name; 137 return mod->ops->name;
139} 138}
140 139
141char *rsnd_mod_dma_name(struct rsnd_mod *mod) 140struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod)
142{ 141{
143 if (!mod || !mod->ops) 142 if (!mod || !mod->ops || !mod->ops->dma_req)
144 return "unknown"; 143 return NULL;
145
146 if (!mod->ops->dma_name)
147 return mod->ops->name;
148 144
149 return mod->ops->dma_name(mod); 145 return mod->ops->dma_req(mod);
150} 146}
151 147
152int rsnd_mod_init(struct rsnd_mod *mod, 148int rsnd_mod_init(struct rsnd_mod *mod,
@@ -175,228 +171,6 @@ void rsnd_mod_quit(struct rsnd_mod *mod)
175} 171}
176 172
177/* 173/*
178 * rsnd_dma functions
179 */
180void rsnd_dma_stop(struct rsnd_dma *dma)
181{
182 dmaengine_terminate_all(dma->chan);
183}
184
185static void rsnd_dma_complete(void *data)
186{
187 struct rsnd_dma *dma = (struct rsnd_dma *)data;
188 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
189 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
190
191 /*
192 * Renesas sound Gen1 needs 1 DMAC,
193 * Gen2 needs 2 DMAC.
194 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
195 * But, Audio-DMAC-peri-peri doesn't have interrupt,
196 * and this driver is assuming that here.
197 *
198 * If Audio-DMAC-peri-peri has interrpt,
199 * rsnd_dai_pointer_update() will be called twice,
200 * ant it will breaks io->byte_pos
201 */
202
203 rsnd_dai_pointer_update(io, io->byte_per_period);
204}
205
206void rsnd_dma_start(struct rsnd_dma *dma)
207{
208 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
209 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
210 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
211 struct snd_pcm_substream *substream = io->substream;
212 struct device *dev = rsnd_priv_to_dev(priv);
213 struct dma_async_tx_descriptor *desc;
214
215 desc = dmaengine_prep_dma_cyclic(dma->chan,
216 (dma->addr) ? dma->addr :
217 substream->runtime->dma_addr,
218 snd_pcm_lib_buffer_bytes(substream),
219 snd_pcm_lib_period_bytes(substream),
220 dma->dir,
221 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
222
223 if (!desc) {
224 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
225 return;
226 }
227
228 desc->callback = rsnd_dma_complete;
229 desc->callback_param = dma;
230
231 if (dmaengine_submit(desc) < 0) {
232 dev_err(dev, "dmaengine_submit() fail\n");
233 return;
234 }
235
236 dma_async_issue_pending(dma->chan);
237}
238
239int rsnd_dma_available(struct rsnd_dma *dma)
240{
241 return !!dma->chan;
242}
243
244#define DMA_NAME_SIZE 16
245#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
246static int _rsnd_dma_of_name(char *dma_name, struct rsnd_mod *mod)
247{
248 if (mod)
249 return snprintf(dma_name, DMA_NAME_SIZE / 2, "%s%d",
250 rsnd_mod_dma_name(mod), rsnd_mod_id(mod));
251 else
252 return snprintf(dma_name, DMA_NAME_SIZE / 2, "mem");
253
254}
255
256static void rsnd_dma_of_name(struct rsnd_mod *mod_from,
257 struct rsnd_mod *mod_to,
258 char *dma_name)
259{
260 int index = 0;
261
262 index = _rsnd_dma_of_name(dma_name + index, mod_from);
263 *(dma_name + index++) = '_';
264 index = _rsnd_dma_of_name(dma_name + index, mod_to);
265}
266
267static void rsnd_dma_of_path(struct rsnd_dma *dma,
268 int is_play,
269 struct rsnd_mod **mod_from,
270 struct rsnd_mod **mod_to)
271{
272 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
273 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
274 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
275 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
276 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
277 struct rsnd_mod *mod[MOD_MAX];
278 int i, index;
279
280
281 for (i = 0; i < MOD_MAX; i++)
282 mod[i] = NULL;
283
284 /*
285 * in play case...
286 *
287 * src -> dst
288 *
289 * mem -> SSI
290 * mem -> SRC -> SSI
291 * mem -> SRC -> DVC -> SSI
292 */
293 mod[0] = NULL; /* for "mem" */
294 index = 1;
295 for (i = 1; i < MOD_MAX; i++) {
296 if (!src) {
297 mod[i] = ssi;
298 } else if (!dvc) {
299 mod[i] = src;
300 src = NULL;
301 } else {
302 if ((!is_play) && (this == src))
303 this = dvc;
304
305 mod[i] = (is_play) ? src : dvc;
306 i++;
307 mod[i] = (is_play) ? dvc : src;
308 src = NULL;
309 dvc = NULL;
310 }
311
312 if (mod[i] == this)
313 index = i;
314
315 if (mod[i] == ssi)
316 break;
317 }
318
319 if (is_play) {
320 *mod_from = mod[index - 1];
321 *mod_to = mod[index];
322 } else {
323 *mod_from = mod[index];
324 *mod_to = mod[index - 1];
325 }
326}
327
328int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma,
329 int is_play, int id)
330{
331 struct device *dev = rsnd_priv_to_dev(priv);
332 struct dma_slave_config cfg;
333 struct rsnd_mod *mod_from;
334 struct rsnd_mod *mod_to;
335 char dma_name[DMA_NAME_SIZE];
336 dma_cap_mask_t mask;
337 int ret;
338
339 if (dma->chan) {
340 dev_err(dev, "it already has dma channel\n");
341 return -EIO;
342 }
343
344 dma_cap_zero(mask);
345 dma_cap_set(DMA_SLAVE, mask);
346
347 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
348 rsnd_dma_of_name(mod_from, mod_to, dma_name);
349
350 cfg.slave_id = id;
351 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
352 cfg.src_addr = rsnd_gen_dma_addr(priv, mod_from, is_play, 1);
353 cfg.dst_addr = rsnd_gen_dma_addr(priv, mod_to, is_play, 0);
354 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
355 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
356
357 dev_dbg(dev, "dma : %s %pad -> %pad\n",
358 dma_name, &cfg.src_addr, &cfg.dst_addr);
359
360 dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter,
361 (void *)id, dev,
362 dma_name);
363 if (!dma->chan) {
364 dev_err(dev, "can't get dma channel\n");
365 goto rsnd_dma_channel_err;
366 }
367
368 ret = dmaengine_slave_config(dma->chan, &cfg);
369 if (ret < 0)
370 goto rsnd_dma_init_err;
371
372 dma->addr = is_play ? cfg.src_addr : cfg.dst_addr;
373 dma->dir = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
374
375 return 0;
376
377rsnd_dma_init_err:
378 rsnd_dma_quit(priv, dma);
379rsnd_dma_channel_err:
380
381 /*
382 * DMA failed. try to PIO mode
383 * see
384 * rsnd_ssi_fallback()
385 * rsnd_rdai_continuance_probe()
386 */
387 return -EAGAIN;
388}
389
390void rsnd_dma_quit(struct rsnd_priv *priv,
391 struct rsnd_dma *dma)
392{
393 if (dma->chan)
394 dma_release_channel(dma->chan);
395
396 dma->chan = NULL;
397}
398
399/*
400 * settting function 174 * settting function
401 */ 175 */
402u32 rsnd_get_adinr(struct rsnd_mod *mod) 176u32 rsnd_get_adinr(struct rsnd_mod *mod)
@@ -429,7 +203,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod)
429({ \ 203({ \
430 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ 204 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \
431 struct device *dev = rsnd_priv_to_dev(priv); \ 205 struct device *dev = rsnd_priv_to_dev(priv); \
432 u32 mask = 1 << __rsnd_mod_shift_##func; \ 206 u32 mask = (1 << __rsnd_mod_shift_##func) & ~(1 << 31); \
433 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \ 207 u32 call = __rsnd_mod_call_##func << __rsnd_mod_shift_##func; \
434 int ret = 0; \ 208 int ret = 0; \
435 if ((mod->status & mask) == call) { \ 209 if ((mod->status & mask) == call) { \
@@ -471,7 +245,7 @@ static int rsnd_dai_connect(struct rsnd_mod *mod,
471 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 245 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
472 struct device *dev = rsnd_priv_to_dev(priv); 246 struct device *dev = rsnd_priv_to_dev(priv);
473 247
474 dev_err(dev, "%s%d is not empty\n", 248 dev_err(dev, "%s[%d] is not empty\n",
475 rsnd_mod_name(mod), 249 rsnd_mod_name(mod),
476 rsnd_mod_id(mod)); 250 rsnd_mod_id(mod));
477 return -EIO; 251 return -EIO;
@@ -887,20 +661,28 @@ static int rsnd_dai_probe(struct platform_device *pdev,
887 drv[i].name = rdai[i].name; 661 drv[i].name = rdai[i].name;
888 drv[i].ops = &rsnd_soc_dai_ops; 662 drv[i].ops = &rsnd_soc_dai_ops;
889 if (pmod) { 663 if (pmod) {
664 snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE,
665 "DAI%d Playback", i);
666
890 drv[i].playback.rates = RSND_RATES; 667 drv[i].playback.rates = RSND_RATES;
891 drv[i].playback.formats = RSND_FMTS; 668 drv[i].playback.formats = RSND_FMTS;
892 drv[i].playback.channels_min = 2; 669 drv[i].playback.channels_min = 2;
893 drv[i].playback.channels_max = 2; 670 drv[i].playback.channels_max = 2;
671 drv[i].playback.stream_name = rdai[i].playback.name;
894 672
895 rdai[i].playback.info = &info->dai_info[i].playback; 673 rdai[i].playback.info = &info->dai_info[i].playback;
896 rdai[i].playback.rdai = rdai + i; 674 rdai[i].playback.rdai = rdai + i;
897 rsnd_path_init(priv, &rdai[i], &rdai[i].playback); 675 rsnd_path_init(priv, &rdai[i], &rdai[i].playback);
898 } 676 }
899 if (cmod) { 677 if (cmod) {
678 snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE,
679 "DAI%d Capture", i);
680
900 drv[i].capture.rates = RSND_RATES; 681 drv[i].capture.rates = RSND_RATES;
901 drv[i].capture.formats = RSND_FMTS; 682 drv[i].capture.formats = RSND_FMTS;
902 drv[i].capture.channels_min = 2; 683 drv[i].capture.channels_min = 2;
903 drv[i].capture.channels_max = 2; 684 drv[i].capture.channels_max = 2;
685 drv[i].capture.stream_name = rdai[i].capture.name;
904 686
905 rdai[i].capture.info = &info->dai_info[i].capture; 687 rdai[i].capture.info = &info->dai_info[i].capture;
906 rdai[i].capture.rdai = rdai + i; 688 rdai[i].capture.rdai = rdai + i;
@@ -946,6 +728,15 @@ static int rsnd_pcm_open(struct snd_pcm_substream *substream)
946static int rsnd_hw_params(struct snd_pcm_substream *substream, 728static int rsnd_hw_params(struct snd_pcm_substream *substream,
947 struct snd_pcm_hw_params *hw_params) 729 struct snd_pcm_hw_params *hw_params)
948{ 730{
731 struct snd_soc_dai *dai = rsnd_substream_to_dai(substream);
732 struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
733 struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);
734 int ret;
735
736 ret = rsnd_dai_call(hw_params, io, substream, hw_params);
737 if (ret)
738 return ret;
739
949 return snd_pcm_lib_malloc_pages(substream, 740 return snd_pcm_lib_malloc_pages(substream,
950 params_buffer_bytes(hw_params)); 741 params_buffer_bytes(hw_params));
951} 742}
@@ -1210,6 +1001,7 @@ static int rsnd_probe(struct platform_device *pdev)
1210 const struct rsnd_of_data *of_data, 1001 const struct rsnd_of_data *of_data,
1211 struct rsnd_priv *priv) = { 1002 struct rsnd_priv *priv) = {
1212 rsnd_gen_probe, 1003 rsnd_gen_probe,
1004 rsnd_dma_probe,
1213 rsnd_ssi_probe, 1005 rsnd_ssi_probe,
1214 rsnd_src_probe, 1006 rsnd_src_probe,
1215 rsnd_dvc_probe, 1007 rsnd_dvc_probe,
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c
new file mode 100644
index 000000000000..ac3756f6af60
--- /dev/null
+++ b/sound/soc/sh/rcar/dma.c
@@ -0,0 +1,616 @@
1/*
2 * Renesas R-Car Audio DMAC support
3 *
4 * Copyright (C) 2015 Renesas Electronics Corp.
5 * Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/delay.h>
12#include <linux/of_dma.h>
13#include "rsnd.h"
14
15/*
16 * Audio DMAC peri peri register
17 */
18#define PDMASAR 0x00
19#define PDMADAR 0x04
20#define PDMACHCR 0x0c
21
22/* PDMACHCR */
23#define PDMACHCR_DE (1 << 0)
24
25struct rsnd_dma_ctrl {
26 void __iomem *base;
27 int dmapp_num;
28};
29
30#define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
31
32/*
33 * Audio DMAC
34 */
35static void rsnd_dmaen_complete(void *data)
36{
37 struct rsnd_dma *dma = (struct rsnd_dma *)data;
38 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
39 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
40
41 /*
42 * Renesas sound Gen1 needs 1 DMAC,
43 * Gen2 needs 2 DMAC.
44 * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri.
45 * But, Audio-DMAC-peri-peri doesn't have interrupt,
46 * and this driver is assuming that here.
47 *
48 * If Audio-DMAC-peri-peri has interrpt,
49 * rsnd_dai_pointer_update() will be called twice,
50 * ant it will breaks io->byte_pos
51 */
52
53 rsnd_dai_pointer_update(io, io->byte_per_period);
54}
55
56static void rsnd_dmaen_stop(struct rsnd_dma *dma)
57{
58 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
59
60 dmaengine_terminate_all(dmaen->chan);
61}
62
63static void rsnd_dmaen_start(struct rsnd_dma *dma)
64{
65 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
66 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
67 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
68 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
69 struct snd_pcm_substream *substream = io->substream;
70 struct device *dev = rsnd_priv_to_dev(priv);
71 struct dma_async_tx_descriptor *desc;
72 int is_play = rsnd_io_is_play(io);
73
74 desc = dmaengine_prep_dma_cyclic(dmaen->chan,
75 substream->runtime->dma_addr,
76 snd_pcm_lib_buffer_bytes(substream),
77 snd_pcm_lib_period_bytes(substream),
78 is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
79 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
80
81 if (!desc) {
82 dev_err(dev, "dmaengine_prep_slave_sg() fail\n");
83 return;
84 }
85
86 desc->callback = rsnd_dmaen_complete;
87 desc->callback_param = dma;
88
89 if (dmaengine_submit(desc) < 0) {
90 dev_err(dev, "dmaengine_submit() fail\n");
91 return;
92 }
93
94 dma_async_issue_pending(dmaen->chan);
95}
96
97struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
98 struct rsnd_mod *mod, char *name)
99{
100 struct dma_chan *chan;
101 struct device_node *np;
102 int i = 0;
103
104 for_each_child_of_node(of_node, np) {
105 if (i == rsnd_mod_id(mod))
106 break;
107 i++;
108 }
109
110 chan = of_dma_request_slave_channel(np, name);
111
112 of_node_put(np);
113 of_node_put(of_node);
114
115 return chan;
116}
117
118static struct dma_chan *rsnd_dmaen_request_channel(struct rsnd_mod *mod_from,
119 struct rsnd_mod *mod_to)
120{
121 if ((!mod_from && !mod_to) ||
122 (mod_from && mod_to))
123 return NULL;
124
125 if (mod_from)
126 return rsnd_mod_dma_req(mod_from);
127 else
128 return rsnd_mod_dma_req(mod_to);
129}
130
131static int rsnd_dmaen_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
132 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
133{
134 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
135 struct device *dev = rsnd_priv_to_dev(priv);
136 struct dma_slave_config cfg = {};
137 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
138 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
139 int is_play = rsnd_io_is_play(io);
140 int ret;
141
142 if (dmaen->chan) {
143 dev_err(dev, "it already has dma channel\n");
144 return -EIO;
145 }
146
147 if (dev->of_node) {
148 dmaen->chan = rsnd_dmaen_request_channel(mod_from, mod_to);
149 } else {
150 dma_cap_mask_t mask;
151
152 dma_cap_zero(mask);
153 dma_cap_set(DMA_SLAVE, mask);
154
155 dmaen->chan = dma_request_channel(mask, shdma_chan_filter,
156 (void *)id);
157 }
158 if (IS_ERR_OR_NULL(dmaen->chan)) {
159 dev_err(dev, "can't get dma channel\n");
160 goto rsnd_dma_channel_err;
161 }
162
163 cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
164 cfg.src_addr = dma->src_addr;
165 cfg.dst_addr = dma->dst_addr;
166 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
167 cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
168
169 dev_dbg(dev, "dma : %pad -> %pad\n",
170 &cfg.src_addr, &cfg.dst_addr);
171
172 ret = dmaengine_slave_config(dmaen->chan, &cfg);
173 if (ret < 0)
174 goto rsnd_dma_init_err;
175
176 return 0;
177
178rsnd_dma_init_err:
179 rsnd_dma_quit(dma);
180rsnd_dma_channel_err:
181
182 /*
183 * DMA failed. try to PIO mode
184 * see
185 * rsnd_ssi_fallback()
186 * rsnd_rdai_continuance_probe()
187 */
188 return -EAGAIN;
189}
190
191static void rsnd_dmaen_quit(struct rsnd_dma *dma)
192{
193 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma);
194
195 if (dmaen->chan)
196 dma_release_channel(dmaen->chan);
197
198 dmaen->chan = NULL;
199}
200
201static struct rsnd_dma_ops rsnd_dmaen_ops = {
202 .start = rsnd_dmaen_start,
203 .stop = rsnd_dmaen_stop,
204 .init = rsnd_dmaen_init,
205 .quit = rsnd_dmaen_quit,
206};
207
208/*
209 * Audio DMAC peri peri
210 */
211static const u8 gen2_id_table_ssiu[] = {
212 0x00, /* SSI00 */
213 0x04, /* SSI10 */
214 0x08, /* SSI20 */
215 0x0c, /* SSI3 */
216 0x0d, /* SSI4 */
217 0x0e, /* SSI5 */
218 0x0f, /* SSI6 */
219 0x10, /* SSI7 */
220 0x11, /* SSI8 */
221 0x12, /* SSI90 */
222};
223static const u8 gen2_id_table_scu[] = {
224 0x2d, /* SCU_SRCI0 */
225 0x2e, /* SCU_SRCI1 */
226 0x2f, /* SCU_SRCI2 */
227 0x30, /* SCU_SRCI3 */
228 0x31, /* SCU_SRCI4 */
229 0x32, /* SCU_SRCI5 */
230 0x33, /* SCU_SRCI6 */
231 0x34, /* SCU_SRCI7 */
232 0x35, /* SCU_SRCI8 */
233 0x36, /* SCU_SRCI9 */
234};
235static const u8 gen2_id_table_cmd[] = {
236 0x37, /* SCU_CMD0 */
237 0x38, /* SCU_CMD1 */
238};
239
240static u32 rsnd_dmapp_get_id(struct rsnd_mod *mod)
241{
242 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
243 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
244 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
245 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
246 const u8 *entry = NULL;
247 int id = rsnd_mod_id(mod);
248 int size = 0;
249
250 if (mod == ssi) {
251 entry = gen2_id_table_ssiu;
252 size = ARRAY_SIZE(gen2_id_table_ssiu);
253 } else if (mod == src) {
254 entry = gen2_id_table_scu;
255 size = ARRAY_SIZE(gen2_id_table_scu);
256 } else if (mod == dvc) {
257 entry = gen2_id_table_cmd;
258 size = ARRAY_SIZE(gen2_id_table_cmd);
259 }
260
261 if (!entry)
262 return 0xFF;
263
264 if (size <= id)
265 return 0xFF;
266
267 return entry[id];
268}
269
270static u32 rsnd_dmapp_get_chcr(struct rsnd_mod *mod_from,
271 struct rsnd_mod *mod_to)
272{
273 return (rsnd_dmapp_get_id(mod_from) << 24) +
274 (rsnd_dmapp_get_id(mod_to) << 16);
275}
276
277#define rsnd_dmapp_addr(dmac, dma, reg) \
278 (dmac->base + 0x20 + reg + \
279 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
280static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg)
281{
282 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
283 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
284 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
285 struct device *dev = rsnd_priv_to_dev(priv);
286
287 dev_dbg(dev, "w %p : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data);
288
289 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg));
290}
291
292static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg)
293{
294 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
295 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
296 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
297
298 return ioread32(rsnd_dmapp_addr(dmac, dma, reg));
299}
300
301static void rsnd_dmapp_stop(struct rsnd_dma *dma)
302{
303 int i;
304
305 rsnd_dmapp_write(dma, 0, PDMACHCR);
306
307 for (i = 0; i < 1024; i++) {
308 if (0 == rsnd_dmapp_read(dma, PDMACHCR))
309 return;
310 udelay(1);
311 }
312}
313
314static void rsnd_dmapp_start(struct rsnd_dma *dma)
315{
316 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
317
318 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR);
319 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR);
320 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR);
321}
322
323static int rsnd_dmapp_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
324 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to)
325{
326 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma);
327 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
328 struct device *dev = rsnd_priv_to_dev(priv);
329
330 dmapp->dmapp_id = dmac->dmapp_num;
331 dmapp->chcr = rsnd_dmapp_get_chcr(mod_from, mod_to) | PDMACHCR_DE;
332
333 dmac->dmapp_num++;
334
335 rsnd_dmapp_stop(dma);
336
337 dev_dbg(dev, "id/src/dst/chcr = %d/%pad/%pad/%08x\n",
338 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr);
339
340 return 0;
341}
342
343static struct rsnd_dma_ops rsnd_dmapp_ops = {
344 .start = rsnd_dmapp_start,
345 .stop = rsnd_dmapp_stop,
346 .init = rsnd_dmapp_init,
347 .quit = rsnd_dmapp_stop,
348};
349
350/*
351 * Common DMAC Interface
352 */
353
354/*
355 * DMA read/write register offset
356 *
357 * RSND_xxx_I_N for Audio DMAC input
358 * RSND_xxx_O_N for Audio DMAC output
359 * RSND_xxx_I_P for Audio DMAC peri peri input
360 * RSND_xxx_O_P for Audio DMAC peri peri output
361 *
362 * ex) R-Car H2 case
363 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
364 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
365 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
366 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
367 * CMD : 0xec500000 / / 0xec008000 0xec308000
368 */
369#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
370#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
371
372#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
373#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
374
375#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
376#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
377
378#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
379#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
380
381#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
382#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
383
384#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
385#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
386
387static dma_addr_t
388rsnd_gen2_dma_addr(struct rsnd_priv *priv,
389 struct rsnd_mod *mod,
390 int is_play, int is_from)
391{
392 struct device *dev = rsnd_priv_to_dev(priv);
393 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
394 phys_addr_t ssi_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SSI);
395 phys_addr_t src_reg = rsnd_gen_get_phy_addr(priv, RSND_GEN2_SCU);
396 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
397 int use_src = !!rsnd_io_to_mod_src(io);
398 int use_dvc = !!rsnd_io_to_mod_dvc(io);
399 int id = rsnd_mod_id(mod);
400 struct dma_addr {
401 dma_addr_t out_addr;
402 dma_addr_t in_addr;
403 } dma_addrs[3][2][3] = {
404 /* SRC */
405 {{{ 0, 0 },
406 /* Capture */
407 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
408 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
409 /* Playback */
410 {{ 0, 0, },
411 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
412 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
413 },
414 /* SSI */
415 /* Capture */
416 {{{ RDMA_SSI_O_N(ssi, id), 0 },
417 { RDMA_SSIU_O_P(ssi, id), 0 },
418 { RDMA_SSIU_O_P(ssi, id), 0 } },
419 /* Playback */
420 {{ 0, RDMA_SSI_I_N(ssi, id) },
421 { 0, RDMA_SSIU_I_P(ssi, id) },
422 { 0, RDMA_SSIU_I_P(ssi, id) } }
423 },
424 /* SSIU */
425 /* Capture */
426 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
427 { RDMA_SSIU_O_P(ssi, id), 0 },
428 { RDMA_SSIU_O_P(ssi, id), 0 } },
429 /* Playback */
430 {{ 0, RDMA_SSIU_I_N(ssi, id) },
431 { 0, RDMA_SSIU_I_P(ssi, id) },
432 { 0, RDMA_SSIU_I_P(ssi, id) } } },
433 };
434
435 /* it shouldn't happen */
436 if (use_dvc && !use_src)
437 dev_err(dev, "DVC is selected without SRC\n");
438
439 /* use SSIU or SSI ? */
440 if (is_ssi && rsnd_ssi_use_busif(mod))
441 is_ssi++;
442
443 return (is_from) ?
444 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
445 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
446}
447
448static dma_addr_t rsnd_dma_addr(struct rsnd_priv *priv,
449 struct rsnd_mod *mod,
450 int is_play, int is_from)
451{
452 /*
453 * gen1 uses default DMA addr
454 */
455 if (rsnd_is_gen1(priv))
456 return 0;
457
458 if (!mod)
459 return 0;
460
461 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
462}
463
464#define MOD_MAX 4 /* MEM/SSI/SRC/DVC */
465static void rsnd_dma_of_path(struct rsnd_dma *dma,
466 int is_play,
467 struct rsnd_mod **mod_from,
468 struct rsnd_mod **mod_to)
469{
470 struct rsnd_mod *this = rsnd_dma_to_mod(dma);
471 struct rsnd_dai_stream *io = rsnd_mod_to_io(this);
472 struct rsnd_mod *ssi = rsnd_io_to_mod_ssi(io);
473 struct rsnd_mod *src = rsnd_io_to_mod_src(io);
474 struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io);
475 struct rsnd_mod *mod[MOD_MAX];
476 int i, index;
477
478
479 for (i = 0; i < MOD_MAX; i++)
480 mod[i] = NULL;
481
482 /*
483 * in play case...
484 *
485 * src -> dst
486 *
487 * mem -> SSI
488 * mem -> SRC -> SSI
489 * mem -> SRC -> DVC -> SSI
490 */
491 mod[0] = NULL; /* for "mem" */
492 index = 1;
493 for (i = 1; i < MOD_MAX; i++) {
494 if (!src) {
495 mod[i] = ssi;
496 } else if (!dvc) {
497 mod[i] = src;
498 src = NULL;
499 } else {
500 if ((!is_play) && (this == src))
501 this = dvc;
502
503 mod[i] = (is_play) ? src : dvc;
504 i++;
505 mod[i] = (is_play) ? dvc : src;
506 src = NULL;
507 dvc = NULL;
508 }
509
510 if (mod[i] == this)
511 index = i;
512
513 if (mod[i] == ssi)
514 break;
515 }
516
517 if (is_play) {
518 *mod_from = mod[index - 1];
519 *mod_to = mod[index];
520 } else {
521 *mod_from = mod[index];
522 *mod_to = mod[index - 1];
523 }
524}
525
526void rsnd_dma_stop(struct rsnd_dma *dma)
527{
528 dma->ops->stop(dma);
529}
530
531void rsnd_dma_start(struct rsnd_dma *dma)
532{
533 dma->ops->start(dma);
534}
535
536void rsnd_dma_quit(struct rsnd_dma *dma)
537{
538 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
539 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
540 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
541
542 if (!dmac)
543 return;
544
545 dma->ops->quit(dma);
546}
547
548int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id)
549{
550 struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
551 struct rsnd_mod *mod_from;
552 struct rsnd_mod *mod_to;
553 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
554 struct rsnd_dma_ctrl *dmac = rsnd_priv_to_dmac(priv);
555 int is_play = rsnd_io_is_play(io);
556
557 /*
558 * DMA failed. try to PIO mode
559 * see
560 * rsnd_ssi_fallback()
561 * rsnd_rdai_continuance_probe()
562 */
563 if (!dmac)
564 return -EAGAIN;
565
566 rsnd_dma_of_path(dma, is_play, &mod_from, &mod_to);
567
568 dma->src_addr = rsnd_dma_addr(priv, mod_from, is_play, 1);
569 dma->dst_addr = rsnd_dma_addr(priv, mod_to, is_play, 0);
570
571 /* for Gen2 */
572 if (mod_from && mod_to)
573 dma->ops = &rsnd_dmapp_ops;
574 else
575 dma->ops = &rsnd_dmaen_ops;
576
577 /* for Gen1, overwrite */
578 if (rsnd_is_gen1(priv))
579 dma->ops = &rsnd_dmaen_ops;
580
581 return dma->ops->init(priv, dma, id, mod_from, mod_to);
582}
583
584int rsnd_dma_probe(struct platform_device *pdev,
585 const struct rsnd_of_data *of_data,
586 struct rsnd_priv *priv)
587{
588 struct device *dev = rsnd_priv_to_dev(priv);
589 struct rsnd_dma_ctrl *dmac;
590 struct resource *res;
591
592 /*
593 * for Gen1
594 */
595 if (rsnd_is_gen1(priv))
596 return 0;
597
598 /*
599 * for Gen2
600 */
601 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audmapp");
602 dmac = devm_kzalloc(dev, sizeof(*dmac), GFP_KERNEL);
603 if (!dmac || !res) {
604 dev_err(dev, "dma allocate failed\n");
605 return 0; /* it will be PIO mode */
606 }
607
608 dmac->dmapp_num = 0;
609 dmac->base = devm_ioremap_resource(dev, res);
610 if (IS_ERR(dmac->base))
611 return PTR_ERR(dmac->base);
612
613 priv->dma = dmac;
614
615 return 0;
616}
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c
index 261997a3f589..e5fcb062ad77 100644
--- a/sound/soc/sh/rcar/dvc.c
+++ b/sound/soc/sh/rcar/dvc.c
@@ -24,6 +24,9 @@ struct rsnd_dvc {
24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */ 24 struct rsnd_kctrl_cfg_s rdown; /* Ramp Rate Down */
25}; 25};
26 26
27#define rsnd_dvc_of_node(priv) \
28 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,dvc")
29
27#define rsnd_mod_to_dvc(_mod) \ 30#define rsnd_mod_to_dvc(_mod) \
28 container_of((_mod), struct rsnd_dvc, mod) 31 container_of((_mod), struct rsnd_dvc, mod)
29 32
@@ -33,7 +36,7 @@ struct rsnd_dvc {
33 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ 36 ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \
34 i++) 37 i++)
35 38
36static const char const *dvc_ramp_rate[] = { 39static const char * const dvc_ramp_rate[] = {
37 "128 dB/1 step", /* 00000 */ 40 "128 dB/1 step", /* 00000 */
38 "64 dB/1 step", /* 00001 */ 41 "64 dB/1 step", /* 00001 */
39 "32 dB/1 step", /* 00010 */ 42 "32 dB/1 step", /* 00010 */
@@ -116,17 +119,6 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod)
116 rsnd_mod_write(mod, DVC_DVUER, 1); 119 rsnd_mod_write(mod, DVC_DVUER, 1);
117} 120}
118 121
119static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod,
120 struct rsnd_priv *priv)
121{
122 struct device *dev = rsnd_priv_to_dev(priv);
123
124 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
125 rsnd_mod_name(mod), rsnd_mod_id(mod));
126
127 return 0;
128}
129
130static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, 122static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod,
131 struct rsnd_priv *priv) 123 struct rsnd_priv *priv)
132{ 124{
@@ -269,9 +261,17 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod,
269 return 0; 261 return 0;
270} 262}
271 263
264static struct dma_chan *rsnd_dvc_dma_req(struct rsnd_mod *mod)
265{
266 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
267
268 return rsnd_dma_request_channel(rsnd_dvc_of_node(priv),
269 mod, "tx");
270}
271
272static struct rsnd_mod_ops rsnd_dvc_ops = { 272static struct rsnd_mod_ops rsnd_dvc_ops = {
273 .name = DVC_NAME, 273 .name = DVC_NAME,
274 .probe = rsnd_dvc_probe_gen2, 274 .dma_req = rsnd_dvc_dma_req,
275 .remove = rsnd_dvc_remove_gen2, 275 .remove = rsnd_dvc_remove_gen2,
276 .init = rsnd_dvc_init, 276 .init = rsnd_dvc_init,
277 .quit = rsnd_dvc_quit, 277 .quit = rsnd_dvc_quit,
@@ -370,8 +370,6 @@ int rsnd_dvc_probe(struct platform_device *pdev,
370 clk, RSND_MOD_DVC, i); 370 clk, RSND_MOD_DVC, i);
371 if (ret) 371 if (ret)
372 return ret; 372 return ret;
373
374 dev_dbg(dev, "CMD%d probed\n", i);
375 } 373 }
376 374
377 return 0; 375 return 0;
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c
index de0685f2abae..8c7dc51b1c4f 100644
--- a/sound/soc/sh/rcar/gen.c
+++ b/sound/soc/sh/rcar/gen.c
@@ -28,6 +28,7 @@ struct rsnd_gen {
28 28
29 struct regmap *regmap[RSND_BASE_MAX]; 29 struct regmap *regmap[RSND_BASE_MAX];
30 struct regmap_field *regs[RSND_REG_MAX]; 30 struct regmap_field *regs[RSND_REG_MAX];
31 phys_addr_t res[RSND_REG_MAX];
31}; 32};
32 33
33#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 34#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen)
@@ -118,11 +119,19 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
118 mask, data); 119 mask, data);
119} 120}
120 121
121#define rsnd_gen_regmap_init(priv, id_size, reg_id, conf) \ 122phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id)
122 _rsnd_gen_regmap_init(priv, id_size, reg_id, conf, ARRAY_SIZE(conf)) 123{
124 struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
125
126 return gen->res[reg_id];
127}
128
129#define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \
130 _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf))
123static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, 131static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
124 int id_size, 132 int id_size,
125 int reg_id, 133 int reg_id,
134 const char *name,
126 struct rsnd_regmap_field_conf *conf, 135 struct rsnd_regmap_field_conf *conf,
127 int conf_size) 136 int conf_size)
128{ 137{
@@ -141,8 +150,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
141 regc.reg_bits = 32; 150 regc.reg_bits = 32;
142 regc.val_bits = 32; 151 regc.val_bits = 32;
143 regc.reg_stride = 4; 152 regc.reg_stride = 4;
153 regc.name = name;
144 154
145 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 155 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
156 if (!res)
157 res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id);
146 if (!res) 158 if (!res)
147 return -ENODEV; 159 return -ENODEV;
148 160
@@ -156,6 +168,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
156 168
157 gen->base[reg_id] = base; 169 gen->base[reg_id] = base;
158 gen->regmap[reg_id] = regmap; 170 gen->regmap[reg_id] = regmap;
171 gen->res[reg_id] = res->start;
159 172
160 for (i = 0; i < conf_size; i++) { 173 for (i = 0; i < conf_size; i++) {
161 174
@@ -176,125 +189,11 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
176} 189}
177 190
178/* 191/*
179 * DMA read/write register offset
180 *
181 * RSND_xxx_I_N for Audio DMAC input
182 * RSND_xxx_O_N for Audio DMAC output
183 * RSND_xxx_I_P for Audio DMAC peri peri input
184 * RSND_xxx_O_P for Audio DMAC peri peri output
185 *
186 * ex) R-Car H2 case
187 * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out
188 * SSI : 0xec541000 / 0xec241008 / 0xec24100c
189 * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000
190 * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
191 * CMD : 0xec500000 / / 0xec008000 0xec308000
192 */
193#define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
194#define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
195
196#define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
197#define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i))
198
199#define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
200#define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i))
201
202#define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
203#define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
204
205#define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
206#define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
207
208#define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
209#define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
210
211static dma_addr_t
212rsnd_gen2_dma_addr(struct rsnd_priv *priv,
213 struct rsnd_mod *mod,
214 int is_play, int is_from)
215{
216 struct platform_device *pdev = rsnd_priv_to_pdev(priv);
217 struct device *dev = rsnd_priv_to_dev(priv);
218 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
219 dma_addr_t ssi_reg = platform_get_resource(pdev,
220 IORESOURCE_MEM, RSND_GEN2_SSI)->start;
221 dma_addr_t src_reg = platform_get_resource(pdev,
222 IORESOURCE_MEM, RSND_GEN2_SCU)->start;
223 int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
224 int use_src = !!rsnd_io_to_mod_src(io);
225 int use_dvc = !!rsnd_io_to_mod_dvc(io);
226 int id = rsnd_mod_id(mod);
227 struct dma_addr {
228 dma_addr_t out_addr;
229 dma_addr_t in_addr;
230 } dma_addrs[3][2][3] = {
231 /* SRC */
232 {{{ 0, 0 },
233 /* Capture */
234 { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) },
235 { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } },
236 /* Playback */
237 {{ 0, 0, },
238 { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) },
239 { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } }
240 },
241 /* SSI */
242 /* Capture */
243 {{{ RDMA_SSI_O_N(ssi, id), 0 },
244 { RDMA_SSIU_O_P(ssi, id), 0 },
245 { RDMA_SSIU_O_P(ssi, id), 0 } },
246 /* Playback */
247 {{ 0, RDMA_SSI_I_N(ssi, id) },
248 { 0, RDMA_SSIU_I_P(ssi, id) },
249 { 0, RDMA_SSIU_I_P(ssi, id) } }
250 },
251 /* SSIU */
252 /* Capture */
253 {{{ RDMA_SSIU_O_N(ssi, id), 0 },
254 { RDMA_SSIU_O_P(ssi, id), 0 },
255 { RDMA_SSIU_O_P(ssi, id), 0 } },
256 /* Playback */
257 {{ 0, RDMA_SSIU_I_N(ssi, id) },
258 { 0, RDMA_SSIU_I_P(ssi, id) },
259 { 0, RDMA_SSIU_I_P(ssi, id) } } },
260 };
261
262 /* it shouldn't happen */
263 if (use_dvc && !use_src)
264 dev_err(dev, "DVC is selected without SRC\n");
265
266 /* use SSIU or SSI ? */
267 if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu")))
268 is_ssi++;
269
270 return (is_from) ?
271 dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr :
272 dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr;
273}
274
275dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv,
276 struct rsnd_mod *mod,
277 int is_play, int is_from)
278{
279 /*
280 * gen1 uses default DMA addr
281 */
282 if (rsnd_is_gen1(priv))
283 return 0;
284
285 if (!mod)
286 return 0;
287
288 return rsnd_gen2_dma_addr(priv, mod, is_play, is_from);
289}
290
291/*
292 * Gen2 192 * Gen2
293 */ 193 */
294static int rsnd_gen2_probe(struct platform_device *pdev, 194static int rsnd_gen2_probe(struct platform_device *pdev,
295 struct rsnd_priv *priv) 195 struct rsnd_priv *priv)
296{ 196{
297 struct device *dev = rsnd_priv_to_dev(priv);
298 struct rsnd_regmap_field_conf conf_ssiu[] = { 197 struct rsnd_regmap_field_conf conf_ssiu[] = {
299 RSND_GEN_S_REG(SSI_MODE0, 0x800), 198 RSND_GEN_S_REG(SSI_MODE0, 0x800),
300 RSND_GEN_S_REG(SSI_MODE1, 0x804), 199 RSND_GEN_S_REG(SSI_MODE1, 0x804),
@@ -368,18 +267,16 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
368 int ret_adg; 267 int ret_adg;
369 int ret_ssi; 268 int ret_ssi;
370 269
371 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, conf_ssiu); 270 ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu);
372 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, conf_scu); 271 ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu);
373 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, conf_adg); 272 ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg);
374 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, conf_ssi); 273 ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi);
375 if (ret_ssiu < 0 || 274 if (ret_ssiu < 0 ||
376 ret_scu < 0 || 275 ret_scu < 0 ||
377 ret_adg < 0 || 276 ret_adg < 0 ||
378 ret_ssi < 0) 277 ret_ssi < 0)
379 return ret_ssiu | ret_scu | ret_adg | ret_ssi; 278 return ret_ssiu | ret_scu | ret_adg | ret_ssi;
380 279
381 dev_dbg(dev, "Gen2 is probed\n");
382
383 return 0; 280 return 0;
384} 281}
385 282
@@ -390,7 +287,6 @@ static int rsnd_gen2_probe(struct platform_device *pdev,
390static int rsnd_gen1_probe(struct platform_device *pdev, 287static int rsnd_gen1_probe(struct platform_device *pdev,
391 struct rsnd_priv *priv) 288 struct rsnd_priv *priv)
392{ 289{
393 struct device *dev = rsnd_priv_to_dev(priv);
394 struct rsnd_regmap_field_conf conf_sru[] = { 290 struct rsnd_regmap_field_conf conf_sru[] = {
395 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 291 RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00),
396 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 292 RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08),
@@ -440,16 +336,14 @@ static int rsnd_gen1_probe(struct platform_device *pdev,
440 int ret_adg; 336 int ret_adg;
441 int ret_ssi; 337 int ret_ssi;
442 338
443 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, conf_sru); 339 ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru);
444 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, conf_adg); 340 ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg);
445 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, conf_ssi); 341 ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi);
446 if (ret_sru < 0 || 342 if (ret_sru < 0 ||
447 ret_adg < 0 || 343 ret_adg < 0 ||
448 ret_ssi < 0) 344 ret_ssi < 0)
449 return ret_sru | ret_adg | ret_ssi; 345 return ret_sru | ret_adg | ret_ssi;
450 346
451 dev_dbg(dev, "Gen1 is probed\n");
452
453 return 0; 347 return 0;
454} 348}
455 349
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h
index 1bccc5515b5a..4e6de6804cfb 100644
--- a/sound/soc/sh/rcar/rsnd.h
+++ b/sound/soc/sh/rcar/rsnd.h
@@ -170,21 +170,47 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod);
170/* 170/*
171 * R-Car DMA 171 * R-Car DMA
172 */ 172 */
173struct rsnd_dma { 173struct rsnd_dma;
174 struct sh_dmae_slave slave; 174struct rsnd_dma_ops {
175 void (*start)(struct rsnd_dma *dma);
176 void (*stop)(struct rsnd_dma *dma);
177 int (*init)(struct rsnd_priv *priv, struct rsnd_dma *dma, int id,
178 struct rsnd_mod *mod_from, struct rsnd_mod *mod_to);
179 void (*quit)(struct rsnd_dma *dma);
180};
181
182struct rsnd_dmaen {
175 struct dma_chan *chan; 183 struct dma_chan *chan;
176 enum dma_transfer_direction dir;
177 dma_addr_t addr;
178}; 184};
179 185
186struct rsnd_dmapp {
187 int dmapp_id;
188 u32 chcr;
189};
190
191struct rsnd_dma {
192 struct rsnd_dma_ops *ops;
193 dma_addr_t src_addr;
194 dma_addr_t dst_addr;
195 union {
196 struct rsnd_dmaen en;
197 struct rsnd_dmapp pp;
198 } dma;
199};
200#define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en)
201#define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp)
202
180void rsnd_dma_start(struct rsnd_dma *dma); 203void rsnd_dma_start(struct rsnd_dma *dma);
181void rsnd_dma_stop(struct rsnd_dma *dma); 204void rsnd_dma_stop(struct rsnd_dma *dma);
182int rsnd_dma_available(struct rsnd_dma *dma); 205int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, int id);
183int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, 206void rsnd_dma_quit(struct rsnd_dma *dma);
184 int is_play, int id); 207int rsnd_dma_probe(struct platform_device *pdev,
185void rsnd_dma_quit(struct rsnd_priv *priv, 208 const struct rsnd_of_data *of_data,
186 struct rsnd_dma *dma); 209 struct rsnd_priv *priv);
210struct dma_chan *rsnd_dma_request_channel(struct device_node *of_node,
211 struct rsnd_mod *mod, char *name);
187 212
213#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
188 214
189/* 215/*
190 * R-Car sound mod 216 * R-Car sound mod
@@ -198,7 +224,7 @@ enum rsnd_mod_type {
198 224
199struct rsnd_mod_ops { 225struct rsnd_mod_ops {
200 char *name; 226 char *name;
201 char* (*dma_name)(struct rsnd_mod *mod); 227 struct dma_chan* (*dma_req)(struct rsnd_mod *mod);
202 int (*probe)(struct rsnd_mod *mod, 228 int (*probe)(struct rsnd_mod *mod,
203 struct rsnd_priv *priv); 229 struct rsnd_priv *priv);
204 int (*remove)(struct rsnd_mod *mod, 230 int (*remove)(struct rsnd_mod *mod,
@@ -213,6 +239,9 @@ struct rsnd_mod_ops {
213 struct rsnd_priv *priv); 239 struct rsnd_priv *priv);
214 int (*pcm_new)(struct rsnd_mod *mod, 240 int (*pcm_new)(struct rsnd_mod *mod,
215 struct snd_soc_pcm_runtime *rtd); 241 struct snd_soc_pcm_runtime *rtd);
242 int (*hw_params)(struct rsnd_mod *mod,
243 struct snd_pcm_substream *substream,
244 struct snd_pcm_hw_params *hw_params);
216 int (*fallback)(struct rsnd_mod *mod, 245 int (*fallback)(struct rsnd_mod *mod,
217 struct rsnd_priv *priv); 246 struct rsnd_priv *priv);
218}; 247};
@@ -236,6 +265,9 @@ struct rsnd_mod {
236 * 2 0: start 1: stop 265 * 2 0: start 1: stop
237 * 3 0: pcm_new 266 * 3 0: pcm_new
238 * 4 0: fallback 267 * 4 0: fallback
268 *
269 * 31 bit is always called (see __rsnd_mod_call)
270 * 31 0: hw_params
239 */ 271 */
240#define __rsnd_mod_shift_probe 0 272#define __rsnd_mod_shift_probe 0
241#define __rsnd_mod_shift_remove 0 273#define __rsnd_mod_shift_remove 0
@@ -245,6 +277,7 @@ struct rsnd_mod {
245#define __rsnd_mod_shift_stop 2 277#define __rsnd_mod_shift_stop 2
246#define __rsnd_mod_shift_pcm_new 3 278#define __rsnd_mod_shift_pcm_new 3
247#define __rsnd_mod_shift_fallback 4 279#define __rsnd_mod_shift_fallback 4
280#define __rsnd_mod_shift_hw_params 31 /* always called */
248 281
249#define __rsnd_mod_call_probe 0 282#define __rsnd_mod_call_probe 0
250#define __rsnd_mod_call_remove 1 283#define __rsnd_mod_call_remove 1
@@ -254,10 +287,10 @@ struct rsnd_mod {
254#define __rsnd_mod_call_stop 1 287#define __rsnd_mod_call_stop 1
255#define __rsnd_mod_call_pcm_new 0 288#define __rsnd_mod_call_pcm_new 0
256#define __rsnd_mod_call_fallback 0 289#define __rsnd_mod_call_fallback 0
290#define __rsnd_mod_call_hw_params 0
257 291
258#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) 292#define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod)))
259#define rsnd_mod_to_dma(mod) (&(mod)->dma) 293#define rsnd_mod_to_dma(mod) (&(mod)->dma)
260#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma)
261#define rsnd_mod_to_io(mod) ((mod)->io) 294#define rsnd_mod_to_io(mod) ((mod)->io)
262#define rsnd_mod_id(mod) ((mod)->id) 295#define rsnd_mod_id(mod) ((mod)->id)
263#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk) 296#define rsnd_mod_hw_start(mod) clk_enable((mod)->clk)
@@ -270,13 +303,14 @@ int rsnd_mod_init(struct rsnd_mod *mod,
270 int id); 303 int id);
271void rsnd_mod_quit(struct rsnd_mod *mod); 304void rsnd_mod_quit(struct rsnd_mod *mod);
272char *rsnd_mod_name(struct rsnd_mod *mod); 305char *rsnd_mod_name(struct rsnd_mod *mod);
273char *rsnd_mod_dma_name(struct rsnd_mod *mod); 306struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod);
274 307
275/* 308/*
276 * R-Car sound DAI 309 * R-Car sound DAI
277 */ 310 */
278#define RSND_DAI_NAME_SIZE 16 311#define RSND_DAI_NAME_SIZE 16
279struct rsnd_dai_stream { 312struct rsnd_dai_stream {
313 char name[RSND_DAI_NAME_SIZE];
280 struct snd_pcm_substream *substream; 314 struct snd_pcm_substream *substream;
281 struct rsnd_mod *mod[RSND_MOD_MAX]; 315 struct rsnd_mod *mod[RSND_MOD_MAX];
282 struct rsnd_dai_path_info *info; /* rcar_snd.h */ 316 struct rsnd_dai_path_info *info; /* rcar_snd.h */
@@ -332,9 +366,7 @@ int rsnd_gen_probe(struct platform_device *pdev,
332void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, 366void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv,
333 struct rsnd_mod *mod, 367 struct rsnd_mod *mod,
334 enum rsnd_reg reg); 368 enum rsnd_reg reg);
335dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, 369phys_addr_t rsnd_gen_get_phy_addr(struct rsnd_priv *priv, int reg_id);
336 struct rsnd_mod *mod,
337 int is_play, int is_from);
338 370
339#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) 371#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1)
340#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) 372#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2)
@@ -390,6 +422,11 @@ struct rsnd_priv {
390 void *adg; 422 void *adg;
391 423
392 /* 424 /*
425 * below value will be filled on rsnd_dma_probe()
426 */
427 void *dma;
428
429 /*
393 * below value will be filled on rsnd_ssi_probe() 430 * below value will be filled on rsnd_ssi_probe()
394 */ 431 */
395 void *ssi; 432 void *ssi;
@@ -415,19 +452,6 @@ struct rsnd_priv {
415#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) 452#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags)
416#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) 453#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags)
417 454
418#define rsnd_info_is_playback(priv, type) \
419({ \
420 struct rcar_snd_info *info = rsnd_priv_to_info(priv); \
421 int i, is_play = 0; \
422 for (i = 0; i < info->dai_info_nr; i++) { \
423 if (info->dai_info[i].playback.type == (type)->info) { \
424 is_play = 1; \
425 break; \
426 } \
427 } \
428 is_play; \
429})
430
431/* 455/*
432 * rsnd_kctrl 456 * rsnd_kctrl
433 */ 457 */
@@ -506,6 +530,7 @@ void rsnd_ssi_remove(struct platform_device *pdev,
506struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); 530struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id);
507int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); 531int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod);
508int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod); 532int rsnd_ssi_is_dma_mode(struct rsnd_mod *mod);
533int rsnd_ssi_use_busif(struct rsnd_mod *mod);
509 534
510/* 535/*
511 * R-Car DVC 536 * R-Car DVC
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c
new file mode 100644
index 000000000000..a68517afe615
--- /dev/null
+++ b/sound/soc/sh/rcar/rsrc-card.c
@@ -0,0 +1,512 @@
1/*
2 * Renesas Sampling Rate Convert Sound Card for DPCM
3 *
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6 *
7 * based on ${LINUX}/sound/soc/generic/simple-card.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/clk.h>
14#include <linux/device.h>
15#include <linux/module.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
18#include <linux/platform_device.h>
19#include <linux/string.h>
20#include <sound/jack.h>
21#include <sound/soc.h>
22#include <sound/soc-dai.h>
23
24struct rsrc_card_of_data {
25 const char *prefix;
26 const struct snd_soc_dapm_route *routes;
27 int num_routes;
28};
29
30static const struct snd_soc_dapm_route routes_ssi0_ak4642[] = {
31 {"ak4642 Playback", NULL, "DAI0 Playback"},
32 {"DAI0 Capture", NULL, "ak4642 Capture"},
33};
34
35static const struct rsrc_card_of_data routes_of_ssi0_ak4642 = {
36 .prefix = "ak4642",
37 .routes = routes_ssi0_ak4642,
38 .num_routes = ARRAY_SIZE(routes_ssi0_ak4642),
39};
40
41static const struct of_device_id rsrc_card_of_match[] = {
42 { .compatible = "renesas,rsrc-card,lager", .data = &routes_of_ssi0_ak4642 },
43 { .compatible = "renesas,rsrc-card,koelsch", .data = &routes_of_ssi0_ak4642 },
44 {},
45};
46MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
47
48struct rsrc_card_dai {
49 const char *name;
50 unsigned int fmt;
51 unsigned int sysclk;
52 struct clk *clk;
53};
54
55#define RSRC_FB_NUM 2 /* FE/BE */
56#define IDX_CPU 0
57#define IDX_CODEC 1
58struct rsrc_card_priv {
59 struct snd_soc_card snd_card;
60 struct rsrc_card_dai_props {
61 struct rsrc_card_dai cpu_dai;
62 struct rsrc_card_dai codec_dai;
63 } dai_props[RSRC_FB_NUM];
64 struct snd_soc_codec_conf codec_conf;
65 struct snd_soc_dai_link dai_link[RSRC_FB_NUM];
66 u32 convert_rate;
67};
68
69#define rsrc_priv_to_dev(priv) ((priv)->snd_card.dev)
70#define rsrc_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
71#define rsrc_priv_to_props(priv, i) ((priv)->dai_props + i)
72#define rsrc_dev_to_of_data(dev) (of_match_device(rsrc_card_of_match, (dev))->data)
73
74static int rsrc_card_startup(struct snd_pcm_substream *substream)
75{
76 struct snd_soc_pcm_runtime *rtd = substream->private_data;
77 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
78 struct rsrc_card_dai_props *dai_props =
79 &priv->dai_props[rtd - rtd->card->rtd];
80 int ret;
81
82 ret = clk_prepare_enable(dai_props->cpu_dai.clk);
83 if (ret)
84 return ret;
85
86 ret = clk_prepare_enable(dai_props->codec_dai.clk);
87 if (ret)
88 clk_disable_unprepare(dai_props->cpu_dai.clk);
89
90 return ret;
91}
92
93static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
97 struct rsrc_card_dai_props *dai_props =
98 &priv->dai_props[rtd - rtd->card->rtd];
99
100 clk_disable_unprepare(dai_props->cpu_dai.clk);
101
102 clk_disable_unprepare(dai_props->codec_dai.clk);
103}
104
105static struct snd_soc_ops rsrc_card_ops = {
106 .startup = rsrc_card_startup,
107 .shutdown = rsrc_card_shutdown,
108};
109
110static int __rsrc_card_dai_init(struct snd_soc_dai *dai,
111 struct rsrc_card_dai *set)
112{
113 int ret;
114
115 if (set->fmt) {
116 ret = snd_soc_dai_set_fmt(dai, set->fmt);
117 if (ret && ret != -ENOTSUPP) {
118 dev_err(dai->dev, "set_fmt error\n");
119 goto err;
120 }
121 }
122
123 if (set->sysclk) {
124 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
125 if (ret && ret != -ENOTSUPP) {
126 dev_err(dai->dev, "set_sysclk error\n");
127 goto err;
128 }
129 }
130
131 ret = 0;
132
133err:
134 return ret;
135}
136
137static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
138{
139 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
140 struct snd_soc_dai *codec = rtd->codec_dai;
141 struct snd_soc_dai *cpu = rtd->cpu_dai;
142 struct rsrc_card_dai_props *dai_props;
143 int num, ret;
144
145 num = rtd - rtd->card->rtd;
146 dai_props = &priv->dai_props[num];
147 ret = __rsrc_card_dai_init(codec, &dai_props->codec_dai);
148 if (ret < 0)
149 return ret;
150
151 ret = __rsrc_card_dai_init(cpu, &dai_props->cpu_dai);
152 if (ret < 0)
153 return ret;
154
155 return 0;
156}
157
158static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
159 struct snd_pcm_hw_params *params)
160{
161 struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
162 struct snd_interval *rate = hw_param_interval(params,
163 SNDRV_PCM_HW_PARAM_RATE);
164
165 if (!priv->convert_rate)
166 return 0;
167
168 rate->min = rate->max = priv->convert_rate;
169
170 return 0;
171}
172
173static int
174rsrc_card_sub_parse_of(struct rsrc_card_priv *priv,
175 struct device_node *np,
176 struct rsrc_card_dai *dai,
177 struct snd_soc_dai_link *dai_link,
178 int *args_count)
179{
180 struct device *dev = rsrc_priv_to_dev(priv);
181 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
182 struct of_phandle_args args;
183 struct device_node **p_node;
184 struct clk *clk;
185 const char **dai_name;
186 const char **name;
187 u32 val;
188 int ret;
189
190 if (args_count) {
191 p_node = &dai_link->cpu_of_node;
192 dai_name = &dai_link->cpu_dai_name;
193 name = &dai_link->cpu_name;
194 } else {
195 p_node = &dai_link->codec_of_node;
196 dai_name = &dai_link->codec_dai_name;
197 name = &dai_link->codec_name;
198 }
199
200 if (!np) {
201 /* use snd-soc-dummy */
202 *p_node = NULL;
203 *dai_name = "snd-soc-dummy-dai";
204 *name = "snd-soc-dummy";
205 return 0;
206 }
207
208 /*
209 * Get node via "sound-dai = <&phandle port>"
210 * it will be used as xxx_of_node on soc_bind_dai_link()
211 */
212 ret = of_parse_phandle_with_args(np, "sound-dai",
213 "#sound-dai-cells", 0, &args);
214 if (ret)
215 return ret;
216
217 *p_node = args.np;
218
219 /* Get dai->name */
220 ret = snd_soc_of_get_dai_name(np, dai_name);
221 if (ret < 0)
222 return ret;
223
224 /*
225 * FIXME
226 *
227 * rsrc assumes DPCM playback/capture
228 */
229 dai_link->dpcm_playback = 1;
230 dai_link->dpcm_capture = 1;
231
232 if (args_count) {
233 *args_count = args.args_count;
234 dai_link->dynamic = 1;
235 } else {
236 dai_link->no_pcm = 1;
237 priv->codec_conf.of_node = (*p_node);
238 priv->codec_conf.name_prefix = of_data->prefix;
239 }
240
241 /*
242 * Parse dai->sysclk come from "clocks = <&xxx>"
243 * (if system has common clock)
244 * or "system-clock-frequency = <xxx>"
245 * or device's module clock.
246 */
247 if (of_property_read_bool(np, "clocks")) {
248 clk = of_clk_get(np, 0);
249 if (IS_ERR(clk)) {
250 ret = PTR_ERR(clk);
251 return ret;
252 }
253
254 dai->sysclk = clk_get_rate(clk);
255 dai->clk = clk;
256 } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
257 dai->sysclk = val;
258 } else {
259 clk = of_clk_get(args.np, 0);
260 if (!IS_ERR(clk))
261 dai->sysclk = clk_get_rate(clk);
262 }
263
264 return 0;
265}
266
267static int rsrc_card_parse_daifmt(struct device_node *node,
268 struct rsrc_card_priv *priv,
269 struct device_node *codec,
270 int idx)
271{
272 struct device_node *bitclkmaster = NULL;
273 struct device_node *framemaster = NULL;
274 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
275 struct rsrc_card_dai *cpu_dai = &dai_props->cpu_dai;
276 struct rsrc_card_dai *codec_dai = &dai_props->codec_dai;
277 unsigned int daifmt;
278
279 daifmt = snd_soc_of_parse_daifmt(node, NULL,
280 &bitclkmaster, &framemaster);
281 daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
282
283 if (!bitclkmaster && !framemaster)
284 return -EINVAL;
285
286 if (codec == bitclkmaster)
287 daifmt |= (codec == framemaster) ?
288 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
289 else
290 daifmt |= (codec == framemaster) ?
291 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
292
293 cpu_dai->fmt = daifmt;
294 codec_dai->fmt = daifmt;
295
296 of_node_put(bitclkmaster);
297 of_node_put(framemaster);
298
299 return 0;
300}
301
302static int rsrc_card_dai_link_of(struct device_node *node,
303 struct rsrc_card_priv *priv,
304 int idx)
305{
306 struct device *dev = rsrc_priv_to_dev(priv);
307 struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
308 struct rsrc_card_dai_props *dai_props = rsrc_priv_to_props(priv, idx);
309 struct device_node *cpu = NULL;
310 struct device_node *codec = NULL;
311 char *name;
312 char prop[128];
313 int ret, cpu_args;
314
315 cpu = of_get_child_by_name(node, "cpu");
316 codec = of_get_child_by_name(node, "codec");
317
318 if (!cpu || !codec) {
319 ret = -EINVAL;
320 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
321 goto dai_link_of_err;
322 }
323
324 ret = rsrc_card_parse_daifmt(node, priv, codec, idx);
325 if (ret < 0)
326 goto dai_link_of_err;
327
328 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CPU) ? cpu : NULL,
329 &dai_props->cpu_dai,
330 dai_link,
331 &cpu_args);
332 if (ret < 0)
333 goto dai_link_of_err;
334
335 ret = rsrc_card_sub_parse_of(priv, (idx == IDX_CODEC) ? codec : NULL,
336 &dai_props->codec_dai,
337 dai_link,
338 NULL);
339 if (ret < 0)
340 goto dai_link_of_err;
341
342 if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
343 ret = -EINVAL;
344 goto dai_link_of_err;
345 }
346
347 /* Simple Card assumes platform == cpu */
348 dai_link->platform_of_node = dai_link->cpu_of_node;
349
350 /* DAI link name is created from CPU/CODEC dai name */
351 name = devm_kzalloc(dev,
352 strlen(dai_link->cpu_dai_name) +
353 strlen(dai_link->codec_dai_name) + 2,
354 GFP_KERNEL);
355 if (!name) {
356 ret = -ENOMEM;
357 goto dai_link_of_err;
358 }
359
360 sprintf(name, "%s-%s", dai_link->cpu_dai_name,
361 dai_link->codec_dai_name);
362 dai_link->name = dai_link->stream_name = name;
363 dai_link->ops = &rsrc_card_ops;
364 dai_link->init = rsrc_card_dai_init;
365
366 if (idx == IDX_CODEC)
367 dai_link->be_hw_params_fixup = rsrc_card_be_hw_params_fixup;
368
369 dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
370 dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
371 dai_link->cpu_dai_name,
372 dai_props->cpu_dai.fmt,
373 dai_props->cpu_dai.sysclk);
374 dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
375 dai_link->codec_dai_name,
376 dai_props->codec_dai.fmt,
377 dai_props->codec_dai.sysclk);
378
379 /*
380 * In soc_bind_dai_link() will check cpu name after
381 * of_node matching if dai_link has cpu_dai_name.
382 * but, it will never match if name was created by
383 * fmt_single_name() remove cpu_dai_name if cpu_args
384 * was 0. See:
385 * fmt_single_name()
386 * fmt_multiple_name()
387 */
388 if (!cpu_args)
389 dai_link->cpu_dai_name = NULL;
390
391dai_link_of_err:
392 of_node_put(cpu);
393 of_node_put(codec);
394
395 return ret;
396}
397
398static int rsrc_card_parse_of(struct device_node *node,
399 struct rsrc_card_priv *priv)
400{
401 struct device *dev = rsrc_priv_to_dev(priv);
402 const struct rsrc_card_of_data *of_data = rsrc_dev_to_of_data(dev);
403 int ret;
404 int i;
405
406 if (!node)
407 return -EINVAL;
408
409 /* Parse the card name from DT */
410 snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
411
412 /* DAPM routes */
413 priv->snd_card.of_dapm_routes = of_data->routes;
414 priv->snd_card.num_of_dapm_routes = of_data->num_routes;
415
416 /* sampling rate convert */
417 of_property_read_u32(node, "convert-rate", &priv->convert_rate);
418
419 dev_dbg(dev, "New rsrc-audio-card: %s (%d)\n",
420 priv->snd_card.name ? priv->snd_card.name : "",
421 priv->convert_rate);
422
423 /* FE/BE */
424 for (i = 0; i < RSRC_FB_NUM; i++) {
425 ret = rsrc_card_dai_link_of(node, priv, i);
426 if (ret < 0)
427 return ret;
428 }
429
430 if (!priv->snd_card.name)
431 priv->snd_card.name = priv->snd_card.dai_link->name;
432
433 return 0;
434}
435
436/* Decrease the reference count of the device nodes */
437static int rsrc_card_unref(struct snd_soc_card *card)
438{
439 struct snd_soc_dai_link *dai_link;
440 int num_links;
441
442 for (num_links = 0, dai_link = card->dai_link;
443 num_links < card->num_links;
444 num_links++, dai_link++) {
445 of_node_put(dai_link->cpu_of_node);
446 of_node_put(dai_link->codec_of_node);
447 }
448 return 0;
449}
450
451static int rsrc_card_probe(struct platform_device *pdev)
452{
453 struct rsrc_card_priv *priv;
454 struct snd_soc_dai_link *dai_link;
455 struct device_node *np = pdev->dev.of_node;
456 struct device *dev = &pdev->dev;
457 int ret;
458
459 /* Allocate the private data */
460 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
461 if (!priv)
462 return -ENOMEM;
463
464 /* Init snd_soc_card */
465 priv->snd_card.owner = THIS_MODULE;
466 priv->snd_card.dev = dev;
467 dai_link = priv->dai_link;
468 priv->snd_card.dai_link = dai_link;
469 priv->snd_card.num_links = RSRC_FB_NUM;
470 priv->snd_card.codec_conf = &priv->codec_conf;
471 priv->snd_card.num_configs = 1;
472
473 ret = rsrc_card_parse_of(np, priv);
474 if (ret < 0) {
475 if (ret != -EPROBE_DEFER)
476 dev_err(dev, "parse error %d\n", ret);
477 goto err;
478 }
479
480 snd_soc_card_set_drvdata(&priv->snd_card, priv);
481
482 ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
483 if (ret >= 0)
484 return ret;
485err:
486 rsrc_card_unref(&priv->snd_card);
487
488 return ret;
489}
490
491static int rsrc_card_remove(struct platform_device *pdev)
492{
493 struct snd_soc_card *card = platform_get_drvdata(pdev);
494
495 return rsrc_card_unref(card);
496}
497
498static struct platform_driver rsrc_card = {
499 .driver = {
500 .name = "renesas-src-audio-card",
501 .of_match_table = rsrc_card_of_match,
502 },
503 .probe = rsrc_card_probe,
504 .remove = rsrc_card_remove,
505};
506
507module_platform_driver(rsrc_card);
508
509MODULE_ALIAS("platform:renesas-src-audio-card");
510MODULE_LICENSE("GPL");
511MODULE_DESCRIPTION("Renesas Sampling Rate Convert Sound Card");
512MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index c77d059edc84..3beb32eb412a 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -22,16 +22,20 @@
22struct rsnd_src { 22struct rsnd_src {
23 struct rsnd_src_platform_info *info; /* rcar_snd.h */ 23 struct rsnd_src_platform_info *info; /* rcar_snd.h */
24 struct rsnd_mod mod; 24 struct rsnd_mod mod;
25 struct rsnd_kctrl_cfg_s sen; /* sync convert enable */
26 struct rsnd_kctrl_cfg_s sync; /* sync convert */
27 u32 convert_rate; /* sampling rate convert */
25 int err; 28 int err;
26}; 29};
27 30
28#define RSND_SRC_NAME_SIZE 16 31#define RSND_SRC_NAME_SIZE 16
29 32
30#define rsnd_src_convert_rate(p) ((p)->info->convert_rate) 33#define rsnd_enable_sync_convert(src) ((src)->sen.val)
34#define rsnd_src_of_node(priv) \
35 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src")
36
31#define rsnd_mod_to_src(_mod) \ 37#define rsnd_mod_to_src(_mod) \
32 container_of((_mod), struct rsnd_src, mod) 38 container_of((_mod), struct rsnd_src, mod)
33#define rsnd_src_dma_available(src) \
34 rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod))
35 39
36#define for_each_rsnd_src(pos, priv, i) \ 40#define for_each_rsnd_src(pos, priv, i) \
37 for ((i) = 0; \ 41 for ((i) = 0; \
@@ -113,6 +117,17 @@ struct rsnd_src {
113/* 117/*
114 * Gen1/Gen2 common functions 118 * Gen1/Gen2 common functions
115 */ 119 */
120static struct dma_chan *rsnd_src_dma_req(struct rsnd_mod *mod)
121{
122 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
123 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
124 int is_play = rsnd_io_is_play(io);
125
126 return rsnd_dma_request_channel(rsnd_src_of_node(priv),
127 mod,
128 is_play ? "rx" : "tx");
129}
130
116int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 131int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod,
117 int use_busif) 132 int use_busif)
118{ 133{
@@ -220,6 +235,30 @@ int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod)
220 return 0; 235 return 0;
221} 236}
222 237
238static u32 rsnd_src_convert_rate(struct rsnd_src *src)
239{
240 struct rsnd_mod *mod = &src->mod;
241 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
242 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
243 u32 convert_rate;
244
245 if (!runtime)
246 return 0;
247
248 if (!rsnd_enable_sync_convert(src))
249 return src->convert_rate;
250
251 convert_rate = src->sync.val;
252
253 if (!convert_rate)
254 convert_rate = src->convert_rate;
255
256 if (!convert_rate)
257 convert_rate = runtime->rate;
258
259 return convert_rate;
260}
261
223unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 262unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv,
224 struct rsnd_dai_stream *io, 263 struct rsnd_dai_stream *io,
225 struct snd_pcm_runtime *runtime) 264 struct snd_pcm_runtime *runtime)
@@ -276,7 +315,43 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod)
276 return 0; 315 return 0;
277} 316}
278 317
279static int rsnd_src_init(struct rsnd_mod *mod) 318static int rsnd_src_hw_params(struct rsnd_mod *mod,
319 struct snd_pcm_substream *substream,
320 struct snd_pcm_hw_params *fe_params)
321{
322 struct rsnd_src *src = rsnd_mod_to_src(mod);
323 struct snd_soc_pcm_runtime *fe = substream->private_data;
324
325 /* default value (mainly for non-DT) */
326 src->convert_rate = src->info->convert_rate;
327
328 /*
329 * SRC assumes that it is used under DPCM if user want to use
330 * sampling rate convert. Then, SRC should be FE.
331 * And then, this function will be called *after* BE settings.
332 * this means, each BE already has fixuped hw_params.
333 * see
334 * dpcm_fe_dai_hw_params()
335 * dpcm_be_dai_hw_params()
336 */
337 if (fe->dai_link->dynamic) {
338 int stream = substream->stream;
339 struct snd_soc_dpcm *dpcm;
340 struct snd_pcm_hw_params *be_params;
341
342 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
343 be_params = &dpcm->hw_params;
344
345 if (params_rate(fe_params) != params_rate(be_params))
346 src->convert_rate = params_rate(be_params);
347 }
348 }
349
350 return 0;
351}
352
353static int rsnd_src_init(struct rsnd_mod *mod,
354 struct rsnd_priv *priv)
280{ 355{
281 struct rsnd_src *src = rsnd_mod_to_src(mod); 356 struct rsnd_src *src = rsnd_mod_to_src(mod);
282 357
@@ -284,6 +359,9 @@ static int rsnd_src_init(struct rsnd_mod *mod)
284 359
285 src->err = 0; 360 src->err = 0;
286 361
362 /* reset sync convert_rate */
363 src->sync.val = 0;
364
287 /* 365 /*
288 * Initialize the operation of the SRC internal circuits 366 * Initialize the operation of the SRC internal circuits
289 * see rsnd_src_start() 367 * see rsnd_src_start()
@@ -305,6 +383,11 @@ static int rsnd_src_quit(struct rsnd_mod *mod,
305 dev_warn(dev, "%s[%d] under/over flow err = %d\n", 383 dev_warn(dev, "%s[%d] under/over flow err = %d\n",
306 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); 384 rsnd_mod_name(mod), rsnd_mod_id(mod), src->err);
307 385
386 src->convert_rate = 0;
387
388 /* reset sync convert_rate */
389 src->sync.val = 0;
390
308 return 0; 391 return 0;
309} 392}
310 393
@@ -448,23 +531,12 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod)
448 return 0; 531 return 0;
449} 532}
450 533
451static int rsnd_src_probe_gen1(struct rsnd_mod *mod,
452 struct rsnd_priv *priv)
453{
454 struct device *dev = rsnd_priv_to_dev(priv);
455
456 dev_dbg(dev, "%s[%d] (Gen1) is probed\n",
457 rsnd_mod_name(mod), rsnd_mod_id(mod));
458
459 return 0;
460}
461
462static int rsnd_src_init_gen1(struct rsnd_mod *mod, 534static int rsnd_src_init_gen1(struct rsnd_mod *mod,
463 struct rsnd_priv *priv) 535 struct rsnd_priv *priv)
464{ 536{
465 int ret; 537 int ret;
466 538
467 ret = rsnd_src_init(mod); 539 ret = rsnd_src_init(mod, priv);
468 if (ret < 0) 540 if (ret < 0)
469 return ret; 541 return ret;
470 542
@@ -505,11 +577,12 @@ static int rsnd_src_stop_gen1(struct rsnd_mod *mod,
505 577
506static struct rsnd_mod_ops rsnd_src_gen1_ops = { 578static struct rsnd_mod_ops rsnd_src_gen1_ops = {
507 .name = SRC_NAME, 579 .name = SRC_NAME,
508 .probe = rsnd_src_probe_gen1, 580 .dma_req = rsnd_src_dma_req,
509 .init = rsnd_src_init_gen1, 581 .init = rsnd_src_init_gen1,
510 .quit = rsnd_src_quit, 582 .quit = rsnd_src_quit,
511 .start = rsnd_src_start_gen1, 583 .start = rsnd_src_start_gen1,
512 .stop = rsnd_src_stop_gen1, 584 .stop = rsnd_src_stop_gen1,
585 .hw_params = rsnd_src_hw_params,
513}; 586};
514 587
515/* 588/*
@@ -607,13 +680,17 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data)
607 680
608 if (rsnd_src_error_record_gen2(mod)) { 681 if (rsnd_src_error_record_gen2(mod)) {
609 struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 682 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
683 struct rsnd_src *src = rsnd_mod_to_src(mod);
610 struct device *dev = rsnd_priv_to_dev(priv); 684 struct device *dev = rsnd_priv_to_dev(priv);
611 685
612 _rsnd_src_stop_gen2(mod);
613 _rsnd_src_start_gen2(mod);
614
615 dev_dbg(dev, "%s[%d] restart\n", 686 dev_dbg(dev, "%s[%d] restart\n",
616 rsnd_mod_name(mod), rsnd_mod_id(mod)); 687 rsnd_mod_name(mod), rsnd_mod_id(mod));
688
689 _rsnd_src_stop_gen2(mod);
690 if (src->err < 1024)
691 _rsnd_src_start_gen2(mod);
692 else
693 dev_warn(dev, "no more SRC restart\n");
617 } 694 }
618 695
619 return IRQ_HANDLED; 696 return IRQ_HANDLED;
@@ -627,6 +704,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
627 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 704 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
628 struct rsnd_src *src = rsnd_mod_to_src(mod); 705 struct rsnd_src *src = rsnd_mod_to_src(mod);
629 u32 convert_rate = rsnd_src_convert_rate(src); 706 u32 convert_rate = rsnd_src_convert_rate(src);
707 u32 cr, route;
630 uint ratio; 708 uint ratio;
631 int ret; 709 int ret;
632 710
@@ -647,13 +725,21 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod)
647 if (ret < 0) 725 if (ret < 0)
648 return ret; 726 return ret;
649 727
650 rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); 728 cr = 0x00011110;
651 729 route = 0x0;
652 if (convert_rate) { 730 if (convert_rate) {
653 /* Gen1/Gen2 are not compatible */ 731 route = 0x1;
654 rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 732
733 if (rsnd_enable_sync_convert(src)) {
734 cr |= 0x1;
735 route |= rsnd_io_is_play(io) ?
736 (0x1 << 24) : (0x1 << 25);
737 }
655 } 738 }
656 739
740 rsnd_mod_write(mod, SRC_SRCCR, cr);
741 rsnd_mod_write(mod, SRC_ROUTE_MODE0, route);
742
657 switch (rsnd_mod_id(mod)) { 743 switch (rsnd_mod_id(mod)) {
658 case 5: 744 case 5:
659 case 6: 745 case 6:
@@ -708,24 +794,12 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod,
708 IRQF_SHARED, 794 IRQF_SHARED,
709 dev_name(dev), mod); 795 dev_name(dev), mod);
710 if (ret) 796 if (ret)
711 goto rsnd_src_probe_gen2_fail; 797 return ret;
712 } 798 }
713 799
714 ret = rsnd_dma_init(priv, 800 ret = rsnd_dma_init(priv,
715 rsnd_mod_to_dma(mod), 801 rsnd_mod_to_dma(mod),
716 rsnd_info_is_playback(priv, src),
717 src->info->dma_id); 802 src->info->dma_id);
718 if (ret)
719 goto rsnd_src_probe_gen2_fail;
720
721 dev_dbg(dev, "%s[%d] (Gen2) is probed\n",
722 rsnd_mod_name(mod), rsnd_mod_id(mod));
723
724 return ret;
725
726rsnd_src_probe_gen2_fail:
727 dev_err(dev, "%s[%d] (Gen2) failed\n",
728 rsnd_mod_name(mod), rsnd_mod_id(mod));
729 803
730 return ret; 804 return ret;
731} 805}
@@ -733,7 +807,7 @@ rsnd_src_probe_gen2_fail:
733static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 807static int rsnd_src_remove_gen2(struct rsnd_mod *mod,
734 struct rsnd_priv *priv) 808 struct rsnd_priv *priv)
735{ 809{
736 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 810 rsnd_dma_quit(rsnd_mod_to_dma(mod));
737 811
738 return 0; 812 return 0;
739} 813}
@@ -743,7 +817,7 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod,
743{ 817{
744 int ret; 818 int ret;
745 819
746 ret = rsnd_src_init(mod); 820 ret = rsnd_src_init(mod, priv);
747 if (ret < 0) 821 if (ret < 0)
748 return ret; 822 return ret;
749 823
@@ -778,14 +852,91 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod,
778 return ret; 852 return ret;
779} 853}
780 854
855static void rsnd_src_reconvert_update(struct rsnd_mod *mod)
856{
857 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
858 struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
859 struct rsnd_src *src = rsnd_mod_to_src(mod);
860 u32 convert_rate = rsnd_src_convert_rate(src);
861 u32 fsrate;
862
863 if (!runtime)
864 return;
865
866 if (!convert_rate)
867 convert_rate = runtime->rate;
868
869 fsrate = 0x0400000 / convert_rate * runtime->rate;
870
871 /* update IFS */
872 rsnd_mod_write(mod, SRC_IFSVR, fsrate);
873}
874
875static int rsnd_src_pcm_new(struct rsnd_mod *mod,
876 struct snd_soc_pcm_runtime *rtd)
877{
878 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
879 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
880 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
881 struct rsnd_src *src = rsnd_mod_to_src(mod);
882 int ret;
883
884 /*
885 * enable SRC sync convert if possible
886 */
887
888 /*
889 * Gen1 is not supported
890 */
891 if (rsnd_is_gen1(priv))
892 return 0;
893
894 /*
895 * SRC sync convert needs clock master
896 */
897 if (!rsnd_rdai_is_clk_master(rdai))
898 return 0;
899
900 /*
901 * We can't use SRC sync convert
902 * if it has DVC
903 */
904 if (rsnd_io_to_mod_dvc(io))
905 return 0;
906
907 /*
908 * enable sync convert
909 */
910 ret = rsnd_kctrl_new_s(mod, rtd,
911 rsnd_io_is_play(io) ?
912 "SRC Out Rate Switch" :
913 "SRC In Rate Switch",
914 rsnd_src_reconvert_update,
915 &src->sen, 1);
916 if (ret < 0)
917 return ret;
918
919 ret = rsnd_kctrl_new_s(mod, rtd,
920 rsnd_io_is_play(io) ?
921 "SRC Out Rate" :
922 "SRC In Rate",
923 rsnd_src_reconvert_update,
924 &src->sync, 192000);
925
926 return ret;
927}
928
781static struct rsnd_mod_ops rsnd_src_gen2_ops = { 929static struct rsnd_mod_ops rsnd_src_gen2_ops = {
782 .name = SRC_NAME, 930 .name = SRC_NAME,
931 .dma_req = rsnd_src_dma_req,
783 .probe = rsnd_src_probe_gen2, 932 .probe = rsnd_src_probe_gen2,
784 .remove = rsnd_src_remove_gen2, 933 .remove = rsnd_src_remove_gen2,
785 .init = rsnd_src_init_gen2, 934 .init = rsnd_src_init_gen2,
786 .quit = rsnd_src_quit, 935 .quit = rsnd_src_quit,
787 .start = rsnd_src_start_gen2, 936 .start = rsnd_src_start_gen2,
788 .stop = rsnd_src_stop_gen2, 937 .stop = rsnd_src_stop_gen2,
938 .hw_params = rsnd_src_hw_params,
939 .pcm_new = rsnd_src_pcm_new,
789}; 940};
790 941
791struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 942struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id)
@@ -810,7 +961,7 @@ static void rsnd_of_parse_src(struct platform_device *pdev,
810 if (!of_data) 961 if (!of_data)
811 return; 962 return;
812 963
813 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 964 src_node = rsnd_src_of_node(priv);
814 if (!src_node) 965 if (!src_node)
815 return; 966 return;
816 967
@@ -893,8 +1044,6 @@ int rsnd_src_probe(struct platform_device *pdev,
893 ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); 1044 ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i);
894 if (ret) 1045 if (ret)
895 return ret; 1046 return ret;
896
897 dev_dbg(dev, "SRC%d probed\n", i);
898 } 1047 }
899 1048
900 return 0; 1049 return 0;
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index f7cb1fd635a0..7bb9c087f3dc 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -80,13 +80,13 @@ struct rsnd_ssi {
80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 80#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) 81#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma))
82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0) 82#define rsnd_ssi_pio_available(ssi) ((ssi)->info->irq > 0)
83#define rsnd_ssi_dma_available(ssi) \
84 rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod))
85#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) 83#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent)
86#define rsnd_ssi_mode_flags(p) ((p)->info->flags) 84#define rsnd_ssi_mode_flags(p) ((p)->info->flags)
87#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) 85#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id)
86#define rsnd_ssi_of_node(priv) \
87 of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,ssi")
88 88
89static int rsnd_ssi_use_busif(struct rsnd_mod *mod) 89int rsnd_ssi_use_busif(struct rsnd_mod *mod)
90{ 90{
91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); 91 struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 92 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
@@ -416,11 +416,14 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
416 /* 416 /*
417 * restart SSI 417 * restart SSI
418 */ 418 */
419 rsnd_ssi_stop(mod, priv);
420 rsnd_ssi_start(mod, priv);
421
422 dev_dbg(dev, "%s[%d] restart\n", 419 dev_dbg(dev, "%s[%d] restart\n",
423 rsnd_mod_name(mod), rsnd_mod_id(mod)); 420 rsnd_mod_name(mod), rsnd_mod_id(mod));
421
422 rsnd_ssi_stop(mod, priv);
423 if (ssi->err < 1024)
424 rsnd_ssi_start(mod, priv);
425 else
426 dev_warn(dev, "no more SSI restart\n");
424 } 427 }
425 428
426 rsnd_ssi_record_error(ssi, status); 429 rsnd_ssi_record_error(ssi, status);
@@ -442,12 +445,6 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod,
442 rsnd_ssi_interrupt, 445 rsnd_ssi_interrupt,
443 IRQF_SHARED, 446 IRQF_SHARED,
444 dev_name(dev), ssi); 447 dev_name(dev), ssi);
445 if (ret)
446 dev_err(dev, "%s[%d] (PIO) request interrupt failed\n",
447 rsnd_mod_name(mod), rsnd_mod_id(mod));
448 else
449 dev_dbg(dev, "%s[%d] (PIO) is probed\n",
450 rsnd_mod_name(mod), rsnd_mod_id(mod));
451 448
452 return ret; 449 return ret;
453} 450}
@@ -474,23 +471,11 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
474 IRQF_SHARED, 471 IRQF_SHARED,
475 dev_name(dev), ssi); 472 dev_name(dev), ssi);
476 if (ret) 473 if (ret)
477 goto rsnd_ssi_dma_probe_fail; 474 return ret;
478 475
479 ret = rsnd_dma_init( 476 ret = rsnd_dma_init(
480 priv, rsnd_mod_to_dma(mod), 477 priv, rsnd_mod_to_dma(mod),
481 rsnd_info_is_playback(priv, ssi),
482 dma_id); 478 dma_id);
483 if (ret)
484 goto rsnd_ssi_dma_probe_fail;
485
486 dev_dbg(dev, "%s[%d] (DMA) is probed\n",
487 rsnd_mod_name(mod), rsnd_mod_id(mod));
488
489 return ret;
490
491rsnd_ssi_dma_probe_fail:
492 dev_err(dev, "%s[%d] (DMA) is failed\n",
493 rsnd_mod_name(mod), rsnd_mod_id(mod));
494 479
495 return ret; 480 return ret;
496} 481}
@@ -502,7 +487,7 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
502 struct device *dev = rsnd_priv_to_dev(priv); 487 struct device *dev = rsnd_priv_to_dev(priv);
503 int irq = ssi->info->irq; 488 int irq = ssi->info->irq;
504 489
505 rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 490 rsnd_dma_quit(rsnd_mod_to_dma(mod));
506 491
507 /* PIO will request IRQ again */ 492 /* PIO will request IRQ again */
508 devm_free_irq(dev, irq, ssi); 493 devm_free_irq(dev, irq, ssi);
@@ -554,14 +539,25 @@ static int rsnd_ssi_dma_stop(struct rsnd_mod *mod,
554 return 0; 539 return 0;
555} 540}
556 541
557static char *rsnd_ssi_dma_name(struct rsnd_mod *mod) 542static struct dma_chan *rsnd_ssi_dma_req(struct rsnd_mod *mod)
558{ 543{
559 return rsnd_ssi_use_busif(mod) ? "ssiu" : SSI_NAME; 544 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
545 struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
546 int is_play = rsnd_io_is_play(io);
547 char *name;
548
549 if (rsnd_ssi_use_busif(mod))
550 name = is_play ? "rxu" : "txu";
551 else
552 name = is_play ? "rx" : "tx";
553
554 return rsnd_dma_request_channel(rsnd_ssi_of_node(priv),
555 mod, name);
560} 556}
561 557
562static struct rsnd_mod_ops rsnd_ssi_dma_ops = { 558static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
563 .name = SSI_NAME, 559 .name = SSI_NAME,
564 .dma_name = rsnd_ssi_dma_name, 560 .dma_req = rsnd_ssi_dma_req,
565 .probe = rsnd_ssi_dma_probe, 561 .probe = rsnd_ssi_dma_probe,
566 .remove = rsnd_ssi_dma_remove, 562 .remove = rsnd_ssi_dma_remove,
567 .init = rsnd_ssi_init, 563 .init = rsnd_ssi_init,
@@ -636,7 +632,7 @@ static void rsnd_of_parse_ssi(struct platform_device *pdev,
636 if (!of_data) 632 if (!of_data)
637 return; 633 return;
638 634
639 node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); 635 node = rsnd_ssi_of_node(priv);
640 if (!node) 636 if (!node)
641 return; 637 return;
642 638