xref: /linux/drivers/mfd/intel_soc_pmic_bxtwc.c (revision 9f8ddee1dab836ca758ca8fc555ab5a3aaa5d3fd)
139d047c0SQipeng Zha /*
239d047c0SQipeng Zha  * MFD core driver for Intel Broxton Whiskey Cove PMIC
339d047c0SQipeng Zha  *
439d047c0SQipeng Zha  * Copyright (C) 2015 Intel Corporation. All rights reserved.
539d047c0SQipeng Zha  *
639d047c0SQipeng Zha  * This program is free software; you can redistribute it and/or modify it
739d047c0SQipeng Zha  * under the terms and conditions of the GNU General Public License,
839d047c0SQipeng Zha  * version 2, as published by the Free Software Foundation.
939d047c0SQipeng Zha  *
1039d047c0SQipeng Zha  * This program is distributed in the hope it will be useful, but WITHOUT
1139d047c0SQipeng Zha  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1239d047c0SQipeng Zha  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1339d047c0SQipeng Zha  * more details.
1439d047c0SQipeng Zha  */
1539d047c0SQipeng Zha 
1639d047c0SQipeng Zha #include <linux/module.h>
1739d047c0SQipeng Zha #include <linux/acpi.h>
1839d047c0SQipeng Zha #include <linux/err.h>
1939d047c0SQipeng Zha #include <linux/delay.h>
2039d047c0SQipeng Zha #include <linux/interrupt.h>
2139d047c0SQipeng Zha #include <linux/kernel.h>
2239d047c0SQipeng Zha #include <linux/mfd/core.h>
23f1e34ad8SAndy Shevchenko #include <linux/mfd/intel_soc_pmic.h>
240c227c51SAndy Shevchenko #include <linux/mfd/intel_soc_pmic_bxtwc.h>
2539d047c0SQipeng Zha #include <asm/intel_pmc_ipc.h>
2639d047c0SQipeng Zha 
2739d047c0SQipeng Zha /* PMIC device registers */
2839d047c0SQipeng Zha #define REG_ADDR_MASK		0xFF00
2939d047c0SQipeng Zha #define REG_ADDR_SHIFT		8
3039d047c0SQipeng Zha #define REG_OFFSET_MASK		0xFF
3139d047c0SQipeng Zha 
3239d047c0SQipeng Zha /* Interrupt Status Registers */
3339d047c0SQipeng Zha #define BXTWC_IRQLVL1		0x4E02
3439d047c0SQipeng Zha 
35*9f8ddee1SAndy Shevchenko #define BXTWC_PWRBTNIRQ		0x4E03
3639d047c0SQipeng Zha #define BXTWC_THRM0IRQ		0x4E04
3739d047c0SQipeng Zha #define BXTWC_THRM1IRQ		0x4E05
3839d047c0SQipeng Zha #define BXTWC_THRM2IRQ		0x4E06
3939d047c0SQipeng Zha #define BXTWC_BCUIRQ		0x4E07
4039d047c0SQipeng Zha #define BXTWC_ADCIRQ		0x4E08
4139d047c0SQipeng Zha #define BXTWC_CHGR0IRQ		0x4E09
4239d047c0SQipeng Zha #define BXTWC_CHGR1IRQ		0x4E0A
4339d047c0SQipeng Zha #define BXTWC_GPIOIRQ0		0x4E0B
4439d047c0SQipeng Zha #define BXTWC_GPIOIRQ1		0x4E0C
4539d047c0SQipeng Zha #define BXTWC_CRITIRQ		0x4E0D
46957ae509SNilesh Bacchewar #define BXTWC_TMUIRQ		0x4FB6
4739d047c0SQipeng Zha 
4839d047c0SQipeng Zha /* Interrupt MASK Registers */
4939d047c0SQipeng Zha #define BXTWC_MIRQLVL1		0x4E0E
509c6235c8SBin Gao #define BXTWC_MIRQLVL1_MCHGR	BIT(5)
519c6235c8SBin Gao 
52*9f8ddee1SAndy Shevchenko #define BXTWC_MPWRBTNIRQ	0x4E0F
5339d047c0SQipeng Zha #define BXTWC_MTHRM0IRQ		0x4E12
5439d047c0SQipeng Zha #define BXTWC_MTHRM1IRQ		0x4E13
5539d047c0SQipeng Zha #define BXTWC_MTHRM2IRQ		0x4E14
5639d047c0SQipeng Zha #define BXTWC_MBCUIRQ		0x4E15
5739d047c0SQipeng Zha #define BXTWC_MADCIRQ		0x4E16
5839d047c0SQipeng Zha #define BXTWC_MCHGR0IRQ		0x4E17
5939d047c0SQipeng Zha #define BXTWC_MCHGR1IRQ		0x4E18
6039d047c0SQipeng Zha #define BXTWC_MGPIO0IRQ		0x4E19
6139d047c0SQipeng Zha #define BXTWC_MGPIO1IRQ		0x4E1A
6239d047c0SQipeng Zha #define BXTWC_MCRITIRQ		0x4E1B
63957ae509SNilesh Bacchewar #define BXTWC_MTMUIRQ		0x4FB7
6439d047c0SQipeng Zha 
6539d047c0SQipeng Zha /* Whiskey Cove PMIC share same ACPI ID between different platforms */
6639d047c0SQipeng Zha #define BROXTON_PMIC_WC_HRV	4
6739d047c0SQipeng Zha 
6839d047c0SQipeng Zha enum bxtwc_irqs {
6939d047c0SQipeng Zha 	BXTWC_PWRBTN_LVL1_IRQ = 0,
7039d047c0SQipeng Zha 	BXTWC_TMU_LVL1_IRQ,
7139d047c0SQipeng Zha 	BXTWC_THRM_LVL1_IRQ,
7239d047c0SQipeng Zha 	BXTWC_BCU_LVL1_IRQ,
7339d047c0SQipeng Zha 	BXTWC_ADC_LVL1_IRQ,
7439d047c0SQipeng Zha 	BXTWC_CHGR_LVL1_IRQ,
7539d047c0SQipeng Zha 	BXTWC_GPIO_LVL1_IRQ,
7639d047c0SQipeng Zha 	BXTWC_CRIT_LVL1_IRQ,
77*9f8ddee1SAndy Shevchenko };
7839d047c0SQipeng Zha 
79*9f8ddee1SAndy Shevchenko enum bxtwc_irqs_pwrbtn {
80*9f8ddee1SAndy Shevchenko 	BXTWC_PWRBTN_IRQ = 0,
81*9f8ddee1SAndy Shevchenko 	BXTWC_UIBTN_IRQ,
8239d047c0SQipeng Zha };
8339d047c0SQipeng Zha 
8457129044SKuppuswamy Sathyanarayanan enum bxtwc_irqs_bcu {
85c4949630SKuppuswamy Sathyanarayanan 	BXTWC_BCU_IRQ = 0,
8657129044SKuppuswamy Sathyanarayanan };
8757129044SKuppuswamy Sathyanarayanan 
8857129044SKuppuswamy Sathyanarayanan enum bxtwc_irqs_adc {
8957129044SKuppuswamy Sathyanarayanan 	BXTWC_ADC_IRQ = 0,
9057129044SKuppuswamy Sathyanarayanan };
9157129044SKuppuswamy Sathyanarayanan 
9257129044SKuppuswamy Sathyanarayanan enum bxtwc_irqs_chgr {
9357129044SKuppuswamy Sathyanarayanan 	BXTWC_USBC_IRQ = 0,
9439d047c0SQipeng Zha 	BXTWC_CHGR0_IRQ,
9539d047c0SQipeng Zha 	BXTWC_CHGR1_IRQ,
964533d855SKuppuswamy Sathyanarayanan };
974533d855SKuppuswamy Sathyanarayanan 
984533d855SKuppuswamy Sathyanarayanan enum bxtwc_irqs_tmu {
994533d855SKuppuswamy Sathyanarayanan 	BXTWC_TMU_IRQ = 0,
10039d047c0SQipeng Zha };
10139d047c0SQipeng Zha 
10257129044SKuppuswamy Sathyanarayanan enum bxtwc_irqs_crit {
10357129044SKuppuswamy Sathyanarayanan 	BXTWC_CRIT_IRQ = 0,
10457129044SKuppuswamy Sathyanarayanan };
10557129044SKuppuswamy Sathyanarayanan 
10639d047c0SQipeng Zha static const struct regmap_irq bxtwc_regmap_irqs[] = {
10739d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
10839d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
10939d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
11039d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
11139d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
11239d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
11339d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
11439d047c0SQipeng Zha 	REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
115*9f8ddee1SAndy Shevchenko };
116*9f8ddee1SAndy Shevchenko 
117*9f8ddee1SAndy Shevchenko static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
118*9f8ddee1SAndy Shevchenko 	REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01),
11939d047c0SQipeng Zha };
12039d047c0SQipeng Zha 
12157129044SKuppuswamy Sathyanarayanan static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
122c4949630SKuppuswamy Sathyanarayanan 	REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f),
12357129044SKuppuswamy Sathyanarayanan };
12457129044SKuppuswamy Sathyanarayanan 
12557129044SKuppuswamy Sathyanarayanan static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
12657129044SKuppuswamy Sathyanarayanan 	REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff),
12757129044SKuppuswamy Sathyanarayanan };
12857129044SKuppuswamy Sathyanarayanan 
12957129044SKuppuswamy Sathyanarayanan static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
130*9f8ddee1SAndy Shevchenko 	REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20),
13157129044SKuppuswamy Sathyanarayanan 	REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
13257129044SKuppuswamy Sathyanarayanan 	REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
13339d047c0SQipeng Zha };
13439d047c0SQipeng Zha 
135957ae509SNilesh Bacchewar static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
136957ae509SNilesh Bacchewar 	REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06),
137957ae509SNilesh Bacchewar };
138957ae509SNilesh Bacchewar 
13957129044SKuppuswamy Sathyanarayanan static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
14057129044SKuppuswamy Sathyanarayanan 	REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03),
14157129044SKuppuswamy Sathyanarayanan };
14257129044SKuppuswamy Sathyanarayanan 
14339d047c0SQipeng Zha static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
14439d047c0SQipeng Zha 	.name = "bxtwc_irq_chip",
14539d047c0SQipeng Zha 	.status_base = BXTWC_IRQLVL1,
14639d047c0SQipeng Zha 	.mask_base = BXTWC_MIRQLVL1,
14739d047c0SQipeng Zha 	.irqs = bxtwc_regmap_irqs,
14839d047c0SQipeng Zha 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
149*9f8ddee1SAndy Shevchenko 	.num_regs = 1,
150*9f8ddee1SAndy Shevchenko };
151*9f8ddee1SAndy Shevchenko 
152*9f8ddee1SAndy Shevchenko static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {
153*9f8ddee1SAndy Shevchenko 	.name = "bxtwc_irq_chip_pwrbtn",
154*9f8ddee1SAndy Shevchenko 	.status_base = BXTWC_PWRBTNIRQ,
155*9f8ddee1SAndy Shevchenko 	.mask_base = BXTWC_MPWRBTNIRQ,
156*9f8ddee1SAndy Shevchenko 	.irqs = bxtwc_regmap_irqs_pwrbtn,
157*9f8ddee1SAndy Shevchenko 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn),
158*9f8ddee1SAndy Shevchenko 	.num_regs = 1,
15939d047c0SQipeng Zha };
16039d047c0SQipeng Zha 
161957ae509SNilesh Bacchewar static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
162957ae509SNilesh Bacchewar 	.name = "bxtwc_irq_chip_tmu",
163957ae509SNilesh Bacchewar 	.status_base = BXTWC_TMUIRQ,
164957ae509SNilesh Bacchewar 	.mask_base = BXTWC_MTMUIRQ,
165957ae509SNilesh Bacchewar 	.irqs = bxtwc_regmap_irqs_tmu,
166957ae509SNilesh Bacchewar 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu),
167957ae509SNilesh Bacchewar 	.num_regs = 1,
168957ae509SNilesh Bacchewar };
169957ae509SNilesh Bacchewar 
17057129044SKuppuswamy Sathyanarayanan static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {
17157129044SKuppuswamy Sathyanarayanan 	.name = "bxtwc_irq_chip_bcu",
17257129044SKuppuswamy Sathyanarayanan 	.status_base = BXTWC_BCUIRQ,
17357129044SKuppuswamy Sathyanarayanan 	.mask_base = BXTWC_MBCUIRQ,
17457129044SKuppuswamy Sathyanarayanan 	.irqs = bxtwc_regmap_irqs_bcu,
17557129044SKuppuswamy Sathyanarayanan 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu),
17657129044SKuppuswamy Sathyanarayanan 	.num_regs = 1,
17757129044SKuppuswamy Sathyanarayanan };
17857129044SKuppuswamy Sathyanarayanan 
17957129044SKuppuswamy Sathyanarayanan static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {
18057129044SKuppuswamy Sathyanarayanan 	.name = "bxtwc_irq_chip_adc",
18157129044SKuppuswamy Sathyanarayanan 	.status_base = BXTWC_ADCIRQ,
18257129044SKuppuswamy Sathyanarayanan 	.mask_base = BXTWC_MADCIRQ,
18357129044SKuppuswamy Sathyanarayanan 	.irqs = bxtwc_regmap_irqs_adc,
18457129044SKuppuswamy Sathyanarayanan 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc),
18557129044SKuppuswamy Sathyanarayanan 	.num_regs = 1,
18657129044SKuppuswamy Sathyanarayanan };
18757129044SKuppuswamy Sathyanarayanan 
18857129044SKuppuswamy Sathyanarayanan static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {
18957129044SKuppuswamy Sathyanarayanan 	.name = "bxtwc_irq_chip_chgr",
19057129044SKuppuswamy Sathyanarayanan 	.status_base = BXTWC_CHGR0IRQ,
19157129044SKuppuswamy Sathyanarayanan 	.mask_base = BXTWC_MCHGR0IRQ,
19257129044SKuppuswamy Sathyanarayanan 	.irqs = bxtwc_regmap_irqs_chgr,
19357129044SKuppuswamy Sathyanarayanan 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr),
19457129044SKuppuswamy Sathyanarayanan 	.num_regs = 2,
19557129044SKuppuswamy Sathyanarayanan };
19657129044SKuppuswamy Sathyanarayanan 
19757129044SKuppuswamy Sathyanarayanan static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = {
19857129044SKuppuswamy Sathyanarayanan 	.name = "bxtwc_irq_chip_crit",
19957129044SKuppuswamy Sathyanarayanan 	.status_base = BXTWC_CRITIRQ,
20057129044SKuppuswamy Sathyanarayanan 	.mask_base = BXTWC_MCRITIRQ,
20157129044SKuppuswamy Sathyanarayanan 	.irqs = bxtwc_regmap_irqs_crit,
20257129044SKuppuswamy Sathyanarayanan 	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit),
20357129044SKuppuswamy Sathyanarayanan 	.num_regs = 1,
20457129044SKuppuswamy Sathyanarayanan };
20557129044SKuppuswamy Sathyanarayanan 
20639d047c0SQipeng Zha static struct resource gpio_resources[] = {
207a1d28c59SKuppuswamy Sathyanarayanan 	DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"),
20839d047c0SQipeng Zha };
20939d047c0SQipeng Zha 
21039d047c0SQipeng Zha static struct resource adc_resources[] = {
21139d047c0SQipeng Zha 	DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
21239d047c0SQipeng Zha };
21339d047c0SQipeng Zha 
2149c6235c8SBin Gao static struct resource usbc_resources[] = {
21596007020SHeikki Krogerus 	DEFINE_RES_IRQ(BXTWC_USBC_IRQ),
2169c6235c8SBin Gao };
2179c6235c8SBin Gao 
21839d047c0SQipeng Zha static struct resource charger_resources[] = {
21939d047c0SQipeng Zha 	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
22039d047c0SQipeng Zha 	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
22139d047c0SQipeng Zha };
22239d047c0SQipeng Zha 
22339d047c0SQipeng Zha static struct resource thermal_resources[] = {
224c4949630SKuppuswamy Sathyanarayanan 	DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ),
22539d047c0SQipeng Zha };
22639d047c0SQipeng Zha 
22739d047c0SQipeng Zha static struct resource bcu_resources[] = {
22839d047c0SQipeng Zha 	DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
22939d047c0SQipeng Zha };
23039d047c0SQipeng Zha 
231957ae509SNilesh Bacchewar static struct resource tmu_resources[] = {
232957ae509SNilesh Bacchewar 	DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"),
233957ae509SNilesh Bacchewar };
234957ae509SNilesh Bacchewar 
23539d047c0SQipeng Zha static struct mfd_cell bxt_wc_dev[] = {
23639d047c0SQipeng Zha 	{
23739d047c0SQipeng Zha 		.name = "bxt_wcove_gpadc",
23839d047c0SQipeng Zha 		.num_resources = ARRAY_SIZE(adc_resources),
23939d047c0SQipeng Zha 		.resources = adc_resources,
24039d047c0SQipeng Zha 	},
24139d047c0SQipeng Zha 	{
24239d047c0SQipeng Zha 		.name = "bxt_wcove_thermal",
24339d047c0SQipeng Zha 		.num_resources = ARRAY_SIZE(thermal_resources),
24439d047c0SQipeng Zha 		.resources = thermal_resources,
24539d047c0SQipeng Zha 	},
24639d047c0SQipeng Zha 	{
2479c6235c8SBin Gao 		.name = "bxt_wcove_usbc",
2489c6235c8SBin Gao 		.num_resources = ARRAY_SIZE(usbc_resources),
2499c6235c8SBin Gao 		.resources = usbc_resources,
2509c6235c8SBin Gao 	},
2519c6235c8SBin Gao 	{
25239d047c0SQipeng Zha 		.name = "bxt_wcove_ext_charger",
25339d047c0SQipeng Zha 		.num_resources = ARRAY_SIZE(charger_resources),
25439d047c0SQipeng Zha 		.resources = charger_resources,
25539d047c0SQipeng Zha 	},
25639d047c0SQipeng Zha 	{
25739d047c0SQipeng Zha 		.name = "bxt_wcove_bcu",
25839d047c0SQipeng Zha 		.num_resources = ARRAY_SIZE(bcu_resources),
25939d047c0SQipeng Zha 		.resources = bcu_resources,
26039d047c0SQipeng Zha 	},
26139d047c0SQipeng Zha 	{
262957ae509SNilesh Bacchewar 		.name = "bxt_wcove_tmu",
263957ae509SNilesh Bacchewar 		.num_resources = ARRAY_SIZE(tmu_resources),
264957ae509SNilesh Bacchewar 		.resources = tmu_resources,
265957ae509SNilesh Bacchewar 	},
266957ae509SNilesh Bacchewar 
267957ae509SNilesh Bacchewar 	{
26839d047c0SQipeng Zha 		.name = "bxt_wcove_gpio",
26939d047c0SQipeng Zha 		.num_resources = ARRAY_SIZE(gpio_resources),
27039d047c0SQipeng Zha 		.resources = gpio_resources,
27139d047c0SQipeng Zha 	},
27239d047c0SQipeng Zha 	{
27339d047c0SQipeng Zha 		.name = "bxt_wcove_region",
27439d047c0SQipeng Zha 	},
27539d047c0SQipeng Zha };
27639d047c0SQipeng Zha 
27739d047c0SQipeng Zha static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
27839d047c0SQipeng Zha 				    unsigned int *val)
27939d047c0SQipeng Zha {
28039d047c0SQipeng Zha 	int ret;
28139d047c0SQipeng Zha 	int i2c_addr;
28239d047c0SQipeng Zha 	u8 ipc_in[2];
28339d047c0SQipeng Zha 	u8 ipc_out[4];
28439d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = context;
28539d047c0SQipeng Zha 
286b4ccc4d2SKuppuswamy Sathyanarayanan 	if (!pmic)
287b4ccc4d2SKuppuswamy Sathyanarayanan 		return -EINVAL;
288b4ccc4d2SKuppuswamy Sathyanarayanan 
28939d047c0SQipeng Zha 	if (reg & REG_ADDR_MASK)
29039d047c0SQipeng Zha 		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
291b4ccc4d2SKuppuswamy Sathyanarayanan 	else
29239d047c0SQipeng Zha 		i2c_addr = BXTWC_DEVICE1_ADDR;
293b4ccc4d2SKuppuswamy Sathyanarayanan 
29439d047c0SQipeng Zha 	reg &= REG_OFFSET_MASK;
29539d047c0SQipeng Zha 
29639d047c0SQipeng Zha 	ipc_in[0] = reg;
29739d047c0SQipeng Zha 	ipc_in[1] = i2c_addr;
29839d047c0SQipeng Zha 	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
29939d047c0SQipeng Zha 			PMC_IPC_PMIC_ACCESS_READ,
30039d047c0SQipeng Zha 			ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1);
30139d047c0SQipeng Zha 	if (ret) {
30239d047c0SQipeng Zha 		dev_err(pmic->dev, "Failed to read from PMIC\n");
30339d047c0SQipeng Zha 		return ret;
30439d047c0SQipeng Zha 	}
30539d047c0SQipeng Zha 	*val = ipc_out[0];
30639d047c0SQipeng Zha 
30739d047c0SQipeng Zha 	return 0;
30839d047c0SQipeng Zha }
30939d047c0SQipeng Zha 
31039d047c0SQipeng Zha static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
31139d047c0SQipeng Zha 				       unsigned int val)
31239d047c0SQipeng Zha {
31339d047c0SQipeng Zha 	int ret;
31439d047c0SQipeng Zha 	int i2c_addr;
31539d047c0SQipeng Zha 	u8 ipc_in[3];
31639d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = context;
31739d047c0SQipeng Zha 
318b4ccc4d2SKuppuswamy Sathyanarayanan 	if (!pmic)
319b4ccc4d2SKuppuswamy Sathyanarayanan 		return -EINVAL;
320b4ccc4d2SKuppuswamy Sathyanarayanan 
32139d047c0SQipeng Zha 	if (reg & REG_ADDR_MASK)
32239d047c0SQipeng Zha 		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
323b4ccc4d2SKuppuswamy Sathyanarayanan 	else
32439d047c0SQipeng Zha 		i2c_addr = BXTWC_DEVICE1_ADDR;
325b4ccc4d2SKuppuswamy Sathyanarayanan 
32639d047c0SQipeng Zha 	reg &= REG_OFFSET_MASK;
32739d047c0SQipeng Zha 
32839d047c0SQipeng Zha 	ipc_in[0] = reg;
32939d047c0SQipeng Zha 	ipc_in[1] = i2c_addr;
33039d047c0SQipeng Zha 	ipc_in[2] = val;
33139d047c0SQipeng Zha 	ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS,
33239d047c0SQipeng Zha 			PMC_IPC_PMIC_ACCESS_WRITE,
33339d047c0SQipeng Zha 			ipc_in, sizeof(ipc_in), NULL, 0);
33439d047c0SQipeng Zha 	if (ret) {
33539d047c0SQipeng Zha 		dev_err(pmic->dev, "Failed to write to PMIC\n");
33639d047c0SQipeng Zha 		return ret;
33739d047c0SQipeng Zha 	}
33839d047c0SQipeng Zha 
33939d047c0SQipeng Zha 	return 0;
34039d047c0SQipeng Zha }
34139d047c0SQipeng Zha 
34239d047c0SQipeng Zha /* sysfs interfaces to r/w PMIC registers, required by initial script */
34339d047c0SQipeng Zha static unsigned long bxtwc_reg_addr;
34439d047c0SQipeng Zha static ssize_t bxtwc_reg_show(struct device *dev,
34539d047c0SQipeng Zha 		struct device_attribute *attr, char *buf)
34639d047c0SQipeng Zha {
34739d047c0SQipeng Zha 	return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
34839d047c0SQipeng Zha }
34939d047c0SQipeng Zha 
35039d047c0SQipeng Zha static ssize_t bxtwc_reg_store(struct device *dev,
35139d047c0SQipeng Zha 	struct device_attribute *attr, const char *buf, size_t count)
35239d047c0SQipeng Zha {
35339d047c0SQipeng Zha 	if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
35439d047c0SQipeng Zha 		dev_err(dev, "Invalid register address\n");
35539d047c0SQipeng Zha 		return -EINVAL;
35639d047c0SQipeng Zha 	}
35739d047c0SQipeng Zha 	return (ssize_t)count;
35839d047c0SQipeng Zha }
35939d047c0SQipeng Zha 
36039d047c0SQipeng Zha static ssize_t bxtwc_val_show(struct device *dev,
36139d047c0SQipeng Zha 		struct device_attribute *attr, char *buf)
36239d047c0SQipeng Zha {
36339d047c0SQipeng Zha 	int ret;
36439d047c0SQipeng Zha 	unsigned int val;
36539d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
36639d047c0SQipeng Zha 
36739d047c0SQipeng Zha 	ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
36839d047c0SQipeng Zha 	if (ret < 0) {
36939d047c0SQipeng Zha 		dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
37039d047c0SQipeng Zha 		return -EIO;
37139d047c0SQipeng Zha 	}
37239d047c0SQipeng Zha 
37339d047c0SQipeng Zha 	return sprintf(buf, "0x%02x\n", val);
37439d047c0SQipeng Zha }
37539d047c0SQipeng Zha 
37639d047c0SQipeng Zha static ssize_t bxtwc_val_store(struct device *dev,
37739d047c0SQipeng Zha 	struct device_attribute *attr, const char *buf, size_t count)
37839d047c0SQipeng Zha {
37939d047c0SQipeng Zha 	int ret;
38039d047c0SQipeng Zha 	unsigned int val;
38139d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
38239d047c0SQipeng Zha 
383f3a654c5SDan Carpenter 	ret = kstrtouint(buf, 0, &val);
384f3a654c5SDan Carpenter 	if (ret)
385f3a654c5SDan Carpenter 		return ret;
38639d047c0SQipeng Zha 
38739d047c0SQipeng Zha 	ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
38839d047c0SQipeng Zha 	if (ret) {
38939d047c0SQipeng Zha 		dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
39039d047c0SQipeng Zha 			val, bxtwc_reg_addr);
39139d047c0SQipeng Zha 		return -EIO;
39239d047c0SQipeng Zha 	}
39339d047c0SQipeng Zha 	return count;
39439d047c0SQipeng Zha }
39539d047c0SQipeng Zha 
39639d047c0SQipeng Zha static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store);
39739d047c0SQipeng Zha static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store);
39839d047c0SQipeng Zha static struct attribute *bxtwc_attrs[] = {
39939d047c0SQipeng Zha 	&dev_attr_addr.attr,
40039d047c0SQipeng Zha 	&dev_attr_val.attr,
40139d047c0SQipeng Zha 	NULL
40239d047c0SQipeng Zha };
40339d047c0SQipeng Zha 
40439d047c0SQipeng Zha static const struct attribute_group bxtwc_group = {
40539d047c0SQipeng Zha 	.attrs = bxtwc_attrs,
40639d047c0SQipeng Zha };
40739d047c0SQipeng Zha 
40839d047c0SQipeng Zha static const struct regmap_config bxtwc_regmap_config = {
40939d047c0SQipeng Zha 	.reg_bits = 16,
41039d047c0SQipeng Zha 	.val_bits = 8,
41139d047c0SQipeng Zha 	.reg_write = regmap_ipc_byte_reg_write,
41239d047c0SQipeng Zha 	.reg_read = regmap_ipc_byte_reg_read,
41339d047c0SQipeng Zha };
41439d047c0SQipeng Zha 
41557129044SKuppuswamy Sathyanarayanan static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
41657129044SKuppuswamy Sathyanarayanan 				struct regmap_irq_chip_data *pdata,
41757129044SKuppuswamy Sathyanarayanan 				int pirq, int irq_flags,
41857129044SKuppuswamy Sathyanarayanan 				const struct regmap_irq_chip *chip,
41957129044SKuppuswamy Sathyanarayanan 				struct regmap_irq_chip_data **data)
42057129044SKuppuswamy Sathyanarayanan {
42157129044SKuppuswamy Sathyanarayanan 	int irq;
42257129044SKuppuswamy Sathyanarayanan 
42357129044SKuppuswamy Sathyanarayanan 	irq = regmap_irq_get_virq(pdata, pirq);
42457129044SKuppuswamy Sathyanarayanan 	if (irq < 0) {
42557129044SKuppuswamy Sathyanarayanan 		dev_err(pmic->dev,
42657129044SKuppuswamy Sathyanarayanan 			"Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
42757129044SKuppuswamy Sathyanarayanan 			pirq, chip->name, irq);
42857129044SKuppuswamy Sathyanarayanan 		return irq;
42957129044SKuppuswamy Sathyanarayanan 	}
43057129044SKuppuswamy Sathyanarayanan 
43157129044SKuppuswamy Sathyanarayanan 	return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
43257129044SKuppuswamy Sathyanarayanan 					0, chip, data);
43357129044SKuppuswamy Sathyanarayanan }
43457129044SKuppuswamy Sathyanarayanan 
43539d047c0SQipeng Zha static int bxtwc_probe(struct platform_device *pdev)
43639d047c0SQipeng Zha {
43739d047c0SQipeng Zha 	int ret;
43839d047c0SQipeng Zha 	acpi_handle handle;
43939d047c0SQipeng Zha 	acpi_status status;
44039d047c0SQipeng Zha 	unsigned long long hrv;
44139d047c0SQipeng Zha 	struct intel_soc_pmic *pmic;
44239d047c0SQipeng Zha 
44339d047c0SQipeng Zha 	handle = ACPI_HANDLE(&pdev->dev);
44439d047c0SQipeng Zha 	status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
44539d047c0SQipeng Zha 	if (ACPI_FAILURE(status)) {
44639d047c0SQipeng Zha 		dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
44739d047c0SQipeng Zha 		return -ENODEV;
44839d047c0SQipeng Zha 	}
44939d047c0SQipeng Zha 	if (hrv != BROXTON_PMIC_WC_HRV) {
45039d047c0SQipeng Zha 		dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
45139d047c0SQipeng Zha 			hrv);
45239d047c0SQipeng Zha 		return -ENODEV;
45339d047c0SQipeng Zha 	}
45439d047c0SQipeng Zha 
45539d047c0SQipeng Zha 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
45639d047c0SQipeng Zha 	if (!pmic)
45739d047c0SQipeng Zha 		return -ENOMEM;
45839d047c0SQipeng Zha 
45939d047c0SQipeng Zha 	ret = platform_get_irq(pdev, 0);
46039d047c0SQipeng Zha 	if (ret < 0) {
46139d047c0SQipeng Zha 		dev_err(&pdev->dev, "Invalid IRQ\n");
46239d047c0SQipeng Zha 		return ret;
46339d047c0SQipeng Zha 	}
46439d047c0SQipeng Zha 	pmic->irq = ret;
46539d047c0SQipeng Zha 
46639d047c0SQipeng Zha 	dev_set_drvdata(&pdev->dev, pmic);
46739d047c0SQipeng Zha 	pmic->dev = &pdev->dev;
46839d047c0SQipeng Zha 
46939d047c0SQipeng Zha 	pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
47039d047c0SQipeng Zha 					&bxtwc_regmap_config);
47139d047c0SQipeng Zha 	if (IS_ERR(pmic->regmap)) {
47239d047c0SQipeng Zha 		ret = PTR_ERR(pmic->regmap);
47339d047c0SQipeng Zha 		dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
47439d047c0SQipeng Zha 		return ret;
47539d047c0SQipeng Zha 	}
47639d047c0SQipeng Zha 
4775131f072SKuppuswamy Sathyanarayanan 	ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
47839d047c0SQipeng Zha 				       IRQF_ONESHOT | IRQF_SHARED,
47939d047c0SQipeng Zha 				       0, &bxtwc_regmap_irq_chip,
48039d047c0SQipeng Zha 				       &pmic->irq_chip_data);
48139d047c0SQipeng Zha 	if (ret) {
48239d047c0SQipeng Zha 		dev_err(&pdev->dev, "Failed to add IRQ chip\n");
48339d047c0SQipeng Zha 		return ret;
48439d047c0SQipeng Zha 	}
48539d047c0SQipeng Zha 
48657129044SKuppuswamy Sathyanarayanan 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
487*9f8ddee1SAndy Shevchenko 					 BXTWC_PWRBTN_LVL1_IRQ,
488*9f8ddee1SAndy Shevchenko 					 IRQF_ONESHOT,
489*9f8ddee1SAndy Shevchenko 					 &bxtwc_regmap_irq_chip_pwrbtn,
490*9f8ddee1SAndy Shevchenko 					 &pmic->irq_chip_data_pwrbtn);
491*9f8ddee1SAndy Shevchenko 	if (ret) {
492*9f8ddee1SAndy Shevchenko 		dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
493*9f8ddee1SAndy Shevchenko 		return ret;
494*9f8ddee1SAndy Shevchenko 	}
495*9f8ddee1SAndy Shevchenko 
496*9f8ddee1SAndy Shevchenko 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
49757129044SKuppuswamy Sathyanarayanan 					 BXTWC_TMU_LVL1_IRQ,
49857129044SKuppuswamy Sathyanarayanan 					 IRQF_ONESHOT,
49957129044SKuppuswamy Sathyanarayanan 					 &bxtwc_regmap_irq_chip_tmu,
500957ae509SNilesh Bacchewar 					 &pmic->irq_chip_data_tmu);
501957ae509SNilesh Bacchewar 	if (ret) {
502957ae509SNilesh Bacchewar 		dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
5035131f072SKuppuswamy Sathyanarayanan 		return ret;
504957ae509SNilesh Bacchewar 	}
505957ae509SNilesh Bacchewar 
50657129044SKuppuswamy Sathyanarayanan 	/* Add chained IRQ handler for BCU IRQs */
50757129044SKuppuswamy Sathyanarayanan 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
50857129044SKuppuswamy Sathyanarayanan 					 BXTWC_BCU_LVL1_IRQ,
50957129044SKuppuswamy Sathyanarayanan 					 IRQF_ONESHOT,
51057129044SKuppuswamy Sathyanarayanan 					 &bxtwc_regmap_irq_chip_bcu,
51157129044SKuppuswamy Sathyanarayanan 					 &pmic->irq_chip_data_bcu);
51257129044SKuppuswamy Sathyanarayanan 
51357129044SKuppuswamy Sathyanarayanan 
51457129044SKuppuswamy Sathyanarayanan 	if (ret) {
51557129044SKuppuswamy Sathyanarayanan 		dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
51657129044SKuppuswamy Sathyanarayanan 		return ret;
51757129044SKuppuswamy Sathyanarayanan 	}
51857129044SKuppuswamy Sathyanarayanan 
51957129044SKuppuswamy Sathyanarayanan 	/* Add chained IRQ handler for ADC IRQs */
52057129044SKuppuswamy Sathyanarayanan 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
52157129044SKuppuswamy Sathyanarayanan 					 BXTWC_ADC_LVL1_IRQ,
52257129044SKuppuswamy Sathyanarayanan 					 IRQF_ONESHOT,
52357129044SKuppuswamy Sathyanarayanan 					 &bxtwc_regmap_irq_chip_adc,
52457129044SKuppuswamy Sathyanarayanan 					 &pmic->irq_chip_data_adc);
52557129044SKuppuswamy Sathyanarayanan 
52657129044SKuppuswamy Sathyanarayanan 
52757129044SKuppuswamy Sathyanarayanan 	if (ret) {
52857129044SKuppuswamy Sathyanarayanan 		dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
52957129044SKuppuswamy Sathyanarayanan 		return ret;
53057129044SKuppuswamy Sathyanarayanan 	}
53157129044SKuppuswamy Sathyanarayanan 
53257129044SKuppuswamy Sathyanarayanan 	/* Add chained IRQ handler for CHGR IRQs */
53357129044SKuppuswamy Sathyanarayanan 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
53457129044SKuppuswamy Sathyanarayanan 					 BXTWC_CHGR_LVL1_IRQ,
53557129044SKuppuswamy Sathyanarayanan 					 IRQF_ONESHOT,
53657129044SKuppuswamy Sathyanarayanan 					 &bxtwc_regmap_irq_chip_chgr,
53757129044SKuppuswamy Sathyanarayanan 					 &pmic->irq_chip_data_chgr);
53857129044SKuppuswamy Sathyanarayanan 
53957129044SKuppuswamy Sathyanarayanan 
54057129044SKuppuswamy Sathyanarayanan 	if (ret) {
54157129044SKuppuswamy Sathyanarayanan 		dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
54257129044SKuppuswamy Sathyanarayanan 		return ret;
54357129044SKuppuswamy Sathyanarayanan 	}
54457129044SKuppuswamy Sathyanarayanan 
54557129044SKuppuswamy Sathyanarayanan 	/* Add chained IRQ handler for CRIT IRQs */
54657129044SKuppuswamy Sathyanarayanan 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
54757129044SKuppuswamy Sathyanarayanan 					 BXTWC_CRIT_LVL1_IRQ,
54857129044SKuppuswamy Sathyanarayanan 					 IRQF_ONESHOT,
54957129044SKuppuswamy Sathyanarayanan 					 &bxtwc_regmap_irq_chip_crit,
55057129044SKuppuswamy Sathyanarayanan 					 &pmic->irq_chip_data_crit);
55157129044SKuppuswamy Sathyanarayanan 
55257129044SKuppuswamy Sathyanarayanan 
55357129044SKuppuswamy Sathyanarayanan 	if (ret) {
55457129044SKuppuswamy Sathyanarayanan 		dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
55557129044SKuppuswamy Sathyanarayanan 		return ret;
55657129044SKuppuswamy Sathyanarayanan 	}
55757129044SKuppuswamy Sathyanarayanan 
5585131f072SKuppuswamy Sathyanarayanan 	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
5595131f072SKuppuswamy Sathyanarayanan 				   ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
56039d047c0SQipeng Zha 	if (ret) {
56139d047c0SQipeng Zha 		dev_err(&pdev->dev, "Failed to add devices\n");
5625131f072SKuppuswamy Sathyanarayanan 		return ret;
56339d047c0SQipeng Zha 	}
56439d047c0SQipeng Zha 
56539d047c0SQipeng Zha 	ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
56639d047c0SQipeng Zha 	if (ret) {
56739d047c0SQipeng Zha 		dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
5685131f072SKuppuswamy Sathyanarayanan 		return ret;
56939d047c0SQipeng Zha 	}
57039d047c0SQipeng Zha 
5719c6235c8SBin Gao 	/*
5729c6235c8SBin Gao 	 * There is known hw bug. Upon reset BIT 5 of register
5739c6235c8SBin Gao 	 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
5749c6235c8SBin Gao 	 * later it's set to 1(masked) automatically by hardware. So we
5759c6235c8SBin Gao 	 * have the software workaround here to unmaksed it in order to let
5769c6235c8SBin Gao 	 * charger interrutp work.
5779c6235c8SBin Gao 	 */
5789c6235c8SBin Gao 	regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
5799c6235c8SBin Gao 				BXTWC_MIRQLVL1_MCHGR, 0);
5809c6235c8SBin Gao 
58139d047c0SQipeng Zha 	return 0;
58239d047c0SQipeng Zha }
58339d047c0SQipeng Zha 
58439d047c0SQipeng Zha static int bxtwc_remove(struct platform_device *pdev)
58539d047c0SQipeng Zha {
58639d047c0SQipeng Zha 	sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
58739d047c0SQipeng Zha 
58839d047c0SQipeng Zha 	return 0;
58939d047c0SQipeng Zha }
59039d047c0SQipeng Zha 
59139d047c0SQipeng Zha static void bxtwc_shutdown(struct platform_device *pdev)
59239d047c0SQipeng Zha {
59339d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
59439d047c0SQipeng Zha 
59539d047c0SQipeng Zha 	disable_irq(pmic->irq);
59639d047c0SQipeng Zha }
59739d047c0SQipeng Zha 
59839d047c0SQipeng Zha #ifdef CONFIG_PM_SLEEP
59939d047c0SQipeng Zha static int bxtwc_suspend(struct device *dev)
60039d047c0SQipeng Zha {
60139d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
60239d047c0SQipeng Zha 
60339d047c0SQipeng Zha 	disable_irq(pmic->irq);
60439d047c0SQipeng Zha 
60539d047c0SQipeng Zha 	return 0;
60639d047c0SQipeng Zha }
60739d047c0SQipeng Zha 
60839d047c0SQipeng Zha static int bxtwc_resume(struct device *dev)
60939d047c0SQipeng Zha {
61039d047c0SQipeng Zha 	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
61139d047c0SQipeng Zha 
61239d047c0SQipeng Zha 	enable_irq(pmic->irq);
61339d047c0SQipeng Zha 	return 0;
61439d047c0SQipeng Zha }
61539d047c0SQipeng Zha #endif
61639d047c0SQipeng Zha static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
61739d047c0SQipeng Zha 
61839d047c0SQipeng Zha static const struct acpi_device_id bxtwc_acpi_ids[] = {
61939d047c0SQipeng Zha 	{ "INT34D3", },
62039d047c0SQipeng Zha 	{ }
62139d047c0SQipeng Zha };
622f57576e7SWei Yongjun MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
62339d047c0SQipeng Zha 
62439d047c0SQipeng Zha static struct platform_driver bxtwc_driver = {
62539d047c0SQipeng Zha 	.probe = bxtwc_probe,
62639d047c0SQipeng Zha 	.remove	= bxtwc_remove,
62739d047c0SQipeng Zha 	.shutdown = bxtwc_shutdown,
62839d047c0SQipeng Zha 	.driver	= {
62939d047c0SQipeng Zha 		.name	= "BXTWC PMIC",
63039d047c0SQipeng Zha 		.pm     = &bxtwc_pm_ops,
63139d047c0SQipeng Zha 		.acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
63239d047c0SQipeng Zha 	},
63339d047c0SQipeng Zha };
63439d047c0SQipeng Zha 
63539d047c0SQipeng Zha module_platform_driver(bxtwc_driver);
63639d047c0SQipeng Zha 
63739d047c0SQipeng Zha MODULE_LICENSE("GPL v2");
63839d047c0SQipeng Zha MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>");
639