Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * TI TPS68470 PMIC operation region driver
0004  *
0005  * Copyright (C) 2017 Intel Corporation. All rights reserved.
0006  *
0007  * Author: Rajmohan Mani <rajmohan.mani@intel.com>
0008  *
0009  * Based on drivers/acpi/pmic/intel_pmic* drivers
0010  */
0011 
0012 #include <linux/acpi.h>
0013 #include <linux/init.h>
0014 #include <linux/mfd/tps68470.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/regmap.h>
0017 
0018 struct tps68470_pmic_table {
0019     u32 address;        /* operation region address */
0020     u32 reg;        /* corresponding register */
0021     u32 bitmask;        /* bit mask for power, clock */
0022 };
0023 
0024 #define TI_PMIC_POWER_OPREGION_ID       0xB0
0025 #define TI_PMIC_VR_VAL_OPREGION_ID      0xB1
0026 #define TI_PMIC_CLOCK_OPREGION_ID       0xB2
0027 #define TI_PMIC_CLKFREQ_OPREGION_ID     0xB3
0028 
0029 struct tps68470_pmic_opregion {
0030     struct mutex lock;
0031     struct regmap *regmap;
0032 };
0033 
0034 #define S_IO_I2C_EN (BIT(0) | BIT(1))
0035 
0036 static const struct tps68470_pmic_table power_table[] = {
0037     {
0038         .address = 0x00,
0039         .reg = TPS68470_REG_S_I2C_CTL,
0040         .bitmask = S_IO_I2C_EN,
0041         /* S_I2C_CTL */
0042     },
0043     {
0044         .address = 0x04,
0045         .reg = TPS68470_REG_VCMCTL,
0046         .bitmask = BIT(0),
0047         /* VCMCTL */
0048     },
0049     {
0050         .address = 0x08,
0051         .reg = TPS68470_REG_VAUX1CTL,
0052         .bitmask = BIT(0),
0053         /* VAUX1_CTL */
0054     },
0055     {
0056         .address = 0x0C,
0057         .reg = TPS68470_REG_VAUX2CTL,
0058         .bitmask = BIT(0),
0059         /* VAUX2CTL */
0060     },
0061     {
0062         .address = 0x10,
0063         .reg = TPS68470_REG_VACTL,
0064         .bitmask = BIT(0),
0065         /* VACTL */
0066     },
0067     {
0068         .address = 0x14,
0069         .reg = TPS68470_REG_VDCTL,
0070         .bitmask = BIT(0),
0071         /* VDCTL */
0072     },
0073 };
0074 
0075 /* Table to set voltage regulator value */
0076 static const struct tps68470_pmic_table vr_val_table[] = {
0077     {
0078         .address = 0x00,
0079         .reg = TPS68470_REG_VSIOVAL,
0080         .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK,
0081         /* TPS68470_REG_VSIOVAL */
0082     },
0083     {
0084         .address = 0x04,
0085         .reg = TPS68470_REG_VIOVAL,
0086         .bitmask = TPS68470_VIOVAL_IOVOLT_MASK,
0087         /* TPS68470_REG_VIOVAL */
0088     },
0089     {
0090         .address = 0x08,
0091         .reg = TPS68470_REG_VCMVAL,
0092         .bitmask = TPS68470_VCMVAL_VCVOLT_MASK,
0093         /* TPS68470_REG_VCMVAL */
0094     },
0095     {
0096         .address = 0x0C,
0097         .reg = TPS68470_REG_VAUX1VAL,
0098         .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK,
0099         /* TPS68470_REG_VAUX1VAL */
0100     },
0101     {
0102         .address = 0x10,
0103         .reg = TPS68470_REG_VAUX2VAL,
0104         .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK,
0105         /* TPS68470_REG_VAUX2VAL */
0106     },
0107     {
0108         .address = 0x14,
0109         .reg = TPS68470_REG_VAVAL,
0110         .bitmask = TPS68470_VAVAL_AVOLT_MASK,
0111         /* TPS68470_REG_VAVAL */
0112     },
0113     {
0114         .address = 0x18,
0115         .reg = TPS68470_REG_VDVAL,
0116         .bitmask = TPS68470_VDVAL_DVOLT_MASK,
0117         /* TPS68470_REG_VDVAL */
0118     },
0119 };
0120 
0121 /* Table to configure clock frequency */
0122 static const struct tps68470_pmic_table clk_freq_table[] = {
0123     {
0124         .address = 0x00,
0125         .reg = TPS68470_REG_POSTDIV2,
0126         .bitmask = BIT(0) | BIT(1),
0127         /* TPS68470_REG_POSTDIV2 */
0128     },
0129     {
0130         .address = 0x04,
0131         .reg = TPS68470_REG_BOOSTDIV,
0132         .bitmask = 0x1F,
0133         /* TPS68470_REG_BOOSTDIV */
0134     },
0135     {
0136         .address = 0x08,
0137         .reg = TPS68470_REG_BUCKDIV,
0138         .bitmask = 0x0F,
0139         /* TPS68470_REG_BUCKDIV */
0140     },
0141     {
0142         .address = 0x0C,
0143         .reg = TPS68470_REG_PLLSWR,
0144         .bitmask = 0x13,
0145         /* TPS68470_REG_PLLSWR */
0146     },
0147     {
0148         .address = 0x10,
0149         .reg = TPS68470_REG_XTALDIV,
0150         .bitmask = 0xFF,
0151         /* TPS68470_REG_XTALDIV */
0152     },
0153     {
0154         .address = 0x14,
0155         .reg = TPS68470_REG_PLLDIV,
0156         .bitmask = 0xFF,
0157         /* TPS68470_REG_PLLDIV */
0158     },
0159     {
0160         .address = 0x18,
0161         .reg = TPS68470_REG_POSTDIV,
0162         .bitmask = 0x83,
0163         /* TPS68470_REG_POSTDIV */
0164     },
0165 };
0166 
0167 /* Table to configure and enable clocks */
0168 static const struct tps68470_pmic_table clk_table[] = {
0169     {
0170         .address = 0x00,
0171         .reg = TPS68470_REG_PLLCTL,
0172         .bitmask = 0xF5,
0173         /* TPS68470_REG_PLLCTL */
0174     },
0175     {
0176         .address = 0x04,
0177         .reg = TPS68470_REG_PLLCTL2,
0178         .bitmask = BIT(0),
0179         /* TPS68470_REG_PLLCTL2 */
0180     },
0181     {
0182         .address = 0x08,
0183         .reg = TPS68470_REG_CLKCFG1,
0184         .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
0185             TPS68470_CLKCFG1_MODE_B_MASK,
0186         /* TPS68470_REG_CLKCFG1 */
0187     },
0188     {
0189         .address = 0x0C,
0190         .reg = TPS68470_REG_CLKCFG2,
0191         .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
0192             TPS68470_CLKCFG1_MODE_B_MASK,
0193         /* TPS68470_REG_CLKCFG2 */
0194     },
0195 };
0196 
0197 static int pmic_get_reg_bit(u64 address,
0198                 const struct tps68470_pmic_table *table,
0199                 const unsigned int table_size, int *reg,
0200                 int *bitmask)
0201 {
0202     u64 i;
0203 
0204     i = address / 4;
0205     if (i >= table_size)
0206         return -ENOENT;
0207 
0208     if (!reg || !bitmask)
0209         return -EINVAL;
0210 
0211     *reg = table[i].reg;
0212     *bitmask = table[i].bitmask;
0213 
0214     return 0;
0215 }
0216 
0217 static int tps68470_pmic_get_power(struct regmap *regmap, int reg,
0218                        int bitmask, u64 *value)
0219 {
0220     unsigned int data;
0221 
0222     if (regmap_read(regmap, reg, &data))
0223         return -EIO;
0224 
0225     *value = (data & bitmask) ? 1 : 0;
0226     return 0;
0227 }
0228 
0229 static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg,
0230                        int bitmask, u64 *value)
0231 {
0232     unsigned int data;
0233 
0234     if (regmap_read(regmap, reg, &data))
0235         return -EIO;
0236 
0237     *value = data & bitmask;
0238     return 0;
0239 }
0240 
0241 static int tps68470_pmic_get_clk(struct regmap *regmap, int reg,
0242                        int bitmask, u64 *value)
0243 {
0244     unsigned int data;
0245 
0246     if (regmap_read(regmap, reg, &data))
0247         return -EIO;
0248 
0249     *value = (data & bitmask) ? 1 : 0;
0250     return 0;
0251 }
0252 
0253 static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg,
0254                        int bitmask, u64 *value)
0255 {
0256     unsigned int data;
0257 
0258     if (regmap_read(regmap, reg, &data))
0259         return -EIO;
0260 
0261     *value = data & bitmask;
0262     return 0;
0263 }
0264 
0265 static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg,
0266                     int bitmask, u64 value)
0267 {
0268     return regmap_update_bits(regmap, reg, bitmask, value);
0269 }
0270 
0271 static acpi_status tps68470_pmic_common_handler(u32 function,
0272                       acpi_physical_address address,
0273                       u32 bits, u64 *value,
0274                       void *region_context,
0275                       int (*get)(struct regmap *,
0276                              int, int, u64 *),
0277                       int (*update)(struct regmap *,
0278                             int, int, u64),
0279                       const struct tps68470_pmic_table *tbl,
0280                       unsigned int tbl_size)
0281 {
0282     struct tps68470_pmic_opregion *opregion = region_context;
0283     struct regmap *regmap = opregion->regmap;
0284     int reg, ret, bitmask;
0285 
0286     if (bits != 32)
0287         return AE_BAD_PARAMETER;
0288 
0289     ret = pmic_get_reg_bit(address, tbl, tbl_size, &reg, &bitmask);
0290     if (ret < 0)
0291         return AE_BAD_PARAMETER;
0292 
0293     if (function == ACPI_WRITE && *value > bitmask)
0294         return AE_BAD_PARAMETER;
0295 
0296     mutex_lock(&opregion->lock);
0297 
0298     ret = (function == ACPI_READ) ?
0299         get(regmap, reg, bitmask, value) :
0300         update(regmap, reg, bitmask, *value);
0301 
0302     mutex_unlock(&opregion->lock);
0303 
0304     return ret ? AE_ERROR : AE_OK;
0305 }
0306 
0307 static acpi_status tps68470_pmic_cfreq_handler(u32 function,
0308                         acpi_physical_address address,
0309                         u32 bits, u64 *value,
0310                         void *handler_context,
0311                         void *region_context)
0312 {
0313     return tps68470_pmic_common_handler(function, address, bits, value,
0314                 region_context,
0315                 tps68470_pmic_get_clk_freq,
0316                 ti_tps68470_regmap_update_bits,
0317                 clk_freq_table,
0318                 ARRAY_SIZE(clk_freq_table));
0319 }
0320 
0321 static acpi_status tps68470_pmic_clk_handler(u32 function,
0322                        acpi_physical_address address, u32 bits,
0323                        u64 *value, void *handler_context,
0324                        void *region_context)
0325 {
0326     return tps68470_pmic_common_handler(function, address, bits, value,
0327                 region_context,
0328                 tps68470_pmic_get_clk,
0329                 ti_tps68470_regmap_update_bits,
0330                 clk_table,
0331                 ARRAY_SIZE(clk_table));
0332 }
0333 
0334 static acpi_status tps68470_pmic_vrval_handler(u32 function,
0335                       acpi_physical_address address,
0336                       u32 bits, u64 *value,
0337                       void *handler_context,
0338                       void *region_context)
0339 {
0340     return tps68470_pmic_common_handler(function, address, bits, value,
0341                 region_context,
0342                 tps68470_pmic_get_vr_val,
0343                 ti_tps68470_regmap_update_bits,
0344                 vr_val_table,
0345                 ARRAY_SIZE(vr_val_table));
0346 }
0347 
0348 static acpi_status tps68470_pmic_pwr_handler(u32 function,
0349                      acpi_physical_address address,
0350                      u32 bits, u64 *value,
0351                      void *handler_context,
0352                      void *region_context)
0353 {
0354     if (bits != 32)
0355         return AE_BAD_PARAMETER;
0356 
0357     /* set/clear for bit 0, bits 0 and 1 together */
0358     if (function == ACPI_WRITE &&
0359         !(*value == 0 || *value == 1 || *value == 3)) {
0360         return AE_BAD_PARAMETER;
0361     }
0362 
0363     return tps68470_pmic_common_handler(function, address, bits, value,
0364                 region_context,
0365                 tps68470_pmic_get_power,
0366                 ti_tps68470_regmap_update_bits,
0367                 power_table,
0368                 ARRAY_SIZE(power_table));
0369 }
0370 
0371 static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
0372 {
0373     struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
0374     acpi_handle handle = ACPI_HANDLE(pdev->dev.parent);
0375     struct device *dev = &pdev->dev;
0376     struct tps68470_pmic_opregion *opregion;
0377     acpi_status status;
0378 
0379     if (!dev || !tps68470_regmap) {
0380         dev_warn(dev, "dev or regmap is NULL\n");
0381         return -EINVAL;
0382     }
0383 
0384     if (!handle) {
0385         dev_warn(dev, "acpi handle is NULL\n");
0386         return -ENODEV;
0387     }
0388 
0389     opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL);
0390     if (!opregion)
0391         return -ENOMEM;
0392 
0393     mutex_init(&opregion->lock);
0394     opregion->regmap = tps68470_regmap;
0395 
0396     status = acpi_install_address_space_handler(handle,
0397                             TI_PMIC_POWER_OPREGION_ID,
0398                             tps68470_pmic_pwr_handler,
0399                             NULL, opregion);
0400     if (ACPI_FAILURE(status))
0401         goto out_mutex_destroy;
0402 
0403     status = acpi_install_address_space_handler(handle,
0404                             TI_PMIC_VR_VAL_OPREGION_ID,
0405                             tps68470_pmic_vrval_handler,
0406                             NULL, opregion);
0407     if (ACPI_FAILURE(status))
0408         goto out_remove_power_handler;
0409 
0410     status = acpi_install_address_space_handler(handle,
0411                             TI_PMIC_CLOCK_OPREGION_ID,
0412                             tps68470_pmic_clk_handler,
0413                             NULL, opregion);
0414     if (ACPI_FAILURE(status))
0415         goto out_remove_vr_val_handler;
0416 
0417     status = acpi_install_address_space_handler(handle,
0418                             TI_PMIC_CLKFREQ_OPREGION_ID,
0419                             tps68470_pmic_cfreq_handler,
0420                             NULL, opregion);
0421     if (ACPI_FAILURE(status))
0422         goto out_remove_clk_handler;
0423 
0424     return 0;
0425 
0426 out_remove_clk_handler:
0427     acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID,
0428                       tps68470_pmic_clk_handler);
0429 out_remove_vr_val_handler:
0430     acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID,
0431                       tps68470_pmic_vrval_handler);
0432 out_remove_power_handler:
0433     acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID,
0434                       tps68470_pmic_pwr_handler);
0435 out_mutex_destroy:
0436     mutex_destroy(&opregion->lock);
0437     return -ENODEV;
0438 }
0439 
0440 static struct platform_driver tps68470_pmic_opregion_driver = {
0441     .probe = tps68470_pmic_opregion_probe,
0442     .driver = {
0443         .name = "tps68470_pmic_opregion",
0444     },
0445 };
0446 
0447 builtin_platform_driver(tps68470_pmic_opregion_driver)