forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/sound/soc/pxa/mmp-sspa.c
....@@ -1,23 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * linux/sound/soc/pxa/mmp-sspa.c
34 * Base on pxa2xx-ssp.c
45 *
56 * Copyright (C) 2011 Marvell International Ltd.
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
- *
217 */
228 #include <linux/init.h>
239 #include <linux/module.h>
....@@ -25,9 +11,9 @@
2511 #include <linux/delay.h>
2612 #include <linux/clk.h>
2713 #include <linux/slab.h>
28
-#include <linux/pxa2xx_ssp.h>
2914 #include <linux/io.h>
3015 #include <linux/dmaengine.h>
16
+#include <linux/pm_runtime.h>
3117
3218 #include <sound/core.h>
3319 #include <sound/pcm.h>
....@@ -42,71 +28,65 @@
4228 * SSPA audio private data
4329 */
4430 struct sspa_priv {
45
- struct ssp_device *sspa;
46
- struct snd_dmaengine_dai_dma_data *dma_params;
31
+ void __iomem *tx_base;
32
+ void __iomem *rx_base;
33
+
34
+ struct snd_dmaengine_dai_dma_data playback_dma_data;
35
+ struct snd_dmaengine_dai_dma_data capture_dma_data;
36
+ struct clk *clk;
4737 struct clk *audio_clk;
4838 struct clk *sysclk;
49
- int dai_fmt;
39
+
5040 int running_cnt;
41
+ u32 sp;
42
+ u32 ctrl;
5143 };
5244
53
-static void mmp_sspa_write_reg(struct ssp_device *sspa, u32 reg, u32 val)
45
+static void mmp_sspa_tx_enable(struct sspa_priv *sspa)
5446 {
55
- __raw_writel(val, sspa->mmio_base + reg);
56
-}
47
+ unsigned int sspa_sp = sspa->sp;
5748
58
-static u32 mmp_sspa_read_reg(struct ssp_device *sspa, u32 reg)
59
-{
60
- return __raw_readl(sspa->mmio_base + reg);
61
-}
62
-
63
-static void mmp_sspa_tx_enable(struct ssp_device *sspa)
64
-{
65
- unsigned int sspa_sp;
66
-
67
- sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
49
+ sspa_sp &= ~SSPA_SP_MSL;
6850 sspa_sp |= SSPA_SP_S_EN;
6951 sspa_sp |= SSPA_SP_WEN;
70
- mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
52
+ __raw_writel(sspa_sp, sspa->tx_base + SSPA_SP);
7153 }
7254
73
-static void mmp_sspa_tx_disable(struct ssp_device *sspa)
55
+static void mmp_sspa_tx_disable(struct sspa_priv *sspa)
7456 {
75
- unsigned int sspa_sp;
57
+ unsigned int sspa_sp = sspa->sp;
7658
77
- sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
59
+ sspa_sp &= ~SSPA_SP_MSL;
7860 sspa_sp &= ~SSPA_SP_S_EN;
7961 sspa_sp |= SSPA_SP_WEN;
80
- mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
62
+ __raw_writel(sspa_sp, sspa->tx_base + SSPA_SP);
8163 }
8264
83
-static void mmp_sspa_rx_enable(struct ssp_device *sspa)
65
+static void mmp_sspa_rx_enable(struct sspa_priv *sspa)
8466 {
85
- unsigned int sspa_sp;
67
+ unsigned int sspa_sp = sspa->sp;
8668
87
- sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
8869 sspa_sp |= SSPA_SP_S_EN;
8970 sspa_sp |= SSPA_SP_WEN;
90
- mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
71
+ __raw_writel(sspa_sp, sspa->rx_base + SSPA_SP);
9172 }
9273
93
-static void mmp_sspa_rx_disable(struct ssp_device *sspa)
74
+static void mmp_sspa_rx_disable(struct sspa_priv *sspa)
9475 {
95
- unsigned int sspa_sp;
76
+ unsigned int sspa_sp = sspa->sp;
9677
97
- sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
9878 sspa_sp &= ~SSPA_SP_S_EN;
9979 sspa_sp |= SSPA_SP_WEN;
100
- mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
80
+ __raw_writel(sspa_sp, sspa->rx_base + SSPA_SP);
10181 }
10282
10383 static int mmp_sspa_startup(struct snd_pcm_substream *substream,
10484 struct snd_soc_dai *dai)
10585 {
106
- struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
86
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai);
10787
108
- clk_enable(priv->sysclk);
109
- clk_enable(priv->sspa->clk);
88
+ clk_prepare_enable(sspa->sysclk);
89
+ clk_prepare_enable(sspa->clk);
11090
11191 return 0;
11292 }
....@@ -114,11 +94,10 @@
11494 static void mmp_sspa_shutdown(struct snd_pcm_substream *substream,
11595 struct snd_soc_dai *dai)
11696 {
117
- struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
97
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai);
11898
119
- clk_disable(priv->sspa->clk);
120
- clk_disable(priv->sysclk);
121
-
99
+ clk_disable_unprepare(sspa->clk);
100
+ clk_disable_unprepare(sspa->sysclk);
122101 }
123102
124103 /*
....@@ -127,12 +106,16 @@
127106 static int mmp_sspa_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
128107 int clk_id, unsigned int freq, int dir)
129108 {
130
- struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
109
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai);
110
+ struct device *dev = cpu_dai->component->dev;
131111 int ret = 0;
112
+
113
+ if (dev->of_node)
114
+ return -ENOTSUPP;
132115
133116 switch (clk_id) {
134117 case MMP_SSPA_CLK_AUDIO:
135
- ret = clk_set_rate(priv->audio_clk, freq);
118
+ ret = clk_set_rate(sspa->audio_clk, freq);
136119 if (ret)
137120 return ret;
138121 break;
....@@ -151,17 +134,21 @@
151134 int source, unsigned int freq_in,
152135 unsigned int freq_out)
153136 {
154
- struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
137
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai);
138
+ struct device *dev = cpu_dai->component->dev;
155139 int ret = 0;
140
+
141
+ if (dev->of_node)
142
+ return -ENOTSUPP;
156143
157144 switch (pll_id) {
158145 case MMP_SYSCLK:
159
- ret = clk_set_rate(priv->sysclk, freq_out);
146
+ ret = clk_set_rate(sspa->sysclk, freq_out);
160147 if (ret)
161148 return ret;
162149 break;
163150 case MMP_SSPA_CLK:
164
- ret = clk_set_rate(priv->sspa->clk, freq_out);
151
+ ret = clk_set_rate(sspa->clk, freq_out);
165152 if (ret)
166153 return ret;
167154 break;
....@@ -173,36 +160,20 @@
173160 }
174161
175162 /*
176
- * Set up the sspa dai format. The sspa port must be inactive
177
- * before calling this function as the physical
178
- * interface format is changed.
163
+ * Set up the sspa dai format.
179164 */
180165 static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai,
181166 unsigned int fmt)
182167 {
183
- struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(cpu_dai);
184
- struct ssp_device *sspa = sspa_priv->sspa;
185
- u32 sspa_sp, sspa_ctrl;
186
-
187
- /* check if we need to change anything at all */
188
- if (sspa_priv->dai_fmt == fmt)
189
- return 0;
190
-
191
- /* we can only change the settings if the port is not in use */
192
- if ((mmp_sspa_read_reg(sspa, SSPA_TXSP) & SSPA_SP_S_EN) ||
193
- (mmp_sspa_read_reg(sspa, SSPA_RXSP) & SSPA_SP_S_EN)) {
194
- dev_err(&sspa->pdev->dev,
195
- "can't change hardware dai format: stream is in use\n");
196
- return -EINVAL;
197
- }
168
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(cpu_dai);
198169
199170 /* reset port settings */
200
- sspa_sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH;
201
- sspa_ctrl = 0;
171
+ sspa->sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH;
172
+ sspa->ctrl = 0;
202173
203174 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
204175 case SND_SOC_DAIFMT_CBS_CFS:
205
- sspa_sp |= SSPA_SP_MSL;
176
+ sspa->sp |= SSPA_SP_MSL;
206177 break;
207178 case SND_SOC_DAIFMT_CBM_CFM:
208179 break;
....@@ -212,7 +183,7 @@
212183
213184 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
214185 case SND_SOC_DAIFMT_NB_NF:
215
- sspa_sp |= SSPA_SP_FSP;
186
+ sspa->sp |= SSPA_SP_FSP;
216187 break;
217188 default:
218189 return -EINVAL;
....@@ -220,39 +191,16 @@
220191
221192 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
222193 case SND_SOC_DAIFMT_I2S:
223
- sspa_sp |= SSPA_TXSP_FPER(63);
224
- sspa_sp |= SSPA_SP_FWID(31);
225
- sspa_ctrl |= SSPA_CTL_XDATDLY(1);
194
+ sspa->ctrl |= SSPA_CTL_XDATDLY(1);
226195 break;
227196 default:
228197 return -EINVAL;
229198 }
230199
231
- mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
232
- mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
233
-
234
- sspa_sp &= ~(SSPA_SP_S_RST | SSPA_SP_FFLUSH);
235
- mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
236
- mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
237
-
238
- /*
239
- * FIXME: hw issue, for the tx serial port,
240
- * can not config the master/slave mode;
241
- * so must clean this bit.
242
- * The master/slave mode has been set in the
243
- * rx port.
244
- */
245
- sspa_sp &= ~SSPA_SP_MSL;
246
- mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
247
-
248
- mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
249
- mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
250
-
251200 /* Since we are configuring the timings for the format by hand
252201 * we have to defer some things until hw_params() where we
253202 * know parameters like the sample size.
254203 */
255
- sspa_priv->dai_fmt = fmt;
256204 return 0;
257205 }
258206
....@@ -264,65 +212,71 @@
264212 struct snd_pcm_hw_params *params,
265213 struct snd_soc_dai *dai)
266214 {
267
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
268
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
269
- struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
270
- struct ssp_device *sspa = sspa_priv->sspa;
271
- struct snd_dmaengine_dai_dma_data *dma_params;
272
- u32 sspa_ctrl;
273
-
274
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
275
- sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_TXCTL);
276
- else
277
- sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_RXCTL);
278
-
279
- sspa_ctrl &= ~SSPA_CTL_XFRLEN1_MASK;
280
- sspa_ctrl |= SSPA_CTL_XFRLEN1(params_channels(params) - 1);
281
- sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK;
282
- sspa_ctrl |= SSPA_CTL_XWDLEN1(SSPA_CTL_32_BITS);
283
- sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK;
215
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai);
216
+ struct device *dev = dai->component->dev;
217
+ u32 sspa_ctrl = sspa->ctrl;
218
+ int bits;
219
+ int bitval;
284220
285221 switch (params_format(params)) {
286222 case SNDRV_PCM_FORMAT_S8:
287
- sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_8_BITS);
223
+ bits = 8;
224
+ bitval = SSPA_CTL_8_BITS;
288225 break;
289226 case SNDRV_PCM_FORMAT_S16_LE:
290
- sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS);
291
- break;
292
- case SNDRV_PCM_FORMAT_S20_3LE:
293
- sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS);
227
+ bits = 16;
228
+ bitval = SSPA_CTL_16_BITS;
294229 break;
295230 case SNDRV_PCM_FORMAT_S24_3LE:
296
- sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS);
231
+ bits = 24;
232
+ bitval = SSPA_CTL_24_BITS;
297233 break;
298234 case SNDRV_PCM_FORMAT_S32_LE:
299
- sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_32_BITS);
235
+ bits = 32;
236
+ bitval = SSPA_CTL_32_BITS;
300237 break;
301238 default:
302239 return -EINVAL;
303240 }
304241
305
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
306
- mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
307
- mmp_sspa_write_reg(sspa, SSPA_TXFIFO_LL, 0x1);
308
- } else {
309
- mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
310
- mmp_sspa_write_reg(sspa, SSPA_RXFIFO_UL, 0x0);
242
+ if (dev->of_node || params_channels(params) == 2)
243
+ sspa_ctrl |= SSPA_CTL_XPH;
244
+
245
+ sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK;
246
+ sspa_ctrl |= SSPA_CTL_XWDLEN1(bitval);
247
+
248
+ sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK;
249
+ sspa_ctrl |= SSPA_CTL_XSSZ1(bitval);
250
+
251
+ sspa_ctrl &= ~SSPA_CTL_XSSZ2_MASK;
252
+ sspa_ctrl |= SSPA_CTL_XSSZ2(bitval);
253
+
254
+ sspa->sp &= ~SSPA_SP_FWID_MASK;
255
+ sspa->sp |= SSPA_SP_FWID(bits - 1);
256
+
257
+ sspa->sp &= ~SSPA_TXSP_FPER_MASK;
258
+ sspa->sp |= SSPA_TXSP_FPER(bits * 2 - 1);
259
+
260
+ if (dev->of_node) {
261
+ clk_set_rate(sspa->clk, params_rate(params) *
262
+ params_channels(params) * bits);
311263 }
312264
313
- dma_params = &sspa_priv->dma_params[substream->stream];
314
- dma_params->addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
315
- (sspa->phys_base + SSPA_TXD) :
316
- (sspa->phys_base + SSPA_RXD);
317
- snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
265
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
266
+ __raw_writel(sspa_ctrl, sspa->tx_base + SSPA_CTL);
267
+ __raw_writel(0x1, sspa->tx_base + SSPA_FIFO_UL);
268
+ } else {
269
+ __raw_writel(sspa_ctrl, sspa->rx_base + SSPA_CTL);
270
+ __raw_writel(0x0, sspa->rx_base + SSPA_FIFO_UL);
271
+ }
272
+
318273 return 0;
319274 }
320275
321276 static int mmp_sspa_trigger(struct snd_pcm_substream *substream, int cmd,
322277 struct snd_soc_dai *dai)
323278 {
324
- struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
325
- struct ssp_device *sspa = sspa_priv->sspa;
279
+ struct sspa_priv *sspa = snd_soc_dai_get_drvdata(dai);
326280 int ret = 0;
327281
328282 switch (cmd) {
....@@ -335,25 +289,25 @@
335289 * enabled or not; if has been enabled by another
336290 * stream, do not enable again.
337291 */
338
- if (!sspa_priv->running_cnt)
292
+ if (!sspa->running_cnt)
339293 mmp_sspa_rx_enable(sspa);
340294
341295 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
342296 mmp_sspa_tx_enable(sspa);
343297
344
- sspa_priv->running_cnt++;
298
+ sspa->running_cnt++;
345299 break;
346300
347301 case SNDRV_PCM_TRIGGER_STOP:
348302 case SNDRV_PCM_TRIGGER_SUSPEND:
349303 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
350
- sspa_priv->running_cnt--;
304
+ sspa->running_cnt--;
351305
352306 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
353307 mmp_sspa_tx_disable(sspa);
354308
355309 /* have no capture stream, disable rx port */
356
- if (!sspa_priv->running_cnt)
310
+ if (!sspa->running_cnt)
357311 mmp_sspa_rx_disable(sspa);
358312 break;
359313
....@@ -366,17 +320,20 @@
366320
367321 static int mmp_sspa_probe(struct snd_soc_dai *dai)
368322 {
369
- struct sspa_priv *priv = dev_get_drvdata(dai->dev);
323
+ struct sspa_priv *sspa = dev_get_drvdata(dai->dev);
370324
371
- snd_soc_dai_set_drvdata(dai, priv);
325
+ snd_soc_dai_init_dma_data(dai,
326
+ &sspa->playback_dma_data,
327
+ &sspa->capture_dma_data);
328
+
329
+ snd_soc_dai_set_drvdata(dai, sspa);
372330 return 0;
373
-
374331 }
375332
376333 #define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000
377334 #define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
378335 SNDRV_PCM_FMTBIT_S16_LE | \
379
- SNDRV_PCM_FMTBIT_S24_LE | \
336
+ SNDRV_PCM_FMTBIT_S24_3LE | \
380337 SNDRV_PCM_FMTBIT_S32_LE)
381338
382339 static const struct snd_soc_dai_ops mmp_sspa_dai_ops = {
....@@ -406,70 +363,212 @@
406363 .ops = &mmp_sspa_dai_ops,
407364 };
408365
366
+#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
367
+ SNDRV_PCM_INFO_MMAP_VALID | \
368
+ SNDRV_PCM_INFO_INTERLEAVED | \
369
+ SNDRV_PCM_INFO_PAUSE | \
370
+ SNDRV_PCM_INFO_RESUME | \
371
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP)
372
+
373
+static const struct snd_pcm_hardware mmp_pcm_hardware[] = {
374
+ {
375
+ .info = MMP_PCM_INFO,
376
+ .period_bytes_min = 1024,
377
+ .period_bytes_max = 2048,
378
+ .periods_min = 2,
379
+ .periods_max = 32,
380
+ .buffer_bytes_max = 4096,
381
+ .fifo_size = 32,
382
+ },
383
+ {
384
+ .info = MMP_PCM_INFO,
385
+ .period_bytes_min = 1024,
386
+ .period_bytes_max = 2048,
387
+ .periods_min = 2,
388
+ .periods_max = 32,
389
+ .buffer_bytes_max = 4096,
390
+ .fifo_size = 32,
391
+ },
392
+};
393
+
394
+static const struct snd_dmaengine_pcm_config mmp_pcm_config = {
395
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
396
+ .pcm_hardware = mmp_pcm_hardware,
397
+ .prealloc_buffer_size = 4096,
398
+};
399
+
400
+static int mmp_pcm_mmap(struct snd_soc_component *component,
401
+ struct snd_pcm_substream *substream,
402
+ struct vm_area_struct *vma)
403
+{
404
+ vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
405
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
406
+ return remap_pfn_range(vma, vma->vm_start,
407
+ substream->dma_buffer.addr >> PAGE_SHIFT,
408
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
409
+}
410
+
411
+static int mmp_sspa_open(struct snd_soc_component *component,
412
+ struct snd_pcm_substream *substream)
413
+{
414
+ struct sspa_priv *sspa = snd_soc_component_get_drvdata(component);
415
+
416
+ pm_runtime_get_sync(component->dev);
417
+
418
+ /* we can only change the settings if the port is not in use */
419
+ if ((__raw_readl(sspa->tx_base + SSPA_SP) & SSPA_SP_S_EN) ||
420
+ (__raw_readl(sspa->rx_base + SSPA_SP) & SSPA_SP_S_EN)) {
421
+ dev_err(component->dev,
422
+ "can't change hardware dai format: stream is in use\n");
423
+ return -EBUSY;
424
+ }
425
+
426
+ __raw_writel(sspa->sp, sspa->tx_base + SSPA_SP);
427
+ __raw_writel(sspa->sp, sspa->rx_base + SSPA_SP);
428
+
429
+ sspa->sp &= ~(SSPA_SP_S_RST | SSPA_SP_FFLUSH);
430
+ __raw_writel(sspa->sp, sspa->tx_base + SSPA_SP);
431
+ __raw_writel(sspa->sp, sspa->rx_base + SSPA_SP);
432
+
433
+ /*
434
+ * FIXME: hw issue, for the tx serial port,
435
+ * can not config the master/slave mode;
436
+ * so must clean this bit.
437
+ * The master/slave mode has been set in the
438
+ * rx port.
439
+ */
440
+ __raw_writel(sspa->sp & ~SSPA_SP_MSL, sspa->tx_base + SSPA_SP);
441
+
442
+ __raw_writel(sspa->ctrl, sspa->tx_base + SSPA_CTL);
443
+ __raw_writel(sspa->ctrl, sspa->rx_base + SSPA_CTL);
444
+
445
+ return 0;
446
+}
447
+
448
+static int mmp_sspa_close(struct snd_soc_component *component,
449
+ struct snd_pcm_substream *substream)
450
+{
451
+ pm_runtime_put_sync(component->dev);
452
+ return 0;
453
+}
454
+
409455 static const struct snd_soc_component_driver mmp_sspa_component = {
410456 .name = "mmp-sspa",
457
+ .mmap = mmp_pcm_mmap,
458
+ .open = mmp_sspa_open,
459
+ .close = mmp_sspa_close,
411460 };
412461
413462 static int asoc_mmp_sspa_probe(struct platform_device *pdev)
414463 {
415
- struct sspa_priv *priv;
416
- struct resource *res;
464
+ struct sspa_priv *sspa;
465
+ int ret;
417466
418
- priv = devm_kzalloc(&pdev->dev,
467
+ sspa = devm_kzalloc(&pdev->dev,
419468 sizeof(struct sspa_priv), GFP_KERNEL);
420
- if (!priv)
469
+ if (!sspa)
421470 return -ENOMEM;
422471
423
- priv->sspa = devm_kzalloc(&pdev->dev,
424
- sizeof(struct ssp_device), GFP_KERNEL);
425
- if (priv->sspa == NULL)
426
- return -ENOMEM;
472
+ if (pdev->dev.of_node) {
473
+ sspa->rx_base = devm_platform_ioremap_resource(pdev, 0);
474
+ if (IS_ERR(sspa->rx_base))
475
+ return PTR_ERR(sspa->rx_base);
427476
428
- priv->dma_params = devm_kcalloc(&pdev->dev,
429
- 2, sizeof(struct snd_dmaengine_dai_dma_data),
430
- GFP_KERNEL);
431
- if (priv->dma_params == NULL)
432
- return -ENOMEM;
477
+ sspa->tx_base = devm_platform_ioremap_resource(pdev, 1);
478
+ if (IS_ERR(sspa->tx_base))
479
+ return PTR_ERR(sspa->tx_base);
433480
434
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
435
- priv->sspa->mmio_base = devm_ioremap_resource(&pdev->dev, res);
436
- if (IS_ERR(priv->sspa->mmio_base))
437
- return PTR_ERR(priv->sspa->mmio_base);
481
+ sspa->clk = devm_clk_get(&pdev->dev, "bitclk");
482
+ if (IS_ERR(sspa->clk))
483
+ return PTR_ERR(sspa->clk);
438484
439
- priv->sspa->clk = devm_clk_get(&pdev->dev, NULL);
440
- if (IS_ERR(priv->sspa->clk))
441
- return PTR_ERR(priv->sspa->clk);
485
+ sspa->audio_clk = devm_clk_get(&pdev->dev, "audio");
486
+ if (IS_ERR(sspa->audio_clk))
487
+ return PTR_ERR(sspa->audio_clk);
488
+ } else {
489
+ struct resource *res;
442490
443
- priv->audio_clk = clk_get(NULL, "mmp-audio");
444
- if (IS_ERR(priv->audio_clk))
445
- return PTR_ERR(priv->audio_clk);
491
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
492
+ if (res == NULL)
493
+ return -ENODEV;
446494
447
- priv->sysclk = clk_get(NULL, "mmp-sysclk");
448
- if (IS_ERR(priv->sysclk)) {
449
- clk_put(priv->audio_clk);
450
- return PTR_ERR(priv->sysclk);
495
+ sspa->rx_base = devm_ioremap(&pdev->dev, res->start, 0x30);
496
+ if (!sspa->rx_base)
497
+ return -ENOMEM;
498
+
499
+ sspa->tx_base = devm_ioremap(&pdev->dev,
500
+ res->start + 0x80, 0x30);
501
+ if (!sspa->tx_base)
502
+ return -ENOMEM;
503
+
504
+ sspa->clk = devm_clk_get(&pdev->dev, NULL);
505
+ if (IS_ERR(sspa->clk))
506
+ return PTR_ERR(sspa->clk);
507
+
508
+ sspa->audio_clk = clk_get(NULL, "mmp-audio");
509
+ if (IS_ERR(sspa->audio_clk))
510
+ return PTR_ERR(sspa->audio_clk);
511
+
512
+ sspa->sysclk = clk_get(NULL, "mmp-sysclk");
513
+ if (IS_ERR(sspa->sysclk)) {
514
+ clk_put(sspa->audio_clk);
515
+ return PTR_ERR(sspa->sysclk);
516
+ }
451517 }
452
- clk_enable(priv->audio_clk);
453
- priv->dai_fmt = (unsigned int) -1;
454
- platform_set_drvdata(pdev, priv);
518
+ platform_set_drvdata(pdev, sspa);
455519
456
- return devm_snd_soc_register_component(&pdev->dev, &mmp_sspa_component,
457
- &mmp_sspa_dai, 1);
520
+ sspa->playback_dma_data.maxburst = 4;
521
+ sspa->capture_dma_data.maxburst = 4;
522
+ /* You know, these addresses are actually ignored. */
523
+ sspa->capture_dma_data.addr = SSPA_D;
524
+ sspa->playback_dma_data.addr = 0x80 + SSPA_D;
525
+
526
+ if (pdev->dev.of_node) {
527
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
528
+ &mmp_pcm_config, 0);
529
+ if (ret)
530
+ return ret;
531
+ }
532
+
533
+ ret = devm_snd_soc_register_component(&pdev->dev, &mmp_sspa_component,
534
+ &mmp_sspa_dai, 1);
535
+ if (ret)
536
+ return ret;
537
+
538
+ pm_runtime_enable(&pdev->dev);
539
+ clk_prepare_enable(sspa->audio_clk);
540
+
541
+ return 0;
458542 }
459543
460544 static int asoc_mmp_sspa_remove(struct platform_device *pdev)
461545 {
462
- struct sspa_priv *priv = platform_get_drvdata(pdev);
546
+ struct sspa_priv *sspa = platform_get_drvdata(pdev);
463547
464
- clk_disable(priv->audio_clk);
465
- clk_put(priv->audio_clk);
466
- clk_put(priv->sysclk);
548
+ clk_disable_unprepare(sspa->audio_clk);
549
+ pm_runtime_disable(&pdev->dev);
550
+
551
+ if (pdev->dev.of_node)
552
+ return 0;
553
+
554
+ clk_put(sspa->audio_clk);
555
+ clk_put(sspa->sysclk);
467556 return 0;
468557 }
558
+
559
+#ifdef CONFIG_OF
560
+static const struct of_device_id mmp_sspa_of_match[] = {
561
+ { .compatible = "marvell,mmp-sspa" },
562
+ {},
563
+};
564
+
565
+MODULE_DEVICE_TABLE(of, mmp_sspa_of_match);
566
+#endif
469567
470568 static struct platform_driver asoc_mmp_sspa_driver = {
471569 .driver = {
472570 .name = "mmp-sspa-dai",
571
+ .of_match_table = of_match_ptr(mmp_sspa_of_match),
473572 },
474573 .probe = asoc_mmp_sspa_probe,
475574 .remove = asoc_mmp_sspa_remove,