aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaewon Kim <jaewon02.kim@samsung.com>2015-03-02 05:10:34 -0500
committerLee Jones <lee.jones@linaro.org>2015-03-04 03:18:28 -0500
commitc7f585fe46d834d5837db7fbe205c46b94f81dc2 (patch)
treec9790d500b95b391202c571fa7d9fff953da6d95
parentd3591df3fada3f4cd6cf60f0f56e87744749018d (diff)
mfd: max77843: Add max77843 MFD driver core driver
This patch adds MAX77843 core/irq driver to support PMIC, MUIC(Micro USB Interface Controller), Charger, Fuel Gauge, LED and Haptic device. Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com> Signed-off-by: Beomho Seo <beomho.seo@samsung.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
-rw-r--r--drivers/mfd/Kconfig14
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/max77843.c243
-rw-r--r--include/linux/mfd/max77843-private.h454
4 files changed, 712 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c602f7440e00..f8ef77d9ac1f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -456,6 +456,20 @@ config MFD_MAX77693
456 additional drivers must be enabled in order to use the functionality 456 additional drivers must be enabled in order to use the functionality
457 of the device. 457 of the device.
458 458
459config MFD_MAX77843
460 bool "Maxim Semiconductor MAX77843 PMIC Support"
461 depends on I2C=y
462 select MFD_CORE
463 select REGMAP_I2C
464 select REGMAP_IRQ
465 help
466 Say yes here to add support for Maxim Semiconductor MAX77843.
467 This is companion Power Management IC with LEDs, Haptic, Charger,
468 Fuel Gauge, MUIC(Micro USB Interface Controller) controls on chip.
469 This driver provides common support for accessing the device;
470 additional drivers must be enabled in order to use the functionality
471 of the device.
472
459config MFD_MAX8907 473config MFD_MAX8907
460 tristate "Maxim Semiconductor MAX8907 PMIC Support" 474 tristate "Maxim Semiconductor MAX8907 PMIC Support"
461 select MFD_CORE 475 select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 26303f712afb..234998d77d43 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -117,6 +117,7 @@ obj-$(CONFIG_MFD_DA9150) += da9150-core.o
117obj-$(CONFIG_MFD_MAX14577) += max14577.o 117obj-$(CONFIG_MFD_MAX14577) += max14577.o
118obj-$(CONFIG_MFD_MAX77686) += max77686.o 118obj-$(CONFIG_MFD_MAX77686) += max77686.o
119obj-$(CONFIG_MFD_MAX77693) += max77693.o 119obj-$(CONFIG_MFD_MAX77693) += max77693.o
120obj-$(CONFIG_MFD_MAX77843) += max77843.o
120obj-$(CONFIG_MFD_MAX8907) += max8907.o 121obj-$(CONFIG_MFD_MAX8907) += max8907.o
121max8925-objs := max8925-core.o max8925-i2c.o 122max8925-objs := max8925-core.o max8925-i2c.o
122obj-$(CONFIG_MFD_MAX8925) += max8925.o 123obj-$(CONFIG_MFD_MAX8925) += max8925.o
diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c
new file mode 100644
index 000000000000..a354ac677ec7
--- /dev/null
+++ b/drivers/mfd/max77843.c
@@ -0,0 +1,243 @@
1/*
2 * MFD core driver for the Maxim MAX77843
3 *
4 * Copyright (C) 2015 Samsung Electronics
5 * Author: Jaewon Kim <jaewon02.kim@samsung.com>
6 * Author: Beomho Seo <beomho.seo@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 */
13
14#include <linux/err.h>
15#include <linux/i2c.h>
16#include <linux/init.h>
17#include <linux/interrupt.h>
18#include <linux/module.h>
19#include <linux/mfd/core.h>
20#include <linux/mfd/max77843-private.h>
21#include <linux/of_device.h>
22#include <linux/platform_device.h>
23
24static const struct mfd_cell max77843_devs[] = {
25 {
26 .name = "max77843-muic",
27 .of_compatible = "maxim,max77843-muic",
28 }, {
29 .name = "max77843-regulator",
30 .of_compatible = "maxim,max77843-regulator",
31 }, {
32 .name = "max77843-charger",
33 .of_compatible = "maxim,max77843-charger"
34 }, {
35 .name = "max77843-fuelgauge",
36 .of_compatible = "maxim,max77843-fuelgauge",
37 }, {
38 .name = "max77843-haptic",
39 .of_compatible = "maxim,max77843-haptic",
40 },
41};
42
43static const struct regmap_config max77843_charger_regmap_config = {
44 .reg_bits = 8,
45 .val_bits = 8,
46 .max_register = MAX77843_CHG_REG_END,
47};
48
49static const struct regmap_config max77843_regmap_config = {
50 .reg_bits = 8,
51 .val_bits = 8,
52 .max_register = MAX77843_SYS_REG_END,
53};
54
55static const struct regmap_irq max77843_irqs[] = {
56 /* TOPSYS interrupts */
57 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSUVLO_INT, },
58 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSOVLO_INT, },
59 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TSHDN_INT, },
60 { .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TM_INT, },
61};
62
63static const struct regmap_irq_chip max77843_irq_chip = {
64 .name = "max77843",
65 .status_base = MAX77843_SYS_REG_SYSINTSRC,
66 .mask_base = MAX77843_SYS_REG_SYSINTMASK,
67 .mask_invert = false,
68 .num_regs = 1,
69 .irqs = max77843_irqs,
70 .num_irqs = ARRAY_SIZE(max77843_irqs),
71};
72
73/* Charger and Charger regulator use same regmap. */
74static int max77843_chg_init(struct max77843 *max77843)
75{
76 int ret;
77
78 max77843->i2c_chg = i2c_new_dummy(max77843->i2c->adapter, I2C_ADDR_CHG);
79 if (!max77843->i2c_chg) {
80 dev_err(&max77843->i2c->dev,
81 "Cannot allocate I2C device for Charger\n");
82 return PTR_ERR(max77843->i2c_chg);
83 }
84 i2c_set_clientdata(max77843->i2c_chg, max77843);
85
86 max77843->regmap_chg = devm_regmap_init_i2c(max77843->i2c_chg,
87 &max77843_charger_regmap_config);
88 if (IS_ERR(max77843->regmap_chg)) {
89 ret = PTR_ERR(max77843->regmap_chg);
90 goto err_chg_i2c;
91 }
92
93 return 0;
94
95err_chg_i2c:
96 i2c_unregister_device(max77843->i2c_chg);
97
98 return ret;
99}
100
101static int max77843_probe(struct i2c_client *i2c,
102 const struct i2c_device_id *id)
103{
104 struct max77843 *max77843;
105 unsigned int reg_data;
106 int ret;
107
108 max77843 = devm_kzalloc(&i2c->dev, sizeof(*max77843), GFP_KERNEL);
109 if (!max77843)
110 return -ENOMEM;
111
112 i2c_set_clientdata(i2c, max77843);
113 max77843->dev = &i2c->dev;
114 max77843->i2c = i2c;
115 max77843->irq = i2c->irq;
116
117 max77843->regmap = devm_regmap_init_i2c(i2c,
118 &max77843_regmap_config);
119 if (IS_ERR(max77843->regmap)) {
120 dev_err(&i2c->dev, "Failed to allocate topsys register map\n");
121 return PTR_ERR(max77843->regmap);
122 }
123
124 ret = regmap_add_irq_chip(max77843->regmap, max77843->irq,
125 IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
126 0, &max77843_irq_chip, &max77843->irq_data);
127 if (ret) {
128 dev_err(&i2c->dev, "Failed to add TOPSYS IRQ chip\n");
129 return ret;
130 }
131
132 ret = regmap_read(max77843->regmap,
133 MAX77843_SYS_REG_PMICID, &reg_data);
134 if (ret < 0) {
135 dev_err(&i2c->dev, "Failed to read PMIC ID\n");
136 goto err_pmic_id;
137 }
138 dev_info(&i2c->dev, "device ID: 0x%x\n", reg_data);
139
140 ret = max77843_chg_init(max77843);
141 if (ret) {
142 dev_err(&i2c->dev, "Failed to init Charger\n");
143 goto err_pmic_id;
144 }
145
146 ret = regmap_update_bits(max77843->regmap,
147 MAX77843_SYS_REG_INTSRCMASK,
148 MAX77843_INTSRC_MASK_MASK,
149 (unsigned int)~MAX77843_INTSRC_MASK_MASK);
150 if (ret < 0) {
151 dev_err(&i2c->dev, "Failed to unmask interrupt source\n");
152 goto err_pmic_id;
153 }
154
155 ret = mfd_add_devices(max77843->dev, -1, max77843_devs,
156 ARRAY_SIZE(max778