config: tegra3: enable /dev mount with ACL
[linux-2.6.git] / drivers / mfd / max8907c.c
1 /*
2  * max8907c.c - mfd driver for MAX8907c
3  *
4  * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/i2c.h>
15 #include <linux/mfd/core.h>
16 #include <linux/mfd/max8907c.h>
17
18 static struct mfd_cell cells[] = {
19         {.name = "max8907-regulator",},
20         {.name = "max8907c-rtc",},
21 };
22
23 static int max8907c_i2c_read(struct i2c_client *i2c, u8 reg, u8 count, u8 *dest)
24 {
25         struct i2c_msg xfer[2];
26         int ret = 0;
27
28         xfer[0].addr = i2c->addr;
29         xfer[0].flags = 0;
30         xfer[0].len = 1;
31         xfer[0].buf = &reg;
32
33         xfer[1].addr = i2c->addr;
34         xfer[1].flags = I2C_M_RD;
35         xfer[1].len = count;
36         xfer[1].buf = dest;
37
38         ret = i2c_transfer(i2c->adapter, xfer, 2);
39         if (ret < 0)
40                 return ret;
41         if (ret != 2)
42                 return -EIO;
43
44         return 0;
45 }
46
47 static int max8907c_i2c_write(struct i2c_client *i2c, u8 reg, u8 count, const u8 *src)
48 {
49         u8 msg[0x100 + 1];
50         int ret = 0;
51
52         msg[0] = reg;
53         memcpy(&msg[1], src, count);
54
55         ret = i2c_master_send(i2c, msg, count + 1);
56         if (ret < 0)
57                 return ret;
58         if (ret != count + 1)
59                 return -EIO;
60
61         return 0;
62 }
63
64 int max8907c_reg_read(struct i2c_client *i2c, u8 reg)
65 {
66         int ret;
67         u8 val;
68
69         ret = max8907c_i2c_read(i2c, reg, 1, &val);
70
71         pr_debug("max8907c: reg read  reg=%x, val=%x\n",
72                  (unsigned int)reg, (unsigned int)val);
73
74         if (ret != 0)
75                 pr_err("Failed to read max8907c I2C driver: %d\n", ret);
76         return val;
77 }
78 EXPORT_SYMBOL_GPL(max8907c_reg_read);
79
80 int max8907c_reg_bulk_read(struct i2c_client *i2c, u8 reg, u8 count, u8 *val)
81 {
82         int ret;
83
84         ret = max8907c_i2c_read(i2c, reg, count, val);
85
86         pr_debug("max8907c: reg read  reg=%x, val=%x\n",
87                  (unsigned int)reg, (unsigned int)*val);
88
89         if (ret != 0)
90                 pr_err("Failed to read max8907c I2C driver: %d\n", ret);
91         return ret;
92 }
93 EXPORT_SYMBOL_GPL(max8907c_reg_bulk_read);
94
95 int max8907c_reg_write(struct i2c_client *i2c, u8 reg, u8 val)
96 {
97         struct max8907c *max8907c = i2c_get_clientdata(i2c);
98         int ret;
99
100         pr_debug("max8907c: reg write  reg=%x, val=%x\n",
101                  (unsigned int)reg, (unsigned int)val);
102
103         mutex_lock(&max8907c->io_lock);
104         ret = max8907c_i2c_write(i2c, reg, 1, &val);
105         mutex_unlock(&max8907c->io_lock);
106
107         if (ret != 0)
108                 pr_err("Failed to write max8907c I2C driver: %d\n", ret);
109         return ret;
110 }
111 EXPORT_SYMBOL_GPL(max8907c_reg_write);
112
113 int max8907c_reg_bulk_write(struct i2c_client *i2c, u8 reg, u8 count, u8 *val)
114 {
115         struct max8907c *max8907c = i2c_get_clientdata(i2c);
116         int ret;
117
118         pr_debug("max8907c: reg write  reg=%x, val=%x\n",
119                  (unsigned int)reg, (unsigned int)*val);
120
121         mutex_lock(&max8907c->io_lock);
122         ret = max8907c_i2c_write(i2c, reg, count, val);
123         mutex_unlock(&max8907c->io_lock);
124
125         if (ret != 0)
126                 pr_err("Failed to write max8907c I2C driver: %d\n", ret);
127         return ret;
128 }
129 EXPORT_SYMBOL_GPL(max8907c_reg_bulk_write);
130
131 int max8907c_set_bits(struct i2c_client *i2c, u8 reg, u8 mask, u8 val)
132 {
133         struct max8907c *max8907c = i2c_get_clientdata(i2c);
134         u8 tmp;
135         int ret;
136
137         pr_debug("max8907c: reg write  reg=%02X, val=%02X, mask=%02X\n",
138                  (unsigned int)reg, (unsigned int)val, (unsigned int)mask);
139
140         mutex_lock(&max8907c->io_lock);
141         ret = max8907c_i2c_read(i2c, reg, 1, &tmp);
142         if (ret == 0) {
143                 val = (tmp & ~mask) | (val & mask);
144                 ret = max8907c_i2c_write(i2c, reg, 1, &val);
145         }
146         mutex_unlock(&max8907c->io_lock);
147
148         if (ret != 0)
149                 pr_err("Failed to write max8907c I2C driver: %d\n", ret);
150         return ret;
151 }
152 EXPORT_SYMBOL_GPL(max8907c_set_bits);
153
154 static struct i2c_client *max8907c_client = NULL;
155 static void max8907c_power_off(void)
156 {
157         if (!max8907c_client)
158                 return;
159
160         max8907c_set_bits(max8907c_client, MAX8907C_REG_RESET_CNFG,
161                                                 MAX8907C_MASK_POWER_OFF, 0x40);
162 }
163
164 void max8907c_deep_sleep(int enter)
165 {
166         if (!max8907c_client)
167                 return;
168
169         if (enter) {
170                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDSEQCNT1,
171                                                 MAX8907C_POWER_UP_DELAY_CNT12);
172                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDSEQCNT2,
173                                                         MAX8907C_DELAY_CNT0);
174                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDCTL2,
175                                                         MAX8907C_SD_SEQ2);
176         } else {
177                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDSEQCNT1,
178                                                         MAX8907C_DELAY_CNT0);
179                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDCTL2,
180                                                         MAX8907C_SD_SEQ1);
181                 max8907c_reg_write(max8907c_client, MAX8907C_REG_SDSEQCNT2,
182                                 MAX8907C_POWER_UP_DELAY_CNT1 | MAX8907C_POWER_DOWN_DELAY_CNT12);
183         }
184 }
185
186 static int max8907c_remove_subdev(struct device *dev, void *unused)
187 {
188         platform_device_unregister(to_platform_device(dev));
189         return 0;
190 }
191
192 static int max8907c_remove_subdevs(struct max8907c *max8907c)
193 {
194         return device_for_each_child(max8907c->dev, NULL,
195                                      max8907c_remove_subdev);
196 }
197
198 static int max8097c_add_subdevs(struct max8907c *max8907c,
199                                 struct max8907c_platform_data *pdata)
200 {
201         struct platform_device *pdev;
202         int ret;
203         int i;
204
205         for (i = 0; i < pdata->num_subdevs; i++) {
206                 pdev = platform_device_alloc(pdata->subdevs[i]->name,
207                                              pdata->subdevs[i]->id);
208
209                 pdev->dev.parent = max8907c->dev;
210                 pdev->dev.platform_data = pdata->subdevs[i]->dev.platform_data;
211
212                 ret = platform_device_add(pdev);
213                 if (ret)
214                         goto error;
215         }
216         return 0;
217
218 error:
219         max8907c_remove_subdevs(max8907c);
220         return ret;
221 }
222
223 int max8907c_pwr_en_config(void)
224 {
225         int ret;
226         u8 data;
227
228         if (!max8907c_client)
229                 return -EINVAL;
230
231         /*
232          * Enable/disable PWREN h/w control mechanism (PWREN signal must be
233          * inactive = high at this time)
234          */
235         ret = max8907c_set_bits(max8907c_client, MAX8907C_REG_RESET_CNFG,
236                                         MAX8907C_MASK_PWR_EN, MAX8907C_PWR_EN);
237         if (ret != 0)
238                 return ret;
239
240         /*
241          * When enabled, connect PWREN to SEQ2 by clearing SEQ2 configuration
242          * settings for silicon revision that requires s/w WAR. On other
243          * MAX8907B revisions PWREN is always connected to SEQ2.
244          */
245         data = max8907c_reg_read(max8907c_client, MAX8907C_REG_II2RR);
246
247         if (data == MAX8907B_II2RR_PWREN_WAR) {
248                 data = 0x00;
249                 ret = max8907c_reg_write(max8907c_client, MAX8907C_REG_SEQ2CNFG, data);
250         }
251         return ret;
252 }
253
254 int max8907c_pwr_en_attach(void)
255 {
256         int ret;
257
258         if (!max8907c_client)
259                 return -EINVAL;
260
261         /* No sequencer delay for CPU rail when it is attached */
262         ret = max8907c_reg_write(max8907c_client, MAX8907C_REG_SDSEQCNT1,
263                                                         MAX8907C_DELAY_CNT0);
264         if (ret != 0)
265                 return ret;
266
267         return max8907c_set_bits(max8907c_client, MAX8907C_REG_SDCTL1,
268                                         MAX8907C_MASK_CTL_SEQ, MAX8907C_CTL_SEQ);
269 }
270
271 static int max8907c_i2c_probe(struct i2c_client *i2c,
272                               const struct i2c_device_id *id)
273 {
274         struct max8907c *max8907c;
275         struct max8907c_platform_data *pdata = i2c->dev.platform_data;
276         int ret;
277         int i;
278         u8 tmp;
279
280         max8907c = kzalloc(sizeof(struct max8907c), GFP_KERNEL);
281         if (max8907c == NULL)
282                 return -ENOMEM;
283
284         max8907c->dev = &i2c->dev;
285         dev_set_drvdata(max8907c->dev, max8907c);
286
287         max8907c->i2c_power = i2c;
288         i2c_set_clientdata(i2c, max8907c);
289
290         max8907c->i2c_rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
291         i2c_set_clientdata(max8907c->i2c_rtc, max8907c);
292
293         mutex_init(&max8907c->io_lock);
294
295         for (i = 0; i < ARRAY_SIZE(cells); i++) {
296                 cells[i].platform_data = max8907c;
297                 cells[i].pdata_size = sizeof(*max8907c);
298         }
299         ret = mfd_add_devices(max8907c->dev, -1, cells, ARRAY_SIZE(cells),
300                               NULL, 0);
301         if (ret != 0) {
302                 i2c_unregister_device(max8907c->i2c_rtc);
303                 kfree(max8907c);
304                 pr_debug("max8907c: failed to add MFD devices   %X\n", ret);
305                 return ret;
306         }
307
308         max8907c_client = i2c;
309
310         max8907c_irq_init(max8907c, i2c->irq, pdata->irq_base);
311
312         ret = max8097c_add_subdevs(max8907c, pdata);
313
314         if (pdata->use_power_off && !pm_power_off)
315                 pm_power_off = max8907c_power_off;
316
317         ret = max8907c_i2c_read(i2c, MAX8907C_REG_SYSENSEL, 1, &tmp);
318         /*Mask HARD RESET, if enabled */
319         if (ret == 0) {
320                 tmp &= ~(BIT(7));
321                 ret = max8907c_i2c_write(i2c, MAX8907C_REG_SYSENSEL, 1, &tmp);
322         }
323
324         if (ret != 0) {
325                 pr_err("Failed to write max8907c I2C driver: %d\n", ret);
326                 return ret;
327         }
328
329         if (pdata->max8907c_setup)
330                 return pdata->max8907c_setup();
331
332         return ret;
333 }
334
335 static int max8907c_i2c_remove(struct i2c_client *i2c)
336 {
337         struct max8907c *max8907c = i2c_get_clientdata(i2c);
338
339         max8907c_remove_subdevs(max8907c);
340         i2c_unregister_device(max8907c->i2c_rtc);
341         mfd_remove_devices(max8907c->dev);
342         max8907c_irq_free(max8907c);
343         kfree(max8907c);
344
345         return 0;
346 }
347
348 static const struct i2c_device_id max8907c_i2c_id[] = {
349         {"max8907c", 0},
350         {}
351 };
352
353 MODULE_DEVICE_TABLE(i2c, max8907c_i2c_id);
354
355 static struct i2c_driver max8907c_i2c_driver = {
356         .driver = {
357                    .name = "max8907c",
358                    .owner = THIS_MODULE,
359                    },
360         .probe = max8907c_i2c_probe,
361         .remove = max8907c_i2c_remove,
362         .suspend = max8907c_suspend,
363         .resume = max8907c_resume,
364         .id_table = max8907c_i2c_id,
365 };
366
367 static int __init max8907c_i2c_init(void)
368 {
369         int ret = -ENODEV;
370
371         ret = i2c_add_driver(&max8907c_i2c_driver);
372         if (ret != 0)
373                 pr_err("Failed to register I2C driver: %d\n", ret);
374
375         return ret;
376 }
377
378 subsys_initcall(max8907c_i2c_init);
379
380 static void __exit max8907c_i2c_exit(void)
381 {
382         i2c_del_driver(&max8907c_i2c_driver);
383 }
384
385 module_exit(max8907c_i2c_exit);
386
387 MODULE_DESCRIPTION("MAX8907C multi-function core driver");
388 MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
389 MODULE_LICENSE("GPL");