0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/acpi.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/i2c.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/mfd/intel_soc_pmic.h>
0017 #include <linux/module.h>
0018 #include <linux/regmap.h>
0019
0020 #define CHTDC_TI_IRQLVL1 0x01
0021 #define CHTDC_TI_MASK_IRQLVL1 0x02
0022
0023
0024 enum {
0025 CHTDC_TI_PWRBTN = 0,
0026 CHTDC_TI_DIETMPWARN,
0027 CHTDC_TI_ADCCMPL,
0028
0029 CHTDC_TI_VBATLOW = 4,
0030 CHTDC_TI_VBUSDET,
0031
0032 CHTDC_TI_CCEOCAL = 7,
0033 };
0034
0035 static const struct resource power_button_resources[] = {
0036 DEFINE_RES_IRQ(CHTDC_TI_PWRBTN),
0037 };
0038
0039 static const struct resource thermal_resources[] = {
0040 DEFINE_RES_IRQ(CHTDC_TI_DIETMPWARN),
0041 };
0042
0043 static const struct resource adc_resources[] = {
0044 DEFINE_RES_IRQ(CHTDC_TI_ADCCMPL),
0045 };
0046
0047 static const struct resource pwrsrc_resources[] = {
0048 DEFINE_RES_IRQ(CHTDC_TI_VBUSDET),
0049 };
0050
0051 static const struct resource battery_resources[] = {
0052 DEFINE_RES_IRQ(CHTDC_TI_VBATLOW),
0053 DEFINE_RES_IRQ(CHTDC_TI_CCEOCAL),
0054 };
0055
0056 static struct mfd_cell chtdc_ti_dev[] = {
0057 {
0058 .name = "chtdc_ti_pwrbtn",
0059 .num_resources = ARRAY_SIZE(power_button_resources),
0060 .resources = power_button_resources,
0061 }, {
0062 .name = "chtdc_ti_adc",
0063 .num_resources = ARRAY_SIZE(adc_resources),
0064 .resources = adc_resources,
0065 }, {
0066 .name = "chtdc_ti_thermal",
0067 .num_resources = ARRAY_SIZE(thermal_resources),
0068 .resources = thermal_resources,
0069 }, {
0070 .name = "chtdc_ti_pwrsrc",
0071 .num_resources = ARRAY_SIZE(pwrsrc_resources),
0072 .resources = pwrsrc_resources,
0073 }, {
0074 .name = "chtdc_ti_battery",
0075 .num_resources = ARRAY_SIZE(battery_resources),
0076 .resources = battery_resources,
0077 },
0078 { .name = "chtdc_ti_region", },
0079 };
0080
0081 static const struct regmap_config chtdc_ti_regmap_config = {
0082 .reg_bits = 8,
0083 .val_bits = 8,
0084 .max_register = 128,
0085 .cache_type = REGCACHE_NONE,
0086 };
0087
0088 static const struct regmap_irq chtdc_ti_irqs[] = {
0089 REGMAP_IRQ_REG(CHTDC_TI_PWRBTN, 0, BIT(CHTDC_TI_PWRBTN)),
0090 REGMAP_IRQ_REG(CHTDC_TI_DIETMPWARN, 0, BIT(CHTDC_TI_DIETMPWARN)),
0091 REGMAP_IRQ_REG(CHTDC_TI_ADCCMPL, 0, BIT(CHTDC_TI_ADCCMPL)),
0092 REGMAP_IRQ_REG(CHTDC_TI_VBATLOW, 0, BIT(CHTDC_TI_VBATLOW)),
0093 REGMAP_IRQ_REG(CHTDC_TI_VBUSDET, 0, BIT(CHTDC_TI_VBUSDET)),
0094 REGMAP_IRQ_REG(CHTDC_TI_CCEOCAL, 0, BIT(CHTDC_TI_CCEOCAL)),
0095 };
0096
0097 static const struct regmap_irq_chip chtdc_ti_irq_chip = {
0098 .name = KBUILD_MODNAME,
0099 .irqs = chtdc_ti_irqs,
0100 .num_irqs = ARRAY_SIZE(chtdc_ti_irqs),
0101 .num_regs = 1,
0102 .status_base = CHTDC_TI_IRQLVL1,
0103 .mask_base = CHTDC_TI_MASK_IRQLVL1,
0104 .ack_base = CHTDC_TI_IRQLVL1,
0105 };
0106
0107 static int chtdc_ti_probe(struct i2c_client *i2c)
0108 {
0109 struct device *dev = &i2c->dev;
0110 struct intel_soc_pmic *pmic;
0111 int ret;
0112
0113 pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
0114 if (!pmic)
0115 return -ENOMEM;
0116
0117 i2c_set_clientdata(i2c, pmic);
0118
0119 pmic->regmap = devm_regmap_init_i2c(i2c, &chtdc_ti_regmap_config);
0120 if (IS_ERR(pmic->regmap))
0121 return PTR_ERR(pmic->regmap);
0122 pmic->irq = i2c->irq;
0123
0124 ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
0125 IRQF_ONESHOT, 0,
0126 &chtdc_ti_irq_chip,
0127 &pmic->irq_chip_data);
0128 if (ret)
0129 return ret;
0130
0131 return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, chtdc_ti_dev,
0132 ARRAY_SIZE(chtdc_ti_dev), NULL, 0,
0133 regmap_irq_get_domain(pmic->irq_chip_data));
0134 }
0135
0136 static void chtdc_ti_shutdown(struct i2c_client *i2c)
0137 {
0138 struct intel_soc_pmic *pmic = i2c_get_clientdata(i2c);
0139
0140 disable_irq(pmic->irq);
0141 }
0142
0143 static int __maybe_unused chtdc_ti_suspend(struct device *dev)
0144 {
0145 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0146
0147 disable_irq(pmic->irq);
0148
0149 return 0;
0150 }
0151
0152 static int __maybe_unused chtdc_ti_resume(struct device *dev)
0153 {
0154 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0155
0156 enable_irq(pmic->irq);
0157
0158 return 0;
0159 }
0160
0161 static SIMPLE_DEV_PM_OPS(chtdc_ti_pm_ops, chtdc_ti_suspend, chtdc_ti_resume);
0162
0163 static const struct acpi_device_id chtdc_ti_acpi_ids[] = {
0164 { "INT33F5" },
0165 { },
0166 };
0167 MODULE_DEVICE_TABLE(acpi, chtdc_ti_acpi_ids);
0168
0169 static struct i2c_driver chtdc_ti_i2c_driver = {
0170 .driver = {
0171 .name = "intel_soc_pmic_chtdc_ti",
0172 .pm = &chtdc_ti_pm_ops,
0173 .acpi_match_table = chtdc_ti_acpi_ids,
0174 },
0175 .probe_new = chtdc_ti_probe,
0176 .shutdown = chtdc_ti_shutdown,
0177 };
0178 module_i2c_driver(chtdc_ti_i2c_driver);
0179
0180 MODULE_DESCRIPTION("I2C driver for Intel SoC Dollar Cove TI PMIC");
0181 MODULE_LICENSE("GPL v2");