Lines Matching +full:reset +full:- +full:source

1 // SPDX-License-Identifier: GPL-2.0-only
29 #include <sound/soc-dapm.h>
41 flush_work(&cs35l56->dsp_work); in cs35l56_wait_dsp_ready()
70 "ASP1 TX1 Source", "ASP1 TX2 Source", "ASP1 TX3 Source", "ASP1 TX4 Source"
75 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cs35l56->component); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
76 const char *prefix = cs35l56->component->name_prefix; in cs35l56_sync_asp1_mixer_widgets_with_firmware()
84 if (cs35l56->asp1_mixer_widgets_initialized) in cs35l56_sync_asp1_mixer_widgets_with_firmware()
91 ret = pm_runtime_resume_and_get(cs35l56->base.dev); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
98 ret = regmap_bulk_read(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, in cs35l56_sync_asp1_mixer_widgets_with_firmware()
101 pm_runtime_mark_last_busy(cs35l56->base.dev); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
102 pm_runtime_put_autosuspend(cs35l56->base.dev); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
105 dev_err(cs35l56->base.dev, "Failed to read ASP1 mixer regs: %d\n", ret); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
117 kcontrol = snd_soc_card_get_kcontrol_locked(dapm->card, name); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
119 dev_warn(cs35l56->base.dev, "Could not find control %s\n", name); in cs35l56_sync_asp1_mixer_widgets_with_firmware()
123 e = (struct soc_enum *)kcontrol->private_value; in cs35l56_sync_asp1_mixer_widgets_with_firmware()
128 cs35l56->asp1_mixer_widgets_initialized = true; in cs35l56_sync_asp1_mixer_widgets_with_firmware()
138 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cs35l56_dspwait_asp1tx_get()
139 int index = e->shift_l; in cs35l56_dspwait_asp1tx_get()
148 ret = regmap_read(cs35l56->base.regmap, addr, &val); in cs35l56_dspwait_asp1tx_get()
153 ucontrol->value.enumerated.item[0] = snd_soc_enum_val_to_item(e, val); in cs35l56_dspwait_asp1tx_get()
164 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cs35l56_dspwait_asp1tx_put()
165 int item = ucontrol->value.enumerated.item[0]; in cs35l56_dspwait_asp1tx_put()
166 int index = e->shift_l; in cs35l56_dspwait_asp1tx_put()
178 ret = regmap_update_bits_check(cs35l56->base.regmap, addr, in cs35l56_dspwait_asp1tx_put()
189 static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
197 6, -400, 400, 9, 0,
285 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_asp1_cfg_event()
291 return cs35l56_force_sync_asp1_registers_from_cache(&cs35l56->base); in cs35l56_asp1_cfg_event()
300 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_play_event()
305 dev_dbg(cs35l56->base.dev, "play: %d\n", event); in cs35l56_play_event()
310 return regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, in cs35l56_play_event()
314 ret = regmap_read_poll_timeout(cs35l56->base.regmap, in cs35l56_play_event()
320 dev_err(cs35l56->base.dev, "PS0 wait failed: %d\n", ret); in cs35l56_play_event()
323 return cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE); in cs35l56_play_event()
358 SND_SOC_DAPM_MUX("ASP1 TX1 Source", SND_SOC_NOPM, 0, 0, &asp1_tx1_mux),
359 SND_SOC_DAPM_MUX("ASP1 TX2 Source", SND_SOC_NOPM, 0, 0, &asp1_tx2_mux),
360 SND_SOC_DAPM_MUX("ASP1 TX3 Source", SND_SOC_NOPM, 0, 0, &asp1_tx3_mux),
361 SND_SOC_DAPM_MUX("ASP1 TX4 Source", SND_SOC_NOPM, 0, 0, &asp1_tx4_mux),
363 SND_SOC_DAPM_MUX("SDW1 TX1 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx1_mux),
364 SND_SOC_DAPM_MUX("SDW1 TX2 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx2_mux),
365 SND_SOC_DAPM_MUX("SDW1 TX3 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx3_mux),
366 SND_SOC_DAPM_MUX("SDW1 TX4 Source", SND_SOC_NOPM, 0, 0, &sdw1_tx4_mux),
378 { name" Source", "ASP1RX1", "ASP1RX1" }, \
379 { name" Source", "ASP1RX2", "ASP1RX2" }, \
380 { name" Source", "VMON", "VMON ADC" }, \
381 { name" Source", "IMON", "IMON ADC" }, \
382 { name" Source", "ERRVOL", "ERRVOL ADC" }, \
383 { name" Source", "CLASSH", "CLASSH ADC" }, \
384 { name" Source", "VDDBMON", "VDDBMON ADC" }, \
385 { name" Source", "VBSTMON", "VBSTMON ADC" }, \
386 { name" Source", "DSP1TX1", "DSP1" }, \
387 { name" Source", "DSP1TX2", "DSP1" }, \
388 { name" Source", "DSP1TX3", "DSP1" }, \
389 { name" Source", "DSP1TX4", "DSP1" }, \
390 { name" Source", "DSP1TX5", "DSP1" }, \
391 { name" Source", "DSP1TX6", "DSP1" }, \
392 { name" Source", "DSP1TX7", "DSP1" }, \
393 { name" Source", "DSP1TX8", "DSP1" }, \
394 { name" Source", "TEMPMON", "TEMPMON ADC" }, \
395 { name" Source", "INTERPOLATOR", "AMP" }, \
396 { name" Source", "SDW1RX1", "SDW1 Playback" }, \
397 { name" Source", "SDW1RX2", "SDW1 Playback" },
422 { "ASP1TX1", NULL, "ASP1 TX1 Source" },
423 { "ASP1TX2", NULL, "ASP1 TX2 Source" },
424 { "ASP1TX3", NULL, "ASP1 TX3 Source" },
425 { "ASP1TX4", NULL, "ASP1 TX4 Source" },
435 { "SDW1 Capture", NULL, "SDW1 TX1 Source" },
436 { "SDW1 Capture", NULL, "SDW1 TX2 Source" },
437 { "SDW1 Capture", NULL, "SDW1 TX3 Source" },
438 { "SDW1 Capture", NULL, "SDW1 TX4 Source" },
444 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_dsp_event()
447 dev_dbg(cs35l56->base.dev, "%s: %d\n", __func__, event); in cs35l56_dsp_event()
454 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); in cs35l56_asp_dai_set_fmt()
457 dev_dbg(cs35l56->base.dev, "%s: %#x\n", __func__, fmt); in cs35l56_asp_dai_set_fmt()
463 dev_err(cs35l56->base.dev, "Unsupported clock source mode\n"); in cs35l56_asp_dai_set_fmt()
464 return -EINVAL; in cs35l56_asp_dai_set_fmt()
470 cs35l56->tdm_mode = true; in cs35l56_asp_dai_set_fmt()
474 cs35l56->tdm_mode = false; in cs35l56_asp_dai_set_fmt()
477 dev_err(cs35l56->base.dev, "Unsupported DAI format\n"); in cs35l56_asp_dai_set_fmt()
478 return -EINVAL; in cs35l56_asp_dai_set_fmt()
494 dev_err(cs35l56->base.dev, "Invalid clock invert\n"); in cs35l56_asp_dai_set_fmt()
495 return -EINVAL; in cs35l56_asp_dai_set_fmt()
498 regmap_update_bits(cs35l56->base.regmap, in cs35l56_asp_dai_set_fmt()
504 /* Hi-Z DOUT in unused slots and when all TX are disabled */ in cs35l56_asp_dai_set_fmt()
505 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_asp_dai_set_fmt()
531 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_tdm_slot()
534 dev_dbg(cs35l56->base.dev, "tdm config cleared\n"); in cs35l56_asp_dai_set_tdm_slot()
535 cs35l56->asp_slot_width = 0; in cs35l56_asp_dai_set_tdm_slot()
536 cs35l56->asp_slot_count = 0; in cs35l56_asp_dai_set_tdm_slot()
541 dev_err(cs35l56->base.dev, "tdm invalid slot width %d\n", slot_width); in cs35l56_asp_dai_set_tdm_slot()
542 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
547 dev_err(cs35l56->base.dev, "tdm invalid slot count %d\n", slots); in cs35l56_asp_dai_set_tdm_slot()
548 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
551 cs35l56->asp_slot_width = (u8)slot_width; in cs35l56_asp_dai_set_tdm_slot()
552 cs35l56->asp_slot_count = (u8)slots; in cs35l56_asp_dai_set_tdm_slot()
562 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL1, in cs35l56_asp_dai_set_tdm_slot()
564 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL5, in cs35l56_asp_dai_set_tdm_slot()
567 dev_dbg(cs35l56->base.dev, "tdm slot width: %u count: %u tx_mask: %#x rx_mask: %#x\n", in cs35l56_asp_dai_set_tdm_slot()
568 cs35l56->asp_slot_width, cs35l56->asp_slot_count, tx_mask, rx_mask); in cs35l56_asp_dai_set_tdm_slot()
577 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_hw_params()
582 if (cs35l56->asp_slot_width) in cs35l56_asp_dai_hw_params()
583 asp_width = cs35l56->asp_slot_width; in cs35l56_asp_dai_hw_params()
587 dev_dbg(cs35l56->base.dev, "%s: wl=%d, width=%d, rate=%d", in cs35l56_asp_dai_hw_params()
590 if (!cs35l56->sysclk_set) { in cs35l56_asp_dai_hw_params()
591 unsigned int slots = cs35l56->asp_slot_count; in cs35l56_asp_dai_hw_params()
599 if (!cs35l56->tdm_mode) in cs35l56_asp_dai_hw_params()
606 dev_err(cs35l56->base.dev, "%s: Invalid BCLK %u\n", __func__, bclk_freq); in cs35l56_asp_dai_hw_params()
607 return -EINVAL; in cs35l56_asp_dai_hw_params()
610 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_hw_params()
615 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_asp_dai_hw_params()
616 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
619 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL5, in cs35l56_asp_dai_hw_params()
622 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
625 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL1, in cs35l56_asp_dai_hw_params()
635 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_sysclk()
639 cs35l56->sysclk_set = false; in cs35l56_asp_dai_set_sysclk()
647 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_set_sysclk()
650 cs35l56->sysclk_set = true; in cs35l56_asp_dai_set_sysclk()
671 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_set_tdm_slot()
674 cs35l56->rx_mask = tx_mask; in cs35l56_sdw_dai_set_tdm_slot()
675 cs35l56->tx_mask = rx_mask; in cs35l56_sdw_dai_set_tdm_slot()
684 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_params()
690 dev_dbg(cs35l56->base.dev, "%s: rate %d\n", __func__, params_rate(params)); in cs35l56_sdw_dai_hw_params()
692 if (!cs35l56->base.init_done) in cs35l56_sdw_dai_hw_params()
693 return -ENODEV; in cs35l56_sdw_dai_hw_params()
696 return -EINVAL; in cs35l56_sdw_dai_hw_params()
704 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_sdw_dai_hw_params()
707 pconfig.ch_mask = cs35l56->rx_mask; in cs35l56_sdw_dai_hw_params()
711 pconfig.ch_mask = cs35l56->tx_mask; in cs35l56_sdw_dai_hw_params()
716 pconfig.ch_mask = GENMASK(sconfig.ch_count - 1, 0); in cs35l56_sdw_dai_hw_params()
721 ret = sdw_stream_add_slave(cs35l56->sdw_peripheral, &sconfig, &pconfig, in cs35l56_sdw_dai_hw_params()
724 dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret); in cs35l56_sdw_dai_hw_params()
734 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_free()
737 if (!cs35l56->sdw_peripheral) in cs35l56_sdw_dai_hw_free()
738 return -EINVAL; in cs35l56_sdw_dai_hw_free()
740 sdw_stream_remove_slave(cs35l56->sdw_peripheral, sdw_stream); in cs35l56_sdw_dai_hw_free()
763 .name = "cs35l56-asp1",
784 .name = "cs35l56-sdw1",
810 ret = wm_adsp_power_up(&cs35l56->dsp, true); in cs35l56_reinit_patch()
812 dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); in cs35l56_reinit_patch()
814 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); in cs35l56_reinit_patch()
823 * Setting sdw_irq_no_unmask prevents the handler re-enabling in cs35l56_patch()
826 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
827 cs35l56->sdw_irq_no_unmask = true; in cs35l56_patch()
828 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
829 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0); in cs35l56_patch()
830 sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1); in cs35l56_patch()
831 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF); in cs35l56_patch()
832 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
835 ret = cs35l56_firmware_shutdown(&cs35l56->base); in cs35l56_patch()
842 * power-up wm_adsp without downloading firmware. in cs35l56_patch()
844 ret = wm_adsp_power_up(&cs35l56->dsp, !!firmware_missing); in cs35l56_patch()
846 dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); in cs35l56_patch()
850 mutex_lock(&cs35l56->base.irq_lock); in cs35l56_patch()
852 reinit_completion(&cs35l56->init_completion); in cs35l56_patch()
854 cs35l56->soft_resetting = true; in cs35l56_patch()
855 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_patch()
857 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
859 * The system-reset causes the CS35L56 to detach from the bus. in cs35l56_patch()
860 * Wait for the manager to re-enumerate the CS35L56 and in cs35l56_patch()
863 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_patch()
865 dev_err(cs35l56->base.dev, "%s: init_completion timed out (SDW)\n", in cs35l56_patch()
873 regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS, in cs35l56_patch()
875 cs35l56->base.fw_patched = true; in cs35l56_patch()
878 mutex_unlock(&cs35l56->base.irq_lock); in cs35l56_patch()
880 /* Re-enable SoundWire interrupts */ in cs35l56_patch()
881 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
882 cs35l56->sdw_irq_no_unmask = false; in cs35l56_patch()
883 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, in cs35l56_patch()
897 if (!cs35l56->base.init_done) in cs35l56_dsp_work()
900 pm_runtime_get_sync(cs35l56->base.dev); in cs35l56_dsp_work()
902 ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version); in cs35l56_dsp_work()
907 kfree(cs35l56->dsp.fwf_name); in cs35l56_dsp_work()
909 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, "%02x-dsp1", cs35l56->base.rev); in cs35l56_dsp_work()
912 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, in cs35l56_dsp_work()
913 "%02x%s-%06x-dsp1", in cs35l56_dsp_work()
914 cs35l56->base.rev, in cs35l56_dsp_work()
915 cs35l56->base.secured ? "-s" : "", in cs35l56_dsp_work()
919 if (!cs35l56->dsp.fwf_name) in cs35l56_dsp_work()
922 dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n", in cs35l56_dsp_work()
923 cs35l56->dsp.fwf_name, cs35l56->dsp.system_name); in cs35l56_dsp_work()
938 pm_runtime_mark_last_busy(cs35l56->base.dev); in cs35l56_dsp_work()
939 pm_runtime_put_autosuspend(cs35l56->base.dev); in cs35l56_dsp_work()
945 struct dentry *debugfs_root = component->debugfs_root; in cs35l56_component_probe()
950 if (!cs35l56->dsp.system_name && in cs35l56_component_probe()
951 (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) { in cs35l56_component_probe()
953 if (cs35l56->speaker_id >= 0) { in cs35l56_component_probe()
954 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
956 "%04x%04x-spkid%d", in cs35l56_component_probe()
958 cs35l56->speaker_id); in cs35l56_component_probe()
960 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
965 if (!cs35l56->dsp.system_name) in cs35l56_component_probe()
966 return -ENOMEM; in cs35l56_component_probe()
969 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_component_probe()
971 dev_err(cs35l56->base.dev, "%s: init_completion timed out\n", __func__); in cs35l56_component_probe()
972 return -ENODEV; in cs35l56_component_probe()
975 cs35l56->component = component; in cs35l56_component_probe()
976 wm_adsp2_component_probe(&cs35l56->dsp, component); in cs35l56_component_probe()
978 debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->base.init_done); in cs35l56_component_probe()
979 debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate); in cs35l56_component_probe()
980 debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched); in cs35l56_component_probe()
986 regcache_drop_region(cs35l56->base.regmap, CS35L56_ASP1TX1_INPUT, CS35L56_ASP1TX4_INPUT); in cs35l56_component_probe()
987 cs35l56->asp1_mixer_widgets_initialized = false; in cs35l56_component_probe()
989 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_component_probe()
998 cancel_work_sync(&cs35l56->dsp_work); in cs35l56_component_remove()
1000 if (cs35l56->dsp.cs_dsp.booted) in cs35l56_component_remove()
1001 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_component_remove()
1003 wm_adsp2_component_remove(&cs35l56->dsp, component); in cs35l56_component_remove()
1005 kfree(cs35l56->dsp.fwf_name); in cs35l56_component_remove()
1006 cs35l56->dsp.fwf_name = NULL; in cs35l56_component_remove()
1008 cs35l56->component = NULL; in cs35l56_component_remove()
1053 return cs35l56_runtime_suspend_common(&cs35l56->base); in cs35l56_runtime_suspend_i2c_spi()
1060 return cs35l56_runtime_resume_common(&cs35l56->base, false); in cs35l56_runtime_resume_i2c_spi()
1069 if (cs35l56->component) in cs35l56_system_suspend()
1070 flush_work(&cs35l56->dsp_work); in cs35l56_system_suspend()
1074 * we can't check if our device is the source of an interrupt, and can't in cs35l56_system_suspend()
1078 if (cs35l56->base.irq) in cs35l56_system_suspend()
1079 disable_irq(cs35l56->base.irq); in cs35l56_system_suspend()
1092 * Assert RESET before removing supplies. in cs35l56_system_suspend_late()
1093 * RESET is usually shared by all amps so it must not be asserted until in cs35l56_system_suspend_late()
1096 if (cs35l56->base.reset_gpio) { in cs35l56_system_suspend_late()
1097 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_suspend_late()
1101 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_suspend_late()
1113 /* Handlers are now disabled so the parent IRQ can safely be re-enabled. */ in cs35l56_system_suspend_no_irq()
1114 if (cs35l56->base.irq) in cs35l56_system_suspend_no_irq()
1115 enable_irq(cs35l56->base.irq); in cs35l56_system_suspend_no_irq()
1130 * We can't check if our device is the source of an interrupt, and can't in cs35l56_system_resume_no_irq()
1134 if (cs35l56->base.irq) in cs35l56_system_resume_no_irq()
1135 disable_irq(cs35l56->base.irq); in cs35l56_system_resume_no_irq()
1148 /* Ensure a spec-compliant RESET pulse. */ in cs35l56_system_resume_early()
1149 if (cs35l56->base.reset_gpio) { in cs35l56_system_resume_early()
1150 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_resume_early()
1154 /* Enable supplies before releasing RESET. */ in cs35l56_system_resume_early()
1155 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_resume_early()
1161 /* Release shared RESET before drivers start resume(). */ in cs35l56_system_resume_early()
1162 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_system_resume_early()
1176 * We might have done a hard reset or the CS35L56 was power-cycled in cs35l56_system_resume()
1181 /* Undo pm_runtime_force_suspend() before re-enabling the irq */ in cs35l56_system_resume()
1183 if (cs35l56->base.irq) in cs35l56_system_resume()
1184 enable_irq(cs35l56->base.irq); in cs35l56_system_resume()
1190 if (!cs35l56->component) in cs35l56_system_resume()
1193 ret = cs35l56_is_fw_reload_needed(&cs35l56->base); in cs35l56_system_resume()
1194 dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret); in cs35l56_system_resume()
1198 cs35l56->base.fw_patched = false; in cs35l56_system_resume()
1199 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_system_resume()
1200 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_system_resume()
1204 * a BIAS_OFF->BIAS_STANDBY transition to complete dsp patching. in cs35l56_system_resume()
1216 cs35l56->dsp_wq = create_singlethread_workqueue("cs35l56-dsp"); in cs35l56_dsp_init()
1217 if (!cs35l56->dsp_wq) in cs35l56_dsp_init()
1218 return -ENOMEM; in cs35l56_dsp_init()
1220 INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work); in cs35l56_dsp_init()
1222 dsp = &cs35l56->dsp; in cs35l56_dsp_init()
1223 cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp); in cs35l56_dsp_init()
1224 dsp->part = "cs35l56"; in cs35l56_dsp_init()
1225 dsp->fw = 12; in cs35l56_dsp_init()
1226 dsp->wmfw_optional = true; in cs35l56_dsp_init()
1228 dev_dbg(cs35l56->base.dev, "DSP system name: '%s'\n", dsp->system_name); in cs35l56_dsp_init()
1232 dev_err(cs35l56->base.dev, "wm_halo_init failed\n"); in cs35l56_dsp_init()
1241 struct device *dev = cs35l56->base.dev; in cs35l56_get_firmware_uid()
1245 ret = device_property_read_string(dev, "cirrus,firmware-uid", &prop); in cs35l56_get_firmware_uid()
1251 if (cs35l56->speaker_id >= 0) in cs35l56_get_firmware_uid()
1252 cs35l56->dsp.system_name = devm_kasprintf(dev, GFP_KERNEL, "%s-spkid%d", in cs35l56_get_firmware_uid()
1253 prop, cs35l56->speaker_id); in cs35l56_get_firmware_uid()
1255 cs35l56->dsp.system_name = devm_kstrdup(dev, prop, GFP_KERNEL); in cs35l56_get_firmware_uid()
1257 if (cs35l56->dsp.system_name == NULL) in cs35l56_get_firmware_uid()
1258 return -ENOMEM; in cs35l56_get_firmware_uid()
1260 dev_dbg(dev, "Firmware UID: %s\n", cs35l56->dsp.system_name); in cs35l56_get_firmware_uid()
1266 * Some SoundWire laptops have a spk-id-gpios property but it points to
1273 { "spk-id-gpios", &cs35l56_af01_first_gpio, 1 },
1290 af01_fwnode = device_get_named_child_node(cs35l56->base.dev, "AF01"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1292 dev_dbg(cs35l56->base.dev, "No AF01 node\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1293 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1296 ret = acpi_dev_get_property(ACPI_COMPANION(cs35l56->base.dev), in cs35l56_try_get_broken_sdca_spkid_gpio()
1297 "spk-id-gpios", ACPI_TYPE_PACKAGE, &obj); in cs35l56_try_get_broken_sdca_spkid_gpio()
1299 dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret); in cs35l56_try_get_broken_sdca_spkid_gpio()
1300 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1303 /* The broken properties we can handle are a 4-element package (one GPIO) */ in cs35l56_try_get_broken_sdca_spkid_gpio()
1304 if (obj->package.count != 4) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1305 dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n", in cs35l56_try_get_broken_sdca_spkid_gpio()
1306 obj->package.count); in cs35l56_try_get_broken_sdca_spkid_gpio()
1307 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1311 if (!fwnode_property_present(af01_fwnode, "spk-id-gpios")) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1321 return dev_err_probe(cs35l56->base.dev, ret, in cs35l56_try_get_broken_sdca_spkid_gpio()
1325 ret = devm_add_action_or_reset(cs35l56->base.dev, in cs35l56_try_get_broken_sdca_spkid_gpio()
1331 dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1334 desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL); in cs35l56_try_get_broken_sdca_spkid_gpio()
1337 return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1344 dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1348 dev_info(cs35l56->base.dev, "Got spk-id from AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1357 init_completion(&cs35l56->init_completion); in cs35l56_common_probe()
1358 mutex_init(&cs35l56->base.irq_lock); in cs35l56_common_probe()
1359 cs35l56->speaker_id = -ENOENT; in cs35l56_common_probe()
1361 dev_set_drvdata(cs35l56->base.dev, cs35l56); in cs35l56_common_probe()
1363 cs35l56_fill_supply_names(cs35l56->supplies); in cs35l56_common_probe()
1364 ret = devm_regulator_bulk_get(cs35l56->base.dev, ARRAY_SIZE(cs35l56->supplies), in cs35l56_common_probe()
1365 cs35l56->supplies); in cs35l56_common_probe()
1367 return dev_err_probe(cs35l56->base.dev, ret, "Failed to request supplies\n"); in cs35l56_common_probe()
1369 /* Reset could be controlled by the BIOS or shared by multiple amps */ in cs35l56_common_probe()
1370 cs35l56->base.reset_gpio = devm_gpiod_get_optional(cs35l56->base.dev, "reset", in cs35l56_common_probe()
1372 if (IS_ERR(cs35l56->base.reset_gpio)) { in cs35l56_common_probe()
1373 ret = PTR_ERR(cs35l56->base.reset_gpio); in cs35l56_common_probe()
1375 * If RESET is shared the first amp to probe will grab the reset in cs35l56_common_probe()
1376 * line and reset all the amps in cs35l56_common_probe()
1378 if (ret != -EBUSY) in cs35l56_common_probe()
1379 return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n"); in cs35l56_common_probe()
1381 dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n"); in cs35l56_common_probe()
1382 cs35l56->base.reset_gpio = NULL; in cs35l56_common_probe()
1385 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1387 return dev_err_probe(cs35l56->base.dev, ret, "Failed to enable supplies\n"); in cs35l56_common_probe()
1389 if (cs35l56->base.reset_gpio) { in cs35l56_common_probe()
1391 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1393 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_common_probe()
1396 ret = cs35l56_get_speaker_id(&cs35l56->base); in cs35l56_common_probe()
1397 if (ACPI_COMPANION(cs35l56->base.dev) && cs35l56->sdw_peripheral && (ret == -ENOENT)) in cs35l56_common_probe()
1400 if ((ret < 0) && (ret != -ENOENT)) in cs35l56_common_probe()
1403 cs35l56->speaker_id = ret; in cs35l56_common_probe()
1411 dev_err_probe(cs35l56->base.dev, ret, "DSP init failed\n"); in cs35l56_common_probe()
1415 ret = devm_snd_soc_register_component(cs35l56->base.dev, in cs35l56_common_probe()
1419 dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n"); in cs35l56_common_probe()
1426 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1427 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1438 * Check whether the actions associated with soft reset or one time in cs35l56_init()
1441 if (cs35l56->soft_resetting) in cs35l56_init()
1444 if (cs35l56->base.init_done) in cs35l56_init()
1447 pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 100); in cs35l56_init()
1448 pm_runtime_use_autosuspend(cs35l56->base.dev); in cs35l56_init()
1449 pm_runtime_set_active(cs35l56->base.dev); in cs35l56_init()
1450 pm_runtime_enable(cs35l56->base.dev); in cs35l56_init()
1452 ret = cs35l56_hw_init(&cs35l56->base); in cs35l56_init()
1456 ret = cs35l56_set_patch(&cs35l56->base); in cs35l56_init()
1460 if (!cs35l56->base.reset_gpio) { in cs35l56_init()
1461 dev_dbg(cs35l56->base.dev, "No reset gpio: using soft reset\n"); in cs35l56_init()
1462 cs35l56->soft_resetting = true; in cs35l56_init()
1463 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_init()
1464 if (cs35l56->sdw_peripheral) { in cs35l56_init()
1465 /* Keep alive while we wait for re-enumeration */ in cs35l56_init()
1466 pm_runtime_get_noresume(cs35l56->base.dev); in cs35l56_init()
1472 if (cs35l56->soft_resetting) { in cs35l56_init()
1473 cs35l56->soft_resetting = false; in cs35l56_init()
1475 /* Done re-enumerating after one-time init so release the keep-alive */ in cs35l56_init()
1476 if (cs35l56->sdw_peripheral && !cs35l56->base.init_done) in cs35l56_init()
1477 pm_runtime_put_noidle(cs35l56->base.dev); in cs35l56_init()
1479 regcache_mark_dirty(cs35l56->base.regmap); in cs35l56_init()
1480 ret = cs35l56_wait_for_firmware_boot(&cs35l56->base); in cs35l56_init()
1484 dev_dbg(cs35l56->base.dev, "Firmware rebooted after soft reset\n"); in cs35l56_init()
1487 /* Disable auto-hibernate so that runtime_pm has control */ in cs35l56_init()
1488 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE); in cs35l56_init()
1492 /* Registers could be dirty after soft reset or SoundWire enumeration */ in cs35l56_init()
1493 regcache_sync(cs35l56->base.regmap); in cs35l56_init()
1495 /* Set ASP1 DOUT to high-impedance when it is not transmitting audio data. */ in cs35l56_init()
1496 ret = regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_init()
1499 return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n"); in cs35l56_init()
1501 cs35l56->base.init_done = true; in cs35l56_init()
1502 complete(&cs35l56->init_completion); in cs35l56_init()
1510 cs35l56->base.init_done = false; in cs35l56_remove()
1516 if (cs35l56->base.irq) in cs35l56_remove()
1517 devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base); in cs35l56_remove()
1519 flush_workqueue(cs35l56->dsp_wq); in cs35l56_remove()
1520 destroy_workqueue(cs35l56->dsp_wq); in cs35l56_remove()
1522 pm_runtime_dont_use_autosuspend(cs35l56->base.dev); in cs35l56_remove()
1523 pm_runtime_suspend(cs35l56->base.dev); in cs35l56_remove()
1524 pm_runtime_disable(cs35l56->base.dev); in cs35l56_remove()
1526 regcache_cache_only(cs35l56->base.regmap, true); in cs35l56_remove()
1528 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_remove()
1529 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_remove()