Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
"Core framework:
- Add the MFD bindings doc to MAINTAINERS

New drivers:
- X-Powers AC100 Audio CODEC and RTC
- TI LP873x PMIC
- Rockchip RK808 PMIC
- Samsung Exynos Low Power Audio

New device support:
- Add support for STMPE1600 variant to stmpe
- Add support for PM8018 PMIC to pm8921-core
- Add support for AXP806 PMIC in axp20x
- Add support for AXP209 GPIO in axp20x

New functionality:
- Add support for Reset to all STMPE variants
- Add support for MKBP event support to cros_ec
- Add support for USB to intel_soc_pmic_bxtwc
- Add support for IRQs and Power Button to tps65217

Fix-ups:
- Clean-up defunct author emails (da9063, max14577)
- Kconfig fixups (wm8350-i2c, as37220
- Constify (altera-a10sr, sm501)
- Supply PCI IDs (intel-lpss-pci)
- Improve clocking (qcom_rpm)
- Fix IRQ probing (ucb1x00-core)
- Ensure fault log is cleared (da9052)
- Remove NO_IRQ check (ucb1x00-core)
- Supply I2C properties (intel-lpss-acpi, intel-lpss-pci)
- Non standard declaration (tps65217, max8997-irq)
- Remove unused code (lp873x, db8500-prcmu, ab8500-debugfs,
cros_ec_spi)
- Make non-modular (altera-a10sr, intel_msic, smsc-ece1099,
sun6i-prcm, twl-core)
- OF bindings (ac100, stmpe, qcom-pm8xxx, qcom-rpm, rk808, axp20x,
lp873x, exynos5433-lpass, act8945a, aspeed-scu, twl6040, arizona)

Bugfixes:
- Release OF pointer (qcom_rpm)
- Avoid double shifting in suspend/resume (88pm80x)
- Fix 'defined but not used' error (exynos-lpass)
- Fix 'sleeping whilst attomic' (atmel-hlcdc)"

* tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits)
mfd: arizona: Handle probe deferral for reset GPIO
mfd: arizona: Remove arizona_of_get_named_gpio helper function
mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config
mfd: twl6040: Register child device for twl6040-pdmclk
mfd: cros_ec_spi: Remove unused variable 'request'
mfd: omap-usb-host: Return value is not 'const int'
mfd: ab8500-debugfs: Remove 'weak' function suspend_test_wake_cause_interrupt_is_mine()
mfd: ab8500-debugfs: Remove ab8500_dump_all_banks_to_mem()
mfd: db8500-prcmu: Remove unused *prcmu_set_ddr_opp() calls
mfd: ab8500-debugfs: Prevent initialised field from being over-written
mfd: max8997-irq: 'inline' should be at the beginning of the declaration
mfd: rk808: Fix RK818_IRQ_DISCHG_ILIM initializer
mfd: tps65217: Fix nonstandard declaration
mfd: lp873x: Remove unused mutex lock from struct lp873x
mfd: atmel-hlcdc: Do not sleep in atomic context
mfd: exynos-lpass: Mark PM functions as __maybe_unused
mfd: intel-lpss: Add default I2C device properties for Apollo Lake
mfd: twl-core: Make it explicitly non-modular
mfd: sun6i-prcm: Make it explicitly non-modular
mfd: smsc-ece1099: Make it explicitly non-modular
...

+3123 -457
+54
Documentation/devicetree/bindings/mfd/ac100.txt
··· 1 + X-Powers AC100 Codec/RTC IC Device Tree bindings 2 + 3 + AC100 is a audio codec and RTC subsystem combo IC. The 2 parts are 4 + separated, including power supplies and interrupt lines, but share 5 + a common register address space and host interface. 6 + 7 + Required properties: 8 + - compatible: "x-powers,ac100" 9 + - reg: The I2C slave address or RSB hardware address for the chip 10 + - sub-nodes: 11 + - codec 12 + - compatible: "x-powers,ac100-codec" 13 + - interrupt-parent: The parent interrupt controller 14 + - interrupts: SoC NMI / GPIO interrupt connected to the 15 + IRQ_AUDIO pin 16 + - #clock-cells: Shall be 0 17 + - clock-output-names: "4M_adda" 18 + 19 + - see clock/clock-bindings.txt for common clock bindings 20 + 21 + - rtc 22 + - compatible: "x-powers,ac100-rtc" 23 + - interrupt-parent: The parent interrupt controller 24 + - interrupts: SoC NMI / GPIO interrupt connected to the 25 + IRQ_RTC pin 26 + - clocks: A phandle to the codec's "4M_adda" clock 27 + - #clock-cells: Shall be 1 28 + - clock-output-names: "cko1_rtc", "cko2_rtc", "cko3_rtc" 29 + 30 + - see clock/clock-bindings.txt for common clock bindings 31 + 32 + Example: 33 + 34 + ac100: codec@e89 { 35 + compatible = "x-powers,ac100"; 36 + reg = <0xe89>; 37 + 38 + ac100_codec: codec { 39 + compatible = "x-powers,ac100-codec"; 40 + interrupt-parent = <&r_pio>; 41 + interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PL9 */ 42 + #clock-cells = <0>; 43 + clock-output-names = "4M_adda"; 44 + }; 45 + 46 + ac100_rtc: rtc { 47 + compatible = "x-powers,ac100-rtc"; 48 + interrupt-parent = <&nmi_intc>; 49 + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; 50 + clocks = <&ac100_codec>; 51 + #clock-cells = <1>; 52 + clock-output-names = "cko1_rtc", "cko2_rtc", "cko3_rtc"; 53 + }; 54 + };
+15 -7
Documentation/devicetree/bindings/mfd/act8945a.txt
··· 14 14 reg = <0x5b>; 15 15 status = "okay"; 16 16 17 - pinctrl-names = "default"; 18 - pinctrl-0 = <&pinctrl_charger_chglev>; 19 - active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>; 20 - active-semi,input-voltage-threshold-microvolt = <6600>; 21 - active-semi,precondition-timeout = <40>; 22 - active-semi,total-timeout = <3>; 23 - 24 17 active-semi,vsel-high; 25 18 26 19 regulators { ··· 65 72 regulator-max-microvolt = <1800000>; 66 73 regulator-always-on; 67 74 }; 75 + }; 76 + 77 + charger { 78 + compatible = "active-semi,act8945a-charger"; 79 + pinctrl-names = "default"; 80 + pinctrl-0 = <&pinctrl_charger_chglev &pinctrl_charger_lbo &pinctrl_charger_irq>; 81 + interrupt-parent = <&pioA>; 82 + interrupts = <45 GPIO_ACTIVE_LOW>; 83 + 84 + active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>; 85 + active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>; 86 + active-semi,input-voltage-threshold-microvolt = <6600>; 87 + active-semi,precondition-timeout = <40>; 88 + active-semi,total-timeout = <3>; 89 + status = "okay"; 68 90 }; 69 91 };
+18
Documentation/devicetree/bindings/mfd/arizona.txt
··· 85 85 present, the number of values should be less than or equal to the 86 86 number of inputs, unspecified inputs will use the chip default. 87 87 88 + - wlf,max-channels-clocked : The maximum number of channels to be clocked on 89 + each AIF, useful for I2S systems with multiple data lines being mastered. 90 + Specify one cell for each AIF to be configured, specify zero for AIFs that 91 + should be handled normally. 92 + If present, number of cells must be less than or equal to the number of 93 + AIFs. If less than the number of AIFs, for cells that have not been 94 + specified the corresponding AIFs will be treated as default setting. 95 + 96 + - wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6). 97 + See the datasheet for values. 98 + The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997, 99 + wm8998, wm1814) 100 + 101 + - wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6). 102 + See the datasheet for values. 103 + The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997, 104 + wm8998, wm1814) 105 + 88 106 - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if 89 107 they are being externally supplied. As covered in 90 108 Documentation/devicetree/bindings/regulator/regulator.txt
+18
Documentation/devicetree/bindings/mfd/aspeed-scu.txt
··· 1 + The Aspeed System Control Unit manages the global behaviour of the SoC, 2 + configuring elements such as clocks, pinmux, and reset. 3 + 4 + Required properties: 5 + - compatible: One of: 6 + "aspeed,ast2400-scu", "syscon", "simple-mfd" 7 + "aspeed,g4-scu", "syscon", "simple-mfd" 8 + "aspeed,ast2500-scu", "syscon", "simple-mfd" 9 + "aspeed,g5-scu", "syscon", "simple-mfd" 10 + 11 + - reg: contains the offset and length of the SCU memory region 12 + 13 + Example: 14 + 15 + syscon: syscon@1e6e2000 { 16 + compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd"; 17 + reg = <0x1e6e2000 0x1a8>; 18 + };
+26 -2
Documentation/devicetree/bindings/mfd/axp20x.txt
··· 10 10 11 11 Required properties: 12 12 - compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209", 13 - "x-powers,axp221", "x-powers,axp223", "x-powers,axp809" 13 + "x-powers,axp221", "x-powers,axp223", "x-powers,axp806", 14 + "x-powers,axp809" 14 15 - reg: The I2C slave address or RSB hardware address for the AXP chip 15 16 - interrupt-parent: The parent interrupt controller 16 17 - interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin ··· 47 46 under light loads for lower output noise. This 48 47 probably makes sense for HiFi audio related 49 48 applications that aren't battery constrained. 50 - 51 49 52 50 AXP202/AXP209 regulators, type, and corresponding input supply names: 53 51 ··· 85 85 LDO_IO1 : LDO : ips-supply : GPIO 1 86 86 RTC_LDO : LDO : ips-supply : always on 87 87 DRIVEVBUS : Enable output : drivevbus-supply : external regulator 88 + 89 + AXP806 regulators, type, and corresponding input supply names: 90 + 91 + Regulator Type Supply Name Notes 92 + --------- ---- ----------- ----- 93 + DCDCA : DC-DC buck : vina-supply : poly-phase capable 94 + DCDCB : DC-DC buck : vinb-supply : poly-phase capable 95 + DCDCC : DC-DC buck : vinc-supply : poly-phase capable 96 + DCDCD : DC-DC buck : vind-supply : poly-phase capable 97 + DCDCE : DC-DC buck : vine-supply : poly-phase capable 98 + ALDO1 : LDO : aldoin-supply : shared supply 99 + ALDO2 : LDO : aldoin-supply : shared supply 100 + ALDO3 : LDO : aldoin-supply : shared supply 101 + BLDO1 : LDO : bldoin-supply : shared supply 102 + BLDO2 : LDO : bldoin-supply : shared supply 103 + BLDO3 : LDO : bldoin-supply : shared supply 104 + BLDO4 : LDO : bldoin-supply : shared supply 105 + CLDO1 : LDO : cldoin-supply : shared supply 106 + CLDO2 : LDO : cldoin-supply : shared supply 107 + CLDO3 : LDO : cldoin-supply : shared supply 108 + SW : On/Off Switch : swin-supply 109 + 110 + Additionally, the AXP806 DC-DC regulators support poly-phase arrangements 111 + for higher output current. The possible groupings are: A+B, A+B+C, D+E. 88 112 89 113 AXP809 regulators, type, and corresponding input supply names: 90 114
+59
Documentation/devicetree/bindings/mfd/lp873x.txt
··· 1 + TI LP873X PMIC MFD driver 2 + 3 + Required properties: 4 + - compatible: "ti,lp8732", "ti,lp8733" 5 + - reg: I2C slave address. 6 + - gpio-controller: Marks the device node as a GPIO Controller. 7 + - #gpio-cells: Should be two. The first cell is the pin number and 8 + the second cell is used to specify flags. 9 + See ../gpio/gpio.txt for more information. 10 + - regulators: List of child nodes that specify the regulator 11 + initialization data. 12 + Example: 13 + 14 + pmic: lp8733@60 { 15 + compatible = "ti,lp8733"; 16 + reg = <0x60>; 17 + gpio-controller; 18 + #gpio-cells = <2>; 19 + 20 + regulators { 21 + lp8733_buck0: buck0 { 22 + regulator-name = "lp8733-buck0"; 23 + regulator-min-microvolt = <800000>; 24 + regulator-max-microvolt = <1400000>; 25 + regulator-min-microamp = <1500000>; 26 + regulator-max-microamp = <4000000>; 27 + regulator-ramp-delay = <10000>; 28 + regulator-always-on; 29 + regulator-boot-on; 30 + }; 31 + 32 + lp8733_buck1: buck1 { 33 + regulator-name = "lp8733-buck1"; 34 + regulator-min-microvolt = <800000>; 35 + regulator-max-microvolt = <1400000>; 36 + regulator-min-microamp = <1500000>; 37 + regulator-max-microamp = <4000000>; 38 + regulator-ramp-delay = <10000>; 39 + regulator-boot-on; 40 + regulator-always-on; 41 + }; 42 + 43 + lp8733_ldo0: ldo0 { 44 + regulator-name = "lp8733-ldo0"; 45 + regulator-min-microvolt = <800000>; 46 + regulator-max-microvolt = <3000000>; 47 + regulator-boot-on; 48 + regulator-always-on; 49 + }; 50 + 51 + lp8733_ldo1: ldo1 { 52 + regulator-name = "lp8733-ldo1"; 53 + regulator-min-microvolt = <800000>; 54 + regulator-max-microvolt = <3000000>; 55 + regulator-always-on; 56 + regulator-boot-on; 57 + }; 58 + }; 59 + };
+1
Documentation/devicetree/bindings/mfd/qcom-pm8xxx.txt
··· 62 62 "qcom,pm8058-rtc" 63 63 "qcom,pm8921-rtc" 64 64 "qcom,pm8941-rtc" 65 + "qcom,pm8018-rtc" 65 66 66 67 - reg: 67 68 Usage: required
+15
Documentation/devicetree/bindings/mfd/qcom-rpm.txt
··· 13 13 "qcom,rpm-msm8660" 14 14 "qcom,rpm-msm8960" 15 15 "qcom,rpm-ipq8064" 16 + "qcom,rpm-mdm9615" 16 17 17 18 - reg: 18 19 Usage: required ··· 60 59 "qcom,rpm-pm8058-regulators" 61 60 "qcom,rpm-pm8901-regulators" 62 61 "qcom,rpm-pm8921-regulators" 62 + "qcom,rpm-pm8018-regulators" 63 63 64 64 - vdd_l0_l1_lvs-supply: 65 65 - vdd_l2_l11_l12-supply: ··· 139 137 Definition: reference to regulator supplying the input pin, as 140 138 described in the data sheet 141 139 140 + - vin_lvs1-supply: 141 + - vdd_l7-supply: 142 + - vdd_l8-supply: 143 + - vdd_l9_l10_l11_l12-supply: 144 + Usage: optional (pm8018 only) 145 + Value type: <phandle> 146 + Definition: reference to regulator supplying the input pin, as 147 + described in the data sheet 148 + 142 149 The regulator node houses sub-nodes for each regulator within the device. Each 143 150 sub-node is identified using the node's name, with valid values listed for each 144 151 of the pmics below. ··· 166 155 l12, l14, l15, l16, l17, l18, l21, l22, l23, l24, l25, l26, l27, l28, 167 156 l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch, 168 157 ncp 158 + 159 + pm8018: 160 + s1, s2, s3, s4, s5, , l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, 161 + l12, l14, lvs1 169 162 170 163 The content of each sub-node is defined by the standard binding for regulators - 171 164 see regulator.txt - with additional custom properties described below:
+34 -3
Documentation/devicetree/bindings/mfd/rk808.txt
··· 1 - RK808 Power Management Integrated Circuit 1 + RK8XX Power Management Integrated Circuit 2 + 3 + The rk8xx family current members: 4 + rk808 5 + rk818 2 6 3 7 Required properties: 4 - - compatible: "rockchip,rk808" 8 + - compatible: "rockchip,rk808", "rockchip,rk818" 5 9 - reg: I2C slave address 6 10 - interrupt-parent: The parent interrupt controller. 7 11 - interrupts: the interrupt outputs of the controller. ··· 17 13 default output clock name 18 14 - rockchip,system-power-controller: Telling whether or not this pmic is controlling 19 15 the system power. 16 + 17 + Optional RK808 properties: 20 18 - vcc1-supply: The input supply for DCDC_REG1 21 19 - vcc2-supply: The input supply for DCDC_REG2 22 20 - vcc3-supply: The input supply for DCDC_REG3 ··· 35 29 the gpio controller. If DVS GPIOs aren't present, voltage changes will happen 36 30 very quickly with no slow ramp time. 37 31 38 - Regulators: All the regulators of RK808 to be instantiated shall be 32 + Optional RK818 properties: 33 + - vcc1-supply: The input supply for DCDC_REG1 34 + - vcc2-supply: The input supply for DCDC_REG2 35 + - vcc3-supply: The input supply for DCDC_REG3 36 + - vcc4-supply: The input supply for DCDC_REG4 37 + - boost-supply: The input supply for DCDC_BOOST 38 + - vcc6-supply: The input supply for LDO_REG1 and LDO_REG2 39 + - vcc7-supply: The input supply for LDO_REG3, LDO_REG5 and LDO_REG7 40 + - vcc8-supply: The input supply for LDO_REG4, LDO_REG6 and LDO_REG8 41 + - vcc9-supply: The input supply for LDO_REG9 and SWITCH_REG 42 + - h_5v-supply: The input supply for HDMI_SWITCH 43 + - usb-supply: The input supply for OTG_SWITCH 44 + 45 + Regulators: All the regulators of RK8XX to be instantiated shall be 39 46 listed in a child node named 'regulators'. Each regulator is represented 40 47 by a child node of the 'regulators' node. 41 48 ··· 66 47 - valid values for n are 1 to 8. 67 48 - SWITCH_REGn 68 49 - valid values for n are 1 to 2 50 + 51 + Following regulators of the RK818 PMIC block are supported. Note that 52 + the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO 53 + number as described in RK818 datasheet. 54 + 55 + - DCDC_REGn 56 + - valid values for n are 1 to 4. 57 + - LDO_REGn 58 + - valid values for n are 1 to 9. 59 + - SWITCH_REG 60 + - HDMI_SWITCH 61 + - OTG_SWITCH 69 62 70 63 Standard regulator bindings are used inside regulator subnodes. Check 71 64 Documentation/devicetree/bindings/regulator/regulator.txt
+70
Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
··· 1 + Samsung Exynos SoC Low Power Audio Subsystem (LPASS) 2 + 3 + Required properties: 4 + 5 + - compatible : "samsung,exynos5433-lpass" 6 + - reg : should contain the LPASS top SFR region location 7 + and size 8 + - samsung,pmu-syscon : the phandle to the Power Management Unit node 9 + - #address-cells : should be 1 10 + - #size-cells : should be 1 11 + - ranges : must be present 12 + 13 + Each IP block of the Low Power Audio Subsystem should be specified as 14 + an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes: 15 + UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices. 16 + 17 + Bindings of the sub-nodes are described in: 18 + ../serial/samsung_uart.txt 19 + ../sound/samsung-i2s.txt 20 + ../dma/arm-pl330.txt 21 + 22 + 23 + Example: 24 + 25 + audio-subsystem { 26 + compatible = "samsung,exynos5433-lpass"; 27 + reg = <0x11400000 0x100>, <0x11500000 0x08>; 28 + samsung,pmu-syscon = <&pmu_system_controller>; 29 + #address-cells = <1>; 30 + #size-cells = <1>; 31 + ranges; 32 + 33 + adma: adma@11420000 { 34 + compatible = "arm,pl330", "arm,primecell"; 35 + reg = <0x11420000 0x1000>; 36 + interrupts = <0 73 0>; 37 + clocks = <&cmu_aud CLK_ACLK_DMAC>; 38 + clock-names = "apb_pclk"; 39 + #dma-cells = <1>; 40 + #dma-channels = <8>; 41 + #dma-requests = <32>; 42 + }; 43 + 44 + i2s0: i2s0@11440000 { 45 + compatible = "samsung,exynos7-i2s"; 46 + reg = <0x11440000 0x100>; 47 + dmas = <&adma 0 &adma 2>; 48 + dma-names = "tx", "rx"; 49 + interrupts = <0 70 0>; 50 + clocks = <&cmu_aud CLK_PCLK_AUD_I2S>, 51 + <&cmu_aud CLK_SCLK_AUD_I2S>, 52 + <&cmu_aud CLK_SCLK_I2S_BCLK>; 53 + clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; 54 + pinctrl-names = "default"; 55 + pinctrl-0 = <&i2s0_bus>; 56 + status = "disabled"; 57 + }; 58 + 59 + serial_3: serial@11460000 { 60 + compatible = "samsung,exynos5433-uart"; 61 + reg = <0x11460000 0x100>; 62 + interrupts = <0 67 0>; 63 + clocks = <&cmu_aud CLK_PCLK_AUD_UART>, 64 + <&cmu_aud CLK_SCLK_AUD_UART>; 65 + clock-names = "uart", "clk_uart_baud0"; 66 + pinctrl-names = "default"; 67 + pinctrl-0 = <&uart_aud_bus>; 68 + status = "disabled"; 69 + }; 70 + };
+1
Documentation/devicetree/bindings/mfd/twl6040.txt
··· 12 12 - interrupt-parent: The parent interrupt controller 13 13 - gpio-controller: 14 14 - #gpio-cells = <1>: twl6040 provides GPO lines. 15 + - #clock-cells = <0>; twl6040 is a provider of pdmclk which is used by McPDM 15 16 - twl6040,audpwron-gpio: Power on GPIO line for the twl6040 16 17 17 18 - vio-supply: Regulator for the twl6040 VIO supply
+1
MAINTAINERS
··· 8098 8098 M: Lee Jones <lee.jones@linaro.org> 8099 8099 T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git 8100 8100 S: Supported 8101 + F: Documentation/devicetree/bindings/mfd/ 8101 8102 F: drivers/mfd/ 8102 8103 F: include/linux/mfd/ 8103 8104
+32 -105
drivers/input/keyboard/cros_ec_keyb.c
··· 27 27 #include <linux/input.h> 28 28 #include <linux/interrupt.h> 29 29 #include <linux/kernel.h> 30 + #include <linux/notifier.h> 30 31 #include <linux/platform_device.h> 31 32 #include <linux/slab.h> 32 33 #include <linux/input/matrix_keypad.h> ··· 45 44 * @dev: Device pointer 46 45 * @idev: Input device 47 46 * @ec: Top level ChromeOS device to use to talk to EC 47 + * @notifier: interrupt event notifier for transport devices 48 48 */ 49 49 struct cros_ec_keyb { 50 50 unsigned int rows; ··· 59 57 struct device *dev; 60 58 struct input_dev *idev; 61 59 struct cros_ec_device *ec; 60 + struct notifier_block notifier; 62 61 }; 63 62 64 63 ··· 149 146 input_sync(ckdev->idev); 150 147 } 151 148 152 - static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) 153 - { 154 - int ret = 0; 155 - struct cros_ec_command *msg; 156 - 157 - msg = kmalloc(sizeof(*msg) + ckdev->cols, GFP_KERNEL); 158 - if (!msg) 159 - return -ENOMEM; 160 - 161 - msg->version = 0; 162 - msg->command = EC_CMD_MKBP_STATE; 163 - msg->insize = ckdev->cols; 164 - msg->outsize = 0; 165 - 166 - ret = cros_ec_cmd_xfer(ckdev->ec, msg); 167 - if (ret < 0) { 168 - dev_err(ckdev->dev, "Error transferring EC message %d\n", ret); 169 - goto exit; 170 - } 171 - 172 - memcpy(kb_state, msg->data, ckdev->cols); 173 - exit: 174 - kfree(msg); 175 - return ret; 176 - } 177 - 178 - static irqreturn_t cros_ec_keyb_irq(int irq, void *data) 179 - { 180 - struct cros_ec_keyb *ckdev = data; 181 - struct cros_ec_device *ec = ckdev->ec; 182 - int ret; 183 - uint8_t kb_state[ckdev->cols]; 184 - 185 - if (device_may_wakeup(ec->dev)) 186 - pm_wakeup_event(ec->dev, 0); 187 - 188 - ret = cros_ec_keyb_get_state(ckdev, kb_state); 189 - if (ret >= 0) 190 - cros_ec_keyb_process(ckdev, kb_state, ret); 191 - else 192 - dev_err(ckdev->dev, "failed to get keyboard state: %d\n", ret); 193 - 194 - return IRQ_HANDLED; 195 - } 196 - 197 149 static int cros_ec_keyb_open(struct input_dev *dev) 198 150 { 199 151 struct cros_ec_keyb *ckdev = input_get_drvdata(dev); 200 - struct cros_ec_device *ec = ckdev->ec; 201 152 202 - return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, 203 - IRQF_TRIGGER_LOW | IRQF_ONESHOT, 204 - "cros_ec_keyb", ckdev); 153 + return blocking_notifier_chain_register(&ckdev->ec->event_notifier, 154 + &ckdev->notifier); 205 155 } 206 156 207 157 static void cros_ec_keyb_close(struct input_dev *dev) 208 158 { 209 159 struct cros_ec_keyb *ckdev = input_get_drvdata(dev); 210 - struct cros_ec_device *ec = ckdev->ec; 211 160 212 - free_irq(ec->irq, ckdev); 161 + blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, 162 + &ckdev->notifier); 163 + } 164 + 165 + static int cros_ec_keyb_work(struct notifier_block *nb, 166 + unsigned long queued_during_suspend, void *_notify) 167 + { 168 + struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb, 169 + notifier); 170 + 171 + if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX) 172 + return NOTIFY_DONE; 173 + /* 174 + * If EC is not the wake source, discard key state changes during 175 + * suspend. 176 + */ 177 + if (queued_during_suspend) 178 + return NOTIFY_OK; 179 + if (ckdev->ec->event_size != ckdev->cols) { 180 + dev_err(ckdev->dev, 181 + "Discarded incomplete key matrix event.\n"); 182 + return NOTIFY_OK; 183 + } 184 + cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix, 185 + ckdev->ec->event_size); 186 + return NOTIFY_OK; 213 187 } 214 188 215 189 /* ··· 245 265 if (!idev) 246 266 return -ENOMEM; 247 267 248 - if (!ec->irq) { 249 - dev_err(dev, "no EC IRQ specified\n"); 250 - return -EINVAL; 251 - } 252 - 253 268 ckdev->ec = ec; 269 + ckdev->notifier.notifier_call = cros_ec_keyb_work; 254 270 ckdev->dev = dev; 255 271 dev_set_drvdata(dev, ckdev); 256 272 ··· 287 311 return 0; 288 312 } 289 313 290 - #ifdef CONFIG_PM_SLEEP 291 - /* Clear any keys in the buffer */ 292 - static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) 293 - { 294 - uint8_t old_state[ckdev->cols]; 295 - uint8_t new_state[ckdev->cols]; 296 - unsigned long duration; 297 - int i, ret; 298 - 299 - /* 300 - * Keep reading until we see that the scan state does not change. 301 - * That indicates that we are done. 302 - * 303 - * Assume that the EC keyscan buffer is at most 32 deep. 304 - */ 305 - duration = jiffies; 306 - ret = cros_ec_keyb_get_state(ckdev, new_state); 307 - for (i = 1; !ret && i < 32; i++) { 308 - memcpy(old_state, new_state, sizeof(old_state)); 309 - ret = cros_ec_keyb_get_state(ckdev, new_state); 310 - if (0 == memcmp(old_state, new_state, sizeof(old_state))) 311 - break; 312 - } 313 - duration = jiffies - duration; 314 - dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, 315 - jiffies_to_usecs(duration)); 316 - } 317 - 318 - static int cros_ec_keyb_resume(struct device *dev) 319 - { 320 - struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); 321 - 322 - /* 323 - * When the EC is not a wake source, then it could not have caused the 324 - * resume, so we clear the EC's key scan buffer. If the EC was a 325 - * wake source (e.g. the lid is open and the user might press a key to 326 - * wake) then the key scan buffer should be preserved. 327 - */ 328 - if (!ckdev->ec->was_wake_device) 329 - cros_ec_keyb_clear_keyboard(ckdev); 330 - 331 - return 0; 332 - } 333 - 334 - #endif 335 - 336 - static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); 337 - 338 314 #ifdef CONFIG_OF 339 315 static const struct of_device_id cros_ec_keyb_of_match[] = { 340 316 { .compatible = "google,cros-ec-keyb" }, ··· 300 372 .driver = { 301 373 .name = "cros-ec-keyb", 302 374 .of_match_table = of_match_ptr(cros_ec_keyb_of_match), 303 - .pm = &cros_ec_keyb_pm_ops, 304 375 }, 305 376 }; 306 377
+23 -3
drivers/mfd/Kconfig
··· 50 50 Support for the AS3711 PMIC from AMS 51 51 52 52 config MFD_AS3722 53 - bool "ams AS3722 Power Management IC" 53 + tristate "ams AS3722 Power Management IC" 54 54 select MFD_CORE 55 55 select REGMAP_I2C 56 56 select REGMAP_IRQ ··· 111 111 depends on I2C 112 112 help 113 113 Support for the BCM590xx PMUs from Broadcom 114 + 115 + config MFD_AC100 116 + tristate "X-Powers AC100" 117 + select MFD_CORE 118 + depends on SUNXI_RSB 119 + help 120 + If you say Y here you get support for the X-Powers AC100 audio codec 121 + IC. 122 + This driver include only the core APIs. You have to select individual 123 + components like codecs or RTC under the corresponding menus. 114 124 115 125 config MFD_AXP20X 116 126 tristate ··· 290 280 DLN-2. Additional drivers such as I2C_DLN2, GPIO_DLN2, 291 281 etc. must be enabled in order to use the functionality of 292 282 the device. 283 + 284 + config MFD_EXYNOS_LPASS 285 + tristate "Samsung Exynos SoC Low Power Audio Subsystem" 286 + select MFD_CORE 287 + select REGMAP_MMIO 288 + help 289 + Select this option to enable support for Samsung Exynos Low Power 290 + Audio Subsystem. 293 291 294 292 config MFD_MC13XXX 295 293 tristate ··· 862 844 different functionality of the device. 863 845 864 846 config MFD_RK808 865 - tristate "Rockchip RK808 Power Management chip" 847 + tristate "Rockchip RK808/RK818 Power Management Chip" 866 848 depends on I2C && OF 867 849 select MFD_CORE 868 850 select REGMAP_I2C 869 851 select REGMAP_IRQ 870 852 help 871 - If you say yes here you get support for the RK808 853 + If you say yes here you get support for the RK808 and RK818 872 854 Power Management chips. 873 855 This driver provides common support for accessing the device 874 856 through I2C interface. The device supports multiple sub-devices ··· 1224 1206 depends on I2C 1225 1207 select MFD_CORE 1226 1208 select REGMAP_I2C 1209 + select IRQ_DOMAIN 1227 1210 help 1228 1211 If you say yes here you get support for the TPS65217 series of 1229 1212 Power Management / White LED chips. ··· 1574 1555 config MFD_WM8350_I2C 1575 1556 bool "Wolfson Microelectronics WM8350 with I2C" 1576 1557 select MFD_WM8350 1558 + select REGMAP_I2C 1577 1559 depends on I2C=y 1578 1560 help 1579 1561 The WM8350 is an integrated audio and power management
+3
drivers/mfd/Makefile
··· 13 13 obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o 14 14 obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o 15 15 obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o 16 + obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o 16 17 17 18 rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o 18 19 obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o ··· 115 114 obj-$(CONFIG_PMIC_DA9052) += da9052-core.o 116 115 obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o 117 116 obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o 117 + 118 + obj-$(CONFIG_MFD_AC100) += ac100.o 118 119 obj-$(CONFIG_MFD_AXP20X) += axp20x.o 119 120 obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o 120 121 obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
+24 -94
drivers/mfd/ab8500-debugfs.c
··· 153 153 154 154 #define AB8500_NAME_STRING "ab8500" 155 155 #define AB8500_ADC_NAME_STRING "gpadc" 156 - #define AB8500_NUM_BANKS 24 156 + #define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST 157 157 158 158 #define AB8500_REV_REG 0x80 159 159 160 160 static struct ab8500_prcmu_ranges *debug_ranges; 161 161 162 162 static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { 163 - [0x0] = { 163 + [AB8500_M_FSM_RANK] = { 164 164 .num_ranges = 0, 165 165 .range = NULL, 166 166 }, ··· 315 315 }, 316 316 }, 317 317 }, 318 - [0x9] = { 318 + [AB8500_RESERVED] = { 319 319 .num_ranges = 0, 320 320 .range = NULL, 321 321 }, ··· 386 386 }, 387 387 }, 388 388 }, 389 - [AB8500_DEVELOPMENT] = { 390 - .num_ranges = 1, 391 - .range = (struct ab8500_reg_range[]) { 392 - { 393 - .first = 0x00, 394 - .last = 0x00, 395 - }, 396 - }, 397 - }, 398 - [AB8500_DEBUG] = { 399 - .num_ranges = 1, 400 - .range = (struct ab8500_reg_range[]) { 401 - { 402 - .first = 0x05, 403 - .last = 0x07, 404 - }, 405 - }, 406 - }, 407 389 [AB8500_AUDIO] = { 408 390 .num_ranges = 1, 409 391 .range = (struct ab8500_reg_range[]) { ··· 445 463 }, 446 464 }, 447 465 }, 448 - [0x11] = { 466 + [AB8500_DEVELOPMENT] = { 467 + .num_ranges = 1, 468 + .range = (struct ab8500_reg_range[]) { 469 + { 470 + .first = 0x00, 471 + .last = 0x00, 472 + }, 473 + }, 474 + }, 475 + [AB8500_DEBUG] = { 476 + .num_ranges = 1, 477 + .range = (struct ab8500_reg_range[]) { 478 + { 479 + .first = 0x05, 480 + .last = 0x07, 481 + }, 482 + }, 483 + }, 484 + [AB8500_PROD_TEST] = { 449 485 .num_ranges = 0, 450 486 .range = NULL, 451 487 }, 452 - [0x12] = { 453 - .num_ranges = 0, 454 - .range = NULL, 455 - }, 456 - [0x13] = { 457 - .num_ranges = 0, 458 - .range = NULL, 459 - }, 460 - [0x14] = { 488 + [AB8500_STE_TEST] = { 461 489 .num_ranges = 0, 462 490 .range = NULL, 463 491 }, ··· 1374 1382 } 1375 1383 } 1376 1384 1377 - /* Space for 500 registers. */ 1378 - #define DUMP_MAX_REGS 700 1379 - static struct ab8500_register_dump 1380 - { 1381 - u8 bank; 1382 - u8 reg; 1383 - u8 value; 1384 - } ab8500_complete_register_dump[DUMP_MAX_REGS]; 1385 - 1386 - /* This shall only be called upon kernel panic! */ 1387 - void ab8500_dump_all_banks_to_mem(void) 1388 - { 1389 - int i, r = 0; 1390 - u8 bank; 1391 - int err = 0; 1392 - 1393 - pr_info("Saving all ABB registers for crash analysis.\n"); 1394 - 1395 - for (bank = 0; bank < AB8500_NUM_BANKS; bank++) { 1396 - for (i = 0; i < debug_ranges[bank].num_ranges; i++) { 1397 - u8 reg; 1398 - 1399 - for (reg = debug_ranges[bank].range[i].first; 1400 - reg <= debug_ranges[bank].range[i].last; 1401 - reg++) { 1402 - u8 value; 1403 - 1404 - err = prcmu_abb_read(bank, reg, &value, 1); 1405 - 1406 - if (err < 0) 1407 - goto out; 1408 - 1409 - ab8500_complete_register_dump[r].bank = bank; 1410 - ab8500_complete_register_dump[r].reg = reg; 1411 - ab8500_complete_register_dump[r].value = value; 1412 - 1413 - r++; 1414 - 1415 - if (r >= DUMP_MAX_REGS) { 1416 - pr_err("%s: too many register to dump!\n", 1417 - __func__); 1418 - err = -EINVAL; 1419 - goto out; 1420 - } 1421 - } 1422 - } 1423 - } 1424 - out: 1425 - if (err >= 0) 1426 - pr_info("Saved all ABB registers.\n"); 1427 - else 1428 - pr_info("Failed to save all ABB registers.\n"); 1429 - } 1430 - 1431 1385 static int ab8500_all_banks_open(struct inode *inode, struct file *file) 1432 1386 { 1433 1387 struct seq_file *s; ··· 1522 1584 static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS]; 1523 1585 static int num_interrupt_lines; 1524 1586 1525 - bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int) 1526 - { 1527 - return false; 1528 - } 1529 - 1530 1587 void ab8500_debug_register_interrupt(int line) 1531 1588 { 1532 - if (line < num_interrupt_lines) { 1589 + if (line < num_interrupt_lines) 1533 1590 num_interrupts[line]++; 1534 - if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500)) 1535 - num_wake_interrupts[line]++; 1536 - } 1537 1591 } 1538 1592 1539 1593 static int ab8500_interrupts_print(struct seq_file *s, void *p)
+137
drivers/mfd/ac100.c
··· 1 + /* 2 + * MFD core driver for X-Powers' AC100 Audio Codec IC 3 + * 4 + * The AC100 is a highly integrated audio codec and RTC subsystem designed 5 + * for mobile applications. It has 3 I2S/PCM interfaces, a 2 channel DAC, 6 + * a 2 channel ADC with 5 inputs and a builtin mixer. The RTC subsystem has 7 + * 3 clock outputs. 8 + * 9 + * The audio codec and RTC parts are completely separate, sharing only the 10 + * host interface for access to its registers. 11 + * 12 + * Copyright (2016) Chen-Yu Tsai 13 + * 14 + * Author: Chen-Yu Tsai <wens@csie.org> 15 + * 16 + * This program is free software; you can redistribute it and/or modify 17 + * it under the terms of the GNU General Public License version 2 as 18 + * published by the Free Software Foundation. 19 + */ 20 + 21 + #include <linux/interrupt.h> 22 + #include <linux/kernel.h> 23 + #include <linux/mfd/core.h> 24 + #include <linux/mfd/ac100.h> 25 + #include <linux/module.h> 26 + #include <linux/of.h> 27 + #include <linux/regmap.h> 28 + #include <linux/sunxi-rsb.h> 29 + 30 + static const struct regmap_range ac100_writeable_ranges[] = { 31 + regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_I2S_SR_CTRL), 32 + regmap_reg_range(AC100_I2S1_CLK_CTRL, AC100_I2S1_MXR_GAIN), 33 + regmap_reg_range(AC100_I2S2_CLK_CTRL, AC100_I2S2_MXR_GAIN), 34 + regmap_reg_range(AC100_I2S3_CLK_CTRL, AC100_I2S3_SIG_PATH_CTRL), 35 + regmap_reg_range(AC100_ADC_DIG_CTRL, AC100_ADC_VOL_CTRL), 36 + regmap_reg_range(AC100_HMIC_CTRL1, AC100_HMIC_STATUS), 37 + regmap_reg_range(AC100_DAC_DIG_CTRL, AC100_DAC_MXR_GAIN), 38 + regmap_reg_range(AC100_ADC_APC_CTRL, AC100_LINEOUT_CTRL), 39 + regmap_reg_range(AC100_ADC_DAP_L_CTRL, AC100_ADC_DAP_OPT), 40 + regmap_reg_range(AC100_DAC_DAP_CTRL, AC100_DAC_DAP_OPT), 41 + regmap_reg_range(AC100_ADC_DAP_ENA, AC100_DAC_DAP_ENA), 42 + regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL2), 43 + regmap_reg_range(AC100_SRC2_CTRL1, AC100_SRC2_CTRL2), 44 + regmap_reg_range(AC100_CLK32K_ANALOG_CTRL, AC100_CLKOUT_CTRL3), 45 + regmap_reg_range(AC100_RTC_RST, AC100_RTC_UPD), 46 + regmap_reg_range(AC100_ALM_INT_ENA, AC100_ALM_INT_STA), 47 + regmap_reg_range(AC100_ALM_SEC, AC100_RTC_GP(15)), 48 + }; 49 + 50 + static const struct regmap_range ac100_volatile_ranges[] = { 51 + regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_PLL_CTRL2), 52 + regmap_reg_range(AC100_HMIC_STATUS, AC100_HMIC_STATUS), 53 + regmap_reg_range(AC100_ADC_DAP_L_STA, AC100_ADC_DAP_L_STA), 54 + regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL1), 55 + regmap_reg_range(AC100_SRC1_CTRL3, AC100_SRC2_CTRL1), 56 + regmap_reg_range(AC100_SRC2_CTRL3, AC100_SRC2_CTRL4), 57 + regmap_reg_range(AC100_RTC_RST, AC100_RTC_RST), 58 + regmap_reg_range(AC100_RTC_SEC, AC100_ALM_INT_STA), 59 + regmap_reg_range(AC100_ALM_SEC, AC100_ALM_UPD), 60 + }; 61 + 62 + static const struct regmap_access_table ac100_writeable_table = { 63 + .yes_ranges = ac100_writeable_ranges, 64 + .n_yes_ranges = ARRAY_SIZE(ac100_writeable_ranges), 65 + }; 66 + 67 + static const struct regmap_access_table ac100_volatile_table = { 68 + .yes_ranges = ac100_volatile_ranges, 69 + .n_yes_ranges = ARRAY_SIZE(ac100_volatile_ranges), 70 + }; 71 + 72 + static const struct regmap_config ac100_regmap_config = { 73 + .reg_bits = 8, 74 + .val_bits = 16, 75 + .wr_table = &ac100_writeable_table, 76 + .volatile_table = &ac100_volatile_table, 77 + .max_register = AC100_RTC_GP(15), 78 + .cache_type = REGCACHE_RBTREE, 79 + }; 80 + 81 + static struct mfd_cell ac100_cells[] = { 82 + { 83 + .name = "ac100-codec", 84 + .of_compatible = "x-powers,ac100-codec", 85 + }, { 86 + .name = "ac100-rtc", 87 + .of_compatible = "x-powers,ac100-rtc", 88 + }, 89 + }; 90 + 91 + static int ac100_rsb_probe(struct sunxi_rsb_device *rdev) 92 + { 93 + struct ac100_dev *ac100; 94 + int ret; 95 + 96 + ac100 = devm_kzalloc(&rdev->dev, sizeof(*ac100), GFP_KERNEL); 97 + if (!ac100) 98 + return -ENOMEM; 99 + 100 + ac100->dev = &rdev->dev; 101 + sunxi_rsb_device_set_drvdata(rdev, ac100); 102 + 103 + ac100->regmap = devm_regmap_init_sunxi_rsb(rdev, &ac100_regmap_config); 104 + if (IS_ERR(ac100->regmap)) { 105 + ret = PTR_ERR(ac100->regmap); 106 + dev_err(ac100->dev, "regmap init failed: %d\n", ret); 107 + return ret; 108 + } 109 + 110 + ret = devm_mfd_add_devices(ac100->dev, PLATFORM_DEVID_NONE, ac100_cells, 111 + ARRAY_SIZE(ac100_cells), NULL, 0, NULL); 112 + if (ret) { 113 + dev_err(ac100->dev, "failed to add MFD devices: %d\n", ret); 114 + return ret; 115 + } 116 + 117 + return 0; 118 + } 119 + 120 + static const struct of_device_id ac100_of_match[] = { 121 + { .compatible = "x-powers,ac100" }, 122 + { }, 123 + }; 124 + MODULE_DEVICE_TABLE(of, ac100_of_match); 125 + 126 + static struct sunxi_rsb_driver ac100_rsb_driver = { 127 + .driver = { 128 + .name = "ac100", 129 + .of_match_table = of_match_ptr(ac100_of_match), 130 + }, 131 + .probe = ac100_rsb_probe, 132 + }; 133 + module_sunxi_rsb_driver(ac100_rsb_driver); 134 + 135 + MODULE_DESCRIPTION("Audio codec MFD core driver for AC100"); 136 + MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); 137 + MODULE_LICENSE("GPL v2");
+1
drivers/mfd/act8945a.c
··· 23 23 }, 24 24 { 25 25 .name = "act8945a-charger", 26 + .of_compatible = "active-semi,act8945a-charger", 26 27 }, 27 28 }; 28 29
+7 -9
drivers/mfd/altera-a10sr.c
··· 1 1 /* 2 + * Altera Arria10 DevKit System Resource MFD Driver 3 + * 4 + * Author: Thor Thayer <tthayer@opensource.altera.com> 5 + * 2 6 * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved 3 7 * 4 8 * This program is free software; you can redistribute it and/or modify it ··· 24 20 25 21 #include <linux/mfd/altera-a10sr.h> 26 22 #include <linux/mfd/core.h> 27 - #include <linux/module.h> 23 + #include <linux/init.h> 28 24 #include <linux/of.h> 29 25 #include <linux/spi/spi.h> 30 26 ··· 98 94 } 99 95 } 100 96 101 - const struct regmap_config altr_a10sr_regmap_config = { 97 + static const struct regmap_config altr_a10sr_regmap_config = { 102 98 .reg_bits = 8, 103 99 .val_bits = 8, 104 100 ··· 156 152 { .compatible = "altr,a10sr" }, 157 153 { }, 158 154 }; 159 - MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match); 160 155 161 156 static struct spi_driver altr_a10sr_spi_driver = { 162 157 .probe = altr_a10sr_spi_probe, ··· 164 161 .of_match_table = of_match_ptr(altr_a10sr_spi_of_match), 165 162 }, 166 163 }; 167 - 168 - module_spi_driver(altr_a10sr_spi_driver); 169 - 170 - MODULE_LICENSE("GPL v2"); 171 - MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>"); 172 - MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver"); 164 + builtin_driver(altr_a10sr_spi_driver, spi_register_driver)
+81 -32
drivers/mfd/arizona-core.c
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 + #include <linux/clk.h> 13 14 #include <linux/delay.h> 14 15 #include <linux/err.h> 15 16 #include <linux/gpio.h> ··· 50 49 case ARIZONA_32KZ_MCLK1: 51 50 ret = pm_runtime_get_sync(arizona->dev); 52 51 if (ret != 0) 53 - goto out; 52 + goto err_ref; 53 + ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]); 54 + if (ret != 0) 55 + goto err_pm; 56 + break; 57 + case ARIZONA_32KZ_MCLK2: 58 + ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]); 59 + if (ret != 0) 60 + goto err_ref; 54 61 break; 55 62 } 56 63 ··· 67 58 ARIZONA_CLK_32K_ENA); 68 59 } 69 60 70 - out: 61 + err_pm: 62 + pm_runtime_put_sync(arizona->dev); 63 + err_ref: 71 64 if (ret != 0) 72 65 arizona->clk32k_ref--; 73 66 ··· 94 83 switch (arizona->pdata.clk32k_src) { 95 84 case ARIZONA_32KZ_MCLK1: 96 85 pm_runtime_put_sync(arizona->dev); 86 + clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]); 87 + break; 88 + case ARIZONA_32KZ_MCLK2: 89 + clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]); 97 90 break; 98 91 } 99 92 } ··· 750 735 return 0; 751 736 } 752 737 753 - static int arizona_suspend_late(struct device *dev) 738 + static int arizona_suspend_noirq(struct device *dev) 754 739 { 755 740 struct arizona *arizona = dev_get_drvdata(dev); 756 741 ··· 774 759 { 775 760 struct arizona *arizona = dev_get_drvdata(dev); 776 761 777 - dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n"); 762 + dev_dbg(arizona->dev, "Resume, reenabling IRQ\n"); 778 763 enable_irq(arizona->irq); 779 764 780 765 return 0; ··· 786 771 arizona_runtime_resume, 787 772 NULL) 788 773 SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume) 789 - #ifdef CONFIG_PM_SLEEP 790 - .suspend_late = arizona_suspend_late, 791 - .resume_noirq = arizona_resume_noirq, 792 - #endif 774 + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq, 775 + arizona_resume_noirq) 793 776 }; 794 777 EXPORT_SYMBOL_GPL(arizona_pm_ops); 795 778 ··· 803 790 } 804 791 EXPORT_SYMBOL_GPL(arizona_of_get_type); 805 792 806 - int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop, 807 - bool mandatory) 808 - { 809 - int gpio; 810 - 811 - gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0); 812 - if (gpio < 0) { 813 - if (mandatory) 814 - dev_err(arizona->dev, 815 - "Mandatory DT gpio %s missing/malformed: %d\n", 816 - prop, gpio); 817 - 818 - gpio = 0; 819 - } 820 - 821 - return gpio; 822 - } 823 - EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio); 824 - 825 793 static int arizona_of_get_core_pdata(struct arizona *arizona) 826 794 { 827 795 struct arizona_pdata *pdata = &arizona->pdata; 828 796 struct property *prop; 829 797 const __be32 *cur; 830 798 u32 val; 799 + u32 pdm_val[ARIZONA_MAX_PDM_SPK]; 831 800 int ret, i; 832 801 int count = 0; 833 802 834 - pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true); 803 + pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0); 804 + if (pdata->reset == -EPROBE_DEFER) { 805 + return pdata->reset; 806 + } else if (pdata->reset < 0) { 807 + dev_err(arizona->dev, "Reset GPIO missing/malformed: %d\n", 808 + pdata->reset); 809 + 810 + pdata->reset = 0; 811 + } 835 812 836 813 ret = of_property_read_u32_array(arizona->dev->of_node, 837 814 "wlf,gpio-defaults", ··· 873 870 pdata->out_mono[count] = !!val; 874 871 count++; 875 872 } 873 + 874 + count = 0; 875 + of_property_for_each_u32(arizona->dev->of_node, 876 + "wlf,max-channels-clocked", 877 + prop, cur, val) { 878 + if (count == ARRAY_SIZE(pdata->max_channels_clocked)) 879 + break; 880 + 881 + pdata->max_channels_clocked[count] = val; 882 + count++; 883 + } 884 + 885 + ret = of_property_read_u32_array(arizona->dev->of_node, 886 + "wlf,spk-fmt", 887 + pdm_val, 888 + ARRAY_SIZE(pdm_val)); 889 + 890 + if (ret >= 0) 891 + for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count) 892 + pdata->spk_fmt[count] = pdm_val[count]; 893 + 894 + ret = of_property_read_u32_array(arizona->dev->of_node, 895 + "wlf,spk-mute", 896 + pdm_val, 897 + ARRAY_SIZE(pdm_val)); 898 + 899 + if (ret >= 0) 900 + for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count) 901 + pdata->spk_mute[count] = pdm_val[count]; 876 902 877 903 return 0; 878 904 } ··· 1032 1000 1033 1001 int arizona_dev_init(struct arizona *arizona) 1034 1002 { 1003 + const char * const mclk_name[] = { "mclk1", "mclk2" }; 1035 1004 struct device *dev = arizona->dev; 1036 1005 const char *type_name = NULL; 1037 1006 unsigned int reg, val, mask; ··· 1043 1010 dev_set_drvdata(arizona->dev, arizona); 1044 1011 mutex_init(&arizona->clk_lock); 1045 1012 1046 - if (dev_get_platdata(arizona->dev)) 1013 + if (dev_get_platdata(arizona->dev)) { 1047 1014 memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), 1048 1015 sizeof(arizona->pdata)); 1049 - else 1050 - arizona_of_get_core_pdata(arizona); 1016 + } else { 1017 + ret = arizona_of_get_core_pdata(arizona); 1018 + if (ret < 0) 1019 + return ret; 1020 + } 1021 + 1022 + BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name)); 1023 + for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) { 1024 + arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]); 1025 + if (IS_ERR(arizona->mclk[i])) { 1026 + dev_info(arizona->dev, "Failed to get %s: %ld\n", 1027 + mclk_name[i], PTR_ERR(arizona->mclk[i])); 1028 + arizona->mclk[i] = NULL; 1029 + } 1030 + } 1051 1031 1052 1032 regcache_cache_only(arizona->regmap, true); 1053 1033 ··· 1081 1035 default: 1082 1036 dev_err(arizona->dev, "Unknown device type %d\n", 1083 1037 arizona->type); 1084 - return -EINVAL; 1038 + return -ENODEV; 1085 1039 } 1086 1040 1087 1041 /* Mark DCVDD as external, LDO1 driver will clear if internal */ ··· 1167 1121 break; 1168 1122 default: 1169 1123 dev_err(arizona->dev, "Unknown device ID: %x\n", reg); 1124 + ret = -ENODEV; 1170 1125 goto err_reset; 1171 1126 } 1172 1127 ··· 1327 1280 break; 1328 1281 default: 1329 1282 dev_err(arizona->dev, "Unknown device ID %x\n", reg); 1283 + ret = -ENODEV; 1330 1284 goto err_reset; 1331 1285 } 1332 1286 1333 1287 if (!subdevs) { 1334 1288 dev_err(arizona->dev, 1335 1289 "No kernel support for device ID %x\n", reg); 1290 + ret = -ENODEV; 1336 1291 goto err_reset; 1337 1292 } 1338 1293
+3 -2
drivers/mfd/atmel-hlcdc.c
··· 50 50 if (reg <= ATMEL_HLCDC_DIS) { 51 51 u32 status; 52 52 53 - readl_poll_timeout(hregmap->regs + ATMEL_HLCDC_SR, status, 54 - !(status & ATMEL_HLCDC_SIP), 1, 100); 53 + readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR, 54 + status, !(status & ATMEL_HLCDC_SIP), 55 + 1, 100); 55 56 } 56 57 57 58 writel(val, hregmap->regs + reg);
+1
drivers/mfd/axp20x-rsb.c
··· 61 61 62 62 static const struct of_device_id axp20x_rsb_of_match[] = { 63 63 { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID }, 64 + { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID }, 64 65 { .compatible = "x-powers,axp809", .data = (void *)AXP809_ID }, 65 66 { }, 66 67 };
+75
drivers/mfd/axp20x.c
··· 38 38 "AXP221", 39 39 "AXP223", 40 40 "AXP288", 41 + "AXP806", 41 42 "AXP809", 42 43 }; 43 44 ··· 128 127 static const struct regmap_access_table axp288_volatile_table = { 129 128 .yes_ranges = axp288_volatile_ranges, 130 129 .n_yes_ranges = ARRAY_SIZE(axp288_volatile_ranges), 130 + }; 131 + 132 + static const struct regmap_range axp806_writeable_ranges[] = { 133 + regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_DATACACHE(3)), 134 + regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL), 135 + regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN), 136 + regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 137 + }; 138 + 139 + static const struct regmap_range axp806_volatile_ranges[] = { 140 + regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE), 141 + }; 142 + 143 + static const struct regmap_access_table axp806_writeable_table = { 144 + .yes_ranges = axp806_writeable_ranges, 145 + .n_yes_ranges = ARRAY_SIZE(axp806_writeable_ranges), 146 + }; 147 + 148 + static const struct regmap_access_table axp806_volatile_table = { 149 + .yes_ranges = axp806_volatile_ranges, 150 + .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges), 131 151 }; 132 152 133 153 static struct resource axp152_pek_resources[] = { ··· 300 278 .cache_type = REGCACHE_RBTREE, 301 279 }; 302 280 281 + static const struct regmap_config axp806_regmap_config = { 282 + .reg_bits = 8, 283 + .val_bits = 8, 284 + .wr_table = &axp806_writeable_table, 285 + .volatile_table = &axp806_volatile_table, 286 + .max_register = AXP806_VREF_TEMP_WARN_L, 287 + .cache_type = REGCACHE_RBTREE, 288 + }; 289 + 303 290 #define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \ 304 291 [_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } 305 292 ··· 440 409 INIT_REGMAP_IRQ(AXP288, BC_USB_CHNG, 5, 1), 441 410 }; 442 411 412 + static const struct regmap_irq axp806_regmap_irqs[] = { 413 + INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV1, 0, 0), 414 + INIT_REGMAP_IRQ(AXP806, DIE_TEMP_HIGH_LV2, 0, 1), 415 + INIT_REGMAP_IRQ(AXP806, DCDCA_V_LOW, 0, 3), 416 + INIT_REGMAP_IRQ(AXP806, DCDCB_V_LOW, 0, 4), 417 + INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5), 418 + INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6), 419 + INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7), 420 + INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0), 421 + INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1), 422 + INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4), 423 + INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5), 424 + INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6), 425 + }; 426 + 443 427 static const struct regmap_irq axp809_regmap_irqs[] = { 444 428 INIT_REGMAP_IRQ(AXP809, ACIN_OVER_V, 0, 7), 445 429 INIT_REGMAP_IRQ(AXP809, ACIN_PLUGIN, 0, 6), ··· 540 494 541 495 }; 542 496 497 + static const struct regmap_irq_chip axp806_regmap_irq_chip = { 498 + .name = "axp806", 499 + .status_base = AXP20X_IRQ1_STATE, 500 + .ack_base = AXP20X_IRQ1_STATE, 501 + .mask_base = AXP20X_IRQ1_EN, 502 + .mask_invert = true, 503 + .init_ack_masked = true, 504 + .irqs = axp806_regmap_irqs, 505 + .num_irqs = ARRAY_SIZE(axp806_regmap_irqs), 506 + .num_regs = 2, 507 + }; 508 + 543 509 static const struct regmap_irq_chip axp809_regmap_irq_chip = { 544 510 .name = "axp809", 545 511 .status_base = AXP20X_IRQ1_STATE, ··· 566 508 567 509 static struct mfd_cell axp20x_cells[] = { 568 510 { 511 + .name = "axp20x-gpio", 512 + .of_compatible = "x-powers,axp209-gpio", 513 + }, { 569 514 .name = "axp20x-pek", 570 515 .num_resources = ARRAY_SIZE(axp20x_pek_resources), 571 516 .resources = axp20x_pek_resources, ··· 721 660 }, 722 661 }; 723 662 663 + static struct mfd_cell axp806_cells[] = { 664 + { 665 + .id = 2, 666 + .name = "axp20x-regulator", 667 + }, 668 + }; 669 + 724 670 static struct mfd_cell axp809_cells[] = { 725 671 { 726 672 .name = "axp20x-pek", 727 673 .num_resources = ARRAY_SIZE(axp809_pek_resources), 728 674 .resources = axp809_pek_resources, 729 675 }, { 676 + .id = 1, 730 677 .name = "axp20x-regulator", 731 678 }, 732 679 }; ··· 800 731 axp20x->nr_cells = ARRAY_SIZE(axp288_cells); 801 732 axp20x->regmap_cfg = &axp288_regmap_config; 802 733 axp20x->regmap_irq_chip = &axp288_regmap_irq_chip; 734 + break; 735 + case AXP806_ID: 736 + axp20x->nr_cells = ARRAY_SIZE(axp806_cells); 737 + axp20x->cells = axp806_cells; 738 + axp20x->regmap_cfg = &axp806_regmap_config; 739 + axp20x->regmap_irq_chip = &axp806_regmap_irq_chip; 803 740 break; 804 741 case AXP809_ID: 805 742 axp20x->nr_cells = ARRAY_SIZE(axp809_cells);
+55 -3
drivers/mfd/cros_ec.c
··· 23 23 #include <linux/module.h> 24 24 #include <linux/mfd/core.h> 25 25 #include <linux/mfd/cros_ec.h> 26 + #include <asm/unaligned.h> 26 27 27 28 #define CROS_EC_DEV_EC_INDEX 0 28 29 #define CROS_EC_DEV_PD_INDEX 1 ··· 50 49 .pdata_size = sizeof(pd_p), 51 50 }; 52 51 52 + static irqreturn_t ec_irq_thread(int irq, void *data) 53 + { 54 + struct cros_ec_device *ec_dev = data; 55 + int ret; 56 + 57 + if (device_may_wakeup(ec_dev->dev)) 58 + pm_wakeup_event(ec_dev->dev, 0); 59 + 60 + ret = cros_ec_get_next_event(ec_dev); 61 + if (ret > 0) 62 + blocking_notifier_call_chain(&ec_dev->event_notifier, 63 + 0, ec_dev); 64 + return IRQ_HANDLED; 65 + } 66 + 53 67 int cros_ec_register(struct cros_ec_device *ec_dev) 54 68 { 55 69 struct device *dev = ec_dev->dev; 56 70 int err = 0; 71 + 72 + BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier); 57 73 58 74 ec_dev->max_request = sizeof(struct ec_params_hello); 59 75 ec_dev->max_response = sizeof(struct ec_response_get_protocol_info); ··· 88 70 89 71 cros_ec_query_all(ec_dev); 90 72 73 + if (ec_dev->irq) { 74 + err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread, 75 + IRQF_TRIGGER_LOW | IRQF_ONESHOT, 76 + "chromeos-ec", ec_dev); 77 + if (err) { 78 + dev_err(dev, "Failed to request IRQ %d: %d", 79 + ec_dev->irq, err); 80 + return err; 81 + } 82 + } 83 + 91 84 err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, 92 85 NULL, ec_dev->irq, NULL); 93 86 if (err) { 94 87 dev_err(dev, 95 88 "Failed to register Embedded Controller subdevice %d\n", 96 89 err); 97 - return err; 90 + goto fail_mfd; 98 91 } 99 92 100 93 if (ec_dev->max_passthru) { ··· 123 94 dev_err(dev, 124 95 "Failed to register Power Delivery subdevice %d\n", 125 96 err); 126 - return err; 97 + goto fail_mfd; 127 98 } 128 99 } 129 100 ··· 132 103 if (err) { 133 104 mfd_remove_devices(dev); 134 105 dev_err(dev, "Failed to register sub-devices\n"); 135 - return err; 106 + goto fail_mfd; 136 107 } 137 108 } 138 109 139 110 dev_info(dev, "Chrome EC device registered\n"); 140 111 141 112 return 0; 113 + 114 + fail_mfd: 115 + if (ec_dev->irq) 116 + free_irq(ec_dev->irq, ec_dev); 117 + return err; 142 118 } 143 119 EXPORT_SYMBOL(cros_ec_register); 144 120 ··· 170 136 } 171 137 EXPORT_SYMBOL(cros_ec_suspend); 172 138 139 + static void cros_ec_drain_events(struct cros_ec_device *ec_dev) 140 + { 141 + while (cros_ec_get_next_event(ec_dev) > 0) 142 + blocking_notifier_call_chain(&ec_dev->event_notifier, 143 + 1, ec_dev); 144 + } 145 + 173 146 int cros_ec_resume(struct cros_ec_device *ec_dev) 174 147 { 175 148 enable_irq(ec_dev->irq); 176 149 150 + /* 151 + * In some cases, we need to distinguish between events that occur 152 + * during suspend if the EC is not a wake source. For example, 153 + * keypresses during suspend should be discarded if it does not wake 154 + * the system. 155 + * 156 + * If the EC is not a wake source, drain the event queue and mark them 157 + * as "queued during suspend". 158 + */ 177 159 if (ec_dev->wake_enabled) { 178 160 disable_irq_wake(ec_dev->irq); 179 161 ec_dev->wake_enabled = 0; 162 + } else { 163 + cros_ec_drain_events(ec_dev); 180 164 } 181 165 182 166 return 0;
-2
drivers/mfd/cros_ec_spi.c
··· 366 366 static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, 367 367 struct cros_ec_command *ec_msg) 368 368 { 369 - struct ec_host_request *request; 370 369 struct ec_host_response *response; 371 370 struct cros_ec_spi *ec_spi = ec_dev->priv; 372 371 struct spi_transfer trans, trans_delay; ··· 377 378 int ret = 0, final_ret; 378 379 379 380 len = cros_ec_prepare_tx(ec_dev, ec_msg); 380 - request = (struct ec_host_request *)ec_dev->dout; 381 381 dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); 382 382 383 383 /* If it's too soon to do another transaction, wait */
+51
drivers/mfd/da9052-core.c
··· 167 167 case DA9052_EVENT_B_REG: 168 168 case DA9052_EVENT_C_REG: 169 169 case DA9052_EVENT_D_REG: 170 + case DA9052_FAULTLOG_REG: 170 171 case DA9052_IRQ_MASK_A_REG: 171 172 case DA9052_IRQ_MASK_B_REG: 172 173 case DA9052_IRQ_MASK_C_REG: ··· 542 541 }; 543 542 EXPORT_SYMBOL_GPL(da9052_regmap_config); 544 543 544 + static int da9052_clear_fault_log(struct da9052 *da9052) 545 + { 546 + int ret = 0; 547 + int fault_log = 0; 548 + 549 + fault_log = da9052_reg_read(da9052, DA9052_FAULTLOG_REG); 550 + if (fault_log < 0) { 551 + dev_err(da9052->dev, 552 + "Cannot read FAULT_LOG %d\n", fault_log); 553 + return fault_log; 554 + } 555 + 556 + if (fault_log) { 557 + if (fault_log & DA9052_FAULTLOG_TWDERROR) 558 + dev_dbg(da9052->dev, 559 + "Fault log entry detected: TWD_ERROR\n"); 560 + if (fault_log & DA9052_FAULTLOG_VDDFAULT) 561 + dev_dbg(da9052->dev, 562 + "Fault log entry detected: VDD_FAULT\n"); 563 + if (fault_log & DA9052_FAULTLOG_VDDSTART) 564 + dev_dbg(da9052->dev, 565 + "Fault log entry detected: VDD_START\n"); 566 + if (fault_log & DA9052_FAULTLOG_TEMPOVER) 567 + dev_dbg(da9052->dev, 568 + "Fault log entry detected: TEMP_OVER\n"); 569 + if (fault_log & DA9052_FAULTLOG_KEYSHUT) 570 + dev_dbg(da9052->dev, 571 + "Fault log entry detected: KEY_SHUT\n"); 572 + if (fault_log & DA9052_FAULTLOG_NSDSET) 573 + dev_dbg(da9052->dev, 574 + "Fault log entry detected: nSD_SHUT\n"); 575 + if (fault_log & DA9052_FAULTLOG_WAITSET) 576 + dev_dbg(da9052->dev, 577 + "Fault log entry detected: WAIT_SHUT\n"); 578 + 579 + ret = da9052_reg_write(da9052, 580 + DA9052_FAULTLOG_REG, 581 + 0xFF); 582 + if (ret < 0) 583 + dev_err(da9052->dev, 584 + "Cannot reset FAULT_LOG values %d\n", ret); 585 + } 586 + 587 + return ret; 588 + } 589 + 545 590 int da9052_device_init(struct da9052 *da9052, u8 chip_id) 546 591 { 547 592 struct da9052_pdata *pdata = dev_get_platdata(da9052->dev); ··· 595 548 596 549 mutex_init(&da9052->auxadc_lock); 597 550 init_completion(&da9052->done); 551 + 552 + ret = da9052_clear_fault_log(da9052); 553 + if (ret < 0) 554 + dev_warn(da9052->dev, "Cannot clear FAULT_LOG\n"); 598 555 599 556 if (pdata && pdata->init != NULL) 600 557 pdata->init(da9052);
+4 -3
drivers/mfd/da9063-core.c
··· 4 4 * Copyright 2012 Dialog Semiconductors Ltd. 5 5 * Copyright 2013 Philipp Zabel, Pengutronix 6 6 * 7 - * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com>, 8 - * Michal Hajduk <michal.hajduk@diasemi.com> 7 + * Author: Krystian Garbaciak, Dialog Semiconductor 8 + * Author: Michal Hajduk, Dialog Semiconductor 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of the GNU General Public License as published by the ··· 242 242 } 243 243 244 244 MODULE_DESCRIPTION("PMIC driver for Dialog DA9063"); 245 - MODULE_AUTHOR("Krystian Garbaciak <krystian.garbaciak@diasemi.com>, Michal Hajduk <michal.hajduk@diasemi.com>"); 245 + MODULE_AUTHOR("Krystian Garbaciak"); 246 + MODULE_AUTHOR("Michal Hajduk"); 246 247 MODULE_LICENSE("GPL");
+1 -1
drivers/mfd/da9063-i2c.c
··· 3 3 * Copyright 2012 Dialog Semiconductor Ltd. 4 4 * Copyright 2013 Philipp Zabel, Pengutronix 5 5 * 6 - * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> 6 + * Author: Krystian Garbaciak, Dialog Semiconductor 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify it 9 9 * under the terms of the GNU General Public License as published by the
+1 -1
drivers/mfd/da9063-irq.c
··· 3 3 * Copyright 2012 Dialog Semiconductor Ltd. 4 4 * Copyright 2013 Philipp Zabel, Pengutronix 5 5 * 6 - * Author: Michal Hajduk <michal.hajduk@diasemi.com> 6 + * Author: Michal Hajduk, Dialog Semiconductor 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify it 9 9 * under the terms of the GNU General Public License as published by the
-19
drivers/mfd/db8500-prcmu.c
··· 938 938 return readb(PRCM_DDR_SUBSYS_APE_MINBW); 939 939 } 940 940 941 - /** 942 - * db8500_set_ddr_opp - set the appropriate DDR OPP 943 - * @opp: The new DDR operating point to which transition is to be made 944 - * Returns: 0 on success, non-zero on failure 945 - * 946 - * This function sets the operating point of the DDR. 947 - */ 948 - static bool enable_set_ddr_opp; 949 - int db8500_prcmu_set_ddr_opp(u8 opp) 950 - { 951 - if (opp < DDR_100_OPP || opp > DDR_25_OPP) 952 - return -EINVAL; 953 - /* Changing the DDR OPP can hang the hardware pre-v21 */ 954 - if (enable_set_ddr_opp) 955 - writeb(opp, PRCM_DDR_SUBSYS_APE_MINBW); 956 - 957 - return 0; 958 - } 959 - 960 941 /* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */ 961 942 static void request_even_slower_clocks(bool enable) 962 943 {
+9 -8
drivers/mfd/dm355evm_msp.c
··· 209 209 status = platform_device_add_data(pdev, pdata, pdata_len); 210 210 if (status < 0) { 211 211 dev_dbg(&pdev->dev, "can't add platform_data\n"); 212 - goto err; 212 + goto put_device; 213 213 } 214 214 } 215 215 ··· 222 222 status = platform_device_add_resources(pdev, &r, 1); 223 223 if (status < 0) { 224 224 dev_dbg(&pdev->dev, "can't add irq\n"); 225 - goto err; 225 + goto put_device; 226 226 } 227 227 } 228 228 229 229 status = platform_device_add(pdev); 230 + if (status) 231 + goto put_device; 230 232 231 - err: 232 - if (status < 0) { 233 - platform_device_put(pdev); 234 - dev_err(&client->dev, "can't add %s dev\n", name); 235 - return ERR_PTR(status); 236 - } 237 233 return &pdev->dev; 234 + 235 + put_device: 236 + platform_device_put(pdev); 237 + dev_err(&client->dev, "failed to add device %s\n", name); 238 + return ERR_PTR(status); 238 239 } 239 240 240 241 static int add_children(struct i2c_client *client)
+185
drivers/mfd/exynos-lpass.c
··· 1 + /* 2 + * Copyright (C) 2015 - 2016 Samsung Electronics Co., Ltd. 3 + * 4 + * Authors: Inha Song <ideal.song@samsung.com> 5 + * Sylwester Nawrocki <s.nawrocki@samsung.com> 6 + * 7 + * Samsung Exynos SoC series Low Power Audio Subsystem driver. 8 + * 9 + * This module provides regmap for the Top SFR region and instantiates 10 + * devices for IP blocks like DMAC, I2S, UART. 11 + * 12 + * This program is free software; you can redistribute it and/or modify 13 + * it under the terms of the GNU General Public License version 2 and 14 + * only version 2 as published by the Free Software Foundation. 15 + */ 16 + 17 + #include <linux/delay.h> 18 + #include <linux/io.h> 19 + #include <linux/module.h> 20 + #include <linux/mfd/syscon.h> 21 + #include <linux/mfd/syscon/exynos5-pmu.h> 22 + #include <linux/of.h> 23 + #include <linux/of_platform.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/regmap.h> 26 + #include <linux/types.h> 27 + 28 + /* LPASS Top register definitions */ 29 + #define SFR_LPASS_CORE_SW_RESET 0x08 30 + #define LPASS_SB_SW_RESET BIT(11) 31 + #define LPASS_UART_SW_RESET BIT(10) 32 + #define LPASS_PCM_SW_RESET BIT(9) 33 + #define LPASS_I2S_SW_RESET BIT(8) 34 + #define LPASS_WDT1_SW_RESET BIT(4) 35 + #define LPASS_WDT0_SW_RESET BIT(3) 36 + #define LPASS_TIMER_SW_RESET BIT(2) 37 + #define LPASS_MEM_SW_RESET BIT(1) 38 + #define LPASS_DMA_SW_RESET BIT(0) 39 + 40 + #define SFR_LPASS_INTR_CA5_MASK 0x48 41 + #define SFR_LPASS_INTR_CPU_MASK 0x58 42 + #define LPASS_INTR_APM BIT(9) 43 + #define LPASS_INTR_MIF BIT(8) 44 + #define LPASS_INTR_TIMER BIT(7) 45 + #define LPASS_INTR_DMA BIT(6) 46 + #define LPASS_INTR_GPIO BIT(5) 47 + #define LPASS_INTR_I2S BIT(4) 48 + #define LPASS_INTR_PCM BIT(3) 49 + #define LPASS_INTR_SLIMBUS BIT(2) 50 + #define LPASS_INTR_UART BIT(1) 51 + #define LPASS_INTR_SFR BIT(0) 52 + 53 + struct exynos_lpass { 54 + /* pointer to the Power Management Unit regmap */ 55 + struct regmap *pmu; 56 + /* pointer to the LPASS TOP regmap */ 57 + struct regmap *top; 58 + }; 59 + 60 + static void exynos_lpass_core_sw_reset(struct exynos_lpass *lpass, int mask) 61 + { 62 + unsigned int val = 0; 63 + 64 + regmap_read(lpass->top, SFR_LPASS_CORE_SW_RESET, &val); 65 + 66 + val &= ~mask; 67 + regmap_write(lpass->top, SFR_LPASS_CORE_SW_RESET, val); 68 + 69 + usleep_range(100, 150); 70 + 71 + val |= mask; 72 + regmap_write(lpass->top, SFR_LPASS_CORE_SW_RESET, val); 73 + } 74 + 75 + static void exynos_lpass_enable(struct exynos_lpass *lpass) 76 + { 77 + /* Unmask SFR, DMA and I2S interrupt */ 78 + regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 79 + LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); 80 + 81 + regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 82 + LPASS_INTR_SFR | LPASS_INTR_DMA | LPASS_INTR_I2S); 83 + 84 + /* Activate related PADs from retention state */ 85 + regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 86 + EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR); 87 + 88 + exynos_lpass_core_sw_reset(lpass, LPASS_I2S_SW_RESET); 89 + exynos_lpass_core_sw_reset(lpass, LPASS_DMA_SW_RESET); 90 + exynos_lpass_core_sw_reset(lpass, LPASS_MEM_SW_RESET); 91 + } 92 + 93 + static void exynos_lpass_disable(struct exynos_lpass *lpass) 94 + { 95 + /* Mask any unmasked IP interrupt sources */ 96 + regmap_write(lpass->top, SFR_LPASS_INTR_CPU_MASK, 0); 97 + regmap_write(lpass->top, SFR_LPASS_INTR_CA5_MASK, 0); 98 + 99 + /* Deactivate related PADs from retention state */ 100 + regmap_write(lpass->pmu, EXYNOS5433_PAD_RETENTION_AUD_OPTION, 0); 101 + } 102 + 103 + static const struct regmap_config exynos_lpass_reg_conf = { 104 + .reg_bits = 32, 105 + .reg_stride = 4, 106 + .val_bits = 32, 107 + .max_register = 0xfc, 108 + .fast_io = true, 109 + }; 110 + 111 + static int exynos_lpass_probe(struct platform_device *pdev) 112 + { 113 + struct device *dev = &pdev->dev; 114 + struct exynos_lpass *lpass; 115 + void __iomem *base_top; 116 + struct resource *res; 117 + 118 + lpass = devm_kzalloc(dev, sizeof(*lpass), GFP_KERNEL); 119 + if (!lpass) 120 + return -ENOMEM; 121 + 122 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 123 + base_top = devm_ioremap_resource(dev, res); 124 + if (IS_ERR(base_top)) 125 + return PTR_ERR(base_top); 126 + 127 + lpass->top = regmap_init_mmio(dev, base_top, 128 + &exynos_lpass_reg_conf); 129 + if (IS_ERR(lpass->top)) { 130 + dev_err(dev, "LPASS top regmap initialization failed\n"); 131 + return PTR_ERR(lpass->top); 132 + } 133 + 134 + lpass->pmu = syscon_regmap_lookup_by_phandle(dev->of_node, 135 + "samsung,pmu-syscon"); 136 + if (IS_ERR(lpass->pmu)) { 137 + dev_err(dev, "Failed to lookup PMU regmap\n"); 138 + return PTR_ERR(lpass->pmu); 139 + } 140 + 141 + platform_set_drvdata(pdev, lpass); 142 + exynos_lpass_enable(lpass); 143 + 144 + return of_platform_populate(dev->of_node, NULL, NULL, dev); 145 + } 146 + 147 + static int __maybe_unused exynos_lpass_suspend(struct device *dev) 148 + { 149 + struct exynos_lpass *lpass = dev_get_drvdata(dev); 150 + 151 + exynos_lpass_disable(lpass); 152 + 153 + return 0; 154 + } 155 + 156 + static int __maybe_unused exynos_lpass_resume(struct device *dev) 157 + { 158 + struct exynos_lpass *lpass = dev_get_drvdata(dev); 159 + 160 + exynos_lpass_enable(lpass); 161 + 162 + return 0; 163 + } 164 + 165 + static SIMPLE_DEV_PM_OPS(lpass_pm_ops, exynos_lpass_suspend, 166 + exynos_lpass_resume); 167 + 168 + static const struct of_device_id exynos_lpass_of_match[] = { 169 + { .compatible = "samsung,exynos5433-lpass" }, 170 + { }, 171 + }; 172 + MODULE_DEVICE_TABLE(of, exynos_lpass_of_match); 173 + 174 + static struct platform_driver exynos_lpass_driver = { 175 + .driver = { 176 + .name = "exynos-lpass", 177 + .pm = &lpass_pm_ops, 178 + .of_match_table = exynos_lpass_of_match, 179 + }, 180 + .probe = exynos_lpass_probe, 181 + }; 182 + module_platform_driver(exynos_lpass_driver); 183 + 184 + MODULE_DESCRIPTION("Samsung Low Power Audio Subsystem driver"); 185 + MODULE_LICENSE("GPL v2");
+13 -1
drivers/mfd/intel-lpss-acpi.c
··· 52 52 .properties = bxt_i2c_properties, 53 53 }; 54 54 55 + static struct property_entry apl_i2c_properties[] = { 56 + PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207), 57 + PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 58 + PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 59 + { }, 60 + }; 61 + 62 + static const struct intel_lpss_platform_info apl_i2c_info = { 63 + .clk_rate = 133000000, 64 + .properties = apl_i2c_properties, 65 + }; 66 + 55 67 static const struct acpi_device_id intel_lpss_acpi_ids[] = { 56 68 /* SPT */ 57 69 { "INT3446", (kernel_ulong_t)&spt_i2c_info }, ··· 73 61 { "80860ABC", (kernel_ulong_t)&bxt_info }, 74 62 { "80860AC2", (kernel_ulong_t)&bxt_info }, 75 63 /* APL */ 76 - { "80865AAC", (kernel_ulong_t)&bxt_i2c_info }, 64 + { "80865AAC", (kernel_ulong_t)&apl_i2c_info }, 77 65 { "80865ABC", (kernel_ulong_t)&bxt_info }, 78 66 { "80865AC2", (kernel_ulong_t)&bxt_info }, 79 67 { }
+43 -8
drivers/mfd/intel-lpss-pci.c
··· 111 111 .properties = bxt_i2c_properties, 112 112 }; 113 113 114 + static struct property_entry apl_i2c_properties[] = { 115 + PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207), 116 + PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 117 + PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 118 + { }, 119 + }; 120 + 121 + static const struct intel_lpss_platform_info apl_i2c_info = { 122 + .clk_rate = 133000000, 123 + .properties = apl_i2c_properties, 124 + }; 125 + 126 + static const struct intel_lpss_platform_info kbl_info = { 127 + .clk_rate = 120000000, 128 + }; 129 + 130 + static const struct intel_lpss_platform_info kbl_uart_info = { 131 + .clk_rate = 120000000, 132 + .clk_con_id = "baudclk", 133 + }; 134 + 135 + static const struct intel_lpss_platform_info kbl_i2c_info = { 136 + .clk_rate = 133000000, 137 + }; 138 + 114 139 static const struct pci_device_id intel_lpss_pci_ids[] = { 115 140 /* BXT A-Step */ 116 141 { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, ··· 171 146 { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info }, 172 147 173 148 /* APL */ 174 - { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info }, 175 - { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info }, 176 - { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&bxt_i2c_info }, 177 - { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&bxt_i2c_info }, 178 - { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&bxt_i2c_info }, 179 - { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&bxt_i2c_info }, 180 - { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&bxt_i2c_info }, 181 - { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&bxt_i2c_info }, 149 + { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info }, 150 + { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info }, 151 + { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&apl_i2c_info }, 152 + { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&apl_i2c_info }, 153 + { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&apl_i2c_info }, 154 + { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&apl_i2c_info }, 155 + { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&apl_i2c_info }, 156 + { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&apl_i2c_info }, 182 157 { PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info }, 183 158 { PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info }, 184 159 { PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info }, ··· 206 181 { PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info }, 207 182 { PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info }, 208 183 { PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info }, 184 + /* KBL-H */ 185 + { PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&kbl_uart_info }, 186 + { PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&kbl_uart_info }, 187 + { PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&kbl_info }, 188 + { PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&kbl_info }, 189 + { PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&kbl_i2c_info }, 190 + { PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&kbl_i2c_info }, 191 + { PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&kbl_i2c_info }, 192 + { PCI_VDEVICE(INTEL, 0xa2e3), (kernel_ulong_t)&kbl_i2c_info }, 193 + { PCI_VDEVICE(INTEL, 0xa2e6), (kernel_ulong_t)&kbl_uart_info }, 209 194 { } 210 195 }; 211 196 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
+2 -7
drivers/mfd/intel_msic.c
··· 12 12 #include <linux/err.h> 13 13 #include <linux/gpio.h> 14 14 #include <linux/io.h> 15 - #include <linux/module.h> 15 + #include <linux/init.h> 16 16 #include <linux/mfd/core.h> 17 17 #include <linux/mfd/intel_msic.h> 18 18 #include <linux/platform_device.h> ··· 449 449 .name = "intel_msic", 450 450 }, 451 451 }; 452 - 453 - module_platform_driver(intel_msic_driver); 454 - 455 - MODULE_DESCRIPTION("Driver for Intel MSIC"); 456 - MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 457 - MODULE_LICENSE("GPL"); 452 + builtin_platform_driver(intel_msic_driver);
+22 -1
drivers/mfd/intel_soc_pmic_bxtwc.c
··· 47 47 #define BXTWC_MIRQLVL1 0x4E0E 48 48 #define BXTWC_MPWRTNIRQ 0x4E0F 49 49 50 + #define BXTWC_MIRQLVL1_MCHGR BIT(5) 51 + 50 52 #define BXTWC_MTHRM0IRQ 0x4E12 51 53 #define BXTWC_MTHRM1IRQ 0x4E13 52 54 #define BXTWC_MTHRM2IRQ 0x4E14 ··· 111 109 REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff), 112 110 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f), 113 111 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff), 114 - REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f), 112 + REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f), 115 113 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f), 116 114 REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff), 117 115 REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f), ··· 145 143 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"), 146 144 }; 147 145 146 + static struct resource usbc_resources[] = { 147 + DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "USBC"), 148 + }; 149 + 148 150 static struct resource charger_resources[] = { 149 151 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"), 150 152 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"), ··· 174 168 .name = "bxt_wcove_thermal", 175 169 .num_resources = ARRAY_SIZE(thermal_resources), 176 170 .resources = thermal_resources, 171 + }, 172 + { 173 + .name = "bxt_wcove_usbc", 174 + .num_resources = ARRAY_SIZE(usbc_resources), 175 + .resources = usbc_resources, 177 176 }, 178 177 { 179 178 .name = "bxt_wcove_ext_charger", ··· 413 402 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret); 414 403 goto err_sysfs; 415 404 } 405 + 406 + /* 407 + * There is known hw bug. Upon reset BIT 5 of register 408 + * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However, 409 + * later it's set to 1(masked) automatically by hardware. So we 410 + * have the software workaround here to unmaksed it in order to let 411 + * charger interrutp work. 412 + */ 413 + regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1, 414 + BXTWC_MIRQLVL1_MCHGR, 0); 416 415 417 416 return 0; 418 417
-2
drivers/mfd/lp873x.c
··· 53 53 return ret; 54 54 } 55 55 56 - mutex_init(&lp873->lock); 57 - 58 56 ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid); 59 57 if (ret) { 60 58 dev_err(lp873->dev, "Failed to read OTP ID\n");
+2 -2
drivers/mfd/max14577.c
··· 3 3 * 4 4 * Copyright (C) 2014 Samsung Electronics 5 5 * Chanwoo Choi <cw00.choi@samsung.com> 6 - * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 + * Krzysztof Kozlowski <krzk@kernel.org> 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify 9 9 * it under the terms of the GNU General Public License as published by ··· 569 569 } 570 570 module_exit(max14577_i2c_exit); 571 571 572 - MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>"); 572 + MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <krzk@kernel.org>"); 573 573 MODULE_DESCRIPTION("Maxim 14577/77836 multi-function core driver"); 574 574 MODULE_LICENSE("GPL");
+1 -1
drivers/mfd/max8997-irq.c
··· 139 139 mutex_unlock(&max8997->irqlock); 140 140 } 141 141 142 - static const inline struct max8997_irq_data * 142 + inline static const struct max8997_irq_data * 143 143 irq_to_max8997_irq(struct max8997_dev *max8997, struct irq_data *data) 144 144 { 145 145 return &max8997_irqs[data->hwirq];
+1 -1
drivers/mfd/omap-usb-host.c
··· 162 162 * provided port mode string as per the port_modes table. 163 163 * If no match is found it returns -ENODEV 164 164 */ 165 - static const int omap_usbhs_get_dt_port_mode(const char *mode) 165 + static int omap_usbhs_get_dt_port_mode(const char *mode) 166 166 { 167 167 int i; 168 168
+1
drivers/mfd/pm8921-core.c
··· 309 309 }; 310 310 311 311 static const struct of_device_id pm8921_id_table[] = { 312 + { .compatible = "qcom,pm8018", }, 312 313 { .compatible = "qcom,pm8058", }, 313 314 { .compatible = "qcom,pm8921", }, 314 315 { }
+72
drivers/mfd/qcom_rpm.c
··· 21 21 #include <linux/mfd/qcom_rpm.h> 22 22 #include <linux/mfd/syscon.h> 23 23 #include <linux/regmap.h> 24 + #include <linux/clk.h> 24 25 25 26 #include <dt-bindings/mfd/qcom-rpm.h> 26 27 ··· 49 48 struct regmap *ipc_regmap; 50 49 unsigned ipc_offset; 51 50 unsigned ipc_bit; 51 + struct clk *ramclk; 52 52 53 53 struct completion ack; 54 54 struct mutex lock; ··· 390 388 .ack_sel_size = 7, 391 389 }; 392 390 391 + static const struct qcom_rpm_resource mdm9615_rpm_resource_table[] = { 392 + [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 }, 393 + [QCOM_RPM_SYS_FABRIC_CLK] = { 26, 10, 9, 1 }, 394 + [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 27, 11, 11, 1 }, 395 + [QCOM_RPM_SFPB_CLK] = { 28, 12, 12, 1 }, 396 + [QCOM_RPM_CFPB_CLK] = { 29, 13, 13, 1 }, 397 + [QCOM_RPM_EBI1_CLK] = { 30, 14, 16, 1 }, 398 + [QCOM_RPM_APPS_FABRIC_HALT] = { 31, 15, 22, 2 }, 399 + [QCOM_RPM_APPS_FABRIC_MODE] = { 33, 16, 23, 3 }, 400 + [QCOM_RPM_APPS_FABRIC_IOCTL] = { 36, 17, 24, 1 }, 401 + [QCOM_RPM_APPS_FABRIC_ARB] = { 37, 18, 25, 27 }, 402 + [QCOM_RPM_PM8018_SMPS1] = { 64, 19, 30, 2 }, 403 + [QCOM_RPM_PM8018_SMPS2] = { 66, 21, 31, 2 }, 404 + [QCOM_RPM_PM8018_SMPS3] = { 68, 23, 32, 2 }, 405 + [QCOM_RPM_PM8018_SMPS4] = { 70, 25, 33, 2 }, 406 + [QCOM_RPM_PM8018_SMPS5] = { 72, 27, 34, 2 }, 407 + [QCOM_RPM_PM8018_LDO1] = { 74, 29, 35, 2 }, 408 + [QCOM_RPM_PM8018_LDO2] = { 76, 31, 36, 2 }, 409 + [QCOM_RPM_PM8018_LDO3] = { 78, 33, 37, 2 }, 410 + [QCOM_RPM_PM8018_LDO4] = { 80, 35, 38, 2 }, 411 + [QCOM_RPM_PM8018_LDO5] = { 82, 37, 39, 2 }, 412 + [QCOM_RPM_PM8018_LDO6] = { 84, 39, 40, 2 }, 413 + [QCOM_RPM_PM8018_LDO7] = { 86, 41, 41, 2 }, 414 + [QCOM_RPM_PM8018_LDO8] = { 88, 43, 42, 2 }, 415 + [QCOM_RPM_PM8018_LDO9] = { 90, 45, 43, 2 }, 416 + [QCOM_RPM_PM8018_LDO10] = { 92, 47, 44, 2 }, 417 + [QCOM_RPM_PM8018_LDO11] = { 94, 49, 45, 2 }, 418 + [QCOM_RPM_PM8018_LDO12] = { 96, 51, 46, 2 }, 419 + [QCOM_RPM_PM8018_LDO13] = { 98, 53, 47, 2 }, 420 + [QCOM_RPM_PM8018_LDO14] = { 100, 55, 48, 2 }, 421 + [QCOM_RPM_PM8018_LVS1] = { 102, 57, 49, 1 }, 422 + [QCOM_RPM_PM8018_NCP] = { 103, 58, 80, 2 }, 423 + [QCOM_RPM_CXO_BUFFERS] = { 105, 60, 81, 1 }, 424 + [QCOM_RPM_USB_OTG_SWITCH] = { 106, 61, 82, 1 }, 425 + [QCOM_RPM_HDMI_SWITCH] = { 107, 62, 83, 1 }, 426 + [QCOM_RPM_VOLTAGE_CORNER] = { 109, 64, 87, 1 }, 427 + }; 428 + 429 + static const struct qcom_rpm_data mdm9615_template = { 430 + .version = 3, 431 + .resource_table = mdm9615_rpm_resource_table, 432 + .n_resources = ARRAY_SIZE(mdm9615_rpm_resource_table), 433 + .req_ctx_off = 3, 434 + .req_sel_off = 11, 435 + .ack_ctx_off = 15, 436 + .ack_sel_off = 23, 437 + .req_sel_size = 4, 438 + .ack_sel_size = 7, 439 + }; 440 + 393 441 static const struct of_device_id qcom_rpm_of_match[] = { 394 442 { .compatible = "qcom,rpm-apq8064", .data = &apq8064_template }, 395 443 { .compatible = "qcom,rpm-msm8660", .data = &msm8660_template }, 396 444 { .compatible = "qcom,rpm-msm8960", .data = &msm8960_template }, 397 445 { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template }, 446 + { .compatible = "qcom,rpm-mdm9615", .data = &mdm9615_template }, 398 447 { } 399 448 }; 400 449 MODULE_DEVICE_TABLE(of, qcom_rpm_of_match); ··· 554 501 mutex_init(&rpm->lock); 555 502 init_completion(&rpm->ack); 556 503 504 + /* Enable message RAM clock */ 505 + rpm->ramclk = devm_clk_get(&pdev->dev, "ram"); 506 + if (IS_ERR(rpm->ramclk)) { 507 + ret = PTR_ERR(rpm->ramclk); 508 + if (ret == -EPROBE_DEFER) 509 + return ret; 510 + /* 511 + * Fall through in all other cases, as the clock is 512 + * optional. (Does not exist on all platforms.) 513 + */ 514 + rpm->ramclk = NULL; 515 + } 516 + clk_prepare_enable(rpm->ramclk); /* Accepts NULL */ 517 + 557 518 irq_ack = platform_get_irq_byname(pdev, "ack"); 558 519 if (irq_ack < 0) { 559 520 dev_err(&pdev->dev, "required ack interrupt missing\n"); ··· 605 538 } 606 539 607 540 rpm->ipc_regmap = syscon_node_to_regmap(syscon_np); 541 + of_node_put(syscon_np); 608 542 if (IS_ERR(rpm->ipc_regmap)) 609 543 return PTR_ERR(rpm->ipc_regmap); 610 544 ··· 688 620 689 621 static int qcom_rpm_remove(struct platform_device *pdev) 690 622 { 623 + struct qcom_rpm *rpm = dev_get_drvdata(&pdev->dev); 624 + 691 625 of_platform_depopulate(&pdev->dev); 626 + clk_disable_unprepare(rpm->ramclk); 627 + 692 628 return 0; 693 629 } 694 630
+201 -37
drivers/mfd/rk808.c
··· 1 1 /* 2 - * MFD core driver for Rockchip RK808 2 + * MFD core driver for Rockchip RK808/RK818 3 3 * 4 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 5 5 * 6 6 * Author: Chris Zhong <zyw@rock-chips.com> 7 7 * Author: Zhang Qing <zhangqing@rock-chips.com> 8 + * 9 + * Copyright (C) 2016 PHYTEC Messtechnik GmbH 10 + * 11 + * Author: Wadim Egorov <w.egorov@phytec.de> 8 12 * 9 13 * This program is free software; you can redistribute it and/or modify it 10 14 * under the terms and conditions of the GNU General Public License, ··· 25 21 #include <linux/mfd/rk808.h> 26 22 #include <linux/mfd/core.h> 27 23 #include <linux/module.h> 24 + #include <linux/of_device.h> 28 25 #include <linux/regmap.h> 29 26 30 27 struct rk808_reg_data { ··· 62 57 return false; 63 58 } 64 59 60 + static const struct regmap_config rk818_regmap_config = { 61 + .reg_bits = 8, 62 + .val_bits = 8, 63 + .max_register = RK818_USB_CTRL_REG, 64 + .cache_type = REGCACHE_RBTREE, 65 + .volatile_reg = rk808_is_volatile_reg, 66 + }; 67 + 65 68 static const struct regmap_config rk808_regmap_config = { 66 69 .reg_bits = 8, 67 70 .val_bits = 8, ··· 92 79 { 93 80 .name = "rk808-rtc", 94 81 .num_resources = ARRAY_SIZE(rtc_resources), 95 - .resources = &rtc_resources[0], 82 + .resources = rtc_resources, 96 83 }, 97 84 }; 98 85 99 - static const struct rk808_reg_data pre_init_reg[] = { 86 + static const struct mfd_cell rk818s[] = { 87 + { .name = "rk808-clkout", }, 88 + { .name = "rk808-regulator", }, 89 + { 90 + .name = "rk808-rtc", 91 + .num_resources = ARRAY_SIZE(rtc_resources), 92 + .resources = rtc_resources, 93 + }, 94 + }; 95 + 96 + static const struct rk808_reg_data rk808_pre_init_reg[] = { 100 97 { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA }, 101 98 { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA }, 102 99 { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA }, ··· 114 91 { RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_200MA }, 115 92 { RK808_DCDC_UV_ACT_REG, BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE}, 116 93 { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | 94 + VB_LO_SEL_3500MV }, 95 + }; 96 + 97 + static const struct rk808_reg_data rk818_pre_init_reg[] = { 98 + /* improve efficiency */ 99 + { RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA }, 100 + { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA }, 101 + { RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA }, 102 + { RK818_USB_CTRL_REG, RK818_USB_ILIM_SEL_MASK, 103 + RK818_USB_ILMIN_2000MA }, 104 + /* close charger when usb lower then 3.4V */ 105 + { RK818_USB_CTRL_REG, RK818_USB_CHG_SD_VSEL_MASK, 106 + (0x7 << 4) }, 107 + /* no action when vref */ 108 + { RK818_H5V_EN_REG, BIT(1), RK818_REF_RDY_CTRL }, 109 + /* enable HDMI 5V */ 110 + { RK818_H5V_EN_REG, BIT(0), RK818_H5V_EN }, 111 + { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | 117 112 VB_LO_SEL_3500MV }, 118 113 }; 119 114 ··· 177 136 }, 178 137 }; 179 138 139 + static const struct regmap_irq rk818_irqs[] = { 140 + /* INT_STS */ 141 + [RK818_IRQ_VOUT_LO] = { 142 + .mask = RK818_IRQ_VOUT_LO_MSK, 143 + .reg_offset = 0, 144 + }, 145 + [RK818_IRQ_VB_LO] = { 146 + .mask = RK818_IRQ_VB_LO_MSK, 147 + .reg_offset = 0, 148 + }, 149 + [RK818_IRQ_PWRON] = { 150 + .mask = RK818_IRQ_PWRON_MSK, 151 + .reg_offset = 0, 152 + }, 153 + [RK818_IRQ_PWRON_LP] = { 154 + .mask = RK818_IRQ_PWRON_LP_MSK, 155 + .reg_offset = 0, 156 + }, 157 + [RK818_IRQ_HOTDIE] = { 158 + .mask = RK818_IRQ_HOTDIE_MSK, 159 + .reg_offset = 0, 160 + }, 161 + [RK818_IRQ_RTC_ALARM] = { 162 + .mask = RK818_IRQ_RTC_ALARM_MSK, 163 + .reg_offset = 0, 164 + }, 165 + [RK818_IRQ_RTC_PERIOD] = { 166 + .mask = RK818_IRQ_RTC_PERIOD_MSK, 167 + .reg_offset = 0, 168 + }, 169 + [RK818_IRQ_USB_OV] = { 170 + .mask = RK818_IRQ_USB_OV_MSK, 171 + .reg_offset = 0, 172 + }, 173 + 174 + /* INT_STS2 */ 175 + [RK818_IRQ_PLUG_IN] = { 176 + .mask = RK818_IRQ_PLUG_IN_MSK, 177 + .reg_offset = 1, 178 + }, 179 + [RK818_IRQ_PLUG_OUT] = { 180 + .mask = RK818_IRQ_PLUG_OUT_MSK, 181 + .reg_offset = 1, 182 + }, 183 + [RK818_IRQ_CHG_OK] = { 184 + .mask = RK818_IRQ_CHG_OK_MSK, 185 + .reg_offset = 1, 186 + }, 187 + [RK818_IRQ_CHG_TE] = { 188 + .mask = RK818_IRQ_CHG_TE_MSK, 189 + .reg_offset = 1, 190 + }, 191 + [RK818_IRQ_CHG_TS1] = { 192 + .mask = RK818_IRQ_CHG_TS1_MSK, 193 + .reg_offset = 1, 194 + }, 195 + [RK818_IRQ_TS2] = { 196 + .mask = RK818_IRQ_TS2_MSK, 197 + .reg_offset = 1, 198 + }, 199 + [RK818_IRQ_CHG_CVTLIM] = { 200 + .mask = RK818_IRQ_CHG_CVTLIM_MSK, 201 + .reg_offset = 1, 202 + }, 203 + [RK818_IRQ_DISCHG_ILIM] = { 204 + .mask = RK818_IRQ_DISCHG_ILIM_MSK, 205 + .reg_offset = 1, 206 + }, 207 + }; 208 + 180 209 static struct regmap_irq_chip rk808_irq_chip = { 181 210 .name = "rk808", 182 211 .irqs = rk808_irqs, ··· 256 145 .status_base = RK808_INT_STS_REG1, 257 146 .mask_base = RK808_INT_STS_MSK_REG1, 258 147 .ack_base = RK808_INT_STS_REG1, 148 + .init_ack_masked = true, 149 + }; 150 + 151 + static struct regmap_irq_chip rk818_irq_chip = { 152 + .name = "rk818", 153 + .irqs = rk818_irqs, 154 + .num_irqs = ARRAY_SIZE(rk818_irqs), 155 + .num_regs = 2, 156 + .irq_reg_stride = 2, 157 + .status_base = RK818_INT_STS_REG1, 158 + .mask_base = RK818_INT_STS_MSK_REG1, 159 + .ack_base = RK818_INT_STS_REG1, 259 160 .init_ack_masked = true, 260 161 }; 261 162 ··· 290 167 dev_err(&rk808_i2c_client->dev, "power off error!\n"); 291 168 } 292 169 170 + static const struct of_device_id rk808_of_match[] = { 171 + { .compatible = "rockchip,rk808" }, 172 + { .compatible = "rockchip,rk818" }, 173 + { }, 174 + }; 175 + MODULE_DEVICE_TABLE(of, rk808_of_match); 176 + 293 177 static int rk808_probe(struct i2c_client *client, 294 178 const struct i2c_device_id *id) 295 179 { 296 180 struct device_node *np = client->dev.of_node; 297 181 struct rk808 *rk808; 182 + const struct rk808_reg_data *pre_init_reg; 183 + const struct mfd_cell *cells; 184 + int nr_pre_init_regs; 185 + int nr_cells; 298 186 int pm_off = 0; 299 187 int ret; 300 188 int i; 189 + 190 + rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL); 191 + if (!rk808) 192 + return -ENOMEM; 193 + 194 + rk808->variant = i2c_smbus_read_word_data(client, RK808_ID_MSB); 195 + if (rk808->variant < 0) { 196 + dev_err(&client->dev, "Failed to read the chip id at 0x%02x\n", 197 + RK808_ID_MSB); 198 + return rk808->variant; 199 + } 200 + 201 + dev_dbg(&client->dev, "Chip id: 0x%x\n", (unsigned int)rk808->variant); 202 + 203 + switch (rk808->variant) { 204 + case RK808_ID: 205 + rk808->regmap_cfg = &rk808_regmap_config; 206 + rk808->regmap_irq_chip = &rk808_irq_chip; 207 + pre_init_reg = rk808_pre_init_reg; 208 + nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); 209 + cells = rk808s; 210 + nr_cells = ARRAY_SIZE(rk808s); 211 + break; 212 + case RK818_ID: 213 + rk808->regmap_cfg = &rk818_regmap_config; 214 + rk808->regmap_irq_chip = &rk818_irq_chip; 215 + pre_init_reg = rk818_pre_init_reg; 216 + nr_pre_init_regs = ARRAY_SIZE(rk818_pre_init_reg); 217 + cells = rk818s; 218 + nr_cells = ARRAY_SIZE(rk818s); 219 + break; 220 + default: 221 + dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", 222 + rk808->variant); 223 + return -EINVAL; 224 + } 225 + 226 + rk808->i2c = client; 227 + i2c_set_clientdata(client, rk808); 228 + 229 + rk808->regmap = devm_regmap_init_i2c(client, rk808->regmap_cfg); 230 + if (IS_ERR(rk808->regmap)) { 231 + dev_err(&client->dev, "regmap initialization failed\n"); 232 + return PTR_ERR(rk808->regmap); 233 + } 301 234 302 235 if (!client->irq) { 303 236 dev_err(&client->dev, "No interrupt support, no core IRQ\n"); 304 237 return -EINVAL; 305 238 } 306 239 307 - rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL); 308 - if (!rk808) 309 - return -ENOMEM; 310 - 311 - rk808->regmap = devm_regmap_init_i2c(client, &rk808_regmap_config); 312 - if (IS_ERR(rk808->regmap)) { 313 - dev_err(&client->dev, "regmap initialization failed\n"); 314 - return PTR_ERR(rk808->regmap); 315 - } 316 - 317 - for (i = 0; i < ARRAY_SIZE(pre_init_reg); i++) { 318 - ret = regmap_update_bits(rk808->regmap, pre_init_reg[i].addr, 319 - pre_init_reg[i].mask, 320 - pre_init_reg[i].value); 321 - if (ret) { 322 - dev_err(&client->dev, 323 - "0x%x write err\n", pre_init_reg[i].addr); 324 - return ret; 325 - } 326 - } 327 - 328 240 ret = regmap_add_irq_chip(rk808->regmap, client->irq, 329 241 IRQF_ONESHOT, -1, 330 - &rk808_irq_chip, &rk808->irq_data); 242 + rk808->regmap_irq_chip, &rk808->irq_data); 331 243 if (ret) { 332 244 dev_err(&client->dev, "Failed to add irq_chip %d\n", ret); 333 245 return ret; 334 246 } 335 247 336 - rk808->i2c = client; 337 - i2c_set_clientdata(client, rk808); 248 + for (i = 0; i < nr_pre_init_regs; i++) { 249 + ret = regmap_update_bits(rk808->regmap, 250 + pre_init_reg[i].addr, 251 + pre_init_reg[i].mask, 252 + pre_init_reg[i].value); 253 + if (ret) { 254 + dev_err(&client->dev, 255 + "0x%x write err\n", 256 + pre_init_reg[i].addr); 257 + return ret; 258 + } 259 + } 338 260 339 - ret = devm_mfd_add_devices(&client->dev, -1, 340 - rk808s, ARRAY_SIZE(rk808s), NULL, 0, 341 - regmap_irq_get_domain(rk808->irq_data)); 261 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, 262 + cells, nr_cells, NULL, 0, 263 + regmap_irq_get_domain(rk808->irq_data)); 342 264 if (ret) { 343 265 dev_err(&client->dev, "failed to add MFD devices %d\n", ret); 344 266 goto err_irq; ··· 413 245 return 0; 414 246 } 415 247 416 - static const struct of_device_id rk808_of_match[] = { 417 - { .compatible = "rockchip,rk808" }, 418 - { }, 419 - }; 420 - MODULE_DEVICE_TABLE(of, rk808_of_match); 421 - 422 248 static const struct i2c_device_id rk808_ids[] = { 423 249 { "rk808" }, 250 + { "rk818" }, 424 251 { }, 425 252 }; 426 253 MODULE_DEVICE_TABLE(i2c, rk808_ids); ··· 435 272 MODULE_LICENSE("GPL"); 436 273 MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 437 274 MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 438 - MODULE_DESCRIPTION("RK808 PMIC driver"); 275 + MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 276 + MODULE_DESCRIPTION("RK808/RK818 PMIC driver");
+5 -5
drivers/mfd/rtsx_usb.c
··· 46 46 47 47 dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__); 48 48 usb_sg_cancel(&ucr->current_sg); 49 - 50 - /* we know the cancellation is caused by time-out */ 51 - ucr->current_sg.status = -ETIMEDOUT; 52 49 } 53 50 54 51 static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, ··· 64 67 ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); 65 68 add_timer(&ucr->sg_timer); 66 69 usb_sg_wait(&ucr->current_sg); 67 - del_timer_sync(&ucr->sg_timer); 70 + if (!del_timer_sync(&ucr->sg_timer)) 71 + ret = -ETIMEDOUT; 72 + else 73 + ret = ucr->current_sg.status; 68 74 69 75 if (act_len) 70 76 *act_len = ucr->current_sg.bytes; 71 77 72 - return ucr->current_sg.status; 78 + return ret; 73 79 } 74 80 75 81 int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+1 -1
drivers/mfd/sm501.c
··· 1001 1001 return 0; 1002 1002 } 1003 1003 1004 - static struct gpio_chip gpio_chip_template = { 1004 + static const struct gpio_chip gpio_chip_template = { 1005 1005 .ngpio = 32, 1006 1006 .direction_input = sm501_gpio_input, 1007 1007 .direction_output = sm501_gpio_output,
+2 -9
drivers/mfd/smsc-ece1099.c
··· 11 11 * 12 12 */ 13 13 14 - #include <linux/module.h> 15 - #include <linux/moduleparam.h> 14 + #include <linux/init.h> 16 15 #include <linux/slab.h> 17 16 #include <linux/i2c.h> 18 17 #include <linux/gpio.h> ··· 80 81 { "smscece1099", 0}, 81 82 {}, 82 83 }; 83 - MODULE_DEVICE_TABLE(i2c, smsc_i2c_id); 84 84 85 85 static struct i2c_driver smsc_i2c_driver = { 86 86 .driver = { ··· 88 90 .probe = smsc_i2c_probe, 89 91 .id_table = smsc_i2c_id, 90 92 }; 91 - 92 - module_i2c_driver(smsc_i2c_driver); 93 - 94 - MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>"); 95 - MODULE_DESCRIPTION("SMSC chip multi-function driver"); 96 - MODULE_LICENSE("GPL v2"); 93 + builtin_i2c_driver(smsc_i2c_driver);
+2 -6
drivers/mfd/sun6i-prcm.c
··· 9 9 */ 10 10 11 11 #include <linux/mfd/core.h> 12 - #include <linux/module.h> 12 + #include <linux/init.h> 13 13 #include <linux/of.h> 14 14 15 15 struct prcm_data { ··· 170 170 }, 171 171 .probe = sun6i_prcm_probe, 172 172 }; 173 - module_platform_driver(sun6i_prcm_driver); 174 - 175 - MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); 176 - MODULE_DESCRIPTION("Allwinner sun6i PRCM driver"); 177 - MODULE_LICENSE("GPL v2"); 173 + builtin_platform_driver(sun6i_prcm_driver);
+198 -9
drivers/mfd/tps65217.c
··· 15 15 * GNU General Public License for more details. 16 16 */ 17 17 18 - #include <linux/kernel.h> 19 18 #include <linux/device.h> 20 - #include <linux/module.h> 21 - #include <linux/platform_device.h> 22 - #include <linux/init.h> 23 - #include <linux/i2c.h> 24 - #include <linux/slab.h> 25 - #include <linux/regmap.h> 26 19 #include <linux/err.h> 20 + #include <linux/init.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/i2c.h> 23 + #include <linux/irq.h> 24 + #include <linux/irqdomain.h> 25 + #include <linux/kernel.h> 26 + #include <linux/module.h> 27 27 #include <linux/of.h> 28 28 #include <linux/of_device.h> 29 + #include <linux/platform_device.h> 30 + #include <linux/regmap.h> 31 + #include <linux/slab.h> 29 32 30 33 #include <linux/mfd/core.h> 31 34 #include <linux/mfd/tps65217.h> 32 35 33 - static const struct mfd_cell tps65217s[] = { 36 + static struct resource charger_resources[] = { 37 + DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_AC, "AC"), 38 + DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_USB, "USB"), 39 + }; 40 + 41 + static struct resource pb_resources[] = { 42 + DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"), 43 + }; 44 + 45 + struct tps65217_irq { 46 + int mask; 47 + int interrupt; 48 + }; 49 + 50 + static const struct tps65217_irq tps65217_irqs[] = { 51 + [TPS65217_IRQ_PB] = { 52 + .mask = TPS65217_INT_PBM, 53 + .interrupt = TPS65217_INT_PBI, 54 + }, 55 + [TPS65217_IRQ_AC] = { 56 + .mask = TPS65217_INT_ACM, 57 + .interrupt = TPS65217_INT_ACI, 58 + }, 59 + [TPS65217_IRQ_USB] = { 60 + .mask = TPS65217_INT_USBM, 61 + .interrupt = TPS65217_INT_USBI, 62 + }, 63 + }; 64 + 65 + static void tps65217_irq_lock(struct irq_data *data) 66 + { 67 + struct tps65217 *tps = irq_data_get_irq_chip_data(data); 68 + 69 + mutex_lock(&tps->irq_lock); 70 + } 71 + 72 + static void tps65217_irq_sync_unlock(struct irq_data *data) 73 + { 74 + struct tps65217 *tps = irq_data_get_irq_chip_data(data); 75 + int ret; 76 + 77 + ret = tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask, 78 + TPS65217_PROTECT_NONE); 79 + if (ret != 0) 80 + dev_err(tps->dev, "Failed to sync IRQ masks\n"); 81 + 82 + mutex_unlock(&tps->irq_lock); 83 + } 84 + 85 + static inline const struct tps65217_irq * 86 + irq_to_tps65217_irq(struct tps65217 *tps, struct irq_data *data) 87 + { 88 + return &tps65217_irqs[data->hwirq]; 89 + } 90 + 91 + static void tps65217_irq_enable(struct irq_data *data) 92 + { 93 + struct tps65217 *tps = irq_data_get_irq_chip_data(data); 94 + const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data); 95 + 96 + tps->irq_mask &= ~irq_data->mask; 97 + } 98 + 99 + static void tps65217_irq_disable(struct irq_data *data) 100 + { 101 + struct tps65217 *tps = irq_data_get_irq_chip_data(data); 102 + const struct tps65217_irq *irq_data = irq_to_tps65217_irq(tps, data); 103 + 104 + tps->irq_mask |= irq_data->mask; 105 + } 106 + 107 + static struct irq_chip tps65217_irq_chip = { 108 + .irq_bus_lock = tps65217_irq_lock, 109 + .irq_bus_sync_unlock = tps65217_irq_sync_unlock, 110 + .irq_enable = tps65217_irq_enable, 111 + .irq_disable = tps65217_irq_disable, 112 + }; 113 + 114 + static struct mfd_cell tps65217s[] = { 34 115 { 35 116 .name = "tps65217-pmic", 36 117 .of_compatible = "ti,tps65217-pmic", ··· 122 41 }, 123 42 { 124 43 .name = "tps65217-charger", 44 + .num_resources = ARRAY_SIZE(charger_resources), 45 + .resources = charger_resources, 125 46 .of_compatible = "ti,tps65217-charger", 126 47 }, 48 + { 49 + .name = "tps65217-pwrbutton", 50 + .num_resources = ARRAY_SIZE(pb_resources), 51 + .resources = pb_resources, 52 + .of_compatible = "ti,tps65217-pwrbutton", 53 + }, 127 54 }; 55 + 56 + static irqreturn_t tps65217_irq_thread(int irq, void *data) 57 + { 58 + struct tps65217 *tps = data; 59 + unsigned int status; 60 + bool handled = false; 61 + int i; 62 + int ret; 63 + 64 + ret = tps65217_reg_read(tps, TPS65217_REG_INT, &status); 65 + if (ret < 0) { 66 + dev_err(tps->dev, "Failed to read IRQ status: %d\n", 67 + ret); 68 + return IRQ_NONE; 69 + } 70 + 71 + for (i = 0; i < ARRAY_SIZE(tps65217_irqs); i++) { 72 + if (status & tps65217_irqs[i].interrupt) { 73 + handle_nested_irq(irq_find_mapping(tps->irq_domain, i)); 74 + handled = true; 75 + } 76 + } 77 + 78 + if (handled) 79 + return IRQ_HANDLED; 80 + 81 + return IRQ_NONE; 82 + } 83 + 84 + static int tps65217_irq_map(struct irq_domain *h, unsigned int virq, 85 + irq_hw_number_t hw) 86 + { 87 + struct tps65217 *tps = h->host_data; 88 + 89 + irq_set_chip_data(virq, tps); 90 + irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq); 91 + irq_set_nested_thread(virq, 1); 92 + irq_set_parent(virq, tps->irq); 93 + irq_set_noprobe(virq); 94 + 95 + return 0; 96 + } 97 + 98 + static const struct irq_domain_ops tps65217_irq_domain_ops = { 99 + .map = tps65217_irq_map, 100 + }; 101 + 102 + static int tps65217_irq_init(struct tps65217 *tps, int irq) 103 + { 104 + int ret; 105 + 106 + mutex_init(&tps->irq_lock); 107 + tps->irq = irq; 108 + 109 + /* Mask all interrupt sources */ 110 + tps->irq_mask = (TPS65217_INT_RESERVEDM | TPS65217_INT_PBM 111 + | TPS65217_INT_ACM | TPS65217_INT_USBM); 112 + tps65217_reg_write(tps, TPS65217_REG_INT, tps->irq_mask, 113 + TPS65217_PROTECT_NONE); 114 + 115 + tps->irq_domain = irq_domain_add_linear(tps->dev->of_node, 116 + TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps); 117 + if (!tps->irq_domain) { 118 + dev_err(tps->dev, "Could not create IRQ domain\n"); 119 + return -ENOMEM; 120 + } 121 + 122 + ret = devm_request_threaded_irq(tps->dev, irq, NULL, 123 + tps65217_irq_thread, IRQF_ONESHOT, 124 + "tps65217-irq", tps); 125 + if (ret) { 126 + dev_err(tps->dev, "Failed to request IRQ %d: %d\n", 127 + irq, ret); 128 + return ret; 129 + } 130 + 131 + return 0; 132 + } 128 133 129 134 /** 130 135 * tps65217_reg_read: Read a single tps65217 register. ··· 316 149 } 317 150 EXPORT_SYMBOL_GPL(tps65217_clear_bits); 318 151 152 + static bool tps65217_volatile_reg(struct device *dev, unsigned int reg) 153 + { 154 + switch (reg) { 155 + case TPS65217_REG_INT: 156 + return true; 157 + default: 158 + return false; 159 + } 160 + } 161 + 319 162 static const struct regmap_config tps65217_regmap_config = { 320 163 .reg_bits = 8, 321 164 .val_bits = 8, 322 165 323 166 .max_register = TPS65217_REG_MAX, 167 + .volatile_reg = tps65217_volatile_reg, 324 168 }; 325 169 326 170 static const struct of_device_id tps65217_of_match[] = { ··· 383 205 return ret; 384 206 } 385 207 208 + if (client->irq) { 209 + tps65217_irq_init(tps, client->irq); 210 + } else { 211 + int i; 212 + 213 + /* Don't tell children about IRQ resources which won't fire */ 214 + for (i = 0; i < ARRAY_SIZE(tps65217s); i++) 215 + tps65217s[i].num_resources = 0; 216 + } 217 + 386 218 ret = devm_mfd_add_devices(tps->dev, -1, tps65217s, 387 - ARRAY_SIZE(tps65217s), NULL, 0, NULL); 219 + ARRAY_SIZE(tps65217s), NULL, 0, 220 + tps->irq_domain); 388 221 if (ret < 0) { 389 222 dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); 390 223 return ret;
+1 -8
drivers/mfd/twl-core.c
··· 30 30 31 31 #include <linux/init.h> 32 32 #include <linux/mutex.h> 33 - #include <linux/module.h> 34 33 #include <linux/platform_device.h> 35 34 #include <linux/regmap.h> 36 35 #include <linux/clk.h> ··· 1257 1258 { "twl6032", TWL6030_CLASS | TWL6032_SUBCLASS }, /* "Phoenix lite" */ 1258 1259 { /* end of list */ }, 1259 1260 }; 1260 - MODULE_DEVICE_TABLE(i2c, twl_ids); 1261 1261 1262 1262 /* One Client Driver , 4 Clients */ 1263 1263 static struct i2c_driver twl_driver = { ··· 1265 1267 .probe = twl_probe, 1266 1268 .remove = twl_remove, 1267 1269 }; 1268 - 1269 - module_i2c_driver(twl_driver); 1270 - 1271 - MODULE_AUTHOR("Texas Instruments, Inc."); 1272 - MODULE_DESCRIPTION("I2C Core interface for TWL"); 1273 - MODULE_LICENSE("GPL"); 1270 + builtin_i2c_driver(twl_driver);
+6
drivers/mfd/twl6040.c
··· 609 609 .writeable_reg = twl6040_writeable_reg, 610 610 611 611 .cache_type = REGCACHE_RBTREE, 612 + .use_single_rw = true, 612 613 }; 613 614 614 615 static const struct regmap_irq twl6040_irqs[] = { ··· 781 780 /* GPO support */ 782 781 cell = &twl6040->cells[children]; 783 782 cell->name = "twl6040-gpo"; 783 + children++; 784 + 785 + /* PDM clock support */ 786 + cell = &twl6040->cells[children]; 787 + cell->name = "twl6040-pdmclk"; 784 788 children++; 785 789 786 790 /* The chip is powered down so mark regmap to cache only and dirty */
+1 -5
drivers/mfd/ucb1x00-core.c
··· 446 446 unsigned long mask; 447 447 448 448 mask = probe_irq_on(); 449 - if (!mask) { 450 - probe_irq_off(mask); 451 - return NO_IRQ; 452 - } 453 449 454 450 /* 455 451 * Enable the ADC interrupt. ··· 537 541 ucb1x00_enable(ucb); 538 542 ucb->irq = ucb1x00_detect_irq(ucb); 539 543 ucb1x00_disable(ucb); 540 - if (ucb->irq == NO_IRQ) { 544 + if (!ucb->irq) { 541 545 dev_err(&ucb->dev, "IRQ probe failed\n"); 542 546 ret = -ENODEV; 543 547 goto err_no_irq;
+92
drivers/platform/chrome/cros_ec_proto.c
··· 19 19 #include <linux/device.h> 20 20 #include <linux/module.h> 21 21 #include <linux/slab.h> 22 + #include <asm/unaligned.h> 22 23 23 24 #define EC_COMMAND_RETRIES 50 24 25 ··· 235 234 return ret; 236 235 } 237 236 237 + static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev, 238 + u16 cmd, u32 *mask) 239 + { 240 + struct ec_params_get_cmd_versions *pver; 241 + struct ec_response_get_cmd_versions *rver; 242 + struct cros_ec_command *msg; 243 + int ret; 244 + 245 + msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)), 246 + GFP_KERNEL); 247 + if (!msg) 248 + return -ENOMEM; 249 + 250 + msg->version = 0; 251 + msg->command = EC_CMD_GET_CMD_VERSIONS; 252 + msg->insize = sizeof(*rver); 253 + msg->outsize = sizeof(*pver); 254 + 255 + pver = (struct ec_params_get_cmd_versions *)msg->data; 256 + pver->cmd = cmd; 257 + 258 + ret = cros_ec_cmd_xfer(ec_dev, msg); 259 + if (ret > 0) { 260 + rver = (struct ec_response_get_cmd_versions *)msg->data; 261 + *mask = rver->version_mask; 262 + } 263 + 264 + kfree(msg); 265 + 266 + return ret; 267 + } 268 + 238 269 int cros_ec_query_all(struct cros_ec_device *ec_dev) 239 270 { 240 271 struct device *dev = ec_dev->dev; 241 272 struct cros_ec_command *proto_msg; 242 273 struct ec_response_get_protocol_info *proto_info; 274 + u32 ver_mask = 0; 243 275 int ret; 244 276 245 277 proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info), ··· 362 328 goto exit; 363 329 } 364 330 331 + /* Probe if MKBP event is supported */ 332 + ret = cros_ec_get_host_command_version_mask(ec_dev, 333 + EC_CMD_GET_NEXT_EVENT, 334 + &ver_mask); 335 + if (ret < 0 || ver_mask == 0) 336 + ec_dev->mkbp_event_supported = 0; 337 + else 338 + ec_dev->mkbp_event_supported = 1; 339 + 365 340 exit: 366 341 kfree(proto_msg); 367 342 return ret; ··· 440 397 return ret; 441 398 } 442 399 EXPORT_SYMBOL(cros_ec_cmd_xfer_status); 400 + 401 + static int get_next_event(struct cros_ec_device *ec_dev) 402 + { 403 + u8 buffer[sizeof(struct cros_ec_command) + sizeof(ec_dev->event_data)]; 404 + struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; 405 + int ret; 406 + 407 + msg->version = 0; 408 + msg->command = EC_CMD_GET_NEXT_EVENT; 409 + msg->insize = sizeof(ec_dev->event_data); 410 + msg->outsize = 0; 411 + 412 + ret = cros_ec_cmd_xfer(ec_dev, msg); 413 + if (ret > 0) { 414 + ec_dev->event_size = ret - 1; 415 + memcpy(&ec_dev->event_data, msg->data, 416 + sizeof(ec_dev->event_data)); 417 + } 418 + 419 + return ret; 420 + } 421 + 422 + static int get_keyboard_state_event(struct cros_ec_device *ec_dev) 423 + { 424 + u8 buffer[sizeof(struct cros_ec_command) + 425 + sizeof(ec_dev->event_data.data)]; 426 + struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; 427 + 428 + msg->version = 0; 429 + msg->command = EC_CMD_MKBP_STATE; 430 + msg->insize = sizeof(ec_dev->event_data.data); 431 + msg->outsize = 0; 432 + 433 + ec_dev->event_size = cros_ec_cmd_xfer(ec_dev, msg); 434 + ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX; 435 + memcpy(&ec_dev->event_data.data, msg->data, 436 + sizeof(ec_dev->event_data.data)); 437 + 438 + return ec_dev->event_size; 439 + } 440 + 441 + int cros_ec_get_next_event(struct cros_ec_device *ec_dev) 442 + { 443 + if (ec_dev->mkbp_event_supported) 444 + return get_next_event(ec_dev); 445 + else 446 + return get_keyboard_state_event(ec_dev); 447 + } 448 + EXPORT_SYMBOL(cros_ec_get_next_event);
+2 -2
drivers/regulator/Kconfig
··· 643 643 outputs which can be controlled by i2c communication. 644 644 645 645 config REGULATOR_RK808 646 - tristate "Rockchip RK808 Power regulators" 646 + tristate "Rockchip RK808/RK818 Power regulators" 647 647 depends on MFD_RK808 648 648 help 649 649 Select this option to enable the power regulator of ROCKCHIP 650 - PMIC RK808. 650 + PMIC RK808 and RK818. 651 651 This driver supports the control of different power rails of device 652 652 through regulator interface. The device supports multiple DCDC/LDO 653 653 outputs which can be controlled by i2c communication.
+112 -8
drivers/regulator/axp20x-regulator.c
··· 244 244 .ops = &axp20x_ops_sw, 245 245 }; 246 246 247 + static const struct regulator_linear_range axp806_dcdca_ranges[] = { 248 + REGULATOR_LINEAR_RANGE(600000, 0x0, 0x32, 10000), 249 + REGULATOR_LINEAR_RANGE(1120000, 0x33, 0x47, 20000), 250 + }; 251 + 252 + static const struct regulator_linear_range axp806_dcdcd_ranges[] = { 253 + REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2d, 20000), 254 + REGULATOR_LINEAR_RANGE(1600000, 0x2e, 0x3f, 100000), 255 + }; 256 + 257 + static const struct regulator_linear_range axp806_cldo2_ranges[] = { 258 + REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000), 259 + REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000), 260 + }; 261 + 262 + static const struct regulator_desc axp806_regulators[] = { 263 + AXP_DESC_RANGES(AXP806, DCDCA, "dcdca", "vina", axp806_dcdca_ranges, 264 + 72, AXP806_DCDCA_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1, 265 + BIT(0)), 266 + AXP_DESC(AXP806, DCDCB, "dcdcb", "vinb", 1000, 2550, 50, 267 + AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(1)), 268 + AXP_DESC_RANGES(AXP806, DCDCC, "dcdcc", "vinc", axp806_dcdca_ranges, 269 + 72, AXP806_DCDCC_V_CTRL, 0x7f, AXP806_PWR_OUT_CTRL1, 270 + BIT(2)), 271 + AXP_DESC_RANGES(AXP806, DCDCD, "dcdcd", "vind", axp806_dcdcd_ranges, 272 + 64, AXP806_DCDCD_V_CTRL, 0x3f, AXP806_PWR_OUT_CTRL1, 273 + BIT(3)), 274 + AXP_DESC(AXP806, DCDCE, "dcdce", "vine", 1100, 3400, 100, 275 + AXP806_DCDCB_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(4)), 276 + AXP_DESC(AXP806, ALDO1, "aldo1", "aldoin", 700, 3300, 100, 277 + AXP806_ALDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(5)), 278 + AXP_DESC(AXP806, ALDO2, "aldo2", "aldoin", 700, 3400, 100, 279 + AXP806_ALDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(6)), 280 + AXP_DESC(AXP806, ALDO3, "aldo3", "aldoin", 700, 3300, 100, 281 + AXP806_ALDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL1, BIT(7)), 282 + AXP_DESC(AXP806, BLDO1, "bldo1", "bldoin", 700, 1900, 100, 283 + AXP806_BLDO1_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(0)), 284 + AXP_DESC(AXP806, BLDO2, "bldo2", "bldoin", 700, 1900, 100, 285 + AXP806_BLDO2_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(1)), 286 + AXP_DESC(AXP806, BLDO3, "bldo3", "bldoin", 700, 1900, 100, 287 + AXP806_BLDO3_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(2)), 288 + AXP_DESC(AXP806, BLDO4, "bldo4", "bldoin", 700, 1900, 100, 289 + AXP806_BLDO4_V_CTRL, 0x0f, AXP806_PWR_OUT_CTRL2, BIT(3)), 290 + AXP_DESC(AXP806, CLDO1, "cldo1", "cldoin", 700, 3300, 100, 291 + AXP806_CLDO1_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(4)), 292 + AXP_DESC_RANGES(AXP806, CLDO2, "cldo2", "cldoin", axp806_cldo2_ranges, 293 + 32, AXP806_CLDO2_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, 294 + BIT(5)), 295 + AXP_DESC(AXP806, CLDO3, "cldo3", "cldoin", 700, 3300, 100, 296 + AXP806_CLDO3_V_CTRL, 0x1f, AXP806_PWR_OUT_CTRL2, BIT(6)), 297 + AXP_DESC_SW(AXP806, SW, "sw", "swin", AXP806_PWR_OUT_CTRL2, BIT(7)), 298 + }; 299 + 247 300 static const struct regulator_linear_range axp809_dcdc4_ranges[] = { 248 301 REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000), 249 302 REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000), 250 - }; 251 - 252 - static const struct regulator_linear_range axp809_dldo1_ranges[] = { 253 - REGULATOR_LINEAR_RANGE(700000, 0x0, 0x1a, 100000), 254 - REGULATOR_LINEAR_RANGE(3400000, 0x1b, 0x1f, 200000), 255 303 }; 256 304 257 305 static const struct regulator_desc axp809_regulators[] = { ··· 326 278 AXP22X_ALDO2_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(7)), 327 279 AXP_DESC(AXP809, ALDO3, "aldo3", "aldoin", 700, 3300, 100, 328 280 AXP22X_ALDO3_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(5)), 329 - AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp809_dldo1_ranges, 281 + AXP_DESC_RANGES(AXP809, DLDO1, "dldo1", "dldoin", axp806_cldo2_ranges, 330 282 32, AXP22X_DLDO1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, 331 283 BIT(3)), 332 284 AXP_DESC(AXP809, DLDO2, "dldo2", "dldoin", 700, 3300, 100, ··· 350 302 static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq) 351 303 { 352 304 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); 305 + unsigned int reg = AXP20X_DCDC_FREQ; 353 306 u32 min, max, def, step; 354 307 355 308 switch (axp20x->variant) { ··· 361 312 def = 1500; 362 313 step = 75; 363 314 break; 315 + case AXP806_ID: 316 + /* 317 + * AXP806 DCDC work frequency setting has the same range and 318 + * step as AXP22X, but at a different register. 319 + * Fall through to the check below. 320 + * (See include/linux/mfd/axp20x.h) 321 + */ 322 + reg = AXP806_DCDC_FREQ_CTRL; 364 323 case AXP221_ID: 365 324 case AXP223_ID: 366 325 case AXP809_ID: ··· 400 343 401 344 dcdcfreq = (dcdcfreq - min) / step; 402 345 403 - return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ, 346 + return regmap_update_bits(axp20x->regmap, reg, 404 347 AXP20X_FREQ_DCDC_MASK, dcdcfreq); 405 348 } 406 349 ··· 434 377 static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) 435 378 { 436 379 struct axp20x_dev *axp20x = rdev_get_drvdata(rdev); 380 + unsigned int reg = AXP20X_DCDC_MODE; 437 381 unsigned int mask; 438 382 439 383 switch (axp20x->variant) { ··· 450 392 workmode <<= ffs(mask) - 1; 451 393 break; 452 394 395 + case AXP806_ID: 396 + reg = AXP806_DCDC_MODE_CTRL2; 397 + /* 398 + * AXP806 DCDC regulator IDs have the same range as AXP22X. 399 + * Fall through to the check below. 400 + * (See include/linux/mfd/axp20x.h) 401 + */ 453 402 case AXP221_ID: 454 403 case AXP223_ID: 455 404 case AXP809_ID: ··· 473 408 return -EINVAL; 474 409 } 475 410 476 - return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode); 411 + return regmap_update_bits(rdev->regmap, reg, mask, workmode); 412 + } 413 + 414 + /* 415 + * This function checks whether a regulator is part of a poly-phase 416 + * output setup based on the registers settings. Returns true if it is. 417 + */ 418 + static bool axp20x_is_polyphase_slave(struct axp20x_dev *axp20x, int id) 419 + { 420 + u32 reg = 0; 421 + 422 + /* Only AXP806 has poly-phase outputs */ 423 + if (axp20x->variant != AXP806_ID) 424 + return false; 425 + 426 + regmap_read(axp20x->regmap, AXP806_DCDC_MODE_CTRL2, &reg); 427 + 428 + switch (id) { 429 + case AXP806_DCDCB: 430 + return (((reg & GENMASK(7, 6)) == BIT(6)) || 431 + ((reg & GENMASK(7, 6)) == BIT(7))); 432 + case AXP806_DCDCC: 433 + return ((reg & GENMASK(7, 6)) == BIT(7)); 434 + case AXP806_DCDCE: 435 + return !!(reg & BIT(5)); 436 + } 437 + 438 + return false; 477 439 } 478 440 479 441 static int axp20x_regulator_probe(struct platform_device *pdev) ··· 532 440 drivevbus = of_property_read_bool(pdev->dev.parent->of_node, 533 441 "x-powers,drive-vbus-en"); 534 442 break; 443 + case AXP806_ID: 444 + regulators = axp806_regulators; 445 + nregulators = AXP806_REG_ID_MAX; 446 + break; 535 447 case AXP809_ID: 536 448 regulators = axp809_regulators; 537 449 nregulators = AXP809_REG_ID_MAX; ··· 552 456 for (i = 0; i < nregulators; i++) { 553 457 const struct regulator_desc *desc = &regulators[i]; 554 458 struct regulator_desc *new_desc; 459 + 460 + /* 461 + * If this regulator is a slave in a poly-phase setup, 462 + * skip it, as its controls are bound to the master 463 + * regulator and won't work. 464 + */ 465 + if (axp20x_is_polyphase_slave(axp20x, i)) 466 + continue; 555 467 556 468 /* 557 469 * Regulators DC1SW and DC5LDO are connected internally,
+66
drivers/regulator/qcom_rpm-regulator.c
··· 448 448 }; 449 449 450 450 /* 451 + * PM8018 regulators 452 + */ 453 + static const struct qcom_rpm_reg pm8018_pldo = { 454 + .desc.linear_ranges = pldo_ranges, 455 + .desc.n_linear_ranges = ARRAY_SIZE(pldo_ranges), 456 + .desc.n_voltages = 161, 457 + .desc.ops = &uV_ops, 458 + .parts = &rpm8960_ldo_parts, 459 + .supports_force_mode_auto = false, 460 + .supports_force_mode_bypass = false, 461 + }; 462 + 463 + static const struct qcom_rpm_reg pm8018_nldo = { 464 + .desc.linear_ranges = nldo_ranges, 465 + .desc.n_linear_ranges = ARRAY_SIZE(nldo_ranges), 466 + .desc.n_voltages = 64, 467 + .desc.ops = &uV_ops, 468 + .parts = &rpm8960_ldo_parts, 469 + .supports_force_mode_auto = false, 470 + .supports_force_mode_bypass = false, 471 + }; 472 + 473 + static const struct qcom_rpm_reg pm8018_smps = { 474 + .desc.linear_ranges = smps_ranges, 475 + .desc.n_linear_ranges = ARRAY_SIZE(smps_ranges), 476 + .desc.n_voltages = 154, 477 + .desc.ops = &uV_ops, 478 + .parts = &rpm8960_smps_parts, 479 + .supports_force_mode_auto = false, 480 + .supports_force_mode_bypass = false, 481 + }; 482 + 483 + static const struct qcom_rpm_reg pm8018_switch = { 484 + .desc.ops = &switch_ops, 485 + .parts = &rpm8960_switch_parts, 486 + }; 487 + 488 + /* 451 489 * PM8058 regulators 452 490 */ 453 491 static const struct qcom_rpm_reg pm8058_pldo = { ··· 793 755 const char *supply; 794 756 }; 795 757 758 + static const struct rpm_regulator_data rpm_pm8018_regulators[] = { 759 + { "s1", QCOM_RPM_PM8018_SMPS1, &pm8018_smps, "vdd_s1" }, 760 + { "s2", QCOM_RPM_PM8018_SMPS2, &pm8018_smps, "vdd_s2" }, 761 + { "s3", QCOM_RPM_PM8018_SMPS3, &pm8018_smps, "vdd_s3" }, 762 + { "s4", QCOM_RPM_PM8018_SMPS4, &pm8018_smps, "vdd_s4" }, 763 + { "s5", QCOM_RPM_PM8018_SMPS5, &pm8018_smps, "vdd_s5" }, 764 + 765 + { "l2", QCOM_RPM_PM8018_LDO2, &pm8018_pldo, "vdd_l2" }, 766 + { "l3", QCOM_RPM_PM8018_LDO3, &pm8018_pldo, "vdd_l3" }, 767 + { "l4", QCOM_RPM_PM8018_LDO4, &pm8018_pldo, "vdd_l4" }, 768 + { "l5", QCOM_RPM_PM8018_LDO5, &pm8018_pldo, "vdd_l5" }, 769 + { "l6", QCOM_RPM_PM8018_LDO6, &pm8018_pldo, "vdd_l7" }, 770 + { "l7", QCOM_RPM_PM8018_LDO7, &pm8018_pldo, "vdd_l7" }, 771 + { "l8", QCOM_RPM_PM8018_LDO8, &pm8018_nldo, "vdd_l8" }, 772 + { "l9", QCOM_RPM_PM8018_LDO9, &pm8921_nldo1200, 773 + "vdd_l9_l10_l11_l12" }, 774 + { "l10", QCOM_RPM_PM8018_LDO10, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, 775 + { "l11", QCOM_RPM_PM8018_LDO11, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, 776 + { "l12", QCOM_RPM_PM8018_LDO12, &pm8018_nldo, "vdd_l9_l10_l11_l12" }, 777 + { "l14", QCOM_RPM_PM8018_LDO14, &pm8018_pldo, "vdd_l14" }, 778 + 779 + { "lvs1", QCOM_RPM_PM8018_LVS1, &pm8018_switch, "lvs1_in" }, 780 + 781 + { } 782 + }; 783 + 796 784 static const struct rpm_regulator_data rpm_pm8058_regulators[] = { 797 785 { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, 798 786 { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, ··· 934 870 }; 935 871 936 872 static const struct of_device_id rpm_of_match[] = { 873 + { .compatible = "qcom,rpm-pm8018-regulators", 874 + .data = &rpm_pm8018_regulators }, 937 875 { .compatible = "qcom,rpm-pm8058-regulators", .data = &rpm_pm8058_regulators }, 938 876 { .compatible = "qcom,rpm-pm8901-regulators", .data = &rpm_pm8901_regulators }, 939 877 { .compatible = "qcom,rpm-pm8921-regulators", .data = &rpm_pm8921_regulators },
+136 -7
drivers/regulator/rk808-regulator.c
··· 1 1 /* 2 - * Regulator driver for Rockchip RK808 2 + * Regulator driver for Rockchip RK808/RK818 3 3 * 4 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 5 5 * 6 6 * Author: Chris Zhong <zyw@rock-chips.com> 7 7 * Author: Zhang Qing <zhangqing@rock-chips.com> 8 + * 9 + * Copyright (C) 2016 PHYTEC Messtechnik GmbH 10 + * 11 + * Author: Wadim Egorov <w.egorov@phytec.de> 8 12 * 9 13 * This program is free software; you can redistribute it and/or modify it 10 14 * under the terms and conditions of the GNU General Public License, ··· 35 31 #define RK808_BUCK_VSEL_MASK 0x3f 36 32 #define RK808_BUCK4_VSEL_MASK 0xf 37 33 #define RK808_LDO_VSEL_MASK 0x1f 34 + 35 + #define RK818_BUCK_VSEL_MASK 0x3f 36 + #define RK818_BUCK4_VSEL_MASK 0x1f 37 + #define RK818_LDO_VSEL_MASK 0x1f 38 + #define RK818_LDO3_ON_VSEL_MASK 0xf 39 + #define RK818_BOOST_ON_VSEL_MASK 0xe0 38 40 39 41 /* Ramp rate definitions for buck1 / buck2 only */ 40 42 #define RK808_RAMP_RATE_OFFSET 3 ··· 464 454 RK808_DCDC_EN_REG, BIT(6)), 465 455 }; 466 456 457 + static const struct regulator_desc rk818_reg[] = { 458 + { 459 + .name = "DCDC_REG1", 460 + .supply_name = "vcc1", 461 + .of_match = of_match_ptr("DCDC_REG1"), 462 + .regulators_node = of_match_ptr("regulators"), 463 + .id = RK818_ID_DCDC1, 464 + .ops = &rk808_reg_ops, 465 + .type = REGULATOR_VOLTAGE, 466 + .min_uV = 712500, 467 + .uV_step = 12500, 468 + .n_voltages = 64, 469 + .vsel_reg = RK818_BUCK1_ON_VSEL_REG, 470 + .vsel_mask = RK818_BUCK_VSEL_MASK, 471 + .enable_reg = RK818_DCDC_EN_REG, 472 + .enable_mask = BIT(0), 473 + .owner = THIS_MODULE, 474 + }, { 475 + .name = "DCDC_REG2", 476 + .supply_name = "vcc2", 477 + .of_match = of_match_ptr("DCDC_REG2"), 478 + .regulators_node = of_match_ptr("regulators"), 479 + .id = RK818_ID_DCDC2, 480 + .ops = &rk808_reg_ops, 481 + .type = REGULATOR_VOLTAGE, 482 + .min_uV = 712500, 483 + .uV_step = 12500, 484 + .n_voltages = 64, 485 + .vsel_reg = RK818_BUCK2_ON_VSEL_REG, 486 + .vsel_mask = RK818_BUCK_VSEL_MASK, 487 + .enable_reg = RK818_DCDC_EN_REG, 488 + .enable_mask = BIT(1), 489 + .owner = THIS_MODULE, 490 + }, { 491 + .name = "DCDC_REG3", 492 + .supply_name = "vcc3", 493 + .of_match = of_match_ptr("DCDC_REG3"), 494 + .regulators_node = of_match_ptr("regulators"), 495 + .id = RK818_ID_DCDC3, 496 + .ops = &rk808_switch_ops, 497 + .type = REGULATOR_VOLTAGE, 498 + .n_voltages = 1, 499 + .enable_reg = RK818_DCDC_EN_REG, 500 + .enable_mask = BIT(2), 501 + .owner = THIS_MODULE, 502 + }, 503 + RK8XX_DESC(RK818_ID_DCDC4, "DCDC_REG4", "vcc4", 1800, 3600, 100, 504 + RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK, 505 + RK818_DCDC_EN_REG, BIT(3), 0), 506 + RK8XX_DESC(RK818_ID_BOOST, "DCDC_BOOST", "boost", 4700, 5400, 100, 507 + RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK, 508 + RK818_DCDC_EN_REG, BIT(4), 0), 509 + RK8XX_DESC(RK818_ID_LDO1, "LDO_REG1", "vcc6", 1800, 3400, 100, 510 + RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 511 + BIT(0), 400), 512 + RK8XX_DESC(RK818_ID_LDO2, "LDO_REG2", "vcc6", 1800, 3400, 100, 513 + RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 514 + BIT(1), 400), 515 + { 516 + .name = "LDO_REG3", 517 + .supply_name = "vcc7", 518 + .of_match = of_match_ptr("LDO_REG3"), 519 + .regulators_node = of_match_ptr("regulators"), 520 + .id = RK818_ID_LDO3, 521 + .ops = &rk808_reg_ops_ranges, 522 + .type = REGULATOR_VOLTAGE, 523 + .n_voltages = 16, 524 + .linear_ranges = rk808_ldo3_voltage_ranges, 525 + .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges), 526 + .vsel_reg = RK818_LDO3_ON_VSEL_REG, 527 + .vsel_mask = RK818_LDO3_ON_VSEL_MASK, 528 + .enable_reg = RK818_LDO_EN_REG, 529 + .enable_mask = BIT(2), 530 + .enable_time = 400, 531 + .owner = THIS_MODULE, 532 + }, 533 + RK8XX_DESC(RK818_ID_LDO4, "LDO_REG4", "vcc8", 1800, 3400, 100, 534 + RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 535 + BIT(3), 400), 536 + RK8XX_DESC(RK818_ID_LDO5, "LDO_REG5", "vcc7", 1800, 3400, 100, 537 + RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 538 + BIT(4), 400), 539 + RK8XX_DESC(RK818_ID_LDO6, "LDO_REG6", "vcc8", 800, 2500, 100, 540 + RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 541 + BIT(5), 400), 542 + RK8XX_DESC(RK818_ID_LDO7, "LDO_REG7", "vcc7", 800, 2500, 100, 543 + RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 544 + BIT(6), 400), 545 + RK8XX_DESC(RK818_ID_LDO8, "LDO_REG8", "vcc8", 1800, 3400, 100, 546 + RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK818_LDO_EN_REG, 547 + BIT(7), 400), 548 + RK8XX_DESC(RK818_ID_LDO9, "LDO_REG9", "vcc9", 1800, 3400, 100, 549 + RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK, 550 + RK818_DCDC_EN_REG, BIT(5), 400), 551 + RK8XX_DESC_SWITCH(RK818_ID_SWITCH, "SWITCH_REG", "vcc9", 552 + RK818_DCDC_EN_REG, BIT(6)), 553 + RK8XX_DESC_SWITCH(RK818_ID_HDMI_SWITCH, "HDMI_SWITCH", "h_5v", 554 + RK818_H5V_EN_REG, BIT(0)), 555 + RK8XX_DESC_SWITCH(RK818_ID_OTG_SWITCH, "OTG_SWITCH", "usb", 556 + RK818_DCDC_EN_REG, BIT(7)), 557 + }; 558 + 467 559 static int rk808_regulator_dt_parse_pdata(struct device *dev, 468 560 struct device *client_dev, 469 561 struct regmap *map, ··· 611 499 struct regulator_config config = {}; 612 500 struct regulator_dev *rk808_rdev; 613 501 struct rk808_regulator_data *pdata; 614 - int ret, i; 502 + const struct regulator_desc *regulators; 503 + int ret, i, nregulators; 615 504 616 505 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 617 506 if (!pdata) ··· 625 512 626 513 platform_set_drvdata(pdev, pdata); 627 514 515 + switch (rk808->variant) { 516 + case RK808_ID: 517 + regulators = rk808_reg; 518 + nregulators = RK808_NUM_REGULATORS; 519 + break; 520 + case RK818_ID: 521 + regulators = rk818_reg; 522 + nregulators = RK818_NUM_REGULATORS; 523 + break; 524 + default: 525 + dev_err(&client->dev, "unsupported RK8XX ID %lu\n", 526 + rk808->variant); 527 + return -EINVAL; 528 + } 529 + 628 530 config.dev = &client->dev; 629 531 config.driver_data = pdata; 630 532 config.regmap = rk808->regmap; 631 533 632 534 /* Instantiate the regulators */ 633 - for (i = 0; i < RK808_NUM_REGULATORS; i++) { 535 + for (i = 0; i < nregulators; i++) { 634 536 rk808_rdev = devm_regulator_register(&pdev->dev, 635 - &rk808_reg[i], &config); 537 + &regulators[i], &config); 636 538 if (IS_ERR(rk808_rdev)) { 637 539 dev_err(&client->dev, 638 540 "failed to register %d regulator\n", i); ··· 667 539 668 540 module_platform_driver(rk808_regulator_driver); 669 541 670 - MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); 671 - MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>"); 672 - MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>"); 542 + MODULE_DESCRIPTION("regulator driver for the RK808/RK818 series PMICs"); 543 + MODULE_AUTHOR("Chris Zhong <zyw@rock-chips.com>"); 544 + MODULE_AUTHOR("Zhang Qing <zhangqing@rock-chips.com>"); 545 + MODULE_AUTHOR("Wadim Egorov <w.egorov@phytec.de>"); 673 546 MODULE_LICENSE("GPL"); 674 547 MODULE_ALIAS("platform:rk808-regulator");
+12 -2
drivers/rtc/Kconfig
··· 187 187 This driver can also be built as a module. If so, the module 188 188 will be called rtc-abx80x. 189 189 190 + config RTC_DRV_AC100 191 + tristate "X-Powers AC100" 192 + depends on MFD_AC100 193 + help 194 + If you say yes here you get support for the real-time clock found 195 + in X-Powers AC100 family peripheral ICs. 196 + 197 + This driver can also be built as a module. If so, the module 198 + will be called rtc-ac100. 199 + 190 200 config RTC_DRV_AS3722 191 201 tristate "ams AS3722 RTC driver" 192 202 depends on MFD_AS3722 ··· 338 328 will be called rtc-max77686. 339 329 340 330 config RTC_DRV_RK808 341 - tristate "Rockchip RK808 RTC" 331 + tristate "Rockchip RK808/RK818 RTC" 342 332 depends on MFD_RK808 343 333 help 344 334 If you say yes here you will get support for the 345 - RTC of RK808 PMIC. 335 + RTC of RK808 and RK818 PMIC. 346 336 347 337 This driver can also be built as a module. If so, the module 348 338 will be called rk808-rtc.
+1
drivers/rtc/Makefile
··· 27 27 obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o 28 28 obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o 29 29 obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o 30 + obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o 30 31 obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o 31 32 obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o 32 33 obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o
+627
drivers/rtc/rtc-ac100.c
··· 1 + /* 2 + * RTC Driver for X-Powers AC100 3 + * 4 + * Copyright (c) 2016 Chen-Yu Tsai 5 + * 6 + * Chen-Yu Tsai <wens@csie.org> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, but WITHOUT 13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 + * more details. 16 + */ 17 + 18 + #include <linux/bcd.h> 19 + #include <linux/clk-provider.h> 20 + #include <linux/device.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/kernel.h> 23 + #include <linux/mfd/ac100.h> 24 + #include <linux/module.h> 25 + #include <linux/mutex.h> 26 + #include <linux/of.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/regmap.h> 29 + #include <linux/rtc.h> 30 + #include <linux/types.h> 31 + 32 + /* Control register */ 33 + #define AC100_RTC_CTRL_24HOUR BIT(0) 34 + 35 + /* Clock output register bits */ 36 + #define AC100_CLKOUT_PRE_DIV_SHIFT 5 37 + #define AC100_CLKOUT_PRE_DIV_WIDTH 3 38 + #define AC100_CLKOUT_MUX_SHIFT 4 39 + #define AC100_CLKOUT_MUX_WIDTH 1 40 + #define AC100_CLKOUT_DIV_SHIFT 1 41 + #define AC100_CLKOUT_DIV_WIDTH 3 42 + #define AC100_CLKOUT_EN BIT(0) 43 + 44 + /* RTC */ 45 + #define AC100_RTC_SEC_MASK GENMASK(6, 0) 46 + #define AC100_RTC_MIN_MASK GENMASK(6, 0) 47 + #define AC100_RTC_HOU_MASK GENMASK(5, 0) 48 + #define AC100_RTC_WEE_MASK GENMASK(2, 0) 49 + #define AC100_RTC_DAY_MASK GENMASK(5, 0) 50 + #define AC100_RTC_MON_MASK GENMASK(4, 0) 51 + #define AC100_RTC_YEA_MASK GENMASK(7, 0) 52 + #define AC100_RTC_YEA_LEAP BIT(15) 53 + #define AC100_RTC_UPD_TRIGGER BIT(15) 54 + 55 + /* Alarm (wall clock) */ 56 + #define AC100_ALM_INT_ENABLE BIT(0) 57 + 58 + #define AC100_ALM_SEC_MASK GENMASK(6, 0) 59 + #define AC100_ALM_MIN_MASK GENMASK(6, 0) 60 + #define AC100_ALM_HOU_MASK GENMASK(5, 0) 61 + #define AC100_ALM_WEE_MASK GENMASK(2, 0) 62 + #define AC100_ALM_DAY_MASK GENMASK(5, 0) 63 + #define AC100_ALM_MON_MASK GENMASK(4, 0) 64 + #define AC100_ALM_YEA_MASK GENMASK(7, 0) 65 + #define AC100_ALM_ENABLE_FLAG BIT(15) 66 + #define AC100_ALM_UPD_TRIGGER BIT(15) 67 + 68 + /* 69 + * The year parameter passed to the driver is usually an offset relative to 70 + * the year 1900. This macro is used to convert this offset to another one 71 + * relative to the minimum year allowed by the hardware. 72 + * 73 + * The year range is 1970 - 2069. This range is selected to match Allwinner's 74 + * driver. 75 + */ 76 + #define AC100_YEAR_MIN 1970 77 + #define AC100_YEAR_MAX 2069 78 + #define AC100_YEAR_OFF (AC100_YEAR_MIN - 1900) 79 + 80 + struct ac100_clkout { 81 + struct clk_hw hw; 82 + struct regmap *regmap; 83 + u8 offset; 84 + }; 85 + 86 + #define to_ac100_clkout(_hw) container_of(_hw, struct ac100_clkout, hw) 87 + 88 + #define AC100_RTC_32K_NAME "ac100-rtc-32k" 89 + #define AC100_RTC_32K_RATE 32768 90 + #define AC100_CLKOUT_NUM 3 91 + 92 + static const char * const ac100_clkout_names[AC100_CLKOUT_NUM] = { 93 + "ac100-cko1-rtc", 94 + "ac100-cko2-rtc", 95 + "ac100-cko3-rtc", 96 + }; 97 + 98 + struct ac100_rtc_dev { 99 + struct rtc_device *rtc; 100 + struct device *dev; 101 + struct regmap *regmap; 102 + int irq; 103 + unsigned long alarm; 104 + 105 + struct clk_hw *rtc_32k_clk; 106 + struct ac100_clkout clks[AC100_CLKOUT_NUM]; 107 + struct clk_hw_onecell_data *clk_data; 108 + }; 109 + 110 + /** 111 + * Clock controls for 3 clock output pins 112 + */ 113 + 114 + static const struct clk_div_table ac100_clkout_prediv[] = { 115 + { .val = 0, .div = 1 }, 116 + { .val = 1, .div = 2 }, 117 + { .val = 2, .div = 4 }, 118 + { .val = 3, .div = 8 }, 119 + { .val = 4, .div = 16 }, 120 + { .val = 5, .div = 32 }, 121 + { .val = 6, .div = 64 }, 122 + { .val = 7, .div = 122 }, 123 + { }, 124 + }; 125 + 126 + /* Abuse the fact that one parent is 32768 Hz, and the other is 4 MHz */ 127 + static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw, 128 + unsigned long prate) 129 + { 130 + struct ac100_clkout *clk = to_ac100_clkout(hw); 131 + unsigned int reg, div; 132 + 133 + regmap_read(clk->regmap, clk->offset, &reg); 134 + 135 + /* Handle pre-divider first */ 136 + if (prate != AC100_RTC_32K_RATE) { 137 + div = (reg >> AC100_CLKOUT_PRE_DIV_SHIFT) & 138 + ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1); 139 + prate = divider_recalc_rate(hw, prate, div, 140 + ac100_clkout_prediv, 0); 141 + } 142 + 143 + div = (reg >> AC100_CLKOUT_DIV_SHIFT) & 144 + (BIT(AC100_CLKOUT_DIV_WIDTH) - 1); 145 + return divider_recalc_rate(hw, prate, div, NULL, 146 + CLK_DIVIDER_POWER_OF_TWO); 147 + } 148 + 149 + static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 150 + unsigned long prate) 151 + { 152 + unsigned long best_rate = 0, tmp_rate, tmp_prate; 153 + int i; 154 + 155 + if (prate == AC100_RTC_32K_RATE) 156 + return divider_round_rate(hw, rate, &prate, NULL, 157 + AC100_CLKOUT_DIV_WIDTH, 158 + CLK_DIVIDER_POWER_OF_TWO); 159 + 160 + for (i = 0; ac100_clkout_prediv[i].div; i++) { 161 + tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val); 162 + tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL, 163 + AC100_CLKOUT_DIV_WIDTH, 164 + CLK_DIVIDER_POWER_OF_TWO); 165 + 166 + if (tmp_rate > rate) 167 + continue; 168 + if (rate - tmp_rate < best_rate - tmp_rate) 169 + best_rate = tmp_rate; 170 + } 171 + 172 + return best_rate; 173 + } 174 + 175 + static int ac100_clkout_determine_rate(struct clk_hw *hw, 176 + struct clk_rate_request *req) 177 + { 178 + struct clk_hw *best_parent; 179 + unsigned long best = 0; 180 + int i, num_parents = clk_hw_get_num_parents(hw); 181 + 182 + for (i = 0; i < num_parents; i++) { 183 + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); 184 + unsigned long tmp, prate = clk_hw_get_rate(parent); 185 + 186 + tmp = ac100_clkout_round_rate(hw, req->rate, prate); 187 + 188 + if (tmp > req->rate) 189 + continue; 190 + if (req->rate - tmp < req->rate - best) { 191 + best = tmp; 192 + best_parent = parent; 193 + } 194 + } 195 + 196 + if (!best) 197 + return -EINVAL; 198 + 199 + req->best_parent_hw = best_parent; 200 + req->best_parent_rate = best; 201 + req->rate = best; 202 + 203 + return 0; 204 + } 205 + 206 + static int ac100_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 207 + unsigned long prate) 208 + { 209 + struct ac100_clkout *clk = to_ac100_clkout(hw); 210 + int div = 0, pre_div = 0; 211 + 212 + do { 213 + div = divider_get_val(rate * ac100_clkout_prediv[pre_div].div, 214 + prate, NULL, AC100_CLKOUT_DIV_WIDTH, 215 + CLK_DIVIDER_POWER_OF_TWO); 216 + if (div >= 0) 217 + break; 218 + } while (prate != AC100_RTC_32K_RATE && 219 + ac100_clkout_prediv[++pre_div].div); 220 + 221 + if (div < 0) 222 + return div; 223 + 224 + pre_div = ac100_clkout_prediv[pre_div].val; 225 + 226 + regmap_update_bits(clk->regmap, clk->offset, 227 + ((1 << AC100_CLKOUT_DIV_WIDTH) - 1) << AC100_CLKOUT_DIV_SHIFT | 228 + ((1 << AC100_CLKOUT_PRE_DIV_WIDTH) - 1) << AC100_CLKOUT_PRE_DIV_SHIFT, 229 + (div - 1) << AC100_CLKOUT_DIV_SHIFT | 230 + (pre_div - 1) << AC100_CLKOUT_PRE_DIV_SHIFT); 231 + 232 + return 0; 233 + } 234 + 235 + static int ac100_clkout_prepare(struct clk_hw *hw) 236 + { 237 + struct ac100_clkout *clk = to_ac100_clkout(hw); 238 + 239 + return regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN, 240 + AC100_CLKOUT_EN); 241 + } 242 + 243 + static void ac100_clkout_unprepare(struct clk_hw *hw) 244 + { 245 + struct ac100_clkout *clk = to_ac100_clkout(hw); 246 + 247 + regmap_update_bits(clk->regmap, clk->offset, AC100_CLKOUT_EN, 0); 248 + } 249 + 250 + static int ac100_clkout_is_prepared(struct clk_hw *hw) 251 + { 252 + struct ac100_clkout *clk = to_ac100_clkout(hw); 253 + unsigned int reg; 254 + 255 + regmap_read(clk->regmap, clk->offset, &reg); 256 + 257 + return reg & AC100_CLKOUT_EN; 258 + } 259 + 260 + static u8 ac100_clkout_get_parent(struct clk_hw *hw) 261 + { 262 + struct ac100_clkout *clk = to_ac100_clkout(hw); 263 + unsigned int reg; 264 + 265 + regmap_read(clk->regmap, clk->offset, &reg); 266 + 267 + return (reg >> AC100_CLKOUT_MUX_SHIFT) & 0x1; 268 + } 269 + 270 + static int ac100_clkout_set_parent(struct clk_hw *hw, u8 index) 271 + { 272 + struct ac100_clkout *clk = to_ac100_clkout(hw); 273 + 274 + return regmap_update_bits(clk->regmap, clk->offset, 275 + BIT(AC100_CLKOUT_MUX_SHIFT), 276 + index ? BIT(AC100_CLKOUT_MUX_SHIFT) : 0); 277 + } 278 + 279 + static const struct clk_ops ac100_clkout_ops = { 280 + .prepare = ac100_clkout_prepare, 281 + .unprepare = ac100_clkout_unprepare, 282 + .is_prepared = ac100_clkout_is_prepared, 283 + .recalc_rate = ac100_clkout_recalc_rate, 284 + .determine_rate = ac100_clkout_determine_rate, 285 + .get_parent = ac100_clkout_get_parent, 286 + .set_parent = ac100_clkout_set_parent, 287 + .set_rate = ac100_clkout_set_rate, 288 + }; 289 + 290 + static int ac100_rtc_register_clks(struct ac100_rtc_dev *chip) 291 + { 292 + struct device_node *np = chip->dev->of_node; 293 + const char *parents[2] = {AC100_RTC_32K_NAME}; 294 + int i, ret; 295 + 296 + chip->clk_data = devm_kzalloc(chip->dev, sizeof(*chip->clk_data) + 297 + sizeof(*chip->clk_data->hws) * 298 + AC100_CLKOUT_NUM, 299 + GFP_KERNEL); 300 + if (!chip->clk_data) 301 + return -ENOMEM; 302 + 303 + chip->rtc_32k_clk = clk_hw_register_fixed_rate(chip->dev, 304 + AC100_RTC_32K_NAME, 305 + NULL, 0, 306 + AC100_RTC_32K_RATE); 307 + if (IS_ERR(chip->rtc_32k_clk)) { 308 + ret = PTR_ERR(chip->rtc_32k_clk); 309 + dev_err(chip->dev, "Failed to register RTC-32k clock: %d\n", 310 + ret); 311 + return ret; 312 + } 313 + 314 + parents[1] = of_clk_get_parent_name(np, 0); 315 + if (!parents[1]) { 316 + dev_err(chip->dev, "Failed to get ADDA 4M clock\n"); 317 + return -EINVAL; 318 + } 319 + 320 + for (i = 0; i < AC100_CLKOUT_NUM; i++) { 321 + struct ac100_clkout *clk = &chip->clks[i]; 322 + struct clk_init_data init = { 323 + .name = ac100_clkout_names[i], 324 + .ops = &ac100_clkout_ops, 325 + .parent_names = parents, 326 + .num_parents = ARRAY_SIZE(parents), 327 + .flags = 0, 328 + }; 329 + 330 + clk->regmap = chip->regmap; 331 + clk->offset = AC100_CLKOUT_CTRL1 + i; 332 + clk->hw.init = &init; 333 + 334 + ret = devm_clk_hw_register(chip->dev, &clk->hw); 335 + if (ret) { 336 + dev_err(chip->dev, "Failed to register clk '%s': %d\n", 337 + init.name, ret); 338 + goto err_unregister_rtc_32k; 339 + } 340 + 341 + chip->clk_data->hws[i] = &clk->hw; 342 + } 343 + 344 + chip->clk_data->num = i; 345 + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, chip->clk_data); 346 + if (ret) 347 + goto err_unregister_rtc_32k; 348 + 349 + return 0; 350 + 351 + err_unregister_rtc_32k: 352 + clk_unregister_fixed_rate(chip->rtc_32k_clk->clk); 353 + 354 + return ret; 355 + } 356 + 357 + static void ac100_rtc_unregister_clks(struct ac100_rtc_dev *chip) 358 + { 359 + of_clk_del_provider(chip->dev->of_node); 360 + clk_unregister_fixed_rate(chip->rtc_32k_clk->clk); 361 + } 362 + 363 + /** 364 + * RTC related bits 365 + */ 366 + static int ac100_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm) 367 + { 368 + struct ac100_rtc_dev *chip = dev_get_drvdata(dev); 369 + struct regmap *regmap = chip->regmap; 370 + u16 reg[7]; 371 + int ret; 372 + 373 + ret = regmap_bulk_read(regmap, AC100_RTC_SEC, reg, 7); 374 + if (ret) 375 + return ret; 376 + 377 + rtc_tm->tm_sec = bcd2bin(reg[0] & AC100_RTC_SEC_MASK); 378 + rtc_tm->tm_min = bcd2bin(reg[1] & AC100_RTC_MIN_MASK); 379 + rtc_tm->tm_hour = bcd2bin(reg[2] & AC100_RTC_HOU_MASK); 380 + rtc_tm->tm_wday = bcd2bin(reg[3] & AC100_RTC_WEE_MASK); 381 + rtc_tm->tm_mday = bcd2bin(reg[4] & AC100_RTC_DAY_MASK); 382 + rtc_tm->tm_mon = bcd2bin(reg[5] & AC100_RTC_MON_MASK) - 1; 383 + rtc_tm->tm_year = bcd2bin(reg[6] & AC100_RTC_YEA_MASK) + 384 + AC100_YEAR_OFF; 385 + 386 + return rtc_valid_tm(rtc_tm); 387 + } 388 + 389 + static int ac100_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) 390 + { 391 + struct ac100_rtc_dev *chip = dev_get_drvdata(dev); 392 + struct regmap *regmap = chip->regmap; 393 + int year; 394 + u16 reg[8]; 395 + 396 + /* our RTC has a limited year range... */ 397 + year = rtc_tm->tm_year - AC100_YEAR_OFF; 398 + if (year < 0 || year > (AC100_YEAR_MAX - 1900)) { 399 + dev_err(dev, "rtc only supports year in range %d - %d\n", 400 + AC100_YEAR_MIN, AC100_YEAR_MAX); 401 + return -EINVAL; 402 + } 403 + 404 + /* convert to BCD */ 405 + reg[0] = bin2bcd(rtc_tm->tm_sec) & AC100_RTC_SEC_MASK; 406 + reg[1] = bin2bcd(rtc_tm->tm_min) & AC100_RTC_MIN_MASK; 407 + reg[2] = bin2bcd(rtc_tm->tm_hour) & AC100_RTC_HOU_MASK; 408 + reg[3] = bin2bcd(rtc_tm->tm_wday) & AC100_RTC_WEE_MASK; 409 + reg[4] = bin2bcd(rtc_tm->tm_mday) & AC100_RTC_DAY_MASK; 410 + reg[5] = bin2bcd(rtc_tm->tm_mon + 1) & AC100_RTC_MON_MASK; 411 + reg[6] = bin2bcd(year) & AC100_RTC_YEA_MASK; 412 + /* trigger write */ 413 + reg[7] = AC100_RTC_UPD_TRIGGER; 414 + 415 + /* Is it a leap year? */ 416 + if (is_leap_year(year + AC100_YEAR_OFF + 1900)) 417 + reg[6] |= AC100_RTC_YEA_LEAP; 418 + 419 + return regmap_bulk_write(regmap, AC100_RTC_SEC, reg, 8); 420 + } 421 + 422 + static int ac100_rtc_alarm_irq_enable(struct device *dev, unsigned int en) 423 + { 424 + struct ac100_rtc_dev *chip = dev_get_drvdata(dev); 425 + struct regmap *regmap = chip->regmap; 426 + unsigned int val; 427 + 428 + val = en ? AC100_ALM_INT_ENABLE : 0; 429 + 430 + return regmap_write(regmap, AC100_ALM_INT_ENA, val); 431 + } 432 + 433 + static int ac100_rtc_get_alarm(struct device *dev, struct rtc_wkalrm *alrm) 434 + { 435 + struct ac100_rtc_dev *chip = dev_get_drvdata(dev); 436 + struct regmap *regmap = chip->regmap; 437 + struct rtc_time *alrm_tm = &alrm->time; 438 + u16 reg[7]; 439 + unsigned int val; 440 + int ret; 441 + 442 + ret = regmap_read(regmap, AC100_ALM_INT_ENA, &val); 443 + if (ret) 444 + return ret; 445 + 446 + alrm->enabled = !!(val & AC100_ALM_INT_ENABLE); 447 + 448 + ret = regmap_bulk_read(regmap, AC100_ALM_SEC, reg, 7); 449 + if (ret) 450 + return ret; 451 + 452 + alrm_tm->tm_sec = bcd2bin(reg[0] & AC100_ALM_SEC_MASK); 453 + alrm_tm->tm_min = bcd2bin(reg[1] & AC100_ALM_MIN_MASK); 454 + alrm_tm->tm_hour = bcd2bin(reg[2] & AC100_ALM_HOU_MASK); 455 + alrm_tm->tm_wday = bcd2bin(reg[3] & AC100_ALM_WEE_MASK); 456 + alrm_tm->tm_mday = bcd2bin(reg[4] & AC100_ALM_DAY_MASK); 457 + alrm_tm->tm_mon = bcd2bin(reg[5] & AC100_ALM_MON_MASK) - 1; 458 + alrm_tm->tm_year = bcd2bin(reg[6] & AC100_ALM_YEA_MASK) + 459 + AC100_YEAR_OFF; 460 + 461 + return 0; 462 + } 463 + 464 + static int ac100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 465 + { 466 + struct ac100_rtc_dev *chip = dev_get_drvdata(dev); 467 + struct regmap *regmap = chip->regmap; 468 + struct rtc_time *alrm_tm = &alrm->time; 469 + u16 reg[8]; 470 + int year; 471 + int ret; 472 + 473 + /* our alarm has a limited year range... */ 474 + year = alrm_tm->tm_year - AC100_YEAR_OFF; 475 + if (year < 0 || year > (AC100_YEAR_MAX - 1900)) { 476 + dev_err(dev, "alarm only supports year in range %d - %d\n", 477 + AC100_YEAR_MIN, AC100_YEAR_MAX); 478 + return -EINVAL; 479 + } 480 + 481 + /* convert to BCD */ 482 + reg[0] = (bin2bcd(alrm_tm->tm_sec) & AC100_ALM_SEC_MASK) | 483 + AC100_ALM_ENABLE_FLAG; 484 + reg[1] = (bin2bcd(alrm_tm->tm_min) & AC100_ALM_MIN_MASK) | 485 + AC100_ALM_ENABLE_FLAG; 486 + reg[2] = (bin2bcd(alrm_tm->tm_hour) & AC100_ALM_HOU_MASK) | 487 + AC100_ALM_ENABLE_FLAG; 488 + /* Do not enable weekday alarm */ 489 + reg[3] = bin2bcd(alrm_tm->tm_wday) & AC100_ALM_WEE_MASK; 490 + reg[4] = (bin2bcd(alrm_tm->tm_mday) & AC100_ALM_DAY_MASK) | 491 + AC100_ALM_ENABLE_FLAG; 492 + reg[5] = (bin2bcd(alrm_tm->tm_mon + 1) & AC100_ALM_MON_MASK) | 493 + AC100_ALM_ENABLE_FLAG; 494 + reg[6] = (bin2bcd(year) & AC100_ALM_YEA_MASK) | 495 + AC100_ALM_ENABLE_FLAG; 496 + /* trigger write */ 497 + reg[7] = AC100_ALM_UPD_TRIGGER; 498 + 499 + ret = regmap_bulk_write(regmap, AC100_ALM_SEC, reg, 8); 500 + if (ret) 501 + return ret; 502 + 503 + return ac100_rtc_alarm_irq_enable(dev, alrm->enabled); 504 + } 505 + 506 + static irqreturn_t ac100_rtc_irq(int irq, void *data) 507 + { 508 + struct ac100_rtc_dev *chip = data; 509 + struct regmap *regmap = chip->regmap; 510 + unsigned int val = 0; 511 + int ret; 512 + 513 + mutex_lock(&chip->rtc->ops_lock); 514 + 515 + /* read status */ 516 + ret = regmap_read(regmap, AC100_ALM_INT_STA, &val); 517 + if (ret) 518 + goto out; 519 + 520 + if (val & AC100_ALM_INT_ENABLE) { 521 + /* signal rtc framework */ 522 + rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF); 523 + 524 + /* clear status */ 525 + ret = regmap_write(regmap, AC100_ALM_INT_STA, val); 526 + if (ret) 527 + goto out; 528 + 529 + /* disable interrupt */ 530 + ret = ac100_rtc_alarm_irq_enable(chip->dev, 0); 531 + if (ret) 532 + goto out; 533 + } 534 + 535 + out: 536 + mutex_unlock(&chip->rtc->ops_lock); 537 + return IRQ_HANDLED; 538 + } 539 + 540 + static const struct rtc_class_ops ac100_rtc_ops = { 541 + .read_time = ac100_rtc_get_time, 542 + .set_time = ac100_rtc_set_time, 543 + .read_alarm = ac100_rtc_get_alarm, 544 + .set_alarm = ac100_rtc_set_alarm, 545 + .alarm_irq_enable = ac100_rtc_alarm_irq_enable, 546 + }; 547 + 548 + static int ac100_rtc_probe(struct platform_device *pdev) 549 + { 550 + struct ac100_dev *ac100 = dev_get_drvdata(pdev->dev.parent); 551 + struct ac100_rtc_dev *chip; 552 + int ret; 553 + 554 + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); 555 + platform_set_drvdata(pdev, chip); 556 + chip->dev = &pdev->dev; 557 + chip->regmap = ac100->regmap; 558 + 559 + chip->irq = platform_get_irq(pdev, 0); 560 + if (chip->irq < 0) { 561 + dev_err(&pdev->dev, "No IRQ resource\n"); 562 + return chip->irq; 563 + } 564 + 565 + ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, 566 + ac100_rtc_irq, 567 + IRQF_SHARED | IRQF_ONESHOT, 568 + dev_name(&pdev->dev), chip); 569 + if (ret) { 570 + dev_err(&pdev->dev, "Could not request IRQ\n"); 571 + return ret; 572 + } 573 + 574 + /* always use 24 hour mode */ 575 + regmap_write_bits(chip->regmap, AC100_RTC_CTRL, AC100_RTC_CTRL_24HOUR, 576 + AC100_RTC_CTRL_24HOUR); 577 + 578 + /* disable counter alarm interrupt */ 579 + regmap_write(chip->regmap, AC100_ALM_INT_ENA, 0); 580 + 581 + /* clear counter alarm pending interrupts */ 582 + regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE); 583 + 584 + chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ac100", 585 + &ac100_rtc_ops, THIS_MODULE); 586 + if (IS_ERR(chip->rtc)) { 587 + dev_err(&pdev->dev, "unable to register device\n"); 588 + return PTR_ERR(chip->rtc); 589 + } 590 + 591 + ret = ac100_rtc_register_clks(chip); 592 + if (ret) 593 + return ret; 594 + 595 + dev_info(&pdev->dev, "RTC enabled\n"); 596 + 597 + return 0; 598 + } 599 + 600 + static int ac100_rtc_remove(struct platform_device *pdev) 601 + { 602 + struct ac100_rtc_dev *chip = platform_get_drvdata(pdev); 603 + 604 + ac100_rtc_unregister_clks(chip); 605 + 606 + return 0; 607 + } 608 + 609 + static const struct of_device_id ac100_rtc_match[] = { 610 + { .compatible = "x-powers,ac100-rtc" }, 611 + { }, 612 + }; 613 + MODULE_DEVICE_TABLE(of, ac100_rtc_match); 614 + 615 + static struct platform_driver ac100_rtc_driver = { 616 + .probe = ac100_rtc_probe, 617 + .remove = ac100_rtc_remove, 618 + .driver = { 619 + .name = "ac100-rtc", 620 + .of_match_table = of_match_ptr(ac100_rtc_match), 621 + }, 622 + }; 623 + module_platform_driver(ac100_rtc_driver); 624 + 625 + MODULE_DESCRIPTION("X-Powers AC100 RTC driver"); 626 + MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); 627 + MODULE_LICENSE("GPL v2");
+1
drivers/rtc/rtc-pm8xxx.c
··· 428 428 */ 429 429 static const struct of_device_id pm8xxx_id_table[] = { 430 430 { .compatible = "qcom,pm8921-rtc", .data = &pm8921_regs }, 431 + { .compatible = "qcom,pm8018-rtc", .data = &pm8921_regs }, 431 432 { .compatible = "qcom,pm8058-rtc", .data = &pm8058_regs }, 432 433 { .compatible = "qcom,pm8941-rtc", .data = &pm8941_regs }, 433 434 { },
+22
include/dt-bindings/mfd/qcom-rpm.h
··· 147 147 #define QCOM_RPM_SMB208_S1b 137 148 148 #define QCOM_RPM_SMB208_S2a 138 149 149 #define QCOM_RPM_SMB208_S2b 139 150 + #define QCOM_RPM_PM8018_SMPS1 140 151 + #define QCOM_RPM_PM8018_SMPS2 141 152 + #define QCOM_RPM_PM8018_SMPS3 142 153 + #define QCOM_RPM_PM8018_SMPS4 143 154 + #define QCOM_RPM_PM8018_SMPS5 144 155 + #define QCOM_RPM_PM8018_LDO1 145 156 + #define QCOM_RPM_PM8018_LDO2 146 157 + #define QCOM_RPM_PM8018_LDO3 147 158 + #define QCOM_RPM_PM8018_LDO4 148 159 + #define QCOM_RPM_PM8018_LDO5 149 160 + #define QCOM_RPM_PM8018_LDO6 150 161 + #define QCOM_RPM_PM8018_LDO7 151 162 + #define QCOM_RPM_PM8018_LDO8 152 163 + #define QCOM_RPM_PM8018_LDO9 153 164 + #define QCOM_RPM_PM8018_LDO10 154 165 + #define QCOM_RPM_PM8018_LDO11 155 166 + #define QCOM_RPM_PM8018_LDO12 156 167 + #define QCOM_RPM_PM8018_LDO13 157 168 + #define QCOM_RPM_PM8018_LDO14 158 169 + #define QCOM_RPM_PM8018_LVS1 159 170 + #define QCOM_RPM_PM8018_NCP 160 171 + #define QCOM_RPM_VOLTAGE_CORNER 161 150 172 151 173 /* 152 174 * Constants used to select force mode for regulators.
+2 -2
include/linux/mfd/88pm80x.h
··· 350 350 int irq = platform_get_irq(pdev, 0); 351 351 352 352 if (device_may_wakeup(dev)) 353 - set_bit((1 << irq), &chip->wu_flag); 353 + set_bit(irq, &chip->wu_flag); 354 354 355 355 return 0; 356 356 } ··· 362 362 int irq = platform_get_irq(pdev, 0); 363 363 364 364 if (device_may_wakeup(dev)) 365 - clear_bit((1 << irq), &chip->wu_flag); 365 + clear_bit(irq, &chip->wu_flag); 366 366 367 367 return 0; 368 368 }
+2
include/linux/mfd/abx500/ab8500.h
··· 63 63 #define AB8500_STE_TEST 0x14 64 64 #define AB8500_OTP_EMUL 0x15 65 65 66 + #define AB8500_DEBUG_FIELD_LAST 0x16 67 + 66 68 /* 67 69 * Interrupts 68 70 * Values used to index into array ab8500_irq_regoffset[] defined in
+178
include/linux/mfd/ac100.h
··· 1 + /* 2 + * Functions and registers to access AC100 codec / RTC combo IC. 3 + * 4 + * Copyright (C) 2016 Chen-Yu Tsai 5 + * 6 + * Chen-Yu Tsai <wens@csie.org> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #ifndef __LINUX_MFD_AC100_H 14 + #define __LINUX_MFD_AC100_H 15 + 16 + #include <linux/regmap.h> 17 + 18 + struct ac100_dev { 19 + struct device *dev; 20 + struct regmap *regmap; 21 + }; 22 + 23 + /* Audio codec related registers */ 24 + #define AC100_CHIP_AUDIO_RST 0x00 25 + #define AC100_PLL_CTRL1 0x01 26 + #define AC100_PLL_CTRL2 0x02 27 + #define AC100_SYSCLK_CTRL 0x03 28 + #define AC100_MOD_CLK_ENA 0x04 29 + #define AC100_MOD_RST_CTRL 0x05 30 + #define AC100_I2S_SR_CTRL 0x06 31 + 32 + /* I2S1 interface */ 33 + #define AC100_I2S1_CLK_CTRL 0x10 34 + #define AC100_I2S1_SND_OUT_CTRL 0x11 35 + #define AC100_I2S1_SND_IN_CTRL 0x12 36 + #define AC100_I2S1_MXR_SRC 0x13 37 + #define AC100_I2S1_VOL_CTRL1 0x14 38 + #define AC100_I2S1_VOL_CTRL2 0x15 39 + #define AC100_I2S1_VOL_CTRL3 0x16 40 + #define AC100_I2S1_VOL_CTRL4 0x17 41 + #define AC100_I2S1_MXR_GAIN 0x18 42 + 43 + /* I2S2 interface */ 44 + #define AC100_I2S2_CLK_CTRL 0x20 45 + #define AC100_I2S2_SND_OUT_CTRL 0x21 46 + #define AC100_I2S2_SND_IN_CTRL 0x22 47 + #define AC100_I2S2_MXR_SRC 0x23 48 + #define AC100_I2S2_VOL_CTRL1 0x24 49 + #define AC100_I2S2_VOL_CTRL2 0x25 50 + #define AC100_I2S2_VOL_CTRL3 0x26 51 + #define AC100_I2S2_VOL_CTRL4 0x27 52 + #define AC100_I2S2_MXR_GAIN 0x28 53 + 54 + /* I2S3 interface */ 55 + #define AC100_I2S3_CLK_CTRL 0x30 56 + #define AC100_I2S3_SND_OUT_CTRL 0x31 57 + #define AC100_I2S3_SND_IN_CTRL 0x32 58 + #define AC100_I2S3_SIG_PATH_CTRL 0x33 59 + 60 + /* ADC digital controls */ 61 + #define AC100_ADC_DIG_CTRL 0x40 62 + #define AC100_ADC_VOL_CTRL 0x41 63 + 64 + /* HMIC plug sensing / key detection */ 65 + #define AC100_HMIC_CTRL1 0x44 66 + #define AC100_HMIC_CTRL2 0x45 67 + #define AC100_HMIC_STATUS 0x46 68 + 69 + /* DAC digital controls */ 70 + #define AC100_DAC_DIG_CTRL 0x48 71 + #define AC100_DAC_VOL_CTRL 0x49 72 + #define AC100_DAC_MXR_SRC 0x4c 73 + #define AC100_DAC_MXR_GAIN 0x4d 74 + 75 + /* Analog controls */ 76 + #define AC100_ADC_APC_CTRL 0x50 77 + #define AC100_ADC_SRC 0x51 78 + #define AC100_ADC_SRC_BST_CTRL 0x52 79 + #define AC100_OUT_MXR_DAC_A_CTRL 0x53 80 + #define AC100_OUT_MXR_SRC 0x54 81 + #define AC100_OUT_MXR_SRC_BST 0x55 82 + #define AC100_HPOUT_CTRL 0x56 83 + #define AC100_ERPOUT_CTRL 0x57 84 + #define AC100_SPKOUT_CTRL 0x58 85 + #define AC100_LINEOUT_CTRL 0x59 86 + 87 + /* ADC digital audio processing (high pass filter & auto gain control */ 88 + #define AC100_ADC_DAP_L_STA 0x80 89 + #define AC100_ADC_DAP_R_STA 0x81 90 + #define AC100_ADC_DAP_L_CTRL 0x82 91 + #define AC100_ADC_DAP_R_CTRL 0x83 92 + #define AC100_ADC_DAP_L_T_L 0x84 /* Left Target Level */ 93 + #define AC100_ADC_DAP_R_T_L 0x85 /* Right Target Level */ 94 + #define AC100_ADC_DAP_L_H_A_C 0x86 /* Left High Avg. Coef */ 95 + #define AC100_ADC_DAP_L_L_A_C 0x87 /* Left Low Avg. Coef */ 96 + #define AC100_ADC_DAP_R_H_A_C 0x88 /* Right High Avg. Coef */ 97 + #define AC100_ADC_DAP_R_L_A_C 0x89 /* Right Low Avg. Coef */ 98 + #define AC100_ADC_DAP_L_D_T 0x8a /* Left Decay Time */ 99 + #define AC100_ADC_DAP_L_A_T 0x8b /* Left Attack Time */ 100 + #define AC100_ADC_DAP_R_D_T 0x8c /* Right Decay Time */ 101 + #define AC100_ADC_DAP_R_A_T 0x8d /* Right Attack Time */ 102 + #define AC100_ADC_DAP_N_TH 0x8e /* Noise Threshold */ 103 + #define AC100_ADC_DAP_L_H_N_A_C 0x8f /* Left High Noise Avg. Coef */ 104 + #define AC100_ADC_DAP_L_L_N_A_C 0x90 /* Left Low Noise Avg. Coef */ 105 + #define AC100_ADC_DAP_R_H_N_A_C 0x91 /* Right High Noise Avg. Coef */ 106 + #define AC100_ADC_DAP_R_L_N_A_C 0x92 /* Right Low Noise Avg. Coef */ 107 + #define AC100_ADC_DAP_H_HPF_C 0x93 /* High High-Pass-Filter Coef */ 108 + #define AC100_ADC_DAP_L_HPF_C 0x94 /* Low High-Pass-Filter Coef */ 109 + #define AC100_ADC_DAP_OPT 0x95 /* AGC Optimum */ 110 + 111 + /* DAC digital audio processing (high pass filter & dynamic range control) */ 112 + #define AC100_DAC_DAP_CTRL 0xa0 113 + #define AC100_DAC_DAP_H_HPF_C 0xa1 /* High High-Pass-Filter Coef */ 114 + #define AC100_DAC_DAP_L_HPF_C 0xa2 /* Low High-Pass-Filter Coef */ 115 + #define AC100_DAC_DAP_L_H_E_A_C 0xa3 /* Left High Energy Avg Coef */ 116 + #define AC100_DAC_DAP_L_L_E_A_C 0xa4 /* Left Low Energy Avg Coef */ 117 + #define AC100_DAC_DAP_R_H_E_A_C 0xa5 /* Right High Energy Avg Coef */ 118 + #define AC100_DAC_DAP_R_L_E_A_C 0xa6 /* Right Low Energy Avg Coef */ 119 + #define AC100_DAC_DAP_H_G_D_T_C 0xa7 /* High Gain Delay Time Coef */ 120 + #define AC100_DAC_DAP_L_G_D_T_C 0xa8 /* Low Gain Delay Time Coef */ 121 + #define AC100_DAC_DAP_H_G_A_T_C 0xa9 /* High Gain Attack Time Coef */ 122 + #define AC100_DAC_DAP_L_G_A_T_C 0xaa /* Low Gain Attack Time Coef */ 123 + #define AC100_DAC_DAP_H_E_TH 0xab /* High Energy Threshold */ 124 + #define AC100_DAC_DAP_L_E_TH 0xac /* Low Energy Threshold */ 125 + #define AC100_DAC_DAP_H_G_K 0xad /* High Gain K parameter */ 126 + #define AC100_DAC_DAP_L_G_K 0xae /* Low Gain K parameter */ 127 + #define AC100_DAC_DAP_H_G_OFF 0xaf /* High Gain offset */ 128 + #define AC100_DAC_DAP_L_G_OFF 0xb0 /* Low Gain offset */ 129 + #define AC100_DAC_DAP_OPT 0xb1 /* DRC optimum */ 130 + 131 + /* Digital audio processing enable */ 132 + #define AC100_ADC_DAP_ENA 0xb4 133 + #define AC100_DAC_DAP_ENA 0xb5 134 + 135 + /* SRC control */ 136 + #define AC100_SRC1_CTRL1 0xb8 137 + #define AC100_SRC1_CTRL2 0xb9 138 + #define AC100_SRC1_CTRL3 0xba 139 + #define AC100_SRC1_CTRL4 0xbb 140 + #define AC100_SRC2_CTRL1 0xbc 141 + #define AC100_SRC2_CTRL2 0xbd 142 + #define AC100_SRC2_CTRL3 0xbe 143 + #define AC100_SRC2_CTRL4 0xbf 144 + 145 + /* RTC clk control */ 146 + #define AC100_CLK32K_ANALOG_CTRL 0xc0 147 + #define AC100_CLKOUT_CTRL1 0xc1 148 + #define AC100_CLKOUT_CTRL2 0xc2 149 + #define AC100_CLKOUT_CTRL3 0xc3 150 + 151 + /* RTC module */ 152 + #define AC100_RTC_RST 0xc6 153 + #define AC100_RTC_CTRL 0xc7 154 + #define AC100_RTC_SEC 0xc8 /* second */ 155 + #define AC100_RTC_MIN 0xc9 /* minute */ 156 + #define AC100_RTC_HOU 0xca /* hour */ 157 + #define AC100_RTC_WEE 0xcb /* weekday */ 158 + #define AC100_RTC_DAY 0xcc /* day */ 159 + #define AC100_RTC_MON 0xcd /* month */ 160 + #define AC100_RTC_YEA 0xce /* year */ 161 + #define AC100_RTC_UPD 0xcf /* update trigger */ 162 + 163 + /* RTC alarm */ 164 + #define AC100_ALM_INT_ENA 0xd0 165 + #define AC100_ALM_INT_STA 0xd1 166 + #define AC100_ALM_SEC 0xd8 167 + #define AC100_ALM_MIN 0xd9 168 + #define AC100_ALM_HOU 0xda 169 + #define AC100_ALM_WEE 0xdb 170 + #define AC100_ALM_DAY 0xdc 171 + #define AC100_ALM_MON 0xdd 172 + #define AC100_ALM_YEA 0xde 173 + #define AC100_ALM_UPD 0xdf 174 + 175 + /* RTC general purpose register 0 ~ 15 */ 176 + #define AC100_RTC_GP(x) (0xe0 + (x)) 177 + 178 + #endif /* __LINUX_MFD_AC100_H */
+9 -3
include/linux/mfd/arizona/core.h
··· 13 13 #ifndef _WM_ARIZONA_CORE_H 14 14 #define _WM_ARIZONA_CORE_H 15 15 16 + #include <linux/clk.h> 16 17 #include <linux/interrupt.h> 17 18 #include <linux/notifier.h> 18 19 #include <linux/regmap.h> ··· 21 20 #include <linux/mfd/arizona/pdata.h> 22 21 23 22 #define ARIZONA_MAX_CORE_SUPPLIES 2 23 + 24 + enum { 25 + ARIZONA_MCLK1, 26 + ARIZONA_MCLK2, 27 + ARIZONA_NUM_MCLK 28 + }; 24 29 25 30 enum arizona_type { 26 31 WM5102 = 1, ··· 146 139 struct mutex clk_lock; 147 140 int clk32k_ref; 148 141 142 + struct clk *mclk[ARIZONA_NUM_MCLK]; 143 + 149 144 bool ctrlif_error; 150 145 151 146 struct snd_soc_dapm_context *dapm; ··· 190 181 int cs47l24_patch(struct arizona *arizona); 191 182 int wm8997_patch(struct arizona *arizona); 192 183 int wm8998_patch(struct arizona *arizona); 193 - 194 - extern int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop, 195 - bool mandatory); 196 184 197 185 #endif
+60
include/linux/mfd/axp20x.h
··· 20 20 AXP221_ID, 21 21 AXP223_ID, 22 22 AXP288_ID, 23 + AXP806_ID, 23 24 AXP809_ID, 24 25 NR_AXP20X_VARIANTS, 25 26 }; ··· 91 90 #define AXP22X_ALDO2_V_OUT 0x29 92 91 #define AXP22X_ALDO3_V_OUT 0x2a 93 92 #define AXP22X_CHRG_CTRL3 0x35 93 + 94 + #define AXP806_STARTUP_SRC 0x00 95 + #define AXP806_CHIP_ID 0x03 96 + #define AXP806_PWR_OUT_CTRL1 0x10 97 + #define AXP806_PWR_OUT_CTRL2 0x11 98 + #define AXP806_DCDCA_V_CTRL 0x12 99 + #define AXP806_DCDCB_V_CTRL 0x13 100 + #define AXP806_DCDCC_V_CTRL 0x14 101 + #define AXP806_DCDCD_V_CTRL 0x15 102 + #define AXP806_DCDCE_V_CTRL 0x16 103 + #define AXP806_ALDO1_V_CTRL 0x17 104 + #define AXP806_ALDO2_V_CTRL 0x18 105 + #define AXP806_ALDO3_V_CTRL 0x19 106 + #define AXP806_DCDC_MODE_CTRL1 0x1a 107 + #define AXP806_DCDC_MODE_CTRL2 0x1b 108 + #define AXP806_DCDC_FREQ_CTRL 0x1c 109 + #define AXP806_BLDO1_V_CTRL 0x20 110 + #define AXP806_BLDO2_V_CTRL 0x21 111 + #define AXP806_BLDO3_V_CTRL 0x22 112 + #define AXP806_BLDO4_V_CTRL 0x23 113 + #define AXP806_CLDO1_V_CTRL 0x24 114 + #define AXP806_CLDO2_V_CTRL 0x25 115 + #define AXP806_CLDO3_V_CTRL 0x26 116 + #define AXP806_VREF_TEMP_WARN_L 0xf3 94 117 95 118 /* Interrupt */ 96 119 #define AXP152_IRQ1_EN 0x40 ··· 291 266 }; 292 267 293 268 enum { 269 + AXP806_DCDCA = 0, 270 + AXP806_DCDCB, 271 + AXP806_DCDCC, 272 + AXP806_DCDCD, 273 + AXP806_DCDCE, 274 + AXP806_ALDO1, 275 + AXP806_ALDO2, 276 + AXP806_ALDO3, 277 + AXP806_BLDO1, 278 + AXP806_BLDO2, 279 + AXP806_BLDO3, 280 + AXP806_BLDO4, 281 + AXP806_CLDO1, 282 + AXP806_CLDO2, 283 + AXP806_CLDO3, 284 + AXP806_SW, 285 + AXP806_REG_ID_MAX, 286 + }; 287 + 288 + enum { 294 289 AXP809_DCDC1 = 0, 295 290 AXP809_DCDC2, 296 291 AXP809_DCDC3, ··· 457 412 AXP288_IRQ_TIMER, 458 413 AXP288_IRQ_MV_CHNG, 459 414 AXP288_IRQ_BC_USB_CHNG, 415 + }; 416 + 417 + enum axp806_irqs { 418 + AXP806_IRQ_DIE_TEMP_HIGH_LV1, 419 + AXP806_IRQ_DIE_TEMP_HIGH_LV2, 420 + AXP806_IRQ_DCDCA_V_LOW, 421 + AXP806_IRQ_DCDCB_V_LOW, 422 + AXP806_IRQ_DCDCC_V_LOW, 423 + AXP806_IRQ_DCDCD_V_LOW, 424 + AXP806_IRQ_DCDCE_V_LOW, 425 + AXP806_IRQ_PWROK_LONG, 426 + AXP806_IRQ_PWROK_SHORT, 427 + AXP806_IRQ_WAKEUP, 428 + AXP806_IRQ_PWROK_FALL, 429 + AXP806_IRQ_PWROK_RISE, 460 430 }; 461 431 462 432 enum axp809_irqs {
+18
include/linux/mfd/cros_ec.h
··· 109 109 * should check msg.result for the EC's result code. 110 110 * @pkt_xfer: send packet to EC and get response 111 111 * @lock: one transaction at a time 112 + * @mkbp_event_supported: true if this EC supports the MKBP event protocol. 113 + * @event_notifier: interrupt event notifier for transport devices. 114 + * @event_data: raw payload transferred with the MKBP event. 115 + * @event_size: size in bytes of the event data. 112 116 */ 113 117 struct cros_ec_device { 114 118 ··· 141 137 int (*pkt_xfer)(struct cros_ec_device *ec, 142 138 struct cros_ec_command *msg); 143 139 struct mutex lock; 140 + bool mkbp_event_supported; 141 + struct blocking_notifier_head event_notifier; 142 + 143 + struct ec_response_get_next_event event_data; 144 + int event_size; 144 145 }; 145 146 146 147 /* struct cros_ec_platform - ChromeOS EC platform information ··· 277 268 * @return 0 if ok, -ve on error 278 269 */ 279 270 int cros_ec_query_all(struct cros_ec_device *ec_dev); 271 + 272 + /** 273 + * cros_ec_get_next_event - Fetch next event from the ChromeOS EC 274 + * 275 + * @ec_dev: Device to fetch event from 276 + * 277 + * Returns: 0 on success, Linux error number on failure 278 + */ 279 + int cros_ec_get_next_event(struct cros_ec_device *ec_dev); 280 280 281 281 /* sysfs stuff */ 282 282 extern struct attribute_group cros_ec_attr_group;
+34
include/linux/mfd/cros_ec_commands.h
··· 1793 1793 }; 1794 1794 } __packed; 1795 1795 1796 + /* 1797 + * Command for retrieving the next pending MKBP event from the EC device 1798 + * 1799 + * The device replies with UNAVAILABLE if there aren't any pending events. 1800 + */ 1801 + #define EC_CMD_GET_NEXT_EVENT 0x67 1802 + 1803 + enum ec_mkbp_event { 1804 + /* Keyboard matrix changed. The event data is the new matrix state. */ 1805 + EC_MKBP_EVENT_KEY_MATRIX = 0, 1806 + 1807 + /* New host event. The event data is 4 bytes of host event flags. */ 1808 + EC_MKBP_EVENT_HOST_EVENT = 1, 1809 + 1810 + /* New Sensor FIFO data. The event data is fifo_info structure. */ 1811 + EC_MKBP_EVENT_SENSOR_FIFO = 2, 1812 + 1813 + /* Number of MKBP events */ 1814 + EC_MKBP_EVENT_COUNT, 1815 + }; 1816 + 1817 + union ec_response_get_next_data { 1818 + uint8_t key_matrix[13]; 1819 + 1820 + /* Unaligned */ 1821 + uint32_t host_event; 1822 + } __packed; 1823 + 1824 + struct ec_response_get_next_event { 1825 + uint8_t event_type; 1826 + /* Followed by event data if any */ 1827 + union ec_response_get_next_data data; 1828 + } __packed; 1829 + 1796 1830 /*****************************************************************************/ 1797 1831 /* Temperature sensor commands */ 1798 1832
+2 -2
include/linux/mfd/da9063/core.h
··· 3 3 * 4 4 * Copyright 2012 Dialog Semiconductor Ltd. 5 5 * 6 - * Author: Michal Hajduk <michal.hajduk@diasemi.com> 7 - * Krystian Garbaciak <krystian.garbaciak@diasemi.com> 6 + * Author: Michal Hajduk, Dialog Semiconductor 7 + * Author: Krystian Garbaciak, Dialog Semiconductor 8 8 * 9 9 * This program is free software; you can redistribute it and/or modify it 10 10 * under the terms of the GNU General Public License as published by the
+2 -2
include/linux/mfd/da9063/pdata.h
··· 3 3 * 4 4 * Copyright 2012 Dialog Semiconductor Ltd. 5 5 * 6 - * Author: Michal Hajduk <michal.hajduk@diasemi.com> 7 - * Author: Krystian Garbaciak <krystian.garbaciak@diasemi.com> 6 + * Author: Michal Hajduk, Dialog Semiconductor 7 + * Author: Krystian Garbaciak, Dialog Semiconductor 8 8 * 9 9 * This program is free software; you can redistribute it and/or modify it 10 10 * under the terms of the GNU General Public License as published by the
+2 -2
include/linux/mfd/da9063/registers.h
··· 3 3 * 4 4 * Copyright 2012 Dialog Semiconductor Ltd. 5 5 * 6 - * Author: Michal Hajduk <michal.hajduk@diasemi.com> 7 - * Krystian Garbaciak <krystian.garbaciak@diasemi.com> 6 + * Author: Michal Hajduk, Dialog Semiconductor 7 + * Author: Krystian Garbaciak, Dialog Semiconductor 8 8 * 9 9 * This program is free software; you can redistribute it and/or modify it 10 10 * under the terms of the GNU General Public License as published by the
-6
include/linux/mfd/db8500-prcmu.h
··· 538 538 int db8500_prcmu_set_ape_opp(u8 opp); 539 539 int db8500_prcmu_get_ape_opp(void); 540 540 int db8500_prcmu_request_ape_opp_100_voltage(bool enable); 541 - int db8500_prcmu_set_ddr_opp(u8 opp); 542 541 int db8500_prcmu_get_ddr_opp(void); 543 542 544 543 u32 db8500_prcmu_read(unsigned int reg); ··· 589 590 } 590 591 591 592 static inline int prcmu_release_usb_wakeup_state(void) 592 - { 593 - return 0; 594 - } 595 - 596 - static inline int db8500_prcmu_set_ddr_opp(u8 opp) 597 593 { 598 594 return 0; 599 595 }
-9
include/linux/mfd/dbx500-prcmu.h
··· 269 269 long prcmu_round_clock_rate(u8 clock, unsigned long rate); 270 270 int prcmu_set_clock_rate(u8 clock, unsigned long rate); 271 271 272 - static inline int prcmu_set_ddr_opp(u8 opp) 273 - { 274 - return db8500_prcmu_set_ddr_opp(opp); 275 - } 276 272 static inline int prcmu_get_ddr_opp(void) 277 273 { 278 274 return db8500_prcmu_get_ddr_opp(); ··· 483 487 static inline int prcmu_get_arm_opp(void) 484 488 { 485 489 return ARM_100_OPP; 486 - } 487 - 488 - static inline int prcmu_set_ddr_opp(u8 opp) 489 - { 490 - return 0; 491 490 } 492 491 493 492 static inline int prcmu_get_ddr_opp(void)
-1
include/linux/mfd/lp873x.h
··· 263 263 struct lp873x { 264 264 struct device *dev; 265 265 u8 rev; 266 - struct mutex lock; /* lock guarding the data structure */ 267 266 struct regmap *regmap; 268 267 }; 269 268 #endif /* __LINUX_MFD_LP873X_H */
+1 -1
include/linux/mfd/max14577-private.h
··· 3 3 * 4 4 * Copyright (C) 2014 Samsung Electrnoics 5 5 * Chanwoo Choi <cw00.choi@samsung.com> 6 - * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 + * Krzysztof Kozlowski <krzk@kernel.org> 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify 9 9 * it under the terms of the GNU General Public License as published by
+1 -1
include/linux/mfd/max14577.h
··· 3 3 * 4 4 * Copyright (C) 2014 Samsung Electrnoics 5 5 * Chanwoo Choi <cw00.choi@samsung.com> 6 - * Krzysztof Kozlowski <k.kozlowski@samsung.com> 6 + * Krzysztof Kozlowski <krzk@kernel.org> 7 7 * 8 8 * This program is free software; you can redistribute it and/or modify 9 9 * it under the terms of the GNU General Public License as published by
+146 -10
include/linux/mfd/rk808.h
··· 1 1 /* 2 - * rk808.h for Rockchip RK808 2 + * Register definitions for Rockchip's RK808/RK818 PMIC 3 3 * 4 4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd 5 5 * 6 6 * Author: Chris Zhong <zyw@rock-chips.com> 7 7 * Author: Zhang Qing <zhangqing@rock-chips.com> 8 + * 9 + * Copyright (C) 2016 PHYTEC Messtechnik GmbH 10 + * 11 + * Author: Wadim Egorov <w.egorov@phytec.de> 8 12 * 9 13 * This program is free software; you can redistribute it and/or modify it 10 14 * under the terms and conditions of the GNU General Public License, ··· 20 16 * more details. 21 17 */ 22 18 23 - #ifndef __LINUX_REGULATOR_rk808_H 24 - #define __LINUX_REGULATOR_rk808_H 19 + #ifndef __LINUX_REGULATOR_RK808_H 20 + #define __LINUX_REGULATOR_RK808_H 25 21 26 22 #include <linux/regulator/machine.h> 27 23 #include <linux/regmap.h> ··· 32 28 33 29 #define RK808_DCDC1 0 /* (0+RK808_START) */ 34 30 #define RK808_LDO1 4 /* (4+RK808_START) */ 35 - #define RK808_NUM_REGULATORS 14 31 + #define RK808_NUM_REGULATORS 14 36 32 37 33 enum rk808_reg { 38 34 RK808_ID_DCDC1, ··· 69 65 #define RK808_RTC_INT_REG 0x12 70 66 #define RK808_RTC_COMP_LSB_REG 0x13 71 67 #define RK808_RTC_COMP_MSB_REG 0x14 68 + #define RK808_ID_MSB 0x17 69 + #define RK808_ID_LSB 0x18 72 70 #define RK808_CLK32OUT_REG 0x20 73 71 #define RK808_VB_MON_REG 0x21 74 72 #define RK808_THERMAL_REG 0x22 ··· 121 115 #define RK808_INT_STS_MSK_REG2 0x4f 122 116 #define RK808_IO_POL_REG 0x50 123 117 124 - /* IRQ Definitions */ 118 + /* RK818 */ 119 + #define RK818_DCDC1 0 120 + #define RK818_LDO1 4 121 + #define RK818_NUM_REGULATORS 17 122 + 123 + enum rk818_reg { 124 + RK818_ID_DCDC1, 125 + RK818_ID_DCDC2, 126 + RK818_ID_DCDC3, 127 + RK818_ID_DCDC4, 128 + RK818_ID_BOOST, 129 + RK818_ID_LDO1, 130 + RK818_ID_LDO2, 131 + RK818_ID_LDO3, 132 + RK818_ID_LDO4, 133 + RK818_ID_LDO5, 134 + RK818_ID_LDO6, 135 + RK818_ID_LDO7, 136 + RK818_ID_LDO8, 137 + RK818_ID_LDO9, 138 + RK818_ID_SWITCH, 139 + RK818_ID_HDMI_SWITCH, 140 + RK818_ID_OTG_SWITCH, 141 + }; 142 + 143 + #define RK818_DCDC_EN_REG 0x23 144 + #define RK818_LDO_EN_REG 0x24 145 + #define RK818_SLEEP_SET_OFF_REG1 0x25 146 + #define RK818_SLEEP_SET_OFF_REG2 0x26 147 + #define RK818_DCDC_UV_STS_REG 0x27 148 + #define RK818_DCDC_UV_ACT_REG 0x28 149 + #define RK818_LDO_UV_STS_REG 0x29 150 + #define RK818_LDO_UV_ACT_REG 0x2a 151 + #define RK818_DCDC_PG_REG 0x2b 152 + #define RK818_LDO_PG_REG 0x2c 153 + #define RK818_VOUT_MON_TDB_REG 0x2d 154 + #define RK818_BUCK1_CONFIG_REG 0x2e 155 + #define RK818_BUCK1_ON_VSEL_REG 0x2f 156 + #define RK818_BUCK1_SLP_VSEL_REG 0x30 157 + #define RK818_BUCK2_CONFIG_REG 0x32 158 + #define RK818_BUCK2_ON_VSEL_REG 0x33 159 + #define RK818_BUCK2_SLP_VSEL_REG 0x34 160 + #define RK818_BUCK3_CONFIG_REG 0x36 161 + #define RK818_BUCK4_CONFIG_REG 0x37 162 + #define RK818_BUCK4_ON_VSEL_REG 0x38 163 + #define RK818_BUCK4_SLP_VSEL_REG 0x39 164 + #define RK818_BOOST_CONFIG_REG 0x3a 165 + #define RK818_LDO1_ON_VSEL_REG 0x3b 166 + #define RK818_LDO1_SLP_VSEL_REG 0x3c 167 + #define RK818_LDO2_ON_VSEL_REG 0x3d 168 + #define RK818_LDO2_SLP_VSEL_REG 0x3e 169 + #define RK818_LDO3_ON_VSEL_REG 0x3f 170 + #define RK818_LDO3_SLP_VSEL_REG 0x40 171 + #define RK818_LDO4_ON_VSEL_REG 0x41 172 + #define RK818_LDO4_SLP_VSEL_REG 0x42 173 + #define RK818_LDO5_ON_VSEL_REG 0x43 174 + #define RK818_LDO5_SLP_VSEL_REG 0x44 175 + #define RK818_LDO6_ON_VSEL_REG 0x45 176 + #define RK818_LDO6_SLP_VSEL_REG 0x46 177 + #define RK818_LDO7_ON_VSEL_REG 0x47 178 + #define RK818_LDO7_SLP_VSEL_REG 0x48 179 + #define RK818_LDO8_ON_VSEL_REG 0x49 180 + #define RK818_LDO8_SLP_VSEL_REG 0x4a 181 + #define RK818_BOOST_LDO9_ON_VSEL_REG 0x54 182 + #define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55 183 + #define RK818_DEVCTRL_REG 0x4b 184 + #define RK818_INT_STS_REG1 0X4c 185 + #define RK818_INT_STS_MSK_REG1 0x4d 186 + #define RK818_INT_STS_REG2 0x4e 187 + #define RK818_INT_STS_MSK_REG2 0x4f 188 + #define RK818_IO_POL_REG 0x50 189 + #define RK818_H5V_EN_REG 0x52 190 + #define RK818_SLEEP_SET_OFF_REG3 0x53 191 + #define RK818_BOOST_LDO9_ON_VSEL_REG 0x54 192 + #define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55 193 + #define RK818_BOOST_CTRL_REG 0x56 194 + #define RK818_DCDC_ILMAX 0x90 195 + #define RK818_USB_CTRL_REG 0xa1 196 + 197 + #define RK818_H5V_EN BIT(0) 198 + #define RK818_REF_RDY_CTRL BIT(1) 199 + #define RK818_USB_ILIM_SEL_MASK 0xf 200 + #define RK818_USB_ILMIN_2000MA 0x7 201 + #define RK818_USB_CHG_SD_VSEL_MASK 0x70 202 + 203 + /* RK808 IRQ Definitions */ 125 204 #define RK808_IRQ_VOUT_LO 0 126 205 #define RK808_IRQ_VB_LO 1 127 206 #define RK808_IRQ_PWRON 2 ··· 227 136 #define RK808_IRQ_RTC_PERIOD_MSK BIT(6) 228 137 #define RK808_IRQ_PLUG_IN_INT_MSK BIT(0) 229 138 #define RK808_IRQ_PLUG_OUT_INT_MSK BIT(1) 139 + 140 + /* RK818 IRQ Definitions */ 141 + #define RK818_IRQ_VOUT_LO 0 142 + #define RK818_IRQ_VB_LO 1 143 + #define RK818_IRQ_PWRON 2 144 + #define RK818_IRQ_PWRON_LP 3 145 + #define RK818_IRQ_HOTDIE 4 146 + #define RK818_IRQ_RTC_ALARM 5 147 + #define RK818_IRQ_RTC_PERIOD 6 148 + #define RK818_IRQ_USB_OV 7 149 + #define RK818_IRQ_PLUG_IN 8 150 + #define RK818_IRQ_PLUG_OUT 9 151 + #define RK818_IRQ_CHG_OK 10 152 + #define RK818_IRQ_CHG_TE 11 153 + #define RK818_IRQ_CHG_TS1 12 154 + #define RK818_IRQ_TS2 13 155 + #define RK818_IRQ_CHG_CVTLIM 14 156 + #define RK818_IRQ_DISCHG_ILIM 15 157 + 158 + #define RK818_IRQ_VOUT_LO_MSK BIT(0) 159 + #define RK818_IRQ_VB_LO_MSK BIT(1) 160 + #define RK818_IRQ_PWRON_MSK BIT(2) 161 + #define RK818_IRQ_PWRON_LP_MSK BIT(3) 162 + #define RK818_IRQ_HOTDIE_MSK BIT(4) 163 + #define RK818_IRQ_RTC_ALARM_MSK BIT(5) 164 + #define RK818_IRQ_RTC_PERIOD_MSK BIT(6) 165 + #define RK818_IRQ_USB_OV_MSK BIT(7) 166 + #define RK818_IRQ_PLUG_IN_MSK BIT(0) 167 + #define RK818_IRQ_PLUG_OUT_MSK BIT(1) 168 + #define RK818_IRQ_CHG_OK_MSK BIT(2) 169 + #define RK818_IRQ_CHG_TE_MSK BIT(3) 170 + #define RK818_IRQ_CHG_TS1_MSK BIT(4) 171 + #define RK818_IRQ_TS2_MSK BIT(5) 172 + #define RK818_IRQ_CHG_CVTLIM_MSK BIT(6) 173 + #define RK818_IRQ_DISCHG_ILIM_MSK BIT(7) 174 + 175 + #define RK818_NUM_IRQ 16 230 176 231 177 #define RK808_VBAT_LOW_2V8 0x00 232 178 #define RK808_VBAT_LOW_2V9 0x01 ··· 319 191 BOOST_ILMIN_250MA, 320 192 }; 321 193 322 - struct rk808 { 323 - struct i2c_client *i2c; 324 - struct regmap_irq_chip_data *irq_data; 325 - struct regmap *regmap; 194 + enum { 195 + RK808_ID = 0x0000, 196 + RK818_ID = 0x8181, 326 197 }; 327 - #endif /* __LINUX_REGULATOR_rk808_H */ 198 + 199 + struct rk808 { 200 + struct i2c_client *i2c; 201 + struct regmap_irq_chip_data *irq_data; 202 + struct regmap *regmap; 203 + long variant; 204 + const struct regmap_config *regmap_cfg; 205 + const struct regmap_irq_chip *regmap_irq_chip; 206 + }; 207 + #endif /* __LINUX_REGULATOR_RK808_H */
+3 -1
include/linux/mfd/syscon/exynos5-pmu.h
··· 43 43 #define EXYNOS5433_MIPI_PHY2_CONTROL (0x718) 44 44 45 45 #define EXYNOS5_PHY_ENABLE BIT(0) 46 - 47 46 #define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) 48 47 #define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) 48 + 49 + #define EXYNOS5433_PAD_RETENTION_AUD_OPTION (0x3028) 50 + #define EXYNOS5433_PAD_INITIATE_WAKEUP_FROM_LOWPWR BIT(28) 49 51 50 52 #endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */
+12
include/linux/mfd/tps65217.h
··· 73 73 #define TPS65217_PPATH_AC_CURRENT_MASK 0x0C 74 74 #define TPS65217_PPATH_USB_CURRENT_MASK 0x03 75 75 76 + #define TPS65217_INT_RESERVEDM BIT(7) 76 77 #define TPS65217_INT_PBM BIT(6) 77 78 #define TPS65217_INT_ACM BIT(5) 78 79 #define TPS65217_INT_USBM BIT(4) ··· 234 233 int dft_brightness; 235 234 }; 236 235 236 + enum tps65217_irq_type { 237 + TPS65217_IRQ_PB, 238 + TPS65217_IRQ_AC, 239 + TPS65217_IRQ_USB, 240 + TPS65217_NUM_IRQ 241 + }; 242 + 237 243 /** 238 244 * struct tps65217_board - packages regulator init data 239 245 * @tps65217_regulator_data: regulator initialization values ··· 266 258 struct regulator_desc desc[TPS65217_NUM_REGULATOR]; 267 259 struct regmap *regmap; 268 260 u8 *strobes; 261 + struct irq_domain *irq_domain; 262 + struct mutex irq_lock; 263 + u8 irq_mask; 264 + int irq; 269 265 }; 270 266 271 267 static inline struct tps65217 *dev_to_tps65217(struct device *dev)
+1 -1
include/linux/mfd/twl6040.h
··· 168 168 #define TWL6040_VIBROCDET 0x20 169 169 #define TWL6040_TSHUTDET 0x40 170 170 171 - #define TWL6040_CELLS 3 171 + #define TWL6040_CELLS 4 172 172 173 173 #define TWL6040_REV_ES1_0 0x00 174 174 #define TWL6040_REV_ES1_1 0x01 /* Rev ES1.1 and ES1.2 */