123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- // SPDX-License-Identifier: GPL-2.0
- //
- // Socionext UniPhier AIO ALSA driver for PXs2.
- //
- // Copyright (c) 2018 Socionext Inc.
- #include <linux/module.h>
- #include "aio.h"
- static const struct uniphier_aio_spec uniphier_aio_pxs2[] = {
- /* for Line PCM In, Pin:AI1Dx */
- {
- .name = AUD_NAME_PCMIN1,
- .gname = AUD_GNAME_LINE,
- .swm = {
- .type = PORT_TYPE_I2S,
- .dir = PORT_DIR_INPUT,
- .rb = { 16, 11, },
- .ch = { 16, 11, },
- .iif = { 0, 0, },
- .iport = { 0, AUD_HW_PCMIN1, },
- },
- },
- /* for Speaker/Headphone/Mic PCM In, Pin:AI2Dx */
- {
- .name = AUD_NAME_PCMIN2,
- .gname = AUD_GNAME_AUX,
- .swm = {
- .type = PORT_TYPE_I2S,
- .dir = PORT_DIR_INPUT,
- .rb = { 17, 12, },
- .ch = { 17, 12, },
- .iif = { 1, 1, },
- .iport = { 1, AUD_HW_PCMIN2, },
- },
- },
- /* for HDMI PCM Out, Pin:AO1Dx (inner) */
- {
- .name = AUD_NAME_HPCMOUT1,
- .gname = AUD_GNAME_HDMI,
- .swm = {
- .type = PORT_TYPE_I2S,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 0, 0, },
- .ch = { 0, 0, },
- .oif = { 0, 0, },
- .oport = { 3, AUD_HW_HPCMOUT1, },
- },
- },
- /* for Line PCM Out, Pin:AO2Dx */
- {
- .name = AUD_NAME_PCMOUT1,
- .gname = AUD_GNAME_LINE,
- .swm = {
- .type = PORT_TYPE_I2S,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 1, 1, },
- .ch = { 1, 1, },
- .oif = { 1, 1, },
- .oport = { 0, AUD_HW_PCMOUT1, },
- },
- },
- /* for Speaker/Headphone/Mic PCM Out, Pin:AO3Dx */
- {
- .name = AUD_NAME_PCMOUT2,
- .gname = AUD_GNAME_AUX,
- .swm = {
- .type = PORT_TYPE_I2S,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 2, 2, },
- .ch = { 2, 2, },
- .oif = { 2, 2, },
- .oport = { 1, AUD_HW_PCMOUT2, },
- },
- },
- /* for HDMI Out, Pin:AO1IEC */
- {
- .name = AUD_NAME_HIECOUT1,
- .swm = {
- .type = PORT_TYPE_SPDIF,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 6, 4, },
- .ch = { 6, 4, },
- .oif = { 6, 4, },
- .oport = { 12, AUD_HW_HIECOUT1, },
- },
- },
- /* for HDMI Out, Pin:AO1IEC, Compress */
- {
- .name = AUD_NAME_HIECCOMPOUT1,
- .swm = {
- .type = PORT_TYPE_SPDIF,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 6, 4, },
- .ch = { 6, 4, },
- .oif = { 6, 4, },
- .oport = { 12, AUD_HW_HIECOUT1, },
- },
- },
- /* for S/PDIF Out, Pin:AO2IEC */
- {
- .name = AUD_NAME_IECOUT1,
- .swm = {
- .type = PORT_TYPE_SPDIF,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 7, 5, },
- .ch = { 7, 5, },
- .oif = { 7, 5, },
- .oport = { 13, AUD_HW_IECOUT1, },
- },
- },
- /* for S/PDIF Out, Pin:AO2IEC */
- {
- .name = AUD_NAME_IECCOMPOUT1,
- .swm = {
- .type = PORT_TYPE_SPDIF,
- .dir = PORT_DIR_OUTPUT,
- .rb = { 7, 5, },
- .ch = { 7, 5, },
- .oif = { 7, 5, },
- .oport = { 13, AUD_HW_IECOUT1, },
- },
- },
- };
- static const struct uniphier_aio_pll uniphier_aio_pll_pxs2[] = {
- [AUD_PLL_A1] = { .enable = true, },
- [AUD_PLL_F1] = { .enable = true, },
- [AUD_PLL_A2] = { .enable = true, },
- [AUD_PLL_F2] = { .enable = true, },
- [AUD_PLL_APLL] = { .enable = true, },
- [AUD_PLL_HSC0] = { .enable = true, },
- };
- static int uniphier_aio_pxs2_probe(struct snd_soc_dai *dai)
- {
- int ret;
- ret = uniphier_aio_dai_probe(dai);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_pll(dai, AUD_PLL_A1, 0, 0, 36864000);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_pll(dai, AUD_PLL_F1, 0, 0, 36864000);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_pll(dai, AUD_PLL_A2, 0, 0, 33868800);
- if (ret < 0)
- return ret;
- ret = snd_soc_dai_set_pll(dai, AUD_PLL_F2, 0, 0, 33868800);
- if (ret < 0)
- return ret;
- return 0;
- }
- static struct snd_soc_dai_driver uniphier_aio_dai_pxs2[] = {
- {
- .name = AUD_GNAME_HDMI,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .playback = {
- .stream_name = AUD_NAME_HPCMOUT1,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &uniphier_aio_i2s_ops,
- },
- {
- .name = AUD_GNAME_LINE,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .playback = {
- .stream_name = AUD_NAME_PCMOUT1,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .stream_name = AUD_NAME_PCMIN1,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &uniphier_aio_i2s_ops,
- },
- {
- .name = AUD_GNAME_AUX,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .playback = {
- .stream_name = AUD_NAME_PCMOUT2,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .capture = {
- .stream_name = AUD_NAME_PCMIN2,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &uniphier_aio_i2s_ops,
- },
- {
- .name = AUD_NAME_HIECOUT1,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .playback = {
- .stream_name = AUD_NAME_HIECOUT1,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &uniphier_aio_spdif_ops,
- },
- {
- .name = AUD_NAME_IECOUT1,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .playback = {
- .stream_name = AUD_NAME_IECOUT1,
- .formats = SNDRV_PCM_FMTBIT_S32_LE,
- .rates = SNDRV_PCM_RATE_48000,
- .channels_min = 2,
- .channels_max = 2,
- },
- .ops = &uniphier_aio_spdif_ops,
- },
- {
- .name = AUD_NAME_HIECCOMPOUT1,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .compress_new = snd_soc_new_compress,
- .playback = {
- .stream_name = AUD_NAME_HIECCOMPOUT1,
- .channels_min = 1,
- .channels_max = 1,
- },
- .ops = &uniphier_aio_spdif_ops,
- },
- {
- .name = AUD_NAME_IECCOMPOUT1,
- .probe = uniphier_aio_pxs2_probe,
- .remove = uniphier_aio_dai_remove,
- .compress_new = snd_soc_new_compress,
- .playback = {
- .stream_name = AUD_NAME_IECCOMPOUT1,
- .channels_min = 1,
- .channels_max = 1,
- },
- .ops = &uniphier_aio_spdif_ops,
- },
- };
- static const struct uniphier_aio_chip_spec uniphier_aio_pxs2_spec = {
- .specs = uniphier_aio_pxs2,
- .num_specs = ARRAY_SIZE(uniphier_aio_pxs2),
- .dais = uniphier_aio_dai_pxs2,
- .num_dais = ARRAY_SIZE(uniphier_aio_dai_pxs2),
- .plls = uniphier_aio_pll_pxs2,
- .num_plls = ARRAY_SIZE(uniphier_aio_pll_pxs2),
- .addr_ext = 0,
- };
- static const struct of_device_id uniphier_aio_of_match[] __maybe_unused = {
- {
- .compatible = "socionext,uniphier-pxs2-aio",
- .data = &uniphier_aio_pxs2_spec,
- },
- {},
- };
- MODULE_DEVICE_TABLE(of, uniphier_aio_of_match);
- static struct platform_driver uniphier_aio_driver = {
- .driver = {
- .name = "snd-uniphier-aio-pxs2",
- .of_match_table = of_match_ptr(uniphier_aio_of_match),
- },
- .probe = uniphier_aio_probe,
- .remove = uniphier_aio_remove,
- };
- module_platform_driver(uniphier_aio_driver);
- MODULE_AUTHOR("Katsuhiro Suzuki <[email protected]>");
- MODULE_DESCRIPTION("UniPhier PXs2 AIO driver.");
- MODULE_LICENSE("GPL v2");
|