brintos

brintos / linux-shallow public Read only

0
0
Text · 6.7 KiB · 81caede Raw
289 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Intel CHT Whiskey Cove PMIC operation region driver4 * 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		0x6e3b18#define CHT_WC_V1P15_CTRL		0x6e3c19#define CHT_WC_V1P05A_VSEL		0x6e3d20#define CHT_WC_V1P15_VSEL		0x6e3e21#define CHT_WC_V1P8A_CTRL		0x6e5622#define CHT_WC_V1P8SX_CTRL		0x6e5723#define CHT_WC_VDDQ_CTRL		0x6e5824#define CHT_WC_V1P2A_CTRL		0x6e5925#define CHT_WC_V1P2SX_CTRL		0x6e5a26#define CHT_WC_V1P8A_VSEL		0x6e5b27#define CHT_WC_VDDQ_VSEL		0x6e5c28#define CHT_WC_V2P8SX_CTRL		0x6e5d29#define CHT_WC_V3P3A_CTRL		0x6e5e30#define CHT_WC_V3P3SD_CTRL		0x6e5f31#define CHT_WC_VSDIO_CTRL		0x6e6732#define CHT_WC_V3P3A_VSEL		0x6e6833#define CHT_WC_VPROG1A_CTRL		0x6e9034#define CHT_WC_VPROG1B_CTRL		0x6e9135#define CHT_WC_VPROG1F_CTRL		0x6e9536#define CHT_WC_VPROG2D_CTRL		0x6e9937#define CHT_WC_VPROG3A_CTRL		0x6e9a38#define CHT_WC_VPROG3B_CTRL		0x6e9b39#define CHT_WC_VPROG4A_CTRL		0x6e9c40#define CHT_WC_VPROG4B_CTRL		0x6e9d41#define CHT_WC_VPROG4C_CTRL		0x6e9e42#define CHT_WC_VPROG4D_CTRL		0x6e9f43#define CHT_WC_VPROG5A_CTRL		0x6ea044#define CHT_WC_VPROG5B_CTRL		0x6ea145#define CHT_WC_VPROG6A_CTRL		0x6ea246#define CHT_WC_VPROG6B_CTRL		0x6ea347#define CHT_WC_VPROG1A_VSEL		0x6ec048#define CHT_WC_VPROG1B_VSEL		0x6ec149#define CHT_WC_V1P8SX_VSEL		0x6ec250#define CHT_WC_V1P2SX_VSEL		0x6ec351#define CHT_WC_V1P2A_VSEL		0x6ec452#define CHT_WC_VPROG1F_VSEL		0x6ec553#define CHT_WC_VSDIO_VSEL		0x6ec654#define CHT_WC_V2P8SX_VSEL		0x6ec755#define CHT_WC_V3P3SD_VSEL		0x6ec856#define CHT_WC_VPROG2D_VSEL		0x6ec957#define CHT_WC_VPROG3A_VSEL		0x6eca58#define CHT_WC_VPROG3B_VSEL		0x6ecb59#define CHT_WC_VPROG4A_VSEL		0x6ecc60#define CHT_WC_VPROG4B_VSEL		0x6ecd61#define CHT_WC_VPROG4C_VSEL		0x6ece62#define CHT_WC_VPROG4D_VSEL		0x6ecf63#define CHT_WC_VPROG5A_VSEL		0x6ed064#define CHT_WC_VPROG5B_VSEL		0x6ed165#define CHT_WC_VPROG6A_VSEL		0x6ed266#define CHT_WC_VPROG6B_VSEL		0x6ed367 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.patch72 */73static const 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 216static 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 228static 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 234static 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	struct device *dev = regmap_get_device(regmap);240	u32 address;241 242	if (i2c_client_address > 0xff || reg_address > 0xff) {243		dev_warn(dev, "warning addresses too big client 0x%x reg 0x%x\n",244			 i2c_client_address, reg_address);245		return -ERANGE;246	}247 248	address = (i2c_client_address << 8) | reg_address;249 250	return regmap_update_bits(regmap, address, mask, value);251}252 253/*254 * The thermal table and ops are empty, we do not support the Thermal opregion255 * (DPTF) due to lacking documentation.256 */257static const struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = {258	.get_power		= intel_cht_wc_pmic_get_power,259	.update_power		= intel_cht_wc_pmic_update_power,260	.exec_mipi_pmic_seq_element = intel_cht_wc_exec_mipi_pmic_seq_element,261	.lpat_raw_to_temp	= acpi_lpat_raw_to_temp,262	.power_table		= power_table,263	.power_table_count	= ARRAY_SIZE(power_table),264};265 266static int intel_cht_wc_pmic_opregion_probe(struct platform_device *pdev)267{268	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);269 270	return intel_pmic_install_opregion_handler(&pdev->dev,271			ACPI_HANDLE(pdev->dev.parent),272			pmic->regmap,273			&intel_cht_wc_pmic_opregion_data);274}275 276static const struct platform_device_id cht_wc_opregion_id_table[] = {277	{ .name = "cht_wcove_region" },278	{},279};280 281static struct platform_driver intel_cht_wc_pmic_opregion_driver = {282	.probe = intel_cht_wc_pmic_opregion_probe,283	.driver = {284		.name = "cht_whiskey_cove_pmic",285	},286	.id_table = cht_wc_opregion_id_table,287};288builtin_platform_driver(intel_cht_wc_pmic_opregion_driver);289