Lines Matching +full:vdd +full:- +full:p +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and
20 #include <linux/mfd/cs42l43-regs.h>
440 #define CS42L43_IRQ_OFFSET(reg) ((CS42L43_##reg##_INT) - CS42L43_DECIM_INT)
509 "vdd-a", "vdd-io", "vdd-cp",
512 static const char * const cs42l43_parent_supplies[] = { "vdd-amp" };
515 { .name = "cs42l43-pinctrl", },
516 { .name = "cs42l43-spi", },
518 .name = "cs42l43-codec",
535 reinit_completion(&cs42l43->device_detach); in cs42l43_soft_reset()
541 regcache_cache_only(cs42l43->regmap, true); in cs42l43_soft_reset()
542 regmap_multi_reg_write_bypassed(cs42l43->regmap, reset, ARRAY_SIZE(reset)); in cs42l43_soft_reset()
546 if (cs42l43->sdw) { in cs42l43_soft_reset()
550 time = wait_for_completion_timeout(&cs42l43->device_detach, timeout); in cs42l43_soft_reset()
552 dev_err(cs42l43->dev, "Timed out waiting for device detach\n"); in cs42l43_soft_reset()
553 return -ETIMEDOUT; in cs42l43_soft_reset()
557 return -EAGAIN; in cs42l43_soft_reset()
561 * This function is essentially a no-op on I2C, but will wait for the device to
566 if (!cs42l43->attached) { in cs42l43_wait_for_attach()
570 time = wait_for_completion_timeout(&cs42l43->device_attach, timeout); in cs42l43_wait_for_attach()
572 dev_err(cs42l43->dev, "Timed out waiting for device re-attach\n"); in cs42l43_wait_for_attach()
573 return -ETIMEDOUT; in cs42l43_wait_for_attach()
577 regcache_cache_only(cs42l43->regmap, false); in cs42l43_wait_for_attach()
580 if (cs42l43->sdw) in cs42l43_wait_for_attach()
581 regmap_write(cs42l43->regmap, CS42L43_OSC_DIV_SEL, in cs42l43_wait_for_attach()
605 regmap_write(cs42l43->regmap, need_reg, 0); in cs42l43_mcu_stage_2_3()
607 ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_BOOT_STATUS, in cs42l43_mcu_stage_2_3()
611 dev_err(cs42l43->dev, "Failed to move to stage 3: %d, 0x%x\n", ret, val); in cs42l43_mcu_stage_2_3()
615 return -EAGAIN; in cs42l43_mcu_stage_2_3()
633 regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_NEED_CONFIGS, in cs42l43_mcu_stage_3_2()
635 regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_HAVE_CONFIGS, 0); in cs42l43_mcu_stage_3_2()
649 regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_MCU_CFG_REG, in cs42l43_mcu_disable()
651 regmap_write(cs42l43->regmap, CS42L43_FW_MISSION_CTRL_MM_CTRL_SELECTION, in cs42l43_mcu_disable()
653 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, CS42L43_CONTROL_IND_MASK); in cs42l43_mcu_disable()
654 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, 0); in cs42l43_mcu_disable()
656 ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_SOFT_INT_SHADOW, val, in cs42l43_mcu_disable()
660 dev_err(cs42l43->dev, "Failed to disable firmware: %d, 0x%x\n", ret, val); in cs42l43_mcu_disable()
679 dev_err(cs42l43->dev, "Failed to load firmware\n"); in cs42l43_mcu_load_firmware()
680 cs42l43->firmware_error = -ENODEV; in cs42l43_mcu_load_firmware()
684 hdr = (const struct cs42l43_patch_header *)&firmware->data[0]; in cs42l43_mcu_load_firmware()
685 loadaddr = le32_to_cpu(hdr->load_addr); in cs42l43_mcu_load_firmware()
687 if (le16_to_cpu(hdr->version) != CS42L43_MCU_UPDATE_FORMAT) { in cs42l43_mcu_load_firmware()
688 dev_err(cs42l43->dev, "Bad firmware file format: %d\n", hdr->version); in cs42l43_mcu_load_firmware()
689 cs42l43->firmware_error = -EINVAL; in cs42l43_mcu_load_firmware()
693 regmap_write(cs42l43->regmap, CS42L43_PATCH_START_ADDR, loadaddr); in cs42l43_mcu_load_firmware()
694 regmap_bulk_write(cs42l43->regmap, loadaddr + CS42L43_MCU_UPDATE_OFFSET, in cs42l43_mcu_load_firmware()
695 &firmware->data[0], firmware->size / sizeof(u32)); in cs42l43_mcu_load_firmware()
697 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, CS42L43_PATCH_IND_MASK); in cs42l43_mcu_load_firmware()
698 regmap_write(cs42l43->regmap, CS42L43_MCU_SW_INTERRUPT, 0); in cs42l43_mcu_load_firmware()
700 ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_SOFT_INT_SHADOW, val, in cs42l43_mcu_load_firmware()
704 dev_err(cs42l43->dev, "Failed to update firmware: %d, 0x%x\n", ret, val); in cs42l43_mcu_load_firmware()
705 cs42l43->firmware_error = ret; in cs42l43_mcu_load_firmware()
712 complete(&cs42l43->firmware_download); in cs42l43_mcu_load_firmware()
725 dev_err(cs42l43->dev, "Firmware too old to support disable\n"); in cs42l43_mcu_is_hw_compatible()
726 return -EINVAL; in cs42l43_mcu_is_hw_compatible()
735 * require the driver to wait for the device to re-attach on the SoundWire bus,
745 regmap_read(cs42l43->regmap, CS42L43_SOFT_INT, &mcu_rev); in cs42l43_mcu_update_step()
747 ret = regmap_read(cs42l43->regmap, CS42L43_BOOT_STATUS, &boot_status); in cs42l43_mcu_update_step()
749 dev_err(cs42l43->dev, "Failed to read boot status: %d\n", ret); in cs42l43_mcu_update_step()
753 ret = regmap_read(cs42l43->regmap, CS42L43_MCU_SW_REV, &mcu_rev); in cs42l43_mcu_update_step()
755 dev_err(cs42l43->dev, "Failed to read firmware revision: %d\n", ret); in cs42l43_mcu_update_step()
778 ret = regmap_read(cs42l43->regmap, CS42L43_BOOT_CONTROL, &secure_cfg); in cs42l43_mcu_update_step()
780 dev_err(cs42l43->dev, "Failed to read security settings: %d\n", ret); in cs42l43_mcu_update_step()
784 cs42l43->hw_lock = secure_cfg & CS42L43_LOCK_HW_STS_MASK; in cs42l43_mcu_update_step()
786 if (!patched && cs42l43->hw_lock) { in cs42l43_mcu_update_step()
787 dev_err(cs42l43->dev, "Unpatched secure device\n"); in cs42l43_mcu_update_step()
788 return -EPERM; in cs42l43_mcu_update_step()
791 dev_dbg(cs42l43->dev, "Firmware(0x%x, 0x%x) in boot stage %d\n", in cs42l43_mcu_update_step()
798 "cs42l43.bin", cs42l43->dev, in cs42l43_mcu_update_step()
802 dev_err(cs42l43->dev, "Failed to request firmware: %d\n", ret); in cs42l43_mcu_update_step()
806 wait_for_completion(&cs42l43->firmware_download); in cs42l43_mcu_update_step()
808 if (cs42l43->firmware_error) in cs42l43_mcu_update_step()
809 return cs42l43->firmware_error; in cs42l43_mcu_update_step()
811 return -EAGAIN; in cs42l43_mcu_update_step()
828 dev_err(cs42l43->dev, "Invalid boot status: %d\n", boot_status); in cs42l43_mcu_update_step()
829 return -EINVAL; in cs42l43_mcu_update_step()
842 if (ret != -EAGAIN) in cs42l43_mcu_update()
850 dev_err(cs42l43->dev, "Failed retrying update\n"); in cs42l43_mcu_update()
851 return -ETIMEDOUT; in cs42l43_mcu_update()
860 if (cs42l43->sdw) in cs42l43_irq_config()
861 cs42l43->irq = cs42l43->sdw->irq; in cs42l43_irq_config()
863 cs42l43->irq_chip = cs42l43_irq_chip; in cs42l43_irq_config()
864 cs42l43->irq_chip.irq_drv_data = cs42l43; in cs42l43_irq_config()
866 irq_data = irq_get_irq_data(cs42l43->irq); in cs42l43_irq_config()
868 dev_err(cs42l43->dev, "Invalid IRQ: %d\n", cs42l43->irq); in cs42l43_irq_config()
869 return -EINVAL; in cs42l43_irq_config()
887 ret = devm_regmap_add_irq_chip(cs42l43->dev, cs42l43->regmap, in cs42l43_irq_config()
888 cs42l43->irq, irq_flags, 0, in cs42l43_irq_config()
889 &cs42l43->irq_chip, &cs42l43->irq_data); in cs42l43_irq_config()
891 dev_err(cs42l43->dev, "Failed to add IRQ chip: %d\n", ret); in cs42l43_irq_config()
895 dev_dbg(cs42l43->dev, "Configured IRQ %d with flags 0x%lx\n", in cs42l43_irq_config()
896 cs42l43->irq, irq_flags); in cs42l43_irq_config()
911 ret = regmap_read(cs42l43->regmap, CS42L43_DEVID, &devid); in cs42l43_boot_work()
913 dev_err(cs42l43->dev, "Failed to read devid: %d\n", ret); in cs42l43_boot_work()
921 dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid); in cs42l43_boot_work()
925 ret = regmap_read(cs42l43->regmap, CS42L43_REVID, &revid); in cs42l43_boot_work()
927 dev_err(cs42l43->dev, "Failed to read rev: %d\n", ret); in cs42l43_boot_work()
931 ret = regmap_read(cs42l43->regmap, CS42L43_OTP_REVISION_ID, &otp); in cs42l43_boot_work()
933 dev_err(cs42l43->dev, "Failed to read otp rev: %d\n", ret); in cs42l43_boot_work()
937 dev_info(cs42l43->dev, in cs42l43_boot_work()
944 ret = regmap_register_patch(cs42l43->regmap, cs42l43_reva_patch, in cs42l43_boot_work()
947 dev_err(cs42l43->dev, "Failed to apply register patch: %d\n", ret); in cs42l43_boot_work()
955 ret = devm_mfd_add_devices(cs42l43->dev, PLATFORM_DEVID_NONE, in cs42l43_boot_work()
959 dev_err(cs42l43->dev, "Failed to add subdevices: %d\n", ret); in cs42l43_boot_work()
963 pm_runtime_mark_last_busy(cs42l43->dev); in cs42l43_boot_work()
964 pm_runtime_put_autosuspend(cs42l43->dev); in cs42l43_boot_work()
969 pm_runtime_put_sync(cs42l43->dev); in cs42l43_boot_work()
977 ret = regulator_enable(cs42l43->vdd_p); in cs42l43_power_up()
979 dev_err(cs42l43->dev, "Failed to enable vdd-p: %d\n", ret); in cs42l43_power_up()
983 /* vdd-p must be on for 50uS before any other supply */ in cs42l43_power_up()
986 gpiod_set_value_cansleep(cs42l43->reset, 1); in cs42l43_power_up()
988 ret = regulator_bulk_enable(CS42L43_N_SUPPLIES, cs42l43->core_supplies); in cs42l43_power_up()
990 dev_err(cs42l43->dev, "Failed to enable core supplies: %d\n", ret); in cs42l43_power_up()
994 ret = regulator_enable(cs42l43->vdd_d); in cs42l43_power_up()
996 dev_err(cs42l43->dev, "Failed to enable vdd-d: %d\n", ret); in cs42l43_power_up()
1005 regulator_bulk_disable(CS42L43_N_SUPPLIES, cs42l43->core_supplies); in cs42l43_power_up()
1007 gpiod_set_value_cansleep(cs42l43->reset, 0); in cs42l43_power_up()
1008 regulator_disable(cs42l43->vdd_p); in cs42l43_power_up()
1017 ret = regulator_disable(cs42l43->vdd_d); in cs42l43_power_down()
1019 dev_err(cs42l43->dev, "Failed to disable vdd-d: %d\n", ret); in cs42l43_power_down()
1023 ret = regulator_bulk_disable(CS42L43_N_SUPPLIES, cs42l43->core_supplies); in cs42l43_power_down()
1025 dev_err(cs42l43->dev, "Failed to disable core supplies: %d\n", ret); in cs42l43_power_down()
1029 gpiod_set_value_cansleep(cs42l43->reset, 0); in cs42l43_power_down()
1031 ret = regulator_disable(cs42l43->vdd_p); in cs42l43_power_down()
1033 dev_err(cs42l43->dev, "Failed to disable vdd-p: %d\n", ret); in cs42l43_power_down()
1044 dev_set_drvdata(cs42l43->dev, cs42l43); in cs42l43_dev_probe()
1046 mutex_init(&cs42l43->pll_lock); in cs42l43_dev_probe()
1047 init_completion(&cs42l43->device_attach); in cs42l43_dev_probe()
1048 init_completion(&cs42l43->device_detach); in cs42l43_dev_probe()
1049 init_completion(&cs42l43->firmware_download); in cs42l43_dev_probe()
1050 INIT_WORK(&cs42l43->boot_work, cs42l43_boot_work); in cs42l43_dev_probe()
1052 regcache_cache_only(cs42l43->regmap, true); in cs42l43_dev_probe()
1054 cs42l43->reset = devm_gpiod_get_optional(cs42l43->dev, "reset", GPIOD_OUT_LOW); in cs42l43_dev_probe()
1055 if (IS_ERR(cs42l43->reset)) in cs42l43_dev_probe()
1056 return dev_err_probe(cs42l43->dev, PTR_ERR(cs42l43->reset), in cs42l43_dev_probe()
1059 cs42l43->vdd_p = devm_regulator_get(cs42l43->dev, "vdd-p"); in cs42l43_dev_probe()
1060 if (IS_ERR(cs42l43->vdd_p)) in cs42l43_dev_probe()
1061 return dev_err_probe(cs42l43->dev, PTR_ERR(cs42l43->vdd_p), in cs42l43_dev_probe()
1062 "Failed to get vdd-p\n"); in cs42l43_dev_probe()
1064 cs42l43->vdd_d = devm_regulator_get(cs42l43->dev, "vdd-d"); in cs42l43_dev_probe()
1065 if (IS_ERR(cs42l43->vdd_d)) in cs42l43_dev_probe()
1066 return dev_err_probe(cs42l43->dev, PTR_ERR(cs42l43->vdd_d), in cs42l43_dev_probe()
1067 "Failed to get vdd-d\n"); in cs42l43_dev_probe()
1072 cs42l43->core_supplies[i].supply = cs42l43_core_supplies[i]; in cs42l43_dev_probe()
1074 ret = devm_regulator_bulk_get(cs42l43->dev, CS42L43_N_SUPPLIES, in cs42l43_dev_probe()
1075 cs42l43->core_supplies); in cs42l43_dev_probe()
1077 return dev_err_probe(cs42l43->dev, ret, in cs42l43_dev_probe()
1084 pm_runtime_set_autosuspend_delay(cs42l43->dev, CS42L43_AUTOSUSPEND_TIME_MS); in cs42l43_dev_probe()
1085 pm_runtime_use_autosuspend(cs42l43->dev); in cs42l43_dev_probe()
1086 pm_runtime_set_active(cs42l43->dev); in cs42l43_dev_probe()
1091 pm_runtime_get_noresume(cs42l43->dev); in cs42l43_dev_probe()
1092 ret = devm_pm_runtime_enable(cs42l43->dev); in cs42l43_dev_probe()
1096 queue_work(system_long_wq, &cs42l43->boot_work); in cs42l43_dev_probe()
1124 dev_err(cs42l43->dev, "Failed to force suspend: %d\n", ret); in cs42l43_suspend()
1149 dev_err(cs42l43->dev, "Failed to force resume: %d\n", ret); in cs42l43_resume()
1165 regcache_cache_only(cs42l43->regmap, true); in cs42l43_runtime_suspend()
1180 ret = regmap_read(cs42l43->regmap, CS42L43_RELID, &reset_canary); in cs42l43_runtime_resume()
1182 dev_err(cs42l43->dev, "Failed to check reset canary: %d\n", ret); in cs42l43_runtime_resume()
1188 * If the canary has cleared the chip has reset, re-handle the in cs42l43_runtime_resume()
1195 regcache_mark_dirty(cs42l43->regmap); in cs42l43_runtime_resume()
1198 ret = regcache_sync(cs42l43->regmap); in cs42l43_runtime_resume()
1200 dev_err(cs42l43->dev, "Failed to restore register cache: %d\n", ret); in cs42l43_runtime_resume()
1207 regcache_cache_only(cs42l43->regmap, true); in cs42l43_runtime_resume()