1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Maxim MAX77705 PMIC core driver 4 * 5 * Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com> 6 **/ 7 #include <linux/i2c.h> 8 #include <linux/interrupt.h> 9 #include <linux/mfd/core.h> 10 #include <linux/mfd/max77705-private.h> 11 #include <linux/mfd/max77693-common.h> 12 #include <linux/pm.h> 13 #include <linux/power/max17042_battery.h> 14 #include <linux/module.h> 15 #include <linux/regmap.h> 16 #include <linux/of.h> 17 18 static struct mfd_cell max77705_devs[] = { 19 MFD_CELL_OF("max77705-rgb", NULL, NULL, 0, 0, "maxim,max77705-rgb"), 20 MFD_CELL_OF("max77705-charger", NULL, NULL, 0, 0, "maxim,max77705-charger"), 21 MFD_CELL_OF("max77705-haptic", NULL, NULL, 0, 0, "maxim,max77705-haptic"), 22 }; 23 24 static const struct regmap_range max77705_readable_ranges[] = { 25 regmap_reg_range(MAX77705_PMIC_REG_PMICID1, MAX77705_PMIC_REG_BSTOUT_MASK), 26 regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29), 27 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), 28 regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2), 29 regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK), 30 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), 31 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2), 32 regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET), 33 }; 34 35 static const struct regmap_range max77705_writable_ranges[] = { 36 regmap_reg_range(MAX77705_PMIC_REG_MAINCTRL1, MAX77705_PMIC_REG_BSTOUT_MASK), 37 regmap_reg_range(MAX77705_PMIC_REG_INTSRC, MAX77705_PMIC_REG_RESERVED_29), 38 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), 39 regmap_reg_range(MAX77705_PMIC_REG_MCONFIG, MAX77705_PMIC_REG_MCONFIG2), 40 regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK), 41 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1), 42 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2), 43 regmap_reg_range(MAX77705_PMIC_REG_SW_RESET, MAX77705_PMIC_REG_USBC_RESET), 44 }; 45 46 static const struct regmap_access_table max77705_readable_table = { 47 .yes_ranges = max77705_readable_ranges, 48 .n_yes_ranges = ARRAY_SIZE(max77705_readable_ranges), 49 }; 50 51 static const struct regmap_access_table max77705_writable_table = { 52 .yes_ranges = max77705_writable_ranges, 53 .n_yes_ranges = ARRAY_SIZE(max77705_writable_ranges), 54 }; 55 56 static const struct regmap_config max77705_regmap_config = { 57 .reg_bits = 8, 58 .val_bits = 8, 59 .rd_table = &max77705_readable_table, 60 .wr_table = &max77705_writable_table, 61 .max_register = MAX77705_PMIC_REG_USBC_RESET, 62 }; 63 64 static const struct regmap_irq max77705_topsys_irqs[] = { 65 { .mask = MAX77705_SYSTEM_IRQ_BSTEN_INT, }, 66 { .mask = MAX77705_SYSTEM_IRQ_SYSUVLO_INT, }, 67 { .mask = MAX77705_SYSTEM_IRQ_SYSOVLO_INT, }, 68 { .mask = MAX77705_SYSTEM_IRQ_TSHDN_INT, }, 69 { .mask = MAX77705_SYSTEM_IRQ_TM_INT, }, 70 }; 71 72 static const struct regmap_irq_chip max77705_topsys_irq_chip = { 73 .name = "max77705-topsys", 74 .status_base = MAX77705_PMIC_REG_SYSTEM_INT, 75 .mask_base = MAX77705_PMIC_REG_SYSTEM_INT_MASK, 76 .num_regs = 1, 77 .irqs = max77705_topsys_irqs, 78 .num_irqs = ARRAY_SIZE(max77705_topsys_irqs), 79 }; 80 81 static int max77705_i2c_probe(struct i2c_client *i2c) 82 { 83 struct device *dev = &i2c->dev; 84 struct max77693_dev *max77705; 85 struct regmap_irq_chip_data *irq_data; 86 struct irq_domain *domain; 87 enum max77705_hw_rev pmic_rev; 88 unsigned int pmic_rev_value; 89 int ret; 90 91 max77705 = devm_kzalloc(dev, sizeof(*max77705), GFP_KERNEL); 92 if (!max77705) 93 return -ENOMEM; 94 95 max77705->i2c = i2c; 96 max77705->type = TYPE_MAX77705; 97 i2c_set_clientdata(i2c, max77705); 98 99 max77705->regmap = devm_regmap_init_i2c(i2c, &max77705_regmap_config); 100 if (IS_ERR(max77705->regmap)) 101 return PTR_ERR(max77705->regmap); 102 103 ret = regmap_read(max77705->regmap, MAX77705_PMIC_REG_PMICREV, &pmic_rev_value); 104 if (ret < 0) 105 return -ENODEV; 106 107 pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK; 108 if (pmic_rev != MAX77705_PASS3) 109 return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev); 110 111 ret = devm_regmap_add_irq_chip(dev, max77705->regmap, 112 i2c->irq, 113 IRQF_ONESHOT | IRQF_SHARED, 0, 114 &max77705_topsys_irq_chip, 115 &irq_data); 116 if (ret) 117 return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); 118 119 /* Unmask interrupts from all blocks in interrupt source register */ 120 ret = regmap_update_bits(max77705->regmap, 121 MAX77705_PMIC_REG_INTSRC_MASK, 122 MAX77705_SRC_IRQ_ALL, (unsigned int)~MAX77705_SRC_IRQ_ALL); 123 if (ret < 0) 124 return dev_err_probe(dev, ret, "Could not unmask interrupts in INTSRC\n"); 125 126 domain = regmap_irq_get_domain(irq_data); 127 128 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, 129 max77705_devs, ARRAY_SIZE(max77705_devs), 130 NULL, 0, domain); 131 if (ret) 132 return dev_err_probe(dev, ret, "Failed to register child devices\n"); 133 134 ret = devm_device_init_wakeup(dev); 135 if (ret) 136 return dev_err_probe(dev, ret, "Failed to init wakeup\n"); 137 138 return 0; 139 } 140 141 static int max77705_suspend(struct device *dev) 142 { 143 struct i2c_client *i2c = to_i2c_client(dev); 144 145 disable_irq(i2c->irq); 146 147 if (device_may_wakeup(dev)) 148 enable_irq_wake(i2c->irq); 149 150 return 0; 151 } 152 153 static int max77705_resume(struct device *dev) 154 { 155 struct i2c_client *i2c = to_i2c_client(dev); 156 157 if (device_may_wakeup(dev)) 158 disable_irq_wake(i2c->irq); 159 160 enable_irq(i2c->irq); 161 162 return 0; 163 } 164 DEFINE_SIMPLE_DEV_PM_OPS(max77705_pm_ops, max77705_suspend, max77705_resume); 165 166 static const struct of_device_id max77705_i2c_of_match[] = { 167 { .compatible = "maxim,max77705" }, 168 { } 169 }; 170 MODULE_DEVICE_TABLE(of, max77705_i2c_of_match); 171 172 static struct i2c_driver max77705_i2c_driver = { 173 .driver = { 174 .name = "max77705", 175 .of_match_table = max77705_i2c_of_match, 176 .pm = pm_sleep_ptr(&max77705_pm_ops), 177 }, 178 .probe = max77705_i2c_probe 179 }; 180 module_i2c_driver(max77705_i2c_driver); 181 182 MODULE_DESCRIPTION("Maxim MAX77705 PMIC core driver"); 183 MODULE_AUTHOR("Dzmitry Sankouski <dsankouski@gmail.com>"); 184 MODULE_LICENSE("GPL"); 185