1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * MFD core driver for Intel Broxton Whiskey Cove PMIC 4 * 5 * Copyright (C) 2015 Intel Corporation. All rights reserved. 6 */ 7 8 #include <linux/acpi.h> 9 #include <linux/delay.h> 10 #include <linux/err.h> 11 #include <linux/interrupt.h> 12 #include <linux/kernel.h> 13 #include <linux/mfd/core.h> 14 #include <linux/mfd/intel_soc_pmic.h> 15 #include <linux/mfd/intel_soc_pmic_bxtwc.h> 16 #include <linux/module.h> 17 18 #include <asm/intel_pmc_ipc.h> 19 20 /* PMIC device registers */ 21 #define REG_ADDR_MASK 0xFF00 22 #define REG_ADDR_SHIFT 8 23 #define REG_OFFSET_MASK 0xFF 24 25 /* Interrupt Status Registers */ 26 #define BXTWC_IRQLVL1 0x4E02 27 28 #define BXTWC_PWRBTNIRQ 0x4E03 29 #define BXTWC_THRM0IRQ 0x4E04 30 #define BXTWC_THRM1IRQ 0x4E05 31 #define BXTWC_THRM2IRQ 0x4E06 32 #define BXTWC_BCUIRQ 0x4E07 33 #define BXTWC_ADCIRQ 0x4E08 34 #define BXTWC_CHGR0IRQ 0x4E09 35 #define BXTWC_CHGR1IRQ 0x4E0A 36 #define BXTWC_GPIOIRQ0 0x4E0B 37 #define BXTWC_GPIOIRQ1 0x4E0C 38 #define BXTWC_CRITIRQ 0x4E0D 39 #define BXTWC_TMUIRQ 0x4FB6 40 41 /* Interrupt MASK Registers */ 42 #define BXTWC_MIRQLVL1 0x4E0E 43 #define BXTWC_MIRQLVL1_MCHGR BIT(5) 44 45 #define BXTWC_MPWRBTNIRQ 0x4E0F 46 #define BXTWC_MTHRM0IRQ 0x4E12 47 #define BXTWC_MTHRM1IRQ 0x4E13 48 #define BXTWC_MTHRM2IRQ 0x4E14 49 #define BXTWC_MBCUIRQ 0x4E15 50 #define BXTWC_MADCIRQ 0x4E16 51 #define BXTWC_MCHGR0IRQ 0x4E17 52 #define BXTWC_MCHGR1IRQ 0x4E18 53 #define BXTWC_MGPIO0IRQ 0x4E19 54 #define BXTWC_MGPIO1IRQ 0x4E1A 55 #define BXTWC_MCRITIRQ 0x4E1B 56 #define BXTWC_MTMUIRQ 0x4FB7 57 58 /* Whiskey Cove PMIC share same ACPI ID between different platforms */ 59 #define BROXTON_PMIC_WC_HRV 4 60 61 enum bxtwc_irqs { 62 BXTWC_PWRBTN_LVL1_IRQ = 0, 63 BXTWC_TMU_LVL1_IRQ, 64 BXTWC_THRM_LVL1_IRQ, 65 BXTWC_BCU_LVL1_IRQ, 66 BXTWC_ADC_LVL1_IRQ, 67 BXTWC_CHGR_LVL1_IRQ, 68 BXTWC_GPIO_LVL1_IRQ, 69 BXTWC_CRIT_LVL1_IRQ, 70 }; 71 72 enum bxtwc_irqs_pwrbtn { 73 BXTWC_PWRBTN_IRQ = 0, 74 BXTWC_UIBTN_IRQ, 75 }; 76 77 enum bxtwc_irqs_bcu { 78 BXTWC_BCU_IRQ = 0, 79 }; 80 81 enum bxtwc_irqs_adc { 82 BXTWC_ADC_IRQ = 0, 83 }; 84 85 enum bxtwc_irqs_chgr { 86 BXTWC_USBC_IRQ = 0, 87 BXTWC_CHGR0_IRQ, 88 BXTWC_CHGR1_IRQ, 89 }; 90 91 enum bxtwc_irqs_tmu { 92 BXTWC_TMU_IRQ = 0, 93 }; 94 95 enum bxtwc_irqs_crit { 96 BXTWC_CRIT_IRQ = 0, 97 }; 98 99 static const struct regmap_irq bxtwc_regmap_irqs[] = { 100 REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)), 101 REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)), 102 REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)), 103 REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)), 104 REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)), 105 REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)), 106 REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)), 107 REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)), 108 }; 109 110 static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = { 111 REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01), 112 }; 113 114 static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = { 115 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f), 116 }; 117 118 static const struct regmap_irq bxtwc_regmap_irqs_adc[] = { 119 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff), 120 }; 121 122 static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = { 123 REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20), 124 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f), 125 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f), 126 }; 127 128 static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = { 129 REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06), 130 }; 131 132 static const struct regmap_irq bxtwc_regmap_irqs_crit[] = { 133 REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03), 134 }; 135 136 static struct regmap_irq_chip bxtwc_regmap_irq_chip = { 137 .name = "bxtwc_irq_chip", 138 .status_base = BXTWC_IRQLVL1, 139 .mask_base = BXTWC_MIRQLVL1, 140 .irqs = bxtwc_regmap_irqs, 141 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs), 142 .num_regs = 1, 143 }; 144 145 static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { 146 .name = "bxtwc_irq_chip_pwrbtn", 147 .status_base = BXTWC_PWRBTNIRQ, 148 .mask_base = BXTWC_MPWRBTNIRQ, 149 .irqs = bxtwc_regmap_irqs_pwrbtn, 150 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn), 151 .num_regs = 1, 152 }; 153 154 static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { 155 .name = "bxtwc_irq_chip_tmu", 156 .status_base = BXTWC_TMUIRQ, 157 .mask_base = BXTWC_MTMUIRQ, 158 .irqs = bxtwc_regmap_irqs_tmu, 159 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu), 160 .num_regs = 1, 161 }; 162 163 static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { 164 .name = "bxtwc_irq_chip_bcu", 165 .status_base = BXTWC_BCUIRQ, 166 .mask_base = BXTWC_MBCUIRQ, 167 .irqs = bxtwc_regmap_irqs_bcu, 168 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu), 169 .num_regs = 1, 170 }; 171 172 static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { 173 .name = "bxtwc_irq_chip_adc", 174 .status_base = BXTWC_ADCIRQ, 175 .mask_base = BXTWC_MADCIRQ, 176 .irqs = bxtwc_regmap_irqs_adc, 177 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc), 178 .num_regs = 1, 179 }; 180 181 static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { 182 .name = "bxtwc_irq_chip_chgr", 183 .status_base = BXTWC_CHGR0IRQ, 184 .mask_base = BXTWC_MCHGR0IRQ, 185 .irqs = bxtwc_regmap_irqs_chgr, 186 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr), 187 .num_regs = 2, 188 }; 189 190 static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { 191 .name = "bxtwc_irq_chip_crit", 192 .status_base = BXTWC_CRITIRQ, 193 .mask_base = BXTWC_MCRITIRQ, 194 .irqs = bxtwc_regmap_irqs_crit, 195 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit), 196 .num_regs = 1, 197 }; 198 199 static struct resource gpio_resources[] = { 200 DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"), 201 }; 202 203 static struct resource adc_resources[] = { 204 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"), 205 }; 206 207 static struct resource usbc_resources[] = { 208 DEFINE_RES_IRQ(BXTWC_USBC_IRQ), 209 }; 210 211 static struct resource charger_resources[] = { 212 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"), 213 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"), 214 }; 215 216 static struct resource thermal_resources[] = { 217 DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ), 218 }; 219 220 static struct resource bcu_resources[] = { 221 DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"), 222 }; 223 224 static struct resource tmu_resources[] = { 225 DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"), 226 }; 227 228 static struct mfd_cell bxt_wc_dev[] = { 229 { 230 .name = "bxt_wcove_gpadc", 231 .num_resources = ARRAY_SIZE(adc_resources), 232 .resources = adc_resources, 233 }, 234 { 235 .name = "bxt_wcove_thermal", 236 .num_resources = ARRAY_SIZE(thermal_resources), 237 .resources = thermal_resources, 238 }, 239 { 240 .name = "bxt_wcove_usbc", 241 .num_resources = ARRAY_SIZE(usbc_resources), 242 .resources = usbc_resources, 243 }, 244 { 245 .name = "bxt_wcove_ext_charger", 246 .num_resources = ARRAY_SIZE(charger_resources), 247 .resources = charger_resources, 248 }, 249 { 250 .name = "bxt_wcove_bcu", 251 .num_resources = ARRAY_SIZE(bcu_resources), 252 .resources = bcu_resources, 253 }, 254 { 255 .name = "bxt_wcove_tmu", 256 .num_resources = ARRAY_SIZE(tmu_resources), 257 .resources = tmu_resources, 258 }, 259 260 { 261 .name = "bxt_wcove_gpio", 262 .num_resources = ARRAY_SIZE(gpio_resources), 263 .resources = gpio_resources, 264 }, 265 { 266 .name = "bxt_wcove_region", 267 }, 268 }; 269 270 static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, 271 unsigned int *val) 272 { 273 int ret; 274 int i2c_addr; 275 u8 ipc_in[2]; 276 u8 ipc_out[4]; 277 struct intel_soc_pmic *pmic = context; 278 279 if (!pmic) 280 return -EINVAL; 281 282 if (reg & REG_ADDR_MASK) 283 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; 284 else 285 i2c_addr = BXTWC_DEVICE1_ADDR; 286 287 reg &= REG_OFFSET_MASK; 288 289 ipc_in[0] = reg; 290 ipc_in[1] = i2c_addr; 291 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, 292 PMC_IPC_PMIC_ACCESS_READ, 293 ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1); 294 if (ret) { 295 dev_err(pmic->dev, "Failed to read from PMIC\n"); 296 return ret; 297 } 298 *val = ipc_out[0]; 299 300 return 0; 301 } 302 303 static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, 304 unsigned int val) 305 { 306 int ret; 307 int i2c_addr; 308 u8 ipc_in[3]; 309 struct intel_soc_pmic *pmic = context; 310 311 if (!pmic) 312 return -EINVAL; 313 314 if (reg & REG_ADDR_MASK) 315 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; 316 else 317 i2c_addr = BXTWC_DEVICE1_ADDR; 318 319 reg &= REG_OFFSET_MASK; 320 321 ipc_in[0] = reg; 322 ipc_in[1] = i2c_addr; 323 ipc_in[2] = val; 324 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, 325 PMC_IPC_PMIC_ACCESS_WRITE, 326 ipc_in, sizeof(ipc_in), NULL, 0); 327 if (ret) { 328 dev_err(pmic->dev, "Failed to write to PMIC\n"); 329 return ret; 330 } 331 332 return 0; 333 } 334 335 /* sysfs interfaces to r/w PMIC registers, required by initial script */ 336 static unsigned long bxtwc_reg_addr; 337 static ssize_t bxtwc_reg_show(struct device *dev, 338 struct device_attribute *attr, char *buf) 339 { 340 return sprintf(buf, "0x%lx\n", bxtwc_reg_addr); 341 } 342 343 static ssize_t bxtwc_reg_store(struct device *dev, 344 struct device_attribute *attr, const char *buf, size_t count) 345 { 346 if (kstrtoul(buf, 0, &bxtwc_reg_addr)) { 347 dev_err(dev, "Invalid register address\n"); 348 return -EINVAL; 349 } 350 return (ssize_t)count; 351 } 352 353 static ssize_t bxtwc_val_show(struct device *dev, 354 struct device_attribute *attr, char *buf) 355 { 356 int ret; 357 unsigned int val; 358 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 359 360 ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val); 361 if (ret < 0) { 362 dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr); 363 return -EIO; 364 } 365 366 return sprintf(buf, "0x%02x\n", val); 367 } 368 369 static ssize_t bxtwc_val_store(struct device *dev, 370 struct device_attribute *attr, const char *buf, size_t count) 371 { 372 int ret; 373 unsigned int val; 374 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 375 376 ret = kstrtouint(buf, 0, &val); 377 if (ret) 378 return ret; 379 380 ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val); 381 if (ret) { 382 dev_err(dev, "Failed to write value 0x%02x to address 0x%lx", 383 val, bxtwc_reg_addr); 384 return -EIO; 385 } 386 return count; 387 } 388 389 static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store); 390 static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store); 391 static struct attribute *bxtwc_attrs[] = { 392 &dev_attr_addr.attr, 393 &dev_attr_val.attr, 394 NULL 395 }; 396 397 static const struct attribute_group bxtwc_group = { 398 .attrs = bxtwc_attrs, 399 }; 400 401 static const struct regmap_config bxtwc_regmap_config = { 402 .reg_bits = 16, 403 .val_bits = 8, 404 .reg_write = regmap_ipc_byte_reg_write, 405 .reg_read = regmap_ipc_byte_reg_read, 406 }; 407 408 static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic, 409 struct regmap_irq_chip_data *pdata, 410 int pirq, int irq_flags, 411 const struct regmap_irq_chip *chip, 412 struct regmap_irq_chip_data **data) 413 { 414 int irq; 415 416 irq = regmap_irq_get_virq(pdata, pirq); 417 if (irq < 0) { 418 dev_err(pmic->dev, 419 "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n", 420 pirq, chip->name, irq); 421 return irq; 422 } 423 424 return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags, 425 0, chip, data); 426 } 427 428 static int bxtwc_probe(struct platform_device *pdev) 429 { 430 int ret; 431 acpi_handle handle; 432 acpi_status status; 433 unsigned long long hrv; 434 struct intel_soc_pmic *pmic; 435 436 handle = ACPI_HANDLE(&pdev->dev); 437 status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); 438 if (ACPI_FAILURE(status)) { 439 dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n"); 440 return -ENODEV; 441 } 442 if (hrv != BROXTON_PMIC_WC_HRV) { 443 dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n", 444 hrv); 445 return -ENODEV; 446 } 447 448 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 449 if (!pmic) 450 return -ENOMEM; 451 452 ret = platform_get_irq(pdev, 0); 453 if (ret < 0) 454 return ret; 455 pmic->irq = ret; 456 457 dev_set_drvdata(&pdev->dev, pmic); 458 pmic->dev = &pdev->dev; 459 460 pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic, 461 &bxtwc_regmap_config); 462 if (IS_ERR(pmic->regmap)) { 463 ret = PTR_ERR(pmic->regmap); 464 dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret); 465 return ret; 466 } 467 468 ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq, 469 IRQF_ONESHOT | IRQF_SHARED, 470 0, &bxtwc_regmap_irq_chip, 471 &pmic->irq_chip_data); 472 if (ret) { 473 dev_err(&pdev->dev, "Failed to add IRQ chip\n"); 474 return ret; 475 } 476 477 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 478 BXTWC_PWRBTN_LVL1_IRQ, 479 IRQF_ONESHOT, 480 &bxtwc_regmap_irq_chip_pwrbtn, 481 &pmic->irq_chip_data_pwrbtn); 482 if (ret) { 483 dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n"); 484 return ret; 485 } 486 487 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 488 BXTWC_TMU_LVL1_IRQ, 489 IRQF_ONESHOT, 490 &bxtwc_regmap_irq_chip_tmu, 491 &pmic->irq_chip_data_tmu); 492 if (ret) { 493 dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); 494 return ret; 495 } 496 497 /* Add chained IRQ handler for BCU IRQs */ 498 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 499 BXTWC_BCU_LVL1_IRQ, 500 IRQF_ONESHOT, 501 &bxtwc_regmap_irq_chip_bcu, 502 &pmic->irq_chip_data_bcu); 503 504 505 if (ret) { 506 dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n"); 507 return ret; 508 } 509 510 /* Add chained IRQ handler for ADC IRQs */ 511 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 512 BXTWC_ADC_LVL1_IRQ, 513 IRQF_ONESHOT, 514 &bxtwc_regmap_irq_chip_adc, 515 &pmic->irq_chip_data_adc); 516 517 518 if (ret) { 519 dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n"); 520 return ret; 521 } 522 523 /* Add chained IRQ handler for CHGR IRQs */ 524 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 525 BXTWC_CHGR_LVL1_IRQ, 526 IRQF_ONESHOT, 527 &bxtwc_regmap_irq_chip_chgr, 528 &pmic->irq_chip_data_chgr); 529 530 531 if (ret) { 532 dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n"); 533 return ret; 534 } 535 536 /* Add chained IRQ handler for CRIT IRQs */ 537 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 538 BXTWC_CRIT_LVL1_IRQ, 539 IRQF_ONESHOT, 540 &bxtwc_regmap_irq_chip_crit, 541 &pmic->irq_chip_data_crit); 542 543 544 if (ret) { 545 dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n"); 546 return ret; 547 } 548 549 ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, 550 ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); 551 if (ret) { 552 dev_err(&pdev->dev, "Failed to add devices\n"); 553 return ret; 554 } 555 556 ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); 557 if (ret) { 558 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret); 559 return ret; 560 } 561 562 /* 563 * There is known hw bug. Upon reset BIT 5 of register 564 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However, 565 * later it's set to 1(masked) automatically by hardware. So we 566 * have the software workaround here to unmaksed it in order to let 567 * charger interrutp work. 568 */ 569 regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1, 570 BXTWC_MIRQLVL1_MCHGR, 0); 571 572 return 0; 573 } 574 575 static int bxtwc_remove(struct platform_device *pdev) 576 { 577 sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group); 578 579 return 0; 580 } 581 582 static void bxtwc_shutdown(struct platform_device *pdev) 583 { 584 struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); 585 586 disable_irq(pmic->irq); 587 } 588 589 #ifdef CONFIG_PM_SLEEP 590 static int bxtwc_suspend(struct device *dev) 591 { 592 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 593 594 disable_irq(pmic->irq); 595 596 return 0; 597 } 598 599 static int bxtwc_resume(struct device *dev) 600 { 601 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 602 603 enable_irq(pmic->irq); 604 return 0; 605 } 606 #endif 607 static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume); 608 609 static const struct acpi_device_id bxtwc_acpi_ids[] = { 610 { "INT34D3", }, 611 { } 612 }; 613 MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids); 614 615 static struct platform_driver bxtwc_driver = { 616 .probe = bxtwc_probe, 617 .remove = bxtwc_remove, 618 .shutdown = bxtwc_shutdown, 619 .driver = { 620 .name = "BXTWC PMIC", 621 .pm = &bxtwc_pm_ops, 622 .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids), 623 }, 624 }; 625 626 module_platform_driver(bxtwc_driver); 627 628 MODULE_LICENSE("GPL v2"); 629 MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>"); 630