max77693.c (10621B)
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// max77693.c - mfd core driver for the MAX 77693 4// 5// Copyright (C) 2012 Samsung Electronics 6// SangYoung Son <hello.son@samsung.com> 7// 8// This program is not provided / owned by Maxim Integrated Products. 9// 10// This driver is based on max8997.c 11 12#include <linux/module.h> 13#include <linux/slab.h> 14#include <linux/i2c.h> 15#include <linux/err.h> 16#include <linux/interrupt.h> 17#include <linux/of.h> 18#include <linux/pm_runtime.h> 19#include <linux/mutex.h> 20#include <linux/mfd/core.h> 21#include <linux/mfd/max77693.h> 22#include <linux/mfd/max77693-common.h> 23#include <linux/mfd/max77693-private.h> 24#include <linux/regulator/machine.h> 25#include <linux/regmap.h> 26 27#define I2C_ADDR_PMIC (0xCC >> 1) /* Charger, Flash LED */ 28#define I2C_ADDR_MUIC (0x4A >> 1) 29#define I2C_ADDR_HAPTIC (0x90 >> 1) 30 31static const struct mfd_cell max77693_devs[] = { 32 { .name = "max77693-pmic", }, 33 { 34 .name = "max77693-charger", 35 .of_compatible = "maxim,max77693-charger", 36 }, 37 { 38 .name = "max77693-muic", 39 .of_compatible = "maxim,max77693-muic", 40 }, 41 { 42 .name = "max77693-haptic", 43 .of_compatible = "maxim,max77693-haptic", 44 }, 45 { 46 .name = "max77693-led", 47 .of_compatible = "maxim,max77693-led", 48 }, 49}; 50 51static const struct regmap_config max77693_regmap_config = { 52 .reg_bits = 8, 53 .val_bits = 8, 54 .max_register = MAX77693_PMIC_REG_END, 55}; 56 57static const struct regmap_irq max77693_led_irqs[] = { 58 { .mask = LED_IRQ_FLED2_OPEN, }, 59 { .mask = LED_IRQ_FLED2_SHORT, }, 60 { .mask = LED_IRQ_FLED1_OPEN, }, 61 { .mask = LED_IRQ_FLED1_SHORT, }, 62 { .mask = LED_IRQ_MAX_FLASH, }, 63}; 64 65static const struct regmap_irq_chip max77693_led_irq_chip = { 66 .name = "max77693-led", 67 .status_base = MAX77693_LED_REG_FLASH_INT, 68 .mask_base = MAX77693_LED_REG_FLASH_INT_MASK, 69 .mask_invert = false, 70 .num_regs = 1, 71 .irqs = max77693_led_irqs, 72 .num_irqs = ARRAY_SIZE(max77693_led_irqs), 73}; 74 75static const struct regmap_irq max77693_topsys_irqs[] = { 76 { .mask = TOPSYS_IRQ_T120C_INT, }, 77 { .mask = TOPSYS_IRQ_T140C_INT, }, 78 { .mask = TOPSYS_IRQ_LOWSYS_INT, }, 79}; 80 81static const struct regmap_irq_chip max77693_topsys_irq_chip = { 82 .name = "max77693-topsys", 83 .status_base = MAX77693_PMIC_REG_TOPSYS_INT, 84 .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK, 85 .mask_invert = false, 86 .num_regs = 1, 87 .irqs = max77693_topsys_irqs, 88 .num_irqs = ARRAY_SIZE(max77693_topsys_irqs), 89}; 90 91static const struct regmap_irq max77693_charger_irqs[] = { 92 { .mask = CHG_IRQ_BYP_I, }, 93 { .mask = CHG_IRQ_THM_I, }, 94 { .mask = CHG_IRQ_BAT_I, }, 95 { .mask = CHG_IRQ_CHG_I, }, 96 { .mask = CHG_IRQ_CHGIN_I, }, 97}; 98 99static const struct regmap_irq_chip max77693_charger_irq_chip = { 100 .name = "max77693-charger", 101 .status_base = MAX77693_CHG_REG_CHG_INT, 102 .mask_base = MAX77693_CHG_REG_CHG_INT_MASK, 103 .mask_invert = false, 104 .num_regs = 1, 105 .irqs = max77693_charger_irqs, 106 .num_irqs = ARRAY_SIZE(max77693_charger_irqs), 107}; 108 109static const struct regmap_config max77693_regmap_muic_config = { 110 .reg_bits = 8, 111 .val_bits = 8, 112 .max_register = MAX77693_MUIC_REG_END, 113}; 114 115static const struct regmap_irq max77693_muic_irqs[] = { 116 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, }, 117 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, }, 118 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, }, 119 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, }, 120 121 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, }, 122 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, }, 123 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, }, 124 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, }, 125 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, }, 126 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, }, 127 128 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, }, 129 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, }, 130 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, }, 131 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, }, 132 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, }, 133 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, }, 134}; 135 136static const struct regmap_irq_chip max77693_muic_irq_chip = { 137 .name = "max77693-muic", 138 .status_base = MAX77693_MUIC_REG_INT1, 139 .mask_base = MAX77693_MUIC_REG_INTMASK1, 140 .mask_invert = true, 141 .num_regs = 3, 142 .irqs = max77693_muic_irqs, 143 .num_irqs = ARRAY_SIZE(max77693_muic_irqs), 144}; 145 146static const struct regmap_config max77693_regmap_haptic_config = { 147 .reg_bits = 8, 148 .val_bits = 8, 149 .max_register = MAX77693_HAPTIC_REG_END, 150}; 151 152static int max77693_i2c_probe(struct i2c_client *i2c, 153 const struct i2c_device_id *id) 154{ 155 struct max77693_dev *max77693; 156 unsigned int reg_data; 157 int ret = 0; 158 159 max77693 = devm_kzalloc(&i2c->dev, 160 sizeof(struct max77693_dev), GFP_KERNEL); 161 if (max77693 == NULL) 162 return -ENOMEM; 163 164 i2c_set_clientdata(i2c, max77693); 165 max77693->dev = &i2c->dev; 166 max77693->i2c = i2c; 167 max77693->irq = i2c->irq; 168 max77693->type = id->driver_data; 169 170 max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); 171 if (IS_ERR(max77693->regmap)) { 172 ret = PTR_ERR(max77693->regmap); 173 dev_err(max77693->dev, "failed to allocate register map: %d\n", 174 ret); 175 return ret; 176 } 177 178 ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, 179 ®_data); 180 if (ret < 0) { 181 dev_err(max77693->dev, "device not found on this channel\n"); 182 return ret; 183 } else 184 dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); 185 186 max77693->i2c_muic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_MUIC); 187 if (IS_ERR(max77693->i2c_muic)) { 188 dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n"); 189 return PTR_ERR(max77693->i2c_muic); 190 } 191 i2c_set_clientdata(max77693->i2c_muic, max77693); 192 193 max77693->i2c_haptic = i2c_new_dummy_device(i2c->adapter, I2C_ADDR_HAPTIC); 194 if (IS_ERR(max77693->i2c_haptic)) { 195 dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n"); 196 ret = PTR_ERR(max77693->i2c_haptic); 197 goto err_i2c_haptic; 198 } 199 i2c_set_clientdata(max77693->i2c_haptic, max77693); 200 201 max77693->regmap_haptic = devm_regmap_init_i2c(max77693->i2c_haptic, 202 &max77693_regmap_haptic_config); 203 if (IS_ERR(max77693->regmap_haptic)) { 204 ret = PTR_ERR(max77693->regmap_haptic); 205 dev_err(max77693->dev, 206 "failed to initialize haptic register map: %d\n", ret); 207 goto err_regmap; 208 } 209 210 /* 211 * Initialize register map for MUIC device because use regmap-muic 212 * instance of MUIC device when irq of max77693 is initialized 213 * before call max77693-muic probe() function. 214 */ 215 max77693->regmap_muic = devm_regmap_init_i2c(max77693->i2c_muic, 216 &max77693_regmap_muic_config); 217 if (IS_ERR(max77693->regmap_muic)) { 218 ret = PTR_ERR(max77693->regmap_muic); 219 dev_err(max77693->dev, 220 "failed to allocate register map: %d\n", ret); 221 goto err_regmap; 222 } 223 224 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, 225 IRQF_ONESHOT | IRQF_SHARED, 0, 226 &max77693_led_irq_chip, 227 &max77693->irq_data_led); 228 if (ret) { 229 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); 230 goto err_regmap; 231 } 232 233 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, 234 IRQF_ONESHOT | IRQF_SHARED, 0, 235 &max77693_topsys_irq_chip, 236 &max77693->irq_data_topsys); 237 if (ret) { 238 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); 239 goto err_irq_topsys; 240 } 241 242 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, 243 IRQF_ONESHOT | IRQF_SHARED, 0, 244 &max77693_charger_irq_chip, 245 &max77693->irq_data_chg); 246 if (ret) { 247 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); 248 goto err_irq_charger; 249 } 250 251 ret = regmap_add_irq_chip(max77693->regmap_muic, max77693->irq, 252 IRQF_ONESHOT | IRQF_SHARED, 0, 253 &max77693_muic_irq_chip, 254 &max77693->irq_data_muic); 255 if (ret) { 256 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); 257 goto err_irq_muic; 258 } 259 260 /* Unmask interrupts from all blocks in interrupt source register */ 261 ret = regmap_update_bits(max77693->regmap, 262 MAX77693_PMIC_REG_INTSRC_MASK, 263 SRC_IRQ_ALL, (unsigned int)~SRC_IRQ_ALL); 264 if (ret < 0) { 265 dev_err(max77693->dev, 266 "Could not unmask interrupts in INTSRC: %d\n", 267 ret); 268 goto err_intsrc; 269 } 270 271 pm_runtime_set_active(max77693->dev); 272 273 ret = mfd_add_devices(max77693->dev, -1, max77693_devs, 274 ARRAY_SIZE(max77693_devs), NULL, 0, NULL); 275 if (ret < 0) 276 goto err_mfd; 277 278 return ret; 279 280err_mfd: 281 mfd_remove_devices(max77693->dev); 282err_intsrc: 283 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); 284err_irq_muic: 285 regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg); 286err_irq_charger: 287 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); 288err_irq_topsys: 289 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); 290err_regmap: 291 i2c_unregister_device(max77693->i2c_haptic); 292err_i2c_haptic: 293 i2c_unregister_device(max77693->i2c_muic); 294 return ret; 295} 296 297static int max77693_i2c_remove(struct i2c_client *i2c) 298{ 299 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 300 301 mfd_remove_devices(max77693->dev); 302 303 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); 304 regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg); 305 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); 306 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); 307 308 i2c_unregister_device(max77693->i2c_muic); 309 i2c_unregister_device(max77693->i2c_haptic); 310 311 return 0; 312} 313 314static const struct i2c_device_id max77693_i2c_id[] = { 315 { "max77693", TYPE_MAX77693 }, 316 { } 317}; 318MODULE_DEVICE_TABLE(i2c, max77693_i2c_id); 319 320static int max77693_suspend(struct device *dev) 321{ 322 struct i2c_client *i2c = to_i2c_client(dev); 323 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 324 325 if (device_may_wakeup(dev)) { 326 enable_irq_wake(max77693->irq); 327 disable_irq(max77693->irq); 328 } 329 330 return 0; 331} 332 333static int max77693_resume(struct device *dev) 334{ 335 struct i2c_client *i2c = to_i2c_client(dev); 336 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 337 338 if (device_may_wakeup(dev)) { 339 disable_irq_wake(max77693->irq); 340 enable_irq(max77693->irq); 341 } 342 343 return 0; 344} 345 346static const struct dev_pm_ops max77693_pm = { 347 .suspend = max77693_suspend, 348 .resume = max77693_resume, 349}; 350 351#ifdef CONFIG_OF 352static const struct of_device_id max77693_dt_match[] = { 353 { .compatible = "maxim,max77693" }, 354 {}, 355}; 356MODULE_DEVICE_TABLE(of, max77693_dt_match); 357#endif 358 359static struct i2c_driver max77693_i2c_driver = { 360 .driver = { 361 .name = "max77693", 362 .pm = &max77693_pm, 363 .of_match_table = of_match_ptr(max77693_dt_match), 364 }, 365 .probe = max77693_i2c_probe, 366 .remove = max77693_i2c_remove, 367 .id_table = max77693_i2c_id, 368}; 369 370module_i2c_driver(max77693_i2c_driver); 371 372MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver"); 373MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>"); 374MODULE_LICENSE("GPL");