Commit d460a6f3d67a8558fb58299518077888b7dbf5f3

Authored by Laxman Dewangan
Committed by Lee Jones
1 parent 71c7f93ea0

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 +};
... ... @@ -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
... ... @@ -162,5 +162,6 @@
162 162 obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
163 163 obj-$(CONFIG_MFD_RETU) += retu-mfd.o
164 164 obj-$(CONFIG_MFD_AS3711) += as3711.o
  165 +obj-$(CONFIG_MFD_AS3722) += as3722.o
165 166 obj-$(CONFIG_MFD_STW481X) += stw481x.o
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__ */