cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intel_soc_pmic_chtdc_ti.c (4616B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Device access for Dollar Cove TI PMIC
      4 *
      5 * Copyright (c) 2014, Intel Corporation.
      6 *   Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com>
      7 *
      8 * Cleanup and forward-ported
      9 *   Copyright (c) 2017 Takashi Iwai <tiwai@suse.de>
     10 */
     11
     12#include <linux/acpi.h>
     13#include <linux/interrupt.h>
     14#include <linux/i2c.h>
     15#include <linux/mfd/core.h>
     16#include <linux/mfd/intel_soc_pmic.h>
     17#include <linux/module.h>
     18#include <linux/regmap.h>
     19
     20#define CHTDC_TI_IRQLVL1	0x01
     21#define CHTDC_TI_MASK_IRQLVL1	0x02
     22
     23/* Level 1 IRQs */
     24enum {
     25	CHTDC_TI_PWRBTN = 0,	/* power button */
     26	CHTDC_TI_DIETMPWARN,	/* thermal */
     27	CHTDC_TI_ADCCMPL,	/* ADC */
     28	/* No IRQ 3 */
     29	CHTDC_TI_VBATLOW = 4,	/* battery */
     30	CHTDC_TI_VBUSDET,	/* power source */
     31	/* No IRQ 6 */
     32	CHTDC_TI_CCEOCAL = 7,	/* battery */
     33};
     34
     35static const struct resource power_button_resources[] = {
     36	DEFINE_RES_IRQ(CHTDC_TI_PWRBTN),
     37};
     38
     39static const struct resource thermal_resources[] = {
     40	DEFINE_RES_IRQ(CHTDC_TI_DIETMPWARN),
     41};
     42
     43static const struct resource adc_resources[] = {
     44	DEFINE_RES_IRQ(CHTDC_TI_ADCCMPL),
     45};
     46
     47static const struct resource pwrsrc_resources[] = {
     48	DEFINE_RES_IRQ(CHTDC_TI_VBUSDET),
     49};
     50
     51static const struct resource battery_resources[] = {
     52	DEFINE_RES_IRQ(CHTDC_TI_VBATLOW),
     53	DEFINE_RES_IRQ(CHTDC_TI_CCEOCAL),
     54};
     55
     56static struct mfd_cell chtdc_ti_dev[] = {
     57	{
     58		.name = "chtdc_ti_pwrbtn",
     59		.num_resources = ARRAY_SIZE(power_button_resources),
     60		.resources = power_button_resources,
     61	}, {
     62		.name = "chtdc_ti_adc",
     63		.num_resources = ARRAY_SIZE(adc_resources),
     64		.resources = adc_resources,
     65	}, {
     66		.name = "chtdc_ti_thermal",
     67		.num_resources = ARRAY_SIZE(thermal_resources),
     68		.resources = thermal_resources,
     69	}, {
     70		.name = "chtdc_ti_pwrsrc",
     71		.num_resources = ARRAY_SIZE(pwrsrc_resources),
     72		.resources = pwrsrc_resources,
     73	}, {
     74		.name = "chtdc_ti_battery",
     75		.num_resources = ARRAY_SIZE(battery_resources),
     76		.resources = battery_resources,
     77	},
     78	{	.name = "chtdc_ti_region", },
     79};
     80
     81static const struct regmap_config chtdc_ti_regmap_config = {
     82	.reg_bits = 8,
     83	.val_bits = 8,
     84	.max_register = 128,
     85	.cache_type = REGCACHE_NONE,
     86};
     87
     88static const struct regmap_irq chtdc_ti_irqs[] = {
     89	REGMAP_IRQ_REG(CHTDC_TI_PWRBTN, 0, BIT(CHTDC_TI_PWRBTN)),
     90	REGMAP_IRQ_REG(CHTDC_TI_DIETMPWARN, 0, BIT(CHTDC_TI_DIETMPWARN)),
     91	REGMAP_IRQ_REG(CHTDC_TI_ADCCMPL, 0, BIT(CHTDC_TI_ADCCMPL)),
     92	REGMAP_IRQ_REG(CHTDC_TI_VBATLOW, 0, BIT(CHTDC_TI_VBATLOW)),
     93	REGMAP_IRQ_REG(CHTDC_TI_VBUSDET, 0, BIT(CHTDC_TI_VBUSDET)),
     94	REGMAP_IRQ_REG(CHTDC_TI_CCEOCAL, 0, BIT(CHTDC_TI_CCEOCAL)),
     95};
     96
     97static const struct regmap_irq_chip chtdc_ti_irq_chip = {
     98	.name = KBUILD_MODNAME,
     99	.irqs = chtdc_ti_irqs,
    100	.num_irqs = ARRAY_SIZE(chtdc_ti_irqs),
    101	.num_regs = 1,
    102	.status_base = CHTDC_TI_IRQLVL1,
    103	.mask_base = CHTDC_TI_MASK_IRQLVL1,
    104	.ack_base = CHTDC_TI_IRQLVL1,
    105};
    106
    107static int chtdc_ti_probe(struct i2c_client *i2c)
    108{
    109	struct device *dev = &i2c->dev;
    110	struct intel_soc_pmic *pmic;
    111	int ret;
    112
    113	pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
    114	if (!pmic)
    115		return -ENOMEM;
    116
    117	i2c_set_clientdata(i2c, pmic);
    118
    119	pmic->regmap = devm_regmap_init_i2c(i2c, &chtdc_ti_regmap_config);
    120	if (IS_ERR(pmic->regmap))
    121		return PTR_ERR(pmic->regmap);
    122	pmic->irq = i2c->irq;
    123
    124	ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
    125				       IRQF_ONESHOT, 0,
    126				       &chtdc_ti_irq_chip,
    127				       &pmic->irq_chip_data);
    128	if (ret)
    129		return ret;
    130
    131	return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, chtdc_ti_dev,
    132				    ARRAY_SIZE(chtdc_ti_dev), NULL, 0,
    133				    regmap_irq_get_domain(pmic->irq_chip_data));
    134}
    135
    136static void chtdc_ti_shutdown(struct i2c_client *i2c)
    137{
    138	struct intel_soc_pmic *pmic = i2c_get_clientdata(i2c);
    139
    140	disable_irq(pmic->irq);
    141}
    142
    143static int __maybe_unused chtdc_ti_suspend(struct device *dev)
    144{
    145	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    146
    147	disable_irq(pmic->irq);
    148
    149	return 0;
    150}
    151
    152static int __maybe_unused chtdc_ti_resume(struct device *dev)
    153{
    154	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    155
    156	enable_irq(pmic->irq);
    157
    158	return 0;
    159}
    160
    161static SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume);
    162
    163static const struct acpi_device_id chtdc_ti_acpi_ids[] = {
    164	{ "INT33F5" },
    165	{ },
    166};
    167MODULE_DEVICE_TABLE(acpi, chtdc_ti_acpi_ids);
    168
    169static struct i2c_driver chtdc_ti_i2c_driver = {
    170	.driver = {
    171		.name = "intel_soc_pmic_chtdc_ti",
    172		.pm = &chtdc_ti_pm_ops,
    173		.acpi_match_table = chtdc_ti_acpi_ids,
    174	},
    175	.probe_new = chtdc_ti_probe,
    176	.shutdown = chtdc_ti_shutdown,
    177};
    178module_i2c_driver(chtdc_ti_i2c_driver);
    179
    180MODULE_DESCRIPTION("I2C driver for Intel SoC Dollar Cove TI PMIC");
    181MODULE_LICENSE("GPL v2");