1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 // Copyright (c) 2018 BayLibre, SAS.
4 // Author: Jerome Brunet <jbrunet@baylibre.com>
7 #include <linux/of_irq.h>
8 #include <linux/of_platform.h>
9 #include <linux/module.h>
10 #include <linux/regmap.h>
11 #include <linux/reset.h>
12 #include <sound/pcm_params.h>
13 #include <sound/soc.h>
14 #include <sound/soc-dai.h>
19 * This file implements the platform operations common to the playback and
20 * capture frontend DAI. The logic behind this two types of fifo is very
21 * similar but some difference exist.
22 * These differences are handled in the respective DAI drivers
25 static struct snd_pcm_hardware axg_fifo_hw
= {
26 .info
= (SNDRV_PCM_INFO_INTERLEAVED
|
28 SNDRV_PCM_INFO_MMAP_VALID
|
29 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
30 SNDRV_PCM_INFO_PAUSE
),
32 .formats
= AXG_FIFO_FORMATS
,
36 .channels_max
= AXG_FIFO_CH_MAX
,
37 .period_bytes_min
= AXG_FIFO_BURST
,
38 .period_bytes_max
= UINT_MAX
,
40 .periods_max
= UINT_MAX
,
42 /* No real justification for this */
43 .buffer_bytes_max
= 1 * 1024 * 1024,
46 static struct snd_soc_dai
*axg_fifo_dai(struct snd_pcm_substream
*ss
)
48 struct snd_soc_pcm_runtime
*rtd
= ss
->private_data
;
53 static struct axg_fifo
*axg_fifo_data(struct snd_pcm_substream
*ss
)
55 struct snd_soc_dai
*dai
= axg_fifo_dai(ss
);
57 return snd_soc_dai_get_drvdata(dai
);
60 static struct device
*axg_fifo_dev(struct snd_pcm_substream
*ss
)
62 struct snd_soc_dai
*dai
= axg_fifo_dai(ss
);
67 static void __dma_enable(struct axg_fifo
*fifo
, bool enable
)
69 regmap_update_bits(fifo
->map
, FIFO_CTRL0
, CTRL0_DMA_EN
,
70 enable
? CTRL0_DMA_EN
: 0);
73 int axg_fifo_pcm_trigger(struct snd_soc_component
*component
,
74 struct snd_pcm_substream
*ss
, int cmd
)
76 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
79 case SNDRV_PCM_TRIGGER_START
:
80 case SNDRV_PCM_TRIGGER_RESUME
:
81 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
82 __dma_enable(fifo
, true);
84 case SNDRV_PCM_TRIGGER_SUSPEND
:
85 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
86 case SNDRV_PCM_TRIGGER_STOP
:
87 __dma_enable(fifo
, false);
95 EXPORT_SYMBOL_GPL(axg_fifo_pcm_trigger
);
97 snd_pcm_uframes_t
axg_fifo_pcm_pointer(struct snd_soc_component
*component
,
98 struct snd_pcm_substream
*ss
)
100 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
101 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
104 regmap_read(fifo
->map
, FIFO_STATUS2
, &addr
);
106 return bytes_to_frames(runtime
, addr
- (unsigned int)runtime
->dma_addr
);
108 EXPORT_SYMBOL_GPL(axg_fifo_pcm_pointer
);
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
)
114 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
115 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
116 unsigned int burst_num
, period
, threshold
;
119 period
= params_period_bytes(params
);
121 /* Setup dma memory pointers */
122 end_ptr
= runtime
->dma_addr
+ runtime
->dma_bytes
- AXG_FIFO_BURST
;
123 regmap_write(fifo
->map
, FIFO_START_ADDR
, runtime
->dma_addr
);
124 regmap_write(fifo
->map
, FIFO_FINISH_ADDR
, end_ptr
);
126 /* Setup interrupt periodicity */
127 burst_num
= period
/ AXG_FIFO_BURST
;
128 regmap_write(fifo
->map
, FIFO_INT_ADDR
, burst_num
);
131 * Start the fifo request on the smallest of the following:
132 * - Half the fifo size
133 * - Half the period size
135 threshold
= min(period
/ 2, fifo
->depth
/ 2);
138 * With the threshold in bytes, register value is:
139 * V = (threshold / burst) - 1
141 threshold
/= AXG_FIFO_BURST
;
142 regmap_field_write(fifo
->field_threshold
,
143 threshold
? threshold
- 1 : 0);
145 /* Enable block count irq */
146 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
147 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT
),
148 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT
));
152 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_params
);
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
)
158 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
159 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
162 ret
= axg_fifo_pcm_hw_params(component
, ss
, params
);
166 /* Set the initial memory address of the DMA */
167 regmap_write(fifo
->map
, FIFO_INIT_ADDR
, runtime
->dma_addr
);
171 EXPORT_SYMBOL_GPL(g12a_fifo_pcm_hw_params
);
173 int axg_fifo_pcm_hw_free(struct snd_soc_component
*component
,
174 struct snd_pcm_substream
*ss
)
176 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
178 /* Disable the block count irq */
179 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
180 CTRL0_INT_EN(FIFO_INT_COUNT_REPEAT
), 0);
184 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free
);
186 static void axg_fifo_ack_irq(struct axg_fifo
*fifo
, u8 mask
)
188 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
189 CTRL1_INT_CLR(FIFO_INT_MASK
),
190 CTRL1_INT_CLR(mask
));
192 /* Clear must also be cleared */
193 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
194 CTRL1_INT_CLR(FIFO_INT_MASK
),
198 static irqreturn_t
axg_fifo_pcm_irq_block(int irq
, void *dev_id
)
200 struct snd_pcm_substream
*ss
= dev_id
;
201 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
204 regmap_read(fifo
->map
, FIFO_STATUS1
, &status
);
206 status
= STATUS1_INT_STS(status
) & FIFO_INT_MASK
;
207 if (status
& FIFO_INT_COUNT_REPEAT
)
208 snd_pcm_period_elapsed(ss
);
210 dev_dbg(axg_fifo_dev(ss
), "unexpected irq - STS 0x%02x\n",
214 axg_fifo_ack_irq(fifo
, status
);
216 return IRQ_RETVAL(status
);
219 int axg_fifo_pcm_open(struct snd_soc_component
*component
,
220 struct snd_pcm_substream
*ss
)
222 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
223 struct device
*dev
= axg_fifo_dev(ss
);
226 snd_soc_set_runtime_hwparams(ss
, &axg_fifo_hw
);
229 * Make sure the buffer and period size are multiple of the FIFO
232 ret
= snd_pcm_hw_constraint_step(ss
->runtime
, 0,
233 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
,
238 ret
= snd_pcm_hw_constraint_step(ss
->runtime
, 0,
239 SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
244 ret
= request_irq(fifo
->irq
, axg_fifo_pcm_irq_block
, 0,
249 /* Enable pclk to access registers and clock the fifo ip */
250 ret
= clk_prepare_enable(fifo
->pclk
);
254 /* Setup status2 so it reports the memory pointer */
255 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
256 CTRL1_STATUS2_SEL_MASK
,
257 CTRL1_STATUS2_SEL(STATUS2_SEL_DDR_READ
));
259 /* Make sure the dma is initially disabled */
260 __dma_enable(fifo
, false);
262 /* Disable irqs until params are ready */
263 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
264 CTRL0_INT_EN(FIFO_INT_MASK
), 0);
266 /* Clear any pending interrupt */
267 axg_fifo_ack_irq(fifo
, FIFO_INT_MASK
);
269 /* Take memory arbitror out of reset */
270 ret
= reset_control_deassert(fifo
->arb
);
272 clk_disable_unprepare(fifo
->pclk
);
276 EXPORT_SYMBOL_GPL(axg_fifo_pcm_open
);
278 int axg_fifo_pcm_close(struct snd_soc_component
*component
,
279 struct snd_pcm_substream
*ss
)
281 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
284 /* Put the memory arbitror back in reset */
285 ret
= reset_control_assert(fifo
->arb
);
287 /* Disable fifo ip and register access */
288 clk_disable_unprepare(fifo
->pclk
);
291 free_irq(fifo
->irq
, ss
);
295 EXPORT_SYMBOL_GPL(axg_fifo_pcm_close
);
297 int axg_fifo_pcm_new(struct snd_soc_pcm_runtime
*rtd
, unsigned int type
)
299 struct snd_card
*card
= rtd
->card
->snd_card
;
300 size_t size
= axg_fifo_hw
.buffer_bytes_max
;
302 snd_pcm_set_managed_buffer(rtd
->pcm
->streams
[type
].substream
,
303 SNDRV_DMA_TYPE_DEV
, card
->dev
,
307 EXPORT_SYMBOL_GPL(axg_fifo_pcm_new
);
309 static const struct regmap_config axg_fifo_regmap_cfg
= {
313 .max_register
= FIFO_CTRL2
,
316 int axg_fifo_probe(struct platform_device
*pdev
)
318 struct device
*dev
= &pdev
->dev
;
319 const struct axg_fifo_match_data
*data
;
320 struct axg_fifo
*fifo
;
324 data
= of_device_get_match_data(dev
);
326 dev_err(dev
, "failed to match device\n");
330 fifo
= devm_kzalloc(dev
, sizeof(*fifo
), GFP_KERNEL
);
333 platform_set_drvdata(pdev
, fifo
);
335 regs
= devm_platform_ioremap_resource(pdev
, 0);
337 return PTR_ERR(regs
);
339 fifo
->map
= devm_regmap_init_mmio(dev
, regs
, &axg_fifo_regmap_cfg
);
340 if (IS_ERR(fifo
->map
)) {
341 dev_err(dev
, "failed to init regmap: %ld\n",
343 return PTR_ERR(fifo
->map
);
346 fifo
->pclk
= devm_clk_get(dev
, NULL
);
347 if (IS_ERR(fifo
->pclk
)) {
348 if (PTR_ERR(fifo
->pclk
) != -EPROBE_DEFER
)
349 dev_err(dev
, "failed to get pclk: %ld\n",
350 PTR_ERR(fifo
->pclk
));
351 return PTR_ERR(fifo
->pclk
);
354 fifo
->arb
= devm_reset_control_get_exclusive(dev
, NULL
);
355 if (IS_ERR(fifo
->arb
)) {
356 if (PTR_ERR(fifo
->arb
) != -EPROBE_DEFER
)
357 dev_err(dev
, "failed to get arb reset: %ld\n",
359 return PTR_ERR(fifo
->arb
);
362 fifo
->irq
= of_irq_get(dev
->of_node
, 0);
363 if (fifo
->irq
<= 0) {
364 dev_err(dev
, "failed to get irq: %d\n", fifo
->irq
);
368 fifo
->field_threshold
=
369 devm_regmap_field_alloc(dev
, fifo
->map
, data
->field_threshold
);
370 if (IS_ERR(fifo
->field_threshold
))
371 return PTR_ERR(fifo
->field_threshold
);
373 ret
= of_property_read_u32(dev
->of_node
, "amlogic,fifo-depth",
376 /* Error out for anything but a missing property */
380 * If the property is missing, it might be because of an old
381 * DT. In such case, assume the smallest known fifo depth
384 dev_warn(dev
, "fifo depth not found, assume %u bytes\n",
388 return devm_snd_soc_register_component(dev
, data
->component_drv
,
391 EXPORT_SYMBOL_GPL(axg_fifo_probe
);
393 MODULE_DESCRIPTION("Amlogic AXG/G12A fifo driver");
394 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
395 MODULE_LICENSE("GPL v2");