From cf9610f9116d55c5a66ef9f1faecacabd93a9322 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 24 Aug 2026 08:46:03 -0700 Subject: Merge tag 'pinctrl-v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl Pull pin control updates from Linus Walleij: "Core changes: - Use the non-blocking mux_state_try_select() in the generic MUX pin control back-end - Free pin maps on pinctrl_generic_to_map() failure in the core helpers New hardware pin control: - Qualcomm Maili TLMM SoC, PMG1110 PMIC, and Eliza LPASS LPI TLMM SoC (this is for the low power audio, LPASS = Low Power Audio SubSystem portions) - Upboard support on top of the Intel pin controller - Apple T6030 and T6031 support (just compatible strings) - Samsung Exynos 8855 SoC - Mediatek MT6858 SoC - Rockchip RK3308B and RV1106 SoCs - Airoha EN7523 and AN7563 SoCs Improvements: - Qualcomm TLMM GPIOs are unconditionally marked as wakeup capable - Qualcomm improvements on top of the Qualcomm PDC (power domain controller) irqchip improvements from tglx:s tree - Qualcomm IPQ806x and IPQ9650 non-urgent pin grop fixups - The NPCM8xx driver has been put into shape fixing many pin and group definitions - Some non-urgent Tegra 264 pin assignments are fixed up - Some non-urgent fixups to Airoha AN7581 and AN7583 registers and pin assignments, missing features etc" * tag 'pinctrl-v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (130 commits) dt-bindings: pinctrl: Convert TI DA850 pupd to DT schema pinctrl: meson: sync some modify from A4 pinctrl: meson: a4: Add input enable pin configuration pinctrl: realtek: rtd1625: remove unused group name spdif_sel pinctrl: realtek: rtd1625: fix base_bit for VE4 GPIO 13 dt-bindings: pinctrl: microchip,pic32mzda-pinctrl: Convert to DT schema Revert "Merge branch 'ib-rsk7204' into devel" pinctrl: rockchip: Add RV1106 pinctrl support dt-bindings: pinctrl: rockchip: Add RV1106 compatible pinctrl: rockchip: Decode drive strength in the get function pinctrl: fix PINCTRL_GENERIC_MUX not always being selectable pinctrl: airoha: add support of an7563 SoC dt-bindings: pinctrl: airoha: add support of an7563 pin controller pinctrl: airoha: try to find chip scu node by phandle first pinctrl: airoha: add support of en7523 SoC dt-bindings: pinctrl: airoha: add support of en7523 pin controller pinctrl: airoha: an7583: add support for olt pinmux pinctrl: airoha: an7583: add support for pon_alt pinmux pinctrl: airoha: an7583: add support for npu_uart pinmux dt-bindings: pinctrl: airoha: an7583: add missed features ... --- drivers/mfd/max77705.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 drivers/mfd/max77705.c (limited to 'drivers/mfd/max77705.c') diff --git a/drivers/mfd/max77705.c b/drivers/mfd/max77705.c new file mode 100644 index 000000000..e98c76d6b --- /dev/null +++ b/drivers/mfd/max77705.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Maxim MAX77705 PMIC core driver + * + * Copyright (C) 2025 Dzmitry Sankouski + **/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mfd_cell max77705_devs[] = { + MFD_CELL_OF("max77705-rgb", NULL, NULL, 0, 0, "maxim,max77705-rgb"), + MFD_CELL_OF("max77705-charger", NULL, NULL, 0, 0, "maxim,max77705-charger"), + MFD_CELL_OF("max77705-haptic", NULL, NULL, 0, 0, "maxim,max77705-haptic"), +}; + +static const struct regmap_range max77705_readable_ranges[] = { + regmap_reg_range(MAX77705_PMIC_REG_PMICID1, MAX77705_PMIC_REG_BSTOUT_MASK), + regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), + regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2), + regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2), + regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET), +}; + +static const struct regmap_range max77705_writable_ranges[] = { + regmap_reg_range(MAX77705_PMIC_REG_MAINCTRL1, MAX77705_PMIC_REG_BSTOUT_MASK), + regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), + regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2), + regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), + regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2), + regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET), +}; + +static const struct regmap_access_table max77705_readable_table = { + .yes_ranges = max77705_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(max77705_readable_ranges), +}; + +static const struct regmap_access_table max77705_writable_table = { + .yes_ranges = max77705_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(max77705_writable_ranges), +}; + +static const struct regmap_config max77705_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .rd_table = &max77705_readable_table, + .wr_table = &max77705_writable_table, + .max_register = MAX77705_PMIC_REG_USBC_RESET, +}; + +static const struct regmap_irq max77705_irqs[] = { + { .mask = MAX77705_SRC_IRQ_CHG, }, + { .mask = MAX77705_SRC_IRQ_TOP, }, + { .mask = MAX77705_SRC_IRQ_FG, }, + { .mask = MAX77705_SRC_IRQ_USBC, }, +}; + +static const struct regmap_irq_chip max77705_irq_chip = { + .name = "max77705", + .status_base = MAX77705_PMIC_REG_INTSRC, + .ack_base = MAX77705_PMIC_REG_INTSRC, + .mask_base = MAX77705_PMIC_REG_INTSRC_MASK, + .num_regs = 1, + .irqs = max77705_irqs, + .num_irqs = ARRAY_SIZE(max77705_irqs), +}; + +static int max77705_i2c_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct max77693_dev *max77705; + struct regmap_irq_chip_data *irq_data; + struct irq_domain *domain; + enum max77705_hw_rev pmic_rev; + unsigned int pmic_rev_value; + int ret; + + max77705 = devm_kzalloc(dev, sizeof(*max77705), GFP_KERNEL); + if (!max77705) + return -ENOMEM; + + max77705->i2c = i2c; + max77705->type = TYPE_MAX77705; + i2c_set_clientdata(i2c, max77705); + + max77705->regmap = devm_regmap_init_i2c(i2c, &max77705_regmap_config); + if (IS_ERR(max77705->regmap)) + return PTR_ERR(max77705->regmap); + + ret = regmap_read(max77705->regmap, MAX77705_PMIC_REG_PMICREV, &pmic_rev_value); + if (ret < 0) + return -ENODEV; + + pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK; + if (pmic_rev != MAX77705_PASS3) + return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev); + + /* Active Discharge Enable */ + regmap_update_bits(max77705->regmap, MAX77705_PMIC_REG_MAINCTRL1, 1, 1); + + ret = devm_regmap_add_irq_chip(dev, max77705->regmap, + i2c->irq, + IRQF_ONESHOT, 0, + &max77705_irq_chip, + &irq_data); + if (ret) + return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); + + domain = regmap_irq_get_domain(irq_data); + + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, + max77705_devs, ARRAY_SIZE(max77705_devs), + NULL, 0, domain); + if (ret) + return dev_err_probe(dev, ret, "Failed to register child devices\n"); + + ret = devm_device_init_wakeup(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to init wakeup\n"); + + return 0; +} + +static int max77705_suspend(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + + disable_irq(i2c->irq); + + if (device_may_wakeup(dev)) + enable_irq_wake(i2c->irq); + + return 0; +} + +static int max77705_resume(struct device *dev) +{ + struct i2c_client *i2c = to_i2c_client(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(i2c->irq); + + enable_irq(i2c->irq); + + return 0; +} +static DEFINE_SIMPLE_DEV_PM_OPS(max77705_pm_ops, max77705_suspend, max77705_resume); + +static const struct of_device_id max77705_i2c_of_match[] = { + { .compatible = "maxim,max77705" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77705_i2c_of_match); + +static struct i2c_driver max77705_i2c_driver = { + .driver = { + .name = "max77705", + .of_match_table = max77705_i2c_of_match, + .pm = pm_sleep_ptr(&max77705_pm_ops), + }, + .probe = max77705_i2c_probe +}; +module_i2c_driver(max77705_i2c_driver); + +MODULE_DESCRIPTION("Maxim MAX77705 PMIC core driver"); +MODULE_AUTHOR("Dzmitry Sankouski "); +MODULE_LICENSE("GPL"); -- cgit v1.3.1