Lines Matching +full:imon +full:- +full:slot +full:- +full:no
1 // SPDX-License-Identifier: GPL-2.0-only
27 #include <sound/cs-amp-lib.h>
31 #include <sound/soc-dapm.h>
43 flush_work(&cs35l56->dsp_work); in cs35l56_wait_dsp_ready()
66 static DECLARE_TLV_DB_SCALE(vol_tlv, -10000, 25, 0);
181 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_play_event()
186 dev_dbg(cs35l56->base.dev, "play: %d\n", event); in cs35l56_play_event()
191 return regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, in cs35l56_play_event()
195 ret = regmap_read_poll_timeout(cs35l56->base.regmap, in cs35l56_play_event()
196 cs35l56->base.fw_reg->transducer_actual_ps, in cs35l56_play_event()
201 dev_err(cs35l56->base.dev, "PS0 wait failed: %d\n", ret); in cs35l56_play_event()
204 return cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE); in cs35l56_play_event()
247 SND_SOC_DAPM_SIGGEN("IMON ADC"),
259 { name" Source", "IMON", "IMON ADC" }, \
319 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_dsp_event()
322 dev_dbg(cs35l56->base.dev, "%s: %d\n", __func__, event); in cs35l56_dsp_event()
329 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); in cs35l56_asp_dai_set_fmt()
332 dev_dbg(cs35l56->base.dev, "%s: %#x\n", __func__, fmt); in cs35l56_asp_dai_set_fmt()
338 dev_err(cs35l56->base.dev, "Unsupported clock source mode\n"); in cs35l56_asp_dai_set_fmt()
339 return -EINVAL; in cs35l56_asp_dai_set_fmt()
345 cs35l56->tdm_mode = true; in cs35l56_asp_dai_set_fmt()
349 cs35l56->tdm_mode = false; in cs35l56_asp_dai_set_fmt()
352 dev_err(cs35l56->base.dev, "Unsupported DAI format\n"); in cs35l56_asp_dai_set_fmt()
353 return -EINVAL; in cs35l56_asp_dai_set_fmt()
369 dev_err(cs35l56->base.dev, "Invalid clock invert\n"); in cs35l56_asp_dai_set_fmt()
370 return -EINVAL; in cs35l56_asp_dai_set_fmt()
373 regmap_update_bits(cs35l56->base.regmap, in cs35l56_asp_dai_set_fmt()
379 /* Hi-Z DOUT in unused slots and when all TX are disabled */ in cs35l56_asp_dai_set_fmt()
380 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_asp_dai_set_fmt()
406 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_tdm_slot()
409 dev_dbg(cs35l56->base.dev, "tdm config cleared\n"); in cs35l56_asp_dai_set_tdm_slot()
410 cs35l56->asp_slot_width = 0; in cs35l56_asp_dai_set_tdm_slot()
411 cs35l56->asp_slot_count = 0; in cs35l56_asp_dai_set_tdm_slot()
416 dev_err(cs35l56->base.dev, "tdm invalid slot width %d\n", slot_width); in cs35l56_asp_dai_set_tdm_slot()
417 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
422 dev_err(cs35l56->base.dev, "tdm invalid slot count %d\n", slots); in cs35l56_asp_dai_set_tdm_slot()
423 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
426 cs35l56->asp_slot_width = (u8)slot_width; in cs35l56_asp_dai_set_tdm_slot()
427 cs35l56->asp_slot_count = (u8)slots; in cs35l56_asp_dai_set_tdm_slot()
437 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL1, in cs35l56_asp_dai_set_tdm_slot()
439 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL5, in cs35l56_asp_dai_set_tdm_slot()
442 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()
443 cs35l56->asp_slot_width, cs35l56->asp_slot_count, tx_mask, rx_mask); in cs35l56_asp_dai_set_tdm_slot()
452 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_hw_params()
457 if (cs35l56->asp_slot_width) in cs35l56_asp_dai_hw_params()
458 asp_width = cs35l56->asp_slot_width; in cs35l56_asp_dai_hw_params()
462 dev_dbg(cs35l56->base.dev, "%s: wl=%d, width=%d, rate=%d", in cs35l56_asp_dai_hw_params()
465 if (!cs35l56->sysclk_set) { in cs35l56_asp_dai_hw_params()
466 unsigned int slots = cs35l56->asp_slot_count; in cs35l56_asp_dai_hw_params()
474 if (!cs35l56->tdm_mode) in cs35l56_asp_dai_hw_params()
481 dev_err(cs35l56->base.dev, "%s: Invalid BCLK %u\n", __func__, bclk_freq); in cs35l56_asp_dai_hw_params()
482 return -EINVAL; in cs35l56_asp_dai_hw_params()
485 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_hw_params()
490 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_asp_dai_hw_params()
491 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
494 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL5, in cs35l56_asp_dai_hw_params()
497 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
500 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL1, in cs35l56_asp_dai_hw_params()
510 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_sysclk()
514 cs35l56->sysclk_set = false; in cs35l56_asp_dai_set_sysclk()
522 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_set_sysclk()
525 cs35l56->sysclk_set = true; in cs35l56_asp_dai_set_sysclk()
546 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_set_tdm_slot()
549 cs35l56->rx_mask = tx_mask; in cs35l56_sdw_dai_set_tdm_slot()
550 cs35l56->tx_mask = rx_mask; in cs35l56_sdw_dai_set_tdm_slot()
559 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_params()
565 dev_dbg(cs35l56->base.dev, "%s: rate %d\n", __func__, params_rate(params)); in cs35l56_sdw_dai_hw_params()
567 if (!cs35l56->base.init_done) in cs35l56_sdw_dai_hw_params()
568 return -ENODEV; in cs35l56_sdw_dai_hw_params()
571 return -EINVAL; in cs35l56_sdw_dai_hw_params()
579 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_sdw_dai_hw_params()
582 pconfig.ch_mask = cs35l56->rx_mask; in cs35l56_sdw_dai_hw_params()
586 pconfig.ch_mask = cs35l56->tx_mask; in cs35l56_sdw_dai_hw_params()
591 pconfig.ch_mask = GENMASK(sconfig.ch_count - 1, 0); in cs35l56_sdw_dai_hw_params()
596 ret = sdw_stream_add_slave(cs35l56->sdw_peripheral, &sconfig, &pconfig, in cs35l56_sdw_dai_hw_params()
599 dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret); in cs35l56_sdw_dai_hw_params()
609 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_free()
612 if (!cs35l56->sdw_peripheral) in cs35l56_sdw_dai_hw_free()
613 return -EINVAL; in cs35l56_sdw_dai_hw_free()
615 sdw_stream_remove_slave(cs35l56->sdw_peripheral, sdw_stream); in cs35l56_sdw_dai_hw_free()
638 .name = "cs35l56-asp1",
659 .name = "cs35l56-sdw1",
672 .name = "cs35l56-sdw1c",
690 if (cs35l56->base.secured || !cs35l56->base.cal_data_valid) in cs35l56_write_cal()
691 return -ENODATA; in cs35l56_write_cal()
693 ret = wm_adsp_run(&cs35l56->dsp); in cs35l56_write_cal()
697 ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, in cs35l56_write_cal()
699 &cs35l56->base.cal_data); in cs35l56_write_cal()
701 wm_adsp_stop(&cs35l56->dsp); in cs35l56_write_cal()
704 dev_info(cs35l56->base.dev, "Calibration applied\n"); in cs35l56_write_cal()
718 cs35l56->dsp.bin_mandatory = (load_firmware && cs35l56->fallback_fw_suffix); in cs35l56_dsp_download_and_power_up()
720 ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware); in cs35l56_dsp_download_and_power_up()
721 if ((ret == -ENOENT) && cs35l56->dsp.bin_mandatory) { in cs35l56_dsp_download_and_power_up()
722 cs35l56->dsp.fwf_suffix = cs35l56->fallback_fw_suffix; in cs35l56_dsp_download_and_power_up()
723 cs35l56->fallback_fw_suffix = NULL; in cs35l56_dsp_download_and_power_up()
724 cs35l56->dsp.bin_mandatory = false; in cs35l56_dsp_download_and_power_up()
725 ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware); in cs35l56_dsp_download_and_power_up()
729 dev_dbg(cs35l56->base.dev, "wm_adsp_power_up ret %d\n", ret); in cs35l56_dsp_download_and_power_up()
747 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); in cs35l56_reinit_patch()
756 * Setting sdw_irq_no_unmask prevents the handler re-enabling in cs35l56_patch()
759 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
760 cs35l56->sdw_irq_no_unmask = true; in cs35l56_patch()
761 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
762 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0); in cs35l56_patch()
763 sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1); in cs35l56_patch()
764 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF); in cs35l56_patch()
765 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
768 ret = cs35l56_firmware_shutdown(&cs35l56->base); in cs35l56_patch()
775 * power-up wm_adsp without downloading firmware. in cs35l56_patch()
781 mutex_lock(&cs35l56->base.irq_lock); in cs35l56_patch()
783 reinit_completion(&cs35l56->init_completion); in cs35l56_patch()
785 cs35l56->soft_resetting = true; in cs35l56_patch()
786 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_patch()
788 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
790 * The system-reset causes the CS35L56 to detach from the bus. in cs35l56_patch()
791 * Wait for the manager to re-enumerate the CS35L56 and in cs35l56_patch()
794 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_patch()
796 dev_err(cs35l56->base.dev, "%s: init_completion timed out (SDW)\n", in cs35l56_patch()
804 regmap_clear_bits(cs35l56->base.regmap, in cs35l56_patch()
805 cs35l56->base.fw_reg->prot_sts, in cs35l56_patch()
807 cs35l56->base.fw_patched = true; in cs35l56_patch()
810 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); in cs35l56_patch()
813 mutex_unlock(&cs35l56->base.irq_lock); in cs35l56_patch()
815 /* Re-enable SoundWire interrupts */ in cs35l56_patch()
816 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
817 cs35l56->sdw_irq_no_unmask = false; in cs35l56_patch()
818 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, in cs35l56_patch()
832 if (!cs35l56->base.init_done) in cs35l56_dsp_work()
835 pm_runtime_get_sync(cs35l56->base.dev); in cs35l56_dsp_work()
837 ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version); in cs35l56_dsp_work()
842 kfree(cs35l56->dsp.fwf_name); in cs35l56_dsp_work()
844 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, "%02x-dsp1", cs35l56->base.rev); in cs35l56_dsp_work()
847 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, in cs35l56_dsp_work()
848 "%02x%s-%06x-dsp1", in cs35l56_dsp_work()
849 cs35l56->base.rev, in cs35l56_dsp_work()
850 cs35l56->base.secured ? "-s" : "", in cs35l56_dsp_work()
854 if (!cs35l56->dsp.fwf_name) in cs35l56_dsp_work()
857 dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n", in cs35l56_dsp_work()
858 cs35l56->dsp.fwf_name, cs35l56->dsp.system_name); in cs35l56_dsp_work()
872 cs35l56_log_tuning(&cs35l56->base, &cs35l56->dsp.cs_dsp); in cs35l56_dsp_work()
874 pm_runtime_mark_last_busy(cs35l56->base.dev); in cs35l56_dsp_work()
875 pm_runtime_put_autosuspend(cs35l56->base.dev); in cs35l56_dsp_work()
880 if (cs35l56->dsp.fwf_suffix) in cs35l56_set_fw_suffix()
883 if (!cs35l56->sdw_peripheral) in cs35l56_set_fw_suffix()
886 cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, in cs35l56_set_fw_suffix()
888 cs35l56->sdw_link_num, in cs35l56_set_fw_suffix()
889 cs35l56->sdw_unique_id); in cs35l56_set_fw_suffix()
890 if (!cs35l56->dsp.fwf_suffix) in cs35l56_set_fw_suffix()
891 return -ENOMEM; in cs35l56_set_fw_suffix()
898 if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0)) { in cs35l56_set_fw_suffix()
899 cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix; in cs35l56_set_fw_suffix()
900 cs35l56->dsp.fwf_suffix = cs35l56->component->name_prefix; in cs35l56_set_fw_suffix()
909 struct dentry *debugfs_root = component->debugfs_root; in cs35l56_component_probe()
915 if (!cs35l56->dsp.system_name && in cs35l56_component_probe()
916 (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) { in cs35l56_component_probe()
918 if (cs35l56->speaker_id >= 0) { in cs35l56_component_probe()
919 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
921 "%04x%04x-spkid%d", in cs35l56_component_probe()
923 cs35l56->speaker_id); in cs35l56_component_probe()
925 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
930 if (!cs35l56->dsp.system_name) in cs35l56_component_probe()
931 return -ENOMEM; in cs35l56_component_probe()
934 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_component_probe()
936 dev_err(cs35l56->base.dev, "%s: init_completion timed out\n", __func__); in cs35l56_component_probe()
937 return -ENODEV; in cs35l56_component_probe()
940 cs35l56->dsp.part = kasprintf(GFP_KERNEL, "cs35l%02x", cs35l56->base.type); in cs35l56_component_probe()
941 if (!cs35l56->dsp.part) in cs35l56_component_probe()
942 return -ENOMEM; in cs35l56_component_probe()
944 cs35l56->component = component; in cs35l56_component_probe()
949 wm_adsp2_component_probe(&cs35l56->dsp, component); in cs35l56_component_probe()
951 debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->base.init_done); in cs35l56_component_probe()
952 debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate); in cs35l56_component_probe()
953 debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched); in cs35l56_component_probe()
956 switch (cs35l56->base.type) { in cs35l56_component_probe()
968 ret = -ENODEV; in cs35l56_component_probe()
973 return dev_err_probe(cs35l56->base.dev, ret, "unable to add controls\n"); in cs35l56_component_probe()
975 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_component_probe()
984 cancel_work_sync(&cs35l56->dsp_work); in cs35l56_component_remove()
986 if (cs35l56->dsp.cs_dsp.booted) in cs35l56_component_remove()
987 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_component_remove()
989 wm_adsp2_component_remove(&cs35l56->dsp, component); in cs35l56_component_remove()
991 kfree(cs35l56->dsp.part); in cs35l56_component_remove()
992 cs35l56->dsp.part = NULL; in cs35l56_component_remove()
994 kfree(cs35l56->dsp.fwf_name); in cs35l56_component_remove()
995 cs35l56->dsp.fwf_name = NULL; in cs35l56_component_remove()
997 cs35l56->component = NULL; in cs35l56_component_remove()
1040 return cs35l56_runtime_suspend_common(&cs35l56->base); in cs35l56_runtime_suspend_i2c_spi()
1047 return cs35l56_runtime_resume_common(&cs35l56->base, false); in cs35l56_runtime_resume_i2c_spi()
1056 if (cs35l56->component) in cs35l56_system_suspend()
1057 flush_work(&cs35l56->dsp_work); in cs35l56_system_suspend()
1065 if (cs35l56->base.irq) in cs35l56_system_suspend()
1066 disable_irq(cs35l56->base.irq); in cs35l56_system_suspend()
1083 if (cs35l56->base.reset_gpio) { in cs35l56_system_suspend_late()
1084 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_suspend_late()
1088 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_suspend_late()
1100 /* Handlers are now disabled so the parent IRQ can safely be re-enabled. */ in cs35l56_system_suspend_no_irq()
1101 if (cs35l56->base.irq) in cs35l56_system_suspend_no_irq()
1102 enable_irq(cs35l56->base.irq); in cs35l56_system_suspend_no_irq()
1121 if (cs35l56->base.irq) in cs35l56_system_resume_no_irq()
1122 disable_irq(cs35l56->base.irq); in cs35l56_system_resume_no_irq()
1135 /* Ensure a spec-compliant RESET pulse. */ in cs35l56_system_resume_early()
1136 if (cs35l56->base.reset_gpio) { in cs35l56_system_resume_early()
1137 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_resume_early()
1142 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_resume_early()
1149 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_system_resume_early()
1163 * We might have done a hard reset or the CS35L56 was power-cycled in cs35l56_system_resume()
1168 /* Undo pm_runtime_force_suspend() before re-enabling the irq */ in cs35l56_system_resume()
1170 if (cs35l56->base.irq) in cs35l56_system_resume()
1171 enable_irq(cs35l56->base.irq); in cs35l56_system_resume()
1177 if (!cs35l56->component) in cs35l56_system_resume()
1180 ret = cs35l56_is_fw_reload_needed(&cs35l56->base); in cs35l56_system_resume()
1181 dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret); in cs35l56_system_resume()
1185 cs35l56->base.fw_patched = false; in cs35l56_system_resume()
1186 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_system_resume()
1187 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_system_resume()
1191 * a BIAS_OFF->BIAS_STANDBY transition to complete dsp patching. in cs35l56_system_resume()
1208 cs35l56->dsp_wq = create_singlethread_workqueue("cs35l56-dsp"); in cs35l56_dsp_init()
1209 if (!cs35l56->dsp_wq) in cs35l56_dsp_init()
1210 return -ENOMEM; in cs35l56_dsp_init()
1212 INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work); in cs35l56_dsp_init()
1214 dsp = &cs35l56->dsp; in cs35l56_dsp_init()
1215 cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp); in cs35l56_dsp_init()
1218 * dsp->part is filled in later as it is based on the DEVID. In a in cs35l56_dsp_init()
1222 dsp->fw = 12; in cs35l56_dsp_init()
1223 dsp->wmfw_optional = true; in cs35l56_dsp_init()
1226 * None of the firmware controls need to be exported so add a no-op in cs35l56_dsp_init()
1229 dsp->control_add = &cs35l56_control_add_nop; in cs35l56_dsp_init()
1231 dev_dbg(cs35l56->base.dev, "DSP system name: '%s'\n", dsp->system_name); in cs35l56_dsp_init()
1235 dev_err(cs35l56->base.dev, "wm_halo_init failed\n"); in cs35l56_dsp_init()
1244 struct device *dev = cs35l56->base.dev; in cs35l56_get_firmware_uid()
1248 ret = device_property_read_string(dev, "cirrus,firmware-uid", &prop); in cs35l56_get_firmware_uid()
1254 if (cs35l56->speaker_id >= 0) in cs35l56_get_firmware_uid()
1255 cs35l56->dsp.system_name = devm_kasprintf(dev, GFP_KERNEL, "%s-spkid%d", in cs35l56_get_firmware_uid()
1256 prop, cs35l56->speaker_id); in cs35l56_get_firmware_uid()
1258 cs35l56->dsp.system_name = devm_kstrdup(dev, prop, GFP_KERNEL); in cs35l56_get_firmware_uid()
1260 if (cs35l56->dsp.system_name == NULL) in cs35l56_get_firmware_uid()
1261 return -ENOMEM; in cs35l56_get_firmware_uid()
1263 dev_dbg(dev, "Firmware UID: %s\n", cs35l56->dsp.system_name); in cs35l56_get_firmware_uid()
1269 * Some SoundWire laptops have a spk-id-gpios property but it points to
1276 { "spk-id-gpios", &cs35l56_af01_first_gpio, 1 },
1293 af01_fwnode = device_get_named_child_node(cs35l56->base.dev, "AF01"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1295 dev_dbg(cs35l56->base.dev, "No AF01 node\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1296 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1299 ret = acpi_dev_get_property(ACPI_COMPANION(cs35l56->base.dev), in cs35l56_try_get_broken_sdca_spkid_gpio()
1300 "spk-id-gpios", ACPI_TYPE_PACKAGE, &obj); in cs35l56_try_get_broken_sdca_spkid_gpio()
1302 dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret); in cs35l56_try_get_broken_sdca_spkid_gpio()
1304 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1307 /* The broken properties we can handle are a 4-element package (one GPIO) */ in cs35l56_try_get_broken_sdca_spkid_gpio()
1308 if (obj->package.count != 4) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1309 dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n", in cs35l56_try_get_broken_sdca_spkid_gpio()
1310 obj->package.count); in cs35l56_try_get_broken_sdca_spkid_gpio()
1312 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1316 if (!fwnode_property_present(af01_fwnode, "spk-id-gpios")) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1327 return dev_err_probe(cs35l56->base.dev, ret, in cs35l56_try_get_broken_sdca_spkid_gpio()
1331 ret = devm_add_action_or_reset(cs35l56->base.dev, in cs35l56_try_get_broken_sdca_spkid_gpio()
1339 dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1342 desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL); in cs35l56_try_get_broken_sdca_spkid_gpio()
1346 return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1354 dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1360 dev_info(cs35l56->base.dev, "Got spk-id from AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1369 init_completion(&cs35l56->init_completion); in cs35l56_common_probe()
1370 mutex_init(&cs35l56->base.irq_lock); in cs35l56_common_probe()
1371 cs35l56->base.cal_index = -1; in cs35l56_common_probe()
1372 cs35l56->speaker_id = -ENOENT; in cs35l56_common_probe()
1374 dev_set_drvdata(cs35l56->base.dev, cs35l56); in cs35l56_common_probe()
1376 cs35l56_fill_supply_names(cs35l56->supplies); in cs35l56_common_probe()
1377 ret = devm_regulator_bulk_get(cs35l56->base.dev, ARRAY_SIZE(cs35l56->supplies), in cs35l56_common_probe()
1378 cs35l56->supplies); in cs35l56_common_probe()
1380 return dev_err_probe(cs35l56->base.dev, ret, "Failed to request supplies\n"); in cs35l56_common_probe()
1383 cs35l56->base.reset_gpio = devm_gpiod_get_optional(cs35l56->base.dev, "reset", in cs35l56_common_probe()
1385 if (IS_ERR(cs35l56->base.reset_gpio)) { in cs35l56_common_probe()
1386 ret = PTR_ERR(cs35l56->base.reset_gpio); in cs35l56_common_probe()
1391 if (ret != -EBUSY) in cs35l56_common_probe()
1392 return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n"); in cs35l56_common_probe()
1394 dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n"); in cs35l56_common_probe()
1395 cs35l56->base.reset_gpio = NULL; in cs35l56_common_probe()
1398 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1400 return dev_err_probe(cs35l56->base.dev, ret, "Failed to enable supplies\n"); in cs35l56_common_probe()
1402 if (cs35l56->base.reset_gpio) { in cs35l56_common_probe()
1404 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1406 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_common_probe()
1409 ret = cs35l56_get_speaker_id(&cs35l56->base); in cs35l56_common_probe()
1410 if (ACPI_COMPANION(cs35l56->base.dev) && cs35l56->sdw_peripheral && (ret == -ENOENT)) in cs35l56_common_probe()
1413 if ((ret < 0) && (ret != -ENOENT)) in cs35l56_common_probe()
1416 cs35l56->speaker_id = ret; in cs35l56_common_probe()
1424 dev_err_probe(cs35l56->base.dev, ret, "DSP init failed\n"); in cs35l56_common_probe()
1428 ret = devm_snd_soc_register_component(cs35l56->base.dev, in cs35l56_common_probe()
1432 dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n"); in cs35l56_common_probe()
1439 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1440 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1454 if (cs35l56->soft_resetting) in cs35l56_init()
1457 if (cs35l56->base.init_done) in cs35l56_init()
1460 pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 100); in cs35l56_init()
1461 pm_runtime_use_autosuspend(cs35l56->base.dev); in cs35l56_init()
1462 pm_runtime_set_active(cs35l56->base.dev); in cs35l56_init()
1463 pm_runtime_enable(cs35l56->base.dev); in cs35l56_init()
1465 ret = cs35l56_hw_init(&cs35l56->base); in cs35l56_init()
1469 ret = cs35l56_set_patch(&cs35l56->base); in cs35l56_init()
1473 ret = cs35l56_get_calibration(&cs35l56->base); in cs35l56_init()
1477 if (!cs35l56->base.reset_gpio) { in cs35l56_init()
1478 dev_dbg(cs35l56->base.dev, "No reset gpio: using soft reset\n"); in cs35l56_init()
1479 cs35l56->soft_resetting = true; in cs35l56_init()
1480 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_init()
1481 if (cs35l56->sdw_peripheral) { in cs35l56_init()
1482 /* Keep alive while we wait for re-enumeration */ in cs35l56_init()
1483 pm_runtime_get_noresume(cs35l56->base.dev); in cs35l56_init()
1489 if (cs35l56->soft_resetting) { in cs35l56_init()
1490 cs35l56->soft_resetting = false; in cs35l56_init()
1492 /* Done re-enumerating after one-time init so release the keep-alive */ in cs35l56_init()
1493 if (cs35l56->sdw_peripheral && !cs35l56->base.init_done) in cs35l56_init()
1494 pm_runtime_put_noidle(cs35l56->base.dev); in cs35l56_init()
1496 regcache_mark_dirty(cs35l56->base.regmap); in cs35l56_init()
1497 ret = cs35l56_wait_for_firmware_boot(&cs35l56->base); in cs35l56_init()
1501 dev_dbg(cs35l56->base.dev, "Firmware rebooted after soft reset\n"); in cs35l56_init()
1503 regcache_cache_only(cs35l56->base.regmap, false); in cs35l56_init()
1506 /* Disable auto-hibernate so that runtime_pm has control */ in cs35l56_init()
1507 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE); in cs35l56_init()
1512 regcache_sync(cs35l56->base.regmap); in cs35l56_init()
1514 /* Set ASP1 DOUT to high-impedance when it is not transmitting audio data. */ in cs35l56_init()
1515 ret = regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_init()
1518 return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n"); in cs35l56_init()
1520 cs35l56->base.init_done = true; in cs35l56_init()
1521 complete(&cs35l56->init_completion); in cs35l56_init()
1529 cs35l56->base.init_done = false; in cs35l56_remove()
1535 if (cs35l56->base.irq) in cs35l56_remove()
1536 devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base); in cs35l56_remove()
1538 destroy_workqueue(cs35l56->dsp_wq); in cs35l56_remove()
1540 pm_runtime_dont_use_autosuspend(cs35l56->base.dev); in cs35l56_remove()
1541 pm_runtime_suspend(cs35l56->base.dev); in cs35l56_remove()
1542 pm_runtime_disable(cs35l56->base.dev); in cs35l56_remove()
1544 regcache_cache_only(cs35l56->base.regmap, true); in cs35l56_remove()
1546 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_remove()
1547 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_remove()