diff options
-rw-r--r-- | include/sound/rcar_snd.h | 1 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.c | 29 | ||||
-rw-r--r-- | sound/soc/codecs/rt286.h | 7 | ||||
-rw-r--r-- | sound/soc/pxa/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/pxa/corgi.c | 16 | ||||
-rw-r--r-- | sound/soc/pxa/e740_wm9705.c | 20 | ||||
-rw-r--r-- | sound/soc/pxa/e750_wm9705.c | 20 | ||||
-rw-r--r-- | sound/soc/pxa/hx4700.c | 8 | ||||
-rw-r--r-- | sound/soc/pxa/magician.c | 21 | ||||
-rw-r--r-- | sound/soc/pxa/palm27x.c | 15 | ||||
-rw-r--r-- | sound/soc/pxa/spitz.c | 22 | ||||
-rw-r--r-- | sound/soc/pxa/ttc-dkb.c | 4 | ||||
-rw-r--r-- | sound/soc/sh/rcar/adg.c | 14 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 111 | ||||
-rw-r--r-- | sound/soc/sh/rcar/dvc.c | 63 | ||||
-rw-r--r-- | sound/soc/sh/rcar/gen.c | 15 | ||||
-rw-r--r-- | sound/soc/sh/rcar/rsnd.h | 81 | ||||
-rw-r--r-- | sound/soc/sh/rcar/src.c | 269 | ||||
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 100 |
19 files changed, 437 insertions, 381 deletions
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h index 83284cae464c..4cecd0c175f6 100644 --- a/include/sound/rcar_snd.h +++ b/include/sound/rcar_snd.h | |||
@@ -55,6 +55,7 @@ struct rsnd_ssi_platform_info { | |||
55 | struct rsnd_src_platform_info { | 55 | struct rsnd_src_platform_info { |
56 | u32 convert_rate; /* sampling rate convert */ | 56 | u32 convert_rate; /* sampling rate convert */ |
57 | int dma_id; /* for Gen2 SCU */ | 57 | int dma_id; /* for Gen2 SCU */ |
58 | int irq; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | /* | 61 | /* |
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c index d0698891b69e..f374840a5a7c 100644 --- a/sound/soc/codecs/rt286.c +++ b/sound/soc/codecs/rt286.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "rt286.h" | 34 | #include "rt286.h" |
35 | 35 | ||
36 | #define RT286_VENDOR_ID 0x10ec0286 | 36 | #define RT286_VENDOR_ID 0x10ec0286 |
37 | #define RT288_VENDOR_ID 0x10ec0288 | ||
37 | 38 | ||
38 | struct rt286_priv { | 39 | struct rt286_priv { |
39 | struct regmap *regmap; | 40 | struct regmap *regmap; |
@@ -1171,6 +1172,7 @@ static const struct regmap_config rt286_regmap = { | |||
1171 | 1172 | ||
1172 | static const struct i2c_device_id rt286_i2c_id[] = { | 1173 | static const struct i2c_device_id rt286_i2c_id[] = { |
1173 | {"rt286", 0}, | 1174 | {"rt286", 0}, |
1175 | {"rt288", 0}, | ||
1174 | {} | 1176 | {} |
1175 | }; | 1177 | }; |
1176 | MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); | 1178 | MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); |
@@ -1191,6 +1193,17 @@ static struct dmi_system_id force_combo_jack_table[] = { | |||
1191 | { } | 1193 | { } |
1192 | }; | 1194 | }; |
1193 | 1195 | ||
1196 | static struct dmi_system_id dmi_dell_dino[] = { | ||
1197 | { | ||
1198 | .ident = "Dell Dino", | ||
1199 | .matches = { | ||
1200 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
1201 | DMI_MATCH(DMI_BOARD_NAME, "0144P8") | ||
1202 | } | ||
1203 | }, | ||
1204 | { } | ||
1205 | }; | ||
1206 | |||
1194 | static int rt286_i2c_probe(struct i2c_client *i2c, | 1207 | static int rt286_i2c_probe(struct i2c_client *i2c, |
1195 | const struct i2c_device_id *id) | 1208 | const struct i2c_device_id *id) |
1196 | { | 1209 | { |
@@ -1213,7 +1226,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1213 | 1226 | ||
1214 | regmap_read(rt286->regmap, | 1227 | regmap_read(rt286->regmap, |
1215 | RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); | 1228 | RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); |
1216 | if (ret != RT286_VENDOR_ID) { | 1229 | if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) { |
1217 | dev_err(&i2c->dev, | 1230 | dev_err(&i2c->dev, |
1218 | "Device with ID register %x is not rt286\n", ret); | 1231 | "Device with ID register %x is not rt286\n", ret); |
1219 | return -ENODEV; | 1232 | return -ENODEV; |
@@ -1226,7 +1239,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1226 | if (pdata) | 1239 | if (pdata) |
1227 | rt286->pdata = *pdata; | 1240 | rt286->pdata = *pdata; |
1228 | 1241 | ||
1229 | if (dmi_check_system(force_combo_jack_table)) | 1242 | if (dmi_check_system(force_combo_jack_table) || |
1243 | dmi_check_system(dmi_dell_dino)) | ||
1230 | rt286->pdata.cbj_en = true; | 1244 | rt286->pdata.cbj_en = true; |
1231 | 1245 | ||
1232 | regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); | 1246 | regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); |
@@ -1265,6 +1279,17 @@ static int rt286_i2c_probe(struct i2c_client *i2c, | |||
1265 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); | 1279 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); |
1266 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); | 1280 | regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); |
1267 | 1281 | ||
1282 | if (dmi_check_system(dmi_dell_dino)) { | ||
1283 | regmap_update_bits(rt286->regmap, | ||
1284 | RT286_SET_GPIO_MASK, 0x40, 0x40); | ||
1285 | regmap_update_bits(rt286->regmap, | ||
1286 | RT286_SET_GPIO_DIRECTION, 0x40, 0x40); | ||
1287 | regmap_update_bits(rt286->regmap, | ||
1288 | RT286_SET_GPIO_DATA, 0x40, 0x40); | ||
1289 | regmap_update_bits(rt286->regmap, | ||
1290 | RT286_GPIO_CTRL, 0xc, 0x8); | ||
1291 | } | ||
1292 | |||
1268 | if (rt286->i2c->irq) { | 1293 | if (rt286->i2c->irq) { |
1269 | ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, | 1294 | ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, |
1270 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); | 1295 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); |
diff --git a/sound/soc/codecs/rt286.h b/sound/soc/codecs/rt286.h index b539b7320a79..7130edb152ef 100644 --- a/sound/soc/codecs/rt286.h +++ b/sound/soc/codecs/rt286.h | |||
@@ -117,6 +117,12 @@ | |||
117 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0) | 117 | VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0) |
118 | #define RT286_PROC_COEF\ | 118 | #define RT286_PROC_COEF\ |
119 | VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0) | 119 | VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0) |
120 | #define RT286_SET_GPIO_MASK\ | ||
121 | VERB_CMD(AC_VERB_SET_GPIO_MASK, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
122 | #define RT286_SET_GPIO_DIRECTION\ | ||
123 | VERB_CMD(AC_VERB_SET_GPIO_DIRECTION, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
124 | #define RT286_SET_GPIO_DATA\ | ||
125 | VERB_CMD(AC_VERB_SET_GPIO_DATA, RT286_AUDIO_FUNCTION_GROUP, 0) | ||
120 | 126 | ||
121 | /* Index registers */ | 127 | /* Index registers */ |
122 | #define RT286_A_BIAS_CTRL1 0x01 | 128 | #define RT286_A_BIAS_CTRL1 0x01 |
@@ -131,6 +137,7 @@ | |||
131 | #define RT286_POWER_CTRL3 0x0f | 137 | #define RT286_POWER_CTRL3 0x0f |
132 | #define RT286_MIC1_DET_CTRL 0x19 | 138 | #define RT286_MIC1_DET_CTRL 0x19 |
133 | #define RT286_MISC_CTRL1 0x20 | 139 | #define RT286_MISC_CTRL1 0x20 |
140 | #define RT286_GPIO_CTRL 0x29 | ||
134 | #define RT286_IRQ_CTRL 0x33 | 141 | #define RT286_IRQ_CTRL 0x33 |
135 | #define RT286_PLL_CTRL1 0x49 | 142 | #define RT286_PLL_CTRL1 0x49 |
136 | #define RT286_CBJ_CTRL1 0x4f | 143 | #define RT286_CBJ_CTRL1 0x4f |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 2434b6d61675..39cea80846c3 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -140,7 +140,7 @@ config SND_PXA910_SOC | |||
140 | Marvell PXA910 reference platform. | 140 | Marvell PXA910 reference platform. |
141 | 141 | ||
142 | config SND_SOC_TTC_DKB | 142 | config SND_SOC_TTC_DKB |
143 | bool "SoC Audio support for TTC DKB" | 143 | tristate "SoC Audio support for TTC DKB" |
144 | depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y | 144 | depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y |
145 | select PXA_SSP | 145 | select PXA_SSP |
146 | select SND_PXA_SOC_SSP | 146 | select SND_PXA_SOC_SSP |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index b7cd0a71fd70..3580d10c9f28 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -259,20 +259,6 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = { | |||
259 | corgi_set_spk), | 259 | corgi_set_spk), |
260 | }; | 260 | }; |
261 | 261 | ||
262 | /* | ||
263 | * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device | ||
264 | */ | ||
265 | static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) | ||
266 | { | ||
267 | struct snd_soc_codec *codec = rtd->codec; | ||
268 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
269 | |||
270 | snd_soc_dapm_nc_pin(dapm, "LLINEIN"); | ||
271 | snd_soc_dapm_nc_pin(dapm, "RLINEIN"); | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | /* corgi digital audio interface glue - connects codec <--> CPU */ | 262 | /* corgi digital audio interface glue - connects codec <--> CPU */ |
277 | static struct snd_soc_dai_link corgi_dai = { | 263 | static struct snd_soc_dai_link corgi_dai = { |
278 | .name = "WM8731", | 264 | .name = "WM8731", |
@@ -281,7 +267,6 @@ static struct snd_soc_dai_link corgi_dai = { | |||
281 | .codec_dai_name = "wm8731-hifi", | 267 | .codec_dai_name = "wm8731-hifi", |
282 | .platform_name = "pxa-pcm-audio", | 268 | .platform_name = "pxa-pcm-audio", |
283 | .codec_name = "wm8731.0-001b", | 269 | .codec_name = "wm8731.0-001b", |
284 | .init = corgi_wm8731_init, | ||
285 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 270 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
286 | SND_SOC_DAIFMT_CBS_CFS, | 271 | SND_SOC_DAIFMT_CBS_CFS, |
287 | .ops = &corgi_ops, | 272 | .ops = &corgi_ops, |
@@ -300,6 +285,7 @@ static struct snd_soc_card corgi = { | |||
300 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), | 285 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), |
301 | .dapm_routes = corgi_audio_map, | 286 | .dapm_routes = corgi_audio_map, |
302 | .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), | 287 | .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), |
288 | .fully_routed = true, | ||
303 | }; | 289 | }; |
304 | 290 | ||
305 | static int corgi_probe(struct platform_device *pdev) | 291 | static int corgi_probe(struct platform_device *pdev) |
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 7c691aae8af2..d72e124a3676 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c | |||
@@ -88,24 +88,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
88 | {"Mic Amp", NULL, "Mic (Internal)"}, | 88 | {"Mic Amp", NULL, "Mic (Internal)"}, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) | ||
92 | { | ||
93 | struct snd_soc_codec *codec = rtd->codec; | ||
94 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
95 | |||
96 | snd_soc_dapm_nc_pin(dapm, "HPOUTL"); | ||
97 | snd_soc_dapm_nc_pin(dapm, "HPOUTR"); | ||
98 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
99 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
100 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
101 | snd_soc_dapm_nc_pin(dapm, "CDINL"); | ||
102 | snd_soc_dapm_nc_pin(dapm, "CDINR"); | ||
103 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
104 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static struct snd_soc_dai_link e740_dai[] = { | 91 | static struct snd_soc_dai_link e740_dai[] = { |
110 | { | 92 | { |
111 | .name = "AC97", | 93 | .name = "AC97", |
@@ -114,7 +96,6 @@ static struct snd_soc_dai_link e740_dai[] = { | |||
114 | .codec_dai_name = "wm9705-hifi", | 96 | .codec_dai_name = "wm9705-hifi", |
115 | .platform_name = "pxa-pcm-audio", | 97 | .platform_name = "pxa-pcm-audio", |
116 | .codec_name = "wm9705-codec", | 98 | .codec_name = "wm9705-codec", |
117 | .init = e740_ac97_init, | ||
118 | }, | 99 | }, |
119 | { | 100 | { |
120 | .name = "AC97 Aux", | 101 | .name = "AC97 Aux", |
@@ -136,6 +117,7 @@ static struct snd_soc_card e740 = { | |||
136 | .num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets), | 117 | .num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets), |
137 | .dapm_routes = audio_map, | 118 | .dapm_routes = audio_map, |
138 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 119 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
120 | .fully_routed = true, | ||
139 | }; | 121 | }; |
140 | 122 | ||
141 | static struct gpio e740_audio_gpios[] = { | 123 | static struct gpio e740_audio_gpios[] = { |
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 30544b65b5a8..48f2d7c2e68c 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c | |||
@@ -70,24 +70,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
70 | {"MIC1", NULL, "Mic (Internal)"}, | 70 | {"MIC1", NULL, "Mic (Internal)"}, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) | ||
74 | { | ||
75 | struct snd_soc_codec *codec = rtd->codec; | ||
76 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
77 | |||
78 | snd_soc_dapm_nc_pin(dapm, "LOUT"); | ||
79 | snd_soc_dapm_nc_pin(dapm, "ROUT"); | ||
80 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
81 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
82 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
83 | snd_soc_dapm_nc_pin(dapm, "CDINL"); | ||
84 | snd_soc_dapm_nc_pin(dapm, "CDINR"); | ||
85 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
86 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static struct snd_soc_dai_link e750_dai[] = { | 73 | static struct snd_soc_dai_link e750_dai[] = { |
92 | { | 74 | { |
93 | .name = "AC97", | 75 | .name = "AC97", |
@@ -96,7 +78,6 @@ static struct snd_soc_dai_link e750_dai[] = { | |||
96 | .codec_dai_name = "wm9705-hifi", | 78 | .codec_dai_name = "wm9705-hifi", |
97 | .platform_name = "pxa-pcm-audio", | 79 | .platform_name = "pxa-pcm-audio", |
98 | .codec_name = "wm9705-codec", | 80 | .codec_name = "wm9705-codec", |
99 | .init = e750_ac97_init, | ||
100 | /* use ops to check startup state */ | 81 | /* use ops to check startup state */ |
101 | }, | 82 | }, |
102 | { | 83 | { |
@@ -119,6 +100,7 @@ static struct snd_soc_card e750 = { | |||
119 | .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets), | 100 | .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets), |
120 | .dapm_routes = audio_map, | 101 | .dapm_routes = audio_map, |
121 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 102 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
103 | .fully_routed = true, | ||
122 | }; | 104 | }; |
123 | 105 | ||
124 | static struct gpio e750_audio_gpios[] = { | 106 | static struct gpio e750_audio_gpios[] = { |
diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index ce26551052a3..73eb5ddf9753 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c | |||
@@ -127,15 +127,8 @@ static const struct snd_soc_dapm_route hx4700_audio_map[] = { | |||
127 | static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) | 127 | static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) |
128 | { | 128 | { |
129 | struct snd_soc_codec *codec = rtd->codec; | 129 | struct snd_soc_codec *codec = rtd->codec; |
130 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
131 | int err; | 130 | int err; |
132 | 131 | ||
133 | /* NC codec pins */ | ||
134 | /* FIXME: is anything connected here? */ | ||
135 | snd_soc_dapm_nc_pin(dapm, "MOUT1"); | ||
136 | snd_soc_dapm_nc_pin(dapm, "MICEXT"); | ||
137 | snd_soc_dapm_nc_pin(dapm, "AUX"); | ||
138 | |||
139 | /* Jack detection API stuff */ | 132 | /* Jack detection API stuff */ |
140 | err = snd_soc_jack_new(codec, "Headphone Jack", | 133 | err = snd_soc_jack_new(codec, "Headphone Jack", |
141 | SND_JACK_HEADPHONE, &hs_jack); | 134 | SND_JACK_HEADPHONE, &hs_jack); |
@@ -184,6 +177,7 @@ static struct snd_soc_card snd_soc_card_hx4700 = { | |||
184 | .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), | 177 | .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), |
185 | .dapm_routes = hx4700_audio_map, | 178 | .dapm_routes = hx4700_audio_map, |
186 | .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), | 179 | .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), |
180 | .fully_routed = true, | ||
187 | }; | 181 | }; |
188 | 182 | ||
189 | static struct gpio hx4700_audio_gpios[] = { | 183 | static struct gpio hx4700_audio_gpios[] = { |
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 259e048681c0..241d0be42d7a 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
@@ -391,25 +391,6 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = { | |||
391 | magician_get_input, magician_set_input), | 391 | magician_get_input, magician_set_input), |
392 | }; | 392 | }; |
393 | 393 | ||
394 | /* | ||
395 | * Logic for a uda1380 as connected on a HTC Magician | ||
396 | */ | ||
397 | static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) | ||
398 | { | ||
399 | struct snd_soc_codec *codec = rtd->codec; | ||
400 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
401 | |||
402 | /* NC codec pins */ | ||
403 | snd_soc_dapm_nc_pin(dapm, "VOUTLHP"); | ||
404 | snd_soc_dapm_nc_pin(dapm, "VOUTRHP"); | ||
405 | |||
406 | /* FIXME: is anything connected here? */ | ||
407 | snd_soc_dapm_nc_pin(dapm, "VINL"); | ||
408 | snd_soc_dapm_nc_pin(dapm, "VINR"); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* magician digital audio interface glue - connects codec <--> CPU */ | 394 | /* magician digital audio interface glue - connects codec <--> CPU */ |
414 | static struct snd_soc_dai_link magician_dai[] = { | 395 | static struct snd_soc_dai_link magician_dai[] = { |
415 | { | 396 | { |
@@ -419,7 +400,6 @@ static struct snd_soc_dai_link magician_dai[] = { | |||
419 | .codec_dai_name = "uda1380-hifi-playback", | 400 | .codec_dai_name = "uda1380-hifi-playback", |
420 | .platform_name = "pxa-pcm-audio", | 401 | .platform_name = "pxa-pcm-audio", |
421 | .codec_name = "uda1380-codec.0-0018", | 402 | .codec_name = "uda1380-codec.0-0018", |
422 | .init = magician_uda1380_init, | ||
423 | .ops = &magician_playback_ops, | 403 | .ops = &magician_playback_ops, |
424 | }, | 404 | }, |
425 | { | 405 | { |
@@ -446,6 +426,7 @@ static struct snd_soc_card snd_soc_card_magician = { | |||
446 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | 426 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), |
447 | .dapm_routes = audio_map, | 427 | .dapm_routes = audio_map, |
448 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 428 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
429 | .fully_routed = true, | ||
449 | }; | 430 | }; |
450 | 431 | ||
451 | static struct platform_device *magician_snd_device; | 432 | static struct platform_device *magician_snd_device; |
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 1eebca2f0a97..910336c5ebeb 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c | |||
@@ -68,7 +68,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
68 | {"Ext. Speaker", NULL, "ROUT2"}, | 68 | {"Ext. Speaker", NULL, "ROUT2"}, |
69 | 69 | ||
70 | /* mic connected to MIC1 */ | 70 | /* mic connected to MIC1 */ |
71 | {"Ext. Microphone", NULL, "MIC1"}, | 71 | {"MIC1", NULL, "Ext. Microphone"}, |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static struct snd_soc_card palm27x_asoc; | 74 | static struct snd_soc_card palm27x_asoc; |
@@ -76,18 +76,8 @@ static struct snd_soc_card palm27x_asoc; | |||
76 | static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) | 76 | static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) |
77 | { | 77 | { |
78 | struct snd_soc_codec *codec = rtd->codec; | 78 | struct snd_soc_codec *codec = rtd->codec; |
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
80 | int err; | 79 | int err; |
81 | 80 | ||
82 | /* not connected pins */ | ||
83 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
84 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); | ||
85 | snd_soc_dapm_nc_pin(dapm, "LINEINL"); | ||
86 | snd_soc_dapm_nc_pin(dapm, "LINEINR"); | ||
87 | snd_soc_dapm_nc_pin(dapm, "PCBEEP"); | ||
88 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | ||
89 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | ||
90 | |||
91 | /* Jack detection API stuff */ | 81 | /* Jack detection API stuff */ |
92 | err = snd_soc_jack_new(codec, "Headphone Jack", | 82 | err = snd_soc_jack_new(codec, "Headphone Jack", |
93 | SND_JACK_HEADPHONE, &hs_jack); | 83 | SND_JACK_HEADPHONE, &hs_jack); |
@@ -133,7 +123,8 @@ static struct snd_soc_card palm27x_asoc = { | |||
133 | .dapm_widgets = palm27x_dapm_widgets, | 123 | .dapm_widgets = palm27x_dapm_widgets, |
134 | .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets), | 124 | .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets), |
135 | .dapm_routes = audio_map, | 125 | .dapm_routes = audio_map, |
136 | .num_dapm_routes = ARRAY_SIZE(audio_map) | 126 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
127 | .fully_routed = true, | ||
137 | }; | 128 | }; |
138 | 129 | ||
139 | static int palm27x_asoc_probe(struct platform_device *pdev) | 130 | static int palm27x_asoc_probe(struct platform_device *pdev) |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index a6d680acd907..461123ad5ff2 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -256,26 +256,6 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = { | |||
256 | spitz_set_spk), | 256 | spitz_set_spk), |
257 | }; | 257 | }; |
258 | 258 | ||
259 | /* | ||
260 | * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device | ||
261 | */ | ||
262 | static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) | ||
263 | { | ||
264 | struct snd_soc_codec *codec = rtd->codec; | ||
265 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
266 | |||
267 | /* NC codec pins */ | ||
268 | snd_soc_dapm_nc_pin(dapm, "RINPUT1"); | ||
269 | snd_soc_dapm_nc_pin(dapm, "LINPUT2"); | ||
270 | snd_soc_dapm_nc_pin(dapm, "RINPUT2"); | ||
271 | snd_soc_dapm_nc_pin(dapm, "LINPUT3"); | ||
272 | snd_soc_dapm_nc_pin(dapm, "RINPUT3"); | ||
273 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
274 | snd_soc_dapm_nc_pin(dapm, "MONO1"); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* spitz digital audio interface glue - connects codec <--> CPU */ | 259 | /* spitz digital audio interface glue - connects codec <--> CPU */ |
280 | static struct snd_soc_dai_link spitz_dai = { | 260 | static struct snd_soc_dai_link spitz_dai = { |
281 | .name = "wm8750", | 261 | .name = "wm8750", |
@@ -284,7 +264,6 @@ static struct snd_soc_dai_link spitz_dai = { | |||
284 | .codec_dai_name = "wm8750-hifi", | 264 | .codec_dai_name = "wm8750-hifi", |
285 | .platform_name = "pxa-pcm-audio", | 265 | .platform_name = "pxa-pcm-audio", |
286 | .codec_name = "wm8750.0-001b", | 266 | .codec_name = "wm8750.0-001b", |
287 | .init = spitz_wm8750_init, | ||
288 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 267 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
289 | SND_SOC_DAIFMT_CBS_CFS, | 268 | SND_SOC_DAIFMT_CBS_CFS, |
290 | .ops = &spitz_ops, | 269 | .ops = &spitz_ops, |
@@ -303,6 +282,7 @@ static struct snd_soc_card snd_soc_spitz = { | |||
303 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | 282 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), |
304 | .dapm_routes = spitz_audio_map, | 283 | .dapm_routes = spitz_audio_map, |
305 | .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), | 284 | .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), |
285 | .fully_routed = true, | ||
306 | }; | 286 | }; |
307 | 287 | ||
308 | static int spitz_probe(struct platform_device *pdev) | 288 | static int spitz_probe(struct platform_device *pdev) |
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index e3d7257ad09c..5001dbb9b257 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c | |||
@@ -76,10 +76,6 @@ static const struct snd_soc_dapm_route ttc_audio_map[] = { | |||
76 | static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) | 76 | static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) |
77 | { | 77 | { |
78 | struct snd_soc_codec *codec = rtd->codec; | 78 | struct snd_soc_codec *codec = rtd->codec; |
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
80 | |||
81 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); | ||
82 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); | ||
83 | 79 | ||
84 | /* Headset jack detection */ | 80 | /* Headset jack detection */ |
85 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE | 81 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE |
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 14d1a7193469..7ac35c9d1cb8 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -57,8 +57,7 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) | |||
57 | return (0x6 + ws) << 8; | 57 | return (0x6 + ws) << 8; |
58 | } | 58 | } |
59 | 59 | ||
60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | 60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, |
61 | struct rsnd_mod *mod, | ||
62 | struct rsnd_dai_stream *io) | 61 | struct rsnd_dai_stream *io) |
63 | { | 62 | { |
64 | int id = rsnd_mod_id(mod); | 63 | int id = rsnd_mod_id(mod); |
@@ -75,12 +74,11 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | |||
75 | return 0; | 74 | return 0; |
76 | } | 75 | } |
77 | 76 | ||
78 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | 77 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod, |
79 | struct rsnd_mod *mod, | ||
80 | struct rsnd_dai_stream *io, | 78 | struct rsnd_dai_stream *io, |
81 | u32 timsel) | 79 | u32 timsel) |
82 | { | 80 | { |
83 | int is_play = rsnd_dai_is_play(rdai, io); | 81 | int is_play = rsnd_io_is_play(io); |
84 | int id = rsnd_mod_id(mod); | 82 | int id = rsnd_mod_id(mod); |
85 | int shift = (id % 2) ? 16 : 0; | 83 | int shift = (id % 2) ? 16 : 0; |
86 | u32 mask, ws; | 84 | u32 mask, ws; |
@@ -122,7 +120,6 @@ static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | |||
122 | } | 120 | } |
123 | 121 | ||
124 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | 122 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, |
125 | struct rsnd_dai *rdai, | ||
126 | struct rsnd_dai_stream *io, | 123 | struct rsnd_dai_stream *io, |
127 | unsigned int src_rate, | 124 | unsigned int src_rate, |
128 | unsigned int dst_rate) | 125 | unsigned int dst_rate) |
@@ -178,7 +175,7 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
178 | return -EIO; | 175 | return -EIO; |
179 | } | 176 | } |
180 | 177 | ||
181 | ret = rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val); | 178 | ret = rsnd_adg_set_src_timsel_gen2(mod, io, val); |
182 | if (ret < 0) { | 179 | if (ret < 0) { |
183 | dev_err(dev, "timsel error\n"); | 180 | dev_err(dev, "timsel error\n"); |
184 | return ret; | 181 | return ret; |
@@ -190,12 +187,11 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
190 | } | 187 | } |
191 | 188 | ||
192 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 189 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
193 | struct rsnd_dai *rdai, | ||
194 | struct rsnd_dai_stream *io) | 190 | struct rsnd_dai_stream *io) |
195 | { | 191 | { |
196 | u32 val = rsnd_adg_ssi_ws_timing_gen2(io); | 192 | u32 val = rsnd_adg_ssi_ws_timing_gen2(io); |
197 | 193 | ||
198 | return rsnd_adg_set_src_timsel_gen2(rdai, mod, io, val); | 194 | return rsnd_adg_set_src_timsel_gen2(mod, io, val); |
199 | } | 195 | } |
200 | 196 | ||
201 | int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, | 197 | int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 75308bbc2ce8..1b53605f7154 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -149,16 +149,16 @@ char *rsnd_mod_dma_name(struct rsnd_mod *mod) | |||
149 | return mod->ops->dma_name(mod); | 149 | return mod->ops->dma_name(mod); |
150 | } | 150 | } |
151 | 151 | ||
152 | void rsnd_mod_init(struct rsnd_priv *priv, | 152 | void rsnd_mod_init(struct rsnd_mod *mod, |
153 | struct rsnd_mod *mod, | ||
154 | struct rsnd_mod_ops *ops, | 153 | struct rsnd_mod_ops *ops, |
154 | struct clk *clk, | ||
155 | enum rsnd_mod_type type, | 155 | enum rsnd_mod_type type, |
156 | int id) | 156 | int id) |
157 | { | 157 | { |
158 | mod->priv = priv; | ||
159 | mod->id = id; | 158 | mod->id = id; |
160 | mod->ops = ops; | 159 | mod->ops = ops; |
161 | mod->type = type; | 160 | mod->type = type; |
161 | mod->clk = clk; | ||
162 | } | 162 | } |
163 | 163 | ||
164 | /* | 164 | /* |
@@ -412,7 +412,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
412 | /* | 412 | /* |
413 | * rsnd_dai functions | 413 | * rsnd_dai functions |
414 | */ | 414 | */ |
415 | #define __rsnd_mod_call(mod, func, rdai...) \ | 415 | #define __rsnd_mod_call(mod, func, param...) \ |
416 | ({ \ | 416 | ({ \ |
417 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 417 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
418 | struct device *dev = rsnd_priv_to_dev(priv); \ | 418 | struct device *dev = rsnd_priv_to_dev(priv); \ |
@@ -422,18 +422,18 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
422 | if ((mod->status & mask) == call) { \ | 422 | if ((mod->status & mask) == call) { \ |
423 | dev_dbg(dev, "%s[%d] %s\n", \ | 423 | dev_dbg(dev, "%s[%d] %s\n", \ |
424 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 424 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ |
425 | ret = (mod)->ops->func(mod, rdai); \ | 425 | ret = (mod)->ops->func(mod, param); \ |
426 | mod->status = (mod->status & ~mask) | (~call & mask); \ | 426 | mod->status = (mod->status & ~mask) | (~call & mask); \ |
427 | } \ | 427 | } \ |
428 | ret; \ | 428 | ret; \ |
429 | }) | 429 | }) |
430 | 430 | ||
431 | #define rsnd_mod_call(mod, func, rdai...) \ | 431 | #define rsnd_mod_call(mod, func, param...) \ |
432 | (!(mod) ? -ENODEV : \ | 432 | (!(mod) ? -ENODEV : \ |
433 | !((mod)->ops->func) ? 0 : \ | 433 | !((mod)->ops->func) ? 0 : \ |
434 | __rsnd_mod_call(mod, func, rdai)) | 434 | __rsnd_mod_call(mod, func, param)) |
435 | 435 | ||
436 | #define rsnd_dai_call(fn, io, rdai...) \ | 436 | #define rsnd_dai_call(fn, io, param...) \ |
437 | ({ \ | 437 | ({ \ |
438 | struct rsnd_mod *mod; \ | 438 | struct rsnd_mod *mod; \ |
439 | int ret = 0, i; \ | 439 | int ret = 0, i; \ |
@@ -441,7 +441,7 @@ u32 rsnd_get_adinr(struct rsnd_mod *mod) | |||
441 | mod = (io)->mod[i]; \ | 441 | mod = (io)->mod[i]; \ |
442 | if (!mod) \ | 442 | if (!mod) \ |
443 | continue; \ | 443 | continue; \ |
444 | ret = rsnd_mod_call(mod, fn, rdai); \ | 444 | ret = rsnd_mod_call(mod, fn, param); \ |
445 | if (ret < 0) \ | 445 | if (ret < 0) \ |
446 | break; \ | 446 | break; \ |
447 | } \ | 447 | } \ |
@@ -477,17 +477,7 @@ static void rsnd_dai_disconnect(struct rsnd_mod *mod, | |||
477 | io->mod[mod->type] = NULL; | 477 | io->mod[mod->type] = NULL; |
478 | } | 478 | } |
479 | 479 | ||
480 | int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) | 480 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id) |
481 | { | ||
482 | int id = rdai - priv->rdai; | ||
483 | |||
484 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) | ||
485 | return -EINVAL; | ||
486 | |||
487 | return id; | ||
488 | } | ||
489 | |||
490 | struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) | ||
491 | { | 481 | { |
492 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) | 482 | if ((id < 0) || (id >= rsnd_rdai_nr(priv))) |
493 | return NULL; | 483 | return NULL; |
@@ -499,12 +489,7 @@ static struct rsnd_dai *rsnd_dai_to_rdai(struct snd_soc_dai *dai) | |||
499 | { | 489 | { |
500 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); | 490 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); |
501 | 491 | ||
502 | return rsnd_dai_get(priv, dai->id); | 492 | return rsnd_rdai_get(priv, dai->id); |
503 | } | ||
504 | |||
505 | int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io) | ||
506 | { | ||
507 | return &rdai->playback == io; | ||
508 | } | 493 | } |
509 | 494 | ||
510 | /* | 495 | /* |
@@ -598,20 +583,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
598 | if (ret < 0) | 583 | if (ret < 0) |
599 | goto dai_trigger_end; | 584 | goto dai_trigger_end; |
600 | 585 | ||
601 | ret = rsnd_dai_call(init, io, rdai); | 586 | ret = rsnd_dai_call(init, io, priv); |
602 | if (ret < 0) | 587 | if (ret < 0) |
603 | goto dai_trigger_end; | 588 | goto dai_trigger_end; |
604 | 589 | ||
605 | ret = rsnd_dai_call(start, io, rdai); | 590 | ret = rsnd_dai_call(start, io, priv); |
606 | if (ret < 0) | 591 | if (ret < 0) |
607 | goto dai_trigger_end; | 592 | goto dai_trigger_end; |
608 | break; | 593 | break; |
609 | case SNDRV_PCM_TRIGGER_STOP: | 594 | case SNDRV_PCM_TRIGGER_STOP: |
610 | ret = rsnd_dai_call(stop, io, rdai); | 595 | ret = rsnd_dai_call(stop, io, priv); |
611 | if (ret < 0) | 596 | if (ret < 0) |
612 | goto dai_trigger_end; | 597 | goto dai_trigger_end; |
613 | 598 | ||
614 | ret = rsnd_dai_call(quit, io, rdai); | 599 | ret = rsnd_dai_call(quit, io, priv); |
615 | if (ret < 0) | 600 | if (ret < 0) |
616 | goto dai_trigger_end; | 601 | goto dai_trigger_end; |
617 | 602 | ||
@@ -873,15 +858,15 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
873 | priv->rdai = rdai; | 858 | priv->rdai = rdai; |
874 | 859 | ||
875 | for (i = 0; i < dai_nr; i++) { | 860 | for (i = 0; i < dai_nr; i++) { |
876 | rdai[i].info = &info->dai_info[i]; | ||
877 | 861 | ||
878 | pmod = rdai[i].info->playback.ssi; | 862 | pmod = info->dai_info[i].playback.ssi; |
879 | cmod = rdai[i].info->capture.ssi; | 863 | cmod = info->dai_info[i].capture.ssi; |
880 | 864 | ||
881 | /* | 865 | /* |
882 | * init rsnd_dai | 866 | * init rsnd_dai |
883 | */ | 867 | */ |
884 | snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); | 868 | snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); |
869 | rdai[i].priv = priv; | ||
885 | 870 | ||
886 | /* | 871 | /* |
887 | * init snd_soc_dai_driver | 872 | * init snd_soc_dai_driver |
@@ -895,6 +880,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
895 | drv[i].playback.channels_max = 2; | 880 | drv[i].playback.channels_max = 2; |
896 | 881 | ||
897 | rdai[i].playback.info = &info->dai_info[i].playback; | 882 | rdai[i].playback.info = &info->dai_info[i].playback; |
883 | rdai[i].playback.rdai = rdai + i; | ||
898 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); | 884 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); |
899 | } | 885 | } |
900 | if (cmod) { | 886 | if (cmod) { |
@@ -904,6 +890,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
904 | drv[i].capture.channels_max = 2; | 890 | drv[i].capture.channels_max = 2; |
905 | 891 | ||
906 | rdai[i].capture.info = &info->dai_info[i].capture; | 892 | rdai[i].capture.info = &info->dai_info[i].capture; |
893 | rdai[i].capture.rdai = rdai + i; | ||
907 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); | 894 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); |
908 | } | 895 | } |
909 | 896 | ||
@@ -1037,7 +1024,6 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl, | |||
1037 | } | 1024 | } |
1038 | 1025 | ||
1039 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, | 1026 | static int __rsnd_kctrl_new(struct rsnd_mod *mod, |
1040 | struct rsnd_dai *rdai, | ||
1041 | struct snd_soc_pcm_runtime *rtd, | 1027 | struct snd_soc_pcm_runtime *rtd, |
1042 | const unsigned char *name, | 1028 | const unsigned char *name, |
1043 | struct rsnd_kctrl_cfg *cfg, | 1029 | struct rsnd_kctrl_cfg *cfg, |
@@ -1060,16 +1046,24 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod, | |||
1060 | return -ENOMEM; | 1046 | return -ENOMEM; |
1061 | 1047 | ||
1062 | ret = snd_ctl_add(card, kctrl); | 1048 | ret = snd_ctl_add(card, kctrl); |
1063 | if (ret < 0) | 1049 | if (ret < 0) { |
1050 | snd_ctl_free_one(kctrl); | ||
1064 | return ret; | 1051 | return ret; |
1052 | } | ||
1065 | 1053 | ||
1066 | cfg->update = update; | 1054 | cfg->update = update; |
1055 | cfg->card = card; | ||
1056 | cfg->kctrl = kctrl; | ||
1067 | 1057 | ||
1068 | return 0; | 1058 | return 0; |
1069 | } | 1059 | } |
1070 | 1060 | ||
1061 | void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg) | ||
1062 | { | ||
1063 | snd_ctl_remove(cfg->card, cfg->kctrl); | ||
1064 | } | ||
1065 | |||
1071 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 1066 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
1072 | struct rsnd_dai *rdai, | ||
1073 | struct snd_soc_pcm_runtime *rtd, | 1067 | struct snd_soc_pcm_runtime *rtd, |
1074 | const unsigned char *name, | 1068 | const unsigned char *name, |
1075 | void (*update)(struct rsnd_mod *mod), | 1069 | void (*update)(struct rsnd_mod *mod), |
@@ -1079,11 +1073,10 @@ int rsnd_kctrl_new_m(struct rsnd_mod *mod, | |||
1079 | _cfg->cfg.max = max; | 1073 | _cfg->cfg.max = max; |
1080 | _cfg->cfg.size = RSND_DVC_CHANNELS; | 1074 | _cfg->cfg.size = RSND_DVC_CHANNELS; |
1081 | _cfg->cfg.val = _cfg->val; | 1075 | _cfg->cfg.val = _cfg->val; |
1082 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1076 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1083 | } | 1077 | } |
1084 | 1078 | ||
1085 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 1079 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
1086 | struct rsnd_dai *rdai, | ||
1087 | struct snd_soc_pcm_runtime *rtd, | 1080 | struct snd_soc_pcm_runtime *rtd, |
1088 | const unsigned char *name, | 1081 | const unsigned char *name, |
1089 | void (*update)(struct rsnd_mod *mod), | 1082 | void (*update)(struct rsnd_mod *mod), |
@@ -1093,11 +1086,10 @@ int rsnd_kctrl_new_s(struct rsnd_mod *mod, | |||
1093 | _cfg->cfg.max = max; | 1086 | _cfg->cfg.max = max; |
1094 | _cfg->cfg.size = 1; | 1087 | _cfg->cfg.size = 1; |
1095 | _cfg->cfg.val = &_cfg->val; | 1088 | _cfg->cfg.val = &_cfg->val; |
1096 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1089 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1097 | } | 1090 | } |
1098 | 1091 | ||
1099 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 1092 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
1100 | struct rsnd_dai *rdai, | ||
1101 | struct snd_soc_pcm_runtime *rtd, | 1093 | struct snd_soc_pcm_runtime *rtd, |
1102 | const unsigned char *name, | 1094 | const unsigned char *name, |
1103 | struct rsnd_kctrl_cfg_s *_cfg, | 1095 | struct rsnd_kctrl_cfg_s *_cfg, |
@@ -1109,7 +1101,7 @@ int rsnd_kctrl_new_e(struct rsnd_mod *mod, | |||
1109 | _cfg->cfg.size = 1; | 1101 | _cfg->cfg.size = 1; |
1110 | _cfg->cfg.val = &_cfg->val; | 1102 | _cfg->cfg.val = &_cfg->val; |
1111 | _cfg->cfg.texts = texts; | 1103 | _cfg->cfg.texts = texts; |
1112 | return __rsnd_kctrl_new(mod, rdai, rtd, name, &_cfg->cfg, update); | 1104 | return __rsnd_kctrl_new(mod, rtd, name, &_cfg->cfg, update); |
1113 | } | 1105 | } |
1114 | 1106 | ||
1115 | /* | 1107 | /* |
@@ -1125,11 +1117,11 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1125 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 1117 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
1126 | int ret; | 1118 | int ret; |
1127 | 1119 | ||
1128 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd); | 1120 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rtd); |
1129 | if (ret) | 1121 | if (ret) |
1130 | return ret; | 1122 | return ret; |
1131 | 1123 | ||
1132 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd); | 1124 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rtd); |
1133 | if (ret) | 1125 | if (ret) |
1134 | return ret; | 1126 | return ret; |
1135 | 1127 | ||
@@ -1140,15 +1132,9 @@ static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
1140 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); | 1132 | PREALLOC_BUFFER, PREALLOC_BUFFER_MAX); |
1141 | } | 1133 | } |
1142 | 1134 | ||
1143 | static void rsnd_pcm_free(struct snd_pcm *pcm) | ||
1144 | { | ||
1145 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
1146 | } | ||
1147 | |||
1148 | static struct snd_soc_platform_driver rsnd_soc_platform = { | 1135 | static struct snd_soc_platform_driver rsnd_soc_platform = { |
1149 | .ops = &rsnd_pcm_ops, | 1136 | .ops = &rsnd_pcm_ops, |
1150 | .pcm_new = rsnd_pcm_new, | 1137 | .pcm_new = rsnd_pcm_new, |
1151 | .pcm_free = rsnd_pcm_free, | ||
1152 | }; | 1138 | }; |
1153 | 1139 | ||
1154 | static const struct snd_soc_component_driver rsnd_soc_component = { | 1140 | static const struct snd_soc_component_driver rsnd_soc_component = { |
@@ -1156,13 +1142,11 @@ static const struct snd_soc_component_driver rsnd_soc_component = { | |||
1156 | }; | 1142 | }; |
1157 | 1143 | ||
1158 | static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | 1144 | static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, |
1159 | struct rsnd_dai *rdai, | 1145 | struct rsnd_dai_stream *io) |
1160 | int is_play) | ||
1161 | { | 1146 | { |
1162 | struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; | ||
1163 | int ret; | 1147 | int ret; |
1164 | 1148 | ||
1165 | ret = rsnd_dai_call(probe, io, rdai); | 1149 | ret = rsnd_dai_call(probe, io, priv); |
1166 | if (ret == -EAGAIN) { | 1150 | if (ret == -EAGAIN) { |
1167 | /* | 1151 | /* |
1168 | * Fallback to PIO mode | 1152 | * Fallback to PIO mode |
@@ -1175,7 +1159,7 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | |||
1175 | * rsnd_dma_init() | 1159 | * rsnd_dma_init() |
1176 | * rsnd_ssi_fallback() | 1160 | * rsnd_ssi_fallback() |
1177 | */ | 1161 | */ |
1178 | rsnd_dai_call(remove, io, rdai); | 1162 | rsnd_dai_call(remove, io, priv); |
1179 | 1163 | ||
1180 | /* | 1164 | /* |
1181 | * remove SRC/DVC from DAI, | 1165 | * remove SRC/DVC from DAI, |
@@ -1186,13 +1170,13 @@ static int rsnd_rdai_continuance_probe(struct rsnd_priv *priv, | |||
1186 | /* | 1170 | /* |
1187 | * fallback | 1171 | * fallback |
1188 | */ | 1172 | */ |
1189 | rsnd_dai_call(fallback, io, rdai); | 1173 | rsnd_dai_call(fallback, io, priv); |
1190 | 1174 | ||
1191 | /* | 1175 | /* |
1192 | * retry to "probe". | 1176 | * retry to "probe". |
1193 | * DAI has SSI which is PIO mode only now. | 1177 | * DAI has SSI which is PIO mode only now. |
1194 | */ | 1178 | */ |
1195 | ret = rsnd_dai_call(probe, io, rdai); | 1179 | ret = rsnd_dai_call(probe, io, priv); |
1196 | } | 1180 | } |
1197 | 1181 | ||
1198 | return ret; | 1182 | return ret; |
@@ -1259,11 +1243,11 @@ static int rsnd_probe(struct platform_device *pdev) | |||
1259 | } | 1243 | } |
1260 | 1244 | ||
1261 | for_each_rsnd_dai(rdai, priv, i) { | 1245 | for_each_rsnd_dai(rdai, priv, i) { |
1262 | ret = rsnd_rdai_continuance_probe(priv, rdai, 1); | 1246 | ret = rsnd_rdai_continuance_probe(priv, &rdai->playback); |
1263 | if (ret) | 1247 | if (ret) |
1264 | goto exit_snd_probe; | 1248 | goto exit_snd_probe; |
1265 | 1249 | ||
1266 | ret = rsnd_rdai_continuance_probe(priv, rdai, 0); | 1250 | ret = rsnd_rdai_continuance_probe(priv, &rdai->capture); |
1267 | if (ret) | 1251 | if (ret) |
1268 | goto exit_snd_probe; | 1252 | goto exit_snd_probe; |
1269 | } | 1253 | } |
@@ -1295,8 +1279,8 @@ exit_snd_soc: | |||
1295 | snd_soc_unregister_platform(dev); | 1279 | snd_soc_unregister_platform(dev); |
1296 | exit_snd_probe: | 1280 | exit_snd_probe: |
1297 | for_each_rsnd_dai(rdai, priv, i) { | 1281 | for_each_rsnd_dai(rdai, priv, i) { |
1298 | rsnd_dai_call(remove, &rdai->playback, rdai); | 1282 | rsnd_dai_call(remove, &rdai->playback, priv); |
1299 | rsnd_dai_call(remove, &rdai->capture, rdai); | 1283 | rsnd_dai_call(remove, &rdai->capture, priv); |
1300 | } | 1284 | } |
1301 | 1285 | ||
1302 | return ret; | 1286 | return ret; |
@@ -1311,10 +1295,13 @@ static int rsnd_remove(struct platform_device *pdev) | |||
1311 | pm_runtime_disable(&pdev->dev); | 1295 | pm_runtime_disable(&pdev->dev); |
1312 | 1296 | ||
1313 | for_each_rsnd_dai(rdai, priv, i) { | 1297 | for_each_rsnd_dai(rdai, priv, i) { |
1314 | ret |= rsnd_dai_call(remove, &rdai->playback, rdai); | 1298 | ret |= rsnd_dai_call(remove, &rdai->playback, priv); |
1315 | ret |= rsnd_dai_call(remove, &rdai->capture, rdai); | 1299 | ret |= rsnd_dai_call(remove, &rdai->capture, priv); |
1316 | } | 1300 | } |
1317 | 1301 | ||
1302 | snd_soc_unregister_component(&pdev->dev); | ||
1303 | snd_soc_unregister_platform(&pdev->dev); | ||
1304 | |||
1318 | return ret; | 1305 | return ret; |
1319 | } | 1306 | } |
1320 | 1307 | ||
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c index 5380a4827ba7..d7f9ed959c4e 100644 --- a/sound/soc/sh/rcar/dvc.c +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -17,7 +17,6 @@ | |||
17 | struct rsnd_dvc { | 17 | struct rsnd_dvc { |
18 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ | 18 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ |
19 | struct rsnd_mod mod; | 19 | struct rsnd_mod mod; |
20 | struct clk *clk; | ||
21 | struct rsnd_kctrl_cfg_m volume; | 20 | struct rsnd_kctrl_cfg_m volume; |
22 | struct rsnd_kctrl_cfg_m mute; | 21 | struct rsnd_kctrl_cfg_m mute; |
23 | struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ | 22 | struct rsnd_kctrl_cfg_s ren; /* Ramp Enable */ |
@@ -118,9 +117,8 @@ static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | |||
118 | } | 117 | } |
119 | 118 | ||
120 | static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, | 119 | static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, |
121 | struct rsnd_dai *rdai) | 120 | struct rsnd_priv *priv) |
122 | { | 121 | { |
123 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
124 | struct device *dev = rsnd_priv_to_dev(priv); | 122 | struct device *dev = rsnd_priv_to_dev(priv); |
125 | 123 | ||
126 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", | 124 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", |
@@ -129,12 +127,24 @@ static int rsnd_dvc_probe_gen2(struct rsnd_mod *mod, | |||
129 | return 0; | 127 | return 0; |
130 | } | 128 | } |
131 | 129 | ||
130 | static int rsnd_dvc_remove_gen2(struct rsnd_mod *mod, | ||
131 | struct rsnd_priv *priv) | ||
132 | { | ||
133 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
134 | |||
135 | rsnd_kctrl_remove(dvc->volume); | ||
136 | rsnd_kctrl_remove(dvc->mute); | ||
137 | rsnd_kctrl_remove(dvc->ren); | ||
138 | rsnd_kctrl_remove(dvc->rup); | ||
139 | rsnd_kctrl_remove(dvc->rdown); | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
132 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | 144 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, |
133 | struct rsnd_dai *rdai) | 145 | struct rsnd_priv *priv) |
134 | { | 146 | { |
135 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod); | ||
136 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | 147 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); |
137 | struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod); | ||
138 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 148 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
139 | struct device *dev = rsnd_priv_to_dev(priv); | 149 | struct device *dev = rsnd_priv_to_dev(priv); |
140 | int dvc_id = rsnd_mod_id(dvc_mod); | 150 | int dvc_id = rsnd_mod_id(dvc_mod); |
@@ -153,7 +163,7 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
153 | return -EINVAL; | 163 | return -EINVAL; |
154 | } | 164 | } |
155 | 165 | ||
156 | clk_prepare_enable(dvc->clk); | 166 | rsnd_mod_hw_start(dvc_mod); |
157 | 167 | ||
158 | /* | 168 | /* |
159 | * fixme | 169 | * fixme |
@@ -173,23 +183,21 @@ static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | |||
173 | 183 | ||
174 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | 184 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); |
175 | 185 | ||
176 | rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io); | 186 | rsnd_adg_set_cmd_timsel_gen2(dvc_mod, io); |
177 | 187 | ||
178 | return 0; | 188 | return 0; |
179 | } | 189 | } |
180 | 190 | ||
181 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | 191 | static int rsnd_dvc_quit(struct rsnd_mod *mod, |
182 | struct rsnd_dai *rdai) | 192 | struct rsnd_priv *priv) |
183 | { | 193 | { |
184 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 194 | rsnd_mod_hw_stop(mod); |
185 | |||
186 | clk_disable_unprepare(dvc->clk); | ||
187 | 195 | ||
188 | return 0; | 196 | return 0; |
189 | } | 197 | } |
190 | 198 | ||
191 | static int rsnd_dvc_start(struct rsnd_mod *mod, | 199 | static int rsnd_dvc_start(struct rsnd_mod *mod, |
192 | struct rsnd_dai *rdai) | 200 | struct rsnd_priv *priv) |
193 | { | 201 | { |
194 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | 202 | rsnd_mod_write(mod, CMD_CTRL, 0x10); |
195 | 203 | ||
@@ -197,7 +205,7 @@ static int rsnd_dvc_start(struct rsnd_mod *mod, | |||
197 | } | 205 | } |
198 | 206 | ||
199 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | 207 | static int rsnd_dvc_stop(struct rsnd_mod *mod, |
200 | struct rsnd_dai *rdai) | 208 | struct rsnd_priv *priv) |
201 | { | 209 | { |
202 | rsnd_mod_write(mod, CMD_CTRL, 0); | 210 | rsnd_mod_write(mod, CMD_CTRL, 0); |
203 | 211 | ||
@@ -205,16 +213,16 @@ static int rsnd_dvc_stop(struct rsnd_mod *mod, | |||
205 | } | 213 | } |
206 | 214 | ||
207 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | 215 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, |
208 | struct rsnd_dai *rdai, | ||
209 | struct snd_soc_pcm_runtime *rtd) | 216 | struct snd_soc_pcm_runtime *rtd) |
210 | { | 217 | { |
211 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 218 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
212 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | 219 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); |
220 | int is_play = rsnd_io_is_play(io); | ||
213 | int ret; | 221 | int ret; |
214 | 222 | ||
215 | /* Volume */ | 223 | /* Volume */ |
216 | ret = rsnd_kctrl_new_m(mod, rdai, rtd, | 224 | ret = rsnd_kctrl_new_m(mod, rtd, |
217 | rsnd_dai_is_play(rdai, io) ? | 225 | is_play ? |
218 | "DVC Out Playback Volume" : "DVC In Capture Volume", | 226 | "DVC Out Playback Volume" : "DVC In Capture Volume", |
219 | rsnd_dvc_volume_update, | 227 | rsnd_dvc_volume_update, |
220 | &dvc->volume, 0x00800000 - 1); | 228 | &dvc->volume, 0x00800000 - 1); |
@@ -222,8 +230,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
222 | return ret; | 230 | return ret; |
223 | 231 | ||
224 | /* Mute */ | 232 | /* Mute */ |
225 | ret = rsnd_kctrl_new_m(mod, rdai, rtd, | 233 | ret = rsnd_kctrl_new_m(mod, rtd, |
226 | rsnd_dai_is_play(rdai, io) ? | 234 | is_play ? |
227 | "DVC Out Mute Switch" : "DVC In Mute Switch", | 235 | "DVC Out Mute Switch" : "DVC In Mute Switch", |
228 | rsnd_dvc_volume_update, | 236 | rsnd_dvc_volume_update, |
229 | &dvc->mute, 1); | 237 | &dvc->mute, 1); |
@@ -231,16 +239,16 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
231 | return ret; | 239 | return ret; |
232 | 240 | ||
233 | /* Ramp */ | 241 | /* Ramp */ |
234 | ret = rsnd_kctrl_new_s(mod, rdai, rtd, | 242 | ret = rsnd_kctrl_new_s(mod, rtd, |
235 | rsnd_dai_is_play(rdai, io) ? | 243 | is_play ? |
236 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", | 244 | "DVC Out Ramp Switch" : "DVC In Ramp Switch", |
237 | rsnd_dvc_volume_update, | 245 | rsnd_dvc_volume_update, |
238 | &dvc->ren, 1); | 246 | &dvc->ren, 1); |
239 | if (ret < 0) | 247 | if (ret < 0) |
240 | return ret; | 248 | return ret; |
241 | 249 | ||
242 | ret = rsnd_kctrl_new_e(mod, rdai, rtd, | 250 | ret = rsnd_kctrl_new_e(mod, rtd, |
243 | rsnd_dai_is_play(rdai, io) ? | 251 | is_play ? |
244 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", | 252 | "DVC Out Ramp Up Rate" : "DVC In Ramp Up Rate", |
245 | &dvc->rup, | 253 | &dvc->rup, |
246 | rsnd_dvc_volume_update, | 254 | rsnd_dvc_volume_update, |
@@ -248,8 +256,8 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
248 | if (ret < 0) | 256 | if (ret < 0) |
249 | return ret; | 257 | return ret; |
250 | 258 | ||
251 | ret = rsnd_kctrl_new_e(mod, rdai, rtd, | 259 | ret = rsnd_kctrl_new_e(mod, rtd, |
252 | rsnd_dai_is_play(rdai, io) ? | 260 | is_play ? |
253 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", | 261 | "DVC Out Ramp Down Rate" : "DVC In Ramp Down Rate", |
254 | &dvc->rdown, | 262 | &dvc->rdown, |
255 | rsnd_dvc_volume_update, | 263 | rsnd_dvc_volume_update, |
@@ -264,6 +272,7 @@ static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | |||
264 | static struct rsnd_mod_ops rsnd_dvc_ops = { | 272 | static struct rsnd_mod_ops rsnd_dvc_ops = { |
265 | .name = DVC_NAME, | 273 | .name = DVC_NAME, |
266 | .probe = rsnd_dvc_probe_gen2, | 274 | .probe = rsnd_dvc_probe_gen2, |
275 | .remove = rsnd_dvc_remove_gen2, | ||
267 | .init = rsnd_dvc_init, | 276 | .init = rsnd_dvc_init, |
268 | .quit = rsnd_dvc_quit, | 277 | .quit = rsnd_dvc_quit, |
269 | .start = rsnd_dvc_start, | 278 | .start = rsnd_dvc_start, |
@@ -356,9 +365,9 @@ int rsnd_dvc_probe(struct platform_device *pdev, | |||
356 | return PTR_ERR(clk); | 365 | return PTR_ERR(clk); |
357 | 366 | ||
358 | dvc->info = &info->dvc_info[i]; | 367 | dvc->info = &info->dvc_info[i]; |
359 | dvc->clk = clk; | ||
360 | 368 | ||
361 | rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i); | 369 | rsnd_mod_init(&dvc->mod, &rsnd_dvc_ops, |
370 | clk, RSND_MOD_DVC, i); | ||
362 | 371 | ||
363 | dev_dbg(dev, "CMD%d probed\n", i); | 372 | dev_dbg(dev, "CMD%d probed\n", i); |
364 | } | 373 | } |
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 87a6f2d62775..de0685f2abae 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -309,8 +309,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev, | |||
309 | RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), | 309 | RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), |
310 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), | 310 | RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), |
311 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), | 311 | RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), |
312 | RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), | ||
312 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), | 313 | RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), |
313 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), | 314 | RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), |
315 | RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), | ||
316 | RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), | ||
317 | RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), | ||
318 | RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), | ||
314 | RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), | 319 | RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), |
315 | RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), | 320 | RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), |
316 | RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), | 321 | RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), |
@@ -403,6 +408,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev, | |||
403 | RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), | 408 | RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), |
404 | RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), | 409 | RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), |
405 | RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), | 410 | RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), |
411 | /* | ||
412 | * ADD US | ||
413 | * | ||
414 | * SRC_STATUS | ||
415 | * SRC_INT_EN | ||
416 | * SCU_SYS_STATUS0 | ||
417 | * SCU_SYS_STATUS1 | ||
418 | * SCU_SYS_INT_EN0 | ||
419 | * SCU_SYS_INT_EN1 | ||
420 | */ | ||
406 | }; | 421 | }; |
407 | struct rsnd_regmap_field_conf conf_adg[] = { | 422 | struct rsnd_regmap_field_conf conf_adg[] = { |
408 | RSND_GEN_S_REG(BRRA, 0x00), | 423 | RSND_GEN_S_REG(BRRA, 0x00), |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 5826c8abf794..e7914bd610e2 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -44,6 +44,8 @@ enum rsnd_reg { | |||
44 | RSND_REG_SRC_IFSCR, | 44 | RSND_REG_SRC_IFSCR, |
45 | RSND_REG_SRC_IFSVR, | 45 | RSND_REG_SRC_IFSVR, |
46 | RSND_REG_SRC_SRCCR, | 46 | RSND_REG_SRC_SRCCR, |
47 | RSND_REG_SCU_SYS_STATUS0, | ||
48 | RSND_REG_SCU_SYS_INT_EN0, | ||
47 | RSND_REG_CMD_ROUTE_SLCT, | 49 | RSND_REG_CMD_ROUTE_SLCT, |
48 | RSND_REG_DVC_SWRSR, | 50 | RSND_REG_DVC_SWRSR, |
49 | RSND_REG_DVC_DVUIR, | 51 | RSND_REG_DVC_DVUIR, |
@@ -94,6 +96,9 @@ enum rsnd_reg { | |||
94 | RSND_REG_SHARE23, | 96 | RSND_REG_SHARE23, |
95 | RSND_REG_SHARE24, | 97 | RSND_REG_SHARE24, |
96 | RSND_REG_SHARE25, | 98 | RSND_REG_SHARE25, |
99 | RSND_REG_SHARE26, | ||
100 | RSND_REG_SHARE27, | ||
101 | RSND_REG_SHARE28, | ||
97 | 102 | ||
98 | RSND_REG_MAX, | 103 | RSND_REG_MAX, |
99 | }; | 104 | }; |
@@ -135,6 +140,9 @@ enum rsnd_reg { | |||
135 | #define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 | 140 | #define RSND_REG_DVC_VRCTR RSND_REG_SHARE23 |
136 | #define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 | 141 | #define RSND_REG_DVC_VRPDR RSND_REG_SHARE24 |
137 | #define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 | 142 | #define RSND_REG_DVC_VRDBR RSND_REG_SHARE25 |
143 | #define RSND_REG_SCU_SYS_STATUS1 RSND_REG_SHARE26 | ||
144 | #define RSND_REG_SCU_SYS_INT_EN1 RSND_REG_SHARE27 | ||
145 | #define RSND_REG_SRC_INT_ENABLE0 RSND_REG_SHARE28 | ||
138 | 146 | ||
139 | struct rsnd_of_data; | 147 | struct rsnd_of_data; |
140 | struct rsnd_priv; | 148 | struct rsnd_priv; |
@@ -182,9 +190,9 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
182 | * R-Car sound mod | 190 | * R-Car sound mod |
183 | */ | 191 | */ |
184 | enum rsnd_mod_type { | 192 | enum rsnd_mod_type { |
185 | RSND_MOD_SRC = 0, | 193 | RSND_MOD_DVC = 0, |
194 | RSND_MOD_SRC, | ||
186 | RSND_MOD_SSI, | 195 | RSND_MOD_SSI, |
187 | RSND_MOD_DVC, | ||
188 | RSND_MOD_MAX, | 196 | RSND_MOD_MAX, |
189 | }; | 197 | }; |
190 | 198 | ||
@@ -192,32 +200,31 @@ struct rsnd_mod_ops { | |||
192 | char *name; | 200 | char *name; |
193 | char* (*dma_name)(struct rsnd_mod *mod); | 201 | char* (*dma_name)(struct rsnd_mod *mod); |
194 | int (*probe)(struct rsnd_mod *mod, | 202 | int (*probe)(struct rsnd_mod *mod, |
195 | struct rsnd_dai *rdai); | 203 | struct rsnd_priv *priv); |
196 | int (*remove)(struct rsnd_mod *mod, | 204 | int (*remove)(struct rsnd_mod *mod, |
197 | struct rsnd_dai *rdai); | 205 | struct rsnd_priv *priv); |
198 | int (*init)(struct rsnd_mod *mod, | 206 | int (*init)(struct rsnd_mod *mod, |
199 | struct rsnd_dai *rdai); | 207 | struct rsnd_priv *priv); |
200 | int (*quit)(struct rsnd_mod *mod, | 208 | int (*quit)(struct rsnd_mod *mod, |
201 | struct rsnd_dai *rdai); | 209 | struct rsnd_priv *priv); |
202 | int (*start)(struct rsnd_mod *mod, | 210 | int (*start)(struct rsnd_mod *mod, |
203 | struct rsnd_dai *rdai); | 211 | struct rsnd_priv *priv); |
204 | int (*stop)(struct rsnd_mod *mod, | 212 | int (*stop)(struct rsnd_mod *mod, |
205 | struct rsnd_dai *rdai); | 213 | struct rsnd_priv *priv); |
206 | int (*pcm_new)(struct rsnd_mod *mod, | 214 | int (*pcm_new)(struct rsnd_mod *mod, |
207 | struct rsnd_dai *rdai, | ||
208 | struct snd_soc_pcm_runtime *rtd); | 215 | struct snd_soc_pcm_runtime *rtd); |
209 | int (*fallback)(struct rsnd_mod *mod, | 216 | int (*fallback)(struct rsnd_mod *mod, |
210 | struct rsnd_dai *rdai); | 217 | struct rsnd_priv *priv); |
211 | }; | 218 | }; |
212 | 219 | ||
213 | struct rsnd_dai_stream; | 220 | struct rsnd_dai_stream; |
214 | struct rsnd_mod { | 221 | struct rsnd_mod { |
215 | int id; | 222 | int id; |
216 | enum rsnd_mod_type type; | 223 | enum rsnd_mod_type type; |
217 | struct rsnd_priv *priv; | ||
218 | struct rsnd_mod_ops *ops; | 224 | struct rsnd_mod_ops *ops; |
219 | struct rsnd_dma dma; | 225 | struct rsnd_dma dma; |
220 | struct rsnd_dai_stream *io; | 226 | struct rsnd_dai_stream *io; |
227 | struct clk *clk; | ||
221 | u32 status; | 228 | u32 status; |
222 | }; | 229 | }; |
223 | /* | 230 | /* |
@@ -248,15 +255,17 @@ struct rsnd_mod { | |||
248 | #define __rsnd_mod_call_pcm_new 0 | 255 | #define __rsnd_mod_call_pcm_new 0 |
249 | #define __rsnd_mod_call_fallback 0 | 256 | #define __rsnd_mod_call_fallback 0 |
250 | 257 | ||
251 | #define rsnd_mod_to_priv(mod) ((mod)->priv) | 258 | #define rsnd_mod_to_priv(mod) (rsnd_io_to_priv(rsnd_mod_to_io(mod))) |
252 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) | 259 | #define rsnd_mod_to_dma(mod) (&(mod)->dma) |
253 | #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) | 260 | #define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) |
254 | #define rsnd_mod_to_io(mod) ((mod)->io) | 261 | #define rsnd_mod_to_io(mod) ((mod)->io) |
255 | #define rsnd_mod_id(mod) ((mod)->id) | 262 | #define rsnd_mod_id(mod) ((mod)->id) |
263 | #define rsnd_mod_hw_start(mod) clk_prepare_enable((mod)->clk) | ||
264 | #define rsnd_mod_hw_stop(mod) clk_disable_unprepare((mod)->clk) | ||
256 | 265 | ||
257 | void rsnd_mod_init(struct rsnd_priv *priv, | 266 | void rsnd_mod_init(struct rsnd_mod *mod, |
258 | struct rsnd_mod *mod, | ||
259 | struct rsnd_mod_ops *ops, | 267 | struct rsnd_mod_ops *ops, |
268 | struct clk *clk, | ||
260 | enum rsnd_mod_type type, | 269 | enum rsnd_mod_type type, |
261 | int id); | 270 | int id); |
262 | char *rsnd_mod_name(struct rsnd_mod *mod); | 271 | char *rsnd_mod_name(struct rsnd_mod *mod); |
@@ -270,6 +279,7 @@ struct rsnd_dai_stream { | |||
270 | struct snd_pcm_substream *substream; | 279 | struct snd_pcm_substream *substream; |
271 | struct rsnd_mod *mod[RSND_MOD_MAX]; | 280 | struct rsnd_mod *mod[RSND_MOD_MAX]; |
272 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ | 281 | struct rsnd_dai_path_info *info; /* rcar_snd.h */ |
282 | struct rsnd_dai *rdai; | ||
273 | int byte_pos; | 283 | int byte_pos; |
274 | int period_pos; | 284 | int period_pos; |
275 | int byte_per_period; | 285 | int byte_per_period; |
@@ -278,12 +288,18 @@ struct rsnd_dai_stream { | |||
278 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) | 288 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) |
279 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) | 289 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) |
280 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) | 290 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) |
291 | #define rsnd_io_to_rdai(io) ((io)->rdai) | ||
292 | #define rsnd_io_to_priv(io) (rsnd_rdai_to_priv(rsnd_io_to_rdai(io))) | ||
293 | #define rsnd_io_is_play(io) (&rsnd_io_to_rdai(io)->playback == io) | ||
294 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | ||
295 | (io)->substream->runtime : NULL) | ||
296 | |||
281 | 297 | ||
282 | struct rsnd_dai { | 298 | struct rsnd_dai { |
283 | char name[RSND_DAI_NAME_SIZE]; | 299 | char name[RSND_DAI_NAME_SIZE]; |
284 | struct rsnd_dai_platform_info *info; /* rcar_snd.h */ | ||
285 | struct rsnd_dai_stream playback; | 300 | struct rsnd_dai_stream playback; |
286 | struct rsnd_dai_stream capture; | 301 | struct rsnd_dai_stream capture; |
302 | struct rsnd_priv *priv; | ||
287 | 303 | ||
288 | unsigned int clk_master:1; | 304 | unsigned int clk_master:1; |
289 | unsigned int bit_clk_inv:1; | 305 | unsigned int bit_clk_inv:1; |
@@ -293,22 +309,18 @@ struct rsnd_dai { | |||
293 | }; | 309 | }; |
294 | 310 | ||
295 | #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) | 311 | #define rsnd_rdai_nr(priv) ((priv)->rdai_nr) |
312 | #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) | ||
313 | #define rsnd_rdai_to_priv(rdai) ((rdai)->priv) | ||
296 | #define for_each_rsnd_dai(rdai, priv, i) \ | 314 | #define for_each_rsnd_dai(rdai, priv, i) \ |
297 | for (i = 0; \ | 315 | for (i = 0; \ |
298 | (i < rsnd_rdai_nr(priv)) && \ | 316 | (i < rsnd_rdai_nr(priv)) && \ |
299 | ((rdai) = rsnd_dai_get(priv, i)); \ | 317 | ((rdai) = rsnd_rdai_get(priv, i)); \ |
300 | i++) | 318 | i++) |
301 | 319 | ||
302 | struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); | 320 | struct rsnd_dai *rsnd_rdai_get(struct rsnd_priv *priv, int id); |
303 | int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); | ||
304 | int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); | ||
305 | #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) | ||
306 | #define rsnd_io_to_runtime(io) ((io)->substream ? \ | ||
307 | (io)->substream->runtime : NULL) | ||
308 | 321 | ||
309 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); | 322 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); |
310 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); | 323 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); |
311 | #define rsnd_dai_is_clk_master(rdai) ((rdai)->clk_master) | ||
312 | 324 | ||
313 | /* | 325 | /* |
314 | * R-Car Gen1/Gen2 | 326 | * R-Car Gen1/Gen2 |
@@ -339,15 +351,12 @@ int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, | |||
339 | unsigned int src_rate, | 351 | unsigned int src_rate, |
340 | unsigned int dst_rate); | 352 | unsigned int dst_rate); |
341 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | 353 | int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, |
342 | struct rsnd_dai *rdai, | ||
343 | struct rsnd_dai_stream *io, | 354 | struct rsnd_dai_stream *io, |
344 | unsigned int src_rate, | 355 | unsigned int src_rate, |
345 | unsigned int dst_rate); | 356 | unsigned int dst_rate); |
346 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 357 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
347 | struct rsnd_dai *rdai, | ||
348 | struct rsnd_dai_stream *io); | 358 | struct rsnd_dai_stream *io); |
349 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | 359 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod, |
350 | struct rsnd_mod *mod, | ||
351 | struct rsnd_dai_stream *io); | 360 | struct rsnd_dai_stream *io); |
352 | 361 | ||
353 | /* | 362 | /* |
@@ -427,6 +436,8 @@ struct rsnd_kctrl_cfg { | |||
427 | u32 *val; | 436 | u32 *val; |
428 | const char * const *texts; | 437 | const char * const *texts; |
429 | void (*update)(struct rsnd_mod *mod); | 438 | void (*update)(struct rsnd_mod *mod); |
439 | struct snd_card *card; | ||
440 | struct snd_kcontrol *kctrl; | ||
430 | }; | 441 | }; |
431 | 442 | ||
432 | #define RSND_DVC_CHANNELS 2 | 443 | #define RSND_DVC_CHANNELS 2 |
@@ -440,22 +451,22 @@ struct rsnd_kctrl_cfg_s { | |||
440 | u32 val; | 451 | u32 val; |
441 | }; | 452 | }; |
442 | 453 | ||
454 | void _rsnd_kctrl_remove(struct rsnd_kctrl_cfg *cfg); | ||
455 | #define rsnd_kctrl_remove(_cfg) _rsnd_kctrl_remove(&((_cfg).cfg)) | ||
456 | |||
443 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, | 457 | int rsnd_kctrl_new_m(struct rsnd_mod *mod, |
444 | struct rsnd_dai *rdai, | ||
445 | struct snd_soc_pcm_runtime *rtd, | 458 | struct snd_soc_pcm_runtime *rtd, |
446 | const unsigned char *name, | 459 | const unsigned char *name, |
447 | void (*update)(struct rsnd_mod *mod), | 460 | void (*update)(struct rsnd_mod *mod), |
448 | struct rsnd_kctrl_cfg_m *_cfg, | 461 | struct rsnd_kctrl_cfg_m *_cfg, |
449 | u32 max); | 462 | u32 max); |
450 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, | 463 | int rsnd_kctrl_new_s(struct rsnd_mod *mod, |
451 | struct rsnd_dai *rdai, | ||
452 | struct snd_soc_pcm_runtime *rtd, | 464 | struct snd_soc_pcm_runtime *rtd, |
453 | const unsigned char *name, | 465 | const unsigned char *name, |
454 | void (*update)(struct rsnd_mod *mod), | 466 | void (*update)(struct rsnd_mod *mod), |
455 | struct rsnd_kctrl_cfg_s *_cfg, | 467 | struct rsnd_kctrl_cfg_s *_cfg, |
456 | u32 max); | 468 | u32 max); |
457 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, | 469 | int rsnd_kctrl_new_e(struct rsnd_mod *mod, |
458 | struct rsnd_dai *rdai, | ||
459 | struct snd_soc_pcm_runtime *rtd, | 470 | struct snd_soc_pcm_runtime *rtd, |
460 | const unsigned char *name, | 471 | const unsigned char *name, |
461 | struct rsnd_kctrl_cfg_s *_cfg, | 472 | struct rsnd_kctrl_cfg_s *_cfg, |
@@ -474,14 +485,10 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
474 | struct rsnd_dai_stream *io, | 485 | struct rsnd_dai_stream *io, |
475 | struct snd_pcm_runtime *runtime); | 486 | struct snd_pcm_runtime *runtime); |
476 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 487 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
477 | struct rsnd_dai *rdai, | ||
478 | int use_busif); | 488 | int use_busif); |
479 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | 489 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod); |
480 | struct rsnd_dai *rdai); | 490 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod); |
481 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | 491 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod); |
482 | struct rsnd_dai *rdai); | ||
483 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, | ||
484 | struct rsnd_dai *rdai); | ||
485 | 492 | ||
486 | #define rsnd_src_nr(priv) ((priv)->src_nr) | 493 | #define rsnd_src_nr(priv) ((priv)->src_nr) |
487 | 494 | ||
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index eede3ac6eed2..81c182b4bad5 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -12,10 +12,17 @@ | |||
12 | 12 | ||
13 | #define SRC_NAME "src" | 13 | #define SRC_NAME "src" |
14 | 14 | ||
15 | /* SRCx_STATUS */ | ||
16 | #define OUF_SRCO ((1 << 12) | (1 << 13)) | ||
17 | #define OUF_SRCI ((1 << 9) | (1 << 8)) | ||
18 | |||
19 | /* SCU_SYSTEM_STATUS0/1 */ | ||
20 | #define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) | ||
21 | |||
15 | struct rsnd_src { | 22 | struct rsnd_src { |
16 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ | 23 | struct rsnd_src_platform_info *info; /* rcar_snd.h */ |
17 | struct rsnd_mod mod; | 24 | struct rsnd_mod mod; |
18 | struct clk *clk; | 25 | int err; |
19 | }; | 26 | }; |
20 | 27 | ||
21 | #define RSND_SRC_NAME_SIZE 16 | 28 | #define RSND_SRC_NAME_SIZE 16 |
@@ -107,10 +114,10 @@ struct rsnd_src { | |||
107 | * Gen1/Gen2 common functions | 114 | * Gen1/Gen2 common functions |
108 | */ | 115 | */ |
109 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | 116 | int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, |
110 | struct rsnd_dai *rdai, | ||
111 | int use_busif) | 117 | int use_busif) |
112 | { | 118 | { |
113 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); | 119 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); |
120 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
114 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 121 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
115 | int ssi_id = rsnd_mod_id(ssi_mod); | 122 | int ssi_id = rsnd_mod_id(ssi_mod); |
116 | 123 | ||
@@ -140,7 +147,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
140 | if (shift >= 0) | 147 | if (shift >= 0) |
141 | rsnd_mod_bset(ssi_mod, SSI_MODE1, | 148 | rsnd_mod_bset(ssi_mod, SSI_MODE1, |
142 | 0x3 << shift, | 149 | 0x3 << shift, |
143 | rsnd_dai_is_clk_master(rdai) ? | 150 | rsnd_rdai_is_clk_master(rdai) ? |
144 | 0x2 << shift : 0x1 << shift); | 151 | 0x2 << shift : 0x1 << shift); |
145 | } | 152 | } |
146 | 153 | ||
@@ -174,8 +181,7 @@ int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, | |||
174 | return 0; | 181 | return 0; |
175 | } | 182 | } |
176 | 183 | ||
177 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | 184 | int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) |
178 | struct rsnd_dai *rdai) | ||
179 | { | 185 | { |
180 | /* | 186 | /* |
181 | * DMA settings for SSIU | 187 | * DMA settings for SSIU |
@@ -185,8 +191,7 @@ int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, | |||
185 | return 0; | 191 | return 0; |
186 | } | 192 | } |
187 | 193 | ||
188 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | 194 | int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod) |
189 | struct rsnd_dai *rdai) | ||
190 | { | 195 | { |
191 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 196 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
192 | 197 | ||
@@ -202,8 +207,7 @@ int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, | |||
202 | return 0; | 207 | return 0; |
203 | } | 208 | } |
204 | 209 | ||
205 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, | 210 | int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) |
206 | struct rsnd_dai *rdai) | ||
207 | { | 211 | { |
208 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 212 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
209 | 213 | ||
@@ -240,8 +244,7 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
240 | return rate; | 244 | return rate; |
241 | } | 245 | } |
242 | 246 | ||
243 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | 247 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) |
244 | struct rsnd_dai *rdai) | ||
245 | { | 248 | { |
246 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 249 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 250 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -273,12 +276,13 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
273 | return 0; | 276 | return 0; |
274 | } | 277 | } |
275 | 278 | ||
276 | static int rsnd_src_init(struct rsnd_mod *mod, | 279 | static int rsnd_src_init(struct rsnd_mod *mod) |
277 | struct rsnd_dai *rdai) | ||
278 | { | 280 | { |
279 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 281 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
280 | 282 | ||
281 | clk_prepare_enable(src->clk); | 283 | rsnd_mod_hw_start(mod); |
284 | |||
285 | src->err = 0; | ||
282 | 286 | ||
283 | /* | 287 | /* |
284 | * Initialize the operation of the SRC internal circuits | 288 | * Initialize the operation of the SRC internal circuits |
@@ -290,11 +294,16 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
290 | } | 294 | } |
291 | 295 | ||
292 | static int rsnd_src_quit(struct rsnd_mod *mod, | 296 | static int rsnd_src_quit(struct rsnd_mod *mod, |
293 | struct rsnd_dai *rdai) | 297 | struct rsnd_priv *priv) |
294 | { | 298 | { |
295 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 299 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
300 | struct device *dev = rsnd_priv_to_dev(priv); | ||
301 | |||
302 | rsnd_mod_hw_stop(mod); | ||
296 | 303 | ||
297 | clk_disable_unprepare(src->clk); | 304 | if (src->err) |
305 | dev_warn(dev, "%s[%d] under/over flow err = %d\n", | ||
306 | rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); | ||
298 | 307 | ||
299 | return 0; | 308 | return 0; |
300 | } | 309 | } |
@@ -319,8 +328,7 @@ static int rsnd_src_stop(struct rsnd_mod *mod) | |||
319 | /* | 328 | /* |
320 | * Gen1 functions | 329 | * Gen1 functions |
321 | */ | 330 | */ |
322 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | 331 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) |
323 | struct rsnd_dai *rdai) | ||
324 | { | 332 | { |
325 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 333 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
326 | struct src_route_config { | 334 | struct src_route_config { |
@@ -348,7 +356,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
348 | /* | 356 | /* |
349 | * SRC_ROUTE_SELECT | 357 | * SRC_ROUTE_SELECT |
350 | */ | 358 | */ |
351 | val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2; | 359 | val = rsnd_io_is_play(io) ? 0x1 : 0x2; |
352 | val = val << routes[id].shift; | 360 | val = val << routes[id].shift; |
353 | mask = routes[id].mask << routes[id].shift; | 361 | mask = routes[id].mask << routes[id].shift; |
354 | 362 | ||
@@ -357,8 +365,7 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
357 | return 0; | 365 | return 0; |
358 | } | 366 | } |
359 | 367 | ||
360 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | 368 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) |
361 | struct rsnd_dai *rdai) | ||
362 | { | 369 | { |
363 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 370 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
364 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 371 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -416,13 +423,12 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | |||
416 | return 0; | 423 | return 0; |
417 | } | 424 | } |
418 | 425 | ||
419 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | 426 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) |
420 | struct rsnd_dai *rdai) | ||
421 | { | 427 | { |
422 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 428 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
423 | int ret; | 429 | int ret; |
424 | 430 | ||
425 | ret = rsnd_src_set_convert_rate(mod, rdai); | 431 | ret = rsnd_src_set_convert_rate(mod); |
426 | if (ret < 0) | 432 | if (ret < 0) |
427 | return ret; | 433 | return ret; |
428 | 434 | ||
@@ -443,9 +449,8 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | |||
443 | } | 449 | } |
444 | 450 | ||
445 | static int rsnd_src_probe_gen1(struct rsnd_mod *mod, | 451 | static int rsnd_src_probe_gen1(struct rsnd_mod *mod, |
446 | struct rsnd_dai *rdai) | 452 | struct rsnd_priv *priv) |
447 | { | 453 | { |
448 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
449 | struct device *dev = rsnd_priv_to_dev(priv); | 454 | struct device *dev = rsnd_priv_to_dev(priv); |
450 | 455 | ||
451 | dev_dbg(dev, "%s[%d] (Gen1) is probed\n", | 456 | dev_dbg(dev, "%s[%d] (Gen1) is probed\n", |
@@ -455,23 +460,23 @@ static int rsnd_src_probe_gen1(struct rsnd_mod *mod, | |||
455 | } | 460 | } |
456 | 461 | ||
457 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 462 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
458 | struct rsnd_dai *rdai) | 463 | struct rsnd_priv *priv) |
459 | { | 464 | { |
460 | int ret; | 465 | int ret; |
461 | 466 | ||
462 | ret = rsnd_src_init(mod, rdai); | 467 | ret = rsnd_src_init(mod); |
463 | if (ret < 0) | 468 | if (ret < 0) |
464 | return ret; | 469 | return ret; |
465 | 470 | ||
466 | ret = rsnd_src_set_route_gen1(mod, rdai); | 471 | ret = rsnd_src_set_route_gen1(mod); |
467 | if (ret < 0) | 472 | if (ret < 0) |
468 | return ret; | 473 | return ret; |
469 | 474 | ||
470 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai); | 475 | ret = rsnd_src_set_convert_rate_gen1(mod); |
471 | if (ret < 0) | 476 | if (ret < 0) |
472 | return ret; | 477 | return ret; |
473 | 478 | ||
474 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai); | 479 | ret = rsnd_src_set_convert_timing_gen1(mod); |
475 | if (ret < 0) | 480 | if (ret < 0) |
476 | return ret; | 481 | return ret; |
477 | 482 | ||
@@ -479,7 +484,7 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
479 | } | 484 | } |
480 | 485 | ||
481 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 486 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
482 | struct rsnd_dai *rdai) | 487 | struct rsnd_priv *priv) |
483 | { | 488 | { |
484 | int id = rsnd_mod_id(mod); | 489 | int id = rsnd_mod_id(mod); |
485 | 490 | ||
@@ -489,7 +494,7 @@ static int rsnd_src_start_gen1(struct rsnd_mod *mod, | |||
489 | } | 494 | } |
490 | 495 | ||
491 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 496 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
492 | struct rsnd_dai *rdai) | 497 | struct rsnd_priv *priv) |
493 | { | 498 | { |
494 | int id = rsnd_mod_id(mod); | 499 | int id = rsnd_mod_id(mod); |
495 | 500 | ||
@@ -510,8 +515,111 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { | |||
510 | /* | 515 | /* |
511 | * Gen2 functions | 516 | * Gen2 functions |
512 | */ | 517 | */ |
513 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | 518 | #define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1) |
514 | struct rsnd_dai *rdai) | 519 | #define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0) |
520 | static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) | ||
521 | { | ||
522 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
523 | u32 sys_int_val, int_val, sys_int_mask; | ||
524 | int irq = src->info->irq; | ||
525 | int id = rsnd_mod_id(mod); | ||
526 | |||
527 | sys_int_val = | ||
528 | sys_int_mask = OUF_SRC(id); | ||
529 | int_val = 0x3300; | ||
530 | |||
531 | /* | ||
532 | * IRQ is not supported on non-DT | ||
533 | * see | ||
534 | * rsnd_src_probe_gen2() | ||
535 | */ | ||
536 | if ((irq <= 0) || !enable) { | ||
537 | sys_int_val = 0; | ||
538 | int_val = 0; | ||
539 | } | ||
540 | |||
541 | rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val); | ||
542 | rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val); | ||
543 | rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); | ||
544 | } | ||
545 | |||
546 | static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) | ||
547 | { | ||
548 | u32 val = OUF_SRC(rsnd_mod_id(mod)); | ||
549 | |||
550 | rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val); | ||
551 | rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); | ||
552 | } | ||
553 | |||
554 | static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) | ||
555 | { | ||
556 | u32 val = OUF_SRC(rsnd_mod_id(mod)); | ||
557 | bool ret = false; | ||
558 | |||
559 | if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) || | ||
560 | (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) { | ||
561 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
562 | |||
563 | src->err++; | ||
564 | ret = true; | ||
565 | } | ||
566 | |||
567 | /* clear error static */ | ||
568 | rsnd_src_error_clear_gen2(mod); | ||
569 | |||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | static int _rsnd_src_start_gen2(struct rsnd_mod *mod) | ||
574 | { | ||
575 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
576 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
577 | |||
578 | rsnd_mod_write(mod, SRC_CTRL, val); | ||
579 | |||
580 | rsnd_src_error_clear_gen2(mod); | ||
581 | |||
582 | rsnd_src_start(mod); | ||
583 | |||
584 | rsnd_src_irq_enable_gen2(mod); | ||
585 | |||
586 | return 0; | ||
587 | } | ||
588 | |||
589 | static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) | ||
590 | { | ||
591 | rsnd_src_irq_disable_gen2(mod); | ||
592 | |||
593 | rsnd_mod_write(mod, SRC_CTRL, 0); | ||
594 | |||
595 | rsnd_src_error_record_gen2(mod); | ||
596 | |||
597 | return rsnd_src_stop(mod); | ||
598 | } | ||
599 | |||
600 | static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) | ||
601 | { | ||
602 | struct rsnd_mod *mod = data; | ||
603 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
604 | |||
605 | if (!io) | ||
606 | return IRQ_NONE; | ||
607 | |||
608 | if (rsnd_src_error_record_gen2(mod)) { | ||
609 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
610 | struct device *dev = rsnd_priv_to_dev(priv); | ||
611 | |||
612 | _rsnd_src_stop_gen2(mod); | ||
613 | _rsnd_src_start_gen2(mod); | ||
614 | |||
615 | dev_dbg(dev, "%s[%d] restart\n", | ||
616 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | ||
617 | } | ||
618 | |||
619 | return IRQ_HANDLED; | ||
620 | } | ||
621 | |||
622 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) | ||
515 | { | 623 | { |
516 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 624 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
517 | struct device *dev = rsnd_priv_to_dev(priv); | 625 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -535,7 +643,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
535 | return -EINVAL; | 643 | return -EINVAL; |
536 | } | 644 | } |
537 | 645 | ||
538 | ret = rsnd_src_set_convert_rate(mod, rdai); | 646 | ret = rsnd_src_set_convert_rate(mod); |
539 | if (ret < 0) | 647 | if (ret < 0) |
540 | return ret; | 648 | return ret; |
541 | 649 | ||
@@ -563,8 +671,7 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
563 | return 0; | 671 | return 0; |
564 | } | 672 | } |
565 | 673 | ||
566 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | 674 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) |
567 | struct rsnd_dai *rdai) | ||
568 | { | 675 | { |
569 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 676 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
570 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 677 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -573,59 +680,78 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | |||
573 | int ret; | 680 | int ret; |
574 | 681 | ||
575 | if (convert_rate) | 682 | if (convert_rate) |
576 | ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io, | 683 | ret = rsnd_adg_set_convert_clk_gen2(mod, io, |
577 | runtime->rate, | 684 | runtime->rate, |
578 | convert_rate); | 685 | convert_rate); |
579 | else | 686 | else |
580 | ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io); | 687 | ret = rsnd_adg_set_convert_timing_gen2(mod, io); |
581 | 688 | ||
582 | return ret; | 689 | return ret; |
583 | } | 690 | } |
584 | 691 | ||
585 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 692 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
586 | struct rsnd_dai *rdai) | 693 | struct rsnd_priv *priv) |
587 | { | 694 | { |
588 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
589 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 695 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
590 | struct device *dev = rsnd_priv_to_dev(priv); | 696 | struct device *dev = rsnd_priv_to_dev(priv); |
697 | int irq = src->info->irq; | ||
591 | int ret; | 698 | int ret; |
592 | 699 | ||
700 | if (irq > 0) { | ||
701 | /* | ||
702 | * IRQ is not supported on non-DT | ||
703 | * see | ||
704 | * rsnd_src_irq_enable_gen2() | ||
705 | */ | ||
706 | ret = devm_request_irq(dev, irq, | ||
707 | rsnd_src_interrupt_gen2, | ||
708 | IRQF_SHARED, | ||
709 | dev_name(dev), mod); | ||
710 | if (ret) | ||
711 | goto rsnd_src_probe_gen2_fail; | ||
712 | } | ||
713 | |||
593 | ret = rsnd_dma_init(priv, | 714 | ret = rsnd_dma_init(priv, |
594 | rsnd_mod_to_dma(mod), | 715 | rsnd_mod_to_dma(mod), |
595 | rsnd_info_is_playback(priv, src), | 716 | rsnd_info_is_playback(priv, src), |
596 | src->info->dma_id); | 717 | src->info->dma_id); |
597 | if (ret < 0) | 718 | if (ret) |
598 | dev_err(dev, "%s[%d] (Gen2) failed\n", | 719 | goto rsnd_src_probe_gen2_fail; |
599 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 720 | |
600 | else | 721 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", |
601 | dev_dbg(dev, "%s[%d] (Gen2) is probed\n", | 722 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
602 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 723 | |
724 | return ret; | ||
725 | |||
726 | rsnd_src_probe_gen2_fail: | ||
727 | dev_err(dev, "%s[%d] (Gen2) failed\n", | ||
728 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | ||
603 | 729 | ||
604 | return ret; | 730 | return ret; |
605 | } | 731 | } |
606 | 732 | ||
607 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 733 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
608 | struct rsnd_dai *rdai) | 734 | struct rsnd_priv *priv) |
609 | { | 735 | { |
610 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 736 | rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); |
611 | 737 | ||
612 | return 0; | 738 | return 0; |
613 | } | 739 | } |
614 | 740 | ||
615 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 741 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
616 | struct rsnd_dai *rdai) | 742 | struct rsnd_priv *priv) |
617 | { | 743 | { |
618 | int ret; | 744 | int ret; |
619 | 745 | ||
620 | ret = rsnd_src_init(mod, rdai); | 746 | ret = rsnd_src_init(mod); |
621 | if (ret < 0) | 747 | if (ret < 0) |
622 | return ret; | 748 | return ret; |
623 | 749 | ||
624 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai); | 750 | ret = rsnd_src_set_convert_rate_gen2(mod); |
625 | if (ret < 0) | 751 | if (ret < 0) |
626 | return ret; | 752 | return ret; |
627 | 753 | ||
628 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai); | 754 | ret = rsnd_src_set_convert_timing_gen2(mod); |
629 | if (ret < 0) | 755 | if (ret < 0) |
630 | return ret; | 756 | return ret; |
631 | 757 | ||
@@ -633,29 +759,23 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
633 | } | 759 | } |
634 | 760 | ||
635 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 761 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
636 | struct rsnd_dai *rdai) | 762 | struct rsnd_priv *priv) |
637 | { | 763 | { |
638 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 764 | rsnd_dma_start(rsnd_mod_to_dma(mod)); |
639 | struct rsnd_src *src = rsnd_mod_to_src(mod); | ||
640 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
641 | |||
642 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); | ||
643 | 765 | ||
644 | rsnd_mod_write(mod, SRC_CTRL, val); | 766 | return _rsnd_src_start_gen2(mod); |
645 | |||
646 | return rsnd_src_start(mod); | ||
647 | } | 767 | } |
648 | 768 | ||
649 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 769 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
650 | struct rsnd_dai *rdai) | 770 | struct rsnd_priv *priv) |
651 | { | 771 | { |
652 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 772 | int ret; |
653 | 773 | ||
654 | rsnd_mod_write(mod, SRC_CTRL, 0); | 774 | ret = _rsnd_src_stop_gen2(mod); |
655 | 775 | ||
656 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); | 776 | rsnd_dma_stop(rsnd_mod_to_dma(mod)); |
657 | 777 | ||
658 | return rsnd_src_stop(mod); | 778 | return ret; |
659 | } | 779 | } |
660 | 780 | ||
661 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { | 781 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { |
@@ -681,10 +801,11 @@ static void rsnd_of_parse_src(struct platform_device *pdev, | |||
681 | struct rsnd_priv *priv) | 801 | struct rsnd_priv *priv) |
682 | { | 802 | { |
683 | struct device_node *src_node; | 803 | struct device_node *src_node; |
804 | struct device_node *np; | ||
684 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | 805 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); |
685 | struct rsnd_src_platform_info *src_info; | 806 | struct rsnd_src_platform_info *src_info; |
686 | struct device *dev = &pdev->dev; | 807 | struct device *dev = &pdev->dev; |
687 | int nr; | 808 | int nr, i; |
688 | 809 | ||
689 | if (!of_data) | 810 | if (!of_data) |
690 | return; | 811 | return; |
@@ -708,6 +829,13 @@ static void rsnd_of_parse_src(struct platform_device *pdev, | |||
708 | info->src_info = src_info; | 829 | info->src_info = src_info; |
709 | info->src_info_nr = nr; | 830 | info->src_info_nr = nr; |
710 | 831 | ||
832 | i = 0; | ||
833 | for_each_child_of_node(src_node, np) { | ||
834 | src_info[i].irq = irq_of_parse_and_map(np, 0); | ||
835 | |||
836 | i++; | ||
837 | } | ||
838 | |||
711 | rsnd_of_parse_src_end: | 839 | rsnd_of_parse_src_end: |
712 | of_node_put(src_node); | 840 | of_node_put(src_node); |
713 | } | 841 | } |
@@ -761,9 +889,8 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
761 | return PTR_ERR(clk); | 889 | return PTR_ERR(clk); |
762 | 890 | ||
763 | src->info = &info->src_info[i]; | 891 | src->info = &info->src_info[i]; |
764 | src->clk = clk; | ||
765 | 892 | ||
766 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); | 893 | rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); |
767 | 894 | ||
768 | dev_dbg(dev, "SRC%d probed\n", i); | 895 | dev_dbg(dev, "SRC%d probed\n", i); |
769 | } | 896 | } |
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 3844fbef4664..9e7b627c08e2 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -60,17 +60,14 @@ | |||
60 | #define SSI_NAME "ssi" | 60 | #define SSI_NAME "ssi" |
61 | 61 | ||
62 | struct rsnd_ssi { | 62 | struct rsnd_ssi { |
63 | struct clk *clk; | ||
64 | struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ | 63 | struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ |
65 | struct rsnd_ssi *parent; | 64 | struct rsnd_ssi *parent; |
66 | struct rsnd_mod mod; | 65 | struct rsnd_mod mod; |
67 | 66 | ||
68 | struct rsnd_dai *rdai; | ||
69 | u32 cr_own; | 67 | u32 cr_own; |
70 | u32 cr_clk; | 68 | u32 cr_clk; |
71 | int err; | 69 | int err; |
72 | unsigned int usrcnt; | 70 | unsigned int usrcnt; |
73 | unsigned int rate; | ||
74 | }; | 71 | }; |
75 | 72 | ||
76 | #define for_each_rsnd_ssi(pos, priv, i) \ | 73 | #define for_each_rsnd_ssi(pos, priv, i) \ |
@@ -128,7 +125,7 @@ static void rsnd_ssi_status_check(struct rsnd_mod *mod, | |||
128 | static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | 125 | static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, |
129 | struct rsnd_dai_stream *io) | 126 | struct rsnd_dai_stream *io) |
130 | { | 127 | { |
131 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 128 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
132 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 129 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
133 | struct device *dev = rsnd_priv_to_dev(priv); | 130 | struct device *dev = rsnd_priv_to_dev(priv); |
134 | int i, j, ret; | 131 | int i, j, ret; |
@@ -157,7 +154,6 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | |||
157 | 154 | ||
158 | ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); | 155 | ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); |
159 | if (0 == ret) { | 156 | if (0 == ret) { |
160 | ssi->rate = rate; | ||
161 | ssi->cr_clk = FORCE | SWL_32 | | 157 | ssi->cr_clk = FORCE | SWL_32 | |
162 | SCKD | SWSD | CKDV(j); | 158 | SCKD | SWSD | CKDV(j); |
163 | 159 | ||
@@ -176,26 +172,25 @@ static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, | |||
176 | 172 | ||
177 | static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) | 173 | static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) |
178 | { | 174 | { |
179 | ssi->rate = 0; | ||
180 | ssi->cr_clk = 0; | 175 | ssi->cr_clk = 0; |
181 | rsnd_adg_ssi_clk_stop(&ssi->mod); | 176 | rsnd_adg_ssi_clk_stop(&ssi->mod); |
182 | } | 177 | } |
183 | 178 | ||
184 | static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | 179 | static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, |
185 | struct rsnd_dai *rdai, | ||
186 | struct rsnd_dai_stream *io) | 180 | struct rsnd_dai_stream *io) |
187 | { | 181 | { |
188 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 182 | struct rsnd_priv *priv = rsnd_io_to_priv(io); |
183 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
189 | struct device *dev = rsnd_priv_to_dev(priv); | 184 | struct device *dev = rsnd_priv_to_dev(priv); |
190 | u32 cr_mode; | 185 | u32 cr_mode; |
191 | u32 cr; | 186 | u32 cr; |
192 | 187 | ||
193 | if (0 == ssi->usrcnt) { | 188 | if (0 == ssi->usrcnt) { |
194 | clk_prepare_enable(ssi->clk); | 189 | rsnd_mod_hw_start(&ssi->mod); |
195 | 190 | ||
196 | if (rsnd_dai_is_clk_master(rdai)) { | 191 | if (rsnd_rdai_is_clk_master(rdai)) { |
197 | if (rsnd_ssi_clk_from_parent(ssi)) | 192 | if (rsnd_ssi_clk_from_parent(ssi)) |
198 | rsnd_ssi_hw_start(ssi->parent, rdai, io); | 193 | rsnd_ssi_hw_start(ssi->parent, io); |
199 | else | 194 | else |
200 | rsnd_ssi_master_clk_start(ssi, io); | 195 | rsnd_ssi_master_clk_start(ssi, io); |
201 | } | 196 | } |
@@ -214,7 +209,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
214 | rsnd_mod_write(&ssi->mod, SSICR, cr); | 209 | rsnd_mod_write(&ssi->mod, SSICR, cr); |
215 | 210 | ||
216 | /* enable WS continue */ | 211 | /* enable WS continue */ |
217 | if (rsnd_dai_is_clk_master(rdai)) | 212 | if (rsnd_rdai_is_clk_master(rdai)) |
218 | rsnd_mod_write(&ssi->mod, SSIWSR, CONT); | 213 | rsnd_mod_write(&ssi->mod, SSIWSR, CONT); |
219 | 214 | ||
220 | /* clear error status */ | 215 | /* clear error status */ |
@@ -226,10 +221,11 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, | |||
226 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); | 221 | rsnd_mod_name(&ssi->mod), rsnd_mod_id(&ssi->mod)); |
227 | } | 222 | } |
228 | 223 | ||
229 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | 224 | static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi) |
230 | struct rsnd_dai *rdai) | ||
231 | { | 225 | { |
232 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); | 226 | struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); |
227 | struct rsnd_dai_stream *io = rsnd_mod_to_io(&ssi->mod); | ||
228 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
233 | struct device *dev = rsnd_priv_to_dev(priv); | 229 | struct device *dev = rsnd_priv_to_dev(priv); |
234 | u32 cr; | 230 | u32 cr; |
235 | 231 | ||
@@ -256,14 +252,14 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
256 | rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ | 252 | rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ |
257 | rsnd_ssi_status_check(&ssi->mod, IIRQ); | 253 | rsnd_ssi_status_check(&ssi->mod, IIRQ); |
258 | 254 | ||
259 | if (rsnd_dai_is_clk_master(rdai)) { | 255 | if (rsnd_rdai_is_clk_master(rdai)) { |
260 | if (rsnd_ssi_clk_from_parent(ssi)) | 256 | if (rsnd_ssi_clk_from_parent(ssi)) |
261 | rsnd_ssi_hw_stop(ssi->parent, rdai); | 257 | rsnd_ssi_hw_stop(ssi->parent); |
262 | else | 258 | else |
263 | rsnd_ssi_master_clk_stop(ssi); | 259 | rsnd_ssi_master_clk_stop(ssi); |
264 | } | 260 | } |
265 | 261 | ||
266 | clk_disable_unprepare(ssi->clk); | 262 | rsnd_mod_hw_stop(&ssi->mod); |
267 | } | 263 | } |
268 | 264 | ||
269 | dev_dbg(dev, "%s[%d] hw stopped\n", | 265 | dev_dbg(dev, "%s[%d] hw stopped\n", |
@@ -274,10 +270,11 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
274 | * SSI mod common functions | 270 | * SSI mod common functions |
275 | */ | 271 | */ |
276 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 272 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
277 | struct rsnd_dai *rdai) | 273 | struct rsnd_priv *priv) |
278 | { | 274 | { |
279 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 275 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
280 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 276 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
277 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | ||
281 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 278 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
282 | u32 cr; | 279 | u32 cr; |
283 | 280 | ||
@@ -311,13 +308,12 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
311 | cr |= SDTA; | 308 | cr |= SDTA; |
312 | if (rdai->sys_delay) | 309 | if (rdai->sys_delay) |
313 | cr |= DEL; | 310 | cr |= DEL; |
314 | if (rsnd_dai_is_play(rdai, io)) | 311 | if (rsnd_io_is_play(io)) |
315 | cr |= TRMD; | 312 | cr |= TRMD; |
316 | 313 | ||
317 | /* | 314 | /* |
318 | * set ssi parameter | 315 | * set ssi parameter |
319 | */ | 316 | */ |
320 | ssi->rdai = rdai; | ||
321 | ssi->cr_own = cr; | 317 | ssi->cr_own = cr; |
322 | ssi->err = -1; /* ignore 1st error */ | 318 | ssi->err = -1; /* ignore 1st error */ |
323 | 319 | ||
@@ -325,16 +321,15 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
325 | } | 321 | } |
326 | 322 | ||
327 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 323 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
328 | struct rsnd_dai *rdai) | 324 | struct rsnd_priv *priv) |
329 | { | 325 | { |
330 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 326 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
331 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
332 | struct device *dev = rsnd_priv_to_dev(priv); | 327 | struct device *dev = rsnd_priv_to_dev(priv); |
333 | 328 | ||
334 | if (ssi->err > 0) | 329 | if (ssi->err > 0) |
335 | dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); | 330 | dev_warn(dev, "%s[%d] under/over flow err = %d\n", |
331 | rsnd_mod_name(mod), rsnd_mod_id(mod), ssi->err); | ||
336 | 332 | ||
337 | ssi->rdai = NULL; | ||
338 | ssi->cr_own = 0; | 333 | ssi->cr_own = 0; |
339 | ssi->err = 0; | 334 | ssi->err = 0; |
340 | 335 | ||
@@ -353,32 +348,32 @@ static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) | |||
353 | } | 348 | } |
354 | 349 | ||
355 | static int rsnd_ssi_start(struct rsnd_mod *mod, | 350 | static int rsnd_ssi_start(struct rsnd_mod *mod, |
356 | struct rsnd_dai *rdai) | 351 | struct rsnd_priv *priv) |
357 | { | 352 | { |
358 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 353 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
359 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 354 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
360 | 355 | ||
361 | rsnd_src_ssiu_start(mod, rdai, rsnd_ssi_use_busif(mod)); | 356 | rsnd_src_ssiu_start(mod, rsnd_ssi_use_busif(mod)); |
362 | 357 | ||
363 | rsnd_ssi_hw_start(ssi, rdai, io); | 358 | rsnd_ssi_hw_start(ssi, io); |
364 | 359 | ||
365 | rsnd_src_ssi_irq_enable(mod, rdai); | 360 | rsnd_src_ssi_irq_enable(mod); |
366 | 361 | ||
367 | return 0; | 362 | return 0; |
368 | } | 363 | } |
369 | 364 | ||
370 | static int rsnd_ssi_stop(struct rsnd_mod *mod, | 365 | static int rsnd_ssi_stop(struct rsnd_mod *mod, |
371 | struct rsnd_dai *rdai) | 366 | struct rsnd_priv *priv) |
372 | { | 367 | { |
373 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 368 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
374 | 369 | ||
375 | rsnd_src_ssi_irq_disable(mod, rdai); | 370 | rsnd_src_ssi_irq_disable(mod); |
376 | 371 | ||
377 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); | 372 | rsnd_ssi_record_error(ssi, rsnd_mod_read(mod, SSISR)); |
378 | 373 | ||
379 | rsnd_ssi_hw_stop(ssi, rdai); | 374 | rsnd_ssi_hw_stop(ssi); |
380 | 375 | ||
381 | rsnd_src_ssiu_stop(mod, rdai); | 376 | rsnd_src_ssiu_stop(mod); |
382 | 377 | ||
383 | return 0; | 378 | return 0; |
384 | } | 379 | } |
@@ -386,16 +381,17 @@ static int rsnd_ssi_stop(struct rsnd_mod *mod, | |||
386 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | 381 | static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) |
387 | { | 382 | { |
388 | struct rsnd_ssi *ssi = data; | 383 | struct rsnd_ssi *ssi = data; |
389 | struct rsnd_dai *rdai = ssi->rdai; | ||
390 | struct rsnd_mod *mod = &ssi->mod; | 384 | struct rsnd_mod *mod = &ssi->mod; |
385 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
391 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | 386 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); |
387 | int is_dma = rsnd_ssi_is_dma_mode(mod); | ||
392 | u32 status = rsnd_mod_read(mod, SSISR); | 388 | u32 status = rsnd_mod_read(mod, SSISR); |
393 | 389 | ||
394 | if (!io) | 390 | if (!io) |
395 | return IRQ_NONE; | 391 | return IRQ_NONE; |
396 | 392 | ||
397 | /* PIO only */ | 393 | /* PIO only */ |
398 | if (status & DIRQ) { | 394 | if (!is_dma && (status & DIRQ)) { |
399 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 395 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
400 | u32 *buf = (u32 *)(runtime->dma_area + | 396 | u32 *buf = (u32 *)(runtime->dma_area + |
401 | rsnd_dai_pointer_offset(io, 0)); | 397 | rsnd_dai_pointer_offset(io, 0)); |
@@ -405,7 +401,7 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
405 | * directly as 32bit data | 401 | * directly as 32bit data |
406 | * see rsnd_ssi_init() | 402 | * see rsnd_ssi_init() |
407 | */ | 403 | */ |
408 | if (rsnd_dai_is_play(rdai, io)) | 404 | if (rsnd_io_is_play(io)) |
409 | rsnd_mod_write(mod, SSITDR, *buf); | 405 | rsnd_mod_write(mod, SSITDR, *buf); |
410 | else | 406 | else |
411 | *buf = rsnd_mod_read(mod, SSIRDR); | 407 | *buf = rsnd_mod_read(mod, SSIRDR); |
@@ -415,14 +411,13 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
415 | 411 | ||
416 | /* PIO / DMA */ | 412 | /* PIO / DMA */ |
417 | if (status & (UIRQ | OIRQ)) { | 413 | if (status & (UIRQ | OIRQ)) { |
418 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
419 | struct device *dev = rsnd_priv_to_dev(priv); | 414 | struct device *dev = rsnd_priv_to_dev(priv); |
420 | 415 | ||
421 | /* | 416 | /* |
422 | * restart SSI | 417 | * restart SSI |
423 | */ | 418 | */ |
424 | rsnd_ssi_stop(mod, rdai); | 419 | rsnd_ssi_stop(mod, priv); |
425 | rsnd_ssi_start(mod, rdai); | 420 | rsnd_ssi_start(mod, priv); |
426 | 421 | ||
427 | dev_dbg(dev, "%s[%d] restart\n", | 422 | dev_dbg(dev, "%s[%d] restart\n", |
428 | rsnd_mod_name(mod), rsnd_mod_id(mod)); | 423 | rsnd_mod_name(mod), rsnd_mod_id(mod)); |
@@ -437,9 +432,8 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) | |||
437 | * SSI PIO | 432 | * SSI PIO |
438 | */ | 433 | */ |
439 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 434 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
440 | struct rsnd_dai *rdai) | 435 | struct rsnd_priv *priv) |
441 | { | 436 | { |
442 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
443 | struct device *dev = rsnd_priv_to_dev(priv); | 437 | struct device *dev = rsnd_priv_to_dev(priv); |
444 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 438 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
445 | int ret; | 439 | int ret; |
@@ -468,9 +462,8 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
468 | }; | 462 | }; |
469 | 463 | ||
470 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 464 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
471 | struct rsnd_dai *rdai) | 465 | struct rsnd_priv *priv) |
472 | { | 466 | { |
473 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
474 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 467 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
475 | struct device *dev = rsnd_priv_to_dev(priv); | 468 | struct device *dev = rsnd_priv_to_dev(priv); |
476 | int dma_id = ssi->info->dma_id; | 469 | int dma_id = ssi->info->dma_id; |
@@ -503,14 +496,13 @@ rsnd_ssi_dma_probe_fail: | |||
503 | } | 496 | } |
504 | 497 | ||
505 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 498 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
506 | struct rsnd_dai *rdai) | 499 | struct rsnd_priv *priv) |
507 | { | 500 | { |
508 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
509 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 501 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
510 | struct device *dev = rsnd_priv_to_dev(priv); | 502 | struct device *dev = rsnd_priv_to_dev(priv); |
511 | int irq = ssi->info->irq; | 503 | int irq = ssi->info->irq; |
512 | 504 | ||
513 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 505 | rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); |
514 | 506 | ||
515 | /* PIO will request IRQ again */ | 507 | /* PIO will request IRQ again */ |
516 | devm_free_irq(dev, irq, ssi); | 508 | devm_free_irq(dev, irq, ssi); |
@@ -519,9 +511,8 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
519 | } | 511 | } |
520 | 512 | ||
521 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, | 513 | static int rsnd_ssi_fallback(struct rsnd_mod *mod, |
522 | struct rsnd_dai *rdai) | 514 | struct rsnd_priv *priv) |
523 | { | 515 | { |
524 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
525 | struct device *dev = rsnd_priv_to_dev(priv); | 516 | struct device *dev = rsnd_priv_to_dev(priv); |
526 | 517 | ||
527 | /* | 518 | /* |
@@ -540,25 +531,25 @@ static int rsnd_ssi_fallback(struct rsnd_mod *mod, | |||
540 | } | 531 | } |
541 | 532 | ||
542 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 533 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
543 | struct rsnd_dai *rdai) | 534 | struct rsnd_priv *priv) |
544 | { | 535 | { |
545 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 536 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
546 | 537 | ||
547 | rsnd_ssi_start(mod, rdai); | ||
548 | |||
549 | rsnd_dma_start(dma); | 538 | rsnd_dma_start(dma); |
550 | 539 | ||
540 | rsnd_ssi_start(mod, priv); | ||
541 | |||
551 | return 0; | 542 | return 0; |
552 | } | 543 | } |
553 | 544 | ||
554 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 545 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
555 | struct rsnd_dai *rdai) | 546 | struct rsnd_priv *priv) |
556 | { | 547 | { |
557 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); | 548 | struct rsnd_dma *dma = rsnd_mod_to_dma(mod); |
558 | 549 | ||
559 | rsnd_dma_stop(dma); | 550 | rsnd_ssi_stop(mod, priv); |
560 | 551 | ||
561 | rsnd_ssi_stop(mod, rdai); | 552 | rsnd_dma_stop(dma); |
562 | 553 | ||
563 | return 0; | 554 | return 0; |
564 | } | 555 | } |
@@ -734,7 +725,6 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
734 | return PTR_ERR(clk); | 725 | return PTR_ERR(clk); |
735 | 726 | ||
736 | ssi->info = pinfo; | 727 | ssi->info = pinfo; |
737 | ssi->clk = clk; | ||
738 | 728 | ||
739 | ops = &rsnd_ssi_non_ops; | 729 | ops = &rsnd_ssi_non_ops; |
740 | if (pinfo->dma_id > 0) | 730 | if (pinfo->dma_id > 0) |
@@ -742,7 +732,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
742 | else if (rsnd_ssi_pio_available(ssi)) | 732 | else if (rsnd_ssi_pio_available(ssi)) |
743 | ops = &rsnd_ssi_pio_ops; | 733 | ops = &rsnd_ssi_pio_ops; |
744 | 734 | ||
745 | rsnd_mod_init(priv, &ssi->mod, ops, RSND_MOD_SSI, i); | 735 | rsnd_mod_init(&ssi->mod, ops, clk, RSND_MOD_SSI, i); |
746 | 736 | ||
747 | rsnd_ssi_parent_clk_setup(priv, ssi); | 737 | rsnd_ssi_parent_clk_setup(priv, ssi); |
748 | } | 738 | } |