1 /* 2 * wm831x-core.c -- Device access for Wolfson WM831x PMICs 3 * 4 * Copyright 2009 Wolfson Microelectronics PLC. 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/bcd.h> 18 #include <linux/delay.h> 19 #include <linux/mfd/core.h> 20 #include <linux/slab.h> 21 22 #include <linux/mfd/wm831x/core.h> 23 #include <linux/mfd/wm831x/pdata.h> 24 #include <linux/mfd/wm831x/irq.h> 25 #include <linux/mfd/wm831x/auxadc.h> 26 #include <linux/mfd/wm831x/otp.h> 27 #include <linux/mfd/wm831x/regulator.h> 28 29 /* Current settings - values are 2*2^(reg_val/4) microamps. These are 30 * exported since they are used by multiple drivers. 31 */ 32 int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = { 33 2, 34 2, 35 3, 36 3, 37 4, 38 5, 39 6, 40 7, 41 8, 42 10, 43 11, 44 13, 45 16, 46 19, 47 23, 48 27, 49 32, 50 38, 51 45, 52 54, 53 64, 54 76, 55 91, 56 108, 57 128, 58 152, 59 181, 60 215, 61 256, 62 304, 63 362, 64 431, 65 512, 66 609, 67 724, 68 861, 69 1024, 70 1218, 71 1448, 72 1722, 73 2048, 74 2435, 75 2896, 76 3444, 77 4096, 78 4871, 79 5793, 80 6889, 81 8192, 82 9742, 83 11585, 84 13777, 85 16384, 86 19484, 87 23170, 88 27554, 89 }; 90 EXPORT_SYMBOL_GPL(wm831x_isinkv_values); 91 92 static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg) 93 { 94 if (!wm831x->locked) 95 return 0; 96 97 switch (reg) { 98 case WM831X_WATCHDOG: 99 case WM831X_DC4_CONTROL: 100 case WM831X_ON_PIN_CONTROL: 101 case WM831X_BACKUP_CHARGER_CONTROL: 102 case WM831X_CHARGER_CONTROL_1: 103 case WM831X_CHARGER_CONTROL_2: 104 return 1; 105 106 default: 107 return 0; 108 } 109 } 110 111 /** 112 * wm831x_reg_unlock: Unlock user keyed registers 113 * 114 * The WM831x has a user key preventing writes to particularly 115 * critical registers. This function locks those registers, 116 * allowing writes to them. 117 */ 118 void wm831x_reg_lock(struct wm831x *wm831x) 119 { 120 int ret; 121 122 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0); 123 if (ret == 0) { 124 dev_vdbg(wm831x->dev, "Registers locked\n"); 125 126 mutex_lock(&wm831x->io_lock); 127 WARN_ON(wm831x->locked); 128 wm831x->locked = 1; 129 mutex_unlock(&wm831x->io_lock); 130 } else { 131 dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret); 132 } 133 134 } 135 EXPORT_SYMBOL_GPL(wm831x_reg_lock); 136 137 /** 138 * wm831x_reg_unlock: Unlock user keyed registers 139 * 140 * The WM831x has a user key preventing writes to particularly 141 * critical registers. This function locks those registers, 142 * preventing spurious writes. 143 */ 144 int wm831x_reg_unlock(struct wm831x *wm831x) 145 { 146 int ret; 147 148 /* 0x9716 is the value required to unlock the registers */ 149 ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716); 150 if (ret == 0) { 151 dev_vdbg(wm831x->dev, "Registers unlocked\n"); 152 153 mutex_lock(&wm831x->io_lock); 154 WARN_ON(!wm831x->locked); 155 wm831x->locked = 0; 156 mutex_unlock(&wm831x->io_lock); 157 } 158 159 return ret; 160 } 161 EXPORT_SYMBOL_GPL(wm831x_reg_unlock); 162 163 static int wm831x_read(struct wm831x *wm831x, unsigned short reg, 164 int bytes, void *dest) 165 { 166 int ret, i; 167 u16 *buf = dest; 168 169 BUG_ON(bytes % 2); 170 BUG_ON(bytes <= 0); 171 172 ret = wm831x->read_dev(wm831x, reg, bytes, dest); 173 if (ret < 0) 174 return ret; 175 176 for (i = 0; i < bytes / 2; i++) { 177 buf[i] = be16_to_cpu(buf[i]); 178 179 dev_vdbg(wm831x->dev, "Read %04x from R%d(0x%x)\n", 180 buf[i], reg + i, reg + i); 181 } 182 183 return 0; 184 } 185 186 /** 187 * wm831x_reg_read: Read a single WM831x register. 188 * 189 * @wm831x: Device to read from. 190 * @reg: Register to read. 191 */ 192 int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg) 193 { 194 unsigned short val; 195 int ret; 196 197 mutex_lock(&wm831x->io_lock); 198 199 ret = wm831x_read(wm831x, reg, 2, &val); 200 201 mutex_unlock(&wm831x->io_lock); 202 203 if (ret < 0) 204 return ret; 205 else 206 return val; 207 } 208 EXPORT_SYMBOL_GPL(wm831x_reg_read); 209 210 /** 211 * wm831x_bulk_read: Read multiple WM831x registers 212 * 213 * @wm831x: Device to read from 214 * @reg: First register 215 * @count: Number of registers 216 * @buf: Buffer to fill. 217 */ 218 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, 219 int count, u16 *buf) 220 { 221 int ret; 222 223 mutex_lock(&wm831x->io_lock); 224 225 ret = wm831x_read(wm831x, reg, count * 2, buf); 226 227 mutex_unlock(&wm831x->io_lock); 228 229 return ret; 230 } 231 EXPORT_SYMBOL_GPL(wm831x_bulk_read); 232 233 static int wm831x_write(struct wm831x *wm831x, unsigned short reg, 234 int bytes, void *src) 235 { 236 u16 *buf = src; 237 int i; 238 239 BUG_ON(bytes % 2); 240 BUG_ON(bytes <= 0); 241 242 for (i = 0; i < bytes / 2; i++) { 243 if (wm831x_reg_locked(wm831x, reg)) 244 return -EPERM; 245 246 dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n", 247 buf[i], reg + i, reg + i); 248 249 buf[i] = cpu_to_be16(buf[i]); 250 } 251 252 return wm831x->write_dev(wm831x, reg, bytes, src); 253 } 254 255 /** 256 * wm831x_reg_write: Write a single WM831x register. 257 * 258 * @wm831x: Device to write to. 259 * @reg: Register to write to. 260 * @val: Value to write. 261 */ 262 int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg, 263 unsigned short val) 264 { 265 int ret; 266 267 mutex_lock(&wm831x->io_lock); 268 269 ret = wm831x_write(wm831x, reg, 2, &val); 270 271 mutex_unlock(&wm831x->io_lock); 272 273 return ret; 274 } 275 EXPORT_SYMBOL_GPL(wm831x_reg_write); 276 277 /** 278 * wm831x_set_bits: Set the value of a bitfield in a WM831x register 279 * 280 * @wm831x: Device to write to. 281 * @reg: Register to write to. 282 * @mask: Mask of bits to set. 283 * @val: Value to set (unshifted) 284 */ 285 int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg, 286 unsigned short mask, unsigned short val) 287 { 288 int ret; 289 u16 r; 290 291 mutex_lock(&wm831x->io_lock); 292 293 ret = wm831x_read(wm831x, reg, 2, &r); 294 if (ret < 0) 295 goto out; 296 297 r &= ~mask; 298 r |= val; 299 300 ret = wm831x_write(wm831x, reg, 2, &r); 301 302 out: 303 mutex_unlock(&wm831x->io_lock); 304 305 return ret; 306 } 307 EXPORT_SYMBOL_GPL(wm831x_set_bits); 308 309 /** 310 * wm831x_auxadc_read: Read a value from the WM831x AUXADC 311 * 312 * @wm831x: Device to read from. 313 * @input: AUXADC input to read. 314 */ 315 int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input) 316 { 317 int ret, src, irq_masked, timeout; 318 319 /* Are we using the interrupt? */ 320 irq_masked = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_1_MASK); 321 irq_masked &= WM831X_AUXADC_DATA_EINT; 322 323 mutex_lock(&wm831x->auxadc_lock); 324 325 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 326 WM831X_AUX_ENA, WM831X_AUX_ENA); 327 if (ret < 0) { 328 dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret); 329 goto out; 330 } 331 332 /* We force a single source at present */ 333 src = input; 334 ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE, 335 1 << src); 336 if (ret < 0) { 337 dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret); 338 goto out; 339 } 340 341 /* Clear any notification from a very late arriving interrupt */ 342 try_wait_for_completion(&wm831x->auxadc_done); 343 344 ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, 345 WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA); 346 if (ret < 0) { 347 dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret); 348 goto disable; 349 } 350 351 if (irq_masked) { 352 /* If we're not using interrupts then poll the 353 * interrupt status register */ 354 timeout = 5; 355 while (timeout) { 356 msleep(1); 357 358 ret = wm831x_reg_read(wm831x, 359 WM831X_INTERRUPT_STATUS_1); 360 if (ret < 0) { 361 dev_err(wm831x->dev, 362 "ISR 1 read failed: %d\n", ret); 363 goto disable; 364 } 365 366 /* Did it complete? */ 367 if (ret & WM831X_AUXADC_DATA_EINT) { 368 wm831x_reg_write(wm831x, 369 WM831X_INTERRUPT_STATUS_1, 370 WM831X_AUXADC_DATA_EINT); 371 break; 372 } else { 373 dev_err(wm831x->dev, 374 "AUXADC conversion timeout\n"); 375 ret = -EBUSY; 376 goto disable; 377 } 378 } 379 } else { 380 /* If we are using interrupts then wait for the 381 * interrupt to complete. Use an extremely long 382 * timeout to handle situations with heavy load where 383 * the notification of the interrupt may be delayed by 384 * threaded IRQ handling. */ 385 if (!wait_for_completion_timeout(&wm831x->auxadc_done, 386 msecs_to_jiffies(500))) { 387 dev_err(wm831x->dev, "Timed out waiting for AUXADC\n"); 388 ret = -EBUSY; 389 goto disable; 390 } 391 } 392 393 ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA); 394 if (ret < 0) { 395 dev_err(wm831x->dev, "Failed to read AUXADC data: %d\n", ret); 396 } else { 397 src = ((ret & WM831X_AUX_DATA_SRC_MASK) 398 >> WM831X_AUX_DATA_SRC_SHIFT) - 1; 399 400 if (src == 14) 401 src = WM831X_AUX_CAL; 402 403 if (src != input) { 404 dev_err(wm831x->dev, "Data from source %d not %d\n", 405 src, input); 406 ret = -EINVAL; 407 } else { 408 ret &= WM831X_AUX_DATA_MASK; 409 } 410 } 411 412 disable: 413 wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0); 414 out: 415 mutex_unlock(&wm831x->auxadc_lock); 416 return ret; 417 } 418 EXPORT_SYMBOL_GPL(wm831x_auxadc_read); 419 420 static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) 421 { 422 struct wm831x *wm831x = irq_data; 423 424 complete(&wm831x->auxadc_done); 425 426 return IRQ_HANDLED; 427 } 428 429 /** 430 * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC 431 * 432 * @wm831x: Device to read from. 433 * @input: AUXADC input to read. 434 */ 435 int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input) 436 { 437 int ret; 438 439 ret = wm831x_auxadc_read(wm831x, input); 440 if (ret < 0) 441 return ret; 442 443 ret *= 1465; 444 445 return ret; 446 } 447 EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv); 448 449 static struct resource wm831x_dcdc1_resources[] = { 450 { 451 .start = WM831X_DC1_CONTROL_1, 452 .end = WM831X_DC1_DVS_CONTROL, 453 .flags = IORESOURCE_IO, 454 }, 455 { 456 .name = "UV", 457 .start = WM831X_IRQ_UV_DC1, 458 .end = WM831X_IRQ_UV_DC1, 459 .flags = IORESOURCE_IRQ, 460 }, 461 { 462 .name = "HC", 463 .start = WM831X_IRQ_HC_DC1, 464 .end = WM831X_IRQ_HC_DC1, 465 .flags = IORESOURCE_IRQ, 466 }, 467 }; 468 469 470 static struct resource wm831x_dcdc2_resources[] = { 471 { 472 .start = WM831X_DC2_CONTROL_1, 473 .end = WM831X_DC2_DVS_CONTROL, 474 .flags = IORESOURCE_IO, 475 }, 476 { 477 .name = "UV", 478 .start = WM831X_IRQ_UV_DC2, 479 .end = WM831X_IRQ_UV_DC2, 480 .flags = IORESOURCE_IRQ, 481 }, 482 { 483 .name = "HC", 484 .start = WM831X_IRQ_HC_DC2, 485 .end = WM831X_IRQ_HC_DC2, 486 .flags = IORESOURCE_IRQ, 487 }, 488 }; 489 490 static struct resource wm831x_dcdc3_resources[] = { 491 { 492 .start = WM831X_DC3_CONTROL_1, 493 .end = WM831X_DC3_SLEEP_CONTROL, 494 .flags = IORESOURCE_IO, 495 }, 496 { 497 .name = "UV", 498 .start = WM831X_IRQ_UV_DC3, 499 .end = WM831X_IRQ_UV_DC3, 500 .flags = IORESOURCE_IRQ, 501 }, 502 }; 503 504 static struct resource wm831x_dcdc4_resources[] = { 505 { 506 .start = WM831X_DC4_CONTROL, 507 .end = WM831X_DC4_SLEEP_CONTROL, 508 .flags = IORESOURCE_IO, 509 }, 510 { 511 .name = "UV", 512 .start = WM831X_IRQ_UV_DC4, 513 .end = WM831X_IRQ_UV_DC4, 514 .flags = IORESOURCE_IRQ, 515 }, 516 }; 517 518 static struct resource wm8320_dcdc4_buck_resources[] = { 519 { 520 .start = WM831X_DC4_CONTROL, 521 .end = WM832X_DC4_SLEEP_CONTROL, 522 .flags = IORESOURCE_IO, 523 }, 524 { 525 .name = "UV", 526 .start = WM831X_IRQ_UV_DC4, 527 .end = WM831X_IRQ_UV_DC4, 528 .flags = IORESOURCE_IRQ, 529 }, 530 }; 531 532 static struct resource wm831x_gpio_resources[] = { 533 { 534 .start = WM831X_IRQ_GPIO_1, 535 .end = WM831X_IRQ_GPIO_16, 536 .flags = IORESOURCE_IRQ, 537 }, 538 }; 539 540 static struct resource wm831x_isink1_resources[] = { 541 { 542 .start = WM831X_CURRENT_SINK_1, 543 .end = WM831X_CURRENT_SINK_1, 544 .flags = IORESOURCE_IO, 545 }, 546 { 547 .start = WM831X_IRQ_CS1, 548 .end = WM831X_IRQ_CS1, 549 .flags = IORESOURCE_IRQ, 550 }, 551 }; 552 553 static struct resource wm831x_isink2_resources[] = { 554 { 555 .start = WM831X_CURRENT_SINK_2, 556 .end = WM831X_CURRENT_SINK_2, 557 .flags = IORESOURCE_IO, 558 }, 559 { 560 .start = WM831X_IRQ_CS2, 561 .end = WM831X_IRQ_CS2, 562 .flags = IORESOURCE_IRQ, 563 }, 564 }; 565 566 static struct resource wm831x_ldo1_resources[] = { 567 { 568 .start = WM831X_LDO1_CONTROL, 569 .end = WM831X_LDO1_SLEEP_CONTROL, 570 .flags = IORESOURCE_IO, 571 }, 572 { 573 .name = "UV", 574 .start = WM831X_IRQ_UV_LDO1, 575 .end = WM831X_IRQ_UV_LDO1, 576 .flags = IORESOURCE_IRQ, 577 }, 578 }; 579 580 static struct resource wm831x_ldo2_resources[] = { 581 { 582 .start = WM831X_LDO2_CONTROL, 583 .end = WM831X_LDO2_SLEEP_CONTROL, 584 .flags = IORESOURCE_IO, 585 }, 586 { 587 .name = "UV", 588 .start = WM831X_IRQ_UV_LDO2, 589 .end = WM831X_IRQ_UV_LDO2, 590 .flags = IORESOURCE_IRQ, 591 }, 592 }; 593 594 static struct resource wm831x_ldo3_resources[] = { 595 { 596 .start = WM831X_LDO3_CONTROL, 597 .end = WM831X_LDO3_SLEEP_CONTROL, 598 .flags = IORESOURCE_IO, 599 }, 600 { 601 .name = "UV", 602 .start = WM831X_IRQ_UV_LDO3, 603 .end = WM831X_IRQ_UV_LDO3, 604 .flags = IORESOURCE_IRQ, 605 }, 606 }; 607 608 static struct resource wm831x_ldo4_resources[] = { 609 { 610 .start = WM831X_LDO4_CONTROL, 611 .end = WM831X_LDO4_SLEEP_CONTROL, 612 .flags = IORESOURCE_IO, 613 }, 614 { 615 .name = "UV", 616 .start = WM831X_IRQ_UV_LDO4, 617 .end = WM831X_IRQ_UV_LDO4, 618 .flags = IORESOURCE_IRQ, 619 }, 620 }; 621 622 static struct resource wm831x_ldo5_resources[] = { 623 { 624 .start = WM831X_LDO5_CONTROL, 625 .end = WM831X_LDO5_SLEEP_CONTROL, 626 .flags = IORESOURCE_IO, 627 }, 628 { 629 .name = "UV", 630 .start = WM831X_IRQ_UV_LDO5, 631 .end = WM831X_IRQ_UV_LDO5, 632 .flags = IORESOURCE_IRQ, 633 }, 634 }; 635 636 static struct resource wm831x_ldo6_resources[] = { 637 { 638 .start = WM831X_LDO6_CONTROL, 639 .end = WM831X_LDO6_SLEEP_CONTROL, 640 .flags = IORESOURCE_IO, 641 }, 642 { 643 .name = "UV", 644 .start = WM831X_IRQ_UV_LDO6, 645 .end = WM831X_IRQ_UV_LDO6, 646 .flags = IORESOURCE_IRQ, 647 }, 648 }; 649 650 static struct resource wm831x_ldo7_resources[] = { 651 { 652 .start = WM831X_LDO7_CONTROL, 653 .end = WM831X_LDO7_SLEEP_CONTROL, 654 .flags = IORESOURCE_IO, 655 }, 656 { 657 .name = "UV", 658 .start = WM831X_IRQ_UV_LDO7, 659 .end = WM831X_IRQ_UV_LDO7, 660 .flags = IORESOURCE_IRQ, 661 }, 662 }; 663 664 static struct resource wm831x_ldo8_resources[] = { 665 { 666 .start = WM831X_LDO8_CONTROL, 667 .end = WM831X_LDO8_SLEEP_CONTROL, 668 .flags = IORESOURCE_IO, 669 }, 670 { 671 .name = "UV", 672 .start = WM831X_IRQ_UV_LDO8, 673 .end = WM831X_IRQ_UV_LDO8, 674 .flags = IORESOURCE_IRQ, 675 }, 676 }; 677 678 static struct resource wm831x_ldo9_resources[] = { 679 { 680 .start = WM831X_LDO9_CONTROL, 681 .end = WM831X_LDO9_SLEEP_CONTROL, 682 .flags = IORESOURCE_IO, 683 }, 684 { 685 .name = "UV", 686 .start = WM831X_IRQ_UV_LDO9, 687 .end = WM831X_IRQ_UV_LDO9, 688 .flags = IORESOURCE_IRQ, 689 }, 690 }; 691 692 static struct resource wm831x_ldo10_resources[] = { 693 { 694 .start = WM831X_LDO10_CONTROL, 695 .end = WM831X_LDO10_SLEEP_CONTROL, 696 .flags = IORESOURCE_IO, 697 }, 698 { 699 .name = "UV", 700 .start = WM831X_IRQ_UV_LDO10, 701 .end = WM831X_IRQ_UV_LDO10, 702 .flags = IORESOURCE_IRQ, 703 }, 704 }; 705 706 static struct resource wm831x_ldo11_resources[] = { 707 { 708 .start = WM831X_LDO11_ON_CONTROL, 709 .end = WM831X_LDO11_SLEEP_CONTROL, 710 .flags = IORESOURCE_IO, 711 }, 712 }; 713 714 static struct resource wm831x_on_resources[] = { 715 { 716 .start = WM831X_IRQ_ON, 717 .end = WM831X_IRQ_ON, 718 .flags = IORESOURCE_IRQ, 719 }, 720 }; 721 722 723 static struct resource wm831x_power_resources[] = { 724 { 725 .name = "SYSLO", 726 .start = WM831X_IRQ_PPM_SYSLO, 727 .end = WM831X_IRQ_PPM_SYSLO, 728 .flags = IORESOURCE_IRQ, 729 }, 730 { 731 .name = "PWR SRC", 732 .start = WM831X_IRQ_PPM_PWR_SRC, 733 .end = WM831X_IRQ_PPM_PWR_SRC, 734 .flags = IORESOURCE_IRQ, 735 }, 736 { 737 .name = "USB CURR", 738 .start = WM831X_IRQ_PPM_USB_CURR, 739 .end = WM831X_IRQ_PPM_USB_CURR, 740 .flags = IORESOURCE_IRQ, 741 }, 742 { 743 .name = "BATT HOT", 744 .start = WM831X_IRQ_CHG_BATT_HOT, 745 .end = WM831X_IRQ_CHG_BATT_HOT, 746 .flags = IORESOURCE_IRQ, 747 }, 748 { 749 .name = "BATT COLD", 750 .start = WM831X_IRQ_CHG_BATT_COLD, 751 .end = WM831X_IRQ_CHG_BATT_COLD, 752 .flags = IORESOURCE_IRQ, 753 }, 754 { 755 .name = "BATT FAIL", 756 .start = WM831X_IRQ_CHG_BATT_FAIL, 757 .end = WM831X_IRQ_CHG_BATT_FAIL, 758 .flags = IORESOURCE_IRQ, 759 }, 760 { 761 .name = "OV", 762 .start = WM831X_IRQ_CHG_OV, 763 .end = WM831X_IRQ_CHG_OV, 764 .flags = IORESOURCE_IRQ, 765 }, 766 { 767 .name = "END", 768 .start = WM831X_IRQ_CHG_END, 769 .end = WM831X_IRQ_CHG_END, 770 .flags = IORESOURCE_IRQ, 771 }, 772 { 773 .name = "TO", 774 .start = WM831X_IRQ_CHG_TO, 775 .end = WM831X_IRQ_CHG_TO, 776 .flags = IORESOURCE_IRQ, 777 }, 778 { 779 .name = "MODE", 780 .start = WM831X_IRQ_CHG_MODE, 781 .end = WM831X_IRQ_CHG_MODE, 782 .flags = IORESOURCE_IRQ, 783 }, 784 { 785 .name = "START", 786 .start = WM831X_IRQ_CHG_START, 787 .end = WM831X_IRQ_CHG_START, 788 .flags = IORESOURCE_IRQ, 789 }, 790 }; 791 792 static struct resource wm831x_rtc_resources[] = { 793 { 794 .name = "PER", 795 .start = WM831X_IRQ_RTC_PER, 796 .end = WM831X_IRQ_RTC_PER, 797 .flags = IORESOURCE_IRQ, 798 }, 799 { 800 .name = "ALM", 801 .start = WM831X_IRQ_RTC_ALM, 802 .end = WM831X_IRQ_RTC_ALM, 803 .flags = IORESOURCE_IRQ, 804 }, 805 }; 806 807 static struct resource wm831x_status1_resources[] = { 808 { 809 .start = WM831X_STATUS_LED_1, 810 .end = WM831X_STATUS_LED_1, 811 .flags = IORESOURCE_IO, 812 }, 813 }; 814 815 static struct resource wm831x_status2_resources[] = { 816 { 817 .start = WM831X_STATUS_LED_2, 818 .end = WM831X_STATUS_LED_2, 819 .flags = IORESOURCE_IO, 820 }, 821 }; 822 823 static struct resource wm831x_touch_resources[] = { 824 { 825 .name = "TCHPD", 826 .start = WM831X_IRQ_TCHPD, 827 .end = WM831X_IRQ_TCHPD, 828 .flags = IORESOURCE_IRQ, 829 }, 830 { 831 .name = "TCHDATA", 832 .start = WM831X_IRQ_TCHDATA, 833 .end = WM831X_IRQ_TCHDATA, 834 .flags = IORESOURCE_IRQ, 835 }, 836 }; 837 838 static struct resource wm831x_wdt_resources[] = { 839 { 840 .start = WM831X_IRQ_WDOG_TO, 841 .end = WM831X_IRQ_WDOG_TO, 842 .flags = IORESOURCE_IRQ, 843 }, 844 }; 845 846 static struct mfd_cell wm8310_devs[] = { 847 { 848 .name = "wm831x-backup", 849 }, 850 { 851 .name = "wm831x-buckv", 852 .id = 1, 853 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), 854 .resources = wm831x_dcdc1_resources, 855 }, 856 { 857 .name = "wm831x-buckv", 858 .id = 2, 859 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), 860 .resources = wm831x_dcdc2_resources, 861 }, 862 { 863 .name = "wm831x-buckp", 864 .id = 3, 865 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), 866 .resources = wm831x_dcdc3_resources, 867 }, 868 { 869 .name = "wm831x-boostp", 870 .id = 4, 871 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), 872 .resources = wm831x_dcdc4_resources, 873 }, 874 { 875 .name = "wm831x-epe", 876 .id = 1, 877 }, 878 { 879 .name = "wm831x-epe", 880 .id = 2, 881 }, 882 { 883 .name = "wm831x-gpio", 884 .num_resources = ARRAY_SIZE(wm831x_gpio_resources), 885 .resources = wm831x_gpio_resources, 886 }, 887 { 888 .name = "wm831x-hwmon", 889 }, 890 { 891 .name = "wm831x-isink", 892 .id = 1, 893 .num_resources = ARRAY_SIZE(wm831x_isink1_resources), 894 .resources = wm831x_isink1_resources, 895 }, 896 { 897 .name = "wm831x-isink", 898 .id = 2, 899 .num_resources = ARRAY_SIZE(wm831x_isink2_resources), 900 .resources = wm831x_isink2_resources, 901 }, 902 { 903 .name = "wm831x-ldo", 904 .id = 1, 905 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), 906 .resources = wm831x_ldo1_resources, 907 }, 908 { 909 .name = "wm831x-ldo", 910 .id = 2, 911 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), 912 .resources = wm831x_ldo2_resources, 913 }, 914 { 915 .name = "wm831x-ldo", 916 .id = 3, 917 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), 918 .resources = wm831x_ldo3_resources, 919 }, 920 { 921 .name = "wm831x-ldo", 922 .id = 4, 923 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), 924 .resources = wm831x_ldo4_resources, 925 }, 926 { 927 .name = "wm831x-ldo", 928 .id = 5, 929 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), 930 .resources = wm831x_ldo5_resources, 931 }, 932 { 933 .name = "wm831x-ldo", 934 .id = 6, 935 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), 936 .resources = wm831x_ldo6_resources, 937 }, 938 { 939 .name = "wm831x-aldo", 940 .id = 7, 941 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), 942 .resources = wm831x_ldo7_resources, 943 }, 944 { 945 .name = "wm831x-aldo", 946 .id = 8, 947 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), 948 .resources = wm831x_ldo8_resources, 949 }, 950 { 951 .name = "wm831x-aldo", 952 .id = 9, 953 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), 954 .resources = wm831x_ldo9_resources, 955 }, 956 { 957 .name = "wm831x-aldo", 958 .id = 10, 959 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), 960 .resources = wm831x_ldo10_resources, 961 }, 962 { 963 .name = "wm831x-alive-ldo", 964 .id = 11, 965 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), 966 .resources = wm831x_ldo11_resources, 967 }, 968 { 969 .name = "wm831x-on", 970 .num_resources = ARRAY_SIZE(wm831x_on_resources), 971 .resources = wm831x_on_resources, 972 }, 973 { 974 .name = "wm831x-power", 975 .num_resources = ARRAY_SIZE(wm831x_power_resources), 976 .resources = wm831x_power_resources, 977 }, 978 { 979 .name = "wm831x-rtc", 980 .num_resources = ARRAY_SIZE(wm831x_rtc_resources), 981 .resources = wm831x_rtc_resources, 982 }, 983 { 984 .name = "wm831x-status", 985 .id = 1, 986 .num_resources = ARRAY_SIZE(wm831x_status1_resources), 987 .resources = wm831x_status1_resources, 988 }, 989 { 990 .name = "wm831x-status", 991 .id = 2, 992 .num_resources = ARRAY_SIZE(wm831x_status2_resources), 993 .resources = wm831x_status2_resources, 994 }, 995 { 996 .name = "wm831x-watchdog", 997 .num_resources = ARRAY_SIZE(wm831x_wdt_resources), 998 .resources = wm831x_wdt_resources, 999 }, 1000 }; 1001 1002 static struct mfd_cell wm8311_devs[] = { 1003 { 1004 .name = "wm831x-backup", 1005 }, 1006 { 1007 .name = "wm831x-buckv", 1008 .id = 1, 1009 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), 1010 .resources = wm831x_dcdc1_resources, 1011 }, 1012 { 1013 .name = "wm831x-buckv", 1014 .id = 2, 1015 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), 1016 .resources = wm831x_dcdc2_resources, 1017 }, 1018 { 1019 .name = "wm831x-buckp", 1020 .id = 3, 1021 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), 1022 .resources = wm831x_dcdc3_resources, 1023 }, 1024 { 1025 .name = "wm831x-boostp", 1026 .id = 4, 1027 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), 1028 .resources = wm831x_dcdc4_resources, 1029 }, 1030 { 1031 .name = "wm831x-epe", 1032 .id = 1, 1033 }, 1034 { 1035 .name = "wm831x-epe", 1036 .id = 2, 1037 }, 1038 { 1039 .name = "wm831x-gpio", 1040 .num_resources = ARRAY_SIZE(wm831x_gpio_resources), 1041 .resources = wm831x_gpio_resources, 1042 }, 1043 { 1044 .name = "wm831x-hwmon", 1045 }, 1046 { 1047 .name = "wm831x-isink", 1048 .id = 1, 1049 .num_resources = ARRAY_SIZE(wm831x_isink1_resources), 1050 .resources = wm831x_isink1_resources, 1051 }, 1052 { 1053 .name = "wm831x-isink", 1054 .id = 2, 1055 .num_resources = ARRAY_SIZE(wm831x_isink2_resources), 1056 .resources = wm831x_isink2_resources, 1057 }, 1058 { 1059 .name = "wm831x-ldo", 1060 .id = 1, 1061 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), 1062 .resources = wm831x_ldo1_resources, 1063 }, 1064 { 1065 .name = "wm831x-ldo", 1066 .id = 2, 1067 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), 1068 .resources = wm831x_ldo2_resources, 1069 }, 1070 { 1071 .name = "wm831x-ldo", 1072 .id = 3, 1073 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), 1074 .resources = wm831x_ldo3_resources, 1075 }, 1076 { 1077 .name = "wm831x-ldo", 1078 .id = 4, 1079 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), 1080 .resources = wm831x_ldo4_resources, 1081 }, 1082 { 1083 .name = "wm831x-ldo", 1084 .id = 5, 1085 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), 1086 .resources = wm831x_ldo5_resources, 1087 }, 1088 { 1089 .name = "wm831x-aldo", 1090 .id = 7, 1091 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), 1092 .resources = wm831x_ldo7_resources, 1093 }, 1094 { 1095 .name = "wm831x-alive-ldo", 1096 .id = 11, 1097 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), 1098 .resources = wm831x_ldo11_resources, 1099 }, 1100 { 1101 .name = "wm831x-on", 1102 .num_resources = ARRAY_SIZE(wm831x_on_resources), 1103 .resources = wm831x_on_resources, 1104 }, 1105 { 1106 .name = "wm831x-power", 1107 .num_resources = ARRAY_SIZE(wm831x_power_resources), 1108 .resources = wm831x_power_resources, 1109 }, 1110 { 1111 .name = "wm831x-rtc", 1112 .num_resources = ARRAY_SIZE(wm831x_rtc_resources), 1113 .resources = wm831x_rtc_resources, 1114 }, 1115 { 1116 .name = "wm831x-status", 1117 .id = 1, 1118 .num_resources = ARRAY_SIZE(wm831x_status1_resources), 1119 .resources = wm831x_status1_resources, 1120 }, 1121 { 1122 .name = "wm831x-status", 1123 .id = 2, 1124 .num_resources = ARRAY_SIZE(wm831x_status2_resources), 1125 .resources = wm831x_status2_resources, 1126 }, 1127 { 1128 .name = "wm831x-touch", 1129 .num_resources = ARRAY_SIZE(wm831x_touch_resources), 1130 .resources = wm831x_touch_resources, 1131 }, 1132 { 1133 .name = "wm831x-watchdog", 1134 .num_resources = ARRAY_SIZE(wm831x_wdt_resources), 1135 .resources = wm831x_wdt_resources, 1136 }, 1137 }; 1138 1139 static struct mfd_cell wm8312_devs[] = { 1140 { 1141 .name = "wm831x-backup", 1142 }, 1143 { 1144 .name = "wm831x-buckv", 1145 .id = 1, 1146 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), 1147 .resources = wm831x_dcdc1_resources, 1148 }, 1149 { 1150 .name = "wm831x-buckv", 1151 .id = 2, 1152 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), 1153 .resources = wm831x_dcdc2_resources, 1154 }, 1155 { 1156 .name = "wm831x-buckp", 1157 .id = 3, 1158 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), 1159 .resources = wm831x_dcdc3_resources, 1160 }, 1161 { 1162 .name = "wm831x-boostp", 1163 .id = 4, 1164 .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources), 1165 .resources = wm831x_dcdc4_resources, 1166 }, 1167 { 1168 .name = "wm831x-epe", 1169 .id = 1, 1170 }, 1171 { 1172 .name = "wm831x-epe", 1173 .id = 2, 1174 }, 1175 { 1176 .name = "wm831x-gpio", 1177 .num_resources = ARRAY_SIZE(wm831x_gpio_resources), 1178 .resources = wm831x_gpio_resources, 1179 }, 1180 { 1181 .name = "wm831x-hwmon", 1182 }, 1183 { 1184 .name = "wm831x-isink", 1185 .id = 1, 1186 .num_resources = ARRAY_SIZE(wm831x_isink1_resources), 1187 .resources = wm831x_isink1_resources, 1188 }, 1189 { 1190 .name = "wm831x-isink", 1191 .id = 2, 1192 .num_resources = ARRAY_SIZE(wm831x_isink2_resources), 1193 .resources = wm831x_isink2_resources, 1194 }, 1195 { 1196 .name = "wm831x-ldo", 1197 .id = 1, 1198 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), 1199 .resources = wm831x_ldo1_resources, 1200 }, 1201 { 1202 .name = "wm831x-ldo", 1203 .id = 2, 1204 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), 1205 .resources = wm831x_ldo2_resources, 1206 }, 1207 { 1208 .name = "wm831x-ldo", 1209 .id = 3, 1210 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), 1211 .resources = wm831x_ldo3_resources, 1212 }, 1213 { 1214 .name = "wm831x-ldo", 1215 .id = 4, 1216 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), 1217 .resources = wm831x_ldo4_resources, 1218 }, 1219 { 1220 .name = "wm831x-ldo", 1221 .id = 5, 1222 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), 1223 .resources = wm831x_ldo5_resources, 1224 }, 1225 { 1226 .name = "wm831x-ldo", 1227 .id = 6, 1228 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), 1229 .resources = wm831x_ldo6_resources, 1230 }, 1231 { 1232 .name = "wm831x-aldo", 1233 .id = 7, 1234 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), 1235 .resources = wm831x_ldo7_resources, 1236 }, 1237 { 1238 .name = "wm831x-aldo", 1239 .id = 8, 1240 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), 1241 .resources = wm831x_ldo8_resources, 1242 }, 1243 { 1244 .name = "wm831x-aldo", 1245 .id = 9, 1246 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), 1247 .resources = wm831x_ldo9_resources, 1248 }, 1249 { 1250 .name = "wm831x-aldo", 1251 .id = 10, 1252 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), 1253 .resources = wm831x_ldo10_resources, 1254 }, 1255 { 1256 .name = "wm831x-alive-ldo", 1257 .id = 11, 1258 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), 1259 .resources = wm831x_ldo11_resources, 1260 }, 1261 { 1262 .name = "wm831x-on", 1263 .num_resources = ARRAY_SIZE(wm831x_on_resources), 1264 .resources = wm831x_on_resources, 1265 }, 1266 { 1267 .name = "wm831x-power", 1268 .num_resources = ARRAY_SIZE(wm831x_power_resources), 1269 .resources = wm831x_power_resources, 1270 }, 1271 { 1272 .name = "wm831x-rtc", 1273 .num_resources = ARRAY_SIZE(wm831x_rtc_resources), 1274 .resources = wm831x_rtc_resources, 1275 }, 1276 { 1277 .name = "wm831x-status", 1278 .id = 1, 1279 .num_resources = ARRAY_SIZE(wm831x_status1_resources), 1280 .resources = wm831x_status1_resources, 1281 }, 1282 { 1283 .name = "wm831x-status", 1284 .id = 2, 1285 .num_resources = ARRAY_SIZE(wm831x_status2_resources), 1286 .resources = wm831x_status2_resources, 1287 }, 1288 { 1289 .name = "wm831x-touch", 1290 .num_resources = ARRAY_SIZE(wm831x_touch_resources), 1291 .resources = wm831x_touch_resources, 1292 }, 1293 { 1294 .name = "wm831x-watchdog", 1295 .num_resources = ARRAY_SIZE(wm831x_wdt_resources), 1296 .resources = wm831x_wdt_resources, 1297 }, 1298 }; 1299 1300 static struct mfd_cell wm8320_devs[] = { 1301 { 1302 .name = "wm831x-backup", 1303 }, 1304 { 1305 .name = "wm831x-buckv", 1306 .id = 1, 1307 .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources), 1308 .resources = wm831x_dcdc1_resources, 1309 }, 1310 { 1311 .name = "wm831x-buckv", 1312 .id = 2, 1313 .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources), 1314 .resources = wm831x_dcdc2_resources, 1315 }, 1316 { 1317 .name = "wm831x-buckp", 1318 .id = 3, 1319 .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources), 1320 .resources = wm831x_dcdc3_resources, 1321 }, 1322 { 1323 .name = "wm831x-buckp", 1324 .id = 4, 1325 .num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources), 1326 .resources = wm8320_dcdc4_buck_resources, 1327 }, 1328 { 1329 .name = "wm831x-gpio", 1330 .num_resources = ARRAY_SIZE(wm831x_gpio_resources), 1331 .resources = wm831x_gpio_resources, 1332 }, 1333 { 1334 .name = "wm831x-hwmon", 1335 }, 1336 { 1337 .name = "wm831x-ldo", 1338 .id = 1, 1339 .num_resources = ARRAY_SIZE(wm831x_ldo1_resources), 1340 .resources = wm831x_ldo1_resources, 1341 }, 1342 { 1343 .name = "wm831x-ldo", 1344 .id = 2, 1345 .num_resources = ARRAY_SIZE(wm831x_ldo2_resources), 1346 .resources = wm831x_ldo2_resources, 1347 }, 1348 { 1349 .name = "wm831x-ldo", 1350 .id = 3, 1351 .num_resources = ARRAY_SIZE(wm831x_ldo3_resources), 1352 .resources = wm831x_ldo3_resources, 1353 }, 1354 { 1355 .name = "wm831x-ldo", 1356 .id = 4, 1357 .num_resources = ARRAY_SIZE(wm831x_ldo4_resources), 1358 .resources = wm831x_ldo4_resources, 1359 }, 1360 { 1361 .name = "wm831x-ldo", 1362 .id = 5, 1363 .num_resources = ARRAY_SIZE(wm831x_ldo5_resources), 1364 .resources = wm831x_ldo5_resources, 1365 }, 1366 { 1367 .name = "wm831x-ldo", 1368 .id = 6, 1369 .num_resources = ARRAY_SIZE(wm831x_ldo6_resources), 1370 .resources = wm831x_ldo6_resources, 1371 }, 1372 { 1373 .name = "wm831x-aldo", 1374 .id = 7, 1375 .num_resources = ARRAY_SIZE(wm831x_ldo7_resources), 1376 .resources = wm831x_ldo7_resources, 1377 }, 1378 { 1379 .name = "wm831x-aldo", 1380 .id = 8, 1381 .num_resources = ARRAY_SIZE(wm831x_ldo8_resources), 1382 .resources = wm831x_ldo8_resources, 1383 }, 1384 { 1385 .name = "wm831x-aldo", 1386 .id = 9, 1387 .num_resources = ARRAY_SIZE(wm831x_ldo9_resources), 1388 .resources = wm831x_ldo9_resources, 1389 }, 1390 { 1391 .name = "wm831x-aldo", 1392 .id = 10, 1393 .num_resources = ARRAY_SIZE(wm831x_ldo10_resources), 1394 .resources = wm831x_ldo10_resources, 1395 }, 1396 { 1397 .name = "wm831x-alive-ldo", 1398 .id = 11, 1399 .num_resources = ARRAY_SIZE(wm831x_ldo11_resources), 1400 .resources = wm831x_ldo11_resources, 1401 }, 1402 { 1403 .name = "wm831x-on", 1404 .num_resources = ARRAY_SIZE(wm831x_on_resources), 1405 .resources = wm831x_on_resources, 1406 }, 1407 { 1408 .name = "wm831x-rtc", 1409 .num_resources = ARRAY_SIZE(wm831x_rtc_resources), 1410 .resources = wm831x_rtc_resources, 1411 }, 1412 { 1413 .name = "wm831x-status", 1414 .id = 1, 1415 .num_resources = ARRAY_SIZE(wm831x_status1_resources), 1416 .resources = wm831x_status1_resources, 1417 }, 1418 { 1419 .name = "wm831x-status", 1420 .id = 2, 1421 .num_resources = ARRAY_SIZE(wm831x_status2_resources), 1422 .resources = wm831x_status2_resources, 1423 }, 1424 { 1425 .name = "wm831x-watchdog", 1426 .num_resources = ARRAY_SIZE(wm831x_wdt_resources), 1427 .resources = wm831x_wdt_resources, 1428 }, 1429 }; 1430 1431 static struct mfd_cell backlight_devs[] = { 1432 { 1433 .name = "wm831x-backlight", 1434 }, 1435 }; 1436 1437 /* 1438 * Instantiate the generic non-control parts of the device. 1439 */ 1440 int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) 1441 { 1442 struct wm831x_pdata *pdata = wm831x->dev->platform_data; 1443 int rev; 1444 enum wm831x_parent parent; 1445 int ret, i; 1446 1447 mutex_init(&wm831x->io_lock); 1448 mutex_init(&wm831x->key_lock); 1449 mutex_init(&wm831x->auxadc_lock); 1450 init_completion(&wm831x->auxadc_done); 1451 dev_set_drvdata(wm831x->dev, wm831x); 1452 1453 ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); 1454 if (ret < 0) { 1455 dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); 1456 goto err; 1457 } 1458 switch (ret) { 1459 case 0x6204: 1460 case 0x6246: 1461 break; 1462 default: 1463 dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); 1464 ret = -EINVAL; 1465 goto err; 1466 } 1467 1468 ret = wm831x_reg_read(wm831x, WM831X_REVISION); 1469 if (ret < 0) { 1470 dev_err(wm831x->dev, "Failed to read revision: %d\n", ret); 1471 goto err; 1472 } 1473 rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT; 1474 1475 ret = wm831x_reg_read(wm831x, WM831X_RESET_ID); 1476 if (ret < 0) { 1477 dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret); 1478 goto err; 1479 } 1480 1481 /* Some engineering samples do not have the ID set, rely on 1482 * the device being registered correctly. 1483 */ 1484 if (ret == 0) { 1485 dev_info(wm831x->dev, "Device is an engineering sample\n"); 1486 ret = id; 1487 } 1488 1489 switch (ret) { 1490 case WM8310: 1491 parent = WM8310; 1492 wm831x->num_gpio = 16; 1493 wm831x->charger_irq_wake = 1; 1494 if (rev > 0) { 1495 wm831x->has_gpio_ena = 1; 1496 wm831x->has_cs_sts = 1; 1497 } 1498 1499 dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev); 1500 break; 1501 1502 case WM8311: 1503 parent = WM8311; 1504 wm831x->num_gpio = 16; 1505 wm831x->charger_irq_wake = 1; 1506 if (rev > 0) { 1507 wm831x->has_gpio_ena = 1; 1508 wm831x->has_cs_sts = 1; 1509 } 1510 1511 dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev); 1512 break; 1513 1514 case WM8312: 1515 parent = WM8312; 1516 wm831x->num_gpio = 16; 1517 wm831x->charger_irq_wake = 1; 1518 if (rev > 0) { 1519 wm831x->has_gpio_ena = 1; 1520 wm831x->has_cs_sts = 1; 1521 } 1522 1523 dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev); 1524 break; 1525 1526 case WM8320: 1527 parent = WM8320; 1528 wm831x->num_gpio = 12; 1529 dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev); 1530 break; 1531 1532 case WM8321: 1533 parent = WM8321; 1534 wm831x->num_gpio = 12; 1535 dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev); 1536 break; 1537 1538 case WM8325: 1539 parent = WM8325; 1540 wm831x->num_gpio = 12; 1541 dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); 1542 break; 1543 1544 case WM8326: 1545 parent = WM8326; 1546 wm831x->num_gpio = 12; 1547 dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev); 1548 break; 1549 1550 default: 1551 dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); 1552 ret = -EINVAL; 1553 goto err; 1554 } 1555 1556 /* This will need revisiting in future but is OK for all 1557 * current parts. 1558 */ 1559 if (parent != id) 1560 dev_warn(wm831x->dev, "Device was registered as a WM%lx\n", 1561 id); 1562 1563 /* Bootstrap the user key */ 1564 ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY); 1565 if (ret < 0) { 1566 dev_err(wm831x->dev, "Failed to read security key: %d\n", ret); 1567 goto err; 1568 } 1569 if (ret != 0) { 1570 dev_warn(wm831x->dev, "Security key had non-zero value %x\n", 1571 ret); 1572 wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0); 1573 } 1574 wm831x->locked = 1; 1575 1576 if (pdata && pdata->pre_init) { 1577 ret = pdata->pre_init(wm831x); 1578 if (ret != 0) { 1579 dev_err(wm831x->dev, "pre_init() failed: %d\n", ret); 1580 goto err; 1581 } 1582 } 1583 1584 if (pdata) { 1585 for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { 1586 if (!pdata->gpio_defaults[i]) 1587 continue; 1588 1589 wm831x_reg_write(wm831x, 1590 WM831X_GPIO1_CONTROL + i, 1591 pdata->gpio_defaults[i] & 0xffff); 1592 } 1593 } 1594 1595 ret = wm831x_irq_init(wm831x, irq); 1596 if (ret != 0) 1597 goto err; 1598 1599 if (wm831x->irq_base) { 1600 ret = request_threaded_irq(wm831x->irq_base + 1601 WM831X_IRQ_AUXADC_DATA, 1602 NULL, wm831x_auxadc_irq, 0, 1603 "auxadc", wm831x); 1604 if (ret < 0) 1605 dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", 1606 ret); 1607 } 1608 1609 /* The core device is up, instantiate the subdevices. */ 1610 switch (parent) { 1611 case WM8310: 1612 ret = mfd_add_devices(wm831x->dev, -1, 1613 wm8310_devs, ARRAY_SIZE(wm8310_devs), 1614 NULL, wm831x->irq_base); 1615 break; 1616 1617 case WM8311: 1618 ret = mfd_add_devices(wm831x->dev, -1, 1619 wm8311_devs, ARRAY_SIZE(wm8311_devs), 1620 NULL, wm831x->irq_base); 1621 break; 1622 1623 case WM8312: 1624 ret = mfd_add_devices(wm831x->dev, -1, 1625 wm8312_devs, ARRAY_SIZE(wm8312_devs), 1626 NULL, wm831x->irq_base); 1627 break; 1628 1629 case WM8320: 1630 case WM8321: 1631 case WM8325: 1632 case WM8326: 1633 ret = mfd_add_devices(wm831x->dev, -1, 1634 wm8320_devs, ARRAY_SIZE(wm8320_devs), 1635 NULL, wm831x->irq_base); 1636 break; 1637 1638 default: 1639 /* If this happens the bus probe function is buggy */ 1640 BUG(); 1641 } 1642 1643 if (ret != 0) { 1644 dev_err(wm831x->dev, "Failed to add children\n"); 1645 goto err_irq; 1646 } 1647 1648 if (pdata && pdata->backlight) { 1649 /* Treat errors as non-critical */ 1650 ret = mfd_add_devices(wm831x->dev, -1, backlight_devs, 1651 ARRAY_SIZE(backlight_devs), NULL, 1652 wm831x->irq_base); 1653 if (ret < 0) 1654 dev_err(wm831x->dev, "Failed to add backlight: %d\n", 1655 ret); 1656 } 1657 1658 wm831x_otp_init(wm831x); 1659 1660 if (pdata && pdata->post_init) { 1661 ret = pdata->post_init(wm831x); 1662 if (ret != 0) { 1663 dev_err(wm831x->dev, "post_init() failed: %d\n", ret); 1664 goto err_irq; 1665 } 1666 } 1667 1668 return 0; 1669 1670 err_irq: 1671 wm831x_irq_exit(wm831x); 1672 err: 1673 mfd_remove_devices(wm831x->dev); 1674 kfree(wm831x); 1675 return ret; 1676 } 1677 1678 void wm831x_device_exit(struct wm831x *wm831x) 1679 { 1680 wm831x_otp_exit(wm831x); 1681 mfd_remove_devices(wm831x->dev); 1682 if (wm831x->irq_base) 1683 free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); 1684 wm831x_irq_exit(wm831x); 1685 kfree(wm831x); 1686 } 1687 1688 int wm831x_device_suspend(struct wm831x *wm831x) 1689 { 1690 int reg, mask; 1691 1692 /* If the charger IRQs are a wake source then make sure we ack 1693 * them even if they're not actively being used (eg, no power 1694 * driver or no IRQ line wired up) then acknowledge the 1695 * interrupts otherwise suspend won't last very long. 1696 */ 1697 if (wm831x->charger_irq_wake) { 1698 reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK); 1699 1700 mask = WM831X_CHG_BATT_HOT_EINT | 1701 WM831X_CHG_BATT_COLD_EINT | 1702 WM831X_CHG_BATT_FAIL_EINT | 1703 WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT | 1704 WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT | 1705 WM831X_CHG_START_EINT; 1706 1707 /* If any of the interrupts are masked read the statuses */ 1708 if (reg & mask) 1709 reg = wm831x_reg_read(wm831x, 1710 WM831X_INTERRUPT_STATUS_2); 1711 1712 if (reg & mask) { 1713 dev_info(wm831x->dev, 1714 "Acknowledging masked charger IRQs: %x\n", 1715 reg & mask); 1716 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2, 1717 reg & mask); 1718 } 1719 } 1720 1721 return 0; 1722 } 1723 1724 MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); 1725 MODULE_LICENSE("GPL"); 1726 MODULE_AUTHOR("Mark Brown"); 1727