2 * intel_pmic_crc.c - Intel CrystalCove 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/init.h>
17 #include <linux/acpi.h>
18 #include <linux/mfd/intel_soc_pmic.h>
19 #include <linux/regmap.h>
20 #include <linux/platform_device.h>
21 #include "intel_pmic.h"
23 #define PWR_SOURCE_SELECT BIT(1)
25 #define PMIC_A0LOCK_REG 0xc5
27 static struct pmic_table power_table
[] = {
40 static struct pmic_table thermal_table
[] = {
91 static int intel_crc_pmic_get_power(struct regmap
*regmap
, int reg
,
96 if (regmap_read(regmap
, reg
, &data
))
99 *value
= (data
& PWR_SOURCE_SELECT
) && (data
& BIT(bit
)) ? 1 : 0;
103 static int intel_crc_pmic_update_power(struct regmap
*regmap
, int reg
,
108 if (regmap_read(regmap
, reg
, &data
))
112 data
|= PWR_SOURCE_SELECT
| BIT(bit
);
115 data
|= PWR_SOURCE_SELECT
;
118 if (regmap_write(regmap
, reg
, data
))
123 static int intel_crc_pmic_get_raw_temp(struct regmap
*regmap
, int reg
)
128 * Raw temperature value is 10bits: 8bits in reg
129 * and 2bits in reg-1: bit0,1
131 if (regmap_read(regmap
, reg
, &temp_l
) ||
132 regmap_read(regmap
, reg
- 1, &temp_h
))
135 return temp_l
| (temp_h
& 0x3) << 8;
138 static int intel_crc_pmic_update_aux(struct regmap
*regmap
, int reg
, int raw
)
140 return regmap_write(regmap
, reg
, raw
) ||
141 regmap_update_bits(regmap
, reg
- 1, 0x3, raw
>> 8) ? -EIO
: 0;
144 static int intel_crc_pmic_get_policy(struct regmap
*regmap
,
145 int reg
, int bit
, u64
*value
)
149 if (regmap_read(regmap
, reg
, &pen
))
155 static int intel_crc_pmic_update_policy(struct regmap
*regmap
,
156 int reg
, int bit
, int enable
)
160 /* Update to policy enable bit requires unlocking a0lock */
161 if (regmap_read(regmap
, PMIC_A0LOCK_REG
, &alert0
))
164 if (regmap_update_bits(regmap
, PMIC_A0LOCK_REG
, 0x01, 0))
167 if (regmap_update_bits(regmap
, reg
, 0x80, enable
<< 7))
171 if (regmap_write(regmap
, PMIC_A0LOCK_REG
, alert0
))
177 static struct intel_pmic_opregion_data intel_crc_pmic_opregion_data
= {
178 .get_power
= intel_crc_pmic_get_power
,
179 .update_power
= intel_crc_pmic_update_power
,
180 .get_raw_temp
= intel_crc_pmic_get_raw_temp
,
181 .update_aux
= intel_crc_pmic_update_aux
,
182 .get_policy
= intel_crc_pmic_get_policy
,
183 .update_policy
= intel_crc_pmic_update_policy
,
184 .power_table
= power_table
,
185 .power_table_count
= ARRAY_SIZE(power_table
),
186 .thermal_table
= thermal_table
,
187 .thermal_table_count
= ARRAY_SIZE(thermal_table
),
190 static int intel_crc_pmic_opregion_probe(struct platform_device
*pdev
)
192 struct intel_soc_pmic
*pmic
= dev_get_drvdata(pdev
->dev
.parent
);
193 return intel_pmic_install_opregion_handler(&pdev
->dev
,
194 ACPI_HANDLE(pdev
->dev
.parent
), pmic
->regmap
,
195 &intel_crc_pmic_opregion_data
);
198 static struct platform_driver intel_crc_pmic_opregion_driver
= {
199 .probe
= intel_crc_pmic_opregion_probe
,
201 .name
= "crystal_cove_pmic",
205 static int __init
intel_crc_pmic_opregion_driver_init(void)
207 return platform_driver_register(&intel_crc_pmic_opregion_driver
);
209 device_initcall(intel_crc_pmic_opregion_driver_init
);