1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * max8907.c - mfd driver for MAX8907 4 * 5 * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com> 6 * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved. 7 */ 8 9 #include <linux/err.h> 10 #include <linux/i2c.h> 11 #include <linux/init.h> 12 #include <linux/interrupt.h> 13 #include <linux/irq.h> 14 #include <linux/mfd/core.h> 15 #include <linux/mfd/max8907.h> 16 #include <linux/module.h> 17 #include <linux/of.h> 18 #include <linux/regmap.h> 19 #include <linux/slab.h> 20 21 static const struct mfd_cell max8907_cells[] = { 22 { .name = "max8907-regulator", }, 23 { .name = "max8907-rtc", }, 24 }; 25 26 static bool max8907_gen_is_volatile_reg(struct device *dev, unsigned int reg) 27 { 28 switch (reg) { 29 case MAX8907_REG_ON_OFF_IRQ1: 30 case MAX8907_REG_ON_OFF_STAT: 31 case MAX8907_REG_ON_OFF_IRQ2: 32 case MAX8907_REG_CHG_IRQ1: 33 case MAX8907_REG_CHG_IRQ2: 34 case MAX8907_REG_CHG_STAT: 35 return true; 36 default: 37 return false; 38 } 39 } 40 41 static bool max8907_gen_is_precious_reg(struct device *dev, unsigned int reg) 42 { 43 switch (reg) { 44 case MAX8907_REG_ON_OFF_IRQ1: 45 case MAX8907_REG_ON_OFF_IRQ2: 46 case MAX8907_REG_CHG_IRQ1: 47 case MAX8907_REG_CHG_IRQ2: 48 return true; 49 default: 50 return false; 51 } 52 } 53 54 static bool max8907_gen_is_writeable_reg(struct device *dev, unsigned int reg) 55 { 56 return !max8907_gen_is_volatile_reg(dev, reg); 57 } 58 59 static const struct regmap_config max8907_regmap_gen_config = { 60 .reg_bits = 8, 61 .val_bits = 8, 62 .volatile_reg = max8907_gen_is_volatile_reg, 63 .precious_reg = max8907_gen_is_precious_reg, 64 .writeable_reg = max8907_gen_is_writeable_reg, 65 .max_register = MAX8907_REG_LDO20VOUT, 66 .cache_type = REGCACHE_RBTREE, 67 }; 68 69 static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg) 70 { 71 if (reg <= MAX8907_REG_RTC_YEAR2) 72 return true; 73 74 switch (reg) { 75 case MAX8907_REG_RTC_STATUS: 76 case MAX8907_REG_RTC_IRQ: 77 return true; 78 default: 79 return false; 80 } 81 } 82 83 static bool max8907_rtc_is_precious_reg(struct device *dev, unsigned int reg) 84 { 85 switch (reg) { 86 case MAX8907_REG_RTC_IRQ: 87 return true; 88 default: 89 return false; 90 } 91 } 92 93 static bool max8907_rtc_is_writeable_reg(struct device *dev, unsigned int reg) 94 { 95 switch (reg) { 96 case MAX8907_REG_RTC_STATUS: 97 case MAX8907_REG_RTC_IRQ: 98 return false; 99 default: 100 return true; 101 } 102 } 103 104 static const struct regmap_config max8907_regmap_rtc_config = { 105 .reg_bits = 8, 106 .val_bits = 8, 107 .volatile_reg = max8907_rtc_is_volatile_reg, 108 .precious_reg = max8907_rtc_is_precious_reg, 109 .writeable_reg = max8907_rtc_is_writeable_reg, 110 .max_register = MAX8907_REG_MPL_CNTL, 111 .cache_type = REGCACHE_RBTREE, 112 }; 113 114 static const struct regmap_irq max8907_chg_irqs[] = { 115 { .reg_offset = 0, .mask = 1 << 0, }, 116 { .reg_offset = 0, .mask = 1 << 1, }, 117 { .reg_offset = 0, .mask = 1 << 2, }, 118 { .reg_offset = 1, .mask = 1 << 0, }, 119 { .reg_offset = 1, .mask = 1 << 1, }, 120 { .reg_offset = 1, .mask = 1 << 2, }, 121 { .reg_offset = 1, .mask = 1 << 3, }, 122 { .reg_offset = 1, .mask = 1 << 4, }, 123 { .reg_offset = 1, .mask = 1 << 5, }, 124 { .reg_offset = 1, .mask = 1 << 6, }, 125 { .reg_offset = 1, .mask = 1 << 7, }, 126 }; 127 128 static const struct regmap_irq_chip max8907_chg_irq_chip = { 129 .name = "max8907 chg", 130 .status_base = MAX8907_REG_CHG_IRQ1, 131 .mask_base = MAX8907_REG_CHG_IRQ1_MASK, 132 .wake_base = MAX8907_REG_CHG_IRQ1_MASK, 133 .irq_reg_stride = MAX8907_REG_CHG_IRQ2 - MAX8907_REG_CHG_IRQ1, 134 .num_regs = 2, 135 .irqs = max8907_chg_irqs, 136 .num_irqs = ARRAY_SIZE(max8907_chg_irqs), 137 }; 138 139 static const struct regmap_irq max8907_on_off_irqs[] = { 140 { .reg_offset = 0, .mask = 1 << 0, }, 141 { .reg_offset = 0, .mask = 1 << 1, }, 142 { .reg_offset = 0, .mask = 1 << 2, }, 143 { .reg_offset = 0, .mask = 1 << 3, }, 144 { .reg_offset = 0, .mask = 1 << 4, }, 145 { .reg_offset = 0, .mask = 1 << 5, }, 146 { .reg_offset = 0, .mask = 1 << 6, }, 147 { .reg_offset = 0, .mask = 1 << 7, }, 148 { .reg_offset = 1, .mask = 1 << 0, }, 149 { .reg_offset = 1, .mask = 1 << 1, }, 150 }; 151 152 static const struct regmap_irq_chip max8907_on_off_irq_chip = { 153 .name = "max8907 on_off", 154 .status_base = MAX8907_REG_ON_OFF_IRQ1, 155 .mask_base = MAX8907_REG_ON_OFF_IRQ1_MASK, 156 .irq_reg_stride = MAX8907_REG_ON_OFF_IRQ2 - MAX8907_REG_ON_OFF_IRQ1, 157 .num_regs = 2, 158 .irqs = max8907_on_off_irqs, 159 .num_irqs = ARRAY_SIZE(max8907_on_off_irqs), 160 }; 161 162 static const struct regmap_irq max8907_rtc_irqs[] = { 163 { .reg_offset = 0, .mask = 1 << 2, }, 164 { .reg_offset = 0, .mask = 1 << 3, }, 165 }; 166 167 static const struct regmap_irq_chip max8907_rtc_irq_chip = { 168 .name = "max8907 rtc", 169 .status_base = MAX8907_REG_RTC_IRQ, 170 .mask_base = MAX8907_REG_RTC_IRQ_MASK, 171 .num_regs = 1, 172 .irqs = max8907_rtc_irqs, 173 .num_irqs = ARRAY_SIZE(max8907_rtc_irqs), 174 }; 175 176 static struct max8907 *max8907_pm_off; 177 static void max8907_power_off(void) 178 { 179 regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG, 180 MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF); 181 } 182 183 static int max8907_i2c_probe(struct i2c_client *i2c) 184 { 185 struct max8907 *max8907; 186 int ret; 187 struct max8907_platform_data *pdata = dev_get_platdata(&i2c->dev); 188 bool pm_off = false; 189 190 if (pdata) 191 pm_off = pdata->pm_off; 192 else if (i2c->dev.of_node) 193 pm_off = of_property_read_bool(i2c->dev.of_node, 194 "maxim,system-power-controller"); 195 196 max8907 = devm_kzalloc(&i2c->dev, sizeof(struct max8907), GFP_KERNEL); 197 if (!max8907) { 198 ret = -ENOMEM; 199 goto err_alloc_drvdata; 200 } 201 202 max8907->dev = &i2c->dev; 203 max8907->i2c_gen = i2c; 204 i2c_set_clientdata(i2c, max8907); 205 max8907->regmap_gen = devm_regmap_init_i2c(i2c, 206 &max8907_regmap_gen_config); 207 if (IS_ERR(max8907->regmap_gen)) { 208 ret = PTR_ERR(max8907->regmap_gen); 209 dev_err(&i2c->dev, "gen regmap init failed: %d\n", ret); 210 goto err_regmap_gen; 211 } 212 213 max8907->i2c_rtc = i2c_new_dummy_device(i2c->adapter, MAX8907_RTC_I2C_ADDR); 214 if (IS_ERR(max8907->i2c_rtc)) { 215 ret = PTR_ERR(max8907->i2c_rtc); 216 goto err_dummy_rtc; 217 } 218 i2c_set_clientdata(max8907->i2c_rtc, max8907); 219 max8907->regmap_rtc = devm_regmap_init_i2c(max8907->i2c_rtc, 220 &max8907_regmap_rtc_config); 221 if (IS_ERR(max8907->regmap_rtc)) { 222 ret = PTR_ERR(max8907->regmap_rtc); 223 dev_err(&i2c->dev, "rtc regmap init failed: %d\n", ret); 224 goto err_regmap_rtc; 225 } 226 227 ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq, 228 IRQF_ONESHOT | IRQF_SHARED, 229 -1, &max8907_chg_irq_chip, 230 &max8907->irqc_chg); 231 if (ret != 0) { 232 dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret); 233 goto err_irqc_chg; 234 } 235 ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq, 236 IRQF_ONESHOT | IRQF_SHARED, -1, 237 &max8907_on_off_irq_chip, 238 &max8907->irqc_on_off); 239 if (ret != 0) { 240 dev_err(&i2c->dev, "failed to add on off irq chip: %d\n", ret); 241 goto err_irqc_on_off; 242 } 243 ret = regmap_add_irq_chip(max8907->regmap_rtc, max8907->i2c_gen->irq, 244 IRQF_ONESHOT | IRQF_SHARED, -1, 245 &max8907_rtc_irq_chip, 246 &max8907->irqc_rtc); 247 if (ret != 0) { 248 dev_err(&i2c->dev, "failed to add rtc irq chip: %d\n", ret); 249 goto err_irqc_rtc; 250 } 251 252 ret = mfd_add_devices(max8907->dev, -1, max8907_cells, 253 ARRAY_SIZE(max8907_cells), NULL, 0, NULL); 254 if (ret != 0) { 255 dev_err(&i2c->dev, "failed to add MFD devices %d\n", ret); 256 goto err_add_devices; 257 } 258 259 if (pm_off && !pm_power_off) { 260 max8907_pm_off = max8907; 261 pm_power_off = max8907_power_off; 262 } 263 264 return 0; 265 266 err_add_devices: 267 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc); 268 err_irqc_rtc: 269 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off); 270 err_irqc_on_off: 271 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg); 272 err_irqc_chg: 273 err_regmap_rtc: 274 i2c_unregister_device(max8907->i2c_rtc); 275 err_dummy_rtc: 276 err_regmap_gen: 277 err_alloc_drvdata: 278 return ret; 279 } 280 281 static void max8907_i2c_remove(struct i2c_client *i2c) 282 { 283 struct max8907 *max8907 = i2c_get_clientdata(i2c); 284 285 mfd_remove_devices(max8907->dev); 286 287 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc); 288 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off); 289 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg); 290 291 i2c_unregister_device(max8907->i2c_rtc); 292 } 293 294 #ifdef CONFIG_OF 295 static const struct of_device_id max8907_of_match[] = { 296 { .compatible = "maxim,max8907" }, 297 { }, 298 }; 299 MODULE_DEVICE_TABLE(of, max8907_of_match); 300 #endif 301 302 static const struct i2c_device_id max8907_i2c_id[] = { 303 {"max8907", 0}, 304 {} 305 }; 306 MODULE_DEVICE_TABLE(i2c, max8907_i2c_id); 307 308 static struct i2c_driver max8907_i2c_driver = { 309 .driver = { 310 .name = "max8907", 311 .of_match_table = of_match_ptr(max8907_of_match), 312 }, 313 .probe = max8907_i2c_probe, 314 .remove = max8907_i2c_remove, 315 .id_table = max8907_i2c_id, 316 }; 317 318 static int __init max8907_i2c_init(void) 319 { 320 int ret = -ENODEV; 321 322 ret = i2c_add_driver(&max8907_i2c_driver); 323 if (ret != 0) 324 pr_err("Failed to register I2C driver: %d\n", ret); 325 326 return ret; 327 } 328 subsys_initcall(max8907_i2c_init); 329 330 static void __exit max8907_i2c_exit(void) 331 { 332 i2c_del_driver(&max8907_i2c_driver); 333 } 334 module_exit(max8907_i2c_exit); 335 336 MODULE_DESCRIPTION("MAX8907 multi-function core driver"); 337 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>"); 338 MODULE_LICENSE("GPL v2"); 339