^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // wm8350.c -- Voltage and current regulation for the Wolfson WM8350 PMIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright 2007, 2008 Wolfson Microelectronics PLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Author: Liam Girdwood
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // linux@wolfsonmicro.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mfd/wm8350/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mfd/wm8350/pmic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* Maximum value possible for VSEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define WM8350_DCDC_MAX_VSEL 0x66
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* Microamps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static const unsigned int isink_cur[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 39,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 46,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 54,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 65,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 77,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 92,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 109,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 130,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 154,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 183,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 218,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 259,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 308,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) 367,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 436,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 518,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 616,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 733,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 872,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 1037,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 1233,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 1466,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 1744,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 2073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 2466,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 2933,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 3487,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 4147,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 4932,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 5865,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 6975,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 8294,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 9864,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 11730,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 13949,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 16589,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 19728,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 23460,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 27899,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 33178,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 39455,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 46920,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 55798,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 66355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 78910,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 93840,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 111596,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 132710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 157820,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 187681,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 223191
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* turn on ISINK followed by DCDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static int wm8350_isink_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) int isink = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) switch (wm8350->pmic.isink_A_dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) WM8350_CS1_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) wm8350_set_bits(wm8350, WM8350_CSA_FLASH_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) WM8350_CS1_DRIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 1 << (wm8350->pmic.isink_A_dcdc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) WM8350_DCDC_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) switch (wm8350->pmic.isink_B_dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) wm8350_set_bits(wm8350, WM8350_POWER_MGMT_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) WM8350_CS2_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) wm8350_set_bits(wm8350, WM8350_CSB_FLASH_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) WM8350_CS2_DRIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) wm8350_set_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 1 << (wm8350->pmic.isink_B_dcdc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) WM8350_DCDC_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int wm8350_isink_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int isink = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) switch (wm8350->pmic.isink_A_dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 1 << (wm8350->pmic.isink_A_dcdc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) WM8350_DCDC_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) WM8350_CS1_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) switch (wm8350->pmic.isink_B_dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) wm8350_clear_bits(wm8350, WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 1 << (wm8350->pmic.isink_B_dcdc -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) WM8350_DCDC_1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) WM8350_CS2_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static int wm8350_isink_is_enabled(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int isink = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_A) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 0x8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return wm8350_reg_read(wm8350, WM8350_CURRENT_SINK_DRIVER_B) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 0x8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int wm8350_isink_enable_time(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int isink = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) reg = wm8350_reg_read(wm8350, WM8350_CSA_FLASH_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) reg = wm8350_reg_read(wm8350, WM8350_CSB_FLASH_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (reg & WM8350_CS1_FLASH_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) switch (reg & WM8350_CS1_ON_RAMP_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 1950;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return 3910;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 7800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) switch (reg & WM8350_CS1_ON_RAMP_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 250000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return 500000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) u16 trigger, u16 duration, u16 on_ramp, u16 off_ramp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u16 drive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) wm8350_reg_write(wm8350, WM8350_CSA_FLASH_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (mode ? WM8350_CS1_FLASH_MODE : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) (trigger ? WM8350_CS1_TRIGSRC : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) duration | on_ramp | off_ramp | drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) wm8350_reg_write(wm8350, WM8350_CSB_FLASH_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (mode ? WM8350_CS2_FLASH_MODE : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) (trigger ? WM8350_CS2_TRIGSRC : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) duration | on_ramp | off_ramp | drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) EXPORT_SYMBOL_GPL(wm8350_isink_set_flash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int sel, volt_reg, dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, dcdc, uV / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) volt_reg = WM8350_DCDC1_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) volt_reg = WM8350_DCDC3_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) volt_reg = WM8350_DCDC4_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) volt_reg = WM8350_DCDC6_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) sel = regulator_map_voltage_linear(rdev, uV, uV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /* all DCDCs have same mV bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_DC1_VSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) wm8350_reg_write(wm8350, volt_reg, val | sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int wm8350_dcdc_set_suspend_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) & ~WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) val | wm8350->pmic.dcdc1_hib_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) & ~WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) val | wm8350->pmic.dcdc3_hib_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) & ~WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) val | wm8350->pmic.dcdc4_hib_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) & ~WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) val | wm8350->pmic.dcdc6_hib_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static int wm8350_dcdc_set_suspend_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) wm8350_reg_write(wm8350, WM8350_DCDC1_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) val | WM8350_DCDC_HIB_MODE_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) wm8350_reg_write(wm8350, WM8350_DCDC3_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) val | WM8350_DCDC_HIB_MODE_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) wm8350_reg_write(wm8350, WM8350_DCDC4_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) val | WM8350_DCDC_HIB_MODE_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) wm8350_reg_write(wm8350, WM8350_DCDC6_LOW_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) val | WM8350_DCDC_HIB_MODE_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int wm8350_dcdc25_set_suspend_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) & ~WM8350_DC2_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) (WM8350_DC2_HIB_MODE_ACTIVE << WM8350_DC2_HIB_MODE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) & ~WM8350_DC5_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) (WM8350_DC5_HIB_MODE_ACTIVE << WM8350_DC5_HIB_MODE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static int wm8350_dcdc25_set_suspend_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) & ~WM8350_DC2_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) (WM8350_DC2_HIB_MODE_DISABLE << WM8350_DC2_HIB_MODE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) & ~WM8350_DC5_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) (WM8350_DC5_HIB_MODE_DISABLE << WM8350_DC5_HIB_MODE_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) u16 *hib_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) hib_mode = &wm8350->pmic.dcdc1_hib_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) hib_mode = &wm8350->pmic.dcdc3_hib_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) hib_mode = &wm8350->pmic.dcdc4_hib_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) hib_mode = &wm8350->pmic.dcdc6_hib_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *hib_mode = WM8350_DCDC_HIB_MODE_IMAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case REGULATOR_MODE_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) *hib_mode = WM8350_DCDC_HIB_MODE_STANDBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case REGULATOR_MODE_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) *hib_mode = WM8350_DCDC_HIB_MODE_LDO_IM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static const struct linear_range wm8350_ldo_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) REGULATOR_LINEAR_RANGE(900000, 0, 15, 50000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) REGULATOR_LINEAR_RANGE(1800000, 16, 31, 100000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int sel, volt_reg, ldo = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) dev_dbg(wm8350->dev, "%s %d mV %d\n", __func__, ldo, uV / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) switch (ldo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case WM8350_LDO_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) volt_reg = WM8350_LDO1_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) case WM8350_LDO_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) volt_reg = WM8350_LDO2_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case WM8350_LDO_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) volt_reg = WM8350_LDO3_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case WM8350_LDO_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) volt_reg = WM8350_LDO4_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) sel = regulator_map_voltage_linear_range(rdev, uV, uV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (sel < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* all LDOs have same mV bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_VSEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) wm8350_reg_write(wm8350, volt_reg, val | sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static int wm8350_ldo_set_suspend_enable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int volt_reg, ldo = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) switch (ldo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) case WM8350_LDO_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) volt_reg = WM8350_LDO1_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) case WM8350_LDO_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) volt_reg = WM8350_LDO2_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) case WM8350_LDO_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) volt_reg = WM8350_LDO3_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) case WM8350_LDO_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) volt_reg = WM8350_LDO4_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* all LDOs have same mV bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) wm8350_reg_write(wm8350, volt_reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int wm8350_ldo_set_suspend_disable(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int volt_reg, ldo = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) switch (ldo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) case WM8350_LDO_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) volt_reg = WM8350_LDO1_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case WM8350_LDO_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) volt_reg = WM8350_LDO2_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) case WM8350_LDO_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) volt_reg = WM8350_LDO3_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) case WM8350_LDO_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) volt_reg = WM8350_LDO4_LOW_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* all LDOs have same mV bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) val = wm8350_reg_read(wm8350, volt_reg) & ~WM8350_LDO1_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) wm8350_reg_write(wm8350, volt_reg, val | WM8350_LDO1_HIB_MODE_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u16 stop, u16 fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int slot_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __func__, dcdc, start, stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* slot valid ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (start > 15 || stop > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) slot_reg = WM8350_DCDC1_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) slot_reg = WM8350_DCDC2_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) slot_reg = WM8350_DCDC3_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) slot_reg = WM8350_DCDC4_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) slot_reg = WM8350_DCDC5_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) slot_reg = WM8350_DCDC6_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) val = wm8350_reg_read(wm8350, slot_reg) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ~(WM8350_DC1_ENSLOT_MASK | WM8350_DC1_SDSLOT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) WM8350_DC1_ERRACT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) wm8350_reg_write(wm8350, slot_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) val | (start << WM8350_DC1_ENSLOT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) (stop << WM8350_DC1_SDSLOT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) (fault << WM8350_DC1_ERRACT_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) EXPORT_SYMBOL_GPL(wm8350_dcdc_set_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) int slot_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev_dbg(wm8350->dev, "%s %d start %d stop %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) __func__, ldo, start, stop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* slot valid ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (start > 15 || stop > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) switch (ldo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case WM8350_LDO_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) slot_reg = WM8350_LDO1_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case WM8350_LDO_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) slot_reg = WM8350_LDO2_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case WM8350_LDO_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) slot_reg = WM8350_LDO3_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) case WM8350_LDO_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) slot_reg = WM8350_LDO4_TIMEOUTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) val = wm8350_reg_read(wm8350, slot_reg) & ~WM8350_LDO1_SDSLOT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) wm8350_reg_write(wm8350, slot_reg, val | ((start << 10) | (stop << 6)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) EXPORT_SYMBOL_GPL(wm8350_ldo_set_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) u16 ilim, u16 ramp, u16 feedback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev_dbg(wm8350->dev, "%s %d mode: %s %s\n", __func__, dcdc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) mode ? "normal" : "boost", ilim ? "low" : "normal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case WM8350_DCDC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) val = wm8350_reg_read(wm8350, WM8350_DCDC2_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) & ~(WM8350_DC2_MODE_MASK | WM8350_DC2_ILIM_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) WM8350_DC2_RMP_MASK | WM8350_DC2_FBSRC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) wm8350_reg_write(wm8350, WM8350_DCDC2_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) (mode << WM8350_DC2_MODE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) (ilim << WM8350_DC2_ILIM_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) (ramp << WM8350_DC2_RMP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) (feedback << WM8350_DC2_FBSRC_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case WM8350_DCDC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) val = wm8350_reg_read(wm8350, WM8350_DCDC5_CONTROL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) & ~(WM8350_DC5_MODE_MASK | WM8350_DC5_ILIM_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) WM8350_DC5_RMP_MASK | WM8350_DC5_FBSRC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) wm8350_reg_write(wm8350, WM8350_DCDC5_CONTROL, val |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) (mode << WM8350_DC5_MODE_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) (ilim << WM8350_DC5_ILIM_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) (ramp << WM8350_DC5_RMP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) (feedback << WM8350_DC5_FBSRC_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) EXPORT_SYMBOL_GPL(wm8350_dcdc25_set_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static int force_continuous_enable(struct wm8350 *wm8350, int dcdc, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) int reg = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) reg = WM8350_DCDC1_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) reg = WM8350_DCDC3_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) reg = WM8350_DCDC4_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) reg = WM8350_DCDC6_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ret = wm8350_set_bits(wm8350, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) WM8350_DCDC1_FORCE_PWM_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ret = wm8350_clear_bits(wm8350, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) WM8350_DCDC1_FORCE_PWM_ENA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int wm8350_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) val = 1 << (dcdc - WM8350_DCDC_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case REGULATOR_MODE_FAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* force continuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) force_continuous_enable(wm8350, dcdc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) case REGULATOR_MODE_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* active / pulse skipping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) wm8350_set_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) force_continuous_enable(wm8350, dcdc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case REGULATOR_MODE_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) /* standby mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) force_continuous_enable(wm8350, dcdc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) wm8350_clear_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) wm8350_clear_bits(wm8350, WM8350_DCDC_ACTIVE_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) case REGULATOR_MODE_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* LDO mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) force_continuous_enable(wm8350, dcdc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) wm8350_set_bits(wm8350, WM8350_DCDC_SLEEP_OPTIONS, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) int dcdc = rdev_get_id(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) u16 mask, sleep, active, force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) int mode = REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) reg = WM8350_DCDC1_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) reg = WM8350_DCDC3_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) reg = WM8350_DCDC4_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) reg = WM8350_DCDC6_FORCE_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) mask = 1 << (dcdc - WM8350_DCDC_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) mask, active, sleep, force);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (active && !sleep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mode = REGULATOR_MODE_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) mode = REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) } else if (!active && !sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) mode = REGULATOR_MODE_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) else if (sleep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) mode = REGULATOR_MODE_STANDBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static unsigned int wm8350_ldo_get_mode(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct wm8350_dcdc_efficiency {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int uA_load_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int uA_load_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static const struct wm8350_dcdc_efficiency dcdc1_6_efficiency[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {100000, 1000000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {-1, -1, REGULATOR_MODE_NORMAL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static const struct wm8350_dcdc_efficiency dcdc3_4_efficiency[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {0, 10000, REGULATOR_MODE_STANDBY}, /* 0 - 10mA - LDO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {10000, 100000, REGULATOR_MODE_IDLE}, /* 10mA - 100mA - Standby */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {100000, 800000, REGULATOR_MODE_NORMAL}, /* > 100mA - Active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) {-1, -1, REGULATOR_MODE_NORMAL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static unsigned int get_mode(int uA, const struct wm8350_dcdc_efficiency *eff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) while (eff[i].uA_load_min != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (uA >= eff[i].uA_load_min && uA <= eff[i].uA_load_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return eff[i].mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* Query the regulator for it's most efficient mode @ uV,uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * WM8350 regulator efficiency is pretty similar over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * different input and output uV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) static unsigned int wm8350_dcdc_get_optimum_mode(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int input_uV, int output_uV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int output_uA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int dcdc = rdev_get_id(rdev), mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) switch (dcdc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) mode = get_mode(output_uA, dcdc1_6_efficiency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) mode = get_mode(output_uA, dcdc3_4_efficiency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) mode = REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static const struct regulator_ops wm8350_dcdc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) .list_voltage = regulator_list_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .map_voltage = regulator_map_voltage_linear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .get_mode = wm8350_dcdc_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) .set_mode = wm8350_dcdc_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .get_optimum_mode = wm8350_dcdc_get_optimum_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .set_suspend_voltage = wm8350_dcdc_set_suspend_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .set_suspend_enable = wm8350_dcdc_set_suspend_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .set_suspend_disable = wm8350_dcdc_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .set_suspend_mode = wm8350_dcdc_set_suspend_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static const struct regulator_ops wm8350_dcdc2_5_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .set_suspend_enable = wm8350_dcdc25_set_suspend_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .set_suspend_disable = wm8350_dcdc25_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static const struct regulator_ops wm8350_ldo_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .map_voltage = regulator_map_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .set_voltage_sel = regulator_set_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .get_voltage_sel = regulator_get_voltage_sel_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .list_voltage = regulator_list_voltage_linear_range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .enable = regulator_enable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .disable = regulator_disable_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .is_enabled = regulator_is_enabled_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .get_mode = wm8350_ldo_get_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .set_suspend_voltage = wm8350_ldo_set_suspend_voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .set_suspend_enable = wm8350_ldo_set_suspend_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .set_suspend_disable = wm8350_ldo_set_suspend_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) static const struct regulator_ops wm8350_isink_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .set_current_limit = regulator_set_current_limit_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .get_current_limit = regulator_get_current_limit_regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .enable = wm8350_isink_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .disable = wm8350_isink_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .is_enabled = wm8350_isink_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .enable_time = wm8350_isink_enable_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .name = "DCDC1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .id = WM8350_DCDC_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .ops = &wm8350_dcdc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .irq = WM8350_IRQ_UV_DC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .min_uV = 850000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .uV_step = 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .vsel_reg = WM8350_DCDC1_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .vsel_mask = WM8350_DC1_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .enable_mask = WM8350_DC1_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .name = "DCDC2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .id = WM8350_DCDC_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .ops = &wm8350_dcdc2_5_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .irq = WM8350_IRQ_UV_DC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .enable_mask = WM8350_DC2_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .name = "DCDC3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .id = WM8350_DCDC_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .ops = &wm8350_dcdc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .irq = WM8350_IRQ_UV_DC3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .min_uV = 850000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .uV_step = 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .vsel_reg = WM8350_DCDC3_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .vsel_mask = WM8350_DC3_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .enable_mask = WM8350_DC3_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .name = "DCDC4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .id = WM8350_DCDC_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .ops = &wm8350_dcdc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .irq = WM8350_IRQ_UV_DC4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .min_uV = 850000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .uV_step = 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .vsel_reg = WM8350_DCDC4_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .vsel_mask = WM8350_DC4_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .enable_mask = WM8350_DC4_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .name = "DCDC5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .id = WM8350_DCDC_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .ops = &wm8350_dcdc2_5_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .irq = WM8350_IRQ_UV_DC5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .enable_mask = WM8350_DC5_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .name = "DCDC6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .id = WM8350_DCDC_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .ops = &wm8350_dcdc_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .irq = WM8350_IRQ_UV_DC6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .min_uV = 850000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .uV_step = 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .vsel_reg = WM8350_DCDC6_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .vsel_mask = WM8350_DC6_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .enable_mask = WM8350_DC6_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .name = "LDO1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .id = WM8350_LDO_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .ops = &wm8350_ldo_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .irq = WM8350_IRQ_UV_LDO1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .linear_ranges = wm8350_ldo_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .vsel_reg = WM8350_LDO1_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .vsel_mask = WM8350_LDO1_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .enable_mask = WM8350_LDO1_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .name = "LDO2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .id = WM8350_LDO_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .ops = &wm8350_ldo_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .irq = WM8350_IRQ_UV_LDO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .linear_ranges = wm8350_ldo_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .vsel_reg = WM8350_LDO2_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .vsel_mask = WM8350_LDO2_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .enable_mask = WM8350_LDO2_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .name = "LDO3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .id = WM8350_LDO_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .ops = &wm8350_ldo_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .irq = WM8350_IRQ_UV_LDO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .linear_ranges = wm8350_ldo_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .vsel_reg = WM8350_LDO3_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .vsel_mask = WM8350_LDO3_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .enable_mask = WM8350_LDO3_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .name = "LDO4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .id = WM8350_LDO_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .ops = &wm8350_ldo_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .irq = WM8350_IRQ_UV_LDO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .linear_ranges = wm8350_ldo_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .vsel_reg = WM8350_LDO4_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .vsel_mask = WM8350_LDO4_VSEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .enable_reg = WM8350_DCDC_LDO_REQUESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .enable_mask = WM8350_LDO4_ENA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .name = "ISINKA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .id = WM8350_ISINK_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .ops = &wm8350_isink_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .irq = WM8350_IRQ_CS1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .type = REGULATOR_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .curr_table = isink_cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .n_current_limits = ARRAY_SIZE(isink_cur),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .csel_reg = WM8350_CURRENT_SINK_DRIVER_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) .csel_mask = WM8350_CS1_ISEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) .name = "ISINKB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) .id = WM8350_ISINK_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) .ops = &wm8350_isink_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .irq = WM8350_IRQ_CS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .type = REGULATOR_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .curr_table = isink_cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .n_current_limits = ARRAY_SIZE(isink_cur),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .csel_reg = WM8350_CURRENT_SINK_DRIVER_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .csel_mask = WM8350_CS2_ISEL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static irqreturn_t pmic_uv_handler(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct regulator_dev *rdev = (struct regulator_dev *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) regulator_notifier_call_chain(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) REGULATOR_EVENT_REGULATION_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) regulator_notifier_call_chain(rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) REGULATOR_EVENT_UNDER_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static int wm8350_regulator_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct regulator_dev *rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* do any regulatior specific init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) switch (pdev->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) case WM8350_DCDC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) case WM8350_DCDC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) case WM8350_DCDC_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) case WM8350_DCDC_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) config.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) config.init_data = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) config.driver_data = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) config.regmap = wm8350->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /* register regulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) rdev = devm_regulator_register(&pdev->dev, &wm8350_reg[pdev->id],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (IS_ERR(rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) dev_err(&pdev->dev, "failed to register %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) wm8350_reg[pdev->id].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return PTR_ERR(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* register regulator IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) pmic_uv_handler, 0, "UV", rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) dev_err(&pdev->dev, "failed to register regulator %s IRQ\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) wm8350_reg[pdev->id].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static int wm8350_regulator_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct regulator_dev *rdev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) int wm8350_register_regulator(struct wm8350 *wm8350, int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct regulator_init_data *initdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (reg < 0 || reg >= NUM_WM8350_REGULATORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (wm8350->pmic.pdev[reg])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (reg >= WM8350_DCDC_1 && reg <= WM8350_DCDC_6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) reg > wm8350->pmic.max_dcdc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (reg >= WM8350_ISINK_A && reg <= WM8350_ISINK_B &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) reg > wm8350->pmic.max_isink)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) pdev = platform_device_alloc("wm8350-regulator", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) wm8350->pmic.pdev[reg] = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) initdata->driver_data = wm8350;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) pdev->dev.platform_data = initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) pdev->dev.parent = wm8350->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) platform_set_drvdata(pdev, wm8350);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ret = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dev_err(wm8350->dev, "Failed to register regulator %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) wm8350->pmic.pdev[reg] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) EXPORT_SYMBOL_GPL(wm8350_register_regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * wm8350_register_led - Register a WM8350 LED output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * @wm8350: The WM8350 device to configure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * @lednum: LED device index to create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * @dcdc: The DCDC to use for the LED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * @isink: The ISINK to use for the LED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * @pdata: Configuration for the LED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * The WM8350 supports the use of an ISINK together with a DCDC to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * provide a power-efficient LED driver. This function registers the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * regulators and instantiates the platform device for a LED. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * operating modes for the LED regulators must be configured using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * wm8350_isink_set_flash(), wm8350_dcdc25_set_mode() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * wm8350_dcdc_set_slot() prior to calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct wm8350_led_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct wm8350_led *led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (lednum >= ARRAY_SIZE(wm8350->pmic.led) || lednum < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) dev_err(wm8350->dev, "Invalid LED index %d\n", lednum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) led = &wm8350->pmic.led[lednum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (led->pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) dev_err(wm8350->dev, "LED %d already allocated\n", lednum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) pdev = platform_device_alloc("wm8350-led", lednum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (pdev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) dev_err(wm8350->dev, "Failed to allocate LED %d\n", lednum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) led->isink_consumer.dev_name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) led->isink_consumer.supply = "led_isink";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) led->isink_init.num_consumer_supplies = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) led->isink_init.consumer_supplies = &led->isink_consumer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) led->isink_init.constraints.min_uA = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) led->isink_init.constraints.max_uA = pdata->max_uA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) led->isink_init.constraints.valid_ops_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) led->isink_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) ret = wm8350_register_regulator(wm8350, isink, &led->isink_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) led->dcdc_consumer.dev_name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) led->dcdc_consumer.supply = "led_vcc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) led->dcdc_init.num_consumer_supplies = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) led->dcdc_init.consumer_supplies = &led->dcdc_consumer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) led->dcdc_init.constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) led->dcdc_init.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) ret = wm8350_register_regulator(wm8350, dcdc, &led->dcdc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) switch (isink) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) case WM8350_ISINK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) wm8350->pmic.isink_A_dcdc = dcdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) case WM8350_ISINK_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) wm8350->pmic.isink_B_dcdc = dcdc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) pdev->dev.platform_data = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) pdev->dev.parent = wm8350->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) ret = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) dev_err(wm8350->dev, "Failed to register LED %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) lednum, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) led->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) EXPORT_SYMBOL_GPL(wm8350_register_led);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static struct platform_driver wm8350_regulator_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .probe = wm8350_regulator_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .remove = wm8350_regulator_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .name = "wm8350-regulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static int __init wm8350_regulator_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) return platform_driver_register(&wm8350_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) subsys_initcall(wm8350_regulator_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static void __exit wm8350_regulator_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) platform_driver_unregister(&wm8350_regulator_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) module_exit(wm8350_regulator_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* Module information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) MODULE_AUTHOR("Liam Girdwood");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) MODULE_ALIAS("platform:wm8350-regulator");