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