forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/meson/axg-fifo.c
....@@ -19,7 +19,7 @@
1919 * This file implements the platform operations common to the playback and
2020 * capture frontend DAI. The logic behind this two types of fifo is very
2121 * similar but some difference exist.
22
- * These differences the respective DAI drivers
22
+ * These differences are handled in the respective DAI drivers
2323 */
2424
2525 static struct snd_pcm_hardware axg_fifo_hw = {
....@@ -34,7 +34,7 @@
3434 .rate_max = 192000,
3535 .channels_min = 1,
3636 .channels_max = AXG_FIFO_CH_MAX,
37
- .period_bytes_min = AXG_FIFO_MIN_DEPTH,
37
+ .period_bytes_min = AXG_FIFO_BURST,
3838 .period_bytes_max = UINT_MAX,
3939 .periods_min = 2,
4040 .periods_max = UINT_MAX,
....@@ -47,7 +47,7 @@
4747 {
4848 struct snd_soc_pcm_runtime *rtd = ss->private_data;
4949
50
- return rtd->cpu_dai;
50
+ return asoc_rtd_to_cpu(rtd, 0);
5151 }
5252
5353 static struct axg_fifo *axg_fifo_data(struct snd_pcm_substream *ss)
....@@ -70,7 +70,8 @@
7070 enable ? CTRL0_DMA_EN : 0);
7171 }
7272
73
-static int axg_fifo_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
73
+int axg_fifo_pcm_trigger(struct snd_soc_component *component,
74
+ struct snd_pcm_substream *ss, int cmd)
7475 {
7576 struct axg_fifo *fifo = axg_fifo_data(ss);
7677
....@@ -91,8 +92,10 @@
9192
9293 return 0;
9394 }
95
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_trigger);
9496
95
-static snd_pcm_uframes_t axg_fifo_pcm_pointer(struct snd_pcm_substream *ss)
97
+snd_pcm_uframes_t axg_fifo_pcm_pointer(struct snd_soc_component *component,
98
+ struct snd_pcm_substream *ss)
9699 {
97100 struct axg_fifo *fifo = axg_fifo_data(ss);
98101 struct snd_pcm_runtime *runtime = ss->runtime;
....@@ -102,19 +105,18 @@
102105
103106 return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
104107 }
108
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_pointer);
105109
106
-static int axg_fifo_pcm_hw_params(struct snd_pcm_substream *ss,
107
- struct snd_pcm_hw_params *params)
110
+int axg_fifo_pcm_hw_params(struct snd_soc_component *component,
111
+ struct snd_pcm_substream *ss,
112
+ struct snd_pcm_hw_params *params)
108113 {
109114 struct snd_pcm_runtime *runtime = ss->runtime;
110115 struct axg_fifo *fifo = axg_fifo_data(ss);
116
+ unsigned int burst_num, period, threshold;
111117 dma_addr_t end_ptr;
112
- unsigned int burst_num;
113
- int ret;
114118
115
- ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(params));
116
- if (ret < 0)
117
- return ret;
119
+ period = params_period_bytes(params);
118120
119121 /* Setup dma memory pointers */
120122 end_ptr = runtime->dma_addr + runtime->dma_bytes - AXG_FIFO_BURST;
....@@ -122,8 +124,23 @@
122124 regmap_write(fifo->map, FIFO_FINISH_ADDR, end_ptr);
123125
124126 /* Setup interrupt periodicity */
125
- burst_num = params_period_bytes(params) / AXG_FIFO_BURST;
127
+ burst_num = period / AXG_FIFO_BURST;
126128 regmap_write(fifo->map, FIFO_INT_ADDR, burst_num);
129
+
130
+ /*
131
+ * Start the fifo request on the smallest of the following:
132
+ * - Half the fifo size
133
+ * - Half the period size
134
+ */
135
+ threshold = min(period / 2, fifo->depth / 2);
136
+
137
+ /*
138
+ * With the threshold in bytes, register value is:
139
+ * V = (threshold / burst) - 1
140
+ */
141
+ threshold /= AXG_FIFO_BURST;
142
+ regmap_field_write(fifo->field_threshold,
143
+ threshold ? threshold - 1 : 0);
127144
128145 /* Enable block count irq */
129146 regmap_update_bits(fifo->map, FIFO_CTRL0,
....@@ -132,8 +149,29 @@
132149
133150 return 0;
134151 }
152
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_params);
135153
136
-static int axg_fifo_pcm_hw_free(struct snd_pcm_substream *ss)
154
+int g12a_fifo_pcm_hw_params(struct snd_soc_component *component,
155
+ struct snd_pcm_substream *ss,
156
+ struct snd_pcm_hw_params *params)
157
+{
158
+ struct axg_fifo *fifo = axg_fifo_data(ss);
159
+ struct snd_pcm_runtime *runtime = ss->runtime;
160
+ int ret;
161
+
162
+ ret = axg_fifo_pcm_hw_params(component, ss, params);
163
+ if (ret)
164
+ return ret;
165
+
166
+ /* Set the initial memory address of the DMA */
167
+ regmap_write(fifo->map, FIFO_INIT_ADDR, runtime->dma_addr);
168
+
169
+ return 0;
170
+}
171
+EXPORT_SYMBOL_GPL(g12a_fifo_pcm_hw_params);
172
+
173
+int axg_fifo_pcm_hw_free(struct snd_soc_component *component,
174
+ struct snd_pcm_substream *ss)
137175 {
138176 struct axg_fifo *fifo = axg_fifo_data(ss);
139177
....@@ -141,8 +179,9 @@
141179 regmap_update_bits(fifo->map, FIFO_CTRL0,
142180 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), 0);
143181
144
- return snd_pcm_lib_free_pages(ss);
182
+ return 0;
145183 }
184
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free);
146185
147186 static void axg_fifo_ack_irq(struct axg_fifo *fifo, u8 mask)
148187 {
....@@ -177,7 +216,8 @@
177216 return IRQ_RETVAL(status);
178217 }
179218
180
-static int axg_fifo_pcm_open(struct snd_pcm_substream *ss)
219
+int axg_fifo_pcm_open(struct snd_soc_component *component,
220
+ struct snd_pcm_substream *ss)
181221 {
182222 struct axg_fifo *fifo = axg_fifo_data(ss);
183223 struct device *dev = axg_fifo_dev(ss);
....@@ -187,17 +227,17 @@
187227
188228 /*
189229 * Make sure the buffer and period size are multiple of the FIFO
190
- * minimum depth size
230
+ * burst
191231 */
192232 ret = snd_pcm_hw_constraint_step(ss->runtime, 0,
193233 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
194
- AXG_FIFO_MIN_DEPTH);
234
+ AXG_FIFO_BURST);
195235 if (ret)
196236 return ret;
197237
198238 ret = snd_pcm_hw_constraint_step(ss->runtime, 0,
199239 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
200
- AXG_FIFO_MIN_DEPTH);
240
+ AXG_FIFO_BURST);
201241 if (ret)
202242 return ret;
203243
....@@ -239,8 +279,10 @@
239279 free_irq(fifo->irq, ss);
240280 return ret;
241281 }
282
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_open);
242283
243
-static int axg_fifo_pcm_close(struct snd_pcm_substream *ss)
284
+int axg_fifo_pcm_close(struct snd_soc_component *component,
285
+ struct snd_pcm_substream *ss)
244286 {
245287 struct axg_fifo *fifo = axg_fifo_data(ss);
246288 int ret;
....@@ -256,26 +298,17 @@
256298
257299 return ret;
258300 }
259
-
260
-const struct snd_pcm_ops axg_fifo_pcm_ops = {
261
- .open = axg_fifo_pcm_open,
262
- .close = axg_fifo_pcm_close,
263
- .ioctl = snd_pcm_lib_ioctl,
264
- .hw_params = axg_fifo_pcm_hw_params,
265
- .hw_free = axg_fifo_pcm_hw_free,
266
- .pointer = axg_fifo_pcm_pointer,
267
- .trigger = axg_fifo_pcm_trigger,
268
-};
269
-EXPORT_SYMBOL_GPL(axg_fifo_pcm_ops);
301
+EXPORT_SYMBOL_GPL(axg_fifo_pcm_close);
270302
271303 int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type)
272304 {
273305 struct snd_card *card = rtd->card->snd_card;
274306 size_t size = axg_fifo_hw.buffer_bytes_max;
275307
276
- return snd_pcm_lib_preallocate_pages(rtd->pcm->streams[type].substream,
277
- SNDRV_DMA_TYPE_DEV, card->dev,
278
- size, size);
308
+ snd_pcm_set_managed_buffer(rtd->pcm->streams[type].substream,
309
+ SNDRV_DMA_TYPE_DEV, card->dev,
310
+ size, size);
311
+ return 0;
279312 }
280313 EXPORT_SYMBOL_GPL(axg_fifo_pcm_new);
281314
....@@ -283,7 +316,7 @@
283316 .reg_bits = 32,
284317 .val_bits = 32,
285318 .reg_stride = 4,
286
- .max_register = FIFO_STATUS2,
319
+ .max_register = FIFO_CTRL2,
287320 };
288321
289322 int axg_fifo_probe(struct platform_device *pdev)
....@@ -291,8 +324,8 @@
291324 struct device *dev = &pdev->dev;
292325 const struct axg_fifo_match_data *data;
293326 struct axg_fifo *fifo;
294
- struct resource *res;
295327 void __iomem *regs;
328
+ int ret;
296329
297330 data = of_device_get_match_data(dev);
298331 if (!data) {
....@@ -305,8 +338,7 @@
305338 return -ENOMEM;
306339 platform_set_drvdata(pdev, fifo);
307340
308
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
309
- regs = devm_ioremap_resource(dev, res);
341
+ regs = devm_platform_ioremap_resource(pdev, 0);
310342 if (IS_ERR(regs))
311343 return PTR_ERR(regs);
312344
....@@ -339,11 +371,31 @@
339371 return fifo->irq;
340372 }
341373
374
+ fifo->field_threshold =
375
+ devm_regmap_field_alloc(dev, fifo->map, data->field_threshold);
376
+ if (IS_ERR(fifo->field_threshold))
377
+ return PTR_ERR(fifo->field_threshold);
378
+
379
+ ret = of_property_read_u32(dev->of_node, "amlogic,fifo-depth",
380
+ &fifo->depth);
381
+ if (ret) {
382
+ /* Error out for anything but a missing property */
383
+ if (ret != -EINVAL)
384
+ return ret;
385
+ /*
386
+ * If the property is missing, it might be because of an old
387
+ * DT. In such case, assume the smallest known fifo depth
388
+ */
389
+ fifo->depth = 256;
390
+ dev_warn(dev, "fifo depth not found, assume %u bytes\n",
391
+ fifo->depth);
392
+ }
393
+
342394 return devm_snd_soc_register_component(dev, data->component_drv,
343395 data->dai_drv, 1);
344396 }
345397 EXPORT_SYMBOL_GPL(axg_fifo_probe);
346398
347
-MODULE_DESCRIPTION("Amlogic AXG fifo driver");
399
+MODULE_DESCRIPTION("Amlogic AXG/G12A fifo driver");
348400 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
349401 MODULE_LICENSE("GPL v2");