1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * TI TPS68470 PMIC operation region driver 4 * 5 * Copyright (C) 2017 Intel Corporation. All rights reserved. 6 * 7 * Author: Rajmohan Mani <rajmohan.mani@intel.com> 8 * 9 * Based on drivers/acpi/pmic/intel_pmic* drivers 10 */ 11 12 #include <linux/acpi.h> 13 #include <linux/init.h> 14 #include <linux/mfd/tps68470.h> 15 #include <linux/platform_device.h> 16 #include <linux/regmap.h> 17 18 struct tps68470_pmic_table { 19 u32 address; /* operation region address */ 20 u32 reg; /* corresponding register */ 21 u32 bitmask; /* bit mask for power, clock */ 22 }; 23 24 #define TI_PMIC_POWER_OPREGION_ID 0xB0 25 #define TI_PMIC_VR_VAL_OPREGION_ID 0xB1 26 #define TI_PMIC_CLOCK_OPREGION_ID 0xB2 27 #define TI_PMIC_CLKFREQ_OPREGION_ID 0xB3 28 29 struct tps68470_pmic_opregion { 30 struct mutex lock; 31 struct regmap *regmap; 32 }; 33 34 #define S_IO_I2C_EN (BIT(0) | BIT(1)) 35 36 static const struct tps68470_pmic_table power_table[] = { 37 { 38 .address = 0x00, 39 .reg = TPS68470_REG_S_I2C_CTL, 40 .bitmask = S_IO_I2C_EN, 41 /* S_I2C_CTL */ 42 }, 43 { 44 .address = 0x04, 45 .reg = TPS68470_REG_VCMCTL, 46 .bitmask = BIT(0), 47 /* VCMCTL */ 48 }, 49 { 50 .address = 0x08, 51 .reg = TPS68470_REG_VAUX1CTL, 52 .bitmask = BIT(0), 53 /* VAUX1_CTL */ 54 }, 55 { 56 .address = 0x0C, 57 .reg = TPS68470_REG_VAUX2CTL, 58 .bitmask = BIT(0), 59 /* VAUX2CTL */ 60 }, 61 { 62 .address = 0x10, 63 .reg = TPS68470_REG_VACTL, 64 .bitmask = BIT(0), 65 /* VACTL */ 66 }, 67 { 68 .address = 0x14, 69 .reg = TPS68470_REG_VDCTL, 70 .bitmask = BIT(0), 71 /* VDCTL */ 72 }, 73 }; 74 75 /* Table to set voltage regulator value */ 76 static const struct tps68470_pmic_table vr_val_table[] = { 77 { 78 .address = 0x00, 79 .reg = TPS68470_REG_VSIOVAL, 80 .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK, 81 /* TPS68470_REG_VSIOVAL */ 82 }, 83 { 84 .address = 0x04, 85 .reg = TPS68470_REG_VIOVAL, 86 .bitmask = TPS68470_VIOVAL_IOVOLT_MASK, 87 /* TPS68470_REG_VIOVAL */ 88 }, 89 { 90 .address = 0x08, 91 .reg = TPS68470_REG_VCMVAL, 92 .bitmask = TPS68470_VCMVAL_VCVOLT_MASK, 93 /* TPS68470_REG_VCMVAL */ 94 }, 95 { 96 .address = 0x0C, 97 .reg = TPS68470_REG_VAUX1VAL, 98 .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK, 99 /* TPS68470_REG_VAUX1VAL */ 100 }, 101 { 102 .address = 0x10, 103 .reg = TPS68470_REG_VAUX2VAL, 104 .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK, 105 /* TPS68470_REG_VAUX2VAL */ 106 }, 107 { 108 .address = 0x14, 109 .reg = TPS68470_REG_VAVAL, 110 .bitmask = TPS68470_VAVAL_AVOLT_MASK, 111 /* TPS68470_REG_VAVAL */ 112 }, 113 { 114 .address = 0x18, 115 .reg = TPS68470_REG_VDVAL, 116 .bitmask = TPS68470_VDVAL_DVOLT_MASK, 117 /* TPS68470_REG_VDVAL */ 118 }, 119 }; 120 121 /* Table to configure clock frequency */ 122 static const struct tps68470_pmic_table clk_freq_table[] = { 123 { 124 .address = 0x00, 125 .reg = TPS68470_REG_POSTDIV2, 126 .bitmask = BIT(0) | BIT(1), 127 /* TPS68470_REG_POSTDIV2 */ 128 }, 129 { 130 .address = 0x04, 131 .reg = TPS68470_REG_BOOSTDIV, 132 .bitmask = 0x1F, 133 /* TPS68470_REG_BOOSTDIV */ 134 }, 135 { 136 .address = 0x08, 137 .reg = TPS68470_REG_BUCKDIV, 138 .bitmask = 0x0F, 139 /* TPS68470_REG_BUCKDIV */ 140 }, 141 { 142 .address = 0x0C, 143 .reg = TPS68470_REG_PLLSWR, 144 .bitmask = 0x13, 145 /* TPS68470_REG_PLLSWR */ 146 }, 147 { 148 .address = 0x10, 149 .reg = TPS68470_REG_XTALDIV, 150 .bitmask = 0xFF, 151 /* TPS68470_REG_XTALDIV */ 152 }, 153 { 154 .address = 0x14, 155 .reg = TPS68470_REG_PLLDIV, 156 .bitmask = 0xFF, 157 /* TPS68470_REG_PLLDIV */ 158 }, 159 { 160 .address = 0x18, 161 .reg = TPS68470_REG_POSTDIV, 162 .bitmask = 0x83, 163 /* TPS68470_REG_POSTDIV */ 164 }, 165 }; 166 167 /* Table to configure and enable clocks */ 168 static const struct tps68470_pmic_table clk_table[] = { 169 { 170 .address = 0x00, 171 .reg = TPS68470_REG_PLLCTL, 172 .bitmask = 0xF5, 173 /* TPS68470_REG_PLLCTL */ 174 }, 175 { 176 .address = 0x04, 177 .reg = TPS68470_REG_PLLCTL2, 178 .bitmask = BIT(0), 179 /* TPS68470_REG_PLLCTL2 */ 180 }, 181 { 182 .address = 0x08, 183 .reg = TPS68470_REG_CLKCFG1, 184 .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | 185 TPS68470_CLKCFG1_MODE_B_MASK, 186 /* TPS68470_REG_CLKCFG1 */ 187 }, 188 { 189 .address = 0x0C, 190 .reg = TPS68470_REG_CLKCFG2, 191 .bitmask = TPS68470_CLKCFG1_MODE_A_MASK | 192 TPS68470_CLKCFG1_MODE_B_MASK, 193 /* TPS68470_REG_CLKCFG2 */ 194 }, 195 }; 196 197 static int pmic_get_reg_bit(u64 address, 198 const struct tps68470_pmic_table *table, 199 const unsigned int table_size, int *reg, 200 int *bitmask) 201 { 202 u64 i; 203 204 i = address / 4; 205 if (i >= table_size) 206 return -ENOENT; 207 208 if (!reg || !bitmask) 209 return -EINVAL; 210 211 *reg = table[i].reg; 212 *bitmask = table[i].bitmask; 213 214 return 0; 215 } 216 217 static int tps68470_pmic_get_power(struct regmap *regmap, int reg, 218 int bitmask, u64 *value) 219 { 220 unsigned int data; 221 222 if (regmap_read(regmap, reg, &data)) 223 return -EIO; 224 225 *value = (data & bitmask) ? 1 : 0; 226 return 0; 227 } 228 229 static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg, 230 int bitmask, u64 *value) 231 { 232 unsigned int data; 233 234 if (regmap_read(regmap, reg, &data)) 235 return -EIO; 236 237 *value = data & bitmask; 238 return 0; 239 } 240 241 static int tps68470_pmic_get_clk(struct regmap *regmap, int reg, 242 int bitmask, u64 *value) 243 { 244 unsigned int data; 245 246 if (regmap_read(regmap, reg, &data)) 247 return -EIO; 248 249 *value = (data & bitmask) ? 1 : 0; 250 return 0; 251 } 252 253 static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg, 254 int bitmask, u64 *value) 255 { 256 unsigned int data; 257 258 if (regmap_read(regmap, reg, &data)) 259 return -EIO; 260 261 *value = data & bitmask; 262 return 0; 263 } 264 265 static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg, 266 int bitmask, u64 value) 267 { 268 return regmap_update_bits(regmap, reg, bitmask, value); 269 } 270 271 static acpi_status tps68470_pmic_common_handler(u32 function, 272 acpi_physical_address address, 273 u32 bits, u64 *value, 274 void *region_context, 275 int (*get)(struct regmap *, 276 int, int, u64 *), 277 int (*update)(struct regmap *, 278 int, int, u64), 279 const struct tps68470_pmic_table *tbl, 280 unsigned int tbl_size) 281 { 282 struct tps68470_pmic_opregion *opregion = region_context; 283 struct regmap *regmap = opregion->regmap; 284 int reg, ret, bitmask; 285 286 if (bits != 32) 287 return AE_BAD_PARAMETER; 288 289 ret = pmic_get_reg_bit(address, tbl, tbl_size, ®, &bitmask); 290 if (ret < 0) 291 return AE_BAD_PARAMETER; 292 293 if (function == ACPI_WRITE && *value > bitmask) 294 return AE_BAD_PARAMETER; 295 296 mutex_lock(&opregion->lock); 297 298 ret = (function == ACPI_READ) ? 299 get(regmap, reg, bitmask, value) : 300 update(regmap, reg, bitmask, *value); 301 302 mutex_unlock(&opregion->lock); 303 304 return ret ? AE_ERROR : AE_OK; 305 } 306 307 static acpi_status tps68470_pmic_cfreq_handler(u32 function, 308 acpi_physical_address address, 309 u32 bits, u64 *value, 310 void *handler_context, 311 void *region_context) 312 { 313 return tps68470_pmic_common_handler(function, address, bits, value, 314 region_context, 315 tps68470_pmic_get_clk_freq, 316 ti_tps68470_regmap_update_bits, 317 clk_freq_table, 318 ARRAY_SIZE(clk_freq_table)); 319 } 320 321 static acpi_status tps68470_pmic_clk_handler(u32 function, 322 acpi_physical_address address, u32 bits, 323 u64 *value, void *handler_context, 324 void *region_context) 325 { 326 return tps68470_pmic_common_handler(function, address, bits, value, 327 region_context, 328 tps68470_pmic_get_clk, 329 ti_tps68470_regmap_update_bits, 330 clk_table, 331 ARRAY_SIZE(clk_table)); 332 } 333 334 static acpi_status tps68470_pmic_vrval_handler(u32 function, 335 acpi_physical_address address, 336 u32 bits, u64 *value, 337 void *handler_context, 338 void *region_context) 339 { 340 return tps68470_pmic_common_handler(function, address, bits, value, 341 region_context, 342 tps68470_pmic_get_vr_val, 343 ti_tps68470_regmap_update_bits, 344 vr_val_table, 345 ARRAY_SIZE(vr_val_table)); 346 } 347 348 static acpi_status tps68470_pmic_pwr_handler(u32 function, 349 acpi_physical_address address, 350 u32 bits, u64 *value, 351 void *handler_context, 352 void *region_context) 353 { 354 if (bits != 32) 355 return AE_BAD_PARAMETER; 356 357 /* set/clear for bit 0, bits 0 and 1 together */ 358 if (function == ACPI_WRITE && 359 !(*value == 0 || *value == 1 || *value == 3)) { 360 return AE_BAD_PARAMETER; 361 } 362 363 return tps68470_pmic_common_handler(function, address, bits, value, 364 region_context, 365 tps68470_pmic_get_power, 366 ti_tps68470_regmap_update_bits, 367 power_table, 368 ARRAY_SIZE(power_table)); 369 } 370 371 static int tps68470_pmic_opregion_probe(struct platform_device *pdev) 372 { 373 struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent); 374 acpi_handle handle = ACPI_HANDLE(pdev->dev.parent); 375 struct device *dev = &pdev->dev; 376 struct tps68470_pmic_opregion *opregion; 377 acpi_status status; 378 379 if (!tps68470_regmap) 380 return dev_err_probe(dev, -EINVAL, "regmap is missing\n"); 381 382 if (!handle) { 383 dev_warn(dev, "acpi handle is NULL\n"); 384 return -ENODEV; 385 } 386 387 opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL); 388 if (!opregion) 389 return -ENOMEM; 390 391 mutex_init(&opregion->lock); 392 opregion->regmap = tps68470_regmap; 393 394 status = acpi_install_address_space_handler(handle, 395 TI_PMIC_POWER_OPREGION_ID, 396 tps68470_pmic_pwr_handler, 397 NULL, opregion); 398 if (ACPI_FAILURE(status)) 399 goto out_mutex_destroy; 400 401 status = acpi_install_address_space_handler(handle, 402 TI_PMIC_VR_VAL_OPREGION_ID, 403 tps68470_pmic_vrval_handler, 404 NULL, opregion); 405 if (ACPI_FAILURE(status)) 406 goto out_remove_power_handler; 407 408 status = acpi_install_address_space_handler(handle, 409 TI_PMIC_CLOCK_OPREGION_ID, 410 tps68470_pmic_clk_handler, 411 NULL, opregion); 412 if (ACPI_FAILURE(status)) 413 goto out_remove_vr_val_handler; 414 415 status = acpi_install_address_space_handler(handle, 416 TI_PMIC_CLKFREQ_OPREGION_ID, 417 tps68470_pmic_cfreq_handler, 418 NULL, opregion); 419 if (ACPI_FAILURE(status)) 420 goto out_remove_clk_handler; 421 422 return 0; 423 424 out_remove_clk_handler: 425 acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID, 426 tps68470_pmic_clk_handler); 427 out_remove_vr_val_handler: 428 acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID, 429 tps68470_pmic_vrval_handler); 430 out_remove_power_handler: 431 acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID, 432 tps68470_pmic_pwr_handler); 433 out_mutex_destroy: 434 mutex_destroy(&opregion->lock); 435 return -ENODEV; 436 } 437 438 static struct platform_driver tps68470_pmic_opregion_driver = { 439 .probe = tps68470_pmic_opregion_probe, 440 .driver = { 441 .name = "tps68470_pmic_opregion", 442 }, 443 }; 444 445 builtin_platform_driver(tps68470_pmic_opregion_driver) 446