1 /* 2 * MFD core driver for the Richtek RT5033. 3 * 4 * RT5033 comprises multiple sub-devices switcing charger, fuel gauge, 5 * flash LED, current source, LDO and BUCK regulators. 6 * 7 * Copyright (C) 2014 Samsung Electronics, Co., Ltd. 8 * Author: Beomho Seo <beomho.seo@samsung.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published bythe Free Software Foundation. 13 */ 14 15 #include <linux/err.h> 16 #include <linux/module.h> 17 #include <linux/interrupt.h> 18 #include <linux/of_device.h> 19 #include <linux/mfd/core.h> 20 #include <linux/mfd/rt5033.h> 21 #include <linux/mfd/rt5033-private.h> 22 23 static const struct regmap_irq rt5033_irqs[] = { 24 { .mask = RT5033_PMIC_IRQ_BUCKOCP, }, 25 { .mask = RT5033_PMIC_IRQ_BUCKLV, }, 26 { .mask = RT5033_PMIC_IRQ_SAFELDOLV, }, 27 { .mask = RT5033_PMIC_IRQ_LDOLV, }, 28 { .mask = RT5033_PMIC_IRQ_OT, }, 29 { .mask = RT5033_PMIC_IRQ_VDDA_UV, }, 30 }; 31 32 static const struct regmap_irq_chip rt5033_irq_chip = { 33 .name = "rt5033", 34 .status_base = RT5033_REG_PMIC_IRQ_STAT, 35 .mask_base = RT5033_REG_PMIC_IRQ_CTRL, 36 .mask_invert = true, 37 .num_regs = 1, 38 .irqs = rt5033_irqs, 39 .num_irqs = ARRAY_SIZE(rt5033_irqs), 40 }; 41 42 static const struct mfd_cell rt5033_devs[] = { 43 { .name = "rt5033-regulator", }, 44 { 45 .name = "rt5033-charger", 46 .of_compatible = "richtek,rt5033-charger", 47 }, { 48 .name = "rt5033-battery", 49 .of_compatible = "richtek,rt5033-battery", 50 }, { 51 .name = "rt5033-led", 52 .of_compatible = "richtek,rt5033-led", 53 }, 54 }; 55 56 static const struct regmap_config rt5033_regmap_config = { 57 .reg_bits = 8, 58 .val_bits = 8, 59 .max_register = RT5033_REG_END, 60 }; 61 62 static int rt5033_i2c_probe(struct i2c_client *i2c, 63 const struct i2c_device_id *id) 64 { 65 struct rt5033_dev *rt5033; 66 unsigned int dev_id; 67 int ret; 68 69 rt5033 = devm_kzalloc(&i2c->dev, sizeof(*rt5033), GFP_KERNEL); 70 if (!rt5033) 71 return -ENOMEM; 72 73 i2c_set_clientdata(i2c, rt5033); 74 rt5033->dev = &i2c->dev; 75 rt5033->irq = i2c->irq; 76 rt5033->wakeup = true; 77 78 rt5033->regmap = devm_regmap_init_i2c(i2c, &rt5033_regmap_config); 79 if (IS_ERR(rt5033->regmap)) { 80 dev_err(&i2c->dev, "Failed to allocate register map.\n"); 81 return PTR_ERR(rt5033->regmap); 82 } 83 84 ret = regmap_read(rt5033->regmap, RT5033_REG_DEVICE_ID, &dev_id); 85 if (ret) { 86 dev_err(&i2c->dev, "Device not found\n"); 87 return -ENODEV; 88 } 89 dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id); 90 91 ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq, 92 IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 93 0, &rt5033_irq_chip, &rt5033->irq_data); 94 if (ret) { 95 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", 96 rt5033->irq, ret); 97 return ret; 98 } 99 100 ret = mfd_add_devices(rt5033->dev, -1, rt5033_devs, 101 ARRAY_SIZE(rt5033_devs), NULL, 0, 102 regmap_irq_get_domain(rt5033->irq_data)); 103 if (ret < 0) { 104 dev_err(&i2c->dev, "Failed to add RT5033 child devices.\n"); 105 return ret; 106 } 107 108 device_init_wakeup(rt5033->dev, rt5033->wakeup); 109 110 return 0; 111 } 112 113 static int rt5033_i2c_remove(struct i2c_client *i2c) 114 { 115 mfd_remove_devices(&i2c->dev); 116 117 return 0; 118 } 119 120 static const struct i2c_device_id rt5033_i2c_id[] = { 121 { "rt5033", }, 122 { } 123 }; 124 MODULE_DEVICE_TABLE(i2c, rt5033_i2c_id); 125 126 static const struct of_device_id rt5033_dt_match[] = { 127 { .compatible = "richtek,rt5033", }, 128 { } 129 }; 130 MODULE_DEVICE_TABLE(of, rt5033_dt_match); 131 132 static struct i2c_driver rt5033_driver = { 133 .driver = { 134 .name = "rt5033", 135 .of_match_table = of_match_ptr(rt5033_dt_match), 136 }, 137 .probe = rt5033_i2c_probe, 138 .remove = rt5033_i2c_remove, 139 .id_table = rt5033_i2c_id, 140 }; 141 module_i2c_driver(rt5033_driver); 142 143 MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver"); 144 MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>"); 145 MODULE_LICENSE("GPL"); 146