root/drivers/mfd/max77693.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. max77693_i2c_probe
  2. max77693_i2c_remove
  3. max77693_suspend
  4. max77693_resume

   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 
  31 static 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 
  51 static const struct regmap_config max77693_regmap_config = {
  52         .reg_bits = 8,
  53         .val_bits = 8,
  54         .max_register = MAX77693_PMIC_REG_END,
  55 };
  56 
  57 static 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 
  65 static 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 
  75 static 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 
  81 static 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 
  91 static 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 
  99 static 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 
 109 static 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 
 115 static 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 
 136 static 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 
 146 static 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 
 152 static 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                                 &reg_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 |
 226                                 IRQF_TRIGGER_FALLING, 0,
 227                                 &max77693_led_irq_chip,
 228                                 &max77693->irq_data_led);
 229         if (ret) {
 230                 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
 231                 goto err_regmap;
 232         }
 233 
 234         ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
 235                                 IRQF_ONESHOT | IRQF_SHARED |
 236                                 IRQF_TRIGGER_FALLING, 0,
 237                                 &max77693_topsys_irq_chip,
 238                                 &max77693->irq_data_topsys);
 239         if (ret) {
 240                 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
 241                 goto err_irq_topsys;
 242         }
 243 
 244         ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
 245                                 IRQF_ONESHOT | IRQF_SHARED |
 246                                 IRQF_TRIGGER_FALLING, 0,
 247                                 &max77693_charger_irq_chip,
 248                                 &max77693->irq_data_chg);
 249         if (ret) {
 250                 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
 251                 goto err_irq_charger;
 252         }
 253 
 254         ret = regmap_add_irq_chip(max77693->regmap_muic, max77693->irq,
 255                                 IRQF_ONESHOT | IRQF_SHARED |
 256                                 IRQF_TRIGGER_FALLING, 0,
 257                                 &max77693_muic_irq_chip,
 258                                 &max77693->irq_data_muic);
 259         if (ret) {
 260                 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
 261                 goto err_irq_muic;
 262         }
 263 
 264         /* Unmask interrupts from all blocks in interrupt source register */
 265         ret = regmap_update_bits(max77693->regmap,
 266                                 MAX77693_PMIC_REG_INTSRC_MASK,
 267                                 SRC_IRQ_ALL, (unsigned int)~SRC_IRQ_ALL);
 268         if (ret < 0) {
 269                 dev_err(max77693->dev,
 270                         "Could not unmask interrupts in INTSRC: %d\n",
 271                         ret);
 272                 goto err_intsrc;
 273         }
 274 
 275         pm_runtime_set_active(max77693->dev);
 276 
 277         ret = mfd_add_devices(max77693->dev, -1, max77693_devs,
 278                               ARRAY_SIZE(max77693_devs), NULL, 0, NULL);
 279         if (ret < 0)
 280                 goto err_mfd;
 281 
 282         return ret;
 283 
 284 err_mfd:
 285         mfd_remove_devices(max77693->dev);
 286 err_intsrc:
 287         regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
 288 err_irq_muic:
 289         regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg);
 290 err_irq_charger:
 291         regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
 292 err_irq_topsys:
 293         regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
 294 err_regmap:
 295         i2c_unregister_device(max77693->i2c_haptic);
 296 err_i2c_haptic:
 297         i2c_unregister_device(max77693->i2c_muic);
 298         return ret;
 299 }
 300 
 301 static int max77693_i2c_remove(struct i2c_client *i2c)
 302 {
 303         struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 304 
 305         mfd_remove_devices(max77693->dev);
 306 
 307         regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
 308         regmap_del_irq_chip(max77693->irq, max77693->irq_data_chg);
 309         regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
 310         regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
 311 
 312         i2c_unregister_device(max77693->i2c_muic);
 313         i2c_unregister_device(max77693->i2c_haptic);
 314 
 315         return 0;
 316 }
 317 
 318 static const struct i2c_device_id max77693_i2c_id[] = {
 319         { "max77693", TYPE_MAX77693 },
 320         { }
 321 };
 322 MODULE_DEVICE_TABLE(i2c, max77693_i2c_id);
 323 
 324 static int max77693_suspend(struct device *dev)
 325 {
 326         struct i2c_client *i2c = to_i2c_client(dev);
 327         struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 328 
 329         if (device_may_wakeup(dev)) {
 330                 enable_irq_wake(max77693->irq);
 331                 disable_irq(max77693->irq);
 332         }
 333 
 334         return 0;
 335 }
 336 
 337 static int max77693_resume(struct device *dev)
 338 {
 339         struct i2c_client *i2c = to_i2c_client(dev);
 340         struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
 341 
 342         if (device_may_wakeup(dev)) {
 343                 disable_irq_wake(max77693->irq);
 344                 enable_irq(max77693->irq);
 345         }
 346 
 347         return 0;
 348 }
 349 
 350 static const struct dev_pm_ops max77693_pm = {
 351         .suspend = max77693_suspend,
 352         .resume = max77693_resume,
 353 };
 354 
 355 #ifdef CONFIG_OF
 356 static const struct of_device_id max77693_dt_match[] = {
 357         { .compatible = "maxim,max77693" },
 358         {},
 359 };
 360 MODULE_DEVICE_TABLE(of, max77693_dt_match);
 361 #endif
 362 
 363 static struct i2c_driver max77693_i2c_driver = {
 364         .driver = {
 365                    .name = "max77693",
 366                    .pm = &max77693_pm,
 367                    .of_match_table = of_match_ptr(max77693_dt_match),
 368         },
 369         .probe = max77693_i2c_probe,
 370         .remove = max77693_i2c_remove,
 371         .id_table = max77693_i2c_id,
 372 };
 373 
 374 module_i2c_driver(max77693_i2c_driver);
 375 
 376 MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver");
 377 MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>");
 378 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */