Lines Matching +full:sun8i +full:- +full:h3 +full:- +full:codec +full:- +full:analog
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
7 * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
33 /* Codec DAC digital controls and FIFO registers */
51 /* Codec DAC side analog signal controls */
77 /* Codec ADC digital controls and FIFO registers */
90 /* Codec ADC side analog signal controls */
124 * have been moved around to accommodate extra analog controls.
127 /* Codec DAC digital controls and FIFO registers */
206 /* Analog performance tuning controls */
226 /* TX FIFO moved on H3 */
268 /* TODO H3 DAP (Digital Audio Processing) bits */
276 /* Codec DAC digital controls and FIFO registers */
309 /* Analog Input Mixer controls */
349 regmap_field_set_bits(scodec->reg_dac_fifoc,
353 regmap_field_set_bits(scodec->reg_dac_fifoc,
360 regmap_field_clear_bits(scodec->reg_dac_fifoc,
367 regmap_field_set_bits(scodec->reg_adc_fifoc,
374 regmap_field_clear_bits(scodec->reg_adc_fifoc,
382 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
388 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
397 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
404 return -EINVAL;
414 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
418 regmap_field_set_bits(scodec->reg_adc_fifoc,
423 regmap_field_update_bits(scodec->reg_adc_fifoc,
432 if (of_device_is_compatible(scodec->dev->of_node,
433 "allwinner,sun4i-a10-codec") ||
434 of_device_is_compatible(scodec->dev->of_node,
435 "allwinner,sun7i-a20-codec")) {
436 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
441 if (of_device_is_compatible(scodec->dev->of_node,
442 "allwinner,sun7i-a20-codec"))
444 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
455 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
459 regmap_field_set_bits(scodec->reg_dac_fifoc,
463 regmap_field_update_bits(scodec->reg_dac_fifoc,
467 if (substream->runtime->rate > 32000)
474 regmap_field_update_bits(scodec->reg_dac_fifoc,
479 regmap_field_clear_bits(scodec->reg_dac_fifoc,
488 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
562 return -EINVAL;
571 regmap_field_update_bits(scodec->reg_adc_fifoc,
577 regmap_field_set_bits(scodec->reg_adc_fifoc,
580 regmap_field_clear_bits(scodec->reg_adc_fifoc,
584 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
585 regmap_field_set_bits(scodec->reg_adc_fifoc,
588 regmap_field_clear_bits(scodec->reg_adc_fifoc,
591 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
593 regmap_field_clear_bits(scodec->reg_adc_fifoc,
597 regmap_field_set_bits(scodec->reg_adc_fifoc,
600 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
613 regmap_field_update_bits(scodec->reg_dac_fifoc,
623 regmap_field_update_bits(scodec->reg_dac_fifoc,
628 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
629 regmap_field_set_bits(scodec->reg_dac_fifoc,
633 regmap_field_clear_bits(scodec->reg_dac_fifoc,
636 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
638 regmap_field_clear_bits(scodec->reg_dac_fifoc,
642 regmap_field_set_bits(scodec->reg_dac_fifoc,
645 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
656 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
662 return -EINVAL;
664 ret = clk_set_rate(scodec->clk_module, clk_freq);
672 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
684 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
690 regmap_field_set_bits(scodec->reg_dac_fifoc,
693 return clk_prepare_enable(scodec->clk_module);
700 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
702 clk_disable_unprepare(scodec->clk_module);
721 .name = "Codec",
724 .stream_name = "Codec Playback",
735 .stream_name = "Codec Capture",
747 /*** sun4i Codec ***/
752 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
753 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale, -150, 150,
755 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale, -1200, 300,
757 static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150,
759 static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150,
858 /* Analog parts of the ADCs */
859 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
861 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
864 /* Analog parts of the DACs */
865 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
867 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
886 /* Mic Pre-Amplifiers */
887 SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
889 SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
926 { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
927 { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
934 { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
935 { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
949 { "Left ADC", NULL, "MIC1 Pre-Amplifier" },
950 { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
951 { "MIC1 Pre-Amplifier", NULL, "Mic1"},
955 { "Left ADC", NULL, "MIC2 Pre-Amplifier" },
956 { "Right ADC", NULL, "MIC2 Pre-Amplifier" },
957 { "MIC2 Pre-Amplifier", NULL, "Mic2"},
985 /*** sun6i Codec ***/
1083 static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
1084 static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
1086 -450, 150, 0);
1089 2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
1116 /* Mixer pre-gains */
1168 /* Analog parts of the ADCs */
1169 SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1171 SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1185 /* Analog parts of the DACs */
1186 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1189 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1292 /* sun8i A23 codec */
1319 /*suniv F1C100s codec */
1379 static const DECLARE_TLV_DB_SCALE(suniv_codec_dvol_scale, -7308, 116, 0);
1380 static const DECLARE_TLV_DB_SCALE(suniv_codec_hp_vol_scale, -6300, 100, 1);
1382 -450, 150, 0);
1443 /* Analog parts of the ADCs */
1444 SND_SOC_DAPM_ADC("ADC", "Codec Capture", SUNIV_CODEC_ADC_ACTL,
1457 /* Analog parts of the DACs */
1458 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1461 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1542 .name = "sun4i-codec",
1557 snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
1558 &scodec->capture_dma_data);
1568 .name = "sun4i-codec-cpu-dai",
1595 .name = "hp-det",
1602 struct snd_soc_card *card = rtd->card;
1606 if (scodec->gpio_hp) {
1613 dev_err(rtd->dev,
1618 sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
1623 dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
1641 link->cpus = &dlc[0];
1642 link->codecs = &dlc[1];
1643 link->platforms = &dlc[2];
1645 link->num_cpus = 1;
1646 link->num_codecs = 1;
1647 link->num_platforms = 1;
1649 link->name = "cdc";
1650 link->stream_name = "CDC PCM";
1651 link->codecs->dai_name = "Codec";
1652 link->cpus->dai_name = dev_name(dev);
1653 link->codecs->name = dev_name(dev);
1654 link->platforms->name = dev_name(dev);
1655 link->dai_fmt = SND_SOC_DAIFMT_I2S;
1656 link->init = sun4i_codec_machine_init;
1666 struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
1668 gpiod_set_value_cansleep(scodec->gpio_pa,
1698 return ERR_PTR(-ENOMEM);
1700 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1701 if (!card->dai_link)
1702 return ERR_PTR(-ENOMEM);
1704 card->dev = dev;
1705 card->owner = THIS_MODULE;
1706 card->name = "sun4i-codec";
1707 card->dapm_widgets = sun4i_codec_card_dapm_widgets;
1708 card->num_dapm_widgets = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
1709 card->dapm_routes = sun4i_codec_card_dapm_routes;
1710 card->num_dapm_routes = ARRAY_SIZE(sun4i_codec_card_dapm_routes);
1731 return ERR_PTR(-ENOMEM);
1733 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1734 if (!card->dai_link)
1735 return ERR_PTR(-ENOMEM);
1737 card->dev = dev;
1738 card->owner = THIS_MODULE;
1739 card->name = "A31 Audio Codec";
1740 card->dapm_widgets = sun6i_codec_card_dapm_widgets;
1741 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1742 card->fully_routed = true;
1744 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1746 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1751 /* Connect digital side enables to analog side widgets */
1756 { "Codec Capture", NULL, "Left ADC" },
1757 { "Codec Capture", NULL, "Right ADC" },
1762 { "Left DAC", NULL, "Codec Playback" },
1763 { "Right DAC", NULL, "Codec Playback" },
1777 return ERR_PTR(-ENOMEM);
1779 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1780 "allwinner,codec-analog-controls",
1783 dev_err(dev, "Can't find analog controls for codec.\n");
1784 return ERR_PTR(-EINVAL);
1787 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1788 if (!card->dai_link)
1789 return ERR_PTR(-ENOMEM);
1791 card->dev = dev;
1792 card->owner = THIS_MODULE;
1793 card->name = "A23 Audio Codec";
1794 card->dapm_widgets = sun6i_codec_card_dapm_widgets;
1795 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1796 card->dapm_routes = sun8i_codec_card_routes;
1797 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
1798 card->aux_dev = &aux_dev;
1799 card->num_aux_devs = 1;
1800 card->fully_routed = true;
1802 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1804 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1816 return ERR_PTR(-ENOMEM);
1818 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1819 "allwinner,codec-analog-controls",
1822 dev_err(dev, "Can't find analog controls for codec.\n");
1823 return ERR_PTR(-EINVAL);
1826 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1827 if (!card->dai_link)
1828 return ERR_PTR(-ENOMEM);
1830 card->dev = dev;
1831 card->owner = THIS_MODULE;
1832 card->name = "H3 Audio Codec";
1833 card->dapm_widgets = sun6i_codec_card_dapm_widgets;
1834 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1835 card->dapm_routes = sun8i_codec_card_routes;
1836 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
1837 card->aux_dev = &aux_dev;
1838 card->num_aux_devs = 1;
1839 card->fully_routed = true;
1841 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1843 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1855 return ERR_PTR(-ENOMEM);
1857 aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1858 "allwinner,codec-analog-controls",
1861 dev_err(dev, "Can't find analog controls for codec.\n");
1862 return ERR_PTR(-EINVAL);
1865 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1866 if (!card->dai_link)
1867 return ERR_PTR(-ENOMEM);
1869 card->dev = dev;
1870 card->owner = THIS_MODULE;
1871 card->name = "V3s Audio Codec";
1872 card->dapm_widgets = sun6i_codec_card_dapm_widgets;
1873 card->num_dapm_widgets = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1874 card->dapm_routes = sun8i_codec_card_routes;
1875 card->num_dapm_routes = ARRAY_SIZE(sun8i_codec_card_routes);
1876 card->aux_dev = &aux_dev;
1877 card->num_aux_devs = 1;
1878 card->fully_routed = true;
1880 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1882 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1929 /* Analog parts of the DACs */
1930 SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1933 SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1974 /* Connect digital side enables to analog side widgets */
2004 return ERR_PTR(-ENOMEM);
2006 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
2007 if (!card->dai_link)
2008 return ERR_PTR(-ENOMEM);
2010 card->dai_link->playback_only = true;
2011 card->dai_link->capture_only = false;
2013 card->dev = dev;
2014 card->owner = THIS_MODULE;
2015 card->name = "H616 Audio Codec";
2016 card->long_name = "h616-audio-codec";
2017 card->driver_name = "sun4i-codec";
2018 card->controls = sun50i_h616_card_controls;
2019 card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls);
2020 card->dapm_widgets = sun50i_h616_codec_card_dapm_widgets;
2021 card->num_dapm_widgets = ARRAY_SIZE(sun50i_h616_codec_card_dapm_widgets);
2022 card->dapm_routes = sun50i_h616_codec_card_routes;
2023 card->num_dapm_routes = ARRAY_SIZE(sun50i_h616_codec_card_routes);
2024 card->fully_routed = true;
2026 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
2028 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
2042 /* Connect digital side enables to analog side widgets */
2046 { "Codec Capture", NULL, "ADC" },
2051 { "Left DAC", NULL, "Codec Playback" },
2052 { "Right DAC", NULL, "Codec Playback" },
2062 return ERR_PTR(-ENOMEM);
2064 card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
2065 if (!card->dai_link)
2066 return ERR_PTR(-ENOMEM);
2068 card->dev = dev;
2069 card->name = "F1C100s Audio Codec";
2070 card->dapm_widgets = suniv_codec_card_dapm_widgets;
2071 card->num_dapm_widgets = ARRAY_SIZE(suniv_codec_card_dapm_widgets);
2072 card->dapm_routes = suniv_codec_card_routes;
2073 card->num_dapm_routes = ARRAY_SIZE(suniv_codec_card_routes);
2074 card->fully_routed = true;
2076 ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
2078 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
2142 const struct snd_soc_component_driver *codec;
2155 .codec = &sun4i_codec_codec,
2166 .codec = &sun6i_codec_codec,
2178 .codec = &sun7i_codec_codec,
2189 .codec = &sun8i_a23_codec_codec,
2202 * TODO Share the codec structure with A23 for now.
2204 * processing support for the H3.
2206 .codec = &sun8i_a23_codec_codec,
2219 * TODO The codec structure should be split out, like
2220 * H3, when adding digital audio processing support.
2222 .codec = &sun8i_a23_codec_codec,
2234 .codec = &sun50i_h616_codec_codec,
2244 .codec = &suniv_codec_codec,
2256 .compatible = "allwinner,sun4i-a10-codec",
2260 .compatible = "allwinner,sun6i-a31-codec",
2264 .compatible = "allwinner,sun7i-a20-codec",
2268 .compatible = "allwinner,sun8i-a23-codec",
2272 .compatible = "allwinner,sun8i-h3-codec",
2276 .compatible = "allwinner,sun8i-v3s-codec",
2280 .compatible = "allwinner,sun50i-h616-codec",
2284 .compatible = "allwinner,suniv-f1c100s-codec",
2300 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
2302 return -ENOMEM;
2304 scodec->dev = &pdev->dev;
2310 quirks = of_device_get_match_data(&pdev->dev);
2312 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
2313 return -ENODEV;
2316 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
2317 quirks->regmap_config);
2318 if (IS_ERR(scodec->regmap)) {
2319 dev_err(&pdev->dev, "Failed to create our regmap\n");
2320 return PTR_ERR(scodec->regmap);
2324 scodec->clk_apb = devm_clk_get_enabled(&pdev->dev, "apb");
2325 if (IS_ERR(scodec->clk_apb)) {
2326 dev_err(&pdev->dev, "Failed to get the APB clock\n");
2327 return PTR_ERR(scodec->clk_apb);
2330 scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
2331 if (IS_ERR(scodec->clk_module)) {
2332 dev_err(&pdev->dev, "Failed to get the module clock\n");
2333 return PTR_ERR(scodec->clk_module);
2336 if (quirks->has_reset) {
2337 scodec->rst = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL);
2338 if (IS_ERR(scodec->rst)) {
2339 dev_err(&pdev->dev, "Failed to get reset control\n");
2340 return PTR_ERR(scodec->rst);
2344 scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
2346 if (IS_ERR(scodec->gpio_pa)) {
2347 ret = PTR_ERR(scodec->gpio_pa);
2348 dev_err_probe(&pdev->dev, ret, "Failed to get pa gpio\n");
2352 scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN);
2353 if (IS_ERR(scodec->gpio_hp)) {
2354 ret = PTR_ERR(scodec->gpio_hp);
2355 dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
2360 scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
2361 scodec->regmap,
2362 quirks->reg_adc_fifoc);
2363 if (IS_ERR(scodec->reg_adc_fifoc)) {
2364 ret = PTR_ERR(scodec->reg_adc_fifoc);
2365 dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
2370 scodec->reg_dac_fifoc = devm_regmap_field_alloc(&pdev->dev,
2371 scodec->regmap,
2372 quirks->reg_dac_fifoc);
2373 if (IS_ERR(scodec->reg_dac_fifoc)) {
2374 ret = PTR_ERR(scodec->reg_dac_fifoc);
2375 dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
2381 scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
2382 scodec->playback_dma_data.maxburst = quirks->dma_max_burst;
2383 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
2385 if (!quirks->playback_only) {
2387 scodec->capture_dma_data.addr = res->start +
2388 quirks->reg_adc_rxdata;
2389 scodec->capture_dma_data.maxburst = quirks->dma_max_burst;
2390 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
2393 ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
2396 dev_err(&pdev->dev, "Failed to register our codec\n");
2400 ret = devm_snd_soc_register_component(&pdev->dev,
2404 dev_err(&pdev->dev, "Failed to register our DAI\n");
2408 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
2410 dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
2414 card = quirks->create_card(&pdev->dev);
2417 dev_err(&pdev->dev, "Failed to create our card\n");
2425 dev_err_probe(&pdev->dev, ret, "Failed to register our card\n");
2441 .name = "sun4i-codec",
2449 MODULE_DESCRIPTION("Allwinner A10 codec driver");
2452 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
2453 MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");