Lines Matching +full:codec +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
3 // Ingenic JZ4770 CODEC driver
17 #include <sound/soc-dai.h>
18 #include <sound/soc-dapm.h>
85 #define REG_AICR_DAC_SERIAL BIT(1)
90 #define REG_AICR_ADC_SERIAL BIT(1)
115 #define REG_CR_MIC_BIAS_V0_OFFSET 1
129 #define REG_CR_VIC_SB_SLEEP BIT(1)
150 #define REG_IMR_GUP_MASK BIT(1)
159 #define REG_IFR_GUP BIT(1)
177 /* codec private data */
185 static int jz4770_codec_set_bias_level(struct snd_soc_component *codec, in jz4770_codec_set_bias_level() argument
188 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4770_codec_set_bias_level()
189 struct regmap *regmap = jz_codec->regmap; in jz4770_codec_set_bias_level()
219 struct snd_soc_component *codec = dai->component; in jz4770_codec_startup() local
220 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); in jz4770_codec_startup()
223 * SYSCLK output from the codec to the AIC is required to keep the in jz4770_codec_startup()
227 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in jz4770_codec_startup()
236 struct snd_soc_component *codec = dai->component; in jz4770_codec_shutdown() local
237 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); in jz4770_codec_shutdown()
239 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in jz4770_codec_shutdown()
247 struct snd_soc_component *codec = dai->component; in jz4770_codec_pcm_trigger() local
254 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) in jz4770_codec_pcm_trigger()
255 snd_soc_component_force_bias_level(codec, in jz4770_codec_pcm_trigger()
264 ret = -EINVAL; in jz4770_codec_pcm_trigger()
272 struct snd_soc_component *codec = dai->component; in jz4770_codec_mute_stream() local
273 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4770_codec_mute_stream()
278 change = snd_soc_component_update_bits(codec, JZ4770_CODEC_REG_CR_DAC, in jz4770_codec_mute_stream()
281 if (change == 1) { in jz4770_codec_mute_stream()
282 regmap_read(jz_codec->regmap, JZ4770_CODEC_REG_CR_DAC, &val); in jz4770_codec_mute_stream()
285 return 1; in jz4770_codec_mute_stream()
287 err = regmap_read_poll_timeout(jz_codec->regmap, in jz4770_codec_mute_stream()
290 1000, 1 * USEC_PER_SEC); in jz4770_codec_mute_stream()
292 dev_err(jz_codec->dev, in jz4770_codec_mute_stream()
298 regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, in jz4770_codec_mute_stream()
306 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_tlv, -3100, 0);
308 static const DECLARE_TLV_DB_MINMAX(out_tlv, -2500, 600);
309 static const DECLARE_TLV_DB_SCALE(linein_tlv, -2500, 100, 0);
310 static const DECLARE_TLV_DB_MINMAX(mixer_tlv, -3100, 0);
322 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, linein_tlv),
326 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
330 REG_GCR_GAIN_OFFSET, REG_GCR_GAIN_MAX, 1, mixer_tlv),
351 REG_GCR_GAIN_MAX, 1),
369 REG_GCR_GAIN_MAX, 1),
376 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); in hpout_event() local
377 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in hpout_event()
384 regmap_clear_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP, in hpout_event()
389 /* wait for ramp-up complete (RUP) */ in hpout_event()
390 err = regmap_read_poll_timeout(jz_codec->regmap, in hpout_event()
393 1000, 1 * USEC_PER_SEC); in hpout_event()
395 dev_err(jz_codec->dev, "RUP timeout: %d", err); in hpout_event()
400 regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, in hpout_event()
407 regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_CR_HP, in hpout_event()
410 err = regmap_read_poll_timeout(jz_codec->regmap, in hpout_event()
413 1000, 1 * USEC_PER_SEC); in hpout_event()
415 dev_err(jz_codec->dev, "RDO timeout: %d", err); in hpout_event()
420 regmap_set_bits(jz_codec->regmap, JZ4770_CODEC_REG_IFR, in hpout_event()
439 "PCM", "Line In", "Mic 1", "Mic 2"
441 static const unsigned int jz4770_codec_hp_values[] = { 3, 2, 0, 1 };
461 "Line In", "Mic 1", "Mic 2"
463 static const unsigned int jz4770_codec_cap_values[] = { 2, 0, 1 };
475 REG_CR_MIC_STEREO_OFFSET, 1, 0),
480 REG_CR_HP_SB_OFFSET, 1, NULL, 0, hpout_event,
485 REG_CR_LO_SB_OFFSET, 1, NULL, 0),
488 REG_CR_LO_MUTE_OFFSET, 1, NULL, 0),
491 REG_CR_LI_SB_OFFSET, 1, NULL, 0),
500 SND_SOC_DAPM_PGA("Mic 1", JZ4770_CODEC_REG_CR_MIC,
501 REG_CR_MIC_SB_MIC1_OFFSET, 1, NULL, 0),
503 REG_CR_MIC_SB_MIC2_OFFSET, 1, NULL, 0),
513 REG_CR_LI_LIBY_OFFSET, 1, NULL, 0),
516 REG_CR_ADC_SB_OFFSET, 1, adc_poweron_event,
519 REG_CR_DAC_SB_OFFSET, 1),
529 REG_CR_MIC_BIAS_SB_OFFSET, 1, NULL, 0),
531 SND_SOC_DAPM_SUPPLY("Cap-less", JZ4770_CODEC_REG_CR_HP,
532 REG_CR_HP_SB_HPCM_OFFSET, 1, NULL, 0),
553 { "Mic 1", NULL, "MIC1P" },
555 { "Mic 1", NULL, "Mic Diff" },
563 { "Mic", "Stereo Capture Switch", "Mic 1" },
565 { "Headphones Source", "Mic 1", "Mic" },
567 { "Capture Source", "Mic 1", "Mic" },
570 { "Headphones Source", "Mic 1", "Mic 1" },
577 { "Capture Source", "Mic 1", "Mic 1" },
600 static void jz4770_codec_codec_init_regs(struct snd_soc_component *codec) in jz4770_codec_codec_init_regs() argument
602 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4770_codec_codec_init_regs()
603 struct regmap *regmap = jz_codec->regmap; in jz4770_codec_codec_init_regs()
618 /* Set mic 1 as default source for ADC */ in jz4770_codec_codec_init_regs()
638 /* 0: 16ohm/220uF, 1: 10kohm/1uF */ in jz4770_codec_codec_init_regs()
654 /* default to cap-less mode(0) */ in jz4770_codec_codec_init_regs()
663 static int jz4770_codec_codec_probe(struct snd_soc_component *codec) in jz4770_codec_codec_probe() argument
665 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4770_codec_codec_probe()
667 clk_prepare_enable(jz_codec->clk); in jz4770_codec_codec_probe()
669 jz4770_codec_codec_init_regs(codec); in jz4770_codec_codec_probe()
674 static void jz4770_codec_codec_remove(struct snd_soc_component *codec) in jz4770_codec_codec_remove() argument
676 struct jz_codec *jz_codec = snd_soc_component_get_drvdata(codec); in jz4770_codec_codec_remove()
678 clk_disable_unprepare(jz_codec->clk); in jz4770_codec_codec_remove()
691 .suspend_bias_off = 1,
692 .use_pmdown_time = 1,
705 struct jz_codec *codec = snd_soc_component_get_drvdata(dai->component); in jz4770_codec_hw_params() local
713 bit_width = 1; in jz4770_codec_hw_params()
722 return -EINVAL; in jz4770_codec_hw_params()
731 return -EINVAL; in jz4770_codec_hw_params()
733 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in jz4770_codec_hw_params()
734 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_DAC, in jz4770_codec_hw_params()
737 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_DAC, in jz4770_codec_hw_params()
741 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_AICR_ADC, in jz4770_codec_hw_params()
744 regmap_update_bits(codec->regmap, JZ4770_CODEC_REG_FCR_ADC, in jz4770_codec_hw_params()
758 .no_capture_mute = 1,
767 .name = "jz4770-hifi",
813 static int jz4770_codec_io_wait(struct jz_codec *codec) in jz4770_codec_io_wait() argument
817 return readl_poll_timeout(codec->base + ICDC_RGADW_OFFSET, reg, in jz4770_codec_io_wait()
819 1000, 1 * USEC_PER_SEC); in jz4770_codec_io_wait()
825 struct jz_codec *codec = context; in jz4770_codec_reg_read() local
830 ret = jz4770_codec_io_wait(codec); in jz4770_codec_reg_read()
834 tmp = readl(codec->base + ICDC_RGADW_OFFSET); in jz4770_codec_reg_read()
837 writel(tmp, codec->base + ICDC_RGADW_OFFSET); in jz4770_codec_reg_read()
841 *val = readl(codec->base + ICDC_RGDATA_OFFSET) & in jz4770_codec_reg_read()
850 struct jz_codec *codec = context; in jz4770_codec_reg_write() local
853 ret = jz4770_codec_io_wait(codec); in jz4770_codec_reg_write()
858 codec->base + ICDC_RGADW_OFFSET); in jz4770_codec_reg_write()
860 ret = jz4770_codec_io_wait(codec); in jz4770_codec_reg_write()
894 struct device *dev = &pdev->dev; in jz4770_codec_probe()
895 struct jz_codec *codec; in jz4770_codec_probe() local
898 codec = devm_kzalloc(dev, sizeof(*codec), GFP_KERNEL); in jz4770_codec_probe()
899 if (!codec) in jz4770_codec_probe()
900 return -ENOMEM; in jz4770_codec_probe()
902 codec->dev = dev; in jz4770_codec_probe()
904 codec->base = devm_platform_ioremap_resource(pdev, 0); in jz4770_codec_probe()
905 if (IS_ERR(codec->base)) in jz4770_codec_probe()
906 return PTR_ERR(codec->base); in jz4770_codec_probe()
908 codec->regmap = devm_regmap_init(dev, NULL, codec, in jz4770_codec_probe()
910 if (IS_ERR(codec->regmap)) in jz4770_codec_probe()
911 return PTR_ERR(codec->regmap); in jz4770_codec_probe()
913 codec->clk = devm_clk_get(dev, "aic"); in jz4770_codec_probe()
914 if (IS_ERR(codec->clk)) in jz4770_codec_probe()
915 return PTR_ERR(codec->clk); in jz4770_codec_probe()
917 platform_set_drvdata(pdev, codec); in jz4770_codec_probe()
920 &jz4770_codec_dai, 1); in jz4770_codec_probe()
922 dev_err(dev, "Failed to register codec: %d\n", ret); in jz4770_codec_probe()
930 { .compatible = "ingenic,jz4770-codec", },
938 .name = "jz4770-codec",
944 MODULE_DESCRIPTION("JZ4770 SoC internal codec driver");