Lines Matching +full:codec +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
3 // Ingenic JZ4760 CODEC driver
18 #include <sound/soc-dai.h>
19 #include <sound/soc-dapm.h>
68 #define REG_AICR_DAC_I2S BIT(1)
80 #define REG_CR1_OUTSEL_MASK GENMASK(1, REG_CR1_OUTSEL_OFFSET)
84 #define REG_CR2_DAC_NOMAD BIT(1)
89 #define REG_CR3_MICSTEREO_OFFSET 1
106 #define REG_PMR1_SB_BYPASS_OFFSET 1
112 #define REG_PMR2_SB_LOUT_OFFSET 1
121 #define REG_ICR_GUP_MASK BIT(1)
130 #define REG_IFR_GUP BIT(1)
161 /* codec private data */
169 static int jz4760_codec_set_bias_level(struct snd_soc_component *codec, in jz4760_codec_set_bias_level() argument
172 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4760_codec_set_bias_level()
173 struct regmap *regmap = jz_codec->regmap; in jz4760_codec_set_bias_level()
199 struct snd_soc_component *codec = dai->component; in jz4760_codec_startup() local
200 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); in jz4760_codec_startup()
204 * SYSCLK output from the codec to the AIC is required to keep the in jz4760_codec_startup()
208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in jz4760_codec_startup()
216 struct snd_soc_component *codec = dai->component; in jz4760_codec_shutdown() local
217 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); in jz4760_codec_shutdown()
219 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in jz4760_codec_shutdown()
227 struct snd_soc_component *codec = dai->component; in jz4760_codec_pcm_trigger() local
234 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) in jz4760_codec_pcm_trigger()
235 snd_soc_component_force_bias_level(codec, SND_SOC_BIAS_ON); in jz4760_codec_pcm_trigger()
243 ret = -EINVAL; in jz4760_codec_pcm_trigger()
251 struct snd_soc_component *codec = dai->component; in jz4760_codec_mute_stream() local
252 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4760_codec_mute_stream()
257 change = snd_soc_component_update_bits(codec, JZ4760_CODEC_REG_CR2, in jz4760_codec_mute_stream()
260 if (change == 1) { in jz4760_codec_mute_stream()
261 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_PMR2, &val); in jz4760_codec_mute_stream()
264 return 1; in jz4760_codec_mute_stream()
266 err = regmap_read_poll_timeout(jz_codec->regmap, in jz4760_codec_mute_stream()
269 1000, 1 * USEC_PER_SEC); in jz4760_codec_mute_stream()
271 dev_err(jz_codec->dev, in jz4760_codec_mute_stream()
277 regmap_write(jz_codec->regmap, JZ4760_CODEC_REG_IFR, gain_bit); in jz4760_codec_mute_stream()
280 regmap_read(jz_codec->regmap, JZ4760_CODEC_REG_CR2, &reg); in jz4760_codec_mute_stream()
286 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 100);
288 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 100);
289 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
290 static const DECLARE_TLV_DB_MINMAX(mixer_tlv, -3100, 0);
301 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
305 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
309 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
311 SOC_SINGLE("High-Pass Filter Capture Switch",
313 REG_CR4_ADC_HPF_OFFSET, 1, 0),
329 REG_GCR_GAIN_MAX, 1),
346 REG_GCR_GAIN_MAX, 1),
353 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); in hpout_event() local
354 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in hpout_event()
361 regmap_clear_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, in hpout_event()
366 /* wait for ramp-up complete (RUP) */ in hpout_event()
367 err = regmap_read_poll_timeout(jz_codec->regmap, in hpout_event()
370 1000, 1 * USEC_PER_SEC); in hpout_event()
372 dev_err(jz_codec->dev, "RUP timeout: %d", err); in hpout_event()
377 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, in hpout_event()
384 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR1, in hpout_event()
387 err = regmap_read_poll_timeout(jz_codec->regmap, in hpout_event()
390 1000, 1 * USEC_PER_SEC); in hpout_event()
392 dev_err(jz_codec->dev, "RDO timeout: %d", err); in hpout_event()
397 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_IFR, in hpout_event()
407 "PCM", "Line In", "Mic 1", "Mic 2"
410 static const unsigned int jz4760_codec_hp_values[] = { 3, 2, 0, 1 };
422 "Line In", "Mic 1", "Mic 2"
425 static const unsigned int jz4760_codec_cap_values[] = { 2, 0, 1 };
438 REG_CR3_MICSTEREO_OFFSET, 1, 0),
450 REG_PMR2_SB_HP_OFFSET, 1, NULL, 0, hpout_event,
455 REG_PMR2_SB_LOUT_OFFSET, 1,
459 REG_PMR2_SB_BTL_OFFSET, 1,
463 REG_PMR1_SB_LINE_OFFSET, 1, NULL, 0),
471 SND_SOC_DAPM_PGA("Mic 1", JZ4760_CODEC_REG_PMR1,
472 REG_PMR1_SB_MIC1_OFFSET, 1, NULL, 0),
475 REG_PMR1_SB_MIC2_OFFSET, 1, NULL, 0),
485 REG_PMR1_SB_BYPASS_OFFSET, 1, NULL, 0),
488 REG_PMR2_SB_ADC_OFFSET, 1),
491 REG_PMR2_SB_DAC_OFFSET, 1),
502 REG_PMR1_SB_MICBIAS_OFFSET, 1, NULL, 0),
526 { "Mic 1", NULL, "MIC1P" },
528 { "Mic 1", NULL, "Mic Diff" },
536 { "Mic", "Stereo Capture Switch", "Mic 1" },
538 { "Headphones Source", "Mic 1", "Mic" },
540 { "Capture Source", "Mic 1", "Mic" },
544 { "Capture Source", "Mic 1", "Mic 1" },
550 { "Headphones Source", "Mic 1", "Mic 1" },
573 static void jz4760_codec_codec_init_regs(struct snd_soc_component *codec) in jz4760_codec_codec_init_regs() argument
575 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4760_codec_codec_init_regs()
576 struct regmap *regmap = jz_codec->regmap; in jz4760_codec_codec_init_regs()
588 /* Set mic 1 as default source for ADC */ in jz4760_codec_codec_init_regs()
607 /* 0: 16ohm/220uF, 1: 10kohm/1uF */ in jz4760_codec_codec_init_regs()
611 regmap_set_bits(jz_codec->regmap, JZ4760_CODEC_REG_CR2, in jz4760_codec_codec_init_regs()
626 static int jz4760_codec_codec_probe(struct snd_soc_component *codec) in jz4760_codec_codec_probe() argument
628 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4760_codec_codec_probe()
630 clk_prepare_enable(jz_codec->clk); in jz4760_codec_codec_probe()
632 jz4760_codec_codec_init_regs(codec); in jz4760_codec_codec_probe()
637 static void jz4760_codec_codec_remove(struct snd_soc_component *codec) in jz4760_codec_codec_remove() argument
639 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4760_codec_codec_remove()
641 clk_disable_unprepare(jz_codec->clk); in jz4760_codec_codec_remove()
654 .suspend_bias_off = 1,
655 .use_pmdown_time = 1,
668 struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); in jz4760_codec_hw_params() local
676 bit_width = 1; in jz4760_codec_hw_params()
685 return -EINVAL; in jz4760_codec_hw_params()
694 return -EINVAL; in jz4760_codec_hw_params()
696 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in jz4760_codec_hw_params()
697 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, in jz4760_codec_hw_params()
700 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, in jz4760_codec_hw_params()
704 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_AICR, in jz4760_codec_hw_params()
707 regmap_update_bits(codec->regmap, JZ4760_CODEC_REG_CCR2, in jz4760_codec_hw_params()
721 .no_capture_mute = 1,
730 .name = "jz4760-hifi",
763 static int jz4760_codec_io_wait(struct jz_codec *codec) in jz4760_codec_io_wait() argument
767 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, in jz4760_codec_io_wait()
769 1000, 1 * USEC_PER_SEC); in jz4760_codec_io_wait()
775 struct jz_codec *codec = context; in jz4760_codec_reg_read() local
780 ret = jz4760_codec_io_wait(codec); in jz4760_codec_reg_read()
784 tmp = readl(codec->base + ICDC_RGADW_OFFSET); in jz4760_codec_reg_read()
787 writel(tmp, codec->base + ICDC_RGADW_OFFSET); in jz4760_codec_reg_read()
791 *val = readl(codec->base + ICDC_RGDATA_OFFSET) & in jz4760_codec_reg_read()
800 struct jz_codec *codec = context; in jz4760_codec_reg_write() local
803 ret = jz4760_codec_io_wait(codec); in jz4760_codec_reg_write()
808 codec->base + ICDC_RGADW_OFFSET); in jz4760_codec_reg_write()
810 ret = jz4760_codec_io_wait(codec); in jz4760_codec_reg_write()
842 struct device *dev = &pdev->dev; in jz4760_codec_probe()
843 struct jz_codec *codec; in jz4760_codec_probe() local
846 codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); in jz4760_codec_probe()
847 if (!codec) in jz4760_codec_probe()
848 return -ENOMEM; in jz4760_codec_probe()
850 codec->dev = dev; in jz4760_codec_probe()
852 codec->base = devm_platform_ioremap_resource(pdev, 0); in jz4760_codec_probe()
853 if (IS_ERR(codec->base)) in jz4760_codec_probe()
854 return PTR_ERR(codec->base); in jz4760_codec_probe()
856 codec->regmap = devm_regmap_init(dev, NULL, codec, in jz4760_codec_probe()
858 if (IS_ERR(codec->regmap)) in jz4760_codec_probe()
859 return PTR_ERR(codec->regmap); in jz4760_codec_probe()
861 codec->clk = devm_clk_get(dev, "aic"); in jz4760_codec_probe()
862 if (IS_ERR(codec->clk)) in jz4760_codec_probe()
863 return PTR_ERR(codec->clk); in jz4760_codec_probe()
865 platform_set_drvdata(pdev, codec); in jz4760_codec_probe()
868 &jz4760_codec_dai, 1); in jz4760_codec_probe()
870 dev_err(dev, "Failed to register codec: %d\n", ret); in jz4760_codec_probe()
878 { .compatible = "ingenic,jz4760-codec", },
886 .name = "jz4760-codec",
892 MODULE_DESCRIPTION("JZ4760 SoC internal codec driver");