aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAbhijeet Dharmapurikar <adharmap@codeaurora.org>2011-04-05 17:40:52 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2011-05-26 13:45:27 -0400
commitcbdb53e1f33baf60ded045dc79cd0dd4e9705fa5 (patch)
tree6fba90fb0b27968c75437bf5c5df2c43f15ce64b /drivers/mfd
parent1305134e8246fb4e86b93d5b6a21caa0e07a8ecf (diff)
mfd: Add Qualcomm PMIC 8921 core driver
Add support for the Qualcomm PM8921 PMIC chip. The core driver will communicate with the PMIC chip via the MSM SSBI bus. Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig18
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/pm8921-core.c158
3 files changed, 177 insertions, 0 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ec2da8392466..d42328873dc9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -691,6 +691,24 @@ config MFD_OMAP_USB_HOST
691 This MFD driver does the required setup functionalities for 691 This MFD driver does the required setup functionalities for
692 OMAP USB Host drivers. 692 OMAP USB Host drivers.
693 693
694config MFD_PM8XXX
695 tristate
696
697config MFD_PM8921_CORE
698 tristate "Qualcomm PM8921 PMIC chip"
699 depends on MSM_SSBI
700 select MFD_CORE
701 select MFD_PM8XXX
702 help
703 If you say yes to this option, support will be included for the
704 built-in PM8921 PMIC chip.
705
706 This is required if your board has a PM8921 and uses its features,
707 such as: MPPs, GPIOs, regulators, interrupts, and PWM.
708
709 Say M here if you want to include support for PM8921 chip as a module.
710 This will build a module called "pm8921-core".
711
694endif # MFD_SUPPORT 712endif # MFD_SUPPORT
695 713
696menu "Multimedia Capabilities Port drivers" 714menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 24aa44448daf..d32a7b8f57f7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -91,3 +91,4 @@ obj-$(CONFIG_MFD_VX855) += vx855.o
91obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o 91obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
92obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o 92obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
93obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o 93obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
94obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
new file mode 100644
index 000000000000..a2ecd3233b1b
--- /dev/null
+++ b/drivers/mfd/pm8921-core.c
@@ -0,0 +1,158 @@
1/*
2 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#define pr_fmt(fmt) "%s: " fmt, __func__
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/msm_ssbi.h>
20#include <linux/mfd/core.h>
21#include <linux/mfd/pm8xxx/pm8921.h>
22#include <linux/mfd/pm8xxx/core.h>
23
24#define REG_HWREV 0x002 /* PMIC4 revision */
25#define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
26
27struct pm8921 {
28 struct device *dev;
29};
30
31static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
32{
33 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
34 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
35
36 return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
37}
38
39static int pm8921_writeb(const struct device *dev, u16 addr, u8 val)
40{
41 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
42 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
43
44 return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
45}
46
47static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf,
48 int cnt)
49{
50 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
51 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
52
53 return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
54}
55
56static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf,
57 int cnt)
58{
59 const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
60 const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
61
62 return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
63}
64
65static struct pm8xxx_drvdata pm8921_drvdata = {
66 .pmic_readb = pm8921_readb,
67 .pmic_writeb = pm8921_writeb,
68 .pmic_read_buf = pm8921_read_buf,
69 .pmic_write_buf = pm8921_write_buf,
70};
71
72static int __devinit pm8921_probe(struct platform_device *pdev)
73{
74 const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
75 struct pm8921 *pmic;
76 int rc;
77 u8 val;
78
79 if (!pdata) {
80 pr_err("missing platform data\n");
81 return -EINVAL;
82 }
83
84 pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL);
85 if (!pmic) {
86 pr_err("Cannot alloc pm8921 struct\n");
87 return -ENOMEM;
88 }
89
90 /* Read PMIC chip revision */
91 rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
92 if (rc) {
93 pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
94 goto err_read_rev;
95 }
96 pr_info("PMIC revision 1: %02X\n", val);
97
98 /* Read PMIC chip revision 2 */
99 rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
100 if (rc) {
101 pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
102 REG_HWREV_2, rc);
103 goto err_read_rev;
104 }
105 pr_info("PMIC revision 2: %02X\n", val);
106
107 pmic->dev = &pdev->dev;
108 pm8921_drvdata.pm_chip_data = pmic;
109 platform_set_drvdata(pdev, &pm8921_drvdata);
110
111 return 0;
112
113err_read_rev:
114 kfree(pmic);
115 return rc;
116}
117
118static int __devexit pm8921_remove(struct platform_device *pdev)
119{
120 struct pm8xxx_drvdata *drvdata;
121 struct pm8921 *pmic = NULL;
122
123 drvdata = platform_get_drvdata(pdev);
124 if (drvdata)
125 pmic = drvdata->pm_chip_data;
126 if (pmic)
127 mfd_remove_devices(pmic->dev);
128 platform_set_drvdata(pdev, NULL);
129 kfree(pmic);
130
131 return 0;
132}
133
134static struct platform_driver pm8921_driver = {
135 .probe = pm8921_probe,
136 .remove = __devexit_p(pm8921_remove),
137 .driver = {
138 .name = "pm8921-core",
139 .owner = THIS_MODULE,
140 },
141};
142
143static int __init pm8921_init(void)
144{
145 return platform_driver_register(&pm8921_driver);
146}
147subsys_initcall(pm8921_init);
148
149static void __exit pm8921_exit(void)
150{
151 platform_driver_unregister(&pm8921_driver);
152}
153module_exit(pm8921_exit);
154
155MODULE_LICENSE("GPL v2");
156MODULE_DESCRIPTION("PMIC 8921 core driver");
157MODULE_VERSION("1.0");
158MODULE_ALIAS("platform:pm8921-core");