The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/allwinner/axp209.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2015-2016 Emmanuel Vadot <manu@freebsd.org>
    3  * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 /*
   31 * X-Power AXP209/AXP211 PMU for Allwinner SoCs
   32 */
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/eventhandler.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 #include <sys/clock.h>
   40 #include <sys/time.h>
   41 #include <sys/bus.h>
   42 #include <sys/proc.h>
   43 #include <sys/gpio.h>
   44 #include <sys/reboot.h>
   45 #include <sys/resource.h>
   46 #include <sys/rman.h>
   47 #include <sys/sysctl.h>
   48 
   49 #include <dev/iicbus/iiconf.h>
   50 
   51 #include <dev/gpio/gpiobusvar.h>
   52 
   53 #include <dev/ofw/ofw_bus.h>
   54 #include <dev/ofw/ofw_bus_subr.h>
   55 
   56 #include <dev/extres/regulator/regulator.h>
   57 
   58 #include <arm/allwinner/axp209reg.h>
   59 
   60 #include "gpio_if.h"
   61 #include "regdev_if.h"
   62 
   63 MALLOC_DEFINE(M_AXP2XX_REG, "Axp2XX regulator", "Axp2XX power regulator");
   64 
   65 struct axp2xx_regdef {
   66         intptr_t                id;
   67         char                    *name;
   68         uint8_t                 enable_reg;
   69         uint8_t                 enable_mask;
   70         uint8_t                 voltage_reg;
   71         uint8_t                 voltage_mask;
   72         uint8_t                 voltage_shift;
   73         int                     voltage_min;
   74         int                     voltage_max;
   75         int                     voltage_step;
   76         int                     voltage_nstep;
   77 };
   78 
   79 static struct axp2xx_regdef axp209_regdefs[] = {
   80         {
   81                 .id = AXP209_REG_ID_DCDC2,
   82                 .name = "dcdc2",
   83                 .enable_reg = AXP209_POWERCTL,
   84                 .enable_mask = AXP209_POWERCTL_DCDC2,
   85                 .voltage_reg = AXP209_REG_DCDC2_VOLTAGE,
   86                 .voltage_mask = 0x3f,
   87                 .voltage_min = 700,
   88                 .voltage_max = 2275,
   89                 .voltage_step = 25,
   90                 .voltage_nstep = 64,
   91         },
   92         {
   93                 .id = AXP209_REG_ID_DCDC3,
   94                 .name = "dcdc3",
   95                 .enable_reg = AXP209_POWERCTL,
   96                 .enable_mask = AXP209_POWERCTL_DCDC3,
   97                 .voltage_reg = AXP209_REG_DCDC3_VOLTAGE,
   98                 .voltage_mask = 0x7f,
   99                 .voltage_min = 700,
  100                 .voltage_max = 3500,
  101                 .voltage_step = 25,
  102                 .voltage_nstep = 128,
  103         },
  104         {
  105                 .id = AXP209_REG_ID_LDO2,
  106                 .name = "ldo2",
  107                 .enable_reg = AXP209_POWERCTL,
  108                 .enable_mask = AXP209_POWERCTL_LDO2,
  109                 .voltage_reg = AXP209_REG_LDO24_VOLTAGE,
  110                 .voltage_mask = 0xf0,
  111                 .voltage_shift = 4,
  112                 .voltage_min = 1800,
  113                 .voltage_max = 3300,
  114                 .voltage_step = 100,
  115                 .voltage_nstep = 16,
  116         },
  117         {
  118                 .id = AXP209_REG_ID_LDO3,
  119                 .name = "ldo3",
  120                 .enable_reg = AXP209_POWERCTL,
  121                 .enable_mask = AXP209_POWERCTL_LDO3,
  122                 .voltage_reg = AXP209_REG_LDO3_VOLTAGE,
  123                 .voltage_mask = 0x7f,
  124                 .voltage_min = 700,
  125                 .voltage_max = 2275,
  126                 .voltage_step = 25,
  127                 .voltage_nstep = 128,
  128         },
  129 };
  130 
  131 static struct axp2xx_regdef axp221_regdefs[] = {
  132         {
  133                 .id = AXP221_REG_ID_DLDO1,
  134                 .name = "dldo1",
  135                 .enable_reg = AXP221_POWERCTL_2,
  136                 .enable_mask = AXP221_POWERCTL2_DLDO1,
  137                 .voltage_reg = AXP221_REG_DLDO1_VOLTAGE,
  138                 .voltage_mask = 0x1f,
  139                 .voltage_min = 700,
  140                 .voltage_max = 3300,
  141                 .voltage_step = 100,
  142                 .voltage_nstep = 26,
  143         },
  144         {
  145                 .id = AXP221_REG_ID_DLDO2,
  146                 .name = "dldo2",
  147                 .enable_reg = AXP221_POWERCTL_2,
  148                 .enable_mask = AXP221_POWERCTL2_DLDO2,
  149                 .voltage_reg = AXP221_REG_DLDO2_VOLTAGE,
  150                 .voltage_mask = 0x1f,
  151                 .voltage_min = 700,
  152                 .voltage_max = 3300,
  153                 .voltage_step = 100,
  154                 .voltage_nstep = 26,
  155         },
  156         {
  157                 .id = AXP221_REG_ID_DLDO3,
  158                 .name = "dldo3",
  159                 .enable_reg = AXP221_POWERCTL_2,
  160                 .enable_mask = AXP221_POWERCTL2_DLDO3,
  161                 .voltage_reg = AXP221_REG_DLDO3_VOLTAGE,
  162                 .voltage_mask = 0x1f,
  163                 .voltage_min = 700,
  164                 .voltage_max = 3300,
  165                 .voltage_step = 100,
  166                 .voltage_nstep = 26,
  167         },
  168         {
  169                 .id = AXP221_REG_ID_DLDO4,
  170                 .name = "dldo4",
  171                 .enable_reg = AXP221_POWERCTL_2,
  172                 .enable_mask = AXP221_POWERCTL2_DLDO4,
  173                 .voltage_reg = AXP221_REG_DLDO4_VOLTAGE,
  174                 .voltage_mask = 0x1f,
  175                 .voltage_min = 700,
  176                 .voltage_max = 3300,
  177                 .voltage_step = 100,
  178                 .voltage_nstep = 26,
  179         },
  180         {
  181                 .id = AXP221_REG_ID_ELDO1,
  182                 .name = "eldo1",
  183                 .enable_reg = AXP221_POWERCTL_2,
  184                 .enable_mask = AXP221_POWERCTL2_ELDO1,
  185                 .voltage_reg = AXP221_REG_ELDO1_VOLTAGE,
  186                 .voltage_mask = 0x1f,
  187                 .voltage_min = 700,
  188                 .voltage_max = 3300,
  189                 .voltage_step = 100,
  190                 .voltage_nstep = 26,
  191         },
  192         {
  193                 .id = AXP221_REG_ID_ELDO2,
  194                 .name = "eldo2",
  195                 .enable_reg = AXP221_POWERCTL_2,
  196                 .enable_mask = AXP221_POWERCTL2_ELDO2,
  197                 .voltage_reg = AXP221_REG_ELDO2_VOLTAGE,
  198                 .voltage_mask = 0x1f,
  199                 .voltage_min = 700,
  200                 .voltage_max = 3300,
  201                 .voltage_step = 100,
  202                 .voltage_nstep = 26,
  203         },
  204         {
  205                 .id = AXP221_REG_ID_ELDO3,
  206                 .name = "eldo3",
  207                 .enable_reg = AXP221_POWERCTL_2,
  208                 .enable_mask = AXP221_POWERCTL2_ELDO3,
  209                 .voltage_reg = AXP221_REG_ELDO3_VOLTAGE,
  210                 .voltage_mask = 0x1f,
  211                 .voltage_min = 700,
  212                 .voltage_max = 3300,
  213                 .voltage_step = 100,
  214                 .voltage_nstep = 26,
  215         },
  216         {
  217                 .id = AXP221_REG_ID_DC5LDO,
  218                 .name = "dc5ldo",
  219                 .enable_reg = AXP221_POWERCTL_1,
  220                 .enable_mask = AXP221_POWERCTL1_DC5LDO,
  221                 .voltage_reg = AXP221_REG_DC5LDO_VOLTAGE,
  222                 .voltage_mask = 0x3,
  223                 .voltage_min = 700,
  224                 .voltage_max = 1400,
  225                 .voltage_step = 100,
  226                 .voltage_nstep = 7,
  227         },
  228         {
  229                 .id = AXP221_REG_ID_DCDC1,
  230                 .name = "dcdc1",
  231                 .enable_reg = AXP221_POWERCTL_1,
  232                 .enable_mask = AXP221_POWERCTL1_DCDC1,
  233                 .voltage_reg = AXP221_REG_DCDC1_VOLTAGE,
  234                 .voltage_mask = 0x1f,
  235                 .voltage_min = 1600,
  236                 .voltage_max = 3400,
  237                 .voltage_step = 100,
  238                 .voltage_nstep = 18,
  239         },
  240         {
  241                 .id = AXP221_REG_ID_DCDC2,
  242                 .name = "dcdc2",
  243                 .enable_reg = AXP221_POWERCTL_1,
  244                 .enable_mask = AXP221_POWERCTL1_DCDC2,
  245                 .voltage_reg = AXP221_REG_DCDC2_VOLTAGE,
  246                 .voltage_mask = 0x3f,
  247                 .voltage_min = 600,
  248                 .voltage_max = 1540,
  249                 .voltage_step = 20,
  250                 .voltage_nstep = 47,
  251         },
  252         {
  253                 .id = AXP221_REG_ID_DCDC3,
  254                 .name = "dcdc3",
  255                 .enable_reg = AXP221_POWERCTL_1,
  256                 .enable_mask = AXP221_POWERCTL1_DCDC3,
  257                 .voltage_reg = AXP221_REG_DCDC3_VOLTAGE,
  258                 .voltage_mask = 0x3f,
  259                 .voltage_min = 600,
  260                 .voltage_max = 1860,
  261                 .voltage_step = 20,
  262                 .voltage_nstep = 63,
  263         },
  264         {
  265                 .id = AXP221_REG_ID_DCDC4,
  266                 .name = "dcdc4",
  267                 .enable_reg = AXP221_POWERCTL_1,
  268                 .enable_mask = AXP221_POWERCTL1_DCDC4,
  269                 .voltage_reg = AXP221_REG_DCDC4_VOLTAGE,
  270                 .voltage_mask = 0x3f,
  271                 .voltage_min = 600,
  272                 .voltage_max = 1540,
  273                 .voltage_step = 20,
  274                 .voltage_nstep = 47,
  275         },
  276         {
  277                 .id = AXP221_REG_ID_DCDC5,
  278                 .name = "dcdc5",
  279                 .enable_reg = AXP221_POWERCTL_1,
  280                 .enable_mask = AXP221_POWERCTL1_DCDC5,
  281                 .voltage_reg = AXP221_REG_DCDC5_VOLTAGE,
  282                 .voltage_mask = 0x1f,
  283                 .voltage_min = 1000,
  284                 .voltage_max = 2550,
  285                 .voltage_step = 50,
  286                 .voltage_nstep = 31,
  287         },
  288         {
  289                 .id = AXP221_REG_ID_ALDO1,
  290                 .name = "aldo1",
  291                 .enable_reg = AXP221_POWERCTL_1,
  292                 .enable_mask = AXP221_POWERCTL1_ALDO1,
  293                 .voltage_reg = AXP221_REG_ALDO1_VOLTAGE,
  294                 .voltage_mask = 0x1f,
  295                 .voltage_min = 700,
  296                 .voltage_max = 3300,
  297                 .voltage_step = 100,
  298                 .voltage_nstep = 26,
  299         },
  300         {
  301                 .id = AXP221_REG_ID_ALDO2,
  302                 .name = "aldo2",
  303                 .enable_reg = AXP221_POWERCTL_1,
  304                 .enable_mask = AXP221_POWERCTL1_ALDO2,
  305                 .voltage_reg = AXP221_REG_ALDO2_VOLTAGE,
  306                 .voltage_mask = 0x1f,
  307                 .voltage_min = 700,
  308                 .voltage_max = 3300,
  309                 .voltage_step = 100,
  310                 .voltage_nstep = 26,
  311         },
  312         {
  313                 .id = AXP221_REG_ID_ALDO3,
  314                 .name = "aldo3",
  315                 .enable_reg = AXP221_POWERCTL_3,
  316                 .enable_mask = AXP221_POWERCTL3_ALDO3,
  317                 .voltage_reg = AXP221_REG_ALDO3_VOLTAGE,
  318                 .voltage_mask = 0x1f,
  319                 .voltage_min = 700,
  320                 .voltage_max = 3300,
  321                 .voltage_step = 100,
  322                 .voltage_nstep = 26,
  323         },
  324         {
  325                 .id = AXP221_REG_ID_DC1SW,
  326                 .name = "dc1sw",
  327                 .enable_reg = AXP221_POWERCTL_2,
  328                 .enable_mask = AXP221_POWERCTL2_DC1SW,
  329         },
  330 };
  331 
  332 struct axp2xx_reg_sc {
  333         struct regnode          *regnode;
  334         device_t                base_dev;
  335         struct axp2xx_regdef    *def;
  336         phandle_t               xref;
  337         struct regnode_std_param *param;
  338 };
  339 
  340 struct axp2xx_pins {
  341         const char      *name;
  342         uint8_t         ctrl_reg;
  343         uint8_t         status_reg;
  344         uint8_t         status_mask;
  345         uint8_t         status_shift;
  346 };
  347 
  348 /* GPIO3 is different, don't expose it for now */
  349 static const struct axp2xx_pins axp209_pins[] = {
  350         {
  351                 .name = "GPIO0",
  352                 .ctrl_reg = AXP2XX_GPIO0_CTRL,
  353                 .status_reg = AXP2XX_GPIO_STATUS,
  354                 .status_mask = 0x10,
  355                 .status_shift = 4,
  356         },
  357         {
  358                 .name = "GPIO1",
  359                 .ctrl_reg = AXP2XX_GPIO1_CTRL,
  360                 .status_reg = AXP2XX_GPIO_STATUS,
  361                 .status_mask = 0x20,
  362                 .status_shift = 5,
  363         },
  364         {
  365                 .name = "GPIO2",
  366                 .ctrl_reg = AXP209_GPIO2_CTRL,
  367                 .status_reg = AXP2XX_GPIO_STATUS,
  368                 .status_mask = 0x40,
  369                 .status_shift = 6,
  370         },
  371 };
  372 
  373 static const struct axp2xx_pins axp221_pins[] = {
  374         {
  375                 .name = "GPIO0",
  376                 .ctrl_reg = AXP2XX_GPIO0_CTRL,
  377                 .status_reg = AXP2XX_GPIO_STATUS,
  378                 .status_mask = 0x1,
  379                 .status_shift = 0x0,
  380         },
  381         {
  382                 .name = "GPIO1",
  383                 .ctrl_reg = AXP2XX_GPIO0_CTRL,
  384                 .status_reg = AXP2XX_GPIO_STATUS,
  385                 .status_mask = 0x2,
  386                 .status_shift = 0x1,
  387         },
  388 };
  389 
  390 struct axp2xx_sensors {
  391         int             id;
  392         const char      *name;
  393         const char      *desc;
  394         const char      *format;
  395         uint8_t         enable_reg;
  396         uint8_t         enable_mask;
  397         uint8_t         value_reg;
  398         uint8_t         value_size;
  399         uint8_t         h_value_mask;
  400         uint8_t         h_value_shift;
  401         uint8_t         l_value_mask;
  402         uint8_t         l_value_shift;
  403         int             value_step;
  404         int             value_convert;
  405 };
  406 
  407 static const struct axp2xx_sensors axp209_sensors[] = {
  408         {
  409                 .id = AXP209_ACVOLT,
  410                 .name = "acvolt",
  411                 .desc = "AC Voltage (microvolt)",
  412                 .format = "I",
  413                 .enable_reg = AXP2XX_ADC_ENABLE1,
  414                 .enable_mask = AXP209_ADC1_ACVOLT,
  415                 .value_reg = AXP209_ACIN_VOLTAGE,
  416                 .value_size = 2,
  417                 .h_value_mask = 0xff,
  418                 .h_value_shift = 4,
  419                 .l_value_mask = 0xf,
  420                 .l_value_shift = 0,
  421                 .value_step = AXP209_VOLT_STEP,
  422         },
  423         {
  424                 .id = AXP209_ACCURRENT,
  425                 .name = "accurrent",
  426                 .desc = "AC Current (microAmpere)",
  427                 .format = "I",
  428                 .enable_reg = AXP2XX_ADC_ENABLE1,
  429                 .enable_mask = AXP209_ADC1_ACCURRENT,
  430                 .value_reg = AXP209_ACIN_CURRENT,
  431                 .value_size = 2,
  432                 .h_value_mask = 0xff,
  433                 .h_value_shift = 4,
  434                 .l_value_mask = 0xf,
  435                 .l_value_shift = 0,
  436                 .value_step = AXP209_ACCURRENT_STEP,
  437         },
  438         {
  439                 .id = AXP209_VBUSVOLT,
  440                 .name = "vbusvolt",
  441                 .desc = "VBUS Voltage (microVolt)",
  442                 .format = "I",
  443                 .enable_reg = AXP2XX_ADC_ENABLE1,
  444                 .enable_mask = AXP209_ADC1_VBUSVOLT,
  445                 .value_reg = AXP209_VBUS_VOLTAGE,
  446                 .value_size = 2,
  447                 .h_value_mask = 0xff,
  448                 .h_value_shift = 4,
  449                 .l_value_mask = 0xf,
  450                 .l_value_shift = 0,
  451                 .value_step = AXP209_VOLT_STEP,
  452         },
  453         {
  454                 .id = AXP209_VBUSCURRENT,
  455                 .name = "vbuscurrent",
  456                 .desc = "VBUS Current (microAmpere)",
  457                 .format = "I",
  458                 .enable_reg = AXP2XX_ADC_ENABLE1,
  459                 .enable_mask = AXP209_ADC1_VBUSCURRENT,
  460                 .value_reg = AXP209_VBUS_CURRENT,
  461                 .value_size = 2,
  462                 .h_value_mask = 0xff,
  463                 .h_value_shift = 4,
  464                 .l_value_mask = 0xf,
  465                 .l_value_shift = 0,
  466                 .value_step = AXP209_VBUSCURRENT_STEP,
  467         },
  468         {
  469                 .id = AXP2XX_BATVOLT,
  470                 .name = "batvolt",
  471                 .desc = "Battery Voltage (microVolt)",
  472                 .format = "I",
  473                 .enable_reg = AXP2XX_ADC_ENABLE1,
  474                 .enable_mask = AXP2XX_ADC1_BATVOLT,
  475                 .value_reg = AXP2XX_BAT_VOLTAGE,
  476                 .value_size = 2,
  477                 .h_value_mask = 0xff,
  478                 .h_value_shift = 4,
  479                 .l_value_mask = 0xf,
  480                 .l_value_shift = 0,
  481                 .value_step = AXP2XX_BATVOLT_STEP,
  482         },
  483         {
  484                 .id = AXP2XX_BATCHARGECURRENT,
  485                 .name = "batchargecurrent",
  486                 .desc = "Battery Charging Current (microAmpere)",
  487                 .format = "I",
  488                 .enable_reg = AXP2XX_ADC_ENABLE1,
  489                 .enable_mask = AXP2XX_ADC1_BATCURRENT,
  490                 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
  491                 .value_size = 2,
  492                 .h_value_mask = 0xff,
  493                 .h_value_shift = 5,
  494                 .l_value_mask = 0x1f,
  495                 .l_value_shift = 0,
  496                 .value_step = AXP2XX_BATCURRENT_STEP,
  497         },
  498         {
  499                 .id = AXP2XX_BATDISCHARGECURRENT,
  500                 .name = "batdischargecurrent",
  501                 .desc = "Battery Discharging Current (microAmpere)",
  502                 .format = "I",
  503                 .enable_reg = AXP2XX_ADC_ENABLE1,
  504                 .enable_mask = AXP2XX_ADC1_BATCURRENT,
  505                 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
  506                 .value_size = 2,
  507                 .h_value_mask = 0xff,
  508                 .h_value_shift = 5,
  509                 .l_value_mask = 0x1f,
  510                 .l_value_shift = 0,
  511                 .value_step = AXP2XX_BATCURRENT_STEP,
  512         },
  513         {
  514                 .id = AXP2XX_TEMP,
  515                 .name = "temp",
  516                 .desc = "Internal Temperature",
  517                 .format = "IK",
  518                 .enable_reg = AXP209_ADC_ENABLE2,
  519                 .enable_mask = AXP209_ADC2_TEMP,
  520                 .value_reg = AXP209_TEMPMON,
  521                 .value_size = 2,
  522                 .h_value_mask = 0xff,
  523                 .h_value_shift = 4,
  524                 .l_value_mask = 0xf,
  525                 .l_value_shift = 0,
  526                 .value_step = 1,
  527                 .value_convert = -(AXP209_TEMPMON_MIN - AXP209_0C_TO_K),
  528         },
  529 };
  530 
  531 static const struct axp2xx_sensors axp221_sensors[] = {
  532         {
  533                 .id = AXP2XX_BATVOLT,
  534                 .name = "batvolt",
  535                 .desc = "Battery Voltage (microVolt)",
  536                 .format = "I",
  537                 .enable_reg = AXP2XX_ADC_ENABLE1,
  538                 .enable_mask = AXP2XX_ADC1_BATVOLT,
  539                 .value_reg = AXP2XX_BAT_VOLTAGE,
  540                 .value_size = 2,
  541                 .h_value_mask = 0xff,
  542                 .h_value_shift = 4,
  543                 .l_value_mask = 0xf,
  544                 .l_value_shift = 0,
  545                 .value_step = AXP2XX_BATVOLT_STEP,
  546         },
  547         {
  548                 .id = AXP2XX_BATCHARGECURRENT,
  549                 .name = "batchargecurrent",
  550                 .desc = "Battery Charging Current (microAmpere)",
  551                 .format = "I",
  552                 .enable_reg = AXP2XX_ADC_ENABLE1,
  553                 .enable_mask = AXP2XX_ADC1_BATCURRENT,
  554                 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
  555                 .value_size = 2,
  556                 .h_value_mask = 0xff,
  557                 .h_value_shift = 5,
  558                 .l_value_mask = 0x1f,
  559                 .l_value_shift = 0,
  560                 .value_step = AXP2XX_BATCURRENT_STEP,
  561         },
  562         {
  563                 .id = AXP2XX_BATDISCHARGECURRENT,
  564                 .name = "batdischargecurrent",
  565                 .desc = "Battery Discharging Current (microAmpere)",
  566                 .format = "I",
  567                 .enable_reg = AXP2XX_ADC_ENABLE1,
  568                 .enable_mask = AXP2XX_ADC1_BATCURRENT,
  569                 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
  570                 .value_size = 2,
  571                 .h_value_mask = 0xff,
  572                 .h_value_shift = 5,
  573                 .l_value_mask = 0x1f,
  574                 .l_value_shift = 0,
  575                 .value_step = AXP2XX_BATCURRENT_STEP,
  576         },
  577         {
  578                 .id = AXP2XX_TEMP,
  579                 .name = "temp",
  580                 .desc = "Internal Temperature",
  581                 .format = "IK",
  582                 .enable_reg = AXP2XX_ADC_ENABLE1,
  583                 .enable_mask = AXP221_ADC1_TEMP,
  584                 .value_reg = AXP221_TEMPMON,
  585                 .value_size = 2,
  586                 .h_value_mask = 0xff,
  587                 .h_value_shift = 4,
  588                 .l_value_mask = 0xf,
  589                 .l_value_shift = 0,
  590                 .value_step = 1,
  591                 .value_convert = -(AXP221_TEMPMON_MIN - AXP209_0C_TO_K),
  592         },
  593 };
  594 
  595 enum AXP2XX_TYPE {
  596         AXP209 = 1,
  597         AXP221,
  598 };
  599 
  600 struct axp2xx_softc {
  601         device_t                dev;
  602         struct resource *       res[1];
  603         void *                  intrcookie;
  604         struct intr_config_hook intr_hook;
  605         struct mtx              mtx;
  606         uint8_t                 type;
  607 
  608         /* GPIO */
  609         device_t                gpiodev;
  610         int                     npins;
  611         const struct axp2xx_pins        *pins;
  612 
  613         /* Sensors */
  614         const struct axp2xx_sensors     *sensors;
  615         int                             nsensors;
  616 
  617         /* Regulators */
  618         struct axp2xx_reg_sc    **regs;
  619         int                     nregs;
  620         struct axp2xx_regdef    *regdefs;
  621 };
  622 
  623 static struct ofw_compat_data compat_data[] = {
  624         { "x-powers,axp209",            AXP209 },
  625         { "x-powers,axp221",            AXP221 },
  626         { NULL,                         0 }
  627 };
  628 
  629 static struct resource_spec axp_res_spec[] = {
  630         { SYS_RES_IRQ,          0,      RF_ACTIVE },
  631         { -1,                   0,      0 }
  632 };
  633 
  634 #define AXP_LOCK(sc)    mtx_lock(&(sc)->mtx)
  635 #define AXP_UNLOCK(sc)  mtx_unlock(&(sc)->mtx)
  636 
  637 static int
  638 axp2xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
  639 {
  640 
  641         return (iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT));
  642 }
  643 
  644 static int
  645 axp2xx_write(device_t dev, uint8_t reg, uint8_t data)
  646 {
  647 
  648         return (iicdev_writeto(dev, reg, &data, sizeof(data), IIC_INTRWAIT));
  649 }
  650 
  651 static int
  652 axp2xx_regnode_init(struct regnode *regnode)
  653 {
  654         return (0);
  655 }
  656 
  657 static int
  658 axp2xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
  659 {
  660         struct axp2xx_reg_sc *sc;
  661         uint8_t val;
  662 
  663         sc = regnode_get_softc(regnode);
  664 
  665         axp2xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
  666         if (enable)
  667                 val |= sc->def->enable_mask;
  668         else
  669                 val &= ~sc->def->enable_mask;
  670         axp2xx_write(sc->base_dev, sc->def->enable_reg, val);
  671 
  672         *udelay = 0;
  673 
  674         return (0);
  675 }
  676 
  677 static void
  678 axp2xx_regnode_reg_to_voltage(struct axp2xx_reg_sc *sc, uint8_t val, int *uv)
  679 {
  680         if (val < sc->def->voltage_nstep)
  681                 *uv = sc->def->voltage_min + val * sc->def->voltage_step;
  682         else
  683                 *uv = sc->def->voltage_min +
  684                        (sc->def->voltage_nstep * sc->def->voltage_step);
  685         *uv *= 1000;
  686 }
  687 
  688 static int
  689 axp2xx_regnode_voltage_to_reg(struct axp2xx_reg_sc *sc, int min_uvolt,
  690     int max_uvolt, uint8_t *val)
  691 {
  692         uint8_t nval;
  693         int nstep, uvolt;
  694 
  695         nval = 0;
  696         uvolt = sc->def->voltage_min * 1000;
  697 
  698         for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
  699              nstep++) {
  700                 ++nval;
  701                 uvolt += (sc->def->voltage_step * 1000);
  702         }
  703         if (uvolt > max_uvolt)
  704                 return (EINVAL);
  705 
  706         *val = nval;
  707         return (0);
  708 }
  709 
  710 static int
  711 axp2xx_regnode_status(struct regnode *regnode, int *status)
  712 {
  713         struct axp2xx_reg_sc *sc;
  714         uint8_t val;
  715 
  716         sc = regnode_get_softc(regnode);
  717 
  718         *status = 0;
  719         axp2xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
  720         if (val & sc->def->enable_mask)
  721                 *status = REGULATOR_STATUS_ENABLED;
  722 
  723         return (0);
  724 }
  725 
  726 static int
  727 axp2xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
  728     int max_uvolt, int *udelay)
  729 {
  730         struct axp2xx_reg_sc *sc;
  731         uint8_t val;
  732 
  733         sc = regnode_get_softc(regnode);
  734 
  735         if (!sc->def->voltage_step)
  736                 return (ENXIO);
  737 
  738         if (axp2xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
  739                 return (ERANGE);
  740 
  741         axp2xx_write(sc->base_dev, sc->def->voltage_reg, val);
  742 
  743         *udelay = 0;
  744 
  745         return (0);
  746 }
  747 
  748 static int
  749 axp2xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
  750 {
  751         struct axp2xx_reg_sc *sc;
  752         uint8_t val;
  753 
  754         sc = regnode_get_softc(regnode);
  755 
  756         if (!sc->def->voltage_step)
  757                 return (ENXIO);
  758 
  759         axp2xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
  760         axp2xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
  761 
  762         return (0);
  763 }
  764 
  765 static regnode_method_t axp2xx_regnode_methods[] = {
  766         /* Regulator interface */
  767         REGNODEMETHOD(regnode_init,             axp2xx_regnode_init),
  768         REGNODEMETHOD(regnode_enable,           axp2xx_regnode_enable),
  769         REGNODEMETHOD(regnode_status,           axp2xx_regnode_status),
  770         REGNODEMETHOD(regnode_set_voltage,      axp2xx_regnode_set_voltage),
  771         REGNODEMETHOD(regnode_get_voltage,      axp2xx_regnode_get_voltage),
  772         REGNODEMETHOD(regnode_check_voltage,    regnode_method_check_voltage),
  773         REGNODEMETHOD_END
  774 };
  775 DEFINE_CLASS_1(axp2xx_regnode, axp2xx_regnode_class, axp2xx_regnode_methods,
  776     sizeof(struct axp2xx_reg_sc), regnode_class);
  777 
  778 static int
  779 axp2xx_sysctl(SYSCTL_HANDLER_ARGS)
  780 {
  781         struct axp2xx_softc *sc;
  782         device_t dev = arg1;
  783         enum axp2xx_sensor sensor = arg2;
  784         uint8_t data[2];
  785         int val, error, i, found;
  786 
  787         sc = device_get_softc(dev);
  788 
  789         for (found = 0, i = 0; i < sc->nsensors; i++) {
  790                 if (sc->sensors[i].id == sensor) {
  791                         found = 1;
  792                         break;
  793                 }
  794         }
  795 
  796         if (found == 0)
  797                 return (ENOENT);
  798 
  799         error = axp2xx_read(dev, sc->sensors[i].value_reg, data, 2);
  800         if (error != 0)
  801                 return (error);
  802 
  803         val = ((data[0] & sc->sensors[i].h_value_mask) <<
  804             sc->sensors[i].h_value_shift);
  805         val |= ((data[1] & sc->sensors[i].l_value_mask) <<
  806             sc->sensors[i].l_value_shift);
  807         val *= sc->sensors[i].value_step;
  808         val += sc->sensors[i].value_convert;
  809 
  810         return sysctl_handle_opaque(oidp, &val, sizeof(val), req);
  811 }
  812 
  813 static void
  814 axp2xx_shutdown(void *devp, int howto)
  815 {
  816         device_t dev;
  817 
  818         if (!(howto & RB_POWEROFF))
  819                 return;
  820         dev = (device_t)devp;
  821 
  822         if (bootverbose)
  823                 device_printf(dev, "Shutdown AXP2xx\n");
  824 
  825         axp2xx_write(dev, AXP2XX_SHUTBAT, AXP2XX_SHUTBAT_SHUTDOWN);
  826 }
  827 
  828 static void
  829 axp2xx_intr(void *arg)
  830 {
  831         struct axp2xx_softc *sc;
  832         uint8_t reg;
  833 
  834         sc = arg;
  835 
  836         axp2xx_read(sc->dev, AXP2XX_IRQ1_STATUS, &reg, 1);
  837         if (reg) {
  838                 if (reg & AXP2XX_IRQ1_AC_OVERVOLT)
  839                         devctl_notify("PMU", "AC", "overvoltage", NULL);
  840                 if (reg & AXP2XX_IRQ1_VBUS_OVERVOLT)
  841                         devctl_notify("PMU", "USB", "overvoltage", NULL);
  842                 if (reg & AXP2XX_IRQ1_VBUS_LOW)
  843                         devctl_notify("PMU", "USB", "undervoltage", NULL);
  844                 if (reg & AXP2XX_IRQ1_AC_CONN)
  845                         devctl_notify("PMU", "AC", "plugged", NULL);
  846                 if (reg & AXP2XX_IRQ1_AC_DISCONN)
  847                         devctl_notify("PMU", "AC", "unplugged", NULL);
  848                 if (reg & AXP2XX_IRQ1_VBUS_CONN)
  849                         devctl_notify("PMU", "USB", "plugged", NULL);
  850                 if (reg & AXP2XX_IRQ1_VBUS_DISCONN)
  851                         devctl_notify("PMU", "USB", "unplugged", NULL);
  852                 axp2xx_write(sc->dev, AXP2XX_IRQ1_STATUS, AXP2XX_IRQ_ACK);
  853         }
  854 
  855         axp2xx_read(sc->dev, AXP2XX_IRQ2_STATUS, &reg, 1);
  856         if (reg) {
  857                 if (reg & AXP2XX_IRQ2_BATT_CHARGED)
  858                         devctl_notify("PMU", "Battery", "charged", NULL);
  859                 if (reg & AXP2XX_IRQ2_BATT_CHARGING)
  860                         devctl_notify("PMU", "Battery", "charging", NULL);
  861                 if (reg & AXP2XX_IRQ2_BATT_CONN)
  862                         devctl_notify("PMU", "Battery", "connected", NULL);
  863                 if (reg & AXP2XX_IRQ2_BATT_DISCONN)
  864                         devctl_notify("PMU", "Battery", "disconnected", NULL);
  865                 if (reg & AXP2XX_IRQ2_BATT_TEMP_LOW)
  866                         devctl_notify("PMU", "Battery", "low-temp", NULL);
  867                 if (reg & AXP2XX_IRQ2_BATT_TEMP_OVER)
  868                         devctl_notify("PMU", "Battery", "high-temp", NULL);
  869                 axp2xx_write(sc->dev, AXP2XX_IRQ2_STATUS, AXP2XX_IRQ_ACK);
  870         }
  871 
  872         axp2xx_read(sc->dev, AXP2XX_IRQ3_STATUS, &reg, 1);
  873         if (reg) {
  874                 if (reg & AXP2XX_IRQ3_PEK_SHORT)
  875                         shutdown_nice(RB_POWEROFF);
  876                 axp2xx_write(sc->dev, AXP2XX_IRQ3_STATUS, AXP2XX_IRQ_ACK);
  877         }
  878 
  879         axp2xx_read(sc->dev, AXP2XX_IRQ4_STATUS, &reg, 1);
  880         if (reg) {
  881                 axp2xx_write(sc->dev, AXP2XX_IRQ4_STATUS, AXP2XX_IRQ_ACK);
  882         }
  883 
  884         axp2xx_read(sc->dev, AXP2XX_IRQ5_STATUS, &reg, 1);
  885         if (reg) {
  886                 axp2xx_write(sc->dev, AXP2XX_IRQ5_STATUS, AXP2XX_IRQ_ACK);
  887         }
  888 }
  889 
  890 static device_t
  891 axp2xx_gpio_get_bus(device_t dev)
  892 {
  893         struct axp2xx_softc *sc;
  894 
  895         sc = device_get_softc(dev);
  896 
  897         return (sc->gpiodev);
  898 }
  899 
  900 static int
  901 axp2xx_gpio_pin_max(device_t dev, int *maxpin)
  902 {
  903         struct axp2xx_softc *sc;
  904 
  905         sc = device_get_softc(dev);
  906 
  907         *maxpin = sc->npins - 1;
  908 
  909         return (0);
  910 }
  911 
  912 static int
  913 axp2xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
  914 {
  915         struct axp2xx_softc *sc;
  916 
  917         sc = device_get_softc(dev);
  918 
  919         if (pin >= sc->npins)
  920                 return (EINVAL);
  921 
  922         snprintf(name, GPIOMAXNAME, "%s", axp209_pins[pin].name);
  923 
  924         return (0);
  925 }
  926 
  927 static int
  928 axp2xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
  929 {
  930         struct axp2xx_softc *sc;
  931 
  932         sc = device_get_softc(dev);
  933 
  934         if (pin >= sc->npins)
  935                 return (EINVAL);
  936 
  937         *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
  938 
  939         return (0);
  940 }
  941 
  942 static int
  943 axp2xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
  944 {
  945         struct axp2xx_softc *sc;
  946         uint8_t data, func;
  947         int error;
  948 
  949         sc = device_get_softc(dev);
  950 
  951         if (pin >= sc->npins)
  952                 return (EINVAL);
  953 
  954         AXP_LOCK(sc);
  955         error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
  956         if (error == 0) {
  957                 func = data & AXP2XX_GPIO_FUNC_MASK;
  958                 if (func == AXP2XX_GPIO_FUNC_INPUT)
  959                         *flags = GPIO_PIN_INPUT;
  960                 else if (func == AXP2XX_GPIO_FUNC_DRVLO ||
  961                     func == AXP2XX_GPIO_FUNC_DRVHI)
  962                         *flags = GPIO_PIN_OUTPUT;
  963                 else
  964                         *flags = 0;
  965         }
  966         AXP_UNLOCK(sc);
  967 
  968         return (error);
  969 }
  970 
  971 static int
  972 axp2xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
  973 {
  974         struct axp2xx_softc *sc;
  975         uint8_t data;
  976         int error;
  977 
  978         sc = device_get_softc(dev);
  979 
  980         if (pin >= sc->npins)
  981                 return (EINVAL);
  982 
  983         AXP_LOCK(sc);
  984         error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
  985         if (error == 0) {
  986                 data &= ~AXP2XX_GPIO_FUNC_MASK;
  987                 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) {
  988                         if ((flags & GPIO_PIN_OUTPUT) == 0)
  989                                 data |= AXP2XX_GPIO_FUNC_INPUT;
  990                 }
  991                 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
  992         }
  993         AXP_UNLOCK(sc);
  994 
  995         return (error);
  996 }
  997 
  998 static int
  999 axp2xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
 1000 {
 1001         struct axp2xx_softc *sc;
 1002         uint8_t data, func;
 1003         int error;
 1004 
 1005         sc = device_get_softc(dev);
 1006 
 1007         if (pin >= sc->npins)
 1008                 return (EINVAL);
 1009 
 1010         AXP_LOCK(sc);
 1011         error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
 1012         if (error == 0) {
 1013                 func = data & AXP2XX_GPIO_FUNC_MASK;
 1014                 switch (func) {
 1015                 case AXP2XX_GPIO_FUNC_DRVLO:
 1016                         *val = 0;
 1017                         break;
 1018                 case AXP2XX_GPIO_FUNC_DRVHI:
 1019                         *val = 1;
 1020                         break;
 1021                 case AXP2XX_GPIO_FUNC_INPUT:
 1022                         error = axp2xx_read(dev, sc->pins[pin].status_reg,
 1023                             &data, 1);
 1024                         if (error == 0) {
 1025                                 *val = (data & sc->pins[pin].status_mask);
 1026                                 *val >>= sc->pins[pin].status_shift;
 1027                         }
 1028                         break;
 1029                 default:
 1030                         error = EIO;
 1031                         break;
 1032                 }
 1033         }
 1034         AXP_UNLOCK(sc);
 1035 
 1036         return (error);
 1037 }
 1038 
 1039 static int
 1040 axp2xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
 1041 {
 1042         struct axp2xx_softc *sc;
 1043         uint8_t data, func;
 1044         int error;
 1045 
 1046         sc = device_get_softc(dev);
 1047 
 1048         if (pin >= sc->npins)
 1049                 return (EINVAL);
 1050 
 1051         AXP_LOCK(sc);
 1052         error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
 1053         if (error == 0) {
 1054                 func = data & AXP2XX_GPIO_FUNC_MASK;
 1055                 switch (func) {
 1056                 case AXP2XX_GPIO_FUNC_DRVLO:
 1057                 case AXP2XX_GPIO_FUNC_DRVHI:
 1058                         /* GPIO2 can't be set to 1 */
 1059                         if (pin == 2 && val == 1) {
 1060                                 error = EINVAL;
 1061                                 break;
 1062                         }
 1063                         data &= ~AXP2XX_GPIO_FUNC_MASK;
 1064                         data |= val;
 1065                         break;
 1066                 default:
 1067                         error = EIO;
 1068                         break;
 1069                 }
 1070         }
 1071         if (error == 0)
 1072                 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
 1073         AXP_UNLOCK(sc);
 1074 
 1075         return (error);
 1076 }
 1077 
 1078 static int
 1079 axp2xx_gpio_pin_toggle(device_t dev, uint32_t pin)
 1080 {
 1081         struct axp2xx_softc *sc;
 1082         uint8_t data, func;
 1083         int error;
 1084 
 1085         sc = device_get_softc(dev);
 1086 
 1087         if (pin >= sc->npins)
 1088                 return (EINVAL);
 1089 
 1090         AXP_LOCK(sc);
 1091         error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
 1092         if (error == 0) {
 1093                 func = data & AXP2XX_GPIO_FUNC_MASK;
 1094                 switch (func) {
 1095                 case AXP2XX_GPIO_FUNC_DRVLO:
 1096                         /* Pin 2 can't be set to 1*/
 1097                         if (pin == 2) {
 1098                                 error = EINVAL;
 1099                                 break;
 1100                         }
 1101                         data &= ~AXP2XX_GPIO_FUNC_MASK;
 1102                         data |= AXP2XX_GPIO_FUNC_DRVHI;
 1103                         break;
 1104                 case AXP2XX_GPIO_FUNC_DRVHI:
 1105                         data &= ~AXP2XX_GPIO_FUNC_MASK;
 1106                         data |= AXP2XX_GPIO_FUNC_DRVLO;
 1107                         break;
 1108                 default:
 1109                         error = EIO;
 1110                         break;
 1111                 }
 1112         }
 1113         if (error == 0)
 1114                 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
 1115         AXP_UNLOCK(sc);
 1116 
 1117         return (error);
 1118 }
 1119 
 1120 static int
 1121 axp2xx_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent,
 1122     int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
 1123 {
 1124         struct axp2xx_softc *sc;
 1125 
 1126         sc = device_get_softc(bus);
 1127 
 1128         if (gpios[0] >= sc->npins)
 1129                 return (EINVAL);
 1130 
 1131         *pin = gpios[0];
 1132         *flags = gpios[1];
 1133 
 1134         return (0);
 1135 }
 1136 
 1137 static phandle_t
 1138 axp2xx_get_node(device_t dev, device_t bus)
 1139 {
 1140         return (ofw_bus_get_node(dev));
 1141 }
 1142 
 1143 static struct axp2xx_reg_sc *
 1144 axp2xx_reg_attach(device_t dev, phandle_t node,
 1145     struct axp2xx_regdef *def)
 1146 {
 1147         struct axp2xx_reg_sc *reg_sc;
 1148         struct regnode_init_def initdef;
 1149         struct regnode *regnode;
 1150 
 1151         memset(&initdef, 0, sizeof(initdef));
 1152         if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
 1153                 device_printf(dev, "cannot create regulator\n");
 1154                 return (NULL);
 1155         }
 1156         if (initdef.std_param.min_uvolt == 0)
 1157                 initdef.std_param.min_uvolt = def->voltage_min * 1000;
 1158         if (initdef.std_param.max_uvolt == 0)
 1159                 initdef.std_param.max_uvolt = def->voltage_max * 1000;
 1160         initdef.id = def->id;
 1161         initdef.ofw_node = node;
 1162         regnode = regnode_create(dev, &axp2xx_regnode_class, &initdef);
 1163         if (regnode == NULL) {
 1164                 device_printf(dev, "cannot create regulator\n");
 1165                 return (NULL);
 1166         }
 1167 
 1168         reg_sc = regnode_get_softc(regnode);
 1169         reg_sc->regnode = regnode;
 1170         reg_sc->base_dev = dev;
 1171         reg_sc->def = def;
 1172         reg_sc->xref = OF_xref_from_node(node);
 1173         reg_sc->param = regnode_get_stdparam(regnode);
 1174 
 1175         regnode_register(regnode);
 1176 
 1177         return (reg_sc);
 1178 }
 1179 
 1180 static int
 1181 axp2xx_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells,
 1182     intptr_t *num)
 1183 {
 1184         struct axp2xx_softc *sc;
 1185         int i;
 1186 
 1187         sc = device_get_softc(dev);
 1188         for (i = 0; i < sc->nregs; i++) {
 1189                 if (sc->regs[i] == NULL)
 1190                         continue;
 1191                 if (sc->regs[i]->xref == xref) {
 1192                         *num = sc->regs[i]->def->id;
 1193                         return (0);
 1194                 }
 1195         }
 1196 
 1197         return (ENXIO);
 1198 }
 1199 
 1200 static void
 1201 axp2xx_start(void *pdev)
 1202 {
 1203         device_t dev;
 1204         struct axp2xx_softc *sc;
 1205         const char *pwr_name[] = {"Battery", "AC", "USB", "AC and USB"};
 1206         int i;
 1207         uint8_t reg, data;
 1208         uint8_t pwr_src;
 1209 
 1210         dev = pdev;
 1211 
 1212         sc = device_get_softc(dev);
 1213         sc->dev = dev;
 1214 
 1215         if (bootverbose) {
 1216                 /*
 1217                  * Read the Power State register.
 1218                  * Shift the AC presence into bit 0.
 1219                  * Shift the Battery presence into bit 1.
 1220                  */
 1221                 axp2xx_read(dev, AXP2XX_PSR, &data, 1);
 1222                 pwr_src = ((data & AXP2XX_PSR_ACIN) >> AXP2XX_PSR_ACIN_SHIFT) |
 1223                     ((data & AXP2XX_PSR_VBUS) >> (AXP2XX_PSR_VBUS_SHIFT - 1));
 1224 
 1225                 device_printf(dev, "Powered by %s\n",
 1226                     pwr_name[pwr_src]);
 1227         }
 1228 
 1229         /* Only enable interrupts that we are interested in */
 1230         axp2xx_write(dev, AXP2XX_IRQ1_ENABLE,
 1231             AXP2XX_IRQ1_AC_OVERVOLT |
 1232             AXP2XX_IRQ1_AC_DISCONN |
 1233             AXP2XX_IRQ1_AC_CONN |
 1234             AXP2XX_IRQ1_VBUS_OVERVOLT |
 1235             AXP2XX_IRQ1_VBUS_DISCONN |
 1236             AXP2XX_IRQ1_VBUS_CONN);
 1237         axp2xx_write(dev, AXP2XX_IRQ2_ENABLE,
 1238             AXP2XX_IRQ2_BATT_CONN |
 1239             AXP2XX_IRQ2_BATT_DISCONN |
 1240             AXP2XX_IRQ2_BATT_CHARGE_ACCT_ON |
 1241             AXP2XX_IRQ2_BATT_CHARGE_ACCT_OFF |
 1242             AXP2XX_IRQ2_BATT_CHARGING |
 1243             AXP2XX_IRQ2_BATT_CHARGED |
 1244             AXP2XX_IRQ2_BATT_TEMP_OVER |
 1245             AXP2XX_IRQ2_BATT_TEMP_LOW);
 1246         axp2xx_write(dev, AXP2XX_IRQ3_ENABLE,
 1247             AXP2XX_IRQ3_PEK_SHORT | AXP2XX_IRQ3_PEK_LONG);
 1248         axp2xx_write(dev, AXP2XX_IRQ4_ENABLE, AXP2XX_IRQ4_APS_LOW_2);
 1249         axp2xx_write(dev, AXP2XX_IRQ5_ENABLE, 0x0);
 1250 
 1251         EVENTHANDLER_REGISTER(shutdown_final, axp2xx_shutdown, dev,
 1252             SHUTDOWN_PRI_LAST);
 1253 
 1254         /* Enable ADC sensors */
 1255         for (i = 0; i < sc->nsensors; i++) {
 1256                 if (axp2xx_read(dev, sc->sensors[i].enable_reg, &reg, 1) == -1) {
 1257                         device_printf(dev, "Cannot enable sensor '%s'\n",
 1258                             sc->sensors[i].name);
 1259                         continue;
 1260                 }
 1261                 reg |= sc->sensors[i].enable_mask;
 1262                 if (axp2xx_write(dev, sc->sensors[i].enable_reg, reg) == -1) {
 1263                         device_printf(dev, "Cannot enable sensor '%s'\n",
 1264                             sc->sensors[i].name);
 1265                         continue;
 1266                 }
 1267                 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
 1268                     SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
 1269                     OID_AUTO, sc->sensors[i].name,
 1270                     CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
 1271                     dev, sc->sensors[i].id, axp2xx_sysctl,
 1272                     sc->sensors[i].format,
 1273                     sc->sensors[i].desc);
 1274         }
 1275 
 1276         if ((bus_setup_intr(dev, sc->res[0], INTR_TYPE_MISC | INTR_MPSAFE,
 1277               NULL, axp2xx_intr, sc, &sc->intrcookie)))
 1278                 device_printf(dev, "unable to register interrupt handler\n");
 1279 
 1280         config_intrhook_disestablish(&sc->intr_hook);
 1281 }
 1282 
 1283 static int
 1284 axp2xx_probe(device_t dev)
 1285 {
 1286 
 1287         if (!ofw_bus_status_okay(dev))
 1288                 return (ENXIO);
 1289 
 1290         switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data)
 1291         {
 1292         case AXP209:
 1293                 device_set_desc(dev, "X-Powers AXP209 Power Management Unit");
 1294                 break;
 1295         case AXP221:
 1296                 device_set_desc(dev, "X-Powers AXP221 Power Management Unit");
 1297                 break;
 1298         default:
 1299                 return (ENXIO);
 1300         }
 1301 
 1302         return (BUS_PROBE_DEFAULT);
 1303 }
 1304 
 1305 static int
 1306 axp2xx_attach(device_t dev)
 1307 {
 1308         struct axp2xx_softc *sc;
 1309         struct axp2xx_reg_sc *reg;
 1310         struct axp2xx_regdef *regdefs;
 1311         phandle_t rnode, child;
 1312         int i;
 1313 
 1314         sc = device_get_softc(dev);
 1315         mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
 1316 
 1317         if (bus_alloc_resources(dev, axp_res_spec, sc->res) != 0) {
 1318                 device_printf(dev, "can't allocate device resources\n");
 1319                 return (ENXIO);
 1320         }
 1321 
 1322         sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
 1323         switch (sc->type) {
 1324         case AXP209:
 1325                 sc->pins = axp209_pins;
 1326                 sc->npins = nitems(axp209_pins);
 1327                 sc->gpiodev = gpiobus_attach_bus(dev);
 1328 
 1329                 sc->sensors = axp209_sensors;
 1330                 sc->nsensors = nitems(axp209_sensors);
 1331 
 1332                 regdefs = axp209_regdefs;
 1333                 sc->nregs = nitems(axp209_regdefs);
 1334                 break;
 1335         case AXP221:
 1336                 sc->pins = axp221_pins;
 1337                 sc->npins = nitems(axp221_pins);
 1338                 sc->gpiodev = gpiobus_attach_bus(dev);
 1339 
 1340                 sc->sensors = axp221_sensors;
 1341                 sc->nsensors = nitems(axp221_sensors);
 1342 
 1343                 regdefs = axp221_regdefs;
 1344                 sc->nregs = nitems(axp221_regdefs);
 1345                 break;
 1346         }
 1347 
 1348         sc->regs = malloc(sizeof(struct axp2xx_reg_sc *) * sc->nregs,
 1349             M_AXP2XX_REG, M_WAITOK | M_ZERO);
 1350 
 1351         sc->intr_hook.ich_func = axp2xx_start;
 1352         sc->intr_hook.ich_arg = dev;
 1353 
 1354         if (config_intrhook_establish(&sc->intr_hook) != 0)
 1355                 return (ENOMEM);
 1356 
 1357         /* Attach known regulators that exist in the DT */
 1358         rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
 1359         if (rnode > 0) {
 1360                 for (i = 0; i < sc->nregs; i++) {
 1361                         child = ofw_bus_find_child(rnode,
 1362                             regdefs[i].name);
 1363                         if (child == 0)
 1364                                 continue;
 1365                         reg = axp2xx_reg_attach(dev, child, &regdefs[i]);
 1366                         if (reg == NULL) {
 1367                                 device_printf(dev,
 1368                                     "cannot attach regulator %s\n",
 1369                                     regdefs[i].name);
 1370                                 continue;
 1371                         }
 1372                         sc->regs[i] = reg;
 1373                         if (bootverbose)
 1374                                 device_printf(dev, "Regulator %s attached\n",
 1375                                     regdefs[i].name);
 1376                 }
 1377         }
 1378 
 1379         return (0);
 1380 }
 1381 
 1382 static device_method_t axp2xx_methods[] = {
 1383         DEVMETHOD(device_probe,         axp2xx_probe),
 1384         DEVMETHOD(device_attach,        axp2xx_attach),
 1385 
 1386         /* GPIO interface */
 1387         DEVMETHOD(gpio_get_bus,         axp2xx_gpio_get_bus),
 1388         DEVMETHOD(gpio_pin_max,         axp2xx_gpio_pin_max),
 1389         DEVMETHOD(gpio_pin_getname,     axp2xx_gpio_pin_getname),
 1390         DEVMETHOD(gpio_pin_getcaps,     axp2xx_gpio_pin_getcaps),
 1391         DEVMETHOD(gpio_pin_getflags,    axp2xx_gpio_pin_getflags),
 1392         DEVMETHOD(gpio_pin_setflags,    axp2xx_gpio_pin_setflags),
 1393         DEVMETHOD(gpio_pin_get,         axp2xx_gpio_pin_get),
 1394         DEVMETHOD(gpio_pin_set,         axp2xx_gpio_pin_set),
 1395         DEVMETHOD(gpio_pin_toggle,      axp2xx_gpio_pin_toggle),
 1396         DEVMETHOD(gpio_map_gpios,       axp2xx_gpio_map_gpios),
 1397 
 1398         /* Regdev interface */
 1399         DEVMETHOD(regdev_map,           axp2xx_regdev_map),
 1400 
 1401         /* OFW bus interface */
 1402         DEVMETHOD(ofw_bus_get_node,     axp2xx_get_node),
 1403 
 1404         DEVMETHOD_END
 1405 };
 1406 
 1407 static driver_t axp2xx_driver = {
 1408         "axp2xx_pmu",
 1409         axp2xx_methods,
 1410         sizeof(struct axp2xx_softc),
 1411 };
 1412 
 1413 static devclass_t axp2xx_devclass;
 1414 extern devclass_t ofwgpiobus_devclass, gpioc_devclass;
 1415 extern driver_t ofw_gpiobus_driver, gpioc_driver;
 1416 
 1417 EARLY_DRIVER_MODULE(axp2xx, iicbus, axp2xx_driver, axp2xx_devclass,
 1418   0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
 1419 EARLY_DRIVER_MODULE(ofw_gpiobus, axp2xx_pmu, ofw_gpiobus_driver,
 1420     ofwgpiobus_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
 1421 DRIVER_MODULE(gpioc, axp2xx_pmu, gpioc_driver, gpioc_devclass,
 1422     0, 0);
 1423 MODULE_VERSION(axp2xx, 1);
 1424 MODULE_DEPEND(axp2xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);

Cache object: 5a1e65d5408710af8fe85aaf5770cbd2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.