diff options
| -rw-r--r-- | drivers/mfd/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mfd/pm8921-core.c | 158 | ||||
| -rw-r--r-- | include/linux/mfd/pm8xxx/core.h | 71 | ||||
| -rw-r--r-- | include/linux/mfd/pm8xxx/pm8921.h | 27 |
5 files changed, 275 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 | ||
| 694 | config MFD_PM8XXX | ||
| 695 | tristate | ||
| 696 | |||
| 697 | config 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 | |||
| 694 | endif # MFD_SUPPORT | 712 | endif # MFD_SUPPORT |
| 695 | 713 | ||
| 696 | menu "Multimedia Capabilities Port drivers" | 714 | menu "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 | |||
| 91 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o | 91 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o |
| 92 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o | 92 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o |
| 93 | obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o | 93 | obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o |
| 94 | obj-$(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 | |||
| 27 | struct pm8921 { | ||
| 28 | struct device *dev; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static 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 | |||
| 39 | static 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 | |||
| 47 | static 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 | |||
| 56 | static 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 | |||
| 65 | static 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 | |||
| 72 | static 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 | |||
| 113 | err_read_rev: | ||
| 114 | kfree(pmic); | ||
| 115 | return rc; | ||
| 116 | } | ||
| 117 | |||
| 118 | static 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 | |||
| 134 | static 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 | |||
| 143 | static int __init pm8921_init(void) | ||
| 144 | { | ||
| 145 | return platform_driver_register(&pm8921_driver); | ||
| 146 | } | ||
| 147 | subsys_initcall(pm8921_init); | ||
| 148 | |||
| 149 | static void __exit pm8921_exit(void) | ||
| 150 | { | ||
| 151 | platform_driver_unregister(&pm8921_driver); | ||
| 152 | } | ||
| 153 | module_exit(pm8921_exit); | ||
| 154 | |||
| 155 | MODULE_LICENSE("GPL v2"); | ||
| 156 | MODULE_DESCRIPTION("PMIC 8921 core driver"); | ||
| 157 | MODULE_VERSION("1.0"); | ||
| 158 | MODULE_ALIAS("platform:pm8921-core"); | ||
diff --git a/include/linux/mfd/pm8xxx/core.h b/include/linux/mfd/pm8xxx/core.h new file mode 100644 index 000000000000..36ccb33332ed --- /dev/null +++ b/include/linux/mfd/pm8xxx/core.h | |||
| @@ -0,0 +1,71 @@ | |||
| 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 | * Qualcomm PMIC 8xxx driver header file | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef __MFD_PM8XXX_CORE_H | ||
| 19 | #define __MFD_PM8XXX_CORE_H | ||
| 20 | |||
| 21 | #include <linux/mfd/core.h> | ||
| 22 | |||
| 23 | struct pm8xxx_drvdata { | ||
| 24 | int (*pmic_readb) (const struct device *dev, u16 addr, u8 *val); | ||
| 25 | int (*pmic_writeb) (const struct device *dev, u16 addr, u8 val); | ||
| 26 | int (*pmic_read_buf) (const struct device *dev, u16 addr, u8 *buf, | ||
| 27 | int n); | ||
| 28 | int (*pmic_write_buf) (const struct device *dev, u16 addr, u8 *buf, | ||
| 29 | int n); | ||
| 30 | void *pm_chip_data; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static inline int pm8xxx_readb(const struct device *dev, u16 addr, u8 *val) | ||
| 34 | { | ||
| 35 | struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); | ||
| 36 | |||
| 37 | if (!dd) | ||
| 38 | return -EINVAL; | ||
| 39 | return dd->pmic_readb(dev, addr, val); | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline int pm8xxx_writeb(const struct device *dev, u16 addr, u8 val) | ||
| 43 | { | ||
| 44 | struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); | ||
| 45 | |||
| 46 | if (!dd) | ||
| 47 | return -EINVAL; | ||
| 48 | return dd->pmic_writeb(dev, addr, val); | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline int pm8xxx_read_buf(const struct device *dev, u16 addr, u8 *buf, | ||
| 52 | int n) | ||
| 53 | { | ||
| 54 | struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); | ||
| 55 | |||
| 56 | if (!dd) | ||
| 57 | return -EINVAL; | ||
| 58 | return dd->pmic_read_buf(dev, addr, buf, n); | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline int pm8xxx_write_buf(const struct device *dev, u16 addr, u8 *buf, | ||
| 62 | int n) | ||
| 63 | { | ||
| 64 | struct pm8xxx_drvdata *dd = dev_get_drvdata(dev); | ||
| 65 | |||
| 66 | if (!dd) | ||
| 67 | return -EINVAL; | ||
| 68 | return dd->pmic_write_buf(dev, addr, buf, n); | ||
| 69 | } | ||
| 70 | |||
| 71 | #endif | ||
diff --git a/include/linux/mfd/pm8xxx/pm8921.h b/include/linux/mfd/pm8xxx/pm8921.h new file mode 100644 index 000000000000..33fbe9c960a3 --- /dev/null +++ b/include/linux/mfd/pm8xxx/pm8921.h | |||
| @@ -0,0 +1,27 @@ | |||
| 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 | * Qualcomm PMIC 8921 driver header file | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef __MFD_PM8921_H | ||
| 19 | #define __MFD_PM8921_H | ||
| 20 | |||
| 21 | #include <linux/device.h> | ||
| 22 | |||
| 23 | struct pm8921_platform_data { | ||
| 24 | int irq_base; | ||
| 25 | }; | ||
| 26 | |||
| 27 | #endif | ||
