2 * MFD core driver for Intel Broxton Whiskey Cove PMIC
4 * Copyright (C) 2015 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 #include <linux/acpi.h>
17 #include <linux/delay.h>
18 #include <linux/err.h>
19 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
21 #include <linux/mfd/core.h>
22 #include <linux/mfd/intel_soc_pmic.h>
23 #include <linux/mfd/intel_soc_pmic_bxtwc.h>
24 #include <linux/module.h>
26 #include <asm/intel_pmc_ipc.h>
28 /* PMIC device registers */
29 #define REG_ADDR_MASK 0xFF00
30 #define REG_ADDR_SHIFT 8
31 #define REG_OFFSET_MASK 0xFF
33 /* Interrupt Status Registers */
34 #define BXTWC_IRQLVL1 0x4E02
36 #define BXTWC_PWRBTNIRQ 0x4E03
37 #define BXTWC_THRM0IRQ 0x4E04
38 #define BXTWC_THRM1IRQ 0x4E05
39 #define BXTWC_THRM2IRQ 0x4E06
40 #define BXTWC_BCUIRQ 0x4E07
41 #define BXTWC_ADCIRQ 0x4E08
42 #define BXTWC_CHGR0IRQ 0x4E09
43 #define BXTWC_CHGR1IRQ 0x4E0A
44 #define BXTWC_GPIOIRQ0 0x4E0B
45 #define BXTWC_GPIOIRQ1 0x4E0C
46 #define BXTWC_CRITIRQ 0x4E0D
47 #define BXTWC_TMUIRQ 0x4FB6
49 /* Interrupt MASK Registers */
50 #define BXTWC_MIRQLVL1 0x4E0E
51 #define BXTWC_MIRQLVL1_MCHGR BIT(5)
53 #define BXTWC_MPWRBTNIRQ 0x4E0F
54 #define BXTWC_MTHRM0IRQ 0x4E12
55 #define BXTWC_MTHRM1IRQ 0x4E13
56 #define BXTWC_MTHRM2IRQ 0x4E14
57 #define BXTWC_MBCUIRQ 0x4E15
58 #define BXTWC_MADCIRQ 0x4E16
59 #define BXTWC_MCHGR0IRQ 0x4E17
60 #define BXTWC_MCHGR1IRQ 0x4E18
61 #define BXTWC_MGPIO0IRQ 0x4E19
62 #define BXTWC_MGPIO1IRQ 0x4E1A
63 #define BXTWC_MCRITIRQ 0x4E1B
64 #define BXTWC_MTMUIRQ 0x4FB7
66 /* Whiskey Cove PMIC share same ACPI ID between different platforms */
67 #define BROXTON_PMIC_WC_HRV 4
70 BXTWC_PWRBTN_LVL1_IRQ = 0,
80 enum bxtwc_irqs_pwrbtn {
93 enum bxtwc_irqs_chgr {
103 enum bxtwc_irqs_crit {
107 static const struct regmap_irq bxtwc_regmap_irqs[] = {
108 REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
109 REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
110 REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
111 REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
112 REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
113 REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
114 REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
115 REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
118 static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
119 REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01),
122 static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
123 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f),
126 static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
127 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff),
130 static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
131 REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20),
132 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
133 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
136 static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
137 REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06),
140 static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
141 REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03),
144 static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
145 .name = "bxtwc_irq_chip",
146 .status_base = BXTWC_IRQLVL1,
147 .mask_base = BXTWC_MIRQLVL1,
148 .irqs = bxtwc_regmap_irqs,
149 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
153 static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {
154 .name = "bxtwc_irq_chip_pwrbtn",
155 .status_base = BXTWC_PWRBTNIRQ,
156 .mask_base = BXTWC_MPWRBTNIRQ,
157 .irqs = bxtwc_regmap_irqs_pwrbtn,
158 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn),
162 static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
163 .name = "bxtwc_irq_chip_tmu",
164 .status_base = BXTWC_TMUIRQ,
165 .mask_base = BXTWC_MTMUIRQ,
166 .irqs = bxtwc_regmap_irqs_tmu,
167 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu),
171 static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {
172 .name = "bxtwc_irq_chip_bcu",
173 .status_base = BXTWC_BCUIRQ,
174 .mask_base = BXTWC_MBCUIRQ,
175 .irqs = bxtwc_regmap_irqs_bcu,
176 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu),
180 static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {
181 .name = "bxtwc_irq_chip_adc",
182 .status_base = BXTWC_ADCIRQ,
183 .mask_base = BXTWC_MADCIRQ,
184 .irqs = bxtwc_regmap_irqs_adc,
185 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc),
189 static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {
190 .name = "bxtwc_irq_chip_chgr",
191 .status_base = BXTWC_CHGR0IRQ,
192 .mask_base = BXTWC_MCHGR0IRQ,
193 .irqs = bxtwc_regmap_irqs_chgr,
194 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr),
198 static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = {
199 .name = "bxtwc_irq_chip_crit",
200 .status_base = BXTWC_CRITIRQ,
201 .mask_base = BXTWC_MCRITIRQ,
202 .irqs = bxtwc_regmap_irqs_crit,
203 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit),
207 static struct resource gpio_resources[] = {
208 DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"),
211 static struct resource adc_resources[] = {
212 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
215 static struct resource usbc_resources[] = {
216 DEFINE_RES_IRQ(BXTWC_USBC_IRQ),
219 static struct resource charger_resources[] = {
220 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
221 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
224 static struct resource thermal_resources[] = {
225 DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ),
228 static struct resource bcu_resources[] = {
229 DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
232 static struct resource tmu_resources[] = {
233 DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"),
236 static struct mfd_cell bxt_wc_dev[] = {
238 .name = "bxt_wcove_gpadc",
239 .num_resources = ARRAY_SIZE(adc_resources),
240 .resources = adc_resources,
243 .name = "bxt_wcove_thermal",
244 .num_resources = ARRAY_SIZE(thermal_resources),
245 .resources = thermal_resources,
248 .name = "bxt_wcove_usbc",
249 .num_resources = ARRAY_SIZE(usbc_resources),
250 .resources = usbc_resources,
253 .name = "bxt_wcove_ext_charger",
254 .num_resources = ARRAY_SIZE(charger_resources),
255 .resources = charger_resources,
258 .name = "bxt_wcove_bcu",
259 .num_resources = ARRAY_SIZE(bcu_resources),
260 .resources = bcu_resources,
263 .name = "bxt_wcove_tmu",
264 .num_resources = ARRAY_SIZE(tmu_resources),
265 .resources = tmu_resources,
269 .name = "bxt_wcove_gpio",
270 .num_resources = ARRAY_SIZE(gpio_resources),
271 .resources = gpio_resources,
274 .name = "bxt_wcove_region",
278 static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
285 struct intel_soc_pmic *pmic = context;
290 if (reg & REG_ADDR_MASK)
291 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
293 i2c_addr = BXTWC_DEVICE1_ADDR;
295 reg &= REG_OFFSET_MASK;
298 ipc_in[1] = i2c_addr;
299 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
300 PMC_IPC_PMIC_ACCESS_READ,
301 ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
303 dev_err(pmic->dev, "Failed to read from PMIC\n");
311 static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
317 struct intel_soc_pmic *pmic = context;
322 if (reg & REG_ADDR_MASK)
323 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
325 i2c_addr = BXTWC_DEVICE1_ADDR;
327 reg &= REG_OFFSET_MASK;
330 ipc_in[1] = i2c_addr;
332 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
333 PMC_IPC_PMIC_ACCESS_WRITE,
334 ipc_in, sizeof(ipc_in), NULL, 0);
336 dev_err(pmic->dev, "Failed to write to PMIC\n");
343 /* sysfs interfaces to r/w PMIC registers, required by initial script */
344 static unsigned long bxtwc_reg_addr;
345 static ssize_t bxtwc_reg_show(struct device *dev,
346 struct device_attribute *attr, char *buf)
348 return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
351 static ssize_t bxtwc_reg_store(struct device *dev,
352 struct device_attribute *attr, const char *buf, size_t count)
354 if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
355 dev_err(dev, "Invalid register address\n");
358 return (ssize_t)count;
361 static ssize_t bxtwc_val_show(struct device *dev,
362 struct device_attribute *attr, char *buf)
366 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
368 ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
370 dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
374 return sprintf(buf, "0x%02x\n", val);
377 static ssize_t bxtwc_val_store(struct device *dev,
378 struct device_attribute *attr, const char *buf, size_t count)
382 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
384 ret = kstrtouint(buf, 0, &val);
388 ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
390 dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
391 val, bxtwc_reg_addr);
397 static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store);
398 static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store);
399 static struct attribute *bxtwc_attrs[] = {
405 static const struct attribute_group bxtwc_group = {
406 .attrs = bxtwc_attrs,
409 static const struct regmap_config bxtwc_regmap_config = {
412 .reg_write = regmap_ipc_byte_reg_write,
413 .reg_read = regmap_ipc_byte_reg_read,
416 static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
417 struct regmap_irq_chip_data *pdata,
418 int pirq, int irq_flags,
419 const struct regmap_irq_chip *chip,
420 struct regmap_irq_chip_data **data)
424 irq = regmap_irq_get_virq(pdata, pirq);
427 "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
428 pirq, chip->name, irq);
432 return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
436 static int bxtwc_probe(struct platform_device *pdev)
441 unsigned long long hrv;
442 struct intel_soc_pmic *pmic;
444 handle = ACPI_HANDLE(&pdev->dev);
445 status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
446 if (ACPI_FAILURE(status)) {
447 dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
450 if (hrv != BROXTON_PMIC_WC_HRV) {
451 dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
456 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
460 ret = platform_get_irq(pdev, 0);
462 dev_err(&pdev->dev, "Invalid IRQ\n");
467 dev_set_drvdata(&pdev->dev, pmic);
468 pmic->dev = &pdev->dev;
470 pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
471 &bxtwc_regmap_config);
472 if (IS_ERR(pmic->regmap)) {
473 ret = PTR_ERR(pmic->regmap);
474 dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
478 ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
479 IRQF_ONESHOT | IRQF_SHARED,
480 0, &bxtwc_regmap_irq_chip,
481 &pmic->irq_chip_data);
483 dev_err(&pdev->dev, "Failed to add IRQ chip\n");
487 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
488 BXTWC_PWRBTN_LVL1_IRQ,
490 &bxtwc_regmap_irq_chip_pwrbtn,
491 &pmic->irq_chip_data_pwrbtn);
493 dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
497 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
500 &bxtwc_regmap_irq_chip_tmu,
501 &pmic->irq_chip_data_tmu);
503 dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
507 /* Add chained IRQ handler for BCU IRQs */
508 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
511 &bxtwc_regmap_irq_chip_bcu,
512 &pmic->irq_chip_data_bcu);
516 dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
520 /* Add chained IRQ handler for ADC IRQs */
521 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
524 &bxtwc_regmap_irq_chip_adc,
525 &pmic->irq_chip_data_adc);
529 dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
533 /* Add chained IRQ handler for CHGR IRQs */
534 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
537 &bxtwc_regmap_irq_chip_chgr,
538 &pmic->irq_chip_data_chgr);
542 dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
546 /* Add chained IRQ handler for CRIT IRQs */
547 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
550 &bxtwc_regmap_irq_chip_crit,
551 &pmic->irq_chip_data_crit);
555 dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
559 ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
560 ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
562 dev_err(&pdev->dev, "Failed to add devices\n");
566 ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
568 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
573 * There is known hw bug. Upon reset BIT 5 of register
574 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
575 * later it's set to 1(masked) automatically by hardware. So we
576 * have the software workaround here to unmaksed it in order to let
577 * charger interrutp work.
579 regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
580 BXTWC_MIRQLVL1_MCHGR, 0);
585 static int bxtwc_remove(struct platform_device *pdev)
587 sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
592 static void bxtwc_shutdown(struct platform_device *pdev)
594 struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
596 disable_irq(pmic->irq);
599 #ifdef CONFIG_PM_SLEEP
600 static int bxtwc_suspend(struct device *dev)
602 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
604 disable_irq(pmic->irq);
609 static int bxtwc_resume(struct device *dev)
611 struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
613 enable_irq(pmic->irq);
617 static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
619 static const struct acpi_device_id bxtwc_acpi_ids[] = {
623 MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
625 static struct platform_driver bxtwc_driver = {
626 .probe = bxtwc_probe,
627 .remove = bxtwc_remove,
628 .shutdown = bxtwc_shutdown,
630 .name = "BXTWC PMIC",
632 .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
636 module_platform_driver(bxtwc_driver);
638 MODULE_LICENSE("GPL v2");
639 MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>");