aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@intel.com>2014-11-24 04:24:47 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-26 17:32:05 -0500
commitd8139f6311129b4fdc370cbfc03424afea83693b (patch)
tree24f99112df72f58fcd5f73fb43aed9d356505ae6
parentb1eea857d8c70dc3789cc2231e3c0a273a67ba06 (diff)
ACPI / PMIC: support PMIC operation region for XPower AXP288
The Baytrail-T-CR platform firmware has defined two customized operation regions for PMIC chip Dollar Cove XPower - one is for power resource handling and one is for thermal just like the CrystalCove one. This patch adds support for them on top of the common PMIC opregion region code. Signed-off-by: Aaron Lu <aaron.lu@intel.com> Acked-by: Lee Jones <lee.jones@linaro.org> for the MFD part Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/Kconfig6
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/pmic/intel_pmic_xpower.c246
-rw-r--r--drivers/mfd/axp20x.c3
4 files changed, 256 insertions, 0 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index df816456dc06..bc682526e155 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -409,6 +409,12 @@ config CRC_PMIC_OPREGION
409 help 409 help
410 This config adds ACPI operation region support for CrystalCove PMIC. 410 This config adds ACPI operation region support for CrystalCove PMIC.
411 411
412config XPOWER_PMIC_OPREGION
413 bool "ACPI operation region support for XPower AXP288 PMIC"
414 depends on AXP288_ADC = y
415 help
416 This config adds ACPI operation region support for XPower AXP288 PMIC.
417
412endif 418endif
413 419
414endif # ACPI 420endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 38ea2a8245ed..5053b0ce585f 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o
90 90
91obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o 91obj-$(CONFIG_PMIC_OPREGION) += pmic/intel_pmic.o
92obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o 92obj-$(CONFIG_CRC_PMIC_OPREGION) += pmic/intel_pmic_crc.o
93obj-$(CONFIG_XPOWER_PMIC_OPREGION) += pmic/intel_pmic_xpower.o
diff --git a/drivers/acpi/pmic/intel_pmic_xpower.c b/drivers/acpi/pmic/intel_pmic_xpower.c
new file mode 100644
index 000000000000..f8853e5eb838
--- /dev/null
+++ b/drivers/acpi/pmic/intel_pmic_xpower.c
@@ -0,0 +1,246 @@
1/*
2 * intel_pmic_xpower.c - XPower AXP288 PMIC operation region driver
3 *
4 * Copyright (C) 2014 Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/module.h>
17#include <linux/acpi.h>
18#include <linux/mfd/axp20x.h>
19#include <linux/regmap.h>
20#include <linux/platform_device.h>
21#include <linux/iio/consumer.h>
22#include "intel_pmic.h"
23
24#define XPOWER_GPADC_LOW 0x5b
25
26static struct pmic_table power_table[] = {
27 {
28 .address = 0x00,
29 .reg = 0x13,
30 .bit = 0x05,
31 },
32 {
33 .address = 0x04,
34 .reg = 0x13,
35 .bit = 0x06,
36 },
37 {
38 .address = 0x08,
39 .reg = 0x13,
40 .bit = 0x07,
41 },
42 {
43 .address = 0x0c,
44 .reg = 0x12,
45 .bit = 0x03,
46 },
47 {
48 .address = 0x10,
49 .reg = 0x12,
50 .bit = 0x04,
51 },
52 {
53 .address = 0x14,
54 .reg = 0x12,
55 .bit = 0x05,
56 },
57 {
58 .address = 0x18,
59 .reg = 0x12,
60 .bit = 0x06,
61 },
62 {
63 .address = 0x1c,
64 .reg = 0x12,
65 .bit = 0x00,
66 },
67 {
68 .address = 0x20,
69 .reg = 0x12,
70 .bit = 0x01,
71 },
72 {
73 .address = 0x24,
74 .reg = 0x12,
75 .bit = 0x02,
76 },
77 {
78 .address = 0x28,
79 .reg = 0x13,
80 .bit = 0x02,
81 },
82 {
83 .address = 0x2c,
84 .reg = 0x13,
85 .bit = 0x03,
86 },
87 {
88 .address = 0x30,
89 .reg = 0x13,
90 .bit = 0x04,
91 },
92 {
93 .address = 0x38,
94 .reg = 0x10,
95 .bit = 0x03,
96 },
97 {
98 .address = 0x3c,
99 .reg = 0x10,
100 .bit = 0x06,
101 },
102 {
103 .address = 0x40,
104 .reg = 0x10,
105 .bit = 0x05,
106 },
107 {
108 .address = 0x44,
109 .reg = 0x10,
110 .bit = 0x04,
111 },
112 {
113 .address = 0x48,
114 .reg = 0x10,
115 .bit = 0x01,
116 },
117 {
118 .address = 0x4c,
119 .reg = 0x10,
120 .bit = 0x00
121 },
122};
123
124/* TMP0 - TMP5 are the same, all from GPADC */
125static struct pmic_table thermal_table[] = {
126 {
127 .address = 0x00,
128 .reg = XPOWER_GPADC_LOW
129 },
130 {
131 .address = 0x0c,
132 .reg = XPOWER_GPADC_LOW
133 },
134 {
135 .address = 0x18,
136 .reg = XPOWER_GPADC_LOW
137 },
138 {
139 .address = 0x24,
140 .reg = XPOWER_GPADC_LOW
141 },
142 {
143 .address = 0x30,
144 .reg = XPOWER_GPADC_LOW
145 },
146 {
147 .address = 0x3c,
148 .reg = XPOWER_GPADC_LOW
149 },
150};
151
152static int intel_xpower_pmic_get_power(struct regmap *regmap, int reg,
153 int bit, u64 *value)
154{
155 int data;
156
157 if (regmap_read(regmap, reg, &data))
158 return -EIO;
159
160 *value = (data & BIT(bit)) ? 1 : 0;
161 return 0;
162}
163
164static int intel_xpower_pmic_update_power(struct regmap *regmap, int reg,
165 int bit, bool on)
166{
167 int data;
168
169 if (regmap_read(regmap, reg, &data))
170 return -EIO;
171
172 if (on)
173 data |= BIT(bit);
174 else
175 data &= ~BIT(bit);
176
177 if (regmap_write(regmap, reg, data))
178 return -EIO;
179
180 return 0;
181}
182
183/**
184 * intel_xpower_pmic_get_raw_temp(): Get raw temperature reading from the PMIC
185 *
186 * @regmap: regmap of the PMIC device
187 * @reg: register to get the reading
188 *
189 * We could get the sensor value by manipulating the HW regs here, but since
190 * the axp288 IIO driver may also access the same regs at the same time, the
191 * APIs provided by IIO subsystem are used here instead to avoid problems. As
192 * a result, the two passed in params are of no actual use.
193 *
194 * Return a positive value on success, errno on failure.
195 */
196static int intel_xpower_pmic_get_raw_temp(struct regmap *regmap, int reg)
197{
198 struct iio_channel *gpadc_chan;
199 int ret, val;
200
201 gpadc_chan = iio_channel_get(NULL, "axp288-system-temp");
202 if (IS_ERR_OR_NULL(gpadc_chan))
203 return -EACCES;
204
205 ret = iio_read_channel_raw(gpadc_chan, &val);
206 if (ret < 0)
207 val = ret;
208
209 iio_channel_release(gpadc_chan);
210 return val;
211}
212
213static struct intel_pmic_opregion_data intel_xpower_pmic_opregion_data = {
214 .get_power = intel_xpower_pmic_get_power,
215 .update_power = intel_xpower_pmic_update_power,
216 .get_raw_temp = intel_xpower_pmic_get_raw_temp,
217 .power_table = power_table,
218 .power_table_count = ARRAY_SIZE(power_table),
219 .thermal_table = thermal_table,
220 .thermal_table_count = ARRAY_SIZE(thermal_table),
221};
222
223
224static int intel_xpower_pmic_opregion_probe(struct platform_device *pdev)
225{
226 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
227 return intel_pmic_install_opregion_handler(&pdev->dev,
228 ACPI_HANDLE(pdev->dev.parent), axp20x->regmap,
229 &intel_xpower_pmic_opregion_data);
230}
231
232static struct platform_driver intel_xpower_pmic_opregion_driver = {
233 .probe = intel_xpower_pmic_opregion_probe,
234 .driver = {
235 .name = "axp288_pmic_acpi",
236 },
237};
238
239static int __init intel_xpower_pmic_opregion_driver_init(void)
240{
241 return platform_driver_register(&intel_xpower_pmic_opregion_driver);
242}
243module_init(intel_xpower_pmic_opregion_driver_init);
244
245MODULE_DESCRIPTION("XPower AXP288 ACPI operation region driver");
246MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 971b0eb8d821..1df18d188342 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -354,6 +354,9 @@ static struct mfd_cell axp288_cells[] = {
354 .num_resources = ARRAY_SIZE(axp288_battery_resources), 354 .num_resources = ARRAY_SIZE(axp288_battery_resources),
355 .resources = axp288_battery_resources, 355 .resources = axp288_battery_resources,
356 }, 356 },
357 {
358 .name = "axp288_pmic_acpi",
359 },
357}; 360};
358 361
359static struct axp20x_dev *axp20x_pm_power_off; 362static struct axp20x_dev *axp20x_pm_power_off;