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