aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/88pm80x.c
diff options
context:
space:
mode:
authorQiao Zhou <zhouqiao@marvell.com>2012-07-09 02:37:32 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2012-07-09 09:12:51 -0400
commit70c6cce040661204986ebbf22224cb24bd77ea71 (patch)
treefe60851749c386e65735818e397850f2b3bd7d3e /drivers/mfd/88pm80x.c
parent49003a68926e073fc71062d210c6f9febc8665a2 (diff)
mfd: Support 88pm80x in 80x driver
88PM800 and 88PM805 are two discrete chips used for power management. Hardware designer can use them together or only one of them according to requirement. 88pm80x.c provides common i2c driver handling for both 800 and 805, such as i2c_driver init, regmap init, read/write api etc. 88pm800.c handles specifically for 800, such as chip init, irq init/handle, mfd device register, including rtc, onkey, regulator( to be add later) etc. besides that, 800 has three i2c device, one regular i2c client, two other i2c dummy for gpadc and power purpose. 88pm805.c handles specifically for 805, such as chip init, irq init/handle, mfd device register, including codec, headset/mic detect etc. the i2c operation of both 800 and 805 are via regmap, and 88pm80x-i2c exported a group of r/w bulk r/w and bits set API for facility. Signed-off-by: Qiao Zhou <zhouqiao@marvell.com> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/88pm80x.c')
-rw-r--r--drivers/mfd/88pm80x.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
new file mode 100644
index 000000000000..90aa18a37f79
--- /dev/null
+++ b/drivers/mfd/88pm80x.c
@@ -0,0 +1,116 @@
1/*
2 * I2C driver for Marvell 88PM80x
3 *
4 * Copyright (C) 2012 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 * Joseph(Yossi) Hanin <yhanin@marvell.com>
7 * Qiao Zhou <zhouqiao@marvell.com>
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 version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/mfd/88pm80x.h>
17#include <linux/slab.h>
18#include <linux/uaccess.h>
19#include <linux/err.h>
20
21
22const struct regmap_config pm80x_regmap_config = {
23 .reg_bits = 8,
24 .val_bits = 8,
25};
26
27int __devinit pm80x_init(struct i2c_client *client,
28 const struct i2c_device_id *id)
29{
30 struct pm80x_chip *chip;
31 struct regmap *map;
32 int ret = 0;
33
34 chip =
35 devm_kzalloc(&client->dev, sizeof(struct pm80x_chip), GFP_KERNEL);
36 if (!chip)
37 return -ENOMEM;
38
39 map = devm_regmap_init_i2c(client, &pm80x_regmap_config);
40 if (IS_ERR(map)) {
41 ret = PTR_ERR(map);
42 dev_err(&client->dev, "Failed to allocate register map: %d\n",
43 ret);
44 goto err_regmap_init;
45 }
46
47 chip->id = id->driver_data;
48 if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805) {
49 ret = -EINVAL;
50 goto err_chip_id;
51 }
52
53 chip->client = client;
54 chip->regmap = map;
55
56 chip->irq = client->irq;
57
58 chip->dev = &client->dev;
59 dev_set_drvdata(chip->dev, chip);
60 i2c_set_clientdata(chip->client, chip);
61
62 device_init_wakeup(&client->dev, 1);
63
64 return 0;
65
66err_chip_id:
67 regmap_exit(map);
68err_regmap_init:
69 devm_kfree(&client->dev, chip);
70 return ret;
71}
72EXPORT_SYMBOL_GPL(pm80x_init);
73
74int __devexit pm80x_deinit(struct i2c_client *client)
75{
76 struct pm80x_chip *chip = i2c_get_clientdata(client);
77
78 regmap_exit(chip->regmap);
79 devm_kfree(&client->dev, chip);
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(pm80x_deinit);
84
85#ifdef CONFIG_PM_SLEEP
86static int pm80x_suspend(struct device *dev)
87{
88 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
89 struct pm80x_chip *chip = i2c_get_clientdata(client);
90
91 if (chip && chip->wu_flag)
92 if (device_may_wakeup(chip->dev))
93 enable_irq_wake(chip->irq);
94
95 return 0;
96}
97
98static int pm80x_resume(struct device *dev)
99{
100 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
101 struct pm80x_chip *chip = i2c_get_clientdata(client);
102
103 if (chip && chip->wu_flag)
104 if (device_may_wakeup(chip->dev))
105 disable_irq_wake(chip->irq);
106
107 return 0;
108}
109#endif
110
111SIMPLE_DEV_PM_OPS(pm80x_pm_ops, pm80x_suspend, pm80x_resume);
112EXPORT_SYMBOL_GPL(pm80x_pm_ops);
113
114MODULE_DESCRIPTION("I2C Driver for Marvell 88PM80x");
115MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
116MODULE_LICENSE("GPL");