tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / mfd / lm3632.c
1 /*
2  * TI LM3632 MFD Driver
3  *
4  * Copyright 2015 Texas Instruments
5  *
6  * Author: Milo Kim <milo.kim@ti.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 version 2 as
10  * published by the Free Software Foundation.
11  *
12  */
13
14 #include <linux/delay.h>
15 #include <linux/err.h>
16 #include <linux/gpio.h>
17 #include <linux/i2c.h>
18 #include <linux/mfd/core.h>
19 #include <linux/mfd/lm3632.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/of_gpio.h>
23 #include <linux/slab.h>
24
25 #define LM3632_DEV_LCD_BIAS(_id)                \
26 {                                               \
27         .name = "lm3632-regulator",             \
28         .id   = _id,                            \
29         .of_compatible = "ti,lm3632-regulator", \
30 }
31
32 #define LM3632_DEV_BL                           \
33 {                                               \
34         .name = "lm3632-backlight",             \
35         .of_compatible = "ti,lm3632-backlight", \
36 }
37
38 #define LM3632_DEV_FLASH                                \
39 {                                               \
40         .name = "lm3632-flash",         \
41         .of_compatible = "ti,lm3632-flash",     \
42 }
43
44 static struct mfd_cell lm3632_devs[] = {
45         /* 3 Regulators */
46         LM3632_DEV_LCD_BIAS(1),
47         LM3632_DEV_LCD_BIAS(2),
48         LM3632_DEV_LCD_BIAS(3),
49
50         /* Backlight */
51         LM3632_DEV_BL,
52         /* Torch Flash */
53         LM3632_DEV_FLASH,
54 };
55
56 int lm3632_read_byte(struct lm3632 *lm3632, u8 reg, u8 *read)
57 {
58         int ret;
59         unsigned int val;
60
61         ret = regmap_read(lm3632->regmap, reg, &val);
62         if (ret < 0)
63                 return ret;
64
65         *read = (u8)val;
66         return 0;
67 }
68 EXPORT_SYMBOL_GPL(lm3632_read_byte);
69
70 int lm3632_write_byte(struct lm3632 *lm3632, u8 reg, u8 data)
71 {
72         return regmap_write(lm3632->regmap, reg, data);
73 }
74 EXPORT_SYMBOL_GPL(lm3632_write_byte);
75
76 int lm3632_update_bits(struct lm3632 *lm3632, u8 reg, u8 mask, u8 data)
77 {
78         return regmap_update_bits(lm3632->regmap, reg, mask, data);
79 }
80 EXPORT_SYMBOL_GPL(lm3632_update_bits);
81
82 static int lm3632_init_device(struct lm3632 *lm3632)
83 {
84         return devm_gpio_request_one(lm3632->dev, lm3632->pdata->en_gpio,
85                                      GPIOF_OUT_INIT_HIGH, "lm3632_hwen");
86 }
87
88 static void lm3632_deinit_device(struct lm3632 *lm3632)
89 {
90         gpio_set_value(lm3632->pdata->en_gpio, 0);
91 }
92
93 static int lm3632_parse_dt(struct device *dev, struct lm3632 *lm3632)
94 {
95         //struct device_node *node = dev->of_node;
96         struct lm3632_platform_data *pdata;
97
98         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
99         if (!pdata)
100                 return -ENOMEM;
101
102         //pdata->en_gpio = of_get_named_gpio(node, "ti,en-gpio", 0);
103         pdata->en_gpio=0;
104         if (pdata->en_gpio == -EPROBE_DEFER)
105                 return -EPROBE_DEFER;
106
107         lm3632->pdata = pdata;
108
109         return 0;
110 }
111
112 static struct regmap_config lm3632_regmap_config = {
113         .reg_bits = 8,
114         .val_bits = 8,
115         .max_register = LM3632_MAX_REGISTERS,
116 };
117
118 static int lm3632_probe(struct i2c_client *cl, const struct i2c_device_id *id)
119 {
120         struct lm3632 *lm3632;
121         struct device *dev = &cl->dev;
122         struct lm3632_platform_data *pdata = dev_get_platdata(dev);
123         int ret;
124         printk("zyun lm3632_probe\n");
125
126         if (!i2c_check_functionality(cl->adapter, I2C_FUNC_I2C)) {
127                 printk("zyun i2c functionality check fail.\n");
128                 return -EOPNOTSUPP;
129         }
130
131         lm3632 = devm_kzalloc(dev, sizeof(*lm3632), GFP_KERNEL);
132         if (!lm3632)
133                 return -ENOMEM;
134
135         lm3632->pdata = pdata;
136         if (!pdata) {
137
138                 if (IS_ENABLED(CONFIG_OF))
139                         ret = lm3632_parse_dt(dev, lm3632);
140         }
141
142         lm3632->regmap = devm_regmap_init_i2c(cl, &lm3632_regmap_config);
143         if (IS_ERR(lm3632->regmap))
144                 return PTR_ERR(lm3632->regmap);
145
146
147         lm3632->dev = &cl->dev;
148         i2c_set_clientdata(cl, lm3632);
149
150
151         ret = lm3632_init_device(lm3632);
152         if (ret)
153                 return ret;
154         //printk("~~~~ %s %d\n", __FUNCTION__, __LINE__);
155         printk("zyun original lm3632 adress=0x%x\n",(int)lm3632);
156         return mfd_add_devices(dev, -1, lm3632_devs, ARRAY_SIZE(lm3632_devs),
157                                NULL, 0, NULL);
158 }
159
160 static int lm3632_remove(struct i2c_client *cl)
161 {
162         struct lm3632 *lm3632 = i2c_get_clientdata(cl);
163
164         lm3632_deinit_device(lm3632);
165         mfd_remove_devices(lm3632->dev);
166
167         return 0;
168 }
169
170 static const struct i2c_device_id lm3632_ids[] = {
171         { "lm3632", 0 },
172         { }
173 };
174 MODULE_DEVICE_TABLE(i2c, lm3632_ids);
175
176 #ifdef CONFIG_OF
177 static const struct of_device_id lm3632_of_match[] = {
178         { .compatible = "ti,lm3632", },
179         { }
180 };
181 MODULE_DEVICE_TABLE(of, lm3632_of_match);
182 #endif
183
184 static struct i2c_driver lm3632_driver = {
185         .probe = lm3632_probe,
186         .remove = lm3632_remove,
187         .driver = {
188                 .name = "lm3632",
189                 .owner = THIS_MODULE,
190                 .of_match_table = of_match_ptr(lm3632_of_match),
191         },
192         .id_table = lm3632_ids,
193 };
194 module_i2c_driver(lm3632_driver);
195
196 MODULE_DESCRIPTION("TI LM3632 MFD Core");
197 MODULE_AUTHOR("Milo Kim");
198 MODULE_LICENSE("GPL");