Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.18-rc3 182 lines 4.7 kB view raw
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 = 0xff, 85 /* The hardware does not support reading multiple registers at once */ 86 .use_single_read = true, 87}; 88 89static const struct regmap_irq chtdc_ti_irqs[] = { 90 REGMAP_IRQ_REG(CHTDC_TI_PWRBTN, 0, BIT(CHTDC_TI_PWRBTN)), 91 REGMAP_IRQ_REG(CHTDC_TI_DIETMPWARN, 0, BIT(CHTDC_TI_DIETMPWARN)), 92 REGMAP_IRQ_REG(CHTDC_TI_ADCCMPL, 0, BIT(CHTDC_TI_ADCCMPL)), 93 REGMAP_IRQ_REG(CHTDC_TI_VBATLOW, 0, BIT(CHTDC_TI_VBATLOW)), 94 REGMAP_IRQ_REG(CHTDC_TI_VBUSDET, 0, BIT(CHTDC_TI_VBUSDET)), 95 REGMAP_IRQ_REG(CHTDC_TI_CCEOCAL, 0, BIT(CHTDC_TI_CCEOCAL)), 96}; 97 98static const struct regmap_irq_chip chtdc_ti_irq_chip = { 99 .name = KBUILD_MODNAME, 100 .irqs = chtdc_ti_irqs, 101 .num_irqs = ARRAY_SIZE(chtdc_ti_irqs), 102 .num_regs = 1, 103 .status_base = CHTDC_TI_IRQLVL1, 104 .mask_base = CHTDC_TI_MASK_IRQLVL1, 105 .ack_base = CHTDC_TI_IRQLVL1, 106}; 107 108static int chtdc_ti_probe(struct i2c_client *i2c) 109{ 110 struct device *dev = &i2c->dev; 111 struct intel_soc_pmic *pmic; 112 int ret; 113 114 pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); 115 if (!pmic) 116 return -ENOMEM; 117 118 i2c_set_clientdata(i2c, pmic); 119 120 pmic->regmap = devm_regmap_init_i2c(i2c, &chtdc_ti_regmap_config); 121 if (IS_ERR(pmic->regmap)) 122 return PTR_ERR(pmic->regmap); 123 pmic->irq = i2c->irq; 124 125 ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq, 126 IRQF_ONESHOT, 0, 127 &chtdc_ti_irq_chip, 128 &pmic->irq_chip_data); 129 if (ret) 130 return ret; 131 132 return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, chtdc_ti_dev, 133 ARRAY_SIZE(chtdc_ti_dev), NULL, 0, 134 regmap_irq_get_domain(pmic->irq_chip_data)); 135} 136 137static void chtdc_ti_shutdown(struct i2c_client *i2c) 138{ 139 struct intel_soc_pmic *pmic = i2c_get_clientdata(i2c); 140 141 disable_irq(pmic->irq); 142} 143 144static int chtdc_ti_suspend(struct device *dev) 145{ 146 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 147 148 disable_irq(pmic->irq); 149 150 return 0; 151} 152 153static int chtdc_ti_resume(struct device *dev) 154{ 155 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 156 157 enable_irq(pmic->irq); 158 159 return 0; 160} 161 162static DEFINE_SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume); 163 164static const struct acpi_device_id chtdc_ti_acpi_ids[] = { 165 { "INT33F5" }, 166 { }, 167}; 168MODULE_DEVICE_TABLE(acpi, chtdc_ti_acpi_ids); 169 170static struct i2c_driver chtdc_ti_i2c_driver = { 171 .driver = { 172 .name = "intel_soc_pmic_chtdc_ti", 173 .pm = pm_sleep_ptr(&chtdc_ti_pm_ops), 174 .acpi_match_table = chtdc_ti_acpi_ids, 175 }, 176 .probe = chtdc_ti_probe, 177 .shutdown = chtdc_ti_shutdown, 178}; 179module_i2c_driver(chtdc_ti_i2c_driver); 180 181MODULE_DESCRIPTION("I2C driver for Intel SoC Dollar Cove TI PMIC"); 182MODULE_LICENSE("GPL v2");