0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/acpi.h>
0011 #include <linux/init.h>
0012 #include <linux/mfd/intel_soc_pmic.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regmap.h>
0015 #include "intel_pmic.h"
0016
0017 #define CHT_WC_V1P05A_CTRL 0x6e3b
0018 #define CHT_WC_V1P15_CTRL 0x6e3c
0019 #define CHT_WC_V1P05A_VSEL 0x6e3d
0020 #define CHT_WC_V1P15_VSEL 0x6e3e
0021 #define CHT_WC_V1P8A_CTRL 0x6e56
0022 #define CHT_WC_V1P8SX_CTRL 0x6e57
0023 #define CHT_WC_VDDQ_CTRL 0x6e58
0024 #define CHT_WC_V1P2A_CTRL 0x6e59
0025 #define CHT_WC_V1P2SX_CTRL 0x6e5a
0026 #define CHT_WC_V1P8A_VSEL 0x6e5b
0027 #define CHT_WC_VDDQ_VSEL 0x6e5c
0028 #define CHT_WC_V2P8SX_CTRL 0x6e5d
0029 #define CHT_WC_V3P3A_CTRL 0x6e5e
0030 #define CHT_WC_V3P3SD_CTRL 0x6e5f
0031 #define CHT_WC_VSDIO_CTRL 0x6e67
0032 #define CHT_WC_V3P3A_VSEL 0x6e68
0033 #define CHT_WC_VPROG1A_CTRL 0x6e90
0034 #define CHT_WC_VPROG1B_CTRL 0x6e91
0035 #define CHT_WC_VPROG1F_CTRL 0x6e95
0036 #define CHT_WC_VPROG2D_CTRL 0x6e99
0037 #define CHT_WC_VPROG3A_CTRL 0x6e9a
0038 #define CHT_WC_VPROG3B_CTRL 0x6e9b
0039 #define CHT_WC_VPROG4A_CTRL 0x6e9c
0040 #define CHT_WC_VPROG4B_CTRL 0x6e9d
0041 #define CHT_WC_VPROG4C_CTRL 0x6e9e
0042 #define CHT_WC_VPROG4D_CTRL 0x6e9f
0043 #define CHT_WC_VPROG5A_CTRL 0x6ea0
0044 #define CHT_WC_VPROG5B_CTRL 0x6ea1
0045 #define CHT_WC_VPROG6A_CTRL 0x6ea2
0046 #define CHT_WC_VPROG6B_CTRL 0x6ea3
0047 #define CHT_WC_VPROG1A_VSEL 0x6ec0
0048 #define CHT_WC_VPROG1B_VSEL 0x6ec1
0049 #define CHT_WC_V1P8SX_VSEL 0x6ec2
0050 #define CHT_WC_V1P2SX_VSEL 0x6ec3
0051 #define CHT_WC_V1P2A_VSEL 0x6ec4
0052 #define CHT_WC_VPROG1F_VSEL 0x6ec5
0053 #define CHT_WC_VSDIO_VSEL 0x6ec6
0054 #define CHT_WC_V2P8SX_VSEL 0x6ec7
0055 #define CHT_WC_V3P3SD_VSEL 0x6ec8
0056 #define CHT_WC_VPROG2D_VSEL 0x6ec9
0057 #define CHT_WC_VPROG3A_VSEL 0x6eca
0058 #define CHT_WC_VPROG3B_VSEL 0x6ecb
0059 #define CHT_WC_VPROG4A_VSEL 0x6ecc
0060 #define CHT_WC_VPROG4B_VSEL 0x6ecd
0061 #define CHT_WC_VPROG4C_VSEL 0x6ece
0062 #define CHT_WC_VPROG4D_VSEL 0x6ecf
0063 #define CHT_WC_VPROG5A_VSEL 0x6ed0
0064 #define CHT_WC_VPROG5B_VSEL 0x6ed1
0065 #define CHT_WC_VPROG6A_VSEL 0x6ed2
0066 #define CHT_WC_VPROG6B_VSEL 0x6ed3
0067
0068
0069
0070
0071
0072
0073 static struct pmic_table power_table[] = {
0074 {
0075 .address = 0x0,
0076 .reg = CHT_WC_V1P8A_CTRL,
0077 .bit = 0x01,
0078 },
0079 {
0080 .address = 0x04,
0081 .reg = CHT_WC_V1P8SX_CTRL,
0082 .bit = 0x07,
0083 },
0084 {
0085 .address = 0x08,
0086 .reg = CHT_WC_VDDQ_CTRL,
0087 .bit = 0x01,
0088 },
0089 {
0090 .address = 0x0c,
0091 .reg = CHT_WC_V1P2A_CTRL,
0092 .bit = 0x07,
0093 },
0094 {
0095 .address = 0x10,
0096 .reg = CHT_WC_V1P2SX_CTRL,
0097 .bit = 0x07,
0098 },
0099 {
0100 .address = 0x14,
0101 .reg = CHT_WC_V2P8SX_CTRL,
0102 .bit = 0x07,
0103 },
0104 {
0105 .address = 0x18,
0106 .reg = CHT_WC_V3P3A_CTRL,
0107 .bit = 0x01,
0108 },
0109 {
0110 .address = 0x1c,
0111 .reg = CHT_WC_V3P3SD_CTRL,
0112 .bit = 0x07,
0113 },
0114 {
0115 .address = 0x20,
0116 .reg = CHT_WC_VSDIO_CTRL,
0117 .bit = 0x07,
0118 },
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 {
0140 .address = 0x34,
0141 .reg = CHT_WC_VPROG1A_CTRL,
0142 .bit = 0x07,
0143 },
0144 {
0145 .address = 0x38,
0146 .reg = CHT_WC_VPROG1B_CTRL,
0147 .bit = 0x07,
0148 },
0149 {
0150 .address = 0x3c,
0151 .reg = CHT_WC_VPROG1F_CTRL,
0152 .bit = 0x07,
0153 },
0154 {
0155 .address = 0x40,
0156 .reg = CHT_WC_VPROG2D_CTRL,
0157 .bit = 0x07,
0158 },
0159 {
0160 .address = 0x44,
0161 .reg = CHT_WC_VPROG3A_CTRL,
0162 .bit = 0x07,
0163 },
0164 {
0165 .address = 0x48,
0166 .reg = CHT_WC_VPROG3B_CTRL,
0167 .bit = 0x07,
0168 },
0169 {
0170 .address = 0x4c,
0171 .reg = CHT_WC_VPROG4A_CTRL,
0172 .bit = 0x07,
0173 },
0174 {
0175 .address = 0x50,
0176 .reg = CHT_WC_VPROG4B_CTRL,
0177 .bit = 0x07,
0178 },
0179 {
0180 .address = 0x54,
0181 .reg = CHT_WC_VPROG4C_CTRL,
0182 .bit = 0x07,
0183 },
0184 {
0185 .address = 0x58,
0186 .reg = CHT_WC_VPROG4D_CTRL,
0187 .bit = 0x07,
0188 },
0189 {
0190 .address = 0x5c,
0191 .reg = CHT_WC_VPROG5A_CTRL,
0192 .bit = 0x07,
0193 },
0194 {
0195 .address = 0x60,
0196 .reg = CHT_WC_VPROG5B_CTRL,
0197 .bit = 0x07,
0198 },
0199 {
0200 .address = 0x64,
0201 .reg = CHT_WC_VPROG6A_CTRL,
0202 .bit = 0x07,
0203 },
0204 {
0205 .address = 0x68,
0206 .reg = CHT_WC_VPROG6B_CTRL,
0207 .bit = 0x07,
0208 },
0209
0210
0211
0212
0213
0214 };
0215
0216 static int intel_cht_wc_pmic_get_power(struct regmap *regmap, int reg,
0217 int bit, u64 *value)
0218 {
0219 int data;
0220
0221 if (regmap_read(regmap, reg, &data))
0222 return -EIO;
0223
0224 *value = (data & bit) ? 1 : 0;
0225 return 0;
0226 }
0227
0228 static int intel_cht_wc_pmic_update_power(struct regmap *regmap, int reg,
0229 int bitmask, bool on)
0230 {
0231 return regmap_update_bits(regmap, reg, bitmask, on ? 1 : 0);
0232 }
0233
0234 static int intel_cht_wc_exec_mipi_pmic_seq_element(struct regmap *regmap,
0235 u16 i2c_client_address,
0236 u32 reg_address,
0237 u32 value, u32 mask)
0238 {
0239 u32 address;
0240
0241 if (i2c_client_address > 0xff || reg_address > 0xff) {
0242 pr_warn("%s warning addresses too big client 0x%x reg 0x%x\n",
0243 __func__, i2c_client_address, reg_address);
0244 return -ERANGE;
0245 }
0246
0247 address = (i2c_client_address << 8) | reg_address;
0248
0249 return regmap_update_bits(regmap, address, mask, value);
0250 }
0251
0252
0253
0254
0255
0256 static const struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = {
0257 .get_power = intel_cht_wc_pmic_get_power,
0258 .update_power = intel_cht_wc_pmic_update_power,
0259 .exec_mipi_pmic_seq_element = intel_cht_wc_exec_mipi_pmic_seq_element,
0260 .lpat_raw_to_temp = acpi_lpat_raw_to_temp,
0261 .power_table = power_table,
0262 .power_table_count = ARRAY_SIZE(power_table),
0263 };
0264
0265 static int intel_cht_wc_pmic_opregion_probe(struct platform_device *pdev)
0266 {
0267 struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
0268
0269 return intel_pmic_install_opregion_handler(&pdev->dev,
0270 ACPI_HANDLE(pdev->dev.parent),
0271 pmic->regmap,
0272 &intel_cht_wc_pmic_opregion_data);
0273 }
0274
0275 static const struct platform_device_id cht_wc_opregion_id_table[] = {
0276 { .name = "cht_wcove_region" },
0277 {},
0278 };
0279
0280 static struct platform_driver intel_cht_wc_pmic_opregion_driver = {
0281 .probe = intel_cht_wc_pmic_opregion_probe,
0282 .driver = {
0283 .name = "cht_whiskey_cove_pmic",
0284 },
0285 .id_table = cht_wc_opregion_id_table,
0286 };
0287 builtin_platform_driver(intel_cht_wc_pmic_opregion_driver);