Lines Matching +full:dsp +full:- +full:reset
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);
162 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_play_event()
167 dev_dbg(cs35l56->base.dev, "play: %d\n", event); in cs35l56_play_event()
172 return regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, in cs35l56_play_event()
176 ret = regmap_read_poll_timeout(cs35l56->base.regmap, in cs35l56_play_event()
182 dev_err(cs35l56->base.dev, "PS0 wait failed: %d\n", ret); in cs35l56_play_event()
185 return cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE); in cs35l56_play_event()
300 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cs35l56_dsp_event()
303 dev_dbg(cs35l56->base.dev, "%s: %d\n", __func__, event); in cs35l56_dsp_event()
310 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); in cs35l56_asp_dai_set_fmt()
313 dev_dbg(cs35l56->base.dev, "%s: %#x\n", __func__, fmt); in cs35l56_asp_dai_set_fmt()
319 dev_err(cs35l56->base.dev, "Unsupported clock source mode\n"); in cs35l56_asp_dai_set_fmt()
320 return -EINVAL; in cs35l56_asp_dai_set_fmt()
326 cs35l56->tdm_mode = true; in cs35l56_asp_dai_set_fmt()
330 cs35l56->tdm_mode = false; in cs35l56_asp_dai_set_fmt()
333 dev_err(cs35l56->base.dev, "Unsupported DAI format\n"); in cs35l56_asp_dai_set_fmt()
334 return -EINVAL; in cs35l56_asp_dai_set_fmt()
350 dev_err(cs35l56->base.dev, "Invalid clock invert\n"); in cs35l56_asp_dai_set_fmt()
351 return -EINVAL; in cs35l56_asp_dai_set_fmt()
354 regmap_update_bits(cs35l56->base.regmap, in cs35l56_asp_dai_set_fmt()
360 /* Hi-Z DOUT in unused slots and when all TX are disabled */ in cs35l56_asp_dai_set_fmt()
361 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_asp_dai_set_fmt()
387 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_tdm_slot()
390 dev_dbg(cs35l56->base.dev, "tdm config cleared\n"); in cs35l56_asp_dai_set_tdm_slot()
391 cs35l56->asp_slot_width = 0; in cs35l56_asp_dai_set_tdm_slot()
392 cs35l56->asp_slot_count = 0; in cs35l56_asp_dai_set_tdm_slot()
397 dev_err(cs35l56->base.dev, "tdm invalid slot width %d\n", slot_width); in cs35l56_asp_dai_set_tdm_slot()
398 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
403 dev_err(cs35l56->base.dev, "tdm invalid slot count %d\n", slots); in cs35l56_asp_dai_set_tdm_slot()
404 return -EINVAL; in cs35l56_asp_dai_set_tdm_slot()
407 cs35l56->asp_slot_width = (u8)slot_width; in cs35l56_asp_dai_set_tdm_slot()
408 cs35l56->asp_slot_count = (u8)slots; in cs35l56_asp_dai_set_tdm_slot()
418 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL1, in cs35l56_asp_dai_set_tdm_slot()
420 regmap_write(cs35l56->base.regmap, CS35L56_ASP1_FRAME_CONTROL5, in cs35l56_asp_dai_set_tdm_slot()
423 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()
424 cs35l56->asp_slot_width, cs35l56->asp_slot_count, tx_mask, rx_mask); in cs35l56_asp_dai_set_tdm_slot()
433 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_hw_params()
438 if (cs35l56->asp_slot_width) in cs35l56_asp_dai_hw_params()
439 asp_width = cs35l56->asp_slot_width; in cs35l56_asp_dai_hw_params()
443 dev_dbg(cs35l56->base.dev, "%s: wl=%d, width=%d, rate=%d", in cs35l56_asp_dai_hw_params()
446 if (!cs35l56->sysclk_set) { in cs35l56_asp_dai_hw_params()
447 unsigned int slots = cs35l56->asp_slot_count; in cs35l56_asp_dai_hw_params()
455 if (!cs35l56->tdm_mode) in cs35l56_asp_dai_hw_params()
462 dev_err(cs35l56->base.dev, "%s: Invalid BCLK %u\n", __func__, bclk_freq); in cs35l56_asp_dai_hw_params()
463 return -EINVAL; in cs35l56_asp_dai_hw_params()
466 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_hw_params()
471 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_asp_dai_hw_params()
472 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
475 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL5, in cs35l56_asp_dai_hw_params()
478 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL2, in cs35l56_asp_dai_hw_params()
481 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_DATA_CONTROL1, in cs35l56_asp_dai_hw_params()
491 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_asp_dai_set_sysclk()
495 cs35l56->sysclk_set = false; in cs35l56_asp_dai_set_sysclk()
503 regmap_update_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL1, in cs35l56_asp_dai_set_sysclk()
506 cs35l56->sysclk_set = true; in cs35l56_asp_dai_set_sysclk()
527 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_set_tdm_slot()
530 cs35l56->rx_mask = tx_mask; in cs35l56_sdw_dai_set_tdm_slot()
531 cs35l56->tx_mask = rx_mask; in cs35l56_sdw_dai_set_tdm_slot()
540 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_params()
546 dev_dbg(cs35l56->base.dev, "%s: rate %d\n", __func__, params_rate(params)); in cs35l56_sdw_dai_hw_params()
548 if (!cs35l56->base.init_done) in cs35l56_sdw_dai_hw_params()
549 return -ENODEV; in cs35l56_sdw_dai_hw_params()
552 return -EINVAL; in cs35l56_sdw_dai_hw_params()
560 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in cs35l56_sdw_dai_hw_params()
563 pconfig.ch_mask = cs35l56->rx_mask; in cs35l56_sdw_dai_hw_params()
567 pconfig.ch_mask = cs35l56->tx_mask; in cs35l56_sdw_dai_hw_params()
572 pconfig.ch_mask = GENMASK(sconfig.ch_count - 1, 0); in cs35l56_sdw_dai_hw_params()
577 ret = sdw_stream_add_slave(cs35l56->sdw_peripheral, &sconfig, &pconfig, in cs35l56_sdw_dai_hw_params()
580 dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret); in cs35l56_sdw_dai_hw_params()
590 struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(dai->component); in cs35l56_sdw_dai_hw_free()
593 if (!cs35l56->sdw_peripheral) in cs35l56_sdw_dai_hw_free()
594 return -EINVAL; in cs35l56_sdw_dai_hw_free()
596 sdw_stream_remove_slave(cs35l56->sdw_peripheral, sdw_stream); in cs35l56_sdw_dai_hw_free()
619 .name = "cs35l56-asp1",
640 .name = "cs35l56-sdw1",
665 if (cs35l56->base.secured || !cs35l56->base.cal_data_valid) in cs35l56_write_cal()
666 return -ENODATA; in cs35l56_write_cal()
668 ret = wm_adsp_run(&cs35l56->dsp); in cs35l56_write_cal()
672 ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, in cs35l56_write_cal()
674 &cs35l56->base.cal_data); in cs35l56_write_cal()
676 wm_adsp_stop(&cs35l56->dsp); in cs35l56_write_cal()
679 dev_info(cs35l56->base.dev, "Calibration applied\n"); in cs35l56_write_cal()
689 ret = wm_adsp_power_up(&cs35l56->dsp, true); in cs35l56_reinit_patch()
691 dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); in cs35l56_reinit_patch()
698 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); in cs35l56_reinit_patch()
707 * Setting sdw_irq_no_unmask prevents the handler re-enabling in cs35l56_patch()
710 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
711 cs35l56->sdw_irq_no_unmask = true; in cs35l56_patch()
712 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
713 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0); in cs35l56_patch()
714 sdw_read_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1); in cs35l56_patch()
715 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF); in cs35l56_patch()
716 flush_work(&cs35l56->sdw_irq_work); in cs35l56_patch()
719 ret = cs35l56_firmware_shutdown(&cs35l56->base); in cs35l56_patch()
726 * power-up wm_adsp without downloading firmware. in cs35l56_patch()
728 ret = wm_adsp_power_up(&cs35l56->dsp, !!firmware_missing); in cs35l56_patch()
730 dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); in cs35l56_patch()
734 mutex_lock(&cs35l56->base.irq_lock); in cs35l56_patch()
736 reinit_completion(&cs35l56->init_completion); in cs35l56_patch()
738 cs35l56->soft_resetting = true; in cs35l56_patch()
739 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_patch()
741 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
743 * The system-reset causes the CS35L56 to detach from the bus. in cs35l56_patch()
744 * Wait for the manager to re-enumerate the CS35L56 and in cs35l56_patch()
747 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_patch()
749 dev_err(cs35l56->base.dev, "%s: init_completion timed out (SDW)\n", in cs35l56_patch()
757 regmap_clear_bits(cs35l56->base.regmap, CS35L56_PROTECTION_STATUS, in cs35l56_patch()
759 cs35l56->base.fw_patched = true; in cs35l56_patch()
762 cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); in cs35l56_patch()
765 mutex_unlock(&cs35l56->base.irq_lock); in cs35l56_patch()
767 /* Re-enable SoundWire interrupts */ in cs35l56_patch()
768 if (cs35l56->sdw_peripheral) { in cs35l56_patch()
769 cs35l56->sdw_irq_no_unmask = false; in cs35l56_patch()
770 sdw_write_no_pm(cs35l56->sdw_peripheral, CS35L56_SDW_GEN_INT_MASK_1, in cs35l56_patch()
784 if (!cs35l56->base.init_done) in cs35l56_dsp_work()
787 pm_runtime_get_sync(cs35l56->base.dev); in cs35l56_dsp_work()
789 ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version); in cs35l56_dsp_work()
794 kfree(cs35l56->dsp.fwf_name); in cs35l56_dsp_work()
796 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, "%02x-dsp1", cs35l56->base.rev); in cs35l56_dsp_work()
799 cs35l56->dsp.fwf_name = kasprintf(GFP_KERNEL, in cs35l56_dsp_work()
800 "%02x%s-%06x-dsp1", in cs35l56_dsp_work()
801 cs35l56->base.rev, in cs35l56_dsp_work()
802 cs35l56->base.secured ? "-s" : "", in cs35l56_dsp_work()
806 if (!cs35l56->dsp.fwf_name) in cs35l56_dsp_work()
809 dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n", in cs35l56_dsp_work()
810 cs35l56->dsp.fwf_name, cs35l56->dsp.system_name); in cs35l56_dsp_work()
825 pm_runtime_mark_last_busy(cs35l56->base.dev); in cs35l56_dsp_work()
826 pm_runtime_put_autosuspend(cs35l56->base.dev); in cs35l56_dsp_work()
832 struct dentry *debugfs_root = component->debugfs_root; in cs35l56_component_probe()
837 if (!cs35l56->dsp.system_name && in cs35l56_component_probe()
838 (snd_soc_card_get_pci_ssid(component->card, &vendor, &device) == 0)) { in cs35l56_component_probe()
840 if (cs35l56->speaker_id >= 0) { in cs35l56_component_probe()
841 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
843 "%04x%04x-spkid%d", in cs35l56_component_probe()
845 cs35l56->speaker_id); in cs35l56_component_probe()
847 cs35l56->dsp.system_name = devm_kasprintf(cs35l56->base.dev, in cs35l56_component_probe()
852 if (!cs35l56->dsp.system_name) in cs35l56_component_probe()
853 return -ENOMEM; in cs35l56_component_probe()
856 if (!wait_for_completion_timeout(&cs35l56->init_completion, in cs35l56_component_probe()
858 dev_err(cs35l56->base.dev, "%s: init_completion timed out\n", __func__); in cs35l56_component_probe()
859 return -ENODEV; in cs35l56_component_probe()
862 cs35l56->dsp.part = kasprintf(GFP_KERNEL, "cs35l%02x", cs35l56->base.type); in cs35l56_component_probe()
863 if (!cs35l56->dsp.part) in cs35l56_component_probe()
864 return -ENOMEM; in cs35l56_component_probe()
866 cs35l56->component = component; in cs35l56_component_probe()
867 wm_adsp2_component_probe(&cs35l56->dsp, component); in cs35l56_component_probe()
869 debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->base.init_done); in cs35l56_component_probe()
870 debugfs_create_bool("can_hibernate", 0444, debugfs_root, &cs35l56->base.can_hibernate); in cs35l56_component_probe()
871 debugfs_create_bool("fw_patched", 0444, debugfs_root, &cs35l56->base.fw_patched); in cs35l56_component_probe()
873 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_component_probe()
882 cancel_work_sync(&cs35l56->dsp_work); in cs35l56_component_remove()
884 if (cs35l56->dsp.cs_dsp.booted) in cs35l56_component_remove()
885 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_component_remove()
887 wm_adsp2_component_remove(&cs35l56->dsp, component); in cs35l56_component_remove()
889 kfree(cs35l56->dsp.part); in cs35l56_component_remove()
890 cs35l56->dsp.part = NULL; in cs35l56_component_remove()
892 kfree(cs35l56->dsp.fwf_name); in cs35l56_component_remove()
893 cs35l56->dsp.fwf_name = NULL; in cs35l56_component_remove()
895 cs35l56->component = NULL; in cs35l56_component_remove()
940 return cs35l56_runtime_suspend_common(&cs35l56->base); in cs35l56_runtime_suspend_i2c_spi()
947 return cs35l56_runtime_resume_common(&cs35l56->base, false); in cs35l56_runtime_resume_i2c_spi()
956 if (cs35l56->component) in cs35l56_system_suspend()
957 flush_work(&cs35l56->dsp_work); in cs35l56_system_suspend()
965 if (cs35l56->base.irq) in cs35l56_system_suspend()
966 disable_irq(cs35l56->base.irq); in cs35l56_system_suspend()
979 * Assert RESET before removing supplies. in cs35l56_system_suspend_late()
980 * RESET is usually shared by all amps so it must not be asserted until in cs35l56_system_suspend_late()
983 if (cs35l56->base.reset_gpio) { in cs35l56_system_suspend_late()
984 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_suspend_late()
988 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_suspend_late()
1000 /* Handlers are now disabled so the parent IRQ can safely be re-enabled. */ in cs35l56_system_suspend_no_irq()
1001 if (cs35l56->base.irq) in cs35l56_system_suspend_no_irq()
1002 enable_irq(cs35l56->base.irq); in cs35l56_system_suspend_no_irq()
1021 if (cs35l56->base.irq) in cs35l56_system_resume_no_irq()
1022 disable_irq(cs35l56->base.irq); in cs35l56_system_resume_no_irq()
1035 /* Ensure a spec-compliant RESET pulse. */ in cs35l56_system_resume_early()
1036 if (cs35l56->base.reset_gpio) { in cs35l56_system_resume_early()
1037 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_system_resume_early()
1041 /* Enable supplies before releasing RESET. */ in cs35l56_system_resume_early()
1042 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_system_resume_early()
1048 /* Release shared RESET before drivers start resume(). */ in cs35l56_system_resume_early()
1049 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_system_resume_early()
1063 * We might have done a hard reset or the CS35L56 was power-cycled in cs35l56_system_resume()
1068 /* Undo pm_runtime_force_suspend() before re-enabling the irq */ in cs35l56_system_resume()
1070 if (cs35l56->base.irq) in cs35l56_system_resume()
1071 enable_irq(cs35l56->base.irq); in cs35l56_system_resume()
1077 if (!cs35l56->component) in cs35l56_system_resume()
1080 ret = cs35l56_is_fw_reload_needed(&cs35l56->base); in cs35l56_system_resume()
1081 dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret); in cs35l56_system_resume()
1085 cs35l56->base.fw_patched = false; in cs35l56_system_resume()
1086 wm_adsp_power_down(&cs35l56->dsp); in cs35l56_system_resume()
1087 queue_work(cs35l56->dsp_wq, &cs35l56->dsp_work); in cs35l56_system_resume()
1091 * a BIAS_OFF->BIAS_STANDBY transition to complete dsp patching. in cs35l56_system_resume()
1098 static int cs35l56_control_add_nop(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl) in cs35l56_control_add_nop() argument
1105 struct wm_adsp *dsp; in cs35l56_dsp_init() local
1108 cs35l56->dsp_wq = create_singlethread_workqueue("cs35l56-dsp"); in cs35l56_dsp_init()
1109 if (!cs35l56->dsp_wq) in cs35l56_dsp_init()
1110 return -ENOMEM; in cs35l56_dsp_init()
1112 INIT_WORK(&cs35l56->dsp_work, cs35l56_dsp_work); in cs35l56_dsp_init()
1114 dsp = &cs35l56->dsp; in cs35l56_dsp_init()
1115 cs35l56_init_cs_dsp(&cs35l56->base, &dsp->cs_dsp); in cs35l56_dsp_init()
1118 * dsp->part is filled in later as it is based on the DEVID. In a in cs35l56_dsp_init()
1122 dsp->fw = 12; in cs35l56_dsp_init()
1123 dsp->wmfw_optional = true; in cs35l56_dsp_init()
1126 * None of the firmware controls need to be exported so add a no-op in cs35l56_dsp_init()
1129 dsp->control_add = &cs35l56_control_add_nop; in cs35l56_dsp_init()
1131 dev_dbg(cs35l56->base.dev, "DSP system name: '%s'\n", dsp->system_name); in cs35l56_dsp_init()
1133 ret = wm_halo_init(dsp); in cs35l56_dsp_init()
1135 dev_err(cs35l56->base.dev, "wm_halo_init failed\n"); in cs35l56_dsp_init()
1144 struct device *dev = cs35l56->base.dev; in cs35l56_get_firmware_uid()
1148 ret = device_property_read_string(dev, "cirrus,firmware-uid", &prop); in cs35l56_get_firmware_uid()
1154 if (cs35l56->speaker_id >= 0) in cs35l56_get_firmware_uid()
1155 cs35l56->dsp.system_name = devm_kasprintf(dev, GFP_KERNEL, "%s-spkid%d", in cs35l56_get_firmware_uid()
1156 prop, cs35l56->speaker_id); in cs35l56_get_firmware_uid()
1158 cs35l56->dsp.system_name = devm_kstrdup(dev, prop, GFP_KERNEL); in cs35l56_get_firmware_uid()
1160 if (cs35l56->dsp.system_name == NULL) in cs35l56_get_firmware_uid()
1161 return -ENOMEM; in cs35l56_get_firmware_uid()
1163 dev_dbg(dev, "Firmware UID: %s\n", cs35l56->dsp.system_name); in cs35l56_get_firmware_uid()
1169 * Some SoundWire laptops have a spk-id-gpios property but it points to
1176 { "spk-id-gpios", &cs35l56_af01_first_gpio, 1 },
1193 af01_fwnode = device_get_named_child_node(cs35l56->base.dev, "AF01"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1195 dev_dbg(cs35l56->base.dev, "No AF01 node\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1196 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1199 ret = acpi_dev_get_property(ACPI_COMPANION(cs35l56->base.dev), in cs35l56_try_get_broken_sdca_spkid_gpio()
1200 "spk-id-gpios", ACPI_TYPE_PACKAGE, &obj); in cs35l56_try_get_broken_sdca_spkid_gpio()
1202 dev_dbg(cs35l56->base.dev, "Could not get spk-id-gpios package: %d\n", ret); in cs35l56_try_get_broken_sdca_spkid_gpio()
1204 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1207 /* The broken properties we can handle are a 4-element package (one GPIO) */ in cs35l56_try_get_broken_sdca_spkid_gpio()
1208 if (obj->package.count != 4) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1209 dev_warn(cs35l56->base.dev, "Unexpected spk-id element count %d\n", in cs35l56_try_get_broken_sdca_spkid_gpio()
1210 obj->package.count); in cs35l56_try_get_broken_sdca_spkid_gpio()
1212 return -ENOENT; in cs35l56_try_get_broken_sdca_spkid_gpio()
1216 if (!fwnode_property_present(af01_fwnode, "spk-id-gpios")) { in cs35l56_try_get_broken_sdca_spkid_gpio()
1227 return dev_err_probe(cs35l56->base.dev, ret, in cs35l56_try_get_broken_sdca_spkid_gpio()
1231 ret = devm_add_action_or_reset(cs35l56->base.dev, in cs35l56_try_get_broken_sdca_spkid_gpio()
1239 dev_dbg(cs35l56->base.dev, "Added spk-id-gpios mapping to AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1242 desc = fwnode_gpiod_get_index(af01_fwnode, "spk-id", 0, GPIOD_IN, NULL); in cs35l56_try_get_broken_sdca_spkid_gpio()
1246 return dev_err_probe(cs35l56->base.dev, ret, "Get GPIO from AF01 failed\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1254 dev_err_probe(cs35l56->base.dev, ret, "Error reading spk-id GPIO\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1260 dev_info(cs35l56->base.dev, "Got spk-id from AF01\n"); in cs35l56_try_get_broken_sdca_spkid_gpio()
1269 init_completion(&cs35l56->init_completion); in cs35l56_common_probe()
1270 mutex_init(&cs35l56->base.irq_lock); in cs35l56_common_probe()
1271 cs35l56->base.cal_index = -1; in cs35l56_common_probe()
1272 cs35l56->speaker_id = -ENOENT; in cs35l56_common_probe()
1274 dev_set_drvdata(cs35l56->base.dev, cs35l56); in cs35l56_common_probe()
1276 cs35l56_fill_supply_names(cs35l56->supplies); in cs35l56_common_probe()
1277 ret = devm_regulator_bulk_get(cs35l56->base.dev, ARRAY_SIZE(cs35l56->supplies), in cs35l56_common_probe()
1278 cs35l56->supplies); in cs35l56_common_probe()
1280 return dev_err_probe(cs35l56->base.dev, ret, "Failed to request supplies\n"); in cs35l56_common_probe()
1282 /* Reset could be controlled by the BIOS or shared by multiple amps */ in cs35l56_common_probe()
1283 cs35l56->base.reset_gpio = devm_gpiod_get_optional(cs35l56->base.dev, "reset", in cs35l56_common_probe()
1285 if (IS_ERR(cs35l56->base.reset_gpio)) { in cs35l56_common_probe()
1286 ret = PTR_ERR(cs35l56->base.reset_gpio); in cs35l56_common_probe()
1288 * If RESET is shared the first amp to probe will grab the reset in cs35l56_common_probe()
1289 * line and reset all the amps in cs35l56_common_probe()
1291 if (ret != -EBUSY) in cs35l56_common_probe()
1292 return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n"); in cs35l56_common_probe()
1294 dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n"); in cs35l56_common_probe()
1295 cs35l56->base.reset_gpio = NULL; in cs35l56_common_probe()
1298 ret = regulator_bulk_enable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1300 return dev_err_probe(cs35l56->base.dev, ret, "Failed to enable supplies\n"); in cs35l56_common_probe()
1302 if (cs35l56->base.reset_gpio) { in cs35l56_common_probe()
1304 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1306 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1); in cs35l56_common_probe()
1309 ret = cs35l56_get_speaker_id(&cs35l56->base); in cs35l56_common_probe()
1310 if (ACPI_COMPANION(cs35l56->base.dev) && cs35l56->sdw_peripheral && (ret == -ENOENT)) in cs35l56_common_probe()
1313 if ((ret < 0) && (ret != -ENOENT)) in cs35l56_common_probe()
1316 cs35l56->speaker_id = ret; in cs35l56_common_probe()
1324 dev_err_probe(cs35l56->base.dev, ret, "DSP init failed\n"); in cs35l56_common_probe()
1328 ret = devm_snd_soc_register_component(cs35l56->base.dev, in cs35l56_common_probe()
1332 dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n"); in cs35l56_common_probe()
1339 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_common_probe()
1340 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_common_probe()
1351 * Check whether the actions associated with soft reset or one time in cs35l56_init()
1354 if (cs35l56->soft_resetting) in cs35l56_init()
1357 if (cs35l56->base.init_done) in cs35l56_init()
1360 pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 100); in cs35l56_init()
1361 pm_runtime_use_autosuspend(cs35l56->base.dev); in cs35l56_init()
1362 pm_runtime_set_active(cs35l56->base.dev); in cs35l56_init()
1363 pm_runtime_enable(cs35l56->base.dev); in cs35l56_init()
1365 ret = cs35l56_hw_init(&cs35l56->base); in cs35l56_init()
1369 ret = cs35l56_set_patch(&cs35l56->base); in cs35l56_init()
1373 ret = cs35l56_get_calibration(&cs35l56->base); in cs35l56_init()
1377 if (!cs35l56->base.reset_gpio) { in cs35l56_init()
1378 dev_dbg(cs35l56->base.dev, "No reset gpio: using soft reset\n"); in cs35l56_init()
1379 cs35l56->soft_resetting = true; in cs35l56_init()
1380 cs35l56_system_reset(&cs35l56->base, !!cs35l56->sdw_peripheral); in cs35l56_init()
1381 if (cs35l56->sdw_peripheral) { in cs35l56_init()
1382 /* Keep alive while we wait for re-enumeration */ in cs35l56_init()
1383 pm_runtime_get_noresume(cs35l56->base.dev); in cs35l56_init()
1389 if (cs35l56->soft_resetting) { in cs35l56_init()
1390 cs35l56->soft_resetting = false; in cs35l56_init()
1392 /* Done re-enumerating after one-time init so release the keep-alive */ in cs35l56_init()
1393 if (cs35l56->sdw_peripheral && !cs35l56->base.init_done) in cs35l56_init()
1394 pm_runtime_put_noidle(cs35l56->base.dev); in cs35l56_init()
1396 regcache_mark_dirty(cs35l56->base.regmap); in cs35l56_init()
1397 ret = cs35l56_wait_for_firmware_boot(&cs35l56->base); in cs35l56_init()
1401 dev_dbg(cs35l56->base.dev, "Firmware rebooted after soft reset\n"); in cs35l56_init()
1403 regcache_cache_only(cs35l56->base.regmap, false); in cs35l56_init()
1406 /* Disable auto-hibernate so that runtime_pm has control */ in cs35l56_init()
1407 ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE); in cs35l56_init()
1411 /* Registers could be dirty after soft reset or SoundWire enumeration */ in cs35l56_init()
1412 regcache_sync(cs35l56->base.regmap); in cs35l56_init()
1414 /* Set ASP1 DOUT to high-impedance when it is not transmitting audio data. */ in cs35l56_init()
1415 ret = regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_CONTROL3, in cs35l56_init()
1418 return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n"); in cs35l56_init()
1420 cs35l56->base.init_done = true; in cs35l56_init()
1421 complete(&cs35l56->init_completion); in cs35l56_init()
1429 cs35l56->base.init_done = false; in cs35l56_remove()
1435 if (cs35l56->base.irq) in cs35l56_remove()
1436 devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base); in cs35l56_remove()
1438 flush_workqueue(cs35l56->dsp_wq); in cs35l56_remove()
1439 destroy_workqueue(cs35l56->dsp_wq); in cs35l56_remove()
1441 pm_runtime_dont_use_autosuspend(cs35l56->base.dev); in cs35l56_remove()
1442 pm_runtime_suspend(cs35l56->base.dev); in cs35l56_remove()
1443 pm_runtime_disable(cs35l56->base.dev); in cs35l56_remove()
1445 regcache_cache_only(cs35l56->base.regmap, true); in cs35l56_remove()
1447 gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); in cs35l56_remove()
1448 regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); in cs35l56_remove()