axg-fifo.c (1913c7f3fc2514e09262baf2267a82dfdb215c39) axg-fifo.c (bb4ba744b1701caf6148ff3b4e8656bf4f6b4758)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2//
3// Copyright (c) 2018 BayLibre, SAS.
4// Author: Jerome Brunet <jbrunet@baylibre.com>
5
6#include <linux/clk.h>
7#include <linux/of_irq.h>
8#include <linux/of_platform.h>

--- 56 unchanged lines hidden (view full) ---

65}
66
67static void __dma_enable(struct axg_fifo *fifo, bool enable)
68{
69 regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_DMA_EN,
70 enable ? CTRL0_DMA_EN : 0);
71}
72
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2//
3// Copyright (c) 2018 BayLibre, SAS.
4// Author: Jerome Brunet <jbrunet@baylibre.com>
5
6#include <linux/clk.h>
7#include <linux/of_irq.h>
8#include <linux/of_platform.h>

--- 56 unchanged lines hidden (view full) ---

65}
66
67static void __dma_enable(struct axg_fifo *fifo, bool enable)
68{
69 regmap_update_bits(fifo->map, FIFO_CTRL0, CTRL0_DMA_EN,
70 enable ? CTRL0_DMA_EN : 0);
71}
72
73static int axg_fifo_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
73int axg_fifo_pcm_trigger(struct snd_soc_component *component,
74 struct snd_pcm_substream *ss, int cmd)
74{
75 struct axg_fifo *fifo = axg_fifo_data(ss);
76
77 switch (cmd) {
78 case SNDRV_PCM_TRIGGER_START:
79 case SNDRV_PCM_TRIGGER_RESUME:
80 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
81 __dma_enable(fifo, true);

--- 4 unchanged lines hidden (view full) ---

86 __dma_enable(fifo, false);
87 break;
88 default:
89 return -EINVAL;
90 }
91
92 return 0;
93}
75{
76 struct axg_fifo *fifo = axg_fifo_data(ss);
77
78 switch (cmd) {
79 case SNDRV_PCM_TRIGGER_START:
80 case SNDRV_PCM_TRIGGER_RESUME:
81 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
82 __dma_enable(fifo, true);

--- 4 unchanged lines hidden (view full) ---

87 __dma_enable(fifo, false);
88 break;
89 default:
90 return -EINVAL;
91 }
92
93 return 0;
94}
95EXPORT_SYMBOL_GPL(axg_fifo_pcm_trigger);
94
96
95static snd_pcm_uframes_t axg_fifo_pcm_pointer(struct snd_pcm_substream *ss)
97snd_pcm_uframes_t axg_fifo_pcm_pointer(struct snd_soc_component *component,
98 struct snd_pcm_substream *ss)
96{
97 struct axg_fifo *fifo = axg_fifo_data(ss);
98 struct snd_pcm_runtime *runtime = ss->runtime;
99 unsigned int addr;
100
101 regmap_read(fifo->map, FIFO_STATUS2, &addr);
102
103 return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
104}
99{
100 struct axg_fifo *fifo = axg_fifo_data(ss);
101 struct snd_pcm_runtime *runtime = ss->runtime;
102 unsigned int addr;
103
104 regmap_read(fifo->map, FIFO_STATUS2, &addr);
105
106 return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
107}
108EXPORT_SYMBOL_GPL(axg_fifo_pcm_pointer);
105
109
106static int axg_fifo_pcm_hw_params(struct snd_pcm_substream *ss,
107 struct snd_pcm_hw_params *params)
110int axg_fifo_pcm_hw_params(struct snd_soc_component *component,
111 struct snd_pcm_substream *ss,
112 struct snd_pcm_hw_params *params)
108{
109 struct snd_pcm_runtime *runtime = ss->runtime;
110 struct axg_fifo *fifo = axg_fifo_data(ss);
111 dma_addr_t end_ptr;
112 unsigned int burst_num;
113 int ret;
114
115 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(params));

--- 11 unchanged lines hidden (view full) ---

127
128 /* Enable block count irq */
129 regmap_update_bits(fifo->map, FIFO_CTRL0,
130 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT),
131 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT));
132
133 return 0;
134}
113{
114 struct snd_pcm_runtime *runtime = ss->runtime;
115 struct axg_fifo *fifo = axg_fifo_data(ss);
116 dma_addr_t end_ptr;
117 unsigned int burst_num;
118 int ret;
119
120 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(params));

--- 11 unchanged lines hidden (view full) ---

132
133 /* Enable block count irq */
134 regmap_update_bits(fifo->map, FIFO_CTRL0,
135 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT),
136 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT));
137
138 return 0;
139}
140EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_params);
135
141
136static int g12a_fifo_pcm_hw_params(struct snd_pcm_substream *ss,
137 struct snd_pcm_hw_params *params)
142int g12a_fifo_pcm_hw_params(struct snd_soc_component *component,
143 struct snd_pcm_substream *ss,
144 struct snd_pcm_hw_params *params)
138{
139 struct axg_fifo *fifo = axg_fifo_data(ss);
140 struct snd_pcm_runtime *runtime = ss->runtime;
141 int ret;
142
145{
146 struct axg_fifo *fifo = axg_fifo_data(ss);
147 struct snd_pcm_runtime *runtime = ss->runtime;
148 int ret;
149
143 ret = axg_fifo_pcm_hw_params(ss, params);
150 ret = axg_fifo_pcm_hw_params(component, ss, params);
144 if (ret)
145 return ret;
146
147 /* Set the initial memory address of the DMA */
148 regmap_write(fifo->map, FIFO_INIT_ADDR, runtime->dma_addr);
149
150 return 0;
151}
151 if (ret)
152 return ret;
153
154 /* Set the initial memory address of the DMA */
155 regmap_write(fifo->map, FIFO_INIT_ADDR, runtime->dma_addr);
156
157 return 0;
158}
159EXPORT_SYMBOL_GPL(g12a_fifo_pcm_hw_params);
152
160
153static int axg_fifo_pcm_hw_free(struct snd_pcm_substream *ss)
161int axg_fifo_pcm_hw_free(struct snd_soc_component *component,
162 struct snd_pcm_substream *ss)
154{
155 struct axg_fifo *fifo = axg_fifo_data(ss);
156
157 /* Disable the block count irq */
158 regmap_update_bits(fifo->map, FIFO_CTRL0,
159 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), 0);
160
161 return snd_pcm_lib_free_pages(ss);
162}
163{
164 struct axg_fifo *fifo = axg_fifo_data(ss);
165
166 /* Disable the block count irq */
167 regmap_update_bits(fifo->map, FIFO_CTRL0,
168 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT), 0);
169
170 return snd_pcm_lib_free_pages(ss);
171}
172EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free);
163
164static void axg_fifo_ack_irq(struct axg_fifo *fifo, u8 mask)
165{
166 regmap_update_bits(fifo->map, FIFO_CTRL1,
167 CTRL1_INT_CLR(FIFO_INT_MASK),
168 CTRL1_INT_CLR(mask));
169
170 /* Clear must also be cleared */

--- 18 unchanged lines hidden (view full) ---

189 status);
190
191 /* Ack irqs */
192 axg_fifo_ack_irq(fifo, status);
193
194 return IRQ_RETVAL(status);
195}
196
173
174static void axg_fifo_ack_irq(struct axg_fifo *fifo, u8 mask)
175{
176 regmap_update_bits(fifo->map, FIFO_CTRL1,
177 CTRL1_INT_CLR(FIFO_INT_MASK),
178 CTRL1_INT_CLR(mask));
179
180 /* Clear must also be cleared */

--- 18 unchanged lines hidden (view full) ---

199 status);
200
201 /* Ack irqs */
202 axg_fifo_ack_irq(fifo, status);
203
204 return IRQ_RETVAL(status);
205}
206
197static int axg_fifo_pcm_open(struct snd_pcm_substream *ss)
207int axg_fifo_pcm_open(struct snd_soc_component *component,
208 struct snd_pcm_substream *ss)
198{
199 struct axg_fifo *fifo = axg_fifo_data(ss);
200 struct device *dev = axg_fifo_dev(ss);
201 int ret;
202
203 snd_soc_set_runtime_hwparams(ss, &axg_fifo_hw);
204
205 /*

--- 39 unchanged lines hidden (view full) ---

245
246 /* Take memory arbitror out of reset */
247 ret = reset_control_deassert(fifo->arb);
248 if (ret)
249 clk_disable_unprepare(fifo->pclk);
250
251 return ret;
252}
209{
210 struct axg_fifo *fifo = axg_fifo_data(ss);
211 struct device *dev = axg_fifo_dev(ss);
212 int ret;
213
214 snd_soc_set_runtime_hwparams(ss, &axg_fifo_hw);
215
216 /*

--- 39 unchanged lines hidden (view full) ---

256
257 /* Take memory arbitror out of reset */
258 ret = reset_control_deassert(fifo->arb);
259 if (ret)
260 clk_disable_unprepare(fifo->pclk);
261
262 return ret;
263}
264EXPORT_SYMBOL_GPL(axg_fifo_pcm_open);
253
265
254static int axg_fifo_pcm_close(struct snd_pcm_substream *ss)
266int axg_fifo_pcm_close(struct snd_soc_component *component,
267 struct snd_pcm_substream *ss)
255{
256 struct axg_fifo *fifo = axg_fifo_data(ss);
257 int ret;
258
259 /* Put the memory arbitror back in reset */
260 ret = reset_control_assert(fifo->arb);
261
262 /* Disable fifo ip and register access */
263 clk_disable_unprepare(fifo->pclk);
264
265 /* remove IRQ */
266 free_irq(fifo->irq, ss);
267
268 return ret;
269}
268{
269 struct axg_fifo *fifo = axg_fifo_data(ss);
270 int ret;
271
272 /* Put the memory arbitror back in reset */
273 ret = reset_control_assert(fifo->arb);
274
275 /* Disable fifo ip and register access */
276 clk_disable_unprepare(fifo->pclk);
277
278 /* remove IRQ */
279 free_irq(fifo->irq, ss);
280
281 return ret;
282}
283EXPORT_SYMBOL_GPL(axg_fifo_pcm_close);
270
284
271const struct snd_pcm_ops axg_fifo_pcm_ops = {
272 .open = axg_fifo_pcm_open,
273 .close = axg_fifo_pcm_close,
274 .ioctl = snd_pcm_lib_ioctl,
275 .hw_params = axg_fifo_pcm_hw_params,
276 .hw_free = axg_fifo_pcm_hw_free,
277 .pointer = axg_fifo_pcm_pointer,
278 .trigger = axg_fifo_pcm_trigger,
279};
280EXPORT_SYMBOL_GPL(axg_fifo_pcm_ops);
281
282const struct snd_pcm_ops g12a_fifo_pcm_ops = {
283 .open = axg_fifo_pcm_open,
284 .close = axg_fifo_pcm_close,
285 .ioctl = snd_pcm_lib_ioctl,
286 .hw_params = g12a_fifo_pcm_hw_params,
287 .hw_free = axg_fifo_pcm_hw_free,
288 .pointer = axg_fifo_pcm_pointer,
289 .trigger = axg_fifo_pcm_trigger,
290};
291EXPORT_SYMBOL_GPL(g12a_fifo_pcm_ops);
292
293int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type)
294{
295 struct snd_card *card = rtd->card->snd_card;
296 size_t size = axg_fifo_hw.buffer_bytes_max;
297
298 snd_pcm_lib_preallocate_pages(rtd->pcm->streams[type].substream,
299 SNDRV_DMA_TYPE_DEV, card->dev,
300 size, size);

--- 70 unchanged lines hidden ---
285int axg_fifo_pcm_new(struct snd_soc_pcm_runtime *rtd, unsigned int type)
286{
287 struct snd_card *card = rtd->card->snd_card;
288 size_t size = axg_fifo_hw.buffer_bytes_max;
289
290 snd_pcm_lib_preallocate_pages(rtd->pcm->streams[type].substream,
291 SNDRV_DMA_TYPE_DEV, card->dev,
292 size, size);

--- 70 unchanged lines hidden ---