Home | History | Annotate | Line # | Download | only in i2c
      1  1.21   thorpej /*	$NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej Exp $ */
      2   1.1   rkujawa 
      3   1.1   rkujawa /*-
      4   1.1   rkujawa  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5   1.1   rkujawa  * All rights reserved.
      6   1.1   rkujawa  *
      7   1.1   rkujawa  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1   rkujawa  * by Radoslaw Kujawa.
      9   1.1   rkujawa  *
     10   1.1   rkujawa  * Redistribution and use in source and binary forms, with or without
     11   1.1   rkujawa  * modification, are permitted provided that the following conditions
     12   1.1   rkujawa  * are met:
     13   1.1   rkujawa  * 1. Redistributions of source code must retain the above copyright
     14   1.1   rkujawa  *    notice, this list of conditions and the following disclaimer.
     15   1.1   rkujawa  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1   rkujawa  *    notice, this list of conditions and the following disclaimer in the
     17   1.1   rkujawa  *    documentation and/or other materials provided with the distribution.
     18   1.1   rkujawa  *
     19   1.1   rkujawa  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1   rkujawa  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1   rkujawa  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1   rkujawa  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1   rkujawa  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1   rkujawa  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1   rkujawa  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1   rkujawa  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1   rkujawa  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1   rkujawa  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1   rkujawa  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1   rkujawa  */
     31   1.1   rkujawa 
     32   1.4  jakllsch /*
     33   1.4  jakllsch  * Texas Instruments TPS65217 Power Management IC driver.
     34   1.3   rkujawa  * TODO: battery, sequencer, pgood
     35   1.2   rkujawa  */
     36   1.2   rkujawa 
     37  1.13  jmcneill #include "opt_fdt.h"
     38  1.13  jmcneill 
     39   1.1   rkujawa #include <sys/cdefs.h>
     40  1.21   thorpej __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej Exp $");
     41   1.1   rkujawa 
     42   1.1   rkujawa #include <sys/param.h>
     43   1.1   rkujawa #include <sys/systm.h>
     44   1.1   rkujawa #include <sys/device.h>
     45   1.1   rkujawa #include <sys/kernel.h>
     46   1.3   rkujawa #include <sys/mutex.h>
     47   1.1   rkujawa 
     48   1.1   rkujawa #include <sys/bus.h>
     49   1.1   rkujawa #include <dev/i2c/i2cvar.h>
     50   1.1   rkujawa 
     51   1.3   rkujawa #include <dev/sysmon/sysmonvar.h>
     52  1.14  jmcneill #include <dev/sysmon/sysmon_taskq.h>
     53   1.3   rkujawa 
     54   1.1   rkujawa #include <dev/i2c/tps65217pmicreg.h>
     55  1.10    bouyer #include <dev/i2c/tps65217pmicvar.h>
     56   1.1   rkujawa 
     57  1.13  jmcneill #ifdef FDT
     58  1.13  jmcneill #include <dev/fdt/fdtvar.h>
     59  1.13  jmcneill #endif
     60  1.13  jmcneill 
     61   1.3   rkujawa #define NTPS_REG	7
     62   1.9  jakllsch #define SNUM_REGS	NTPS_REG-1
     63   1.6   rkujawa #define SNUM_USBSTATUS	NTPS_REG
     64   1.6   rkujawa #define SNUM_ACSTATUS	NTPS_REG+1
     65   1.3   rkujawa 
     66  1.13  jmcneill struct tps_reg_param;
     67  1.13  jmcneill 
     68   1.1   rkujawa struct tps65217pmic_softc {
     69   1.3   rkujawa 	device_t		sc_dev;
     70   1.3   rkujawa 
     71   1.3   rkujawa 	i2c_tag_t		sc_tag;
     72   1.3   rkujawa 	i2c_addr_t		sc_addr;
     73  1.13  jmcneill 	int			sc_phandle;
     74   1.1   rkujawa 
     75   1.3   rkujawa 	uint8_t			sc_version;
     76   1.3   rkujawa 	uint8_t			sc_revision;
     77   1.1   rkujawa 
     78   1.6   rkujawa 	kmutex_t		sc_lock;
     79   1.6   rkujawa 
     80   1.6   rkujawa 	bool			sc_acstatus;
     81   1.6   rkujawa 	bool			sc_usbstatus;
     82   1.6   rkujawa 	bool			sc_acenabled;
     83   1.6   rkujawa 	bool			sc_usbenabled;
     84   1.6   rkujawa 
     85   1.6   rkujawa 	callout_t		sc_powerpollco;
     86   1.6   rkujawa 
     87   1.6   rkujawa 	/* sysmon(4) stuff */
     88   1.3   rkujawa 	struct sysmon_envsys	*sc_sme;
     89   1.6   rkujawa 	envsys_data_t		sc_regsensor[NTPS_REG];
     90   1.6   rkujawa 	envsys_data_t		sc_acsensor;
     91   1.6   rkujawa 	envsys_data_t		sc_usbsensor;
     92   1.6   rkujawa 
     93   1.6   rkujawa 	struct sysmon_pswitch	sc_smpsw;
     94   1.1   rkujawa };
     95   1.1   rkujawa 
     96  1.13  jmcneill struct tps65217reg_softc {
     97  1.13  jmcneill 	device_t		sc_dev;
     98  1.13  jmcneill 	int			sc_phandle;
     99  1.13  jmcneill 	struct tps_reg_param	*sc_param;
    100  1.13  jmcneill };
    101  1.13  jmcneill 
    102  1.13  jmcneill struct tps65217reg_attach_args {
    103  1.13  jmcneill 	struct tps_reg_param	*reg_param;
    104  1.13  jmcneill 	int			reg_phandle;
    105  1.13  jmcneill };
    106  1.13  jmcneill 
    107   1.2   rkujawa /* Voltage regulators */
    108   1.2   rkujawa enum tps_reg_num {
    109   1.2   rkujawa 	TPS65217PMIC_LDO1,
    110   1.2   rkujawa 	TPS65217PMIC_LDO2,
    111   1.2   rkujawa 	TPS65217PMIC_LDO3LS,
    112   1.2   rkujawa 	TPS65217PMIC_LDO4LS,
    113   1.2   rkujawa 	TPS65217PMIC_DCDC1,
    114   1.2   rkujawa 	TPS65217PMIC_DCDC2,
    115   1.2   rkujawa 	TPS65217PMIC_DCDC3
    116   1.4  jakllsch };
    117   1.2   rkujawa 
    118   1.2   rkujawa struct tps_reg_param {
    119   1.2   rkujawa 	/* parameters configured statically */
    120   1.2   rkujawa 
    121   1.2   rkujawa 	const char* name;
    122   1.2   rkujawa 	uint16_t voltage_min;		/* in mV */
    123   1.2   rkujawa 	uint16_t voltage_max;		/* in mV */
    124   1.2   rkujawa 	const uint16_t *voltages;	/* all possible voltage settings */
    125   1.2   rkujawa 	uint8_t nvoltages;		/* number of voltage settings */
    126   1.2   rkujawa 
    127   1.2   rkujawa 	bool can_track;			/* regulator can track U of other r. */
    128   1.2   rkujawa 	struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
    129   1.2   rkujawa 	bool can_xadj;			/* voltage can be adjusted externally */
    130   1.2   rkujawa 	bool can_ls;			/* can be a load switch instead of r. */
    131   1.2   rkujawa 
    132   1.2   rkujawa 	uint8_t defreg_num;		/* DEF register */
    133   1.2   rkujawa 	uint8_t enable_bit;		/* position in ENABLE register */
    134   1.4  jakllsch 
    135   1.2   rkujawa 	/*
    136   1.2   rkujawa 	 * Run-time parameters configured during attachment and later, these
    137   1.2   rkujawa 	 * probably should be split into separate struct that would be a part
    138   1.2   rkujawa 	 * of softc. But since we can have only one TPS chip, that should be
    139   1.2   rkujawa 	 * okay for now.
    140   1.2   rkujawa 	 */
    141   1.2   rkujawa 
    142   1.2   rkujawa 	bool is_enabled;		/* regulator is enabled */
    143   1.2   rkujawa 	bool is_pg;			/* regulator is "power good" */
    144   1.2   rkujawa 	bool is_tracking;		/* voltage is tracking other reg. */
    145   1.2   rkujawa 	bool is_ls;			/* is a load switch */
    146   1.2   rkujawa 	bool is_xadj;			/* voltage is adjusted externally */
    147   1.2   rkujawa 
    148   1.2   rkujawa 	uint16_t current_voltage;	/* in mV */
    149   1.2   rkujawa };
    150   1.2   rkujawa 
    151   1.1   rkujawa static int tps65217pmic_match(device_t, cfdata_t, void *);
    152   1.1   rkujawa static void tps65217pmic_attach(device_t, device_t, void *);
    153   1.1   rkujawa 
    154  1.15   thorpej static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *);
    155  1.15   thorpej static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *);
    156  1.15   thorpej 
    157   1.3   rkujawa static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
    158   1.8  jakllsch static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
    159   1.8  jakllsch     uint8_t);
    160   1.3   rkujawa 
    161   1.6   rkujawa static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
    162   1.2   rkujawa 
    163   1.3   rkujawa static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
    164   1.3   rkujawa static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
    165   1.1   rkujawa 
    166   1.3   rkujawa static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
    167   1.3   rkujawa     struct tps_reg_param *);
    168   1.1   rkujawa 
    169   1.3   rkujawa static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
    170   1.3   rkujawa static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
    171   1.2   rkujawa 
    172   1.3   rkujawa static void tps65217pmic_version(struct tps65217pmic_softc *);
    173   1.2   rkujawa 
    174   1.3   rkujawa static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
    175   1.3   rkujawa static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
    176   1.1   rkujawa 
    177   1.6   rkujawa static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
    178   1.6   rkujawa static void tps65217pmic_power_monitor(void *);
    179   1.6   rkujawa 
    180  1.11  kiyohara static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
    181  1.11  kiyohara 
    182   1.1   rkujawa CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
    183   1.1   rkujawa     tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
    184   1.1   rkujawa 
    185  1.13  jmcneill #ifdef FDT
    186  1.13  jmcneill static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
    187  1.13  jmcneill #endif
    188  1.13  jmcneill 
    189   1.1   rkujawa /* Possible settings of LDO1 in mV. */
    190   1.4  jakllsch static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
    191   1.1   rkujawa     1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
    192   1.1   rkujawa /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
    193   1.4  jakllsch static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
    194   1.4  jakllsch     1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
    195   1.4  jakllsch     1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
    196   1.4  jakllsch     1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
    197   1.4  jakllsch     2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
    198   1.1   rkujawa     3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
    199   1.1   rkujawa /* Possible settings of LDO3, LDO4 in mV. */
    200   1.4  jakllsch static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
    201   1.4  jakllsch     1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
    202   1.4  jakllsch     2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
    203   1.1   rkujawa     3250, 3300 };
    204   1.1   rkujawa 
    205   1.2   rkujawa static struct tps_reg_param tps_regulators[] = {
    206   1.4  jakllsch 	{
    207  1.13  jmcneill 		.name = "ldo1",
    208   1.4  jakllsch 		.voltage_min = 1000,
    209   1.4  jakllsch 		.voltage_max = 3300,
    210   1.2   rkujawa 		.voltages = ldo1voltages,
    211   1.2   rkujawa 		.nvoltages = 16,
    212   1.2   rkujawa 		.can_track = false,
    213   1.2   rkujawa 		.tracked_reg = NULL,
    214   1.2   rkujawa 		.can_xadj =  false,
    215   1.2   rkujawa 		.can_ls = false,
    216   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFLDO1,
    217   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_LDO1
    218   1.2   rkujawa 	},
    219   1.4  jakllsch 	{
    220  1.13  jmcneill 		.name = "ldo2",
    221   1.4  jakllsch 		.voltage_min = 900,
    222   1.2   rkujawa 		.voltage_max = 3300,
    223   1.2   rkujawa 		.voltages = ldo2voltages,
    224   1.2   rkujawa 		.nvoltages = 64,
    225   1.2   rkujawa 		.can_track = true,
    226   1.4  jakllsch 		.tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
    227   1.2   rkujawa 		.can_xadj = false,
    228   1.2   rkujawa 		.can_ls = false,
    229   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFLDO2,
    230   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_LDO2
    231   1.2   rkujawa 	},
    232   1.4  jakllsch 	{
    233  1.13  jmcneill 		.name = "ldo3",
    234   1.4  jakllsch 		.voltage_min = 1500,
    235   1.2   rkujawa 		.voltage_max = 3300,
    236   1.2   rkujawa 		.voltages = ldo3voltages,
    237   1.2   rkujawa 		.nvoltages = 32,
    238   1.2   rkujawa 		.can_track = false,
    239   1.4  jakllsch 		.tracked_reg = NULL,
    240   1.2   rkujawa 		.can_xadj = false,
    241   1.2   rkujawa 		.can_ls = true,
    242   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFLDO3,
    243   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_LDO3
    244   1.2   rkujawa 	},
    245   1.4  jakllsch 	{
    246  1.13  jmcneill 		.name = "ldo4",
    247   1.4  jakllsch 		.voltage_min = 1500,
    248   1.2   rkujawa 		.voltage_max = 3300,
    249   1.2   rkujawa 		.voltages = ldo3voltages,
    250   1.2   rkujawa 		.nvoltages = 32,
    251   1.2   rkujawa 		.can_track = false,
    252   1.4  jakllsch 		.tracked_reg = NULL,
    253   1.2   rkujawa 		.can_xadj = false,
    254   1.2   rkujawa 		.can_ls = true,
    255   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFLDO4,
    256   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_LDO4
    257   1.2   rkujawa 	},
    258   1.4  jakllsch 	{
    259  1.13  jmcneill 		.name = "dcdc1",
    260   1.4  jakllsch 		.voltage_min = 900,
    261   1.2   rkujawa 		.voltage_max = 3300,
    262   1.2   rkujawa 		.voltages = ldo2voltages,
    263   1.2   rkujawa 		.nvoltages = 64,
    264   1.2   rkujawa 		.can_track = false,
    265   1.4  jakllsch 		.tracked_reg = NULL,
    266   1.2   rkujawa 		.can_xadj = true,
    267   1.2   rkujawa 		.can_ls = false,
    268   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFDCDC1,
    269   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_DCDC1
    270   1.2   rkujawa 	},
    271   1.4  jakllsch 	{
    272  1.13  jmcneill 		.name = "dcdc2",
    273   1.4  jakllsch 		.voltage_min = 900,
    274   1.2   rkujawa 		.voltage_max = 3300,
    275   1.2   rkujawa 		.voltages = ldo2voltages,
    276   1.2   rkujawa 		.nvoltages = 64,
    277   1.2   rkujawa 		.can_track = false,
    278   1.4  jakllsch 		.tracked_reg = NULL,
    279   1.2   rkujawa 		.can_xadj = true,
    280   1.2   rkujawa 		.can_ls = false,
    281   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFDCDC2,
    282   1.4  jakllsch 		.enable_bit = TPS65217PMIC_ENABLE_DCDC2
    283   1.2   rkujawa 	},
    284   1.4  jakllsch 	{
    285  1.13  jmcneill 		.name = "dcdc3",
    286   1.4  jakllsch 		.voltage_min = 900,
    287   1.2   rkujawa 		.voltage_max = 3300,
    288   1.2   rkujawa 		.voltages = ldo2voltages,
    289   1.2   rkujawa 		.nvoltages = 64,
    290   1.2   rkujawa 		.can_track = false,
    291   1.4  jakllsch 		.tracked_reg = NULL,
    292   1.2   rkujawa 		.can_xadj = true,
    293   1.2   rkujawa 		.can_ls = false,
    294   1.2   rkujawa 		.defreg_num = TPS65217PMIC_DEFDCDC3,
    295   1.2   rkujawa 		.enable_bit = TPS65217PMIC_ENABLE_DCDC3
    296   1.2   rkujawa 	}
    297   1.2   rkujawa };
    298   1.2   rkujawa 
    299   1.2   rkujawa static bool matched = false;
    300   1.2   rkujawa 
    301  1.13  jmcneill static const struct device_compatible_entry compat_data[] = {
    302  1.16   thorpej 	{ .compat = "ti,tps65217" },
    303  1.18   thorpej 	DEVICE_COMPAT_EOL
    304  1.13  jmcneill };
    305  1.13  jmcneill 
    306   1.1   rkujawa static int
    307   1.1   rkujawa tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
    308   1.1   rkujawa {
    309   1.1   rkujawa 	struct i2c_attach_args *ia = aux;
    310  1.13  jmcneill 	int match_result;
    311  1.13  jmcneill 
    312  1.13  jmcneill 	if (iic_use_direct_match(ia, cf, compat_data, &match_result))
    313  1.13  jmcneill 		return match_result;
    314   1.1   rkujawa 
    315   1.2   rkujawa 	if (ia->ia_addr == TPS65217PMIC_ADDR) {
    316   1.2   rkujawa 		/* we can only have one */
    317   1.2   rkujawa 		if (matched)
    318   1.2   rkujawa 			return 0;
    319   1.2   rkujawa 
    320  1.12   thorpej 		return I2C_MATCH_ADDRESS_ONLY;
    321   1.2   rkujawa 	}
    322   1.1   rkujawa 	return 0;
    323   1.1   rkujawa }
    324   1.1   rkujawa 
    325   1.1   rkujawa static void
    326   1.1   rkujawa tps65217pmic_attach(device_t parent, device_t self, void *aux)
    327   1.1   rkujawa {
    328   1.1   rkujawa 	struct tps65217pmic_softc *sc = device_private(self);
    329   1.1   rkujawa 	struct i2c_attach_args *ia = aux;
    330  1.11  kiyohara 	prop_dictionary_t dict;
    331  1.11  kiyohara 	int isel, fdim, brightness;
    332   1.1   rkujawa 
    333  1.12   thorpej 	/* XXXJRT But what if you have multiple i2c busses? */
    334  1.12   thorpej 	matched = true;
    335  1.12   thorpej 
    336   1.1   rkujawa 	sc->sc_dev = self;
    337   1.1   rkujawa 	sc->sc_addr = ia->ia_addr;
    338   1.1   rkujawa 	sc->sc_tag = ia->ia_tag;
    339   1.1   rkujawa 
    340  1.21   thorpej #ifdef FDT
    341  1.21   thorpej 	if (devhandle_type(device_handle(self)) == DEVHANDLE_TYPE_OF) {
    342  1.21   thorpej 		sc->sc_phandle = devhandle_to_of(device_handle(self));
    343  1.21   thorpej 	}
    344  1.21   thorpej #endif
    345  1.21   thorpej 
    346  1.11  kiyohara 	dict = device_properties(self);
    347  1.11  kiyohara 	if (prop_dictionary_get_int32(dict, "isel", &isel)) {
    348  1.11  kiyohara 		prop_dictionary_get_int32(dict, "fdim", &fdim);
    349  1.11  kiyohara 		prop_dictionary_get_int32(dict, "brightness", &brightness);
    350  1.11  kiyohara 	} else
    351  1.11  kiyohara 		isel = -1;
    352  1.11  kiyohara 
    353   1.1   rkujawa 	tps65217pmic_version(sc);
    354   1.1   rkujawa 
    355   1.1   rkujawa 	aprint_normal(": TPS65217");
    356   1.1   rkujawa 	switch (sc->sc_version) {
    357   1.1   rkujawa 	case TPS65217PMIC_CHIPID_VER_A:
    358   1.1   rkujawa 		aprint_normal("A");
    359   1.1   rkujawa 		break;
    360   1.1   rkujawa 	case TPS65217PMIC_CHIPID_VER_B:
    361   1.1   rkujawa 		aprint_normal("B");
    362   1.1   rkujawa 		break;
    363   1.1   rkujawa 	case TPS65217PMIC_CHIPID_VER_C:
    364   1.1   rkujawa 		aprint_normal("C");
    365   1.1   rkujawa 		break;
    366   1.1   rkujawa 	case TPS65217PMIC_CHIPID_VER_D:
    367   1.1   rkujawa 		aprint_normal("D");
    368   1.1   rkujawa 		break;
    369   1.1   rkujawa 	default:
    370   1.1   rkujawa 		/* unknown version */
    371   1.1   rkujawa 		break;
    372   1.1   rkujawa 	}
    373   1.1   rkujawa 
    374   1.4  jakllsch 	aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
    375   1.1   rkujawa 	    sc->sc_revision);
    376   1.1   rkujawa 
    377   1.3   rkujawa 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    378   1.3   rkujawa 
    379   1.6   rkujawa 	sc->sc_smpsw.smpsw_name = device_xname(self);
    380   1.6   rkujawa 	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
    381   1.6   rkujawa 	sysmon_pswitch_register(&sc->sc_smpsw);
    382   1.6   rkujawa 
    383   1.6   rkujawa 	tps65217pmic_reg_refresh(sc);
    384   1.2   rkujawa 
    385   1.2   rkujawa 	tps65217pmic_print_ppath(sc);
    386   1.2   rkujawa 	tps65217pmic_print_ldos(sc);
    387   1.3   rkujawa 
    388   1.6   rkujawa 	tps65217pmic_power_monitor_init(sc);
    389   1.6   rkujawa 
    390  1.11  kiyohara 	if (isel != -1)
    391  1.11  kiyohara 		tps65217pmic_wled_init(sc, isel, fdim, brightness);
    392  1.11  kiyohara 
    393   1.3   rkujawa 	tps65217pmic_envsys_register(sc);
    394  1.13  jmcneill 
    395  1.13  jmcneill #ifdef FDT
    396  1.13  jmcneill 	tps65217pmic_regulator_attach(sc);
    397  1.13  jmcneill #endif
    398   1.2   rkujawa }
    399   1.2   rkujawa 
    400   1.2   rkujawa static void
    401   1.6   rkujawa tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
    402   1.6   rkujawa {
    403   1.6   rkujawa 	uint8_t intr, intrmask, status, ppath;
    404   1.6   rkujawa 
    405   1.9  jakllsch 	intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
    406   1.6   rkujawa 	    TPS65217PMIC_INT_PBM;
    407   1.6   rkujawa 
    408  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc) != 0) {
    409  1.15   thorpej 		aprint_error_dev(sc->sc_dev,
    410  1.15   thorpej 		    "failed to initialize power monitor\n");
    411  1.15   thorpej 		return;
    412  1.15   thorpej 	}
    413  1.15   thorpej 
    414   1.6   rkujawa 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    415   1.6   rkujawa 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    416   1.6   rkujawa 	/* acknowledge and disregard whatever interrupt was generated earlier */
    417   1.6   rkujawa 	intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
    418   1.6   rkujawa 
    419  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    420  1.15   thorpej 
    421   1.6   rkujawa 	sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    422   1.6   rkujawa 	sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    423   1.6   rkujawa 	sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
    424   1.6   rkujawa 	sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
    425   1.6   rkujawa 
    426   1.6   rkujawa 	if (intr & intrmask)
    427   1.9  jakllsch 		aprint_normal_dev(sc->sc_dev,
    428   1.6   rkujawa 		    "WARNING: hardware interrupt enabled but not supported");
    429   1.6   rkujawa 
    430   1.6   rkujawa 	/* set up callout to poll for power source changes */
    431   1.6   rkujawa 	callout_init(&sc->sc_powerpollco, 0);
    432   1.6   rkujawa 	callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
    433   1.6   rkujawa 
    434   1.6   rkujawa 	callout_schedule(&sc->sc_powerpollco, hz);
    435   1.6   rkujawa }
    436   1.6   rkujawa 
    437   1.6   rkujawa static void
    438  1.14  jmcneill tps65217pmic_power_monitor_task(void *aux)
    439   1.6   rkujawa {
    440   1.6   rkujawa 	struct tps65217pmic_softc *sc;
    441   1.6   rkujawa 	uint8_t status;
    442   1.6   rkujawa 	bool usbstatus, acstatus;
    443   1.6   rkujawa 
    444   1.6   rkujawa 	sc = aux;
    445   1.6   rkujawa 
    446   1.6   rkujawa 	mutex_enter(&sc->sc_lock);
    447   1.6   rkujawa 
    448  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc) != 0) {
    449  1.15   thorpej 		device_printf(sc->sc_dev,
    450  1.15   thorpej 		    "WARNING: unable to perform power monitor task.\n");
    451  1.15   thorpej 		return;
    452  1.15   thorpej 	}
    453   1.6   rkujawa 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    454  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    455  1.15   thorpej 
    456   1.6   rkujawa 	usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    457   1.6   rkujawa 	acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    458   1.6   rkujawa 
    459   1.6   rkujawa 	if (usbstatus != sc->sc_usbstatus) {
    460   1.6   rkujawa 		sc->sc_usbstatus = usbstatus;
    461   1.6   rkujawa 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    462   1.6   rkujawa 		if (usbstatus)
    463   1.9  jakllsch 			aprint_normal_dev(sc->sc_dev,
    464   1.6   rkujawa 			    "USB power source connected\n");
    465   1.6   rkujawa 		else
    466   1.9  jakllsch 			aprint_normal_dev(sc->sc_dev,
    467   1.6   rkujawa 			    "USB power source disconnected\n");
    468   1.6   rkujawa 	}
    469   1.6   rkujawa 
    470   1.6   rkujawa 	if (acstatus != sc->sc_acstatus) {
    471   1.6   rkujawa 		sc->sc_acstatus = acstatus;
    472   1.6   rkujawa 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    473   1.6   rkujawa 		if (acstatus) {
    474   1.9  jakllsch 			sysmon_pswitch_event(&sc->sc_smpsw,
    475   1.6   rkujawa 			    PSWITCH_EVENT_PRESSED);
    476   1.6   rkujawa 		} else {
    477   1.9  jakllsch 			sysmon_pswitch_event(&sc->sc_smpsw,
    478   1.6   rkujawa 			    PSWITCH_EVENT_RELEASED);
    479   1.6   rkujawa 		}
    480   1.6   rkujawa 	}
    481   1.6   rkujawa 
    482   1.6   rkujawa 	mutex_exit(&sc->sc_lock);
    483   1.6   rkujawa 
    484   1.6   rkujawa 	callout_schedule(&sc->sc_powerpollco, hz);
    485   1.6   rkujawa }
    486   1.6   rkujawa 
    487   1.6   rkujawa static void
    488  1.14  jmcneill tps65217pmic_power_monitor(void *aux)
    489  1.14  jmcneill {
    490  1.14  jmcneill 	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
    491  1.14  jmcneill }
    492  1.14  jmcneill 
    493  1.14  jmcneill static void
    494  1.11  kiyohara tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
    495  1.11  kiyohara 		       int brightness)
    496  1.11  kiyohara {
    497  1.11  kiyohara 	uint8_t val = 0;
    498  1.11  kiyohara 
    499  1.11  kiyohara 	switch (isel) {
    500  1.11  kiyohara 	case 1:
    501  1.11  kiyohara 	case 2:
    502  1.11  kiyohara 		val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
    503  1.11  kiyohara 		break;
    504  1.11  kiyohara 	default:
    505  1.11  kiyohara 		aprint_error_dev(sc->sc_dev,
    506  1.11  kiyohara 		    "WLED ISET selection is 1 or 2: isel %d\n", isel);
    507  1.11  kiyohara 		return;
    508  1.11  kiyohara 	}
    509  1.11  kiyohara 	switch (fdim) {
    510  1.11  kiyohara 	case 100:
    511  1.11  kiyohara 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
    512  1.11  kiyohara 		break;
    513  1.11  kiyohara 	case 200:
    514  1.11  kiyohara 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
    515  1.11  kiyohara 		break;
    516  1.11  kiyohara 	case 500:
    517  1.11  kiyohara 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
    518  1.11  kiyohara 		break;
    519  1.11  kiyohara 	case 1000:
    520  1.11  kiyohara 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
    521  1.11  kiyohara 		break;
    522  1.11  kiyohara 	default:
    523  1.11  kiyohara 		aprint_error_dev(sc->sc_dev,
    524  1.11  kiyohara 		    "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
    525  1.11  kiyohara 		    " fdim %d\n", fdim);
    526  1.11  kiyohara 		return;
    527  1.11  kiyohara 	}
    528  1.11  kiyohara 	if (brightness > 100 ||
    529  1.11  kiyohara 	    brightness < 0) {
    530  1.11  kiyohara 		aprint_error_dev(sc->sc_dev,
    531  1.11  kiyohara 		    "invalid brightness: between 0 and 100: %d\n", brightness);
    532  1.11  kiyohara 		return;
    533  1.11  kiyohara 	}
    534  1.11  kiyohara 
    535  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc) != 0) {
    536  1.15   thorpej 		device_printf(sc->sc_dev,
    537  1.15   thorpej 		    "WARNING: unable to configure LED\n");
    538  1.15   thorpej 		return;
    539  1.15   thorpej 	}
    540  1.15   thorpej 
    541  1.11  kiyohara 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    542  1.11  kiyohara 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
    543  1.11  kiyohara 	    (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
    544  1.11  kiyohara 	val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
    545  1.11  kiyohara 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    546  1.15   thorpej 
    547  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    548  1.11  kiyohara }
    549  1.11  kiyohara 
    550  1.11  kiyohara static void
    551   1.6   rkujawa tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
    552   1.2   rkujawa {
    553   1.2   rkujawa 	int i;
    554   1.2   rkujawa 	struct tps_reg_param *c_reg;
    555   1.2   rkujawa 
    556  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc) != 0) {
    557  1.15   thorpej 		device_printf(sc->sc_dev,
    558  1.15   thorpej 		    "WARNING: unable to refresh regulators\n");
    559  1.15   thorpej 		return;
    560  1.15   thorpej 	}
    561  1.15   thorpej 
    562   1.2   rkujawa 	for (i = 0; i < NTPS_REG; i++) {
    563   1.2   rkujawa 		c_reg = &tps_regulators[i];
    564   1.4  jakllsch 		tps65217pmic_regulator_read_config(sc, c_reg);
    565   1.2   rkujawa 	}
    566  1.15   thorpej 
    567  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    568   1.1   rkujawa }
    569   1.1   rkujawa 
    570   1.1   rkujawa /* Get version and revision of the chip. */
    571   1.4  jakllsch static void
    572   1.1   rkujawa tps65217pmic_version(struct tps65217pmic_softc *sc)
    573   1.1   rkujawa {
    574   1.1   rkujawa 	uint8_t chipid;
    575   1.1   rkujawa 
    576  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc) != 0) {
    577  1.15   thorpej 		device_printf(sc->sc_dev,
    578  1.15   thorpej 		    "WARNING: unable to get chip ID\n");
    579  1.15   thorpej 		return;
    580  1.15   thorpej 	}
    581  1.15   thorpej 
    582   1.1   rkujawa 	chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
    583   1.1   rkujawa 
    584  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    585  1.15   thorpej 
    586   1.1   rkujawa 	sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
    587   1.1   rkujawa 	sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
    588   1.1   rkujawa }
    589   1.1   rkujawa 
    590   1.4  jakllsch static uint16_t
    591   1.4  jakllsch tps65217pmic_ppath_max_ac_current(uint8_t ppath)
    592   1.1   rkujawa {
    593   1.4  jakllsch 	switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
    594   1.1   rkujawa 	    TPS65217PMIC_PPATH_IAC_RSHFIT) {
    595   1.1   rkujawa 	case TPS65217PMIC_PPATH_IAC_100MA:
    596   1.1   rkujawa 		return 100;
    597   1.1   rkujawa 	case TPS65217PMIC_PPATH_IAC_500MA:
    598   1.5   rkujawa 		return 500;
    599   1.1   rkujawa 	case TPS65217PMIC_PPATH_IAC_1300MA:
    600   1.1   rkujawa 		return 1300;
    601   1.1   rkujawa 	case TPS65217PMIC_PPATH_IAC_2500MA:
    602   1.1   rkujawa 		return 2500;
    603   1.1   rkujawa 	}
    604   1.1   rkujawa 	return 0;
    605   1.1   rkujawa }
    606   1.1   rkujawa 
    607   1.4  jakllsch static uint16_t
    608   1.1   rkujawa tps65217pmic_ppath_max_usb_current(uint8_t ppath)
    609   1.1   rkujawa {
    610   1.1   rkujawa 	switch (ppath & TPS65217PMIC_PPATH_IUSB) {
    611   1.1   rkujawa 	case TPS65217PMIC_PPATH_IUSB_100MA:
    612   1.1   rkujawa 		return 100;
    613   1.1   rkujawa 	case TPS65217PMIC_PPATH_IUSB_500MA:
    614   1.5   rkujawa 		return 500;
    615   1.1   rkujawa 	case TPS65217PMIC_PPATH_IUSB_1300MA:
    616   1.1   rkujawa 		return 1300;
    617   1.1   rkujawa 	case TPS65217PMIC_PPATH_IUSB_1800MA:
    618   1.1   rkujawa 		return 1800;
    619   1.1   rkujawa 	}
    620   1.1   rkujawa 	return 0;
    621   1.1   rkujawa }
    622   1.1   rkujawa 
    623   1.2   rkujawa /* Read regulator state and save it to tps_reg_param. */
    624   1.4  jakllsch static void
    625   1.4  jakllsch tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
    626   1.2   rkujawa     tps_reg_param *regulator)
    627   1.1   rkujawa {
    628   1.2   rkujawa 	uint8_t defreg, regenable;
    629   1.2   rkujawa 	uint16_t voltage;
    630   1.1   rkujawa 
    631   1.2   rkujawa 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    632   1.2   rkujawa 
    633   1.2   rkujawa 	if (regenable & (regulator->enable_bit))
    634   1.2   rkujawa 		regulator->is_enabled = true;
    635   1.2   rkujawa 	else {
    636   1.2   rkujawa 		regulator->is_enabled = false;
    637   1.2   rkujawa 		return;
    638   1.2   rkujawa 	}
    639   1.2   rkujawa 
    640   1.4  jakllsch 	defreg = tps65217pmic_reg_read(sc,
    641   1.2   rkujawa 	    regulator->defreg_num);
    642   1.2   rkujawa 
    643   1.2   rkujawa 	switch (regulator->nvoltages) {
    644   1.2   rkujawa 	case 16:
    645   1.4  jakllsch 		voltage = regulator->voltages[defreg &
    646   1.2   rkujawa 		    TPS65217PMIC_DEFX_VOLTAGE_16];
    647   1.2   rkujawa 		break;
    648   1.2   rkujawa 	case 32:
    649   1.4  jakllsch 		voltage = regulator->voltages[defreg &
    650   1.2   rkujawa 		    TPS65217PMIC_DEFX_VOLTAGE_32];
    651   1.2   rkujawa 		break;
    652   1.2   rkujawa 	case 64:
    653   1.4  jakllsch 		voltage = regulator->voltages[defreg &
    654   1.2   rkujawa 		    TPS65217PMIC_DEFX_VOLTAGE_64];
    655   1.2   rkujawa 		break;
    656   1.1   rkujawa 	default:
    657   1.2   rkujawa 		/* unsupported number of voltage settings? */
    658   1.2   rkujawa 		voltage = 0;
    659   1.1   rkujawa 		break;
    660   1.1   rkujawa 	}
    661   1.1   rkujawa 
    662   1.2   rkujawa 	/* Handle regulator tracking other regulator voltage. */
    663   1.2   rkujawa 	if (regulator->can_track)
    664   1.2   rkujawa 		if (defreg & TPS65217PMIC_DEFX_TRACKING) {
    665   1.2   rkujawa 			regulator->is_tracking = true;
    666   1.2   rkujawa 			voltage = 0; /* see regulator->tracked_reg */
    667   1.2   rkujawa 		}
    668   1.2   rkujawa 
    669   1.2   rkujawa 	/* Handle regulator configured into load switch mode. */
    670   1.2   rkujawa 	if (regulator->can_ls)
    671   1.2   rkujawa 		if (!(defreg & TPS65217PMIC_DEFX_LS)) {
    672   1.2   rkujawa 			regulator->is_ls = true;
    673   1.4  jakllsch 			voltage = 0;
    674   1.2   rkujawa 		}
    675   1.2   rkujawa 
    676   1.2   rkujawa 	if (regulator->can_xadj)
    677   1.2   rkujawa 		if (defreg & TPS65217PMIC_DEFX_XADJ) {
    678   1.2   rkujawa 			regulator->is_xadj = true;
    679   1.2   rkujawa 			voltage = 0;
    680   1.2   rkujawa 
    681   1.2   rkujawa 		}
    682   1.2   rkujawa 
    683   1.2   rkujawa 	/* TODO: add PGOOD checking */
    684   1.2   rkujawa 
    685   1.2   rkujawa 	regulator->current_voltage = voltage;
    686   1.2   rkujawa }
    687   1.2   rkujawa 
    688   1.2   rkujawa static void
    689   1.2   rkujawa tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
    690   1.2   rkujawa {
    691   1.2   rkujawa 	int i;
    692   1.2   rkujawa 	struct tps_reg_param *c_reg;
    693   1.2   rkujawa 
    694   1.2   rkujawa 	aprint_normal_dev(sc->sc_dev, "");
    695   1.2   rkujawa 
    696   1.2   rkujawa 	for (i = 0; i < NTPS_REG; i++) {
    697   1.2   rkujawa 		c_reg = &tps_regulators[i];
    698   1.2   rkujawa 
    699   1.3   rkujawa 		if (c_reg->is_enabled) {
    700   1.3   rkujawa 			if (c_reg->is_ls)
    701   1.2   rkujawa 				aprint_normal("[%s: LS] ", c_reg->name);
    702   1.3   rkujawa 			else if (c_reg->is_xadj)
    703   1.2   rkujawa 				aprint_normal("[%s: XADJ] ", c_reg->name);
    704   1.3   rkujawa 			else
    705   1.2   rkujawa 				aprint_normal("[%s: %d mV] ", c_reg->name,
    706   1.2   rkujawa 				    c_reg->current_voltage);
    707   1.2   rkujawa 		}
    708   1.2   rkujawa 	}
    709   1.2   rkujawa 	aprint_normal("\n");
    710   1.1   rkujawa }
    711   1.1   rkujawa 
    712   1.4  jakllsch static void
    713   1.2   rkujawa tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
    714   1.1   rkujawa {
    715   1.7     skrll 	uint8_t status, ppath;
    716   1.1   rkujawa 
    717   1.1   rkujawa 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    718   1.1   rkujawa 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    719   1.1   rkujawa 
    720   1.1   rkujawa 	aprint_normal_dev(sc->sc_dev, "power sources ");
    721   1.1   rkujawa 
    722   1.1   rkujawa 	if (ppath & TPS65217PMIC_PPATH_USB_EN) {
    723   1.1   rkujawa 		if (status & TPS65217PMIC_STATUS_USBPWR)
    724   1.1   rkujawa 			aprint_normal("[USB] ");
    725   1.1   rkujawa 		else
    726   1.1   rkujawa 			aprint_normal("USB ");
    727   1.4  jakllsch 		aprint_normal("max %d mA, ",
    728   1.1   rkujawa 		    tps65217pmic_ppath_max_usb_current(ppath));
    729   1.1   rkujawa 	}
    730   1.1   rkujawa 
    731   1.1   rkujawa 	if (ppath & TPS65217PMIC_PPATH_AC_EN) {
    732   1.1   rkujawa 		if (status & TPS65217PMIC_STATUS_ACPWR)
    733   1.1   rkujawa 			aprint_normal("[AC] ");
    734   1.1   rkujawa 		else
    735   1.1   rkujawa 			aprint_normal("AC ");
    736   1.4  jakllsch 		aprint_normal("max %d mA",
    737   1.1   rkujawa 		    tps65217pmic_ppath_max_ac_current(ppath));
    738   1.1   rkujawa 	}
    739   1.1   rkujawa 
    740   1.1   rkujawa 	aprint_normal("\n");
    741   1.1   rkujawa }
    742   1.1   rkujawa 
    743  1.15   thorpej static int
    744  1.15   thorpej tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc)
    745  1.15   thorpej {
    746  1.15   thorpej 	int error;
    747  1.15   thorpej 
    748  1.15   thorpej 	error = iic_acquire_bus(sc->sc_tag, 0);
    749  1.15   thorpej 	if (error) {
    750  1.15   thorpej 		device_printf(sc->sc_dev,
    751  1.15   thorpej 		    "unable to acquire i2c bus, error %d\n", error);
    752  1.15   thorpej 	}
    753  1.15   thorpej 	return error;
    754  1.15   thorpej }
    755  1.15   thorpej 
    756  1.15   thorpej static void
    757  1.15   thorpej tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
    758  1.15   thorpej {
    759  1.15   thorpej 	iic_release_bus(sc->sc_tag, 0);
    760  1.15   thorpej }
    761  1.15   thorpej 
    762   1.1   rkujawa static uint8_t
    763   1.1   rkujawa tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
    764   1.1   rkujawa {
    765   1.1   rkujawa 	uint8_t wbuf[2];
    766   1.1   rkujawa 	uint8_t rv;
    767   1.1   rkujawa 
    768   1.1   rkujawa 	wbuf[0] = reg;
    769   1.1   rkujawa 
    770   1.4  jakllsch 	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
    771  1.15   thorpej 	    1, &rv, 1, 0)) {
    772   1.1   rkujawa 		aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
    773  1.15   thorpej 		iic_release_bus(sc->sc_tag, 0);
    774   1.1   rkujawa 		return 0;
    775   1.1   rkujawa 	}
    776   1.1   rkujawa 
    777   1.1   rkujawa 	return rv;
    778   1.1   rkujawa }
    779   1.1   rkujawa 
    780  1.10    bouyer static void
    781  1.15   thorpej tps65217pmic_reg_write(struct tps65217pmic_softc *sc,
    782  1.10    bouyer     uint8_t reg, uint8_t data)
    783  1.10    bouyer {
    784  1.10    bouyer 	uint8_t wbuf[2];
    785  1.10    bouyer 
    786  1.10    bouyer 	wbuf[0] = reg;
    787  1.10    bouyer 	wbuf[1] = data;
    788  1.10    bouyer 
    789  1.10    bouyer 	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
    790  1.15   thorpej 	    wbuf, 2, 0)) {
    791  1.10    bouyer 		aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
    792  1.10    bouyer 	}
    793  1.10    bouyer }
    794  1.10    bouyer 
    795  1.10    bouyer static void
    796  1.10    bouyer tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
    797  1.10    bouyer     uint8_t reg, uint8_t data)
    798  1.10    bouyer {
    799  1.10    bouyer 	uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
    800  1.15   thorpej 
    801  1.15   thorpej 	if (tps65217pmic_i2c_lock(sc))
    802   1.8  jakllsch 		return;
    803   1.8  jakllsch 
    804  1.15   thorpej 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    805  1.15   thorpej 	tps65217pmic_reg_write(sc, reg, data);
    806  1.15   thorpej 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    807  1.15   thorpej 	tps65217pmic_reg_write(sc, reg, data);
    808  1.15   thorpej 
    809  1.15   thorpej 	tps65217pmic_i2c_unlock(sc);
    810   1.8  jakllsch }
    811   1.8  jakllsch 
    812   1.3   rkujawa static void
    813   1.3   rkujawa tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
    814   1.3   rkujawa {
    815   1.3   rkujawa 	int i;
    816   1.3   rkujawa 
    817   1.3   rkujawa 	sc->sc_sme = sysmon_envsys_create();
    818   1.3   rkujawa 
    819   1.6   rkujawa 	/* iterate over all regulators and attach them as sensors */
    820   1.6   rkujawa 	for(i = 0; i <= SNUM_REGS; i++) {
    821   1.3   rkujawa 		/* set name */
    822   1.6   rkujawa 		strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
    823   1.6   rkujawa 		    sizeof(sc->sc_regsensor[i].desc));
    824   1.6   rkujawa 		sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
    825   1.6   rkujawa 		sc->sc_regsensor[i].state = ENVSYS_SINVALID;
    826   1.3   rkujawa 
    827   1.6   rkujawa 		if (sysmon_envsys_sensor_attach(sc->sc_sme,
    828   1.6   rkujawa 		    &sc->sc_regsensor[i]))
    829   1.4  jakllsch 			aprint_error_dev(sc->sc_dev,
    830   1.6   rkujawa 			    "error attaching regulator sensor %d\n", i);
    831   1.3   rkujawa 	}
    832   1.3   rkujawa 
    833   1.6   rkujawa 	/* attach power source indicators */
    834   1.6   rkujawa 	strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
    835   1.6   rkujawa 	sc->sc_usbsensor.units = ENVSYS_INDICATOR;
    836   1.9  jakllsch 	sc->sc_usbsensor.state = ENVSYS_SINVALID;
    837   1.6   rkujawa 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
    838   1.9  jakllsch 		aprint_error_dev(sc->sc_dev,
    839   1.6   rkujawa 		    "error attaching USB power source sensor\n");
    840   1.6   rkujawa 	strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
    841   1.6   rkujawa 	sc->sc_acsensor.units = ENVSYS_INDICATOR;
    842   1.9  jakllsch 	sc->sc_acsensor.state = ENVSYS_SINVALID;
    843   1.6   rkujawa 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
    844   1.9  jakllsch 		aprint_error_dev(sc->sc_dev,
    845   1.9  jakllsch 		    "error attaching AC power source sensor\n");
    846   1.6   rkujawa 
    847   1.6   rkujawa 	/* register everything in sysmon */
    848   1.3   rkujawa 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    849   1.3   rkujawa 	sc->sc_sme->sme_cookie = sc;
    850   1.3   rkujawa 	sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
    851   1.3   rkujawa 
    852   1.3   rkujawa 	if (sysmon_envsys_register(sc->sc_sme)) {
    853   1.3   rkujawa 		aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
    854   1.3   rkujawa 		sysmon_envsys_destroy(sc->sc_sme);
    855   1.3   rkujawa 	}
    856   1.3   rkujawa }
    857   1.3   rkujawa 
    858   1.3   rkujawa static void
    859   1.3   rkujawa tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    860   1.3   rkujawa {
    861   1.4  jakllsch 	struct tps65217pmic_softc *sc = sme->sme_cookie;
    862   1.3   rkujawa 
    863   1.3   rkujawa 	mutex_enter(&sc->sc_lock);
    864   1.3   rkujawa 
    865   1.6   rkujawa 	tps65217pmic_reg_refresh(sc);
    866   1.3   rkujawa 
    867   1.6   rkujawa 	if (edata->sensor <= SNUM_REGS) {
    868   1.6   rkujawa 		/* TODO: handle special cases like LS, XADJ... */
    869   1.6   rkujawa 		edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
    870   1.6   rkujawa 		edata->state = ENVSYS_SVALID;
    871   1.6   rkujawa 	} else if (edata->sensor == SNUM_USBSTATUS) {
    872   1.6   rkujawa 		edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
    873   1.6   rkujawa 		edata->state = ENVSYS_SVALID;
    874   1.6   rkujawa 	} else if (edata->sensor == SNUM_ACSTATUS) {
    875   1.6   rkujawa 		edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
    876   1.6   rkujawa 		edata->state = ENVSYS_SVALID;
    877   1.6   rkujawa 	} else
    878   1.6   rkujawa 		aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
    879   1.4  jakllsch 
    880   1.3   rkujawa 	mutex_exit(&sc->sc_lock);
    881   1.3   rkujawa }
    882   1.3   rkujawa 
    883  1.10    bouyer int
    884  1.10    bouyer tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
    885  1.10    bouyer {
    886  1.10    bouyer 	int i;
    887  1.10    bouyer 	struct tps65217pmic_softc *sc = device_private(self);
    888  1.10    bouyer 	struct tps_reg_param *regulator = NULL;
    889  1.10    bouyer 	uint8_t val;
    890  1.10    bouyer 
    891  1.10    bouyer 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    892  1.10    bouyer 		if (strcmp(name, tps_regulators[i].name) == 0) {
    893  1.10    bouyer 			regulator = &tps_regulators[i];
    894  1.10    bouyer 			break;
    895  1.10    bouyer 		}
    896  1.10    bouyer 	}
    897  1.10    bouyer 	if (regulator == NULL)
    898  1.10    bouyer 		return EINVAL;
    899  1.10    bouyer 
    900  1.10    bouyer 	if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
    901  1.10    bouyer 		return EINVAL;
    902  1.10    bouyer 
    903  1.10    bouyer 	if (!regulator->is_enabled)
    904  1.10    bouyer 		return EINVAL;
    905  1.10    bouyer 
    906  1.10    bouyer 	if (regulator->is_tracking)
    907  1.10    bouyer 		return EINVAL;
    908  1.10    bouyer 
    909  1.10    bouyer 	if (regulator->is_xadj)
    910  1.10    bouyer 		return EINVAL;
    911  1.10    bouyer 
    912  1.10    bouyer 	/* find closest voltage entry */
    913  1.10    bouyer 	for (i = 0; i < regulator->nvoltages; i++) {
    914  1.10    bouyer 		if (mvolt <= regulator->voltages[i]) {
    915  1.10    bouyer 			break;
    916  1.10    bouyer 		}
    917  1.10    bouyer 	}
    918  1.10    bouyer 	KASSERT(i < regulator->nvoltages);
    919  1.10    bouyer 	tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
    920  1.10    bouyer 
    921  1.10    bouyer 	val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    922  1.10    bouyer 	val |= TPS65217PMIC_DEFSLEW_GO;
    923  1.10    bouyer 	tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
    924  1.10    bouyer 
    925  1.10    bouyer 	while (val & TPS65217PMIC_DEFSLEW_GO) {
    926  1.10    bouyer 		val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    927  1.10    bouyer 	}
    928  1.13  jmcneill 
    929  1.13  jmcneill 	regulator->current_voltage = regulator->voltages[i];
    930  1.13  jmcneill 
    931  1.10    bouyer 	return 0;
    932  1.10    bouyer }
    933  1.13  jmcneill 
    934  1.13  jmcneill #ifdef FDT
    935  1.13  jmcneill static struct tps_reg_param *
    936  1.13  jmcneill tps65217pmic_get_params(const char *name)
    937  1.13  jmcneill {
    938  1.13  jmcneill 	int i;
    939  1.13  jmcneill 
    940  1.13  jmcneill 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    941  1.13  jmcneill 		if (strcmp(name, tps_regulators[i].name) == 0)
    942  1.13  jmcneill 			return &tps_regulators[i];
    943  1.13  jmcneill 	}
    944  1.13  jmcneill 
    945  1.13  jmcneill 	return NULL;
    946  1.13  jmcneill }
    947  1.13  jmcneill 
    948  1.13  jmcneill static void
    949  1.13  jmcneill tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
    950  1.13  jmcneill {
    951  1.13  jmcneill 	struct tps65217reg_attach_args raa;
    952  1.13  jmcneill 	struct tps_reg_param *param;
    953  1.13  jmcneill 	const char *compat_name;
    954  1.13  jmcneill 	int phandle, child;
    955  1.13  jmcneill 
    956  1.13  jmcneill 	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
    957  1.13  jmcneill 	if (phandle <= 0)
    958  1.13  jmcneill 		return;
    959  1.13  jmcneill 
    960  1.13  jmcneill 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    961  1.13  jmcneill 		compat_name = fdtbus_get_string(child, "regulator-compatible");
    962  1.13  jmcneill 		if (compat_name == NULL)
    963  1.13  jmcneill 			continue;
    964  1.13  jmcneill 		param = tps65217pmic_get_params(compat_name);
    965  1.13  jmcneill 		if (param == NULL)
    966  1.13  jmcneill 			continue;
    967  1.13  jmcneill 
    968  1.13  jmcneill 		raa.reg_param = param;
    969  1.13  jmcneill 		raa.reg_phandle = child;
    970  1.20   thorpej 		config_found(sc->sc_dev, &raa, NULL, CFARGS_NONE);
    971  1.13  jmcneill 	}
    972  1.13  jmcneill }
    973  1.13  jmcneill 
    974  1.13  jmcneill static int
    975  1.13  jmcneill tps65217reg_acquire(device_t dev)
    976  1.13  jmcneill {
    977  1.13  jmcneill 	return 0;
    978  1.13  jmcneill }
    979  1.13  jmcneill 
    980  1.13  jmcneill static void
    981  1.13  jmcneill tps65217reg_release(device_t dev)
    982  1.13  jmcneill {
    983  1.13  jmcneill }
    984  1.13  jmcneill 
    985  1.13  jmcneill static int
    986  1.13  jmcneill tps65217reg_enable(device_t dev, bool enable)
    987  1.13  jmcneill {
    988  1.13  jmcneill 	struct tps65217reg_softc *sc = device_private(dev);
    989  1.13  jmcneill 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
    990  1.13  jmcneill 	struct tps_reg_param *regulator = sc->sc_param;
    991  1.13  jmcneill 	uint8_t val;
    992  1.13  jmcneill 	int error;
    993  1.13  jmcneill 
    994  1.15   thorpej 	error = tps65217pmic_i2c_lock(pmic_sc);
    995  1.13  jmcneill 	if (error != 0)
    996  1.13  jmcneill 		return error;
    997  1.13  jmcneill 
    998  1.13  jmcneill 	val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
    999  1.13  jmcneill 	if (enable)
   1000  1.13  jmcneill 		val |= regulator->enable_bit;
   1001  1.13  jmcneill 	else
   1002  1.13  jmcneill 		val &= ~regulator->enable_bit;
   1003  1.13  jmcneill 	tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
   1004  1.13  jmcneill 
   1005  1.13  jmcneill 	regulator->is_enabled = enable;
   1006  1.13  jmcneill 
   1007  1.15   thorpej 	tps65217pmic_i2c_unlock(pmic_sc);
   1008  1.13  jmcneill 
   1009  1.13  jmcneill 	return 0;
   1010  1.13  jmcneill }
   1011  1.13  jmcneill 
   1012  1.13  jmcneill static int
   1013  1.13  jmcneill tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
   1014  1.13  jmcneill {
   1015  1.13  jmcneill 	struct tps65217reg_softc *sc = device_private(dev);
   1016  1.13  jmcneill 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
   1017  1.13  jmcneill 	struct tps_reg_param *regulator = sc->sc_param;
   1018  1.13  jmcneill 	int error;
   1019  1.13  jmcneill 
   1020  1.15   thorpej 	error = tps65217pmic_i2c_lock(pmic_sc);
   1021  1.13  jmcneill 	if (error != 0)
   1022  1.13  jmcneill 		return error;
   1023  1.13  jmcneill 
   1024  1.13  jmcneill 	error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
   1025  1.13  jmcneill 
   1026  1.15   thorpej 	tps65217pmic_i2c_unlock(pmic_sc);
   1027  1.13  jmcneill 
   1028  1.13  jmcneill 	return error;
   1029  1.13  jmcneill }
   1030  1.13  jmcneill 
   1031  1.13  jmcneill static int
   1032  1.13  jmcneill tps65217reg_get_voltage(device_t dev, u_int *puvol)
   1033  1.13  jmcneill {
   1034  1.13  jmcneill 	struct tps65217reg_softc *sc = device_private(dev);
   1035  1.13  jmcneill 	struct tps_reg_param *regulator = sc->sc_param;
   1036  1.13  jmcneill 
   1037  1.13  jmcneill 	*puvol = (u_int)regulator->current_voltage * 1000;
   1038  1.13  jmcneill 
   1039  1.13  jmcneill 	return 0;
   1040  1.13  jmcneill }
   1041  1.13  jmcneill 
   1042  1.13  jmcneill static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
   1043  1.13  jmcneill 	.acquire = tps65217reg_acquire,
   1044  1.13  jmcneill 	.release = tps65217reg_release,
   1045  1.13  jmcneill 	.enable = tps65217reg_enable,
   1046  1.13  jmcneill 	.set_voltage = tps65217reg_set_voltage,
   1047  1.13  jmcneill 	.get_voltage = tps65217reg_get_voltage,
   1048  1.13  jmcneill };
   1049  1.13  jmcneill 
   1050  1.13  jmcneill static int
   1051  1.13  jmcneill tps65217reg_match(device_t parent, cfdata_t match, void *aux)
   1052  1.13  jmcneill {
   1053  1.13  jmcneill 	return 1;
   1054  1.13  jmcneill }
   1055  1.13  jmcneill 
   1056  1.13  jmcneill static void
   1057  1.13  jmcneill tps65217reg_attach(device_t parent, device_t self, void *aux)
   1058  1.13  jmcneill {
   1059  1.13  jmcneill 	struct tps65217reg_softc *sc = device_private(self);
   1060  1.13  jmcneill 	struct tps65217reg_attach_args *raa = aux;
   1061  1.13  jmcneill 	const char *regname;
   1062  1.13  jmcneill 
   1063  1.13  jmcneill 	sc->sc_dev = self;
   1064  1.13  jmcneill 	sc->sc_phandle = raa->reg_phandle;
   1065  1.13  jmcneill 	sc->sc_param = raa->reg_param;
   1066  1.13  jmcneill 
   1067  1.13  jmcneill 	fdtbus_register_regulator_controller(self, sc->sc_phandle,
   1068  1.13  jmcneill 	    &tps65217reg_funcs);
   1069  1.13  jmcneill 
   1070  1.13  jmcneill 	regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
   1071  1.13  jmcneill 	if (regname == NULL)
   1072  1.13  jmcneill 		regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
   1073  1.13  jmcneill 
   1074  1.13  jmcneill 	aprint_naive("\n");
   1075  1.13  jmcneill 	if (regname != NULL)
   1076  1.13  jmcneill 		aprint_normal(": %s\n", regname);
   1077  1.13  jmcneill 	else
   1078  1.13  jmcneill 		aprint_normal("\n");
   1079  1.13  jmcneill }
   1080  1.13  jmcneill 
   1081  1.13  jmcneill CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
   1082  1.13  jmcneill     tps65217reg_match, tps65217reg_attach, NULL, NULL);
   1083  1.13  jmcneill 
   1084  1.13  jmcneill #endif
   1085