aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2012-05-14 16:50:39 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-05-20 11:27:05 -0400
commit83871c00bb43f41d85dd15aba56a83bbb191eabc (patch)
tree034d40d8696896f4c42895675b3bfb79def58812 /drivers/mfd
parentebd29c6cc0b29b4bb041441fc251e0f400eea2cf (diff)
mfd: Add MAX77693 driver
This patch adds MFD driver for MAX77693 to enable its sub devices. The MAX77693 is a multi-function devices. It includes PMIC, MUIC(Micro USB Interface Controller), flash LED control and haptic motor control. Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig12
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/max77693.c217
3 files changed, 230 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index af46ce019fc7..a0e1b834af61 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -420,6 +420,18 @@ config PMIC_ADP5520
420 individual components like LCD backlight, LEDs, GPIOs and Kepad 420 individual components like LCD backlight, LEDs, GPIOs and Kepad
421 under the corresponding menus. 421 under the corresponding menus.
422 422
423config MFD_MAX77693
424 bool "Maxim Semiconductor MAX77693 PMIC Support"
425 depends on I2C=y && GENERIC_HARDIRQS
426 select MFD_CORE
427 help
428 Say yes here to support for Maxim Semiconductor MAX77693.
429 This is a companion Power Management IC with Flash, Haptic, Charger,
430 and MUIC(Micro USB Interface Controller) controls on chip.
431 This driver provides common support for accessing the device;
432 additional drivers must be enabled in order to use the functionality
433 of the device.
434
423config MFD_MAX8925 435config MFD_MAX8925
424 bool "Maxim Semiconductor MAX8925 PMIC Support" 436 bool "Maxim Semiconductor MAX8925 PMIC Support"
425 depends on I2C=y && GENERIC_HARDIRQS 437 depends on I2C=y && GENERIC_HARDIRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d3dae9567800..db0262b34af6 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
78obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o 78obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
79obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o 79obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
80 80
81obj-$(CONFIG_MFD_MAX77693) += max77693.o
81max8925-objs := max8925-core.o max8925-i2c.o 82max8925-objs := max8925-core.o max8925-i2c.o
82obj-$(CONFIG_MFD_MAX8925) += max8925.o 83obj-$(CONFIG_MFD_MAX8925) += max8925.o
83obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o 84obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
new file mode 100644
index 000000000000..c852515e68c8
--- /dev/null
+++ b/drivers/mfd/max77693.c
@@ -0,0 +1,217 @@
1/*
2 * max77693.c - mfd core driver for the MAX 77693
3 *
4 * Copyright (C) 2012 Samsung Electronics
5 * SangYoung Son <hello.son@smasung.com>
6 *
7 * This program is not provided / owned by Maxim Integrated Products.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 * This driver is based on max8997.c
24 */
25
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/i2c.h>
29#include <linux/err.h>
30#include <linux/interrupt.h>
31#include <linux/pm_runtime.h>
32#include <linux/mutex.h>
33#include <linux/mfd/core.h>
34#include <linux/mfd/max77693.h>
35#include <linux/mfd/max77693-private.h>
36#include <linux/regulator/machine.h>
37#include <linux/regmap.h>
38
39#define I2C_ADDR_PMIC (0xCC >> 1) /* Charger, Flash LED */
40#define I2C_ADDR_MUIC (0x4A >> 1)
41#define I2C_ADDR_HAPTIC (0x90 >> 1)
42
43static struct mfd_cell max77693_devs[] = {
44 { .name = "max77693-pmic", },
45 { .name = "max77693-charger", },
46 { .name = "max77693-flash", },
47 { .name = "max77693-muic", },
48 { .name = "max77693-haptic", },
49};
50
51int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest)
52{
53 unsigned int val;
54 int ret;
55
56 ret = regmap_read(map, reg, &val);
57 *dest = val;
58
59 return ret;
60}
61EXPORT_SYMBOL_GPL(max77693_read_reg);
62
63int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf)
64{
65 int ret;
66
67 ret = regmap_bulk_read(map, reg, buf, count);
68
69 return ret;
70}
71EXPORT_SYMBOL_GPL(max77693_bulk_read);
72
73int max77693_write_reg(struct regmap *map, u8 reg, u8 value)
74{
75 int ret;
76
77 ret = regmap_write(map, reg, value);
78
79 return ret;
80}
81EXPORT_SYMBOL_GPL(max77693_write_reg);
82
83int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf)
84{
85 int ret;
86
87 ret = regmap_bulk_write(map, reg, buf, count);
88
89 return ret;
90}
91EXPORT_SYMBOL_GPL(max77693_bulk_write);
92
93int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask)
94{
95 int ret;
96
97 ret = regmap_update_bits(map, reg, mask, val);
98
99 return ret;
100}
101EXPORT_SYMBOL_GPL(max77693_update_reg);
102
103static const struct regmap_config max77693_regmap_config = {
104 .reg_bits = 8,
105 .val_bits = 8,
106 .max_register = MAX77693_PMIC_REG_END,
107};
108
109static int max77693_i2c_probe(struct i2c_client *i2c,
110 const struct i2c_device_id *id)
111{
112 struct max77693_dev *max77693;
113 struct max77693_platform_data *pdata = i2c->dev.platform_data;
114 u8 reg_data;
115 int ret = 0;
116
117 max77693 = devm_kzalloc(&i2c->dev,
118 sizeof(struct max77693_dev), GFP_KERNEL);
119 if (max77693 == NULL)
120 return -ENOMEM;
121
122 max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
123 if (IS_ERR(max77693->regmap)) {
124 ret = PTR_ERR(max77693->regmap);
125 dev_err(max77693->dev,"failed to allocate register map: %d\n",
126 ret);
127 goto err_regmap;
128 }
129
130 i2c_set_clientdata(i2c, max77693);
131 max77693->dev = &i2c->dev;
132 max77693->i2c = i2c;
133 max77693->irq = i2c->irq;
134 max77693->type = id->driver_data;
135
136 if (!pdata)
137 goto err_regmap;
138
139 max77693->wakeup = pdata->wakeup;
140
141 mutex_init(&max77693->iolock);
142
143 if (max77693_read_reg(max77693->regmap,
144 MAX77693_PMIC_REG_PMIC_ID2, &reg_data) < 0) {
145 dev_err(max77693->dev, "device not found on this channel\n");
146 ret = -ENODEV;
147 goto err_regmap;
148 } else
149 dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
150
151 max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
152 i2c_set_clientdata(max77693->muic, max77693);
153
154 max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
155 i2c_set_clientdata(max77693->haptic, max77693);
156
157 pm_runtime_set_active(max77693->dev);
158
159 ret = mfd_add_devices(max77693->dev, -1, max77693_devs,
160 ARRAY_SIZE(max77693_devs), NULL, 0);
161 if (ret < 0)
162 goto err_mfd;
163
164 return ret;
165
166err_mfd:
167 i2c_unregister_device(max77693->muic);
168 i2c_unregister_device(max77693->haptic);
169err_regmap:
170 kfree(max77693);
171
172 return ret;
173}
174
175static int max77693_i2c_remove(struct i2c_client *i2c)
176{
177 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
178
179 mfd_remove_devices(max77693->dev);
180 i2c_unregister_device(max77693->muic);
181 i2c_unregister_device(max77693->haptic);
182
183 return 0;
184}
185
186static const struct i2c_device_id max77693_i2c_id[] = {
187 { "max77693", TYPE_MAX77693 },
188 { }
189};
190MODULE_DEVICE_TABLE(i2c, max77693_i2c_id);
191
192static struct i2c_driver max77693_i2c_driver = {
193 .driver = {
194 .name = "max77693",
195 .owner = THIS_MODULE,
196 },
197 .probe = max77693_i2c_probe,
198 .remove = max77693_i2c_remove,
199 .id_table = max77693_i2c_id,
200};
201
202static int __init max77693_i2c_init(void)
203{
204 return i2c_add_driver(&max77693_i2c_driver);
205}
206/* init early so consumer devices can complete system boot */
207subsys_initcall(max77693_i2c_init);
208
209static void __exit max77693_i2c_exit(void)
210{
211 i2c_del_driver(&max77693_i2c_driver);
212}
213module_exit(max77693_i2c_exit);
214
215MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver");
216MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>");
217MODULE_LICENSE("GPL");