Commit d460a6f3d67a8558fb58299518077888b7dbf5f3
Committed by
Lee Jones
1 parent
71c7f93ea0
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
mfd: Add support for ams AS3722 PMIC
The ams AS3722 is a compact system PMU suitable for mobile phones, tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down controller, 11 LDOs, RTC, automatic battery, temperature and over-current monitoring, 8 GPIOs, ADC and a watchdog. Add MFD core driver for the AS3722 to support core functionality. Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Signed-off-by: Florian Lobmaier <florian.lobmaier@ams.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Showing 6 changed files with 1131 additions and 0 deletions Side-by-side Diff
Documentation/devicetree/bindings/mfd/as3722.txt
1 | +* ams AS3722 Power management IC. | |
2 | + | |
3 | +Required properties: | |
4 | +------------------- | |
5 | +- compatible: Must be "ams,as3722". | |
6 | +- reg: I2C device address. | |
7 | +- interrupt-controller: AS3722 has internal interrupt controller which takes the | |
8 | + interrupt request from internal sub-blocks like RTC, regulators, GPIOs as well | |
9 | + as external input. | |
10 | +- #interrupt-cells: Should be set to 2 for IRQ number and flags. | |
11 | + The first cell is the IRQ number. IRQ numbers for different interrupt source | |
12 | + of AS3722 are defined at dt-bindings/mfd/as3722.h | |
13 | + The second cell is the flags, encoded as the trigger masks from binding document | |
14 | + interrupts.txt, using dt-bindings/irq. | |
15 | + | |
16 | +Optional submodule and their properties: | |
17 | +======================================= | |
18 | + | |
19 | +Pinmux and GPIO: | |
20 | +=============== | |
21 | +Device has 8 GPIO pins which can be configured as GPIO as well as the special IO | |
22 | +functions. | |
23 | + | |
24 | +Please refer to pinctrl-bindings.txt in this directory for details of the | |
25 | +common pinctrl bindings used by client devices, including the meaning of the | |
26 | +phrase "pin configuration node". | |
27 | + | |
28 | +Following are properties which is needed if GPIO and pinmux functionality | |
29 | +is required: | |
30 | + Required properties: | |
31 | + ------------------- | |
32 | + - gpio-controller: Marks the device node as a GPIO controller. | |
33 | + - #gpio-cells: Number of GPIO cells. Refer to binding document | |
34 | + gpio/gpio.txt | |
35 | + | |
36 | + Optional properties: | |
37 | + -------------------- | |
38 | + Following properties are require if pin control setting is required | |
39 | + at boot. | |
40 | + - pinctrl-names: A pinctrl state named "default" be defined, using the | |
41 | + bindings in pinctrl/pinctrl-binding.txt. | |
42 | + - pinctrl[0...n]: Properties to contain the phandle that refer to | |
43 | + different nodes of pin control settings. These nodes represents | |
44 | + the pin control setting of state 0 to state n. Each of these | |
45 | + nodes contains different subnodes to represents some desired | |
46 | + configuration for a list of pins. This configuration can | |
47 | + include the mux function to select on those pin(s), and | |
48 | + various pin configuration parameters, such as pull-up, | |
49 | + open drain. | |
50 | + | |
51 | + Each subnode have following properties: | |
52 | + Required properties: | |
53 | + - pins: List of pins. Valid values of pins properties are: | |
54 | + gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, | |
55 | + gpio6, gpio7 | |
56 | + | |
57 | + Optional properties: | |
58 | + function, bias-disable, bias-pull-up, bias-pull-down, | |
59 | + bias-high-impedance, drive-open-drain. | |
60 | + | |
61 | + Valid values for function properties are: | |
62 | + gpio, interrupt-out, gpio-in-interrupt, | |
63 | + vsup-vbat-low-undebounce-out, | |
64 | + vsup-vbat-low-debounce-out, | |
65 | + voltage-in-standby, oc-pg-sd0, oc-pg-sd6, | |
66 | + powergood-out, pwm-in, pwm-out, clk32k-out, | |
67 | + watchdog-in, soft-reset-in | |
68 | + | |
69 | +Regulators: | |
70 | +=========== | |
71 | +Device has multiple DCDC and LDOs. The node "regulators" is require if regulator | |
72 | +functionality is needed. | |
73 | + | |
74 | +Following are properties of regulator subnode. | |
75 | + | |
76 | + Optional properties: | |
77 | + ------------------- | |
78 | + The input supply of regulators are the optional properties on the | |
79 | + regulator node. The input supply of these regulators are provided | |
80 | + through following properties: | |
81 | + vsup-sd2-supply: Input supply for SD2. | |
82 | + vsup-sd3-supply: Input supply for SD3. | |
83 | + vsup-sd4-supply: Input supply for SD4. | |
84 | + vsup-sd5-supply: Input supply for SD5. | |
85 | + vin-ldo0-supply: Input supply for LDO0. | |
86 | + vin-ldo1-6-supply: Input supply for LDO1 and LDO6. | |
87 | + vin-ldo2-5-7-supply: Input supply for LDO2, LDO5 and LDO7. | |
88 | + vin-ldo3-4-supply: Input supply for LDO3 and LDO4. | |
89 | + vin-ldo9-10-supply: Input supply for LDO9 and LDO10. | |
90 | + vin-ldo11-supply: Input supply for LDO11. | |
91 | + | |
92 | + Optional sub nodes for regulators: | |
93 | + --------------------------------- | |
94 | + The subnodes name is the name of regulator and it must be one of: | |
95 | + sd[0-6], ldo[0-7], ldo[9-11] | |
96 | + | |
97 | + Each sub-node should contain the constraints and initialization | |
98 | + information for that regulator. See regulator.txt for a description | |
99 | + of standard properties for these sub-nodes. | |
100 | + Additional optional custom properties are listed below. | |
101 | + ams,ext-control: External control of the rail. The option of | |
102 | + this properties will tell which external input is | |
103 | + controlling this rail. Valid values are 0, 1, 2 ad 3. | |
104 | + 0: There is no external control of this rail. | |
105 | + 1: Rail is controlled by ENABLE1 input pin. | |
106 | + 2: Rail is controlled by ENABLE2 input pin. | |
107 | + 3: Rail is controlled by ENABLE3 input pin. | |
108 | + Missing this property on DT will be assume as no | |
109 | + external control. The external control pin macros | |
110 | + are defined @dt-bindings/mfd/as3722.h | |
111 | + | |
112 | + ams,enable-tracking: Enable tracking with SD1, only supported | |
113 | + by LDO3. | |
114 | + | |
115 | +Example: | |
116 | +-------- | |
117 | +#include <dt-bindings/mfd/as3722.h> | |
118 | +... | |
119 | +ams3722 { | |
120 | + compatible = "ams,as3722"; | |
121 | + reg = <0x48>; | |
122 | + | |
123 | + interrupt-parent = <&intc>; | |
124 | + interrupt-controller; | |
125 | + #interrupt-cells = <2>; | |
126 | + | |
127 | + gpio-controller; | |
128 | + #gpio-cells = <2>; | |
129 | + | |
130 | + pinctrl-names = "default"; | |
131 | + pinctrl-0 = <&as3722_default>; | |
132 | + | |
133 | + as3722_default: pinmux { | |
134 | + gpio0 { | |
135 | + pins = "gpio0"; | |
136 | + function = "gpio"; | |
137 | + bias-pull-down; | |
138 | + }; | |
139 | + | |
140 | + gpio1_2_4_7 { | |
141 | + pins = "gpio1", "gpio2", "gpio4", "gpio7"; | |
142 | + function = "gpio"; | |
143 | + bias-pull-up; | |
144 | + }; | |
145 | + | |
146 | + gpio5 { | |
147 | + pins = "gpio5"; | |
148 | + function = "clk32k_out"; | |
149 | + }; | |
150 | + } | |
151 | + | |
152 | + regulators { | |
153 | + vsup-sd2-supply = <...>; | |
154 | + ... | |
155 | + | |
156 | + sd0 { | |
157 | + regulator-name = "vdd_cpu"; | |
158 | + regulator-min-microvolt = <700000>; | |
159 | + regulator-max-microvolt = <1400000>; | |
160 | + regulator-always-on; | |
161 | + ams,ext-control = <2>; | |
162 | + }; | |
163 | + | |
164 | + sd1 { | |
165 | + regulator-name = "vdd_core"; | |
166 | + regulator-min-microvolt = <700000>; | |
167 | + regulator-max-microvolt = <1400000>; | |
168 | + regulator-always-on; | |
169 | + ams,ext-control = <1>; | |
170 | + }; | |
171 | + | |
172 | + sd2 { | |
173 | + regulator-name = "vddio_ddr"; | |
174 | + regulator-min-microvolt = <1350000>; | |
175 | + regulator-max-microvolt = <1350000>; | |
176 | + regulator-always-on; | |
177 | + }; | |
178 | + | |
179 | + sd4 { | |
180 | + regulator-name = "avdd-hdmi-pex"; | |
181 | + regulator-min-microvolt = <1050000>; | |
182 | + regulator-max-microvolt = <1050000>; | |
183 | + regulator-always-on; | |
184 | + }; | |
185 | + | |
186 | + sd5 { | |
187 | + regulator-name = "vdd-1v8"; | |
188 | + regulator-min-microvolt = <1800000>; | |
189 | + regulator-max-microvolt = <1800000>; | |
190 | + regulator-always-on; | |
191 | + }; | |
192 | + .... | |
193 | + }; | |
194 | +}; |
drivers/mfd/Kconfig
... | ... | @@ -27,6 +27,18 @@ |
27 | 27 | help |
28 | 28 | Support for the AS3711 PMIC from AMS |
29 | 29 | |
30 | +config MFD_AS3722 | |
31 | + bool "ams AS3722 Power Management IC" | |
32 | + select MFD_CORE | |
33 | + select REGMAP_I2C | |
34 | + select REGMAP_IRQ | |
35 | + depends on I2C && OF | |
36 | + help | |
37 | + The ams AS3722 is a compact system PMU suitable for mobile phones, | |
38 | + tablets etc. It has 4 DC/DC step-down regulators, 3 DC/DC step-down | |
39 | + controllers, 11 LDOs, RTC, automatic battery, temperature and | |
40 | + over current monitoring, GPIOs, ADC and a watchdog. | |
41 | + | |
30 | 42 | config PMIC_ADP5520 |
31 | 43 | bool "Analog Devices ADP5520/01 MFD PMIC Core Support" |
32 | 44 | depends on I2C=y |
drivers/mfd/Makefile
drivers/mfd/as3722.c
1 | +/* | |
2 | + * Core driver for ams AS3722 PMICs | |
3 | + * | |
4 | + * Copyright (C) 2013 AMS AG | |
5 | + * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. | |
6 | + * | |
7 | + * Author: Florian Lobmaier <florian.lobmaier@ams.com> | |
8 | + * Author: Laxman Dewangan <ldewangan@nvidia.com> | |
9 | + * | |
10 | + * This program is free software; you can redistribute it and/or modify | |
11 | + * it under the terms of the GNU General Public License as published by | |
12 | + * the Free Software Foundation; either version 2 of the License, or | |
13 | + * (at your option) any later version. | |
14 | + * | |
15 | + * This program is distributed in the hope that it will be useful, | |
16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | + * GNU General Public License for more details. | |
19 | + * | |
20 | + * You should have received a copy of the GNU General Public License | |
21 | + * along with this program; if not, write to the Free Software | |
22 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | + */ | |
24 | + | |
25 | +#include <linux/err.h> | |
26 | +#include <linux/i2c.h> | |
27 | +#include <linux/interrupt.h> | |
28 | +#include <linux/irq.h> | |
29 | +#include <linux/kernel.h> | |
30 | +#include <linux/module.h> | |
31 | +#include <linux/mfd/core.h> | |
32 | +#include <linux/mfd/as3722.h> | |
33 | +#include <linux/of.h> | |
34 | +#include <linux/regmap.h> | |
35 | +#include <linux/slab.h> | |
36 | + | |
37 | +#define AS3722_DEVICE_ID 0x0C | |
38 | + | |
39 | +static const struct resource as3722_rtc_resource[] = { | |
40 | + { | |
41 | + .name = "as3722-rtc-alarm", | |
42 | + .start = AS3722_IRQ_RTC_ALARM, | |
43 | + .end = AS3722_IRQ_RTC_ALARM, | |
44 | + .flags = IORESOURCE_IRQ, | |
45 | + }, | |
46 | +}; | |
47 | + | |
48 | +static const struct resource as3722_adc_resource[] = { | |
49 | + { | |
50 | + .name = "as3722-adc", | |
51 | + .start = AS3722_IRQ_ADC, | |
52 | + .end = AS3722_IRQ_ADC, | |
53 | + .flags = IORESOURCE_IRQ, | |
54 | + }, | |
55 | +}; | |
56 | + | |
57 | +static struct mfd_cell as3722_devs[] = { | |
58 | + { | |
59 | + .name = "as3722-pinctrl", | |
60 | + }, | |
61 | + { | |
62 | + .name = "as3722-regulator", | |
63 | + }, | |
64 | + { | |
65 | + .name = "as3722-rtc", | |
66 | + .num_resources = ARRAY_SIZE(as3722_rtc_resource), | |
67 | + .resources = as3722_rtc_resource, | |
68 | + }, | |
69 | + { | |
70 | + .name = "as3722-adc", | |
71 | + .num_resources = ARRAY_SIZE(as3722_adc_resource), | |
72 | + .resources = as3722_adc_resource, | |
73 | + }, | |
74 | + { | |
75 | + .name = "as3722-power-off", | |
76 | + }, | |
77 | +}; | |
78 | + | |
79 | +static const struct regmap_irq as3722_irqs[] = { | |
80 | + /* INT1 IRQs */ | |
81 | + [AS3722_IRQ_LID] = { | |
82 | + .mask = AS3722_INTERRUPT_MASK1_LID, | |
83 | + }, | |
84 | + [AS3722_IRQ_ACOK] = { | |
85 | + .mask = AS3722_INTERRUPT_MASK1_ACOK, | |
86 | + }, | |
87 | + [AS3722_IRQ_ENABLE1] = { | |
88 | + .mask = AS3722_INTERRUPT_MASK1_ENABLE1, | |
89 | + }, | |
90 | + [AS3722_IRQ_OCCUR_ALARM_SD0] = { | |
91 | + .mask = AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0, | |
92 | + }, | |
93 | + [AS3722_IRQ_ONKEY_LONG_PRESS] = { | |
94 | + .mask = AS3722_INTERRUPT_MASK1_ONKEY_LONG, | |
95 | + }, | |
96 | + [AS3722_IRQ_ONKEY] = { | |
97 | + .mask = AS3722_INTERRUPT_MASK1_ONKEY, | |
98 | + }, | |
99 | + [AS3722_IRQ_OVTMP] = { | |
100 | + .mask = AS3722_INTERRUPT_MASK1_OVTMP, | |
101 | + }, | |
102 | + [AS3722_IRQ_LOWBAT] = { | |
103 | + .mask = AS3722_INTERRUPT_MASK1_LOWBAT, | |
104 | + }, | |
105 | + | |
106 | + /* INT2 IRQs */ | |
107 | + [AS3722_IRQ_SD0_LV] = { | |
108 | + .mask = AS3722_INTERRUPT_MASK2_SD0_LV, | |
109 | + .reg_offset = 1, | |
110 | + }, | |
111 | + [AS3722_IRQ_SD1_LV] = { | |
112 | + .mask = AS3722_INTERRUPT_MASK2_SD1_LV, | |
113 | + .reg_offset = 1, | |
114 | + }, | |
115 | + [AS3722_IRQ_SD2_LV] = { | |
116 | + .mask = AS3722_INTERRUPT_MASK2_SD2345_LV, | |
117 | + .reg_offset = 1, | |
118 | + }, | |
119 | + [AS3722_IRQ_PWM1_OV_PROT] = { | |
120 | + .mask = AS3722_INTERRUPT_MASK2_PWM1_OV_PROT, | |
121 | + .reg_offset = 1, | |
122 | + }, | |
123 | + [AS3722_IRQ_PWM2_OV_PROT] = { | |
124 | + .mask = AS3722_INTERRUPT_MASK2_PWM2_OV_PROT, | |
125 | + .reg_offset = 1, | |
126 | + }, | |
127 | + [AS3722_IRQ_ENABLE2] = { | |
128 | + .mask = AS3722_INTERRUPT_MASK2_ENABLE2, | |
129 | + .reg_offset = 1, | |
130 | + }, | |
131 | + [AS3722_IRQ_SD6_LV] = { | |
132 | + .mask = AS3722_INTERRUPT_MASK2_SD6_LV, | |
133 | + .reg_offset = 1, | |
134 | + }, | |
135 | + [AS3722_IRQ_RTC_REP] = { | |
136 | + .mask = AS3722_INTERRUPT_MASK2_RTC_REP, | |
137 | + .reg_offset = 1, | |
138 | + }, | |
139 | + | |
140 | + /* INT3 IRQs */ | |
141 | + [AS3722_IRQ_RTC_ALARM] = { | |
142 | + .mask = AS3722_INTERRUPT_MASK3_RTC_ALARM, | |
143 | + .reg_offset = 2, | |
144 | + }, | |
145 | + [AS3722_IRQ_GPIO1] = { | |
146 | + .mask = AS3722_INTERRUPT_MASK3_GPIO1, | |
147 | + .reg_offset = 2, | |
148 | + }, | |
149 | + [AS3722_IRQ_GPIO2] = { | |
150 | + .mask = AS3722_INTERRUPT_MASK3_GPIO2, | |
151 | + .reg_offset = 2, | |
152 | + }, | |
153 | + [AS3722_IRQ_GPIO3] = { | |
154 | + .mask = AS3722_INTERRUPT_MASK3_GPIO3, | |
155 | + .reg_offset = 2, | |
156 | + }, | |
157 | + [AS3722_IRQ_GPIO4] = { | |
158 | + .mask = AS3722_INTERRUPT_MASK3_GPIO4, | |
159 | + .reg_offset = 2, | |
160 | + }, | |
161 | + [AS3722_IRQ_GPIO5] = { | |
162 | + .mask = AS3722_INTERRUPT_MASK3_GPIO5, | |
163 | + .reg_offset = 2, | |
164 | + }, | |
165 | + [AS3722_IRQ_WATCHDOG] = { | |
166 | + .mask = AS3722_INTERRUPT_MASK3_WATCHDOG, | |
167 | + .reg_offset = 2, | |
168 | + }, | |
169 | + [AS3722_IRQ_ENABLE3] = { | |
170 | + .mask = AS3722_INTERRUPT_MASK3_ENABLE3, | |
171 | + .reg_offset = 2, | |
172 | + }, | |
173 | + | |
174 | + /* INT4 IRQs */ | |
175 | + [AS3722_IRQ_TEMP_SD0_SHUTDOWN] = { | |
176 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN, | |
177 | + .reg_offset = 3, | |
178 | + }, | |
179 | + [AS3722_IRQ_TEMP_SD1_SHUTDOWN] = { | |
180 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN, | |
181 | + .reg_offset = 3, | |
182 | + }, | |
183 | + [AS3722_IRQ_TEMP_SD2_SHUTDOWN] = { | |
184 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN, | |
185 | + .reg_offset = 3, | |
186 | + }, | |
187 | + [AS3722_IRQ_TEMP_SD0_ALARM] = { | |
188 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM, | |
189 | + .reg_offset = 3, | |
190 | + }, | |
191 | + [AS3722_IRQ_TEMP_SD1_ALARM] = { | |
192 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM, | |
193 | + .reg_offset = 3, | |
194 | + }, | |
195 | + [AS3722_IRQ_TEMP_SD6_ALARM] = { | |
196 | + .mask = AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM, | |
197 | + .reg_offset = 3, | |
198 | + }, | |
199 | + [AS3722_IRQ_OCCUR_ALARM_SD6] = { | |
200 | + .mask = AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6, | |
201 | + .reg_offset = 3, | |
202 | + }, | |
203 | + [AS3722_IRQ_ADC] = { | |
204 | + .mask = AS3722_INTERRUPT_MASK4_ADC, | |
205 | + .reg_offset = 3, | |
206 | + }, | |
207 | +}; | |
208 | + | |
209 | +static const struct regmap_irq_chip as3722_irq_chip = { | |
210 | + .name = "as3722", | |
211 | + .irqs = as3722_irqs, | |
212 | + .num_irqs = ARRAY_SIZE(as3722_irqs), | |
213 | + .num_regs = 4, | |
214 | + .status_base = AS3722_INTERRUPT_STATUS1_REG, | |
215 | + .mask_base = AS3722_INTERRUPT_MASK1_REG, | |
216 | +}; | |
217 | + | |
218 | +static int as3722_check_device_id(struct as3722 *as3722) | |
219 | +{ | |
220 | + u32 val; | |
221 | + int ret; | |
222 | + | |
223 | + /* Check that this is actually a AS3722 */ | |
224 | + ret = as3722_read(as3722, AS3722_ASIC_ID1_REG, &val); | |
225 | + if (ret < 0) { | |
226 | + dev_err(as3722->dev, "ASIC_ID1 read failed: %d\n", ret); | |
227 | + return ret; | |
228 | + } | |
229 | + | |
230 | + if (val != AS3722_DEVICE_ID) { | |
231 | + dev_err(as3722->dev, "Device is not AS3722, ID is 0x%x\n", val); | |
232 | + return -ENODEV; | |
233 | + } | |
234 | + | |
235 | + ret = as3722_read(as3722, AS3722_ASIC_ID2_REG, &val); | |
236 | + if (ret < 0) { | |
237 | + dev_err(as3722->dev, "ASIC_ID2 read failed: %d\n", ret); | |
238 | + return ret; | |
239 | + } | |
240 | + | |
241 | + dev_info(as3722->dev, "AS3722 with revision 0x%x found\n", val); | |
242 | + return 0; | |
243 | +} | |
244 | + | |
245 | +static int as3722_configure_pullups(struct as3722 *as3722) | |
246 | +{ | |
247 | + int ret; | |
248 | + u32 val = 0; | |
249 | + | |
250 | + if (as3722->en_intern_int_pullup) | |
251 | + val |= AS3722_INT_PULL_UP; | |
252 | + if (as3722->en_intern_i2c_pullup) | |
253 | + val |= AS3722_I2C_PULL_UP; | |
254 | + | |
255 | + ret = as3722_update_bits(as3722, AS3722_IOVOLTAGE_REG, | |
256 | + AS3722_INT_PULL_UP | AS3722_I2C_PULL_UP, val); | |
257 | + if (ret < 0) | |
258 | + dev_err(as3722->dev, "IOVOLTAGE_REG update failed: %d\n", ret); | |
259 | + return ret; | |
260 | +} | |
261 | + | |
262 | +static const struct regmap_range as3722_readable_ranges[] = { | |
263 | + regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG), | |
264 | + regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG), | |
265 | + regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_REG_SEQU_MOD3_REG), | |
266 | + regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG), | |
267 | + regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG), | |
268 | + regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG, | |
269 | + AS3722_BATTERY_VOLTAGE_MONITOR2_REG), | |
270 | + regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG), | |
271 | + regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG), | |
272 | + regmap_reg_range(AS3722_RTC_ACCESS_REG, AS3722_RTC_ACCESS_REG), | |
273 | + regmap_reg_range(AS3722_RTC_STATUS_REG, AS3722_TEMP_STATUS_REG), | |
274 | + regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG), | |
275 | + regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG), | |
276 | + regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), | |
277 | +}; | |
278 | + | |
279 | +static const struct regmap_access_table as3722_readable_table = { | |
280 | + .yes_ranges = as3722_readable_ranges, | |
281 | + .n_yes_ranges = ARRAY_SIZE(as3722_readable_ranges), | |
282 | +}; | |
283 | + | |
284 | +static const struct regmap_range as3722_writable_ranges[] = { | |
285 | + regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_SD6_VOLTAGE_REG), | |
286 | + regmap_reg_range(AS3722_GPIO0_CONTROL_REG, AS3722_LDO7_VOLTAGE_REG), | |
287 | + regmap_reg_range(AS3722_LDO9_VOLTAGE_REG, AS3722_GPIO_SIGNAL_OUT_REG), | |
288 | + regmap_reg_range(AS3722_REG_SEQU_MOD1_REG, AS3722_REG_SEQU_MOD3_REG), | |
289 | + regmap_reg_range(AS3722_SD_PHSW_CTRL_REG, AS3722_PWM_CONTROL_H_REG), | |
290 | + regmap_reg_range(AS3722_WATCHDOG_TIMER_REG, AS3722_WATCHDOG_TIMER_REG), | |
291 | + regmap_reg_range(AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG, | |
292 | + AS3722_BATTERY_VOLTAGE_MONITOR2_REG), | |
293 | + regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_PWM_VCONTROL4_REG), | |
294 | + regmap_reg_range(AS3722_BB_CHARGER_REG, AS3722_SRAM_REG), | |
295 | + regmap_reg_range(AS3722_INTERRUPT_MASK1_REG, AS3722_TEMP_STATUS_REG), | |
296 | + regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC1_CONTROL_REG), | |
297 | + regmap_reg_range(AS3722_ADC1_THRESHOLD_HI_MSB_REG, | |
298 | + AS3722_ADC_CONFIGURATION_REG), | |
299 | + regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), | |
300 | +}; | |
301 | + | |
302 | +static const struct regmap_access_table as3722_writable_table = { | |
303 | + .yes_ranges = as3722_writable_ranges, | |
304 | + .n_yes_ranges = ARRAY_SIZE(as3722_writable_ranges), | |
305 | +}; | |
306 | + | |
307 | +static const struct regmap_range as3722_cacheable_ranges[] = { | |
308 | + regmap_reg_range(AS3722_SD0_VOLTAGE_REG, AS3722_LDO11_VOLTAGE_REG), | |
309 | + regmap_reg_range(AS3722_SD_CONTROL_REG, AS3722_LDOCONTROL1_REG), | |
310 | +}; | |
311 | + | |
312 | +static const struct regmap_access_table as3722_volatile_table = { | |
313 | + .no_ranges = as3722_cacheable_ranges, | |
314 | + .n_no_ranges = ARRAY_SIZE(as3722_cacheable_ranges), | |
315 | +}; | |
316 | + | |
317 | +const struct regmap_config as3722_regmap_config = { | |
318 | + .reg_bits = 8, | |
319 | + .val_bits = 8, | |
320 | + .max_register = AS3722_MAX_REGISTER, | |
321 | + .cache_type = REGCACHE_RBTREE, | |
322 | + .rd_table = &as3722_readable_table, | |
323 | + .wr_table = &as3722_writable_table, | |
324 | + .volatile_table = &as3722_volatile_table, | |
325 | +}; | |
326 | + | |
327 | +static int as3722_i2c_of_probe(struct i2c_client *i2c, | |
328 | + struct as3722 *as3722) | |
329 | +{ | |
330 | + struct device_node *np = i2c->dev.of_node; | |
331 | + struct irq_data *irq_data; | |
332 | + | |
333 | + if (!np) { | |
334 | + dev_err(&i2c->dev, "Device Tree not found\n"); | |
335 | + return -EINVAL; | |
336 | + } | |
337 | + | |
338 | + irq_data = irq_get_irq_data(i2c->irq); | |
339 | + if (!irq_data) { | |
340 | + dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq); | |
341 | + return -EINVAL; | |
342 | + } | |
343 | + | |
344 | + as3722->en_intern_int_pullup = of_property_read_bool(np, | |
345 | + "ams,enable-internal-int-pullup"); | |
346 | + as3722->en_intern_i2c_pullup = of_property_read_bool(np, | |
347 | + "ams,enable-internal-i2c-pullup"); | |
348 | + as3722->irq_flags = irqd_get_trigger_type(irq_data); | |
349 | + dev_dbg(&i2c->dev, "IRQ flags are 0x%08lx\n", as3722->irq_flags); | |
350 | + return 0; | |
351 | +} | |
352 | + | |
353 | +static int as3722_i2c_probe(struct i2c_client *i2c, | |
354 | + const struct i2c_device_id *id) | |
355 | +{ | |
356 | + struct as3722 *as3722; | |
357 | + unsigned long irq_flags; | |
358 | + int ret; | |
359 | + | |
360 | + as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL); | |
361 | + if (!as3722) | |
362 | + return -ENOMEM; | |
363 | + | |
364 | + as3722->dev = &i2c->dev; | |
365 | + as3722->chip_irq = i2c->irq; | |
366 | + i2c_set_clientdata(i2c, as3722); | |
367 | + | |
368 | + ret = as3722_i2c_of_probe(i2c, as3722); | |
369 | + if (ret < 0) | |
370 | + return ret; | |
371 | + | |
372 | + as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config); | |
373 | + if (IS_ERR(as3722->regmap)) { | |
374 | + ret = PTR_ERR(as3722->regmap); | |
375 | + dev_err(&i2c->dev, "regmap init failed: %d\n", ret); | |
376 | + return ret; | |
377 | + } | |
378 | + | |
379 | + ret = as3722_check_device_id(as3722); | |
380 | + if (ret < 0) | |
381 | + return ret; | |
382 | + | |
383 | + irq_flags = as3722->irq_flags | IRQF_ONESHOT; | |
384 | + ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq, | |
385 | + irq_flags, -1, &as3722_irq_chip, | |
386 | + &as3722->irq_data); | |
387 | + if (ret < 0) { | |
388 | + dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret); | |
389 | + return ret; | |
390 | + } | |
391 | + | |
392 | + ret = as3722_configure_pullups(as3722); | |
393 | + if (ret < 0) | |
394 | + goto scrub; | |
395 | + | |
396 | + ret = mfd_add_devices(&i2c->dev, -1, as3722_devs, | |
397 | + ARRAY_SIZE(as3722_devs), NULL, 0, | |
398 | + regmap_irq_get_domain(as3722->irq_data)); | |
399 | + if (ret) { | |
400 | + dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret); | |
401 | + goto scrub; | |
402 | + } | |
403 | + | |
404 | + dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); | |
405 | + return 0; | |
406 | + | |
407 | +scrub: | |
408 | + regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data); | |
409 | + return ret; | |
410 | +} | |
411 | + | |
412 | +static int as3722_i2c_remove(struct i2c_client *i2c) | |
413 | +{ | |
414 | + struct as3722 *as3722 = i2c_get_clientdata(i2c); | |
415 | + | |
416 | + mfd_remove_devices(as3722->dev); | |
417 | + regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data); | |
418 | + return 0; | |
419 | +} | |
420 | + | |
421 | +static const struct of_device_id as3722_of_match[] = { | |
422 | + { .compatible = "ams,as3722", }, | |
423 | + {}, | |
424 | +}; | |
425 | +MODULE_DEVICE_TABLE(of, as3722_of_match); | |
426 | + | |
427 | +static const struct i2c_device_id as3722_i2c_id[] = { | |
428 | + { "as3722", 0 }, | |
429 | + {}, | |
430 | +}; | |
431 | +MODULE_DEVICE_TABLE(i2c, as3722_i2c_id); | |
432 | + | |
433 | +static struct i2c_driver as3722_i2c_driver = { | |
434 | + .driver = { | |
435 | + .name = "as3722", | |
436 | + .owner = THIS_MODULE, | |
437 | + .of_match_table = as3722_of_match, | |
438 | + }, | |
439 | + .probe = as3722_i2c_probe, | |
440 | + .remove = as3722_i2c_remove, | |
441 | + .id_table = as3722_i2c_id, | |
442 | +}; | |
443 | + | |
444 | +module_i2c_driver(as3722_i2c_driver); | |
445 | + | |
446 | +MODULE_DESCRIPTION("I2C support for AS3722 PMICs"); | |
447 | +MODULE_AUTHOR("Florian Lobmaier <florian.lobmaier@ams.com>"); | |
448 | +MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | |
449 | +MODULE_LICENSE("GPL"); |
include/dt-bindings/mfd/as3722.h
1 | +/* | |
2 | + * This header provides macros for ams AS3722 device bindings. | |
3 | + * | |
4 | + * Copyright (c) 2013, NVIDIA Corporation. | |
5 | + * | |
6 | + * Author: Laxman Dewangan <ldewangan@nvidia.com> | |
7 | + * | |
8 | + */ | |
9 | + | |
10 | +#ifndef __DT_BINDINGS_AS3722_H__ | |
11 | +#define __DT_BINDINGS_AS3722_H__ | |
12 | + | |
13 | +/* External control pins */ | |
14 | +#define AS3722_EXT_CONTROL_PIN_ENABLE1 1 | |
15 | +#define AS3722_EXT_CONTROL_PIN_ENABLE2 2 | |
16 | +#define AS3722_EXT_CONTROL_PIN_ENABLE2 3 | |
17 | + | |
18 | +/* Interrupt numbers for AS3722 */ | |
19 | +#define AS3722_IRQ_LID 0 | |
20 | +#define AS3722_IRQ_ACOK 1 | |
21 | +#define AS3722_IRQ_ENABLE1 2 | |
22 | +#define AS3722_IRQ_OCCUR_ALARM_SD0 3 | |
23 | +#define AS3722_IRQ_ONKEY_LONG_PRESS 4 | |
24 | +#define AS3722_IRQ_ONKEY 5 | |
25 | +#define AS3722_IRQ_OVTMP 6 | |
26 | +#define AS3722_IRQ_LOWBAT 7 | |
27 | +#define AS3722_IRQ_SD0_LV 8 | |
28 | +#define AS3722_IRQ_SD1_LV 9 | |
29 | +#define AS3722_IRQ_SD2_LV 10 | |
30 | +#define AS3722_IRQ_PWM1_OV_PROT 11 | |
31 | +#define AS3722_IRQ_PWM2_OV_PROT 12 | |
32 | +#define AS3722_IRQ_ENABLE2 13 | |
33 | +#define AS3722_IRQ_SD6_LV 14 | |
34 | +#define AS3722_IRQ_RTC_REP 15 | |
35 | +#define AS3722_IRQ_RTC_ALARM 16 | |
36 | +#define AS3722_IRQ_GPIO1 17 | |
37 | +#define AS3722_IRQ_GPIO2 18 | |
38 | +#define AS3722_IRQ_GPIO3 19 | |
39 | +#define AS3722_IRQ_GPIO4 20 | |
40 | +#define AS3722_IRQ_GPIO5 21 | |
41 | +#define AS3722_IRQ_WATCHDOG 22 | |
42 | +#define AS3722_IRQ_ENABLE3 23 | |
43 | +#define AS3722_IRQ_TEMP_SD0_SHUTDOWN 24 | |
44 | +#define AS3722_IRQ_TEMP_SD1_SHUTDOWN 25 | |
45 | +#define AS3722_IRQ_TEMP_SD2_SHUTDOWN 26 | |
46 | +#define AS3722_IRQ_TEMP_SD0_ALARM 27 | |
47 | +#define AS3722_IRQ_TEMP_SD1_ALARM 28 | |
48 | +#define AS3722_IRQ_TEMP_SD6_ALARM 29 | |
49 | +#define AS3722_IRQ_OCCUR_ALARM_SD6 30 | |
50 | +#define AS3722_IRQ_ADC 31 | |
51 | + | |
52 | +#endif /* __DT_BINDINGS_AS3722_H__ */ |
include/linux/mfd/as3722.h
1 | +/* | |
2 | + * as3722 definitions | |
3 | + * | |
4 | + * Copyright (C) 2013 ams | |
5 | + * Copyright (c) 2013, NVIDIA Corporation. All rights reserved. | |
6 | + * | |
7 | + * Author: Florian Lobmaier <florian.lobmaier@ams.com> | |
8 | + * Author: Laxman Dewangan <ldewangan@nvidia.com> | |
9 | + * | |
10 | + * This program is free software; you can redistribute it and/or modify | |
11 | + * it under the terms of the GNU General Public License as published by | |
12 | + * the Free Software Foundation; either version 2 of the License, or | |
13 | + * (at your option) any later version. | |
14 | + * | |
15 | + * This program is distributed in the hope that it will be useful, | |
16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | + * GNU General Public License for more details. | |
19 | + * | |
20 | + * You should have received a copy of the GNU General Public License | |
21 | + * along with this program; if not, write to the Free Software | |
22 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 | + * | |
24 | + */ | |
25 | + | |
26 | +#ifndef __LINUX_MFD_AS3722_H__ | |
27 | +#define __LINUX_MFD_AS3722_H__ | |
28 | + | |
29 | +#include <linux/regmap.h> | |
30 | + | |
31 | +/* AS3722 registers */ | |
32 | +#define AS3722_SD0_VOLTAGE_REG 0x00 | |
33 | +#define AS3722_SD1_VOLTAGE_REG 0x01 | |
34 | +#define AS3722_SD2_VOLTAGE_REG 0x02 | |
35 | +#define AS3722_SD3_VOLTAGE_REG 0x03 | |
36 | +#define AS3722_SD4_VOLTAGE_REG 0x04 | |
37 | +#define AS3722_SD5_VOLTAGE_REG 0x05 | |
38 | +#define AS3722_SD6_VOLTAGE_REG 0x06 | |
39 | +#define AS3722_GPIO0_CONTROL_REG 0x08 | |
40 | +#define AS3722_GPIO1_CONTROL_REG 0x09 | |
41 | +#define AS3722_GPIO2_CONTROL_REG 0x0A | |
42 | +#define AS3722_GPIO3_CONTROL_REG 0x0B | |
43 | +#define AS3722_GPIO4_CONTROL_REG 0x0C | |
44 | +#define AS3722_GPIO5_CONTROL_REG 0x0D | |
45 | +#define AS3722_GPIO6_CONTROL_REG 0x0E | |
46 | +#define AS3722_GPIO7_CONTROL_REG 0x0F | |
47 | +#define AS3722_LDO0_VOLTAGE_REG 0x10 | |
48 | +#define AS3722_LDO1_VOLTAGE_REG 0x11 | |
49 | +#define AS3722_LDO2_VOLTAGE_REG 0x12 | |
50 | +#define AS3722_LDO3_VOLTAGE_REG 0x13 | |
51 | +#define AS3722_LDO4_VOLTAGE_REG 0x14 | |
52 | +#define AS3722_LDO5_VOLTAGE_REG 0x15 | |
53 | +#define AS3722_LDO6_VOLTAGE_REG 0x16 | |
54 | +#define AS3722_LDO7_VOLTAGE_REG 0x17 | |
55 | +#define AS3722_LDO9_VOLTAGE_REG 0x19 | |
56 | +#define AS3722_LDO10_VOLTAGE_REG 0x1A | |
57 | +#define AS3722_LDO11_VOLTAGE_REG 0x1B | |
58 | +#define AS3722_GPIO_DEB1_REG 0x1E | |
59 | +#define AS3722_GPIO_DEB2_REG 0x1F | |
60 | +#define AS3722_GPIO_SIGNAL_OUT_REG 0x20 | |
61 | +#define AS3722_GPIO_SIGNAL_IN_REG 0x21 | |
62 | +#define AS3722_REG_SEQU_MOD1_REG 0x22 | |
63 | +#define AS3722_REG_SEQU_MOD2_REG 0x23 | |
64 | +#define AS3722_REG_SEQU_MOD3_REG 0x24 | |
65 | +#define AS3722_SD_PHSW_CTRL_REG 0x27 | |
66 | +#define AS3722_SD_PHSW_STATUS 0x28 | |
67 | +#define AS3722_SD0_CONTROL_REG 0x29 | |
68 | +#define AS3722_SD1_CONTROL_REG 0x2A | |
69 | +#define AS3722_SDmph_CONTROL_REG 0x2B | |
70 | +#define AS3722_SD23_CONTROL_REG 0x2C | |
71 | +#define AS3722_SD4_CONTROL_REG 0x2D | |
72 | +#define AS3722_SD5_CONTROL_REG 0x2E | |
73 | +#define AS3722_SD6_CONTROL_REG 0x2F | |
74 | +#define AS3722_SD_DVM_REG 0x30 | |
75 | +#define AS3722_RESET_REASON_REG 0x31 | |
76 | +#define AS3722_BATTERY_VOLTAGE_MONITOR_REG 0x32 | |
77 | +#define AS3722_STARTUP_CONTROL_REG 0x33 | |
78 | +#define AS3722_RESET_TIMER_REG 0x34 | |
79 | +#define AS3722_REFERENCE_CONTROL_REG 0x35 | |
80 | +#define AS3722_RESET_CONTROL_REG 0x36 | |
81 | +#define AS3722_OVER_TEMP_CONTROL_REG 0x37 | |
82 | +#define AS3722_WATCHDOG_CONTROL_REG 0x38 | |
83 | +#define AS3722_REG_STANDBY_MOD1_REG 0x39 | |
84 | +#define AS3722_REG_STANDBY_MOD2_REG 0x3A | |
85 | +#define AS3722_REG_STANDBY_MOD3_REG 0x3B | |
86 | +#define AS3722_ENABLE_CTRL1_REG 0x3C | |
87 | +#define AS3722_ENABLE_CTRL2_REG 0x3D | |
88 | +#define AS3722_ENABLE_CTRL3_REG 0x3E | |
89 | +#define AS3722_ENABLE_CTRL4_REG 0x3F | |
90 | +#define AS3722_ENABLE_CTRL5_REG 0x40 | |
91 | +#define AS3722_PWM_CONTROL_L_REG 0x41 | |
92 | +#define AS3722_PWM_CONTROL_H_REG 0x42 | |
93 | +#define AS3722_WATCHDOG_TIMER_REG 0x46 | |
94 | +#define AS3722_WATCHDOG_SOFTWARE_SIGNAL_REG 0x48 | |
95 | +#define AS3722_IOVOLTAGE_REG 0x49 | |
96 | +#define AS3722_BATTERY_VOLTAGE_MONITOR2_REG 0x4A | |
97 | +#define AS3722_SD_CONTROL_REG 0x4D | |
98 | +#define AS3722_LDOCONTROL0_REG 0x4E | |
99 | +#define AS3722_LDOCONTROL1_REG 0x4F | |
100 | +#define AS3722_SD0_PROTECT_REG 0x50 | |
101 | +#define AS3722_SD6_PROTECT_REG 0x51 | |
102 | +#define AS3722_PWM_VCONTROL1_REG 0x52 | |
103 | +#define AS3722_PWM_VCONTROL2_REG 0x53 | |
104 | +#define AS3722_PWM_VCONTROL3_REG 0x54 | |
105 | +#define AS3722_PWM_VCONTROL4_REG 0x55 | |
106 | +#define AS3722_BB_CHARGER_REG 0x57 | |
107 | +#define AS3722_CTRL_SEQU1_REG 0x58 | |
108 | +#define AS3722_CTRL_SEQU2_REG 0x59 | |
109 | +#define AS3722_OVCURRENT_REG 0x5A | |
110 | +#define AS3722_OVCURRENT_DEB_REG 0x5B | |
111 | +#define AS3722_SDLV_DEB_REG 0x5C | |
112 | +#define AS3722_OC_PG_CTRL_REG 0x5D | |
113 | +#define AS3722_OC_PG_CTRL2_REG 0x5E | |
114 | +#define AS3722_CTRL_STATUS 0x5F | |
115 | +#define AS3722_RTC_CONTROL_REG 0x60 | |
116 | +#define AS3722_RTC_SECOND_REG 0x61 | |
117 | +#define AS3722_RTC_MINUTE_REG 0x62 | |
118 | +#define AS3722_RTC_HOUR_REG 0x63 | |
119 | +#define AS3722_RTC_DAY_REG 0x64 | |
120 | +#define AS3722_RTC_MONTH_REG 0x65 | |
121 | +#define AS3722_RTC_YEAR_REG 0x66 | |
122 | +#define AS3722_RTC_ALARM_SECOND_REG 0x67 | |
123 | +#define AS3722_RTC_ALARM_MINUTE_REG 0x68 | |
124 | +#define AS3722_RTC_ALARM_HOUR_REG 0x69 | |
125 | +#define AS3722_RTC_ALARM_DAY_REG 0x6A | |
126 | +#define AS3722_RTC_ALARM_MONTH_REG 0x6B | |
127 | +#define AS3722_RTC_ALARM_YEAR_REG 0x6C | |
128 | +#define AS3722_SRAM_REG 0x6D | |
129 | +#define AS3722_RTC_ACCESS_REG 0x6F | |
130 | +#define AS3722_RTC_STATUS_REG 0x73 | |
131 | +#define AS3722_INTERRUPT_MASK1_REG 0x74 | |
132 | +#define AS3722_INTERRUPT_MASK2_REG 0x75 | |
133 | +#define AS3722_INTERRUPT_MASK3_REG 0x76 | |
134 | +#define AS3722_INTERRUPT_MASK4_REG 0x77 | |
135 | +#define AS3722_INTERRUPT_STATUS1_REG 0x78 | |
136 | +#define AS3722_INTERRUPT_STATUS2_REG 0x79 | |
137 | +#define AS3722_INTERRUPT_STATUS3_REG 0x7A | |
138 | +#define AS3722_INTERRUPT_STATUS4_REG 0x7B | |
139 | +#define AS3722_TEMP_STATUS_REG 0x7D | |
140 | +#define AS3722_ADC0_CONTROL_REG 0x80 | |
141 | +#define AS3722_ADC1_CONTROL_REG 0x81 | |
142 | +#define AS3722_ADC0_MSB_RESULT_REG 0x82 | |
143 | +#define AS3722_ADC0_LSB_RESULT_REG 0x83 | |
144 | +#define AS3722_ADC1_MSB_RESULT_REG 0x84 | |
145 | +#define AS3722_ADC1_LSB_RESULT_REG 0x85 | |
146 | +#define AS3722_ADC1_THRESHOLD_HI_MSB_REG 0x86 | |
147 | +#define AS3722_ADC1_THRESHOLD_HI_LSB_REG 0x87 | |
148 | +#define AS3722_ADC1_THRESHOLD_LO_MSB_REG 0x88 | |
149 | +#define AS3722_ADC1_THRESHOLD_LO_LSB_REG 0x89 | |
150 | +#define AS3722_ADC_CONFIGURATION_REG 0x8A | |
151 | +#define AS3722_ASIC_ID1_REG 0x90 | |
152 | +#define AS3722_ASIC_ID2_REG 0x91 | |
153 | +#define AS3722_LOCK_REG 0x9E | |
154 | +#define AS3722_MAX_REGISTER 0xF4 | |
155 | + | |
156 | +#define AS3722_SD0_EXT_ENABLE_MASK 0x03 | |
157 | +#define AS3722_SD1_EXT_ENABLE_MASK 0x0C | |
158 | +#define AS3722_SD2_EXT_ENABLE_MASK 0x30 | |
159 | +#define AS3722_SD3_EXT_ENABLE_MASK 0xC0 | |
160 | +#define AS3722_SD4_EXT_ENABLE_MASK 0x03 | |
161 | +#define AS3722_SD5_EXT_ENABLE_MASK 0x0C | |
162 | +#define AS3722_SD6_EXT_ENABLE_MASK 0x30 | |
163 | +#define AS3722_LDO0_EXT_ENABLE_MASK 0x03 | |
164 | +#define AS3722_LDO1_EXT_ENABLE_MASK 0x0C | |
165 | +#define AS3722_LDO2_EXT_ENABLE_MASK 0x30 | |
166 | +#define AS3722_LDO3_EXT_ENABLE_MASK 0xC0 | |
167 | +#define AS3722_LDO4_EXT_ENABLE_MASK 0x03 | |
168 | +#define AS3722_LDO5_EXT_ENABLE_MASK 0x0C | |
169 | +#define AS3722_LDO6_EXT_ENABLE_MASK 0x30 | |
170 | +#define AS3722_LDO7_EXT_ENABLE_MASK 0xC0 | |
171 | +#define AS3722_LDO9_EXT_ENABLE_MASK 0x0C | |
172 | +#define AS3722_LDO10_EXT_ENABLE_MASK 0x30 | |
173 | +#define AS3722_LDO11_EXT_ENABLE_MASK 0xC0 | |
174 | + | |
175 | +#define AS3722_OVCURRENT_SD0_ALARM_MASK 0x07 | |
176 | +#define AS3722_OVCURRENT_SD0_ALARM_SHIFT 0x01 | |
177 | +#define AS3722_OVCURRENT_SD0_TRIP_MASK 0x18 | |
178 | +#define AS3722_OVCURRENT_SD0_TRIP_SHIFT 0x03 | |
179 | +#define AS3722_OVCURRENT_SD1_TRIP_MASK 0x60 | |
180 | +#define AS3722_OVCURRENT_SD1_TRIP_SHIFT 0x05 | |
181 | + | |
182 | +#define AS3722_OVCURRENT_SD6_ALARM_MASK 0x07 | |
183 | +#define AS3722_OVCURRENT_SD6_ALARM_SHIFT 0x01 | |
184 | +#define AS3722_OVCURRENT_SD6_TRIP_MASK 0x18 | |
185 | +#define AS3722_OVCURRENT_SD6_TRIP_SHIFT 0x03 | |
186 | + | |
187 | +/* AS3722 register bits and bit masks */ | |
188 | +#define AS3722_LDO_ILIMIT_MASK BIT(7) | |
189 | +#define AS3722_LDO_ILIMIT_BIT BIT(7) | |
190 | +#define AS3722_LDO0_VSEL_MASK 0x1F | |
191 | +#define AS3722_LDO0_VSEL_MIN 0x01 | |
192 | +#define AS3722_LDO0_VSEL_MAX 0x12 | |
193 | +#define AS3722_LDO0_NUM_VOLT 0x12 | |
194 | +#define AS3722_LDO3_VSEL_MASK 0x3F | |
195 | +#define AS3722_LDO3_VSEL_MIN 0x01 | |
196 | +#define AS3722_LDO3_VSEL_MAX 0x2D | |
197 | +#define AS3722_LDO3_NUM_VOLT 0x2D | |
198 | +#define AS3722_LDO_VSEL_MASK 0x7F | |
199 | +#define AS3722_LDO_VSEL_MIN 0x01 | |
200 | +#define AS3722_LDO_VSEL_MAX 0x7F | |
201 | +#define AS3722_LDO_VSEL_DNU_MIN 0x25 | |
202 | +#define AS3722_LDO_VSEL_DNU_MAX 0x3F | |
203 | +#define AS3722_LDO_NUM_VOLT 0x80 | |
204 | + | |
205 | +#define AS3722_LDO0_CTRL BIT(0) | |
206 | +#define AS3722_LDO1_CTRL BIT(1) | |
207 | +#define AS3722_LDO2_CTRL BIT(2) | |
208 | +#define AS3722_LDO3_CTRL BIT(3) | |
209 | +#define AS3722_LDO4_CTRL BIT(4) | |
210 | +#define AS3722_LDO5_CTRL BIT(5) | |
211 | +#define AS3722_LDO6_CTRL BIT(6) | |
212 | +#define AS3722_LDO7_CTRL BIT(7) | |
213 | +#define AS3722_LDO9_CTRL BIT(1) | |
214 | +#define AS3722_LDO10_CTRL BIT(2) | |
215 | +#define AS3722_LDO11_CTRL BIT(3) | |
216 | + | |
217 | +#define AS3722_LDO3_MODE_MASK (3 << 6) | |
218 | +#define AS3722_LDO3_MODE_VAL(n) (((n) & 0x3) << 6) | |
219 | +#define AS3722_LDO3_MODE_PMOS AS3722_LDO3_MODE_VAL(0) | |
220 | +#define AS3722_LDO3_MODE_PMOS_TRACKING AS3722_LDO3_MODE_VAL(1) | |
221 | +#define AS3722_LDO3_MODE_NMOS AS3722_LDO3_MODE_VAL(2) | |
222 | +#define AS3722_LDO3_MODE_SWITCH AS3722_LDO3_MODE_VAL(3) | |
223 | + | |
224 | +#define AS3722_SD_VSEL_MASK 0x7F | |
225 | +#define AS3722_SD0_VSEL_MIN 0x01 | |
226 | +#define AS3722_SD0_VSEL_MAX 0x5A | |
227 | +#define AS3722_SD2_VSEL_MIN 0x01 | |
228 | +#define AS3722_SD2_VSEL_MAX 0x7F | |
229 | + | |
230 | +#define AS3722_SDn_CTRL(n) BIT(n) | |
231 | + | |
232 | +#define AS3722_SD0_MODE_FAST BIT(4) | |
233 | +#define AS3722_SD1_MODE_FAST BIT(4) | |
234 | +#define AS3722_SD2_MODE_FAST BIT(2) | |
235 | +#define AS3722_SD3_MODE_FAST BIT(6) | |
236 | +#define AS3722_SD4_MODE_FAST BIT(2) | |
237 | +#define AS3722_SD5_MODE_FAST BIT(2) | |
238 | +#define AS3722_SD6_MODE_FAST BIT(4) | |
239 | + | |
240 | +#define AS3722_POWER_OFF BIT(1) | |
241 | + | |
242 | +#define AS3722_INTERRUPT_MASK1_LID BIT(0) | |
243 | +#define AS3722_INTERRUPT_MASK1_ACOK BIT(1) | |
244 | +#define AS3722_INTERRUPT_MASK1_ENABLE1 BIT(2) | |
245 | +#define AS3722_INTERRUPT_MASK1_OCURR_ALARM_SD0 BIT(3) | |
246 | +#define AS3722_INTERRUPT_MASK1_ONKEY_LONG BIT(4) | |
247 | +#define AS3722_INTERRUPT_MASK1_ONKEY BIT(5) | |
248 | +#define AS3722_INTERRUPT_MASK1_OVTMP BIT(6) | |
249 | +#define AS3722_INTERRUPT_MASK1_LOWBAT BIT(7) | |
250 | + | |
251 | +#define AS3722_INTERRUPT_MASK2_SD0_LV BIT(0) | |
252 | +#define AS3722_INTERRUPT_MASK2_SD1_LV BIT(1) | |
253 | +#define AS3722_INTERRUPT_MASK2_SD2345_LV BIT(2) | |
254 | +#define AS3722_INTERRUPT_MASK2_PWM1_OV_PROT BIT(3) | |
255 | +#define AS3722_INTERRUPT_MASK2_PWM2_OV_PROT BIT(4) | |
256 | +#define AS3722_INTERRUPT_MASK2_ENABLE2 BIT(5) | |
257 | +#define AS3722_INTERRUPT_MASK2_SD6_LV BIT(6) | |
258 | +#define AS3722_INTERRUPT_MASK2_RTC_REP BIT(7) | |
259 | + | |
260 | +#define AS3722_INTERRUPT_MASK3_RTC_ALARM BIT(0) | |
261 | +#define AS3722_INTERRUPT_MASK3_GPIO1 BIT(1) | |
262 | +#define AS3722_INTERRUPT_MASK3_GPIO2 BIT(2) | |
263 | +#define AS3722_INTERRUPT_MASK3_GPIO3 BIT(3) | |
264 | +#define AS3722_INTERRUPT_MASK3_GPIO4 BIT(4) | |
265 | +#define AS3722_INTERRUPT_MASK3_GPIO5 BIT(5) | |
266 | +#define AS3722_INTERRUPT_MASK3_WATCHDOG BIT(6) | |
267 | +#define AS3722_INTERRUPT_MASK3_ENABLE3 BIT(7) | |
268 | + | |
269 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD0_SHUTDOWN BIT(0) | |
270 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD1_SHUTDOWN BIT(1) | |
271 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD6_SHUTDOWN BIT(2) | |
272 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD0_ALARM BIT(3) | |
273 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD1_ALARM BIT(4) | |
274 | +#define AS3722_INTERRUPT_MASK4_TEMP_SD6_ALARM BIT(5) | |
275 | +#define AS3722_INTERRUPT_MASK4_OCCUR_ALARM_SD6 BIT(6) | |
276 | +#define AS3722_INTERRUPT_MASK4_ADC BIT(7) | |
277 | + | |
278 | +#define AS3722_ADC1_INTERVAL_TIME BIT(0) | |
279 | +#define AS3722_ADC1_INT_MODE_ON BIT(1) | |
280 | +#define AS3722_ADC_BUF_ON BIT(2) | |
281 | +#define AS3722_ADC1_LOW_VOLTAGE_RANGE BIT(5) | |
282 | +#define AS3722_ADC1_INTEVAL_SCAN BIT(6) | |
283 | +#define AS3722_ADC1_INT_MASK BIT(7) | |
284 | + | |
285 | +#define AS3722_ADC_MSB_VAL_MASK 0x7F | |
286 | +#define AS3722_ADC_LSB_VAL_MASK 0x07 | |
287 | + | |
288 | +#define AS3722_ADC0_CONV_START BIT(7) | |
289 | +#define AS3722_ADC0_CONV_NOTREADY BIT(7) | |
290 | +#define AS3722_ADC0_SOURCE_SELECT_MASK 0x1F | |
291 | + | |
292 | +#define AS3722_ADC1_CONV_START BIT(7) | |
293 | +#define AS3722_ADC1_CONV_NOTREADY BIT(7) | |
294 | +#define AS3722_ADC1_SOURCE_SELECT_MASK 0x1F | |
295 | + | |
296 | +/* GPIO modes */ | |
297 | +#define AS3722_GPIO_MODE_MASK 0x07 | |
298 | +#define AS3722_GPIO_MODE_INPUT 0x00 | |
299 | +#define AS3722_GPIO_MODE_OUTPUT_VDDH 0x01 | |
300 | +#define AS3722_GPIO_MODE_IO_OPEN_DRAIN 0x02 | |
301 | +#define AS3722_GPIO_MODE_ADC_IN 0x03 | |
302 | +#define AS3722_GPIO_MODE_INPUT_PULL_UP 0x04 | |
303 | +#define AS3722_GPIO_MODE_INPUT_PULL_DOWN 0x05 | |
304 | +#define AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP 0x06 | |
305 | +#define AS3722_GPIO_MODE_OUTPUT_VDDL 0x07 | |
306 | +#define AS3722_GPIO_MODE_VAL(n) ((n) & AS3722_GPIO_MODE_MASK) | |
307 | + | |
308 | +#define AS3722_GPIO_INV BIT(7) | |
309 | +#define AS3722_GPIO_IOSF_MASK 0x78 | |
310 | +#define AS3722_GPIO_IOSF_VAL(n) (((n) & 0xF) << 3) | |
311 | +#define AS3722_GPIO_IOSF_NORMAL AS3722_GPIO_IOSF_VAL(0) | |
312 | +#define AS3722_GPIO_IOSF_INTERRUPT_OUT AS3722_GPIO_IOSF_VAL(1) | |
313 | +#define AS3722_GPIO_IOSF_VSUP_LOW_OUT AS3722_GPIO_IOSF_VAL(2) | |
314 | +#define AS3722_GPIO_IOSF_GPIO_INTERRUPT_IN AS3722_GPIO_IOSF_VAL(3) | |
315 | +#define AS3722_GPIO_IOSF_ISINK_PWM_IN AS3722_GPIO_IOSF_VAL(4) | |
316 | +#define AS3722_GPIO_IOSF_VOLTAGE_STBY AS3722_GPIO_IOSF_VAL(5) | |
317 | +#define AS3722_GPIO_IOSF_PWR_GOOD_OUT AS3722_GPIO_IOSF_VAL(7) | |
318 | +#define AS3722_GPIO_IOSF_Q32K_OUT AS3722_GPIO_IOSF_VAL(8) | |
319 | +#define AS3722_GPIO_IOSF_WATCHDOG_IN AS3722_GPIO_IOSF_VAL(9) | |
320 | +#define AS3722_GPIO_IOSF_SOFT_RESET_IN AS3722_GPIO_IOSF_VAL(11) | |
321 | +#define AS3722_GPIO_IOSF_PWM_OUT AS3722_GPIO_IOSF_VAL(12) | |
322 | +#define AS3722_GPIO_IOSF_VSUP_LOW_DEB_OUT AS3722_GPIO_IOSF_VAL(13) | |
323 | +#define AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW AS3722_GPIO_IOSF_VAL(14) | |
324 | + | |
325 | +#define AS3722_GPIOn_SIGNAL(n) BIT(n) | |
326 | +#define AS3722_GPIOn_CONTROL_REG(n) (AS3722_GPIO0_CONTROL_REG + n) | |
327 | +#define AS3722_I2C_PULL_UP BIT(4) | |
328 | +#define AS3722_INT_PULL_UP BIT(5) | |
329 | + | |
330 | +#define AS3722_RTC_REP_WAKEUP_EN BIT(0) | |
331 | +#define AS3722_RTC_ALARM_WAKEUP_EN BIT(1) | |
332 | +#define AS3722_RTC_ON BIT(2) | |
333 | +#define AS3722_RTC_IRQMODE BIT(3) | |
334 | +#define AS3722_RTC_CLK32K_OUT_EN BIT(5) | |
335 | + | |
336 | +#define AS3722_WATCHDOG_TIMER_MAX 0x7F | |
337 | +#define AS3722_WATCHDOG_ON BIT(0) | |
338 | +#define AS3722_WATCHDOG_SW_SIG BIT(0) | |
339 | + | |
340 | +#define AS3722_EXT_CONTROL_ENABLE1 0x1 | |
341 | +#define AS3722_EXT_CONTROL_ENABLE2 0x2 | |
342 | +#define AS3722_EXT_CONTROL_ENABLE3 0x3 | |
343 | + | |
344 | +/* Interrupt IDs */ | |
345 | +enum as3722_irq { | |
346 | + AS3722_IRQ_LID, | |
347 | + AS3722_IRQ_ACOK, | |
348 | + AS3722_IRQ_ENABLE1, | |
349 | + AS3722_IRQ_OCCUR_ALARM_SD0, | |
350 | + AS3722_IRQ_ONKEY_LONG_PRESS, | |
351 | + AS3722_IRQ_ONKEY, | |
352 | + AS3722_IRQ_OVTMP, | |
353 | + AS3722_IRQ_LOWBAT, | |
354 | + AS3722_IRQ_SD0_LV, | |
355 | + AS3722_IRQ_SD1_LV, | |
356 | + AS3722_IRQ_SD2_LV, | |
357 | + AS3722_IRQ_PWM1_OV_PROT, | |
358 | + AS3722_IRQ_PWM2_OV_PROT, | |
359 | + AS3722_IRQ_ENABLE2, | |
360 | + AS3722_IRQ_SD6_LV, | |
361 | + AS3722_IRQ_RTC_REP, | |
362 | + AS3722_IRQ_RTC_ALARM, | |
363 | + AS3722_IRQ_GPIO1, | |
364 | + AS3722_IRQ_GPIO2, | |
365 | + AS3722_IRQ_GPIO3, | |
366 | + AS3722_IRQ_GPIO4, | |
367 | + AS3722_IRQ_GPIO5, | |
368 | + AS3722_IRQ_WATCHDOG, | |
369 | + AS3722_IRQ_ENABLE3, | |
370 | + AS3722_IRQ_TEMP_SD0_SHUTDOWN, | |
371 | + AS3722_IRQ_TEMP_SD1_SHUTDOWN, | |
372 | + AS3722_IRQ_TEMP_SD2_SHUTDOWN, | |
373 | + AS3722_IRQ_TEMP_SD0_ALARM, | |
374 | + AS3722_IRQ_TEMP_SD1_ALARM, | |
375 | + AS3722_IRQ_TEMP_SD6_ALARM, | |
376 | + AS3722_IRQ_OCCUR_ALARM_SD6, | |
377 | + AS3722_IRQ_ADC, | |
378 | + AS3722_IRQ_MAX, | |
379 | +}; | |
380 | + | |
381 | +struct as3722 { | |
382 | + struct device *dev; | |
383 | + struct regmap *regmap; | |
384 | + int chip_irq; | |
385 | + unsigned long irq_flags; | |
386 | + bool en_intern_int_pullup; | |
387 | + bool en_intern_i2c_pullup; | |
388 | + struct regmap_irq_chip_data *irq_data; | |
389 | +}; | |
390 | + | |
391 | +static inline int as3722_read(struct as3722 *as3722, u32 reg, u32 *dest) | |
392 | +{ | |
393 | + return regmap_read(as3722->regmap, reg, dest); | |
394 | +} | |
395 | + | |
396 | +static inline int as3722_write(struct as3722 *as3722, u32 reg, u32 value) | |
397 | +{ | |
398 | + return regmap_write(as3722->regmap, reg, value); | |
399 | +} | |
400 | + | |
401 | +static inline int as3722_block_read(struct as3722 *as3722, u32 reg, | |
402 | + int count, u8 *buf) | |
403 | +{ | |
404 | + return regmap_bulk_read(as3722->regmap, reg, buf, count); | |
405 | +} | |
406 | + | |
407 | +static inline int as3722_block_write(struct as3722 *as3722, u32 reg, | |
408 | + int count, u8 *data) | |
409 | +{ | |
410 | + return regmap_bulk_write(as3722->regmap, reg, data, count); | |
411 | +} | |
412 | + | |
413 | +static inline int as3722_update_bits(struct as3722 *as3722, u32 reg, | |
414 | + u32 mask, u8 val) | |
415 | +{ | |
416 | + return regmap_update_bits(as3722->regmap, reg, mask, val); | |
417 | +} | |
418 | + | |
419 | +static inline int as3722_irq_get_virq(struct as3722 *as3722, int irq) | |
420 | +{ | |
421 | + return regmap_irq_get_virq(as3722->irq_data, irq); | |
422 | +} | |
423 | +#endif /* __LINUX_MFD_AS3722_H__ */ |