Lines Matching +full:rk3308 +full:- +full:codec

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip RK3308 internal audio codec driver
6 * Copyright (c) 2024, Vivax-Metrotech Ltd
57 static const DECLARE_TLV_DB_SCALE(rk3308_codec_adc_alc_gain_tlv, -1800, 150, 0);
58 static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpout_gain_tlv, -3900, 150, 0);
59 static const DECLARE_TLV_DB_SCALE(rk3308_codec_dac_hpmix_gain_tlv, -600, 600, 0);
62 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0),
63 1, 1, TLV_DB_SCALE_ITEM(-300, 0, 0),
64 2, 2, TLV_DB_SCALE_ITEM(-150, 0, 0),
182 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in rk3308_codec_pop_sound_set()
183 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_pop_sound_set() local
189 regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON01, in rk3308_codec_pop_sound_set()
190 mask << w->shift, val << w->shift); in rk3308_codec_pop_sound_set()
485 struct snd_soc_component *component = codec_dai->component; in rk3308_codec_set_dai_fmt()
486 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_set_dai_fmt() local
494 const unsigned int dac_master_bits = rk3308->codec_ver < ACODEC_VERSION_C ? in rk3308_codec_set_dai_fmt()
511 return -EINVAL; in rk3308_codec_set_dai_fmt()
532 return -EINVAL; in rk3308_codec_set_dai_fmt()
553 regmap_clear_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK); in rk3308_codec_set_dai_fmt()
556 regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), in rk3308_codec_set_dai_fmt()
560 regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), in rk3308_codec_set_dai_fmt()
569 regmap_set_bits(rk3308->regmap, RK3308_GLB_CON, RK3308_ADC_DIG_WORK); in rk3308_codec_set_dai_fmt()
571 regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, in rk3308_codec_set_dai_fmt()
575 regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, in rk3308_codec_set_dai_fmt()
582 static int rk3308_codec_dac_dig_config(struct rk3308_codec_priv *rk3308, in rk3308_codec_dac_dig_config() argument
601 return -EINVAL; in rk3308_codec_dac_dig_config()
604 regmap_update_bits(rk3308->regmap, RK3308_DAC_DIG_CON01, in rk3308_codec_dac_dig_config()
606 regmap_set_bits(rk3308->regmap, RK3308_DAC_DIG_CON02, RK3308_DAC_I2S_WORK); in rk3308_codec_dac_dig_config()
611 static int rk3308_codec_adc_dig_config(struct rk3308_codec_priv *rk3308, in rk3308_codec_adc_dig_config() argument
636 dev_err(rk3308->dev, "Invalid channel number %d\n", params_channels(params)); in rk3308_codec_adc_dig_config()
637 return -EINVAL; in rk3308_codec_adc_dig_config()
654 return -EINVAL; in rk3308_codec_adc_dig_config()
658 regmap_update_bits(rk3308->regmap, in rk3308_codec_adc_dig_config()
662 regmap_update_bits(rk3308->regmap, RK3308_ADC_DIG_CON01(grp), in rk3308_codec_adc_dig_config()
664 regmap_set_bits(rk3308->regmap, RK3308_ADC_DIG_CON02(grp), RK3308_ADC_I2S_WORK); in rk3308_codec_adc_dig_config()
674 struct snd_soc_component *component = dai->component; in rk3308_codec_hw_params()
675 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_hw_params() local
677 return (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? in rk3308_codec_hw_params()
678 rk3308_codec_dac_dig_config(rk3308, params) : in rk3308_codec_hw_params()
679 rk3308_codec_adc_dig_config(rk3308, params); in rk3308_codec_hw_params()
688 .name = "rk3308-hifi",
714 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_reset() local
716 reset_control_assert(rk3308->reset); in rk3308_codec_reset()
718 reset_control_deassert(rk3308->reset); in rk3308_codec_reset()
720 regmap_write(rk3308->regmap, RK3308_GLB_CON, 0x00); in rk3308_codec_reset()
722 regmap_write(rk3308->regmap, RK3308_GLB_CON, in rk3308_codec_reset()
732 static int rk3308_codec_initialize(struct rk3308_codec_priv *rk3308) in rk3308_codec_initialize() argument
738 * Range: -97dB ~ +32dB. in rk3308_codec_initialize()
740 if (rk3308->codec_ver == ACODEC_VERSION_C) { in rk3308_codec_initialize()
742 regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON05(grp), in rk3308_codec_initialize()
744 regmap_write(rk3308->regmap, RK3308_ADC_DIG_CON06(grp), in rk3308_codec_initialize()
750 regmap_update_bits(rk3308->regmap, RK3308_DAC_ANA_CON12, in rk3308_codec_initialize()
757 if (rk3308->codec_ver == ACODEC_VERSION_C) in rk3308_codec_initialize()
758 regmap_write(rk3308->regmap, RK3308_DAC_DIG_CON04, in rk3308_codec_initialize()
762 * Unconditionally enable zero-cross detection (needed for AGC, in rk3308_codec_initialize()
766 regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON02(grp), in rk3308_codec_initialize()
775 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_probe() local
777 rk3308->component = component; in rk3308_codec_probe()
780 rk3308_codec_initialize(rk3308); in rk3308_codec_probe()
788 struct rk3308_codec_priv *rk3308 = snd_soc_component_get_drvdata(component); in rk3308_codec_set_bias_level() local
800 regmap_set_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, in rk3308_codec_set_bias_level()
802 regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), in rk3308_codec_set_bias_level()
804 regmap_set_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), in rk3308_codec_set_bias_level()
806 regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), in rk3308_codec_set_bias_level()
812 regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), in rk3308_codec_set_bias_level()
814 regmap_clear_bits(rk3308->regmap, RK3308_ADC_ANA_CON10(0), in rk3308_codec_set_bias_level()
816 regmap_clear_bits(rk3308->regmap, RK3308_DAC_ANA_CON02, in rk3308_codec_set_bias_level()
842 static int rk3308_codec_get_version(struct rk3308_codec_priv *rk3308) in rk3308_codec_get_version() argument
847 err = regmap_read(rk3308->grf, GRF_CHIP_ID, &chip_id); in rk3308_codec_get_version()
853 rk3308->codec_ver = ACODEC_VERSION_A; in rk3308_codec_get_version()
856 rk3308->codec_ver = ACODEC_VERSION_B; in rk3308_codec_get_version()
857 return dev_err_probe(rk3308->dev, -EINVAL, "Chip version B not supported\n"); in rk3308_codec_get_version()
859 rk3308->codec_ver = ACODEC_VERSION_C; in rk3308_codec_get_version()
862 return dev_err_probe(rk3308->dev, -EINVAL, "Unknown chip_id: 0x%x\n", chip_id); in rk3308_codec_get_version()
865 dev_info(rk3308->dev, "Found codec version %c\n", rk3308->codec_ver); in rk3308_codec_get_version()
869 static int rk3308_codec_set_micbias_level(struct rk3308_codec_priv *rk3308) in rk3308_codec_set_micbias_level() argument
871 struct device_node *np = rk3308->dev->of_node; in rk3308_codec_set_micbias_level()
876 err = of_property_read_u32(np, "rockchip,micbias-avdd-percent", &percent); in rk3308_codec_set_micbias_level()
877 if (err == -EINVAL) in rk3308_codec_set_micbias_level()
880 return dev_err_probe(rk3308->dev, err, in rk3308_codec_set_micbias_level()
881 "Error reading 'rockchip,micbias-avdd-percent'\n"); in rk3308_codec_set_micbias_level()
883 /* Convert percent to register value, linerarly (50% -> 0, 5% step = +1) */ in rk3308_codec_set_micbias_level()
884 mult = (percent - 50) / 5; in rk3308_codec_set_micbias_level()
888 return dev_err_probe(rk3308->dev, -EINVAL, in rk3308_codec_set_micbias_level()
889 "Invalid value %u for 'rockchip,micbias-avdd-percent'\n", in rk3308_codec_set_micbias_level()
892 regmap_update_bits(rk3308->regmap, RK3308_ADC_ANA_CON07(0), in rk3308_codec_set_micbias_level()
901 struct device_node *np = pdev->dev.of_node; in rk3308_codec_platform_probe()
902 struct device *dev = &pdev->dev; in rk3308_codec_platform_probe()
903 struct rk3308_codec_priv *rk3308; in rk3308_codec_platform_probe() local
907 rk3308 = devm_kzalloc(&pdev->dev, sizeof(*rk3308), GFP_KERNEL); in rk3308_codec_platform_probe()
908 if (!rk3308) in rk3308_codec_platform_probe()
909 return -ENOMEM; in rk3308_codec_platform_probe()
911 rk3308->dev = dev; in rk3308_codec_platform_probe()
913 rk3308->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); in rk3308_codec_platform_probe()
914 if (IS_ERR(rk3308->grf)) in rk3308_codec_platform_probe()
915 return dev_err_probe(dev, PTR_ERR(rk3308->grf), "Error getting GRF\n"); in rk3308_codec_platform_probe()
917 rk3308->reset = devm_reset_control_get_optional_exclusive(dev, "codec"); in rk3308_codec_platform_probe()
918 if (IS_ERR(rk3308->reset)) in rk3308_codec_platform_probe()
919 return dev_err_probe(dev, PTR_ERR(rk3308->reset), "Failed to get reset control\n"); in rk3308_codec_platform_probe()
929 err = rk3308_codec_get_version(rk3308); in rk3308_codec_platform_probe()
937 rk3308->regmap = devm_regmap_init_mmio(dev, base, &rk3308_codec_regmap_config); in rk3308_codec_platform_probe()
938 if (IS_ERR(rk3308->regmap)) in rk3308_codec_platform_probe()
939 return dev_err_probe(dev, PTR_ERR(rk3308->regmap), in rk3308_codec_platform_probe()
942 platform_set_drvdata(pdev, rk3308); in rk3308_codec_platform_probe()
944 err = rk3308_codec_set_micbias_level(rk3308); in rk3308_codec_platform_probe()
951 return dev_err_probe(dev, err, "Failed to register codec\n"); in rk3308_codec_platform_probe()
957 { .compatible = "rockchip,rk3308-codec", },
964 .name = "rk3308-acodec",
971 MODULE_AUTHOR("Xing Zheng <zhengxing@rock-chips.com>");
973 MODULE_DESCRIPTION("ASoC RK3308 Codec Driver");