max77843.c (5540B)
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// MFD core driver for the Maxim MAX77843 4// 5// Copyright (C) 2015 Samsung Electronics 6// Author: Jaewon Kim <jaewon02.kim@samsung.com> 7// Author: Beomho Seo <beomho.seo@samsung.com> 8 9#include <linux/err.h> 10#include <linux/i2c.h> 11#include <linux/init.h> 12#include <linux/interrupt.h> 13#include <linux/mfd/core.h> 14#include <linux/mfd/max77693-common.h> 15#include <linux/mfd/max77843-private.h> 16#include <linux/of_device.h> 17#include <linux/platform_device.h> 18 19static const struct mfd_cell max77843_devs[] = { 20 { 21 .name = "max77843-muic", 22 .of_compatible = "maxim,max77843-muic", 23 }, { 24 .name = "max77843-regulator", 25 .of_compatible = "maxim,max77843-regulator", 26 }, { 27 .name = "max77843-charger", 28 .of_compatible = "maxim,max77843-charger" 29 }, { 30 .name = "max77843-fuelgauge", 31 .of_compatible = "maxim,max77843-fuelgauge", 32 }, { 33 .name = "max77843-haptic", 34 .of_compatible = "maxim,max77843-haptic", 35 }, 36}; 37 38static const struct regmap_config max77843_charger_regmap_config = { 39 .reg_bits = 8, 40 .val_bits = 8, 41 .max_register = MAX77843_CHG_REG_END, 42}; 43 44static const struct regmap_config max77843_regmap_config = { 45 .reg_bits = 8, 46 .val_bits = 8, 47 .max_register = MAX77843_SYS_REG_END, 48}; 49 50static const struct regmap_irq max77843_irqs[] = { 51 /* TOPSYS interrupts */ 52 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSUVLO_INT, }, 53 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSOVLO_INT, }, 54 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TSHDN_INT, }, 55 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TM_INT, }, 56}; 57 58static const struct regmap_irq_chip max77843_irq_chip = { 59 .name = "max77843", 60 .status_base = MAX77843_SYS_REG_SYSINTSRC, 61 .mask_base = MAX77843_SYS_REG_SYSINTMASK, 62 .mask_invert = false, 63 .num_regs = 1, 64 .irqs = max77843_irqs, 65 .num_irqs = ARRAY_SIZE(max77843_irqs), 66}; 67 68/* Charger and Charger regulator use same regmap. */ 69static int max77843_chg_init(struct max77693_dev *max77843) 70{ 71 int ret; 72 73 max77843->i2c_chg = i2c_new_dummy_device(max77843->i2c->adapter, I2C_ADDR_CHG); 74 if (IS_ERR(max77843->i2c_chg)) { 75 dev_err(&max77843->i2c->dev, 76 "Cannot allocate I2C device for Charger\n"); 77 return PTR_ERR(max77843->i2c_chg); 78 } 79 i2c_set_clientdata(max77843->i2c_chg, max77843); 80 81 max77843->regmap_chg = devm_regmap_init_i2c(max77843->i2c_chg, 82 &max77843_charger_regmap_config); 83 if (IS_ERR(max77843->regmap_chg)) { 84 ret = PTR_ERR(max77843->regmap_chg); 85 goto err_chg_i2c; 86 } 87 88 return 0; 89 90err_chg_i2c: 91 i2c_unregister_device(max77843->i2c_chg); 92 93 return ret; 94} 95 96static int max77843_probe(struct i2c_client *i2c, 97 const struct i2c_device_id *id) 98{ 99 struct max77693_dev *max77843; 100 unsigned int reg_data; 101 int ret; 102 103 max77843 = devm_kzalloc(&i2c->dev, sizeof(*max77843), GFP_KERNEL); 104 if (!max77843) 105 return -ENOMEM; 106 107 i2c_set_clientdata(i2c, max77843); 108 max77843->dev = &i2c->dev; 109 max77843->i2c = i2c; 110 max77843->irq = i2c->irq; 111 max77843->type = id->driver_data; 112 113 max77843->regmap = devm_regmap_init_i2c(i2c, 114 &max77843_regmap_config); 115 if (IS_ERR(max77843->regmap)) { 116 dev_err(&i2c->dev, "Failed to allocate topsys register map\n"); 117 return PTR_ERR(max77843->regmap); 118 } 119 120 ret = regmap_add_irq_chip(max77843->regmap, max77843->irq, 121 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 122 0, &max77843_irq_chip, &max77843->irq_data_topsys); 123 if (ret) { 124 dev_err(&i2c->dev, "Failed to add TOPSYS IRQ chip\n"); 125 return ret; 126 } 127 128 ret = regmap_read(max77843->regmap, 129 MAX77843_SYS_REG_PMICID, ®_data); 130 if (ret < 0) { 131 dev_err(&i2c->dev, "Failed to read PMIC ID\n"); 132 goto err_pmic_id; 133 } 134 dev_info(&i2c->dev, "device ID: 0x%x\n", reg_data); 135 136 ret = max77843_chg_init(max77843); 137 if (ret) { 138 dev_err(&i2c->dev, "Failed to init Charger\n"); 139 goto err_pmic_id; 140 } 141 142 ret = regmap_update_bits(max77843->regmap, 143 MAX77843_SYS_REG_INTSRCMASK, 144 MAX77843_INTSRC_MASK_MASK, 145 (unsigned int)~MAX77843_INTSRC_MASK_MASK); 146 if (ret < 0) { 147 dev_err(&i2c->dev, "Failed to unmask interrupt source\n"); 148 goto err_pmic_id; 149 } 150 151 ret = mfd_add_devices(max77843->dev, -1, max77843_devs, 152 ARRAY_SIZE(max77843_devs), NULL, 0, NULL); 153 if (ret < 0) { 154 dev_err(&i2c->dev, "Failed to add mfd device\n"); 155 goto err_pmic_id; 156 } 157 158 device_init_wakeup(max77843->dev, true); 159 160 return 0; 161 162err_pmic_id: 163 regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys); 164 165 return ret; 166} 167 168static const struct of_device_id max77843_dt_match[] = { 169 { .compatible = "maxim,max77843", }, 170 { }, 171}; 172 173static const struct i2c_device_id max77843_id[] = { 174 { "max77843", TYPE_MAX77843, }, 175 { }, 176}; 177 178static int __maybe_unused max77843_suspend(struct device *dev) 179{ 180 struct i2c_client *i2c = to_i2c_client(dev); 181 struct max77693_dev *max77843 = i2c_get_clientdata(i2c); 182 183 disable_irq(max77843->irq); 184 if (device_may_wakeup(dev)) 185 enable_irq_wake(max77843->irq); 186 187 return 0; 188} 189 190static int __maybe_unused max77843_resume(struct device *dev) 191{ 192 struct i2c_client *i2c = to_i2c_client(dev); 193 struct max77693_dev *max77843 = i2c_get_clientdata(i2c); 194 195 if (device_may_wakeup(dev)) 196 disable_irq_wake(max77843->irq); 197 enable_irq(max77843->irq); 198 199 return 0; 200} 201 202static SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume); 203 204static struct i2c_driver max77843_i2c_driver = { 205 .driver = { 206 .name = "max77843", 207 .pm = &max77843_pm, 208 .of_match_table = max77843_dt_match, 209 .suppress_bind_attrs = true, 210 }, 211 .probe = max77843_probe, 212 .id_table = max77843_id, 213}; 214 215static int __init max77843_i2c_init(void) 216{ 217 return i2c_add_driver(&max77843_i2c_driver); 218} 219subsys_initcall(max77843_i2c_init);