Lines Matching +full:dsp +full:- +full:aif1 +full:- +full:bclk

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * (C) Copyright 2010-2016
9 * Mylène Josserand <mylene.josserand@free-electrons.com>
27 #include <sound/soc-dapm.h>
251 ret = clk_prepare_enable(scodec->clk_bus); in sun8i_codec_runtime_resume()
257 regcache_cache_only(scodec->regmap, false); in sun8i_codec_runtime_resume()
259 ret = regcache_sync(scodec->regmap); in sun8i_codec_runtime_resume()
272 regcache_cache_only(scodec->regmap, true); in sun8i_codec_runtime_suspend()
273 regcache_mark_dirty(scodec->regmap); in sun8i_codec_runtime_suspend()
275 clk_disable_unprepare(scodec->clk_bus); in sun8i_codec_runtime_suspend()
311 return -EINVAL; in sun8i_codec_get_hw_rate()
321 struct sun8i_codec_aif *aif = &scodec->aifs[i]; in sun8i_codec_update_sample_rate()
323 if (aif->active_streams) in sun8i_codec_update_sample_rate()
324 max_rate = max(max_rate, aif->sample_rate); in sun8i_codec_update_sample_rate()
327 /* Set the sample rate for ADC->DAC passthrough when no AIF is active. */ in sun8i_codec_update_sample_rate()
335 regmap_update_bits(scodec->regmap, SUN8I_SYS_SR_CTRL, in sun8i_codec_update_sample_rate()
356 return -EINVAL; in sun8i_codec_set_fmt()
359 if (dai->id == SUN8I_CODEC_AIF3) { in sun8i_codec_set_fmt()
362 return -EINVAL; in sun8i_codec_set_fmt()
364 /* Use the AIF2 BCLK and LRCK for AIF3. */ in sun8i_codec_set_fmt()
365 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), in sun8i_codec_set_fmt()
369 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), in sun8i_codec_set_fmt()
394 return -EINVAL; in sun8i_codec_set_fmt()
397 if (dai->id == SUN8I_CODEC_AIF3) { in sun8i_codec_set_fmt()
398 /* AIF3 only supports DSP mode. */ in sun8i_codec_set_fmt()
400 return -EINVAL; in sun8i_codec_set_fmt()
402 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), in sun8i_codec_set_fmt()
415 case SND_SOC_DAIFMT_IB_NF: /* Inverted BCLK */ in sun8i_codec_set_fmt()
422 return -EINVAL; in sun8i_codec_set_fmt()
426 /* Inverted LRCK is not available in DSP mode. */ in sun8i_codec_set_fmt()
428 return -EINVAL; in sun8i_codec_set_fmt()
430 /* Instead, the bit selects between DSP A/B formats. */ in sun8i_codec_set_fmt()
443 invert ^= scodec->quirks->lrck_inversion; in sun8i_codec_set_fmt()
446 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), in sun8i_codec_set_fmt()
458 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id]; in sun8i_codec_set_tdm_slot()
461 return -EINVAL; in sun8i_codec_set_tdm_slot()
463 aif->slots = slots; in sun8i_codec_set_tdm_slot()
464 aif->slot_width = slot_width; in sun8i_codec_set_tdm_slot()
498 if (dai->id != SUN8I_CODEC_AIF1) in sun8i_codec_startup()
501 if (!scodec->sysclk_refcnt) in sun8i_codec_startup()
503 else if (scodec->sysclk_rate == 22579200) in sun8i_codec_startup()
505 else if (scodec->sysclk_rate == 24576000) in sun8i_codec_startup()
508 return -EINVAL; in sun8i_codec_startup()
510 return snd_pcm_hw_constraint_list(substream->runtime, 0, in sun8i_codec_startup()
546 if (bdiv->div == div) in sun8i_codec_get_bclk_div()
547 return bdiv->val; in sun8i_codec_get_bclk_div()
550 return -EINVAL; in sun8i_codec_get_bclk_div()
559 return -EINVAL; in sun8i_codec_get_lrck_div_order()
574 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id]; in sun8i_codec_hw_params()
576 unsigned int slots = aif->slots ?: params_channels(params); in sun8i_codec_hw_params()
577 unsigned int slot_width = aif->slot_width ?: params_width(params); in sun8i_codec_hw_params()
597 return -EINVAL; in sun8i_codec_hw_params()
600 regmap_update_bits(scodec->regmap, SUN8I_AIF_CLK_CTRL(dai->id), in sun8i_codec_hw_params()
604 /* LRCK divider (BCLK/LRCK ratio) */ in sun8i_codec_hw_params()
609 if (dai->id == SUN8I_CODEC_AIF2 || dai->id == SUN8I_CODEC_AIF3) { in sun8i_codec_hw_params()
610 /* AIF2 and AIF3 share AIF2's BCLK and LRCK generation circuitry. */ in sun8i_codec_hw_params()
611 int partner = (SUN8I_CODEC_AIF2 + SUN8I_CODEC_AIF3) - dai->id; in sun8i_codec_hw_params()
612 const struct sun8i_codec_aif *partner_aif = &scodec->aifs[partner]; in sun8i_codec_hw_params()
615 if (partner_aif->open_streams && in sun8i_codec_hw_params()
616 (lrck_div_order != partner_aif->lrck_div_order || in sun8i_codec_hw_params()
617 sample_rate != partner_aif->sample_rate)) { in sun8i_codec_hw_params()
618 dev_err(dai->dev, in sun8i_codec_hw_params()
620 dai->name, partner_name); in sun8i_codec_hw_params()
621 return -EBUSY; in sun8i_codec_hw_params()
626 clk_reg = SUN8I_AIF_CLK_CTRL(dai->id); in sun8i_codec_hw_params()
629 regmap_update_bits(scodec->regmap, clk_reg, in sun8i_codec_hw_params()
631 (lrck_div_order - 4) << SUN8I_AIF_CLK_CTRL_LRCK_DIV); in sun8i_codec_hw_params()
633 /* BCLK divider (SYSCLK/BCLK ratio) */ in sun8i_codec_hw_params()
638 regmap_update_bits(scodec->regmap, clk_reg, in sun8i_codec_hw_params()
651 ret = (aif->open_streams ? clk_set_rate : clk_set_rate_exclusive)(scodec->clk_module, in sun8i_codec_hw_params()
653 if (ret == -EBUSY) in sun8i_codec_hw_params()
654 dev_err(dai->dev, in sun8i_codec_hw_params()
656 dai->name, sample_rate); in sun8i_codec_hw_params()
660 if (!aif->open_streams) in sun8i_codec_hw_params()
661 scodec->sysclk_refcnt++; in sun8i_codec_hw_params()
662 scodec->sysclk_rate = sysclk_rate; in sun8i_codec_hw_params()
664 aif->lrck_div_order = lrck_div_order; in sun8i_codec_hw_params()
665 aif->sample_rate = sample_rate; in sun8i_codec_hw_params()
666 aif->open_streams |= BIT(substream->stream); in sun8i_codec_hw_params()
675 struct sun8i_codec_aif *aif = &scodec->aifs[dai->id]; in sun8i_codec_hw_free()
678 if (aif->open_streams != BIT(substream->stream)) in sun8i_codec_hw_free()
681 clk_rate_exclusive_put(scodec->clk_module); in sun8i_codec_hw_free()
682 scodec->sysclk_refcnt--; in sun8i_codec_hw_free()
683 aif->lrck_div_order = 0; in sun8i_codec_hw_free()
684 aif->sample_rate = 0; in sun8i_codec_hw_free()
687 aif->open_streams &= ~BIT(substream->stream); in sun8i_codec_hw_free()
701 .name = "sun8i-codec-aif1",
706 .stream_name = "AIF1 Capture",
715 .stream_name = "AIF1 Playback",
726 .name = "sun8i-codec-aif2",
751 .name = "sun8i-codec-aif3",
777 static const DECLARE_TLV_DB_SCALE(sun8i_codec_vol_scale, -12000, 75, 1);
780 SOC_DOUBLE_TLV("AIF1 AD0 Capture Volume",
785 SOC_DOUBLE_TLV("AIF1 DA0 Playback Volume",
815 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in sun8i_codec_aif_event()
817 struct sun8i_codec_aif *aif = &scodec->aifs[w->sname[3] - '1']; in sun8i_codec_aif_event()
818 int stream = w->id == snd_soc_dapm_aif_out; in sun8i_codec_aif_event()
821 aif->active_streams |= BIT(stream); in sun8i_codec_aif_event()
823 aif->active_streams &= ~BIT(stream); in sun8i_codec_aif_event()
839 SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route",
866 SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
874 SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
885 SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA0 Capture Switch",
889 SOC_DAPM_DOUBLE("AIF2 ADC Mixer AIF1 DA1 Capture Switch",
923 SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route",
937 SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
941 SOC_DAPM_DOUBLE("AIF1 Slot 1 Digital DAC Playback Switch",
968 SND_SOC_DAPM_SUPPLY("CLK AIF1",
985 SND_SOC_DAPM_SUPPLY("RST AIF1",
1010 SND_SOC_DAPM_AIF_OUT_E("AIF1 AD0L", "AIF1 Capture", 0,
1015 SND_SOC_DAPM_AIF_OUT("AIF1 AD0R", "AIF1 Capture", 1,
1034 SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
1036 SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
1049 SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
1051 SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
1066 SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
1068 SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
1077 SND_SOC_DAPM_AIF_IN_E("AIF1 DA0L", "AIF1 Playback", 0,
1082 SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "AIF1 Playback", 1,
1121 { "CLK AIF1", NULL, "AIF1CLK" },
1122 { "CLK AIF1", NULL, "SYSCLK" },
1123 { "RST AIF1", NULL, "CLK AIF1" },
1124 { "AIF1 AD0L", NULL, "RST AIF1" },
1125 { "AIF1 AD0R", NULL, "RST AIF1" },
1126 { "AIF1 DA0L", NULL, "RST AIF1" },
1127 { "AIF1 DA0R", NULL, "RST AIF1" },
1156 { "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
1157 { "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
1165 { "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
1166 { "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
1167 { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1168 { "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1169 { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1170 { "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1172 { "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
1173 { "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
1174 { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
1175 { "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
1176 { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
1177 { "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
1198 { "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
1199 { "AIF1 AD0L Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACL Source" },
1200 { "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
1201 { "AIF1 AD0L Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACR Source" },
1203 { "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
1204 { "AIF1 AD0R Mixer", "AIF2 Digital ADC Capture Switch", "AIF2 DACR Source" },
1205 { "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
1206 { "AIF1 AD0R Mixer", "AIF2 Inv Digital ADC Capture Switch", "AIF2 DACL Source" },
1208 { "AIF2 ADCL Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0L Stereo Mux" },
1212 { "AIF2 ADCR Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0R Stereo Mux" },
1226 { "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
1227 { "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
1228 { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1229 { "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1230 { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1231 { "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1233 { "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
1234 { "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
1235 { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
1236 { "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
1237 { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
1238 { "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
1259 { "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
1263 { "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
1270 SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0),
1271 SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0),
1274 SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0),
1275 SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0),
1280 { "ADCL", NULL, "AIF1 Slot 0 Left ADC" },
1281 { "ADCR", NULL, "AIF1 Slot 0 Right ADC" },
1284 { "AIF1 Slot 0 Left", NULL, "DACL" },
1285 { "AIF1 Slot 0 Right", NULL, "DACR" },
1294 scodec->component = component; in sun8i_codec_component_probe()
1297 if (scodec->quirks->legacy_widgets) { in sun8i_codec_component_probe()
1311 * and MCLK (from the CPU DAI connected to AIF1). MCLK's parent is also in sun8i_codec_component_probe()
1315 regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL, in sun8i_codec_component_probe()
1321 /* Use AIF1CLK as the SYSCLK parent since AIF1 is used most often. */ in sun8i_codec_component_probe()
1322 regmap_update_bits(scodec->regmap, SUN8I_SYSCLK_CTL, in sun8i_codec_component_probe()
1334 struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm; in sun8i_codec_set_hmic_bias()
1344 regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1, in sun8i_codec_set_hmic_bias()
1355 guard(mutex)(&scodec->jack_mutex); in sun8i_codec_jack_work()
1357 if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) { in sun8i_codec_jack_work()
1358 if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST) in sun8i_codec_jack_work()
1361 scodec->jack_last_sample = -1; in sun8i_codec_jack_work()
1363 if (scodec->jack_type & SND_JACK_MICROPHONE) { in sun8i_codec_jack_work()
1368 scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600); in sun8i_codec_jack_work()
1371 &scodec->jack_work, in sun8i_codec_jack_work()
1373 scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS; in sun8i_codec_jack_work()
1375 snd_soc_jack_report(scodec->jack, SND_JACK_HEADPHONE, in sun8i_codec_jack_work()
1376 scodec->jack_type); in sun8i_codec_jack_work()
1377 scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED; in sun8i_codec_jack_work()
1379 } else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) { in sun8i_codec_jack_work()
1381 * If we're waiting for HBIAS to stabilize, and we get plug-out in sun8i_codec_jack_work()
1385 if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) { in sun8i_codec_jack_work()
1386 scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED; in sun8i_codec_jack_work()
1394 if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) { in sun8i_codec_jack_work()
1395 s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready, in sun8i_codec_jack_work()
1399 &scodec->jack_work, in sun8i_codec_jack_work()
1407 regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata); in sun8i_codec_jack_work()
1411 regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0); in sun8i_codec_jack_work()
1417 snd_soc_jack_report(scodec->jack, type, scodec->jack_type); in sun8i_codec_jack_work()
1418 scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED; in sun8i_codec_jack_work()
1419 } else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) { in sun8i_codec_jack_work()
1420 if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) in sun8i_codec_jack_work()
1423 scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED; in sun8i_codec_jack_work()
1424 if (scodec->jack_type & SND_JACK_MICROPHONE) in sun8i_codec_jack_work()
1427 snd_soc_jack_report(scodec->jack, 0, scodec->jack_type); in sun8i_codec_jack_work()
1437 guard(mutex)(&scodec->jack_mutex); in sun8i_codec_jack_irq()
1439 regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status); in sun8i_codec_jack_irq()
1440 regmap_write(scodec->regmap, SUN8I_HMIC_STS, status); in sun8i_codec_jack_irq()
1443 * De-bounce in/out interrupts via a delayed work re-scheduling to in sun8i_codec_jack_irq()
1452 scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST; in sun8i_codec_jack_irq()
1453 mod_delayed_work(system_power_efficient_wq, &scodec->jack_work, in sun8i_codec_jack_irq()
1456 scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST; in sun8i_codec_jack_irq()
1457 mod_delayed_work(system_power_efficient_wq, &scodec->jack_work, in sun8i_codec_jack_irq()
1465 if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED) in sun8i_codec_jack_irq()
1485 * De-bounce. Only report button after two consecutive A/D in sun8i_codec_jack_irq()
1488 if (scodec->jack_last_sample >= 0 && in sun8i_codec_jack_irq()
1489 scodec->jack_last_sample == value) in sun8i_codec_jack_irq()
1490 snd_soc_jack_report(scodec->jack, type, in sun8i_codec_jack_irq()
1491 scodec->jack_type); in sun8i_codec_jack_irq()
1493 scodec->jack_last_sample = value; in sun8i_codec_jack_irq()
1503 struct platform_device *pdev = to_platform_device(component->dev); in sun8i_codec_enable_jack_detect()
1506 if (!scodec->quirks->jack_detection) in sun8i_codec_enable_jack_detect()
1509 scodec->jack = jack; in sun8i_codec_enable_jack_detect()
1511 scodec->jack_irq = platform_get_irq(pdev, 0); in sun8i_codec_enable_jack_detect()
1512 if (scodec->jack_irq < 0) in sun8i_codec_enable_jack_detect()
1513 return scodec->jack_irq; in sun8i_codec_enable_jack_detect()
1516 regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1, in sun8i_codec_enable_jack_detect()
1522 regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2, in sun8i_codec_enable_jack_detect()
1528 regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0); in sun8i_codec_enable_jack_detect()
1530 regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1, in sun8i_codec_enable_jack_detect()
1534 ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq, in sun8i_codec_enable_jack_detect()
1537 dev_name(&pdev->dev), scodec); in sun8i_codec_enable_jack_detect()
1548 if (!scodec->quirks->jack_detection) in sun8i_codec_disable_jack_detect()
1551 devm_free_irq(component->dev, scodec->jack_irq, scodec); in sun8i_codec_disable_jack_detect()
1553 cancel_delayed_work_sync(&scodec->jack_work); in sun8i_codec_disable_jack_detect()
1555 regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1, in sun8i_codec_disable_jack_detect()
1560 scodec->jack = NULL; in sun8i_codec_disable_jack_detect()
1611 scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL); in sun8i_codec_probe()
1613 return -ENOMEM; in sun8i_codec_probe()
1615 scodec->quirks = of_device_get_match_data(&pdev->dev); in sun8i_codec_probe()
1616 INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work); in sun8i_codec_probe()
1617 mutex_init(&scodec->jack_mutex); in sun8i_codec_probe()
1621 if (scodec->quirks->bus_clock) { in sun8i_codec_probe()
1622 scodec->clk_bus = devm_clk_get(&pdev->dev, "bus"); in sun8i_codec_probe()
1623 if (IS_ERR(scodec->clk_bus)) { in sun8i_codec_probe()
1624 dev_err(&pdev->dev, "Failed to get the bus clock\n"); in sun8i_codec_probe()
1625 return PTR_ERR(scodec->clk_bus); in sun8i_codec_probe()
1629 scodec->clk_module = devm_clk_get(&pdev->dev, "mod"); in sun8i_codec_probe()
1630 if (IS_ERR(scodec->clk_module)) { in sun8i_codec_probe()
1631 dev_err(&pdev->dev, "Failed to get the module clock\n"); in sun8i_codec_probe()
1632 return PTR_ERR(scodec->clk_module); in sun8i_codec_probe()
1637 dev_err(&pdev->dev, "Failed to map the registers\n"); in sun8i_codec_probe()
1641 scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, in sun8i_codec_probe()
1643 if (IS_ERR(scodec->regmap)) { in sun8i_codec_probe()
1644 dev_err(&pdev->dev, "Failed to create our regmap\n"); in sun8i_codec_probe()
1645 return PTR_ERR(scodec->regmap); in sun8i_codec_probe()
1648 regcache_cache_only(scodec->regmap, true); in sun8i_codec_probe()
1649 pm_runtime_enable(&pdev->dev); in sun8i_codec_probe()
1650 if (!pm_runtime_enabled(&pdev->dev)) { in sun8i_codec_probe()
1651 ret = sun8i_codec_runtime_resume(&pdev->dev); in sun8i_codec_probe()
1656 ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component, in sun8i_codec_probe()
1660 dev_err(&pdev->dev, "Failed to register codec\n"); in sun8i_codec_probe()
1667 if (!pm_runtime_status_suspended(&pdev->dev)) in sun8i_codec_probe()
1668 sun8i_codec_runtime_suspend(&pdev->dev); in sun8i_codec_probe()
1671 pm_runtime_disable(&pdev->dev); in sun8i_codec_probe()
1678 pm_runtime_disable(&pdev->dev); in sun8i_codec_remove()
1679 if (!pm_runtime_status_suspended(&pdev->dev)) in sun8i_codec_remove()
1680 sun8i_codec_runtime_suspend(&pdev->dev); in sun8i_codec_remove()
1695 { .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks },
1696 { .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks },
1708 .name = "sun8i-codec",
1718 MODULE_AUTHOR("Mylène Josserand <mylene.josserand@free-electrons.com>");
1720 MODULE_ALIAS("platform:sun8i-codec");