brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · ecb36fb Raw
141 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Dollar Cove TI PMIC operation region driver4 * Copyright (C) 2014 Intel Corporation. All rights reserved.5 *6 * Rewritten and cleaned up7 * Copyright (C) 2017 Takashi Iwai <tiwai@suse.de>8 */9 10#include <linux/acpi.h>11#include <linux/bits.h>12#include <linux/init.h>13#include <linux/mfd/intel_soc_pmic.h>14#include <linux/platform_device.h>15#include <asm/byteorder.h>16#include "intel_pmic.h"17 18/* registers stored in 16bit BE (high:low, total 10bit) */19#define PMIC_REG_MASK		GENMASK(9, 0)20 21#define CHTDC_TI_VBAT		0x5422#define CHTDC_TI_DIETEMP	0x5623#define CHTDC_TI_BPTHERM	0x5824#define CHTDC_TI_GPADC		0x5a25 26static const struct pmic_table chtdc_ti_power_table[] = {27	{ .address = 0x00, .reg = 0x41 }, /* LDO1 */28	{ .address = 0x04, .reg = 0x42 }, /* LDO2 */29	{ .address = 0x08, .reg = 0x43 }, /* LDO3 */30	{ .address = 0x0c, .reg = 0x45 }, /* LDO5 */31	{ .address = 0x10, .reg = 0x46 }, /* LDO6 */32	{ .address = 0x14, .reg = 0x47 }, /* LDO7 */33	{ .address = 0x18, .reg = 0x48 }, /* LDO8 */34	{ .address = 0x1c, .reg = 0x49 }, /* LDO9 */35	{ .address = 0x20, .reg = 0x4a }, /* LD10 */36	{ .address = 0x24, .reg = 0x4b }, /* LD11 */37	{ .address = 0x28, .reg = 0x4c }, /* LD12 */38	{ .address = 0x2c, .reg = 0x4d }, /* LD13 */39	{ .address = 0x30, .reg = 0x4e }, /* LD14 */40};41 42static const struct pmic_table chtdc_ti_thermal_table[] = {43	{44		.address = 0x00,45		.reg = CHTDC_TI_GPADC46	},47	{48		.address = 0x0c,49		.reg = CHTDC_TI_GPADC50	},51	/* TMP2 -> SYSTEMP */52	{53		.address = 0x18,54		.reg = CHTDC_TI_GPADC55	},56	/* TMP3 -> BPTHERM */57	{58		.address = 0x24,59		.reg = CHTDC_TI_BPTHERM60	},61	{62		.address = 0x30,63		.reg = CHTDC_TI_GPADC64	},65	/* TMP5 -> DIETEMP */66	{67		.address = 0x3c,68		.reg = CHTDC_TI_DIETEMP69	},70};71 72static int chtdc_ti_pmic_get_power(struct regmap *regmap, int reg, int bit,73				   u64 *value)74{75	int data;76 77	if (regmap_read(regmap, reg, &data))78		return -EIO;79 80	*value = data & BIT(0);81	return 0;82}83 84static int chtdc_ti_pmic_update_power(struct regmap *regmap, int reg, int bit,85				      bool on)86{87	return regmap_update_bits(regmap, reg, 1, on);88}89 90static int chtdc_ti_pmic_get_raw_temp(struct regmap *regmap, int reg)91{92	__be16 buf;93 94	if (regmap_bulk_read(regmap, reg, &buf, sizeof(buf)))95		return -EIO;96 97	return be16_to_cpu(buf) & PMIC_REG_MASK;98}99 100static const struct intel_pmic_opregion_data chtdc_ti_pmic_opregion_data = {101	.get_power = chtdc_ti_pmic_get_power,102	.update_power = chtdc_ti_pmic_update_power,103	.get_raw_temp = chtdc_ti_pmic_get_raw_temp,104	.lpat_raw_to_temp = acpi_lpat_raw_to_temp,105	.power_table = chtdc_ti_power_table,106	.power_table_count = ARRAY_SIZE(chtdc_ti_power_table),107	.thermal_table = chtdc_ti_thermal_table,108	.thermal_table_count = ARRAY_SIZE(chtdc_ti_thermal_table),109	.pmic_i2c_address = 0x5e,110};111 112static int chtdc_ti_pmic_opregion_probe(struct platform_device *pdev)113{114	struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);115	int err;116 117	err = intel_pmic_install_opregion_handler(&pdev->dev,118			ACPI_HANDLE(pdev->dev.parent), pmic->regmap,119			&chtdc_ti_pmic_opregion_data);120	if (err < 0)121		return err;122 123	/* Re-enumerate devices depending on PMIC */124	acpi_dev_clear_dependencies(ACPI_COMPANION(pdev->dev.parent));125	return 0;126}127 128static const struct platform_device_id chtdc_ti_pmic_opregion_id_table[] = {129	{ .name = "chtdc_ti_region" },130	{},131};132 133static struct platform_driver chtdc_ti_pmic_opregion_driver = {134	.probe = chtdc_ti_pmic_opregion_probe,135	.driver = {136		.name = "cht_dollar_cove_ti_pmic",137	},138	.id_table = chtdc_ti_pmic_opregion_id_table,139};140builtin_platform_driver(chtdc_ti_pmic_opregion_driver);141