root/drivers/mfd/max77843.c

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

DEFINITIONS

This source file includes following definitions.
  1. max77843_chg_init
  2. max77843_probe
  3. max77843_suspend
  4. max77843_resume
  5. max77843_i2c_init

   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 
  19 static 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 
  38 static 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 
  44 static const struct regmap_config max77843_regmap_config = {
  45         .reg_bits       = 8,
  46         .val_bits       = 8,
  47         .max_register   = MAX77843_SYS_REG_END,
  48 };
  49 
  50 static 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 
  58 static 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. */
  69 static 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 
  90 err_chg_i2c:
  91         i2c_unregister_device(max77843->i2c_chg);
  92 
  93         return ret;
  94 }
  95 
  96 static 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, &reg_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 
 162 err_pmic_id:
 163         regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
 164 
 165         return ret;
 166 }
 167 
 168 static const struct of_device_id max77843_dt_match[] = {
 169         { .compatible = "maxim,max77843", },
 170         { },
 171 };
 172 
 173 static const struct i2c_device_id max77843_id[] = {
 174         { "max77843", TYPE_MAX77843, },
 175         { },
 176 };
 177 
 178 static 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 
 190 static 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 
 202 static SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume);
 203 
 204 static 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 
 215 static int __init max77843_i2c_init(void)
 216 {
 217         return i2c_add_driver(&max77843_i2c_driver);
 218 }
 219 subsys_initcall(max77843_i2c_init);

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