1 // SPDX-License-Identifier: GPL-2.0
3 // Socionext UniPhier AIO ALSA CPU DAI driver.
5 // Copyright (c) 2016-2018 Socionext Inc.
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/mfd/syscon.h>
11 #include <linux/module.h>
13 #include <linux/of_platform.h>
14 #include <linux/platform_device.h>
15 #include <linux/reset.h>
16 #include <sound/core.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
19 #include <sound/soc.h>
23 static bool is_valid_pll(struct uniphier_aio_chip
*chip
, int pll_id
)
25 struct device
*dev
= &chip
->pdev
->dev
;
27 if (pll_id
< 0 || chip
->num_plls
<= pll_id
) {
28 dev_err(dev
, "PLL(%d) is not supported\n", pll_id
);
32 return chip
->plls
[pll_id
].enable
;
36 * find_volume - find volume supported HW port by HW port number
37 * @chip: the AIO chip pointer
38 * @oport_hw: HW port number, one of AUD_HW_XXXX
40 * Find AIO device from device list by HW port number. Volume feature is
41 * available only in Output and PCM ports, this limitation comes from HW
44 * Return: The pointer of AIO substream if successful, otherwise NULL on error.
46 static struct uniphier_aio_sub
*find_volume(struct uniphier_aio_chip
*chip
,
51 for (i
= 0; i
< chip
->num_aios
; i
++) {
52 struct uniphier_aio_sub
*sub
= &chip
->aios
[i
].sub
[0];
57 if (sub
->swm
->oport
.hw
== oport_hw
)
64 static bool match_spec(const struct uniphier_aio_spec
*spec
,
65 const char *name
, int dir
)
67 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
&&
68 spec
->swm
.dir
!= PORT_DIR_OUTPUT
) {
72 if (dir
== SNDRV_PCM_STREAM_CAPTURE
&&
73 spec
->swm
.dir
!= PORT_DIR_INPUT
) {
77 if (spec
->name
&& strcmp(spec
->name
, name
) == 0)
80 if (spec
->gname
&& strcmp(spec
->gname
, name
) == 0)
87 * find_spec - find HW specification info by name
88 * @aio: the AIO device pointer
89 * @name: name of device
90 * @direction: the direction of substream, SNDRV_PCM_STREAM_*
92 * Find hardware specification information from list by device name. This
93 * information is used for telling the difference of SoCs to driver.
95 * Specification list is array of 'struct uniphier_aio_spec' which is defined
96 * in each drivers (see: aio-i2s.c).
98 * Return: The pointer of hardware specification of AIO if successful,
99 * otherwise NULL on error.
101 static const struct uniphier_aio_spec
*find_spec(struct uniphier_aio
*aio
,
105 const struct uniphier_aio_chip_spec
*chip_spec
= aio
->chip
->chip_spec
;
108 for (i
= 0; i
< chip_spec
->num_specs
; i
++) {
109 const struct uniphier_aio_spec
*spec
= &chip_spec
->specs
[i
];
111 if (match_spec(spec
, name
, direction
))
119 * find_divider - find clock divider by frequency
120 * @aio: the AIO device pointer
121 * @pll_id: PLL ID, should be AUD_PLL_XX
122 * @freq: required frequency
124 * Find suitable clock divider by frequency.
126 * Return: The ID of PLL if successful, otherwise negative error value.
128 static int find_divider(struct uniphier_aio
*aio
, int pll_id
, unsigned int freq
)
130 struct uniphier_aio_pll
*pll
;
131 int mul
[] = { 1, 1, 1, 2, };
132 int div
[] = { 2, 3, 1, 3, };
135 if (!is_valid_pll(aio
->chip
, pll_id
))
138 pll
= &aio
->chip
->plls
[pll_id
];
139 for (i
= 0; i
< ARRAY_SIZE(mul
); i
++)
140 if (pll
->freq
* mul
[i
] / div
[i
] == freq
)
146 static int uniphier_aio_set_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
147 unsigned int freq
, int dir
)
149 struct uniphier_aio
*aio
= uniphier_priv(dai
);
150 struct device
*dev
= &aio
->chip
->pdev
->dev
;
151 bool pll_auto
= false;
178 pll_id
= AUD_PLL_APLL
;
181 pll_id
= AUD_PLL_RX0
;
184 pll_id
= AUD_PLL_USB0
;
187 pll_id
= AUD_PLL_HSC0
;
190 dev_err(dev
, "Sysclk(%d) is not supported\n", clk_id
);
195 for (pll_id
= 0; pll_id
< aio
->chip
->num_plls
; pll_id
++) {
196 div_id
= find_divider(aio
, pll_id
, freq
);
198 aio
->plldiv
= div_id
;
202 if (pll_id
== aio
->chip
->num_plls
) {
203 dev_err(dev
, "Sysclk frequency is not supported(%d)\n",
209 if (dir
== SND_SOC_CLOCK_OUT
)
210 aio
->pll_out
= pll_id
;
212 aio
->pll_in
= pll_id
;
217 static int uniphier_aio_set_pll(struct snd_soc_dai
*dai
, int pll_id
,
218 int source
, unsigned int freq_in
,
219 unsigned int freq_out
)
221 struct uniphier_aio
*aio
= uniphier_priv(dai
);
224 if (!is_valid_pll(aio
->chip
, pll_id
))
227 ret
= aio_chip_set_pll(aio
->chip
, pll_id
, freq_out
);
234 static int uniphier_aio_set_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
236 struct uniphier_aio
*aio
= uniphier_priv(dai
);
237 struct device
*dev
= &aio
->chip
->pdev
->dev
;
239 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
240 case SND_SOC_DAIFMT_LEFT_J
:
241 case SND_SOC_DAIFMT_RIGHT_J
:
242 case SND_SOC_DAIFMT_I2S
:
243 aio
->fmt
= fmt
& SND_SOC_DAIFMT_FORMAT_MASK
;
246 dev_err(dev
, "Format is not supported(%d)\n",
247 fmt
& SND_SOC_DAIFMT_FORMAT_MASK
);
254 static int uniphier_aio_startup(struct snd_pcm_substream
*substream
,
255 struct snd_soc_dai
*dai
)
257 struct uniphier_aio
*aio
= uniphier_priv(dai
);
258 struct uniphier_aio_sub
*sub
= &aio
->sub
[substream
->stream
];
261 sub
->substream
= substream
;
262 sub
->pass_through
= 0;
263 sub
->use_mmap
= true;
272 static void uniphier_aio_shutdown(struct snd_pcm_substream
*substream
,
273 struct snd_soc_dai
*dai
)
275 struct uniphier_aio
*aio
= uniphier_priv(dai
);
276 struct uniphier_aio_sub
*sub
= &aio
->sub
[substream
->stream
];
278 sub
->substream
= NULL
;
281 static int uniphier_aio_hw_params(struct snd_pcm_substream
*substream
,
282 struct snd_pcm_hw_params
*params
,
283 struct snd_soc_dai
*dai
)
285 struct uniphier_aio
*aio
= uniphier_priv(dai
);
286 struct uniphier_aio_sub
*sub
= &aio
->sub
[substream
->stream
];
287 struct device
*dev
= &aio
->chip
->pdev
->dev
;
290 switch (params_rate(params
)) {
301 dev_err(dev
, "Rate is not supported(%d)\n",
302 params_rate(params
));
305 ret
= snd_soc_dai_set_sysclk(dai
, AUD_CLK_A
,
306 freq
, SND_SOC_CLOCK_OUT
);
310 sub
->params
= *params
;
314 aio_port_set_volume(sub
, sub
->vol
);
320 static int uniphier_aio_hw_free(struct snd_pcm_substream
*substream
,
321 struct snd_soc_dai
*dai
)
323 struct uniphier_aio
*aio
= uniphier_priv(dai
);
324 struct uniphier_aio_sub
*sub
= &aio
->sub
[substream
->stream
];
331 static int uniphier_aio_prepare(struct snd_pcm_substream
*substream
,
332 struct snd_soc_dai
*dai
)
334 struct uniphier_aio
*aio
= uniphier_priv(dai
);
335 struct uniphier_aio_sub
*sub
= &aio
->sub
[substream
->stream
];
338 ret
= aio_port_set_param(sub
, sub
->pass_through
, &sub
->params
);
341 ret
= aio_src_set_param(sub
, &sub
->params
);
344 aio_port_set_enable(sub
, 1);
346 ret
= aio_if_set_param(sub
, sub
->pass_through
);
350 if (sub
->swm
->type
== PORT_TYPE_CONV
) {
351 ret
= aio_srcif_set_param(sub
);
354 ret
= aio_srcch_set_param(sub
);
357 aio_srcch_set_enable(sub
, 1);
363 const struct snd_soc_dai_ops uniphier_aio_i2s_ops
= {
364 .set_sysclk
= uniphier_aio_set_sysclk
,
365 .set_pll
= uniphier_aio_set_pll
,
366 .set_fmt
= uniphier_aio_set_fmt
,
367 .startup
= uniphier_aio_startup
,
368 .shutdown
= uniphier_aio_shutdown
,
369 .hw_params
= uniphier_aio_hw_params
,
370 .hw_free
= uniphier_aio_hw_free
,
371 .prepare
= uniphier_aio_prepare
,
373 EXPORT_SYMBOL_GPL(uniphier_aio_i2s_ops
);
375 const struct snd_soc_dai_ops uniphier_aio_spdif_ops
= {
376 .set_sysclk
= uniphier_aio_set_sysclk
,
377 .set_pll
= uniphier_aio_set_pll
,
378 .startup
= uniphier_aio_startup
,
379 .shutdown
= uniphier_aio_shutdown
,
380 .hw_params
= uniphier_aio_hw_params
,
381 .hw_free
= uniphier_aio_hw_free
,
382 .prepare
= uniphier_aio_prepare
,
384 EXPORT_SYMBOL_GPL(uniphier_aio_spdif_ops
);
386 int uniphier_aio_dai_probe(struct snd_soc_dai
*dai
)
388 struct uniphier_aio
*aio
= uniphier_priv(dai
);
391 for (i
= 0; i
< ARRAY_SIZE(aio
->sub
); i
++) {
392 struct uniphier_aio_sub
*sub
= &aio
->sub
[i
];
393 const struct uniphier_aio_spec
*spec
;
395 spec
= find_spec(aio
, dai
->name
, i
);
399 sub
->swm
= &spec
->swm
;
402 sub
->vol
= AUD_VOL_INIT
;
405 aio_iecout_set_enable(aio
->chip
, true);
406 aio_chip_init(aio
->chip
);
407 aio
->chip
->active
= 1;
411 EXPORT_SYMBOL_GPL(uniphier_aio_dai_probe
);
413 int uniphier_aio_dai_remove(struct snd_soc_dai
*dai
)
415 struct uniphier_aio
*aio
= uniphier_priv(dai
);
417 aio
->chip
->active
= 0;
421 EXPORT_SYMBOL_GPL(uniphier_aio_dai_remove
);
423 static void uniphier_aio_dai_suspend(struct snd_soc_dai
*dai
)
425 struct uniphier_aio
*aio
= uniphier_priv(dai
);
430 aio
->chip
->num_wup_aios
--;
431 if (!aio
->chip
->num_wup_aios
) {
432 reset_control_assert(aio
->chip
->rst
);
433 clk_disable_unprepare(aio
->chip
->clk
);
437 static int uniphier_aio_suspend(struct snd_soc_component
*component
)
439 struct snd_soc_dai
*dai
;
441 for_each_component_dais(component
, dai
)
442 uniphier_aio_dai_suspend(dai
);
446 static int uniphier_aio_dai_resume(struct snd_soc_dai
*dai
)
448 struct uniphier_aio
*aio
= uniphier_priv(dai
);
454 if (!aio
->chip
->active
)
457 if (!aio
->chip
->num_wup_aios
) {
458 ret
= clk_prepare_enable(aio
->chip
->clk
);
462 ret
= reset_control_deassert(aio
->chip
->rst
);
467 aio_iecout_set_enable(aio
->chip
, true);
468 aio_chip_init(aio
->chip
);
470 for (i
= 0; i
< ARRAY_SIZE(aio
->sub
); i
++) {
471 struct uniphier_aio_sub
*sub
= &aio
->sub
[i
];
473 if (!sub
->spec
|| !sub
->substream
)
486 aio
->chip
->num_wup_aios
++;
491 if (!aio
->chip
->num_wup_aios
)
492 reset_control_assert(aio
->chip
->rst
);
494 if (!aio
->chip
->num_wup_aios
)
495 clk_disable_unprepare(aio
->chip
->clk
);
500 static int uniphier_aio_resume(struct snd_soc_component
*component
)
502 struct snd_soc_dai
*dai
;
505 for_each_component_dais(component
, dai
)
506 ret
|= uniphier_aio_dai_resume(dai
);
510 static int uniphier_aio_vol_info(struct snd_kcontrol
*kcontrol
,
511 struct snd_ctl_elem_info
*uinfo
)
513 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
515 uinfo
->value
.integer
.min
= 0;
516 uinfo
->value
.integer
.max
= AUD_VOL_MAX
;
521 static int uniphier_aio_vol_get(struct snd_kcontrol
*kcontrol
,
522 struct snd_ctl_elem_value
*ucontrol
)
524 struct snd_soc_component
*comp
= snd_soc_kcontrol_component(kcontrol
);
525 struct uniphier_aio_chip
*chip
= snd_soc_component_get_drvdata(comp
);
526 struct uniphier_aio_sub
*sub
;
527 int oport_hw
= kcontrol
->private_value
;
529 sub
= find_volume(chip
, oport_hw
);
533 ucontrol
->value
.integer
.value
[0] = sub
->vol
;
538 static int uniphier_aio_vol_put(struct snd_kcontrol
*kcontrol
,
539 struct snd_ctl_elem_value
*ucontrol
)
541 struct snd_soc_component
*comp
= snd_soc_kcontrol_component(kcontrol
);
542 struct uniphier_aio_chip
*chip
= snd_soc_component_get_drvdata(comp
);
543 struct uniphier_aio_sub
*sub
;
544 int oport_hw
= kcontrol
->private_value
;
546 sub
= find_volume(chip
, oport_hw
);
550 if (sub
->vol
== ucontrol
->value
.integer
.value
[0])
552 sub
->vol
= ucontrol
->value
.integer
.value
[0];
554 aio_port_set_volume(sub
, sub
->vol
);
559 static const struct snd_kcontrol_new uniphier_aio_controls
[] = {
561 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
562 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
563 .name
= "HPCMOUT1 Volume",
564 .info
= uniphier_aio_vol_info
,
565 .get
= uniphier_aio_vol_get
,
566 .put
= uniphier_aio_vol_put
,
567 .private_value
= AUD_HW_HPCMOUT1
,
570 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
571 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
572 .name
= "PCMOUT1 Volume",
573 .info
= uniphier_aio_vol_info
,
574 .get
= uniphier_aio_vol_get
,
575 .put
= uniphier_aio_vol_put
,
576 .private_value
= AUD_HW_PCMOUT1
,
579 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
580 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
581 .name
= "PCMOUT2 Volume",
582 .info
= uniphier_aio_vol_info
,
583 .get
= uniphier_aio_vol_get
,
584 .put
= uniphier_aio_vol_put
,
585 .private_value
= AUD_HW_PCMOUT2
,
588 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
589 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
590 .name
= "PCMOUT3 Volume",
591 .info
= uniphier_aio_vol_info
,
592 .get
= uniphier_aio_vol_get
,
593 .put
= uniphier_aio_vol_put
,
594 .private_value
= AUD_HW_PCMOUT3
,
597 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
598 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
599 .name
= "HIECOUT1 Volume",
600 .info
= uniphier_aio_vol_info
,
601 .get
= uniphier_aio_vol_get
,
602 .put
= uniphier_aio_vol_put
,
603 .private_value
= AUD_HW_HIECOUT1
,
606 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
607 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
608 .name
= "IECOUT1 Volume",
609 .info
= uniphier_aio_vol_info
,
610 .get
= uniphier_aio_vol_get
,
611 .put
= uniphier_aio_vol_put
,
612 .private_value
= AUD_HW_IECOUT1
,
616 static const struct snd_soc_component_driver uniphier_aio_component
= {
617 .name
= "uniphier-aio",
618 .controls
= uniphier_aio_controls
,
619 .num_controls
= ARRAY_SIZE(uniphier_aio_controls
),
620 .suspend
= uniphier_aio_suspend
,
621 .resume
= uniphier_aio_resume
,
624 int uniphier_aio_probe(struct platform_device
*pdev
)
626 struct uniphier_aio_chip
*chip
;
627 struct device
*dev
= &pdev
->dev
;
630 chip
= devm_kzalloc(dev
, sizeof(*chip
), GFP_KERNEL
);
634 chip
->chip_spec
= of_device_get_match_data(dev
);
635 if (!chip
->chip_spec
)
638 chip
->regmap_sg
= syscon_regmap_lookup_by_phandle(dev
->of_node
,
640 if (IS_ERR(chip
->regmap_sg
)) {
641 if (PTR_ERR(chip
->regmap_sg
) == -EPROBE_DEFER
)
642 return -EPROBE_DEFER
;
643 chip
->regmap_sg
= NULL
;
646 chip
->clk
= devm_clk_get(dev
, "aio");
647 if (IS_ERR(chip
->clk
))
648 return PTR_ERR(chip
->clk
);
650 chip
->rst
= devm_reset_control_get_shared(dev
, "aio");
651 if (IS_ERR(chip
->rst
))
652 return PTR_ERR(chip
->rst
);
654 chip
->num_aios
= chip
->chip_spec
->num_dais
;
655 chip
->num_wup_aios
= chip
->num_aios
;
656 chip
->aios
= devm_kcalloc(dev
,
657 chip
->num_aios
, sizeof(struct uniphier_aio
),
662 chip
->num_plls
= chip
->chip_spec
->num_plls
;
663 chip
->plls
= devm_kcalloc(dev
,
665 sizeof(struct uniphier_aio_pll
),
669 memcpy(chip
->plls
, chip
->chip_spec
->plls
,
670 sizeof(struct uniphier_aio_pll
) * chip
->num_plls
);
672 for (i
= 0; i
< chip
->num_aios
; i
++) {
673 struct uniphier_aio
*aio
= &chip
->aios
[i
];
676 aio
->fmt
= SND_SOC_DAIFMT_I2S
;
678 for (j
= 0; j
< ARRAY_SIZE(aio
->sub
); j
++) {
679 struct uniphier_aio_sub
*sub
= &aio
->sub
[j
];
682 spin_lock_init(&sub
->lock
);
687 platform_set_drvdata(pdev
, chip
);
689 ret
= clk_prepare_enable(chip
->clk
);
693 ret
= reset_control_deassert(chip
->rst
);
697 ret
= devm_snd_soc_register_component(dev
, &uniphier_aio_component
,
698 chip
->chip_spec
->dais
,
699 chip
->chip_spec
->num_dais
);
701 dev_err(dev
, "Register component failed.\n");
705 ret
= uniphier_aiodma_soc_register_platform(pdev
);
707 dev_err(dev
, "Register platform failed.\n");
714 reset_control_assert(chip
->rst
);
717 clk_disable_unprepare(chip
->clk
);
721 EXPORT_SYMBOL_GPL(uniphier_aio_probe
);
723 int uniphier_aio_remove(struct platform_device
*pdev
)
725 struct uniphier_aio_chip
*chip
= platform_get_drvdata(pdev
);
727 reset_control_assert(chip
->rst
);
728 clk_disable_unprepare(chip
->clk
);
732 EXPORT_SYMBOL_GPL(uniphier_aio_remove
);
734 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
735 MODULE_DESCRIPTION("UniPhier AIO CPU DAI driver.");
736 MODULE_LICENSE("GPL v2");