1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
3 // Copyright (c) 2018 BayLibre, SAS.
4 // Author: Jerome Brunet <jbrunet@baylibre.com>
6 #include <linux/bitfield.h>
8 #include <linux/of_irq.h>
9 #include <linux/of_platform.h>
10 #include <linux/module.h>
11 #include <linux/regmap.h>
12 #include <linux/reset.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/soc-dai.h>
20 * This file implements the platform operations common to the playback and
21 * capture frontend DAI. The logic behind this two types of fifo is very
22 * similar but some difference exist.
23 * These differences are handled in the respective DAI drivers
26 static const struct snd_pcm_hardware axg_fifo_hw
= {
27 .info
= (SNDRV_PCM_INFO_INTERLEAVED
|
29 SNDRV_PCM_INFO_MMAP_VALID
|
30 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
31 SNDRV_PCM_INFO_PAUSE
|
32 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP
),
33 .formats
= AXG_FIFO_FORMATS
,
37 .channels_max
= AXG_FIFO_CH_MAX
,
38 .period_bytes_min
= AXG_FIFO_BURST
,
39 .period_bytes_max
= UINT_MAX
,
41 .periods_max
= UINT_MAX
,
43 /* No real justification for this */
44 .buffer_bytes_max
= 1 * 1024 * 1024,
47 static struct snd_soc_dai
*axg_fifo_dai(struct snd_pcm_substream
*ss
)
49 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(ss
);
51 return snd_soc_rtd_to_cpu(rtd
, 0);
54 static struct axg_fifo
*axg_fifo_data(struct snd_pcm_substream
*ss
)
56 struct snd_soc_dai
*dai
= axg_fifo_dai(ss
);
58 return snd_soc_dai_get_drvdata(dai
);
61 static struct device
*axg_fifo_dev(struct snd_pcm_substream
*ss
)
63 struct snd_soc_dai
*dai
= axg_fifo_dai(ss
);
68 static void __dma_enable(struct axg_fifo
*fifo
, bool enable
)
70 regmap_update_bits(fifo
->map
, FIFO_CTRL0
, CTRL0_DMA_EN
,
71 enable
? CTRL0_DMA_EN
: 0);
74 int axg_fifo_pcm_trigger(struct snd_soc_component
*component
,
75 struct snd_pcm_substream
*ss
, int cmd
)
77 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
80 case SNDRV_PCM_TRIGGER_START
:
81 case SNDRV_PCM_TRIGGER_RESUME
:
82 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
83 __dma_enable(fifo
, true);
85 case SNDRV_PCM_TRIGGER_SUSPEND
:
86 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
87 case SNDRV_PCM_TRIGGER_STOP
:
88 __dma_enable(fifo
, false);
96 EXPORT_SYMBOL_GPL(axg_fifo_pcm_trigger
);
98 snd_pcm_uframes_t
axg_fifo_pcm_pointer(struct snd_soc_component
*component
,
99 struct snd_pcm_substream
*ss
)
101 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
102 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
105 regmap_read(fifo
->map
, FIFO_STATUS2
, &addr
);
107 return bytes_to_frames(runtime
, addr
- (unsigned int)runtime
->dma_addr
);
109 EXPORT_SYMBOL_GPL(axg_fifo_pcm_pointer
);
111 int axg_fifo_pcm_hw_params(struct snd_soc_component
*component
,
112 struct snd_pcm_substream
*ss
,
113 struct snd_pcm_hw_params
*params
)
115 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
116 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
117 unsigned int burst_num
, period
, threshold
, irq_en
;
120 period
= params_period_bytes(params
);
122 /* Setup dma memory pointers */
123 end_ptr
= runtime
->dma_addr
+ runtime
->dma_bytes
- AXG_FIFO_BURST
;
124 regmap_write(fifo
->map
, FIFO_START_ADDR
, runtime
->dma_addr
);
125 regmap_write(fifo
->map
, FIFO_FINISH_ADDR
, end_ptr
);
127 /* Setup interrupt periodicity */
128 burst_num
= period
/ AXG_FIFO_BURST
;
129 regmap_write(fifo
->map
, FIFO_INT_ADDR
, burst_num
);
132 * Start the fifo request on the smallest of the following:
133 * - Half the fifo size
134 * - Half the period size
136 threshold
= min(period
/ 2, fifo
->depth
/ 2);
139 * With the threshold in bytes, register value is:
140 * V = (threshold / burst) - 1
142 threshold
/= AXG_FIFO_BURST
;
143 regmap_field_write(fifo
->field_threshold
,
144 threshold
? threshold
- 1 : 0);
146 /* Enable irq if necessary */
147 irq_en
= runtime
->no_period_wakeup
? 0 : FIFO_INT_COUNT_REPEAT
;
148 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
150 FIELD_PREP(CTRL0_INT_EN
, irq_en
));
154 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_params
);
156 int g12a_fifo_pcm_hw_params(struct snd_soc_component
*component
,
157 struct snd_pcm_substream
*ss
,
158 struct snd_pcm_hw_params
*params
)
160 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
161 struct snd_pcm_runtime
*runtime
= ss
->runtime
;
164 ret
= axg_fifo_pcm_hw_params(component
, ss
, params
);
168 /* Set the initial memory address of the DMA */
169 regmap_write(fifo
->map
, FIFO_INIT_ADDR
, runtime
->dma_addr
);
173 EXPORT_SYMBOL_GPL(g12a_fifo_pcm_hw_params
);
175 int axg_fifo_pcm_hw_free(struct snd_soc_component
*component
,
176 struct snd_pcm_substream
*ss
)
178 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
181 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
186 EXPORT_SYMBOL_GPL(axg_fifo_pcm_hw_free
);
188 static void axg_fifo_ack_irq(struct axg_fifo
*fifo
, u8 mask
)
190 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
192 FIELD_PREP(CTRL1_INT_CLR
, mask
));
194 /* Clear must also be cleared */
195 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
197 FIELD_PREP(CTRL1_INT_CLR
, 0));
200 static irqreturn_t
axg_fifo_pcm_irq_block(int irq
, void *dev_id
)
202 struct snd_pcm_substream
*ss
= dev_id
;
203 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
206 regmap_read(fifo
->map
, FIFO_STATUS1
, &status
);
207 status
= FIELD_GET(STATUS1_INT_STS
, status
);
208 axg_fifo_ack_irq(fifo
, status
);
210 if (status
& ~FIFO_INT_COUNT_REPEAT
)
211 dev_dbg(axg_fifo_dev(ss
), "unexpected irq - STS 0x%02x\n",
214 if (status
& FIFO_INT_COUNT_REPEAT
) {
215 snd_pcm_period_elapsed(ss
);
222 int axg_fifo_pcm_open(struct snd_soc_component
*component
,
223 struct snd_pcm_substream
*ss
)
225 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
226 struct device
*dev
= axg_fifo_dev(ss
);
229 snd_soc_set_runtime_hwparams(ss
, &axg_fifo_hw
);
232 * Make sure the buffer and period size are multiple of the FIFO
235 ret
= snd_pcm_hw_constraint_step(ss
->runtime
, 0,
236 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
,
241 ret
= snd_pcm_hw_constraint_step(ss
->runtime
, 0,
242 SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
247 /* Use the threaded irq handler only with non-atomic links */
248 ret
= request_threaded_irq(fifo
->irq
, NULL
,
249 axg_fifo_pcm_irq_block
,
250 IRQF_ONESHOT
, dev_name(dev
), ss
);
254 /* Enable pclk to access registers and clock the fifo ip */
255 ret
= clk_prepare_enable(fifo
->pclk
);
259 /* Setup status2 so it reports the memory pointer */
260 regmap_update_bits(fifo
->map
, FIFO_CTRL1
,
262 FIELD_PREP(CTRL1_STATUS2_SEL
, STATUS2_SEL_DDR_READ
));
264 /* Make sure the dma is initially disabled */
265 __dma_enable(fifo
, false);
267 /* Disable irqs until params are ready */
268 regmap_update_bits(fifo
->map
, FIFO_CTRL0
,
271 /* Clear any pending interrupt */
272 axg_fifo_ack_irq(fifo
, FIFO_INT_MASK
);
274 /* Take memory arbitror out of reset */
275 ret
= reset_control_deassert(fifo
->arb
);
282 clk_disable_unprepare(fifo
->pclk
);
284 free_irq(fifo
->irq
, ss
);
287 EXPORT_SYMBOL_GPL(axg_fifo_pcm_open
);
289 int axg_fifo_pcm_close(struct snd_soc_component
*component
,
290 struct snd_pcm_substream
*ss
)
292 struct axg_fifo
*fifo
= axg_fifo_data(ss
);
295 /* Put the memory arbitror back in reset */
296 ret
= reset_control_assert(fifo
->arb
);
298 /* Disable fifo ip and register access */
299 clk_disable_unprepare(fifo
->pclk
);
302 free_irq(fifo
->irq
, ss
);
306 EXPORT_SYMBOL_GPL(axg_fifo_pcm_close
);
308 int axg_fifo_pcm_new(struct snd_soc_pcm_runtime
*rtd
, unsigned int type
)
310 struct snd_card
*card
= rtd
->card
->snd_card
;
311 size_t size
= axg_fifo_hw
.buffer_bytes_max
;
313 snd_pcm_set_managed_buffer(rtd
->pcm
->streams
[type
].substream
,
314 SNDRV_DMA_TYPE_DEV
, card
->dev
,
318 EXPORT_SYMBOL_GPL(axg_fifo_pcm_new
);
320 static const struct regmap_config axg_fifo_regmap_cfg
= {
324 .max_register
= FIFO_CTRL2
,
327 int axg_fifo_probe(struct platform_device
*pdev
)
329 struct device
*dev
= &pdev
->dev
;
330 const struct axg_fifo_match_data
*data
;
331 struct axg_fifo
*fifo
;
335 data
= of_device_get_match_data(dev
);
337 dev_err(dev
, "failed to match device\n");
341 fifo
= devm_kzalloc(dev
, sizeof(*fifo
), GFP_KERNEL
);
344 platform_set_drvdata(pdev
, fifo
);
346 regs
= devm_platform_ioremap_resource(pdev
, 0);
348 return PTR_ERR(regs
);
350 fifo
->map
= devm_regmap_init_mmio(dev
, regs
, &axg_fifo_regmap_cfg
);
351 if (IS_ERR(fifo
->map
)) {
352 dev_err(dev
, "failed to init regmap: %ld\n",
354 return PTR_ERR(fifo
->map
);
357 fifo
->pclk
= devm_clk_get(dev
, NULL
);
358 if (IS_ERR(fifo
->pclk
))
359 return dev_err_probe(dev
, PTR_ERR(fifo
->pclk
), "failed to get pclk\n");
361 fifo
->arb
= devm_reset_control_get_exclusive(dev
, NULL
);
362 if (IS_ERR(fifo
->arb
))
363 return dev_err_probe(dev
, PTR_ERR(fifo
->arb
), "failed to get arb reset\n");
365 fifo
->irq
= of_irq_get(dev
->of_node
, 0);
366 if (fifo
->irq
<= 0) {
367 dev_err(dev
, "failed to get irq: %d\n", fifo
->irq
);
371 fifo
->field_threshold
=
372 devm_regmap_field_alloc(dev
, fifo
->map
, data
->field_threshold
);
373 if (IS_ERR(fifo
->field_threshold
))
374 return PTR_ERR(fifo
->field_threshold
);
376 ret
= of_property_read_u32(dev
->of_node
, "amlogic,fifo-depth",
379 /* Error out for anything but a missing property */
383 * If the property is missing, it might be because of an old
384 * DT. In such case, assume the smallest known fifo depth
387 dev_warn(dev
, "fifo depth not found, assume %u bytes\n",
391 return devm_snd_soc_register_component(dev
, data
->component_drv
,
394 EXPORT_SYMBOL_GPL(axg_fifo_probe
);
396 MODULE_DESCRIPTION("Amlogic AXG/G12A fifo driver");
397 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
398 MODULE_LICENSE("GPL v2");