Lines Matching full:cs35l41
3 // CS35l41 ALSA HDA audio driver
24 #define CS35L41_PART "cs35l41"
94 static void cs35l41_add_controls(struct cs35l41_hda *cs35l41) in cs35l41_add_controls() argument
98 info.device_name = cs35l41->amp_name; in cs35l41_add_controls()
99 info.fw_type = cs35l41->firmware_type; in cs35l41_add_controls()
100 info.card = cs35l41->codec->card; in cs35l41_add_controls()
102 hda_cs_dsp_add_controls(&cs35l41->cs_dsp, &info); in cs35l41_add_controls()
109 static int cs35l41_request_firmware_file(struct cs35l41_hda *cs35l41, in cs35l41_request_firmware_file() argument
114 const char * const dsp_name = cs35l41->cs_dsp.name; in cs35l41_request_firmware_file()
120 dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], in cs35l41_request_firmware_file()
124 dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], in cs35l41_request_firmware_file()
128 dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], in cs35l41_request_firmware_file()
132 dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], in cs35l41_request_firmware_file()
136 dsp_name, hda_cs_dsp_fw_ids[cs35l41->firmware_type], in cs35l41_request_firmware_file()
156 ret = firmware_request_nowarn(firmware, *filename, cs35l41->dev); in cs35l41_request_firmware_file()
158 dev_dbg(cs35l41->dev, "Failed to request '%s'\n", *filename); in cs35l41_request_firmware_file()
166 static int cs35l41_request_firmware_files_spkid(struct cs35l41_hda *cs35l41, in cs35l41_request_firmware_files_spkid() argument
175 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files_spkid()
177 cs35l41->acpi_subsystem_id, cs35l41->amp_name, in cs35l41_request_firmware_files_spkid()
178 cs35l41->speaker_id, "wmfw"); in cs35l41_request_firmware_files_spkid()
181 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
183 cs35l41->acpi_subsystem_id, cs35l41->amp_name, in cs35l41_request_firmware_files_spkid()
184 cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
189 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files_spkid()
190 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
191 cs35l41->amp_name, -1, "wmfw"); in cs35l41_request_firmware_files_spkid()
194 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
195 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
196 cs35l41->amp_name, cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
201 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files_spkid()
202 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
203 NULL, cs35l41->speaker_id, "wmfw"); in cs35l41_request_firmware_files_spkid()
206 ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
208 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
209 cs35l41->amp_name, cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
212 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
214 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
215 NULL, cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
220 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files_spkid()
221 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
225 ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
227 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
228 cs35l41->amp_name, cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
231 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
233 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files_spkid()
234 NULL, cs35l41->speaker_id, "bin"); in cs35l41_request_firmware_files_spkid()
239 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files_spkid()
243 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files_spkid()
248 dev_warn(cs35l41->dev, "Failed to request firmware\n"); in cs35l41_request_firmware_files_spkid()
253 static int cs35l41_request_firmware_files(struct cs35l41_hda *cs35l41, in cs35l41_request_firmware_files() argument
261 if (cs35l41->speaker_id > -1) in cs35l41_request_firmware_files()
262 return cs35l41_request_firmware_files_spkid(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files()
266 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files()
267 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files()
268 cs35l41->amp_name, -1, "wmfw"); in cs35l41_request_firmware_files()
271 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files()
272 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files()
273 cs35l41->amp_name, -1, "bin"); in cs35l41_request_firmware_files()
278 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files()
279 CS35L41_FIRMWARE_ROOT, cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files()
283 ret = cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files()
285 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files()
286 cs35l41->amp_name, -1, "bin"); in cs35l41_request_firmware_files()
289 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files()
291 cs35l41->acpi_subsystem_id, in cs35l41_request_firmware_files()
297 ret = cs35l41_request_firmware_file(cs35l41, wmfw_firmware, wmfw_filename, in cs35l41_request_firmware_files()
301 cs35l41_request_firmware_file(cs35l41, coeff_firmware, coeff_filename, in cs35l41_request_firmware_files()
306 dev_warn(cs35l41->dev, "Failed to request firmware\n"); in cs35l41_request_firmware_files()
312 static int cs35l41_apply_calibration(struct cs35l41_hda *cs35l41, unsigned int ambient, in cs35l41_apply_calibration() argument
317 ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_AMBIENT_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, in cs35l41_apply_calibration()
320 dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_AMBIENT_DSP_CTL_NAME, in cs35l41_apply_calibration()
324 ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_R_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, in cs35l41_apply_calibration()
327 dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_R_DSP_CTL_NAME, ret); in cs35l41_apply_calibration()
330 ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_STATUS_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, in cs35l41_apply_calibration()
333 dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_STATUS_DSP_CTL_NAME, in cs35l41_apply_calibration()
337 ret = hda_cs_dsp_write_ctl(&cs35l41->cs_dsp, CAL_CHECKSUM_DSP_CTL_NAME, CAL_DSP_CTL_TYPE, in cs35l41_apply_calibration()
340 dev_err(cs35l41->dev, "Cannot Write Control: %s - %d\n", CAL_CHECKSUM_DSP_CTL_NAME, in cs35l41_apply_calibration()
348 static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) in cs35l41_save_calibration() argument
373 dev_dbg(cs35l41->dev, "Calibration: Size=%d, Amp Count=%d\n", in cs35l41_save_calibration()
375 if (efi_data->count > cs35l41->index) { in cs35l41_save_calibration()
376 cl = &efi_data->data[cs35l41->index]; in cs35l41_save_calibration()
377 dev_dbg(cs35l41->dev, in cs35l41_save_calibration()
382 ret = cs35l41_apply_calibration(cs35l41, in cs35l41_save_calibration()
394 static int cs35l41_save_calibration(struct cs35l41_hda *cs35l41) in cs35l41_save_calibration() argument
396 dev_warn(cs35l41->dev, "Calibration not supported without EFI support.\n"); in cs35l41_save_calibration()
401 static int cs35l41_init_dsp(struct cs35l41_hda *cs35l41) in cs35l41_init_dsp() argument
405 struct cs_dsp *dsp = &cs35l41->cs_dsp; in cs35l41_init_dsp()
410 if (!cs35l41->halo_initialized) { in cs35l41_init_dsp()
411 cs35l41_configure_cs_dsp(cs35l41->dev, cs35l41->regmap, dsp); in cs35l41_init_dsp()
414 ret = cs_dsp_halo_init(&cs35l41->cs_dsp); in cs35l41_init_dsp()
417 cs35l41->halo_initialized = true; in cs35l41_init_dsp()
420 ret = cs35l41_request_firmware_files(cs35l41, &wmfw_firmware, &wmfw_filename, in cs35l41_init_dsp()
425 dev_dbg(cs35l41->dev, "Loading WMFW Firmware: %s\n", wmfw_filename); in cs35l41_init_dsp()
427 dev_dbg(cs35l41->dev, "Loading Coefficient File: %s\n", coeff_filename); in cs35l41_init_dsp()
429 dev_warn(cs35l41->dev, "No Coefficient File available.\n"); in cs35l41_init_dsp()
432 hda_cs_dsp_fw_ids[cs35l41->firmware_type]); in cs35l41_init_dsp()
436 cs35l41_add_controls(cs35l41); in cs35l41_init_dsp()
438 ret = cs35l41_save_calibration(cs35l41); in cs35l41_init_dsp()
449 static void cs35l41_shutdown_dsp(struct cs35l41_hda *cs35l41) in cs35l41_shutdown_dsp() argument
451 struct cs_dsp *dsp = &cs35l41->cs_dsp; in cs35l41_shutdown_dsp()
455 cs35l41->firmware_running = false; in cs35l41_shutdown_dsp()
456 dev_dbg(cs35l41->dev, "Unloaded Firmware\n"); in cs35l41_shutdown_dsp()
459 static void cs35l41_remove_dsp(struct cs35l41_hda *cs35l41) in cs35l41_remove_dsp() argument
461 struct cs_dsp *dsp = &cs35l41->cs_dsp; in cs35l41_remove_dsp()
463 cancel_work_sync(&cs35l41->fw_load_work); in cs35l41_remove_dsp()
465 mutex_lock(&cs35l41->fw_mutex); in cs35l41_remove_dsp()
466 cs35l41_shutdown_dsp(cs35l41); in cs35l41_remove_dsp()
468 cs35l41->halo_initialized = false; in cs35l41_remove_dsp()
469 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_remove_dsp()
481 static void cs35l41_irq_release(struct cs35l41_hda *cs35l41) in cs35l41_irq_release() argument
483 cs35l41_error_release(cs35l41->dev, cs35l41->regmap, cs35l41->irq_errors); in cs35l41_irq_release()
484 cs35l41->irq_errors = 0; in cs35l41_irq_release()
489 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_hda_playback_hook() local
490 struct regmap *reg = cs35l41->regmap; in cs35l41_hda_playback_hook()
496 mutex_lock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
497 cs35l41->playback_started = true; in cs35l41_hda_playback_hook()
498 if (cs35l41->firmware_running) { in cs35l41_hda_playback_hook()
501 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, in cs35l41_hda_playback_hook()
504 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, in cs35l41_hda_playback_hook()
512 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) in cs35l41_hda_playback_hook()
514 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
517 mutex_lock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
518 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1); in cs35l41_hda_playback_hook()
519 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
522 mutex_lock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
524 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0); in cs35l41_hda_playback_hook()
525 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
528 mutex_lock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
531 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) in cs35l41_hda_playback_hook()
533 if (cs35l41->firmware_running) { in cs35l41_hda_playback_hook()
534 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, in cs35l41_hda_playback_hook()
536 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, in cs35l41_hda_playback_hook()
540 cs35l41_irq_release(cs35l41); in cs35l41_hda_playback_hook()
541 cs35l41->playback_started = false; in cs35l41_hda_playback_hook()
542 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_hda_playback_hook()
548 dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); in cs35l41_hda_playback_hook()
553 dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); in cs35l41_hda_playback_hook()
559 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_hda_channel_map() local
562 if (!cs35l41->amp_name) { in cs35l41_hda_channel_map()
566 cs35l41->amp_name = devm_kasprintf(cs35l41->dev, GFP_KERNEL, "%s%d", in cs35l41_hda_channel_map()
567 channel_name[*rx_slot], cs35l41->channel_index); in cs35l41_hda_channel_map()
568 if (!cs35l41->amp_name) in cs35l41_hda_channel_map()
572 return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num, in cs35l41_hda_channel_map()
576 static void cs35l41_ready_for_reset(struct cs35l41_hda *cs35l41) in cs35l41_ready_for_reset() argument
578 mutex_lock(&cs35l41->fw_mutex); in cs35l41_ready_for_reset()
579 if (cs35l41->firmware_running) { in cs35l41_ready_for_reset()
581 regcache_cache_only(cs35l41->regmap, false); in cs35l41_ready_for_reset()
583 cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); in cs35l41_ready_for_reset()
584 cs35l41_shutdown_dsp(cs35l41); in cs35l41_ready_for_reset()
585 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); in cs35l41_ready_for_reset()
587 regcache_cache_only(cs35l41->regmap, true); in cs35l41_ready_for_reset()
588 regcache_mark_dirty(cs35l41->regmap); in cs35l41_ready_for_reset()
590 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_ready_for_reset()
595 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_system_suspend() local
598 dev_dbg(cs35l41->dev, "System Suspend\n"); in cs35l41_system_suspend()
600 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { in cs35l41_system_suspend()
601 dev_err(cs35l41->dev, "System Suspend not supported\n"); in cs35l41_system_suspend()
610 cs35l41_ready_for_reset(cs35l41); in cs35l41_system_suspend()
621 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_system_resume() local
624 dev_dbg(cs35l41->dev, "System Resume\n"); in cs35l41_system_resume()
626 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { in cs35l41_system_resume()
627 dev_err(cs35l41->dev, "System Resume not supported\n"); in cs35l41_system_resume()
631 if (cs35l41->reset_gpio) { in cs35l41_system_resume()
633 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); in cs35l41_system_resume()
640 mutex_lock(&cs35l41->fw_mutex); in cs35l41_system_resume()
641 if (!ret && cs35l41->request_fw_load && !cs35l41->fw_request_ongoing) { in cs35l41_system_resume()
642 cs35l41->fw_request_ongoing = true; in cs35l41_system_resume()
643 schedule_work(&cs35l41->fw_load_work); in cs35l41_system_resume()
645 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_system_resume()
652 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_runtime_suspend() local
655 dev_dbg(cs35l41->dev, "Runtime Suspend\n"); in cs35l41_runtime_suspend()
657 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { in cs35l41_runtime_suspend()
658 dev_dbg(cs35l41->dev, "Runtime Suspend not supported\n"); in cs35l41_runtime_suspend()
662 mutex_lock(&cs35l41->fw_mutex); in cs35l41_runtime_suspend()
664 if (cs35l41->playback_started) { in cs35l41_runtime_suspend()
665 regmap_multi_reg_write(cs35l41->regmap, cs35l41_hda_mute, in cs35l41_runtime_suspend()
667 cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0); in cs35l41_runtime_suspend()
668 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, in cs35l41_runtime_suspend()
670 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) in cs35l41_runtime_suspend()
671 regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001); in cs35l41_runtime_suspend()
672 regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, in cs35l41_runtime_suspend()
675 cs35l41->playback_started = false; in cs35l41_runtime_suspend()
678 if (cs35l41->firmware_running) { in cs35l41_runtime_suspend()
679 ret = cs35l41_enter_hibernate(cs35l41->dev, cs35l41->regmap, in cs35l41_runtime_suspend()
680 cs35l41->hw_cfg.bst_type); in cs35l41_runtime_suspend()
684 cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type); in cs35l41_runtime_suspend()
687 regcache_cache_only(cs35l41->regmap, true); in cs35l41_runtime_suspend()
688 regcache_mark_dirty(cs35l41->regmap); in cs35l41_runtime_suspend()
691 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_runtime_suspend()
698 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_runtime_resume() local
701 dev_dbg(cs35l41->dev, "Runtime Resume\n"); in cs35l41_runtime_resume()
703 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { in cs35l41_runtime_resume()
704 dev_dbg(cs35l41->dev, "Runtime Resume not supported\n"); in cs35l41_runtime_resume()
708 mutex_lock(&cs35l41->fw_mutex); in cs35l41_runtime_resume()
710 regcache_cache_only(cs35l41->regmap, false); in cs35l41_runtime_resume()
712 if (cs35l41->firmware_running) { in cs35l41_runtime_resume()
713 ret = cs35l41_exit_hibernate(cs35l41->dev, cs35l41->regmap); in cs35l41_runtime_resume()
715 dev_warn(cs35l41->dev, "Unable to exit Hibernate."); in cs35l41_runtime_resume()
721 cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); in cs35l41_runtime_resume()
722 ret = regcache_sync(cs35l41->regmap); in cs35l41_runtime_resume()
723 cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); in cs35l41_runtime_resume()
725 dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret); in cs35l41_runtime_resume()
729 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) in cs35l41_runtime_resume()
730 cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg); in cs35l41_runtime_resume()
733 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_runtime_resume()
738 static int cs35l41_smart_amp(struct cs35l41_hda *cs35l41) in cs35l41_smart_amp() argument
743 ret = cs35l41_init_dsp(cs35l41); in cs35l41_smart_amp()
745 dev_warn(cs35l41->dev, "Cannot Initialize Firmware. Error: %d\n", ret); in cs35l41_smart_amp()
749 ret = cs35l41_write_fs_errata(cs35l41->dev, cs35l41->regmap); in cs35l41_smart_amp()
751 dev_err(cs35l41->dev, "Cannot Write FS Errata: %d\n", ret); in cs35l41_smart_amp()
755 ret = cs_dsp_run(&cs35l41->cs_dsp); in cs35l41_smart_amp()
757 dev_err(cs35l41->dev, "Fail to start dsp: %d\n", ret); in cs35l41_smart_amp()
763 1000, 15000, false, &cs35l41->cs_dsp, HALO_STATE_DSP_CTL_NAME, in cs35l41_smart_amp()
768 dev_err(cs35l41->dev, "Timeout waiting for HALO Core to start. State: %d\n", in cs35l41_smart_amp()
773 cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_PAUSE); in cs35l41_smart_amp()
774 cs35l41->firmware_running = true; in cs35l41_smart_amp()
779 cs35l41_shutdown_dsp(cs35l41); in cs35l41_smart_amp()
783 static void cs35l41_load_firmware(struct cs35l41_hda *cs35l41, bool load) in cs35l41_load_firmware() argument
785 if (cs35l41->firmware_running && !load) { in cs35l41_load_firmware()
786 dev_dbg(cs35l41->dev, "Unloading Firmware\n"); in cs35l41_load_firmware()
787 cs35l41_shutdown_dsp(cs35l41); in cs35l41_load_firmware()
788 } else if (!cs35l41->firmware_running && load) { in cs35l41_load_firmware()
789 dev_dbg(cs35l41->dev, "Loading Firmware\n"); in cs35l41_load_firmware()
790 cs35l41_smart_amp(cs35l41); in cs35l41_load_firmware()
792 dev_dbg(cs35l41->dev, "Unable to Load firmware.\n"); in cs35l41_load_firmware()
799 struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); in cs35l41_fw_load_ctl_get() local
801 ucontrol->value.integer.value[0] = cs35l41->request_fw_load; in cs35l41_fw_load_ctl_get()
807 struct cs35l41_hda *cs35l41 = container_of(work, struct cs35l41_hda, fw_load_work); in cs35l41_fw_load_work() local
809 pm_runtime_get_sync(cs35l41->dev); in cs35l41_fw_load_work()
811 mutex_lock(&cs35l41->fw_mutex); in cs35l41_fw_load_work()
814 if (cs35l41->playback_started) in cs35l41_fw_load_work()
815 dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback. Retrying...\n"); in cs35l41_fw_load_work()
817 cs35l41_load_firmware(cs35l41, cs35l41->request_fw_load); in cs35l41_fw_load_work()
819 cs35l41->fw_request_ongoing = false; in cs35l41_fw_load_work()
820 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_fw_load_work()
822 pm_runtime_mark_last_busy(cs35l41->dev); in cs35l41_fw_load_work()
823 pm_runtime_put_autosuspend(cs35l41->dev); in cs35l41_fw_load_work()
829 struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); in cs35l41_fw_load_ctl_put() local
832 mutex_lock(&cs35l41->fw_mutex); in cs35l41_fw_load_ctl_put()
834 if (cs35l41->request_fw_load == ucontrol->value.integer.value[0]) in cs35l41_fw_load_ctl_put()
837 if (cs35l41->fw_request_ongoing) { in cs35l41_fw_load_ctl_put()
838 dev_dbg(cs35l41->dev, "Existing request not complete\n"); in cs35l41_fw_load_ctl_put()
844 if (cs35l41->playback_started) { in cs35l41_fw_load_ctl_put()
845 dev_err(cs35l41->dev, "Cannot Load/Unload firmware during Playback\n"); in cs35l41_fw_load_ctl_put()
850 cs35l41->fw_request_ongoing = true; in cs35l41_fw_load_ctl_put()
851 cs35l41->request_fw_load = ucontrol->value.integer.value[0]; in cs35l41_fw_load_ctl_put()
852 schedule_work(&cs35l41->fw_load_work); in cs35l41_fw_load_ctl_put()
855 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_fw_load_ctl_put()
863 struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); in cs35l41_fw_type_ctl_get() local
865 ucontrol->value.enumerated.item[0] = cs35l41->firmware_type; in cs35l41_fw_type_ctl_get()
873 struct cs35l41_hda *cs35l41 = snd_kcontrol_chip(kcontrol); in cs35l41_fw_type_ctl_put() local
876 cs35l41->firmware_type = ucontrol->value.enumerated.item[0]; in cs35l41_fw_type_ctl_put()
888 static int cs35l41_create_controls(struct cs35l41_hda *cs35l41) in cs35l41_create_controls() argument
909 cs35l41->amp_name); in cs35l41_create_controls()
911 cs35l41->amp_name); in cs35l41_create_controls()
913 ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41)); in cs35l41_create_controls()
915 dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_type_ctl.name, ret); in cs35l41_create_controls()
919 dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name); in cs35l41_create_controls()
921 ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_load_ctl, cs35l41)); in cs35l41_create_controls()
923 dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_load_ctl.name, ret); in cs35l41_create_controls()
927 dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name); in cs35l41_create_controls()
934 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_hda_bind() local
938 if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) in cs35l41_hda_bind()
941 comps = &comps[cs35l41->index]; in cs35l41_hda_bind()
947 mutex_lock(&cs35l41->fw_mutex); in cs35l41_hda_bind()
950 if (!cs35l41->acpi_subsystem_id) in cs35l41_hda_bind()
951 cs35l41->acpi_subsystem_id = kasprintf(GFP_KERNEL, "%.8x", in cs35l41_hda_bind()
953 cs35l41->codec = comps->codec; in cs35l41_hda_bind()
956 cs35l41->firmware_type = HDA_CS_DSP_FW_SPK_PROT; in cs35l41_hda_bind()
959 dev_dbg(cs35l41->dev, "Firmware Autostart.\n"); in cs35l41_hda_bind()
960 cs35l41->request_fw_load = true; in cs35l41_hda_bind()
961 if (cs35l41_smart_amp(cs35l41) < 0) in cs35l41_hda_bind()
962 dev_warn(cs35l41->dev, "Cannot Run Firmware, reverting to dsp bypass...\n"); in cs35l41_hda_bind()
964 dev_dbg(cs35l41->dev, "Firmware Autostart is disabled.\n"); in cs35l41_hda_bind()
967 ret = cs35l41_create_controls(cs35l41); in cs35l41_hda_bind()
971 mutex_unlock(&cs35l41->fw_mutex); in cs35l41_hda_bind()
981 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_hda_unbind() local
984 if (comps[cs35l41->index].dev == dev) in cs35l41_hda_unbind()
985 memset(&comps[cs35l41->index], 0, sizeof(*comps)); in cs35l41_hda_unbind()
995 struct cs35l41_hda *cs35l41 = data; in cs35l41_bst_short_err() local
997 dev_crit_ratelimited(cs35l41->dev, "LBST Error\n"); in cs35l41_bst_short_err()
998 set_bit(CS35L41_BST_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_bst_short_err()
1005 struct cs35l41_hda *cs35l41 = data; in cs35l41_bst_dcm_uvp_err() local
1007 dev_crit_ratelimited(cs35l41->dev, "DCM VBST Under Voltage Error\n"); in cs35l41_bst_dcm_uvp_err()
1008 set_bit(CS35L41_BST_UVP_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_bst_dcm_uvp_err()
1015 struct cs35l41_hda *cs35l41 = data; in cs35l41_bst_ovp_err() local
1017 dev_crit_ratelimited(cs35l41->dev, "VBST Over Voltage error\n"); in cs35l41_bst_ovp_err()
1018 set_bit(CS35L41_BST_OVP_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_bst_ovp_err()
1025 struct cs35l41_hda *cs35l41 = data; in cs35l41_temp_err() local
1027 dev_crit_ratelimited(cs35l41->dev, "Over temperature error\n"); in cs35l41_temp_err()
1028 set_bit(CS35L41_TEMP_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_temp_err()
1035 struct cs35l41_hda *cs35l41 = data; in cs35l41_temp_warn() local
1037 dev_crit_ratelimited(cs35l41->dev, "Over temperature warning\n"); in cs35l41_temp_warn()
1038 set_bit(CS35L41_TEMP_WARN_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_temp_warn()
1045 struct cs35l41_hda *cs35l41 = data; in cs35l41_amp_short() local
1047 dev_crit_ratelimited(cs35l41->dev, "Amp short error\n"); in cs35l41_amp_short()
1048 set_bit(CS35L41_AMP_SHORT_ERR_RLS_SHIFT, &cs35l41->irq_errors); in cs35l41_amp_short()
1072 .name = "cs35l41 IRQ1 Controller",
1082 static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) in cs35l41_hda_apply_properties() argument
1084 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; in cs35l41_hda_apply_properties()
1090 if (!cs35l41->hw_cfg.valid) in cs35l41_hda_apply_properties()
1093 ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg); in cs35l41_hda_apply_properties()
1109 dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", in cs35l41_hda_apply_properties()
1124 dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); in cs35l41_hda_apply_properties()
1129 irq_pol = cs35l41_gpio_config(cs35l41->regmap, hw_cfg); in cs35l41_hda_apply_properties()
1131 if (cs35l41->irq && using_irq) { in cs35l41_hda_apply_properties()
1132 ret = devm_regmap_add_irq_chip(cs35l41->dev, cs35l41->regmap, cs35l41->irq, in cs35l41_hda_apply_properties()
1134 0, &cs35l41_regmap_irq_chip, &cs35l41->irq_data); in cs35l41_hda_apply_properties()
1139 irq = regmap_irq_get_virq(cs35l41->irq_data, cs35l41_irqs[i].irq); in cs35l41_hda_apply_properties()
1143 ret = devm_request_threaded_irq(cs35l41->dev, irq, NULL, in cs35l41_hda_apply_properties()
1146 cs35l41_irqs[i].name, cs35l41); in cs35l41_hda_apply_properties()
1152 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); in cs35l41_hda_apply_properties()
1217 static int cs35l41_no_acpi_dsd(struct cs35l41_hda *cs35l41, struct device *physdev, int id, in cs35l41_no_acpi_dsd() argument
1220 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; in cs35l41_no_acpi_dsd()
1223 cs35l41->index = id == 0x40 ? 0 : 1; in cs35l41_no_acpi_dsd()
1224 cs35l41->channel_index = 0; in cs35l41_no_acpi_dsd()
1225 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); in cs35l41_no_acpi_dsd()
1226 cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, 0, 0, 2); in cs35l41_no_acpi_dsd()
1227 hw_cfg->spk_pos = cs35l41->index; in cs35l41_no_acpi_dsd()
1243 dev_err(cs35l41->dev, "Error: ACPI _DSD Properties are missing for HID %s.\n", hid); in cs35l41_no_acpi_dsd()
1253 static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) in cs35l41_hda_read_acpi() argument
1255 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; in cs35l41_hda_read_acpi()
1266 dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); in cs35l41_hda_read_acpi()
1276 cs35l41->acpi_subsystem_id = sub; in cs35l41_hda_read_acpi()
1281 ret = cs35l41_no_acpi_dsd(cs35l41, physdev, id, hid); in cs35l41_hda_read_acpi()
1294 cs35l41->index = -1; in cs35l41_hda_read_acpi()
1297 cs35l41->index = i; in cs35l41_hda_read_acpi()
1301 if (cs35l41->index == -1) { in cs35l41_hda_read_acpi()
1302 dev_err(cs35l41->dev, "No index found in %s\n", property); in cs35l41_hda_read_acpi()
1310 cs35l41->reset_gpio = fwnode_gpiod_get_index(acpi_fwnode_handle(adev), "reset", cs35l41->index, in cs35l41_hda_read_acpi()
1311 GPIOD_OUT_LOW, "cs35l41-reset"); in cs35l41_hda_read_acpi()
1317 hw_cfg->spk_pos = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1319 cs35l41->channel_index = 0; in cs35l41_hda_read_acpi()
1320 for (i = 0; i < cs35l41->index; i++) in cs35l41_hda_read_acpi()
1322 cs35l41->channel_index++; in cs35l41_hda_read_acpi()
1328 hw_cfg->gpio1.func = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1335 hw_cfg->gpio2.func = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1341 hw_cfg->bst_ipk = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1348 hw_cfg->bst_ind = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1355 hw_cfg->bst_cap = values[cs35l41->index]; in cs35l41_hda_read_acpi()
1359 cs35l41->speaker_id = cs35l41_get_speaker_id(physdev, cs35l41->index, nval, -1); in cs35l41_hda_read_acpi()
1372 dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); in cs35l41_hda_read_acpi()
1383 struct cs35l41_hda *cs35l41; in cs35l41_hda_probe() local
1392 cs35l41 = devm_kzalloc(dev, sizeof(*cs35l41), GFP_KERNEL); in cs35l41_hda_probe()
1393 if (!cs35l41) in cs35l41_hda_probe()
1396 cs35l41->dev = dev; in cs35l41_hda_probe()
1397 cs35l41->irq = irq; in cs35l41_hda_probe()
1398 cs35l41->regmap = regmap; in cs35l41_hda_probe()
1399 dev_set_drvdata(dev, cs35l41); in cs35l41_hda_probe()
1401 ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); in cs35l41_hda_probe()
1403 return dev_err_probe(cs35l41->dev, ret, "Platform not supported\n"); in cs35l41_hda_probe()
1405 if (IS_ERR(cs35l41->reset_gpio)) { in cs35l41_hda_probe()
1406 ret = PTR_ERR(cs35l41->reset_gpio); in cs35l41_hda_probe()
1407 cs35l41->reset_gpio = NULL; in cs35l41_hda_probe()
1409 dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); in cs35l41_hda_probe()
1411 dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO\n"); in cs35l41_hda_probe()
1415 if (cs35l41->reset_gpio) { in cs35l41_hda_probe()
1417 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); in cs35l41_hda_probe()
1422 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, in cs35l41_hda_probe()
1425 dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret); in cs35l41_hda_probe()
1429 ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); in cs35l41_hda_probe()
1431 dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n", in cs35l41_hda_probe()
1437 ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); in cs35l41_hda_probe()
1439 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); in cs35l41_hda_probe()
1443 ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); in cs35l41_hda_probe()
1445 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); in cs35l41_hda_probe()
1453 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", regid, chipid); in cs35l41_hda_probe()
1458 ret = cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); in cs35l41_hda_probe()
1462 ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); in cs35l41_hda_probe()
1466 ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); in cs35l41_hda_probe()
1468 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); in cs35l41_hda_probe()
1472 ret = cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); in cs35l41_hda_probe()
1476 INIT_WORK(&cs35l41->fw_load_work, cs35l41_fw_load_work); in cs35l41_hda_probe()
1477 mutex_init(&cs35l41->fw_mutex); in cs35l41_hda_probe()
1479 pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); in cs35l41_hda_probe()
1480 pm_runtime_use_autosuspend(cs35l41->dev); in cs35l41_hda_probe()
1481 pm_runtime_mark_last_busy(cs35l41->dev); in cs35l41_hda_probe()
1482 pm_runtime_set_active(cs35l41->dev); in cs35l41_hda_probe()
1483 pm_runtime_get_noresume(cs35l41->dev); in cs35l41_hda_probe()
1484 pm_runtime_enable(cs35l41->dev); in cs35l41_hda_probe()
1486 ret = cs35l41_hda_apply_properties(cs35l41); in cs35l41_hda_probe()
1490 pm_runtime_put_autosuspend(cs35l41->dev); in cs35l41_hda_probe()
1492 ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); in cs35l41_hda_probe()
1494 dev_err(cs35l41->dev, "Register component failed: %d\n", ret); in cs35l41_hda_probe()
1495 pm_runtime_disable(cs35l41->dev); in cs35l41_hda_probe()
1499 dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); in cs35l41_hda_probe()
1504 pm_runtime_disable(cs35l41->dev); in cs35l41_hda_probe()
1505 pm_runtime_put_noidle(cs35l41->dev); in cs35l41_hda_probe()
1508 if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) in cs35l41_hda_probe()
1509 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); in cs35l41_hda_probe()
1510 gpiod_put(cs35l41->reset_gpio); in cs35l41_hda_probe()
1511 kfree(cs35l41->acpi_subsystem_id); in cs35l41_hda_probe()
1519 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); in cs35l41_hda_remove() local
1521 pm_runtime_get_sync(cs35l41->dev); in cs35l41_hda_remove()
1522 pm_runtime_disable(cs35l41->dev); in cs35l41_hda_remove()
1524 if (cs35l41->halo_initialized) in cs35l41_hda_remove()
1525 cs35l41_remove_dsp(cs35l41); in cs35l41_hda_remove()
1527 component_del(cs35l41->dev, &cs35l41_hda_comp_ops); in cs35l41_hda_remove()
1529 pm_runtime_put_noidle(cs35l41->dev); in cs35l41_hda_remove()
1531 if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) in cs35l41_hda_remove()
1532 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); in cs35l41_hda_remove()
1533 gpiod_put(cs35l41->reset_gpio); in cs35l41_hda_remove()
1534 kfree(cs35l41->acpi_subsystem_id); in cs35l41_hda_remove()
1544 MODULE_DESCRIPTION("CS35L41 HDA Driver");