root/drivers/acpi/pmic/tps68470_pmic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmic_get_reg_bit
  2. tps68470_pmic_get_power
  3. tps68470_pmic_get_vr_val
  4. tps68470_pmic_get_clk
  5. tps68470_pmic_get_clk_freq
  6. ti_tps68470_regmap_update_bits
  7. tps68470_pmic_common_handler
  8. tps68470_pmic_cfreq_handler
  9. tps68470_pmic_clk_handler
  10. tps68470_pmic_vrval_handler
  11. tps68470_pmic_pwr_handler
  12. tps68470_pmic_opregion_probe

   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, &reg, &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 (!dev || !tps68470_regmap) {
 380                 dev_warn(dev, "dev or regmap is NULL\n");
 381                 return -EINVAL;
 382         }
 383 
 384         if (!handle) {
 385                 dev_warn(dev, "acpi handle is NULL\n");
 386                 return -ENODEV;
 387         }
 388 
 389         opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL);
 390         if (!opregion)
 391                 return -ENOMEM;
 392 
 393         mutex_init(&opregion->lock);
 394         opregion->regmap = tps68470_regmap;
 395 
 396         status = acpi_install_address_space_handler(handle,
 397                                                     TI_PMIC_POWER_OPREGION_ID,
 398                                                     tps68470_pmic_pwr_handler,
 399                                                     NULL, opregion);
 400         if (ACPI_FAILURE(status))
 401                 goto out_mutex_destroy;
 402 
 403         status = acpi_install_address_space_handler(handle,
 404                                                     TI_PMIC_VR_VAL_OPREGION_ID,
 405                                                     tps68470_pmic_vrval_handler,
 406                                                     NULL, opregion);
 407         if (ACPI_FAILURE(status))
 408                 goto out_remove_power_handler;
 409 
 410         status = acpi_install_address_space_handler(handle,
 411                                                     TI_PMIC_CLOCK_OPREGION_ID,
 412                                                     tps68470_pmic_clk_handler,
 413                                                     NULL, opregion);
 414         if (ACPI_FAILURE(status))
 415                 goto out_remove_vr_val_handler;
 416 
 417         status = acpi_install_address_space_handler(handle,
 418                                                     TI_PMIC_CLKFREQ_OPREGION_ID,
 419                                                     tps68470_pmic_cfreq_handler,
 420                                                     NULL, opregion);
 421         if (ACPI_FAILURE(status))
 422                 goto out_remove_clk_handler;
 423 
 424         return 0;
 425 
 426 out_remove_clk_handler:
 427         acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID,
 428                                           tps68470_pmic_clk_handler);
 429 out_remove_vr_val_handler:
 430         acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID,
 431                                           tps68470_pmic_vrval_handler);
 432 out_remove_power_handler:
 433         acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID,
 434                                           tps68470_pmic_pwr_handler);
 435 out_mutex_destroy:
 436         mutex_destroy(&opregion->lock);
 437         return -ENODEV;
 438 }
 439 
 440 static struct platform_driver tps68470_pmic_opregion_driver = {
 441         .probe = tps68470_pmic_opregion_probe,
 442         .driver = {
 443                 .name = "tps68470_pmic_opregion",
 444         },
 445 };
 446 
 447 builtin_platform_driver(tps68470_pmic_opregion_driver)

/* [<][>][^][v][top][bottom][index][help] */