root/drivers/acpi/pmic/intel_pmic_chtwc.c

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

DEFINITIONS

This source file includes following definitions.
  1. intel_cht_wc_pmic_get_power
  2. intel_cht_wc_pmic_update_power
  3. intel_cht_wc_exec_mipi_pmic_seq_element
  4. intel_cht_wc_pmic_opregion_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Intel CHT Whiskey Cove PMIC operation region driver
   4  * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
   5  *
   6  * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
   7  * Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
   8  */
   9 
  10 #include <linux/acpi.h>
  11 #include <linux/init.h>
  12 #include <linux/mfd/intel_soc_pmic.h>
  13 #include <linux/platform_device.h>
  14 #include <linux/regmap.h>
  15 #include "intel_pmic.h"
  16 
  17 #define CHT_WC_V1P05A_CTRL              0x6e3b
  18 #define CHT_WC_V1P15_CTRL               0x6e3c
  19 #define CHT_WC_V1P05A_VSEL              0x6e3d
  20 #define CHT_WC_V1P15_VSEL               0x6e3e
  21 #define CHT_WC_V1P8A_CTRL               0x6e56
  22 #define CHT_WC_V1P8SX_CTRL              0x6e57
  23 #define CHT_WC_VDDQ_CTRL                0x6e58
  24 #define CHT_WC_V1P2A_CTRL               0x6e59
  25 #define CHT_WC_V1P2SX_CTRL              0x6e5a
  26 #define CHT_WC_V1P8A_VSEL               0x6e5b
  27 #define CHT_WC_VDDQ_VSEL                0x6e5c
  28 #define CHT_WC_V2P8SX_CTRL              0x6e5d
  29 #define CHT_WC_V3P3A_CTRL               0x6e5e
  30 #define CHT_WC_V3P3SD_CTRL              0x6e5f
  31 #define CHT_WC_VSDIO_CTRL               0x6e67
  32 #define CHT_WC_V3P3A_VSEL               0x6e68
  33 #define CHT_WC_VPROG1A_CTRL             0x6e90
  34 #define CHT_WC_VPROG1B_CTRL             0x6e91
  35 #define CHT_WC_VPROG1F_CTRL             0x6e95
  36 #define CHT_WC_VPROG2D_CTRL             0x6e99
  37 #define CHT_WC_VPROG3A_CTRL             0x6e9a
  38 #define CHT_WC_VPROG3B_CTRL             0x6e9b
  39 #define CHT_WC_VPROG4A_CTRL             0x6e9c
  40 #define CHT_WC_VPROG4B_CTRL             0x6e9d
  41 #define CHT_WC_VPROG4C_CTRL             0x6e9e
  42 #define CHT_WC_VPROG4D_CTRL             0x6e9f
  43 #define CHT_WC_VPROG5A_CTRL             0x6ea0
  44 #define CHT_WC_VPROG5B_CTRL             0x6ea1
  45 #define CHT_WC_VPROG6A_CTRL             0x6ea2
  46 #define CHT_WC_VPROG6B_CTRL             0x6ea3
  47 #define CHT_WC_VPROG1A_VSEL             0x6ec0
  48 #define CHT_WC_VPROG1B_VSEL             0x6ec1
  49 #define CHT_WC_V1P8SX_VSEL              0x6ec2
  50 #define CHT_WC_V1P2SX_VSEL              0x6ec3
  51 #define CHT_WC_V1P2A_VSEL               0x6ec4
  52 #define CHT_WC_VPROG1F_VSEL             0x6ec5
  53 #define CHT_WC_VSDIO_VSEL               0x6ec6
  54 #define CHT_WC_V2P8SX_VSEL              0x6ec7
  55 #define CHT_WC_V3P3SD_VSEL              0x6ec8
  56 #define CHT_WC_VPROG2D_VSEL             0x6ec9
  57 #define CHT_WC_VPROG3A_VSEL             0x6eca
  58 #define CHT_WC_VPROG3B_VSEL             0x6ecb
  59 #define CHT_WC_VPROG4A_VSEL             0x6ecc
  60 #define CHT_WC_VPROG4B_VSEL             0x6ecd
  61 #define CHT_WC_VPROG4C_VSEL             0x6ece
  62 #define CHT_WC_VPROG4D_VSEL             0x6ecf
  63 #define CHT_WC_VPROG5A_VSEL             0x6ed0
  64 #define CHT_WC_VPROG5B_VSEL             0x6ed1
  65 #define CHT_WC_VPROG6A_VSEL             0x6ed2
  66 #define CHT_WC_VPROG6B_VSEL             0x6ed3
  67 
  68 /*
  69  * Regulator support is based on the non upstream patch:
  70  * "regulator: whiskey_cove: implements Whiskey Cove pmic VRF support"
  71  * https://github.com/intel-aero/meta-intel-aero/blob/master/recipes-kernel/linux/linux-yocto/0019-regulator-whiskey_cove-implements-WhiskeyCove-pmic-V.patch
  72  */
  73 static struct pmic_table power_table[] = {
  74         {
  75                 .address = 0x0,
  76                 .reg = CHT_WC_V1P8A_CTRL,
  77                 .bit = 0x01,
  78         }, /* V18A */
  79         {
  80                 .address = 0x04,
  81                 .reg = CHT_WC_V1P8SX_CTRL,
  82                 .bit = 0x07,
  83         }, /* V18X */
  84         {
  85                 .address = 0x08,
  86                 .reg = CHT_WC_VDDQ_CTRL,
  87                 .bit = 0x01,
  88         }, /* VDDQ */
  89         {
  90                 .address = 0x0c,
  91                 .reg = CHT_WC_V1P2A_CTRL,
  92                 .bit = 0x07,
  93         }, /* V12A */
  94         {
  95                 .address = 0x10,
  96                 .reg = CHT_WC_V1P2SX_CTRL,
  97                 .bit = 0x07,
  98         }, /* V12X */
  99         {
 100                 .address = 0x14,
 101                 .reg = CHT_WC_V2P8SX_CTRL,
 102                 .bit = 0x07,
 103         }, /* V28X */
 104         {
 105                 .address = 0x18,
 106                 .reg = CHT_WC_V3P3A_CTRL,
 107                 .bit = 0x01,
 108         }, /* V33A */
 109         {
 110                 .address = 0x1c,
 111                 .reg = CHT_WC_V3P3SD_CTRL,
 112                 .bit = 0x07,
 113         }, /* V3SD */
 114         {
 115                 .address = 0x20,
 116                 .reg = CHT_WC_VSDIO_CTRL,
 117                 .bit = 0x07,
 118         }, /* VSD */
 119 /*      {
 120                 .address = 0x24,
 121                 .reg = ??,
 122                 .bit = ??,
 123         }, ** VSW2 */
 124 /*      {
 125                 .address = 0x28,
 126                 .reg = ??,
 127                 .bit = ??,
 128         }, ** VSW1 */
 129 /*      {
 130                 .address = 0x2c,
 131                 .reg = ??,
 132                 .bit = ??,
 133         }, ** VUPY */
 134 /*      {
 135                 .address = 0x30,
 136                 .reg = ??,
 137                 .bit = ??,
 138         }, ** VRSO */
 139         {
 140                 .address = 0x34,
 141                 .reg = CHT_WC_VPROG1A_CTRL,
 142                 .bit = 0x07,
 143         }, /* VP1A */
 144         {
 145                 .address = 0x38,
 146                 .reg = CHT_WC_VPROG1B_CTRL,
 147                 .bit = 0x07,
 148         }, /* VP1B */
 149         {
 150                 .address = 0x3c,
 151                 .reg = CHT_WC_VPROG1F_CTRL,
 152                 .bit = 0x07,
 153         }, /* VP1F */
 154         {
 155                 .address = 0x40,
 156                 .reg = CHT_WC_VPROG2D_CTRL,
 157                 .bit = 0x07,
 158         }, /* VP2D */
 159         {
 160                 .address = 0x44,
 161                 .reg = CHT_WC_VPROG3A_CTRL,
 162                 .bit = 0x07,
 163         }, /* VP3A */
 164         {
 165                 .address = 0x48,
 166                 .reg = CHT_WC_VPROG3B_CTRL,
 167                 .bit = 0x07,
 168         }, /* VP3B */
 169         {
 170                 .address = 0x4c,
 171                 .reg = CHT_WC_VPROG4A_CTRL,
 172                 .bit = 0x07,
 173         }, /* VP4A */
 174         {
 175                 .address = 0x50,
 176                 .reg = CHT_WC_VPROG4B_CTRL,
 177                 .bit = 0x07,
 178         }, /* VP4B */
 179         {
 180                 .address = 0x54,
 181                 .reg = CHT_WC_VPROG4C_CTRL,
 182                 .bit = 0x07,
 183         }, /* VP4C */
 184         {
 185                 .address = 0x58,
 186                 .reg = CHT_WC_VPROG4D_CTRL,
 187                 .bit = 0x07,
 188         }, /* VP4D */
 189         {
 190                 .address = 0x5c,
 191                 .reg = CHT_WC_VPROG5A_CTRL,
 192                 .bit = 0x07,
 193         }, /* VP5A */
 194         {
 195                 .address = 0x60,
 196                 .reg = CHT_WC_VPROG5B_CTRL,
 197                 .bit = 0x07,
 198         }, /* VP5B */
 199         {
 200                 .address = 0x64,
 201                 .reg = CHT_WC_VPROG6A_CTRL,
 202                 .bit = 0x07,
 203         }, /* VP6A */
 204         {
 205                 .address = 0x68,
 206                 .reg = CHT_WC_VPROG6B_CTRL,
 207                 .bit = 0x07,
 208         }, /* VP6B */
 209 /*      {
 210                 .address = 0x6c,
 211                 .reg = ??,
 212                 .bit = ??,
 213         }  ** VP7A */
 214 };
 215 
 216 static int intel_cht_wc_pmic_get_power(struct regmap *regmap, int reg,
 217                 int bit, u64 *value)
 218 {
 219         int data;
 220 
 221         if (regmap_read(regmap, reg, &data))
 222                 return -EIO;
 223 
 224         *value = (data & bit) ? 1 : 0;
 225         return 0;
 226 }
 227 
 228 static int intel_cht_wc_pmic_update_power(struct regmap *regmap, int reg,
 229                 int bitmask, bool on)
 230 {
 231         return regmap_update_bits(regmap, reg, bitmask, on ? 1 : 0);
 232 }
 233 
 234 static int intel_cht_wc_exec_mipi_pmic_seq_element(struct regmap *regmap,
 235                                                    u16 i2c_client_address,
 236                                                    u32 reg_address,
 237                                                    u32 value, u32 mask)
 238 {
 239         u32 address;
 240 
 241         if (i2c_client_address > 0xff || reg_address > 0xff) {
 242                 pr_warn("%s warning addresses too big client 0x%x reg 0x%x\n",
 243                         __func__, i2c_client_address, reg_address);
 244                 return -ERANGE;
 245         }
 246 
 247         address = (i2c_client_address << 8) | reg_address;
 248 
 249         return regmap_update_bits(regmap, address, mask, value);
 250 }
 251 
 252 /*
 253  * The thermal table and ops are empty, we do not support the Thermal opregion
 254  * (DPTF) due to lacking documentation.
 255  */
 256 static struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = {
 257         .get_power              = intel_cht_wc_pmic_get_power,
 258         .update_power           = intel_cht_wc_pmic_update_power,
 259         .exec_mipi_pmic_seq_element = intel_cht_wc_exec_mipi_pmic_seq_element,
 260         .power_table            = power_table,
 261         .power_table_count      = ARRAY_SIZE(power_table),
 262 };
 263 
 264 static int intel_cht_wc_pmic_opregion_probe(struct platform_device *pdev)
 265 {
 266         struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
 267 
 268         return intel_pmic_install_opregion_handler(&pdev->dev,
 269                         ACPI_HANDLE(pdev->dev.parent),
 270                         pmic->regmap,
 271                         &intel_cht_wc_pmic_opregion_data);
 272 }
 273 
 274 static const struct platform_device_id cht_wc_opregion_id_table[] = {
 275         { .name = "cht_wcove_region" },
 276         {},
 277 };
 278 
 279 static struct platform_driver intel_cht_wc_pmic_opregion_driver = {
 280         .probe = intel_cht_wc_pmic_opregion_probe,
 281         .driver = {
 282                 .name = "cht_whiskey_cove_pmic",
 283         },
 284         .id_table = cht_wc_opregion_id_table,
 285 };
 286 builtin_platform_driver(intel_cht_wc_pmic_opregion_driver);

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