2 * intel_pmic_xpower.c - XPower AXP288 PMIC operation region driver
4 * Copyright (C) 2014 Intel Corporation. All rights reserved.
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.
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.
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"
24 #define XPOWER_GPADC_LOW 0x5b
26 static struct pmic_table power_table
[] = {
124 /* TMP0 - TMP5 are the same, all from GPADC */
125 static struct pmic_table thermal_table
[] = {
128 .reg
= XPOWER_GPADC_LOW
132 .reg
= XPOWER_GPADC_LOW
136 .reg
= XPOWER_GPADC_LOW
140 .reg
= XPOWER_GPADC_LOW
144 .reg
= XPOWER_GPADC_LOW
148 .reg
= XPOWER_GPADC_LOW
152 static int intel_xpower_pmic_get_power(struct regmap
*regmap
, int reg
,
157 if (regmap_read(regmap
, reg
, &data
))
160 *value
= (data
& BIT(bit
)) ? 1 : 0;
164 static int intel_xpower_pmic_update_power(struct regmap
*regmap
, int reg
,
169 if (regmap_read(regmap
, reg
, &data
))
177 if (regmap_write(regmap
, reg
, data
))
184 * intel_xpower_pmic_get_raw_temp(): Get raw temperature reading from the PMIC
186 * @regmap: regmap of the PMIC device
187 * @reg: register to get the reading
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.
194 * Return a positive value on success, errno on failure.
196 static int intel_xpower_pmic_get_raw_temp(struct regmap
*regmap
, int reg
)
198 struct iio_channel
*gpadc_chan
;
201 gpadc_chan
= iio_channel_get(NULL
, "axp288-system-temp");
202 if (IS_ERR_OR_NULL(gpadc_chan
))
205 ret
= iio_read_channel_raw(gpadc_chan
, &val
);
209 iio_channel_release(gpadc_chan
);
213 static 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
),
223 static acpi_status
intel_xpower_pmic_gpio_handler(u32 function
,
224 acpi_physical_address address
, u32 bit_width
, u64
*value
,
225 void *handler_context
, void *region_context
)
230 static int intel_xpower_pmic_opregion_probe(struct platform_device
*pdev
)
232 struct device
*parent
= pdev
->dev
.parent
;
233 struct axp20x_dev
*axp20x
= dev_get_drvdata(parent
);
237 status
= acpi_install_address_space_handler(ACPI_HANDLE(parent
),
238 ACPI_ADR_SPACE_GPIO
, intel_xpower_pmic_gpio_handler
,
240 if (ACPI_FAILURE(status
))
243 result
= intel_pmic_install_opregion_handler(&pdev
->dev
,
244 ACPI_HANDLE(parent
), axp20x
->regmap
,
245 &intel_xpower_pmic_opregion_data
);
247 acpi_remove_address_space_handler(ACPI_HANDLE(parent
),
249 intel_xpower_pmic_gpio_handler
);
254 static struct platform_driver intel_xpower_pmic_opregion_driver
= {
255 .probe
= intel_xpower_pmic_opregion_probe
,
257 .name
= "axp288_pmic_acpi",
261 static int __init
intel_xpower_pmic_opregion_driver_init(void)
263 return platform_driver_register(&intel_xpower_pmic_opregion_driver
);
265 module_init(intel_xpower_pmic_opregion_driver_init
);
267 MODULE_DESCRIPTION("XPower AXP288 ACPI operation region driver");
268 MODULE_LICENSE("GPL");