Home | History | Annotate | Line # | Download | only in i2c
tps65217pmic.c revision 1.3
      1 /*	$NetBSD: tps65217pmic.c,v 1.3 2013/04/26 19:32:43 rkujawa Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Radoslaw Kujawa.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Texas Instruments TPS65217 Power Management IC driver.
     34  * TODO: battery, sequencer, pgood
     35  */
     36 
     37 #include <sys/cdefs.h>
     38 __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.3 2013/04/26 19:32:43 rkujawa Exp $");
     39 
     40 #include <sys/param.h>
     41 #include <sys/systm.h>
     42 #include <sys/device.h>
     43 #include <sys/kernel.h>
     44 #include <sys/mutex.h>
     45 
     46 #include <sys/bus.h>
     47 #include <dev/i2c/i2cvar.h>
     48 
     49 #include <dev/sysmon/sysmonvar.h>
     50 
     51 #include <dev/i2c/tps65217pmicreg.h>
     52 
     53 #define NTPS_REG	7
     54 
     55 struct tps65217pmic_softc {
     56 	device_t		sc_dev;
     57 
     58 	i2c_tag_t		sc_tag;
     59 	i2c_addr_t		sc_addr;
     60 
     61 	uint8_t			sc_version;
     62 	uint8_t			sc_revision;
     63 
     64 	/* envsys(4) stuff */
     65 	struct sysmon_envsys	*sc_sme;
     66 	envsys_data_t		sc_sensor[NTPS_REG];
     67 	kmutex_t		sc_lock;
     68 };
     69 
     70 /* Voltage regulators */
     71 enum tps_reg_num {
     72 	TPS65217PMIC_LDO1,
     73 	TPS65217PMIC_LDO2,
     74 	TPS65217PMIC_LDO3LS,
     75 	TPS65217PMIC_LDO4LS,
     76 	TPS65217PMIC_DCDC1,
     77 	TPS65217PMIC_DCDC2,
     78 	TPS65217PMIC_DCDC3
     79 };
     80 
     81 struct tps_reg_param {
     82 	/* parameters configured statically */
     83 
     84 	const char* name;
     85 	uint16_t voltage_min;		/* in mV */
     86 	uint16_t voltage_max;		/* in mV */
     87 	const uint16_t *voltages;	/* all possible voltage settings */
     88 	uint8_t nvoltages;		/* number of voltage settings */
     89 
     90 	bool can_track;			/* regulator can track U of other r. */
     91 	struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
     92 	bool can_xadj;			/* voltage can be adjusted externally */
     93 	bool can_ls;			/* can be a load switch instead of r. */
     94 
     95 	uint8_t defreg_num;		/* DEF register */
     96 	uint8_t enable_bit;		/* position in ENABLE register */
     97 
     98 	/*
     99 	 * Run-time parameters configured during attachment and later, these
    100 	 * probably should be split into separate struct that would be a part
    101 	 * of softc. But since we can have only one TPS chip, that should be
    102 	 * okay for now.
    103 	 */
    104 
    105 	bool is_enabled;		/* regulator is enabled */
    106 	bool is_pg;			/* regulator is "power good" */
    107 	bool is_tracking;		/* voltage is tracking other reg. */
    108 	bool is_ls;			/* is a load switch */
    109 	bool is_xadj;			/* voltage is adjusted externally */
    110 
    111 	uint16_t current_voltage;	/* in mV */
    112 
    113 };
    114 
    115 static int tps65217pmic_match(device_t, cfdata_t, void *);
    116 static void tps65217pmic_attach(device_t, device_t, void *);
    117 
    118 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
    119 
    120 static void tps65217pmic_refresh(struct tps65217pmic_softc *);
    121 
    122 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
    123 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
    124 
    125 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
    126     struct tps_reg_param *);
    127 
    128 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
    129 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
    130 
    131 static void tps65217pmic_version(struct tps65217pmic_softc *);
    132 
    133 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
    134 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
    135 
    136 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
    137     tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
    138 
    139 /* Possible settings of LDO1 in mV. */
    140 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
    141     1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
    142 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
    143 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
    144     1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
    145     1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
    146     1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
    147     2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
    148     3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
    149 /* Possible settings of LDO3, LDO4 in mV. */
    150 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
    151     1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
    152     2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
    153     3250, 3300 };
    154 
    155 static struct tps_reg_param tps_regulators[] = {
    156 	{
    157 		.name = "LDO1",
    158 		.voltage_min = 1000,
    159 		.voltage_max = 3300,
    160 		.voltages = ldo1voltages,
    161 		.nvoltages = 16,
    162 		.can_track = false,
    163 		.tracked_reg = NULL,
    164 		.can_xadj =  false,
    165 		.can_ls = false,
    166 		.defreg_num = TPS65217PMIC_DEFLDO1,
    167 		.enable_bit = TPS65217PMIC_ENABLE_LDO1
    168 	},
    169 	{
    170 		.name = "LDO2",
    171 		.voltage_min = 900,
    172 		.voltage_max = 3300,
    173 		.voltages = ldo2voltages,
    174 		.nvoltages = 64,
    175 		.can_track = true,
    176 		.tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
    177 		.can_xadj = false,
    178 		.can_ls = false,
    179 		.defreg_num = TPS65217PMIC_DEFLDO2,
    180 		.enable_bit = TPS65217PMIC_ENABLE_LDO2
    181 	},
    182 	{
    183 		.name = "LDO3",
    184 		.voltage_min = 1500,
    185 		.voltage_max = 3300,
    186 		.voltages = ldo3voltages,
    187 		.nvoltages = 32,
    188 		.can_track = false,
    189 		.tracked_reg = NULL,
    190 		.can_xadj = false,
    191 		.can_ls = true,
    192 		.defreg_num = TPS65217PMIC_DEFLDO3,
    193 		.enable_bit = TPS65217PMIC_ENABLE_LDO3
    194 	},
    195 	{
    196 		.name = "LDO4",
    197 		.voltage_min = 1500,
    198 		.voltage_max = 3300,
    199 		.voltages = ldo3voltages,
    200 		.nvoltages = 32,
    201 		.can_track = false,
    202 		.tracked_reg = NULL,
    203 		.can_xadj = false,
    204 		.can_ls = true,
    205 		.defreg_num = TPS65217PMIC_DEFLDO4,
    206 		.enable_bit = TPS65217PMIC_ENABLE_LDO4
    207 	},
    208 	{
    209 		.name = "DCDC1",
    210 		.voltage_min = 900,
    211 		.voltage_max = 3300,
    212 		.voltages = ldo2voltages,
    213 		.nvoltages = 64,
    214 		.can_track = false,
    215 		.tracked_reg = NULL,
    216 		.can_xadj = true,
    217 		.can_ls = false,
    218 		.defreg_num = TPS65217PMIC_DEFDCDC1,
    219 		.enable_bit = TPS65217PMIC_ENABLE_DCDC1
    220 	},
    221 	{
    222 		.name = "DCDC2",
    223 		.voltage_min = 900,
    224 		.voltage_max = 3300,
    225 		.voltages = ldo2voltages,
    226 		.nvoltages = 64,
    227 		.can_track = false,
    228 		.tracked_reg = NULL,
    229 		.can_xadj = true,
    230 		.can_ls = false,
    231 		.defreg_num = TPS65217PMIC_DEFDCDC2,
    232 		.enable_bit = TPS65217PMIC_ENABLE_DCDC2
    233 	},
    234 	{
    235 		.name = "DCDC3",
    236 		.voltage_min = 900,
    237 		.voltage_max = 3300,
    238 		.voltages = ldo2voltages,
    239 		.nvoltages = 64,
    240 		.can_track = false,
    241 		.tracked_reg = NULL,
    242 		.can_xadj = true,
    243 		.can_ls = false,
    244 		.defreg_num = TPS65217PMIC_DEFDCDC3,
    245 		.enable_bit = TPS65217PMIC_ENABLE_DCDC3
    246 	}
    247 };
    248 
    249 static bool matched = false;
    250 
    251 static int
    252 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
    253 {
    254 	struct i2c_attach_args *ia = aux;
    255 
    256 	if (ia->ia_addr == TPS65217PMIC_ADDR) {
    257 		/* we can only have one */
    258 		if (matched)
    259 			return 0;
    260 		else
    261 			matched = true;
    262 
    263 		return 1;
    264 	}
    265 	return 0;
    266 }
    267 
    268 static void
    269 tps65217pmic_attach(device_t parent, device_t self, void *aux)
    270 {
    271 	struct tps65217pmic_softc *sc = device_private(self);
    272 	struct i2c_attach_args *ia = aux;
    273 
    274 	sc->sc_dev = self;
    275 	sc->sc_addr = ia->ia_addr;
    276 	sc->sc_tag = ia->ia_tag;
    277 
    278 	tps65217pmic_version(sc);
    279 
    280 	aprint_normal(": TPS65217");
    281 	switch (sc->sc_version) {
    282 	case TPS65217PMIC_CHIPID_VER_A:
    283 		aprint_normal("A");
    284 		break;
    285 	case TPS65217PMIC_CHIPID_VER_B:
    286 		aprint_normal("B");
    287 		break;
    288 	case TPS65217PMIC_CHIPID_VER_C:
    289 		aprint_normal("C");
    290 		break;
    291 	case TPS65217PMIC_CHIPID_VER_D:
    292 		aprint_normal("D");
    293 		break;
    294 	default:
    295 		/* unknown version */
    296 		break;
    297 	}
    298 
    299 	aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
    300 	    sc->sc_revision);
    301 
    302 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    303 
    304 	tps65217pmic_refresh(sc);
    305 
    306 	tps65217pmic_print_ppath(sc);
    307 	tps65217pmic_print_ldos(sc);
    308 
    309 	tps65217pmic_envsys_register(sc);
    310 }
    311 
    312 static void
    313 tps65217pmic_refresh(struct tps65217pmic_softc *sc)
    314 {
    315 	int i;
    316 	struct tps_reg_param *c_reg;
    317 
    318 	for (i = 0; i < NTPS_REG; i++) {
    319 		c_reg = &tps_regulators[i];
    320 		tps65217pmic_regulator_read_config(sc, c_reg);
    321 	}
    322 }
    323 
    324 /* Get version and revision of the chip. */
    325 static void
    326 tps65217pmic_version(struct tps65217pmic_softc *sc)
    327 {
    328 	uint8_t chipid;
    329 
    330 	chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
    331 
    332 	sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
    333 	sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
    334 }
    335 
    336 static uint16_t
    337 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
    338 {
    339 	switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
    340 	    TPS65217PMIC_PPATH_IAC_RSHFIT) {
    341 	case TPS65217PMIC_PPATH_IAC_100MA:
    342 		return 100;
    343 	case TPS65217PMIC_PPATH_IAC_500MA:
    344 		return 300;
    345 	case TPS65217PMIC_PPATH_IAC_1300MA:
    346 		return 1300;
    347 	case TPS65217PMIC_PPATH_IAC_2500MA:
    348 		return 2500;
    349 	}
    350 	return 0;
    351 }
    352 
    353 static uint16_t
    354 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
    355 {
    356 	switch (ppath & TPS65217PMIC_PPATH_IUSB) {
    357 	case TPS65217PMIC_PPATH_IUSB_100MA:
    358 		return 100;
    359 	case TPS65217PMIC_PPATH_IUSB_500MA:
    360 		return 300;
    361 	case TPS65217PMIC_PPATH_IUSB_1300MA:
    362 		return 1300;
    363 	case TPS65217PMIC_PPATH_IUSB_1800MA:
    364 		return 1800;
    365 	}
    366 	return 0;
    367 }
    368 
    369 /* Read regulator state and save it to tps_reg_param. */
    370 static void
    371 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
    372     tps_reg_param *regulator)
    373 {
    374 	uint8_t defreg, regenable;
    375 	uint16_t voltage;
    376 
    377 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    378 
    379 	if (regenable & (regulator->enable_bit))
    380 		regulator->is_enabled = true;
    381 	else {
    382 		regulator->is_enabled = false;
    383 		return;
    384 	}
    385 
    386 	defreg = tps65217pmic_reg_read(sc,
    387 	    regulator->defreg_num);
    388 
    389 	switch (regulator->nvoltages) {
    390 	case 16:
    391 		voltage = regulator->voltages[defreg &
    392 		    TPS65217PMIC_DEFX_VOLTAGE_16];
    393 		break;
    394 	case 32:
    395 		voltage = regulator->voltages[defreg &
    396 		    TPS65217PMIC_DEFX_VOLTAGE_32];
    397 		break;
    398 	case 64:
    399 		voltage = regulator->voltages[defreg &
    400 		    TPS65217PMIC_DEFX_VOLTAGE_64];
    401 		break;
    402 	default:
    403 		/* unsupported number of voltage settings? */
    404 		voltage = 0;
    405 		break;
    406 	}
    407 
    408 	/* Handle regulator tracking other regulator voltage. */
    409 	if (regulator->can_track)
    410 		if (defreg & TPS65217PMIC_DEFX_TRACKING) {
    411 			regulator->is_tracking = true;
    412 			voltage = 0; /* see regulator->tracked_reg */
    413 		}
    414 
    415 	/* Handle regulator configured into load switch mode. */
    416 	if (regulator->can_ls)
    417 		if (!(defreg & TPS65217PMIC_DEFX_LS)) {
    418 			regulator->is_ls = true;
    419 			voltage = 0;
    420 		}
    421 
    422 	if (regulator->can_xadj)
    423 		if (defreg & TPS65217PMIC_DEFX_XADJ) {
    424 			regulator->is_xadj = true;
    425 			voltage = 0;
    426 
    427 		}
    428 
    429 	/* TODO: add PGOOD checking */
    430 
    431 	regulator->current_voltage = voltage;
    432 }
    433 
    434 static void
    435 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
    436 {
    437 	int i;
    438 	struct tps_reg_param *c_reg;
    439 
    440 	aprint_normal_dev(sc->sc_dev, "");
    441 
    442 	for (i = 0; i < NTPS_REG; i++) {
    443 		c_reg = &tps_regulators[i];
    444 
    445 		if (c_reg->is_enabled) {
    446 			if (c_reg->is_ls)
    447 				aprint_normal("[%s: LS] ", c_reg->name);
    448 			else if (c_reg->is_xadj)
    449 				aprint_normal("[%s: XADJ] ", c_reg->name);
    450 			else
    451 				aprint_normal("[%s: %d mV] ", c_reg->name,
    452 				    c_reg->current_voltage);
    453 		}
    454 	}
    455 	aprint_normal("\n");
    456 }
    457 
    458 static void
    459 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
    460 {
    461 	uint8_t status, ppath, regenable;
    462 
    463 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    464 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    465 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    466 
    467 	aprint_normal_dev(sc->sc_dev, "power sources ");
    468 
    469 	if (ppath & TPS65217PMIC_PPATH_USB_EN) {
    470 		if (status & TPS65217PMIC_STATUS_USBPWR)
    471 			aprint_normal("[USB] ");
    472 		else
    473 			aprint_normal("USB ");
    474 		aprint_normal("max %d mA, ",
    475 		    tps65217pmic_ppath_max_usb_current(ppath));
    476 	}
    477 
    478 	if (ppath & TPS65217PMIC_PPATH_AC_EN) {
    479 		if (status & TPS65217PMIC_STATUS_ACPWR)
    480 			aprint_normal("[AC] ");
    481 		else
    482 			aprint_normal("AC ");
    483 		aprint_normal("max %d mA",
    484 		    tps65217pmic_ppath_max_ac_current(ppath));
    485 	}
    486 
    487 	aprint_normal("\n");
    488 }
    489 
    490 static uint8_t
    491 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
    492 {
    493 	uint8_t wbuf[2];
    494 	uint8_t rv;
    495 
    496 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
    497 		aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n");
    498 		return 0;
    499 	}
    500 
    501 	wbuf[0] = reg;
    502 
    503 	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
    504 	    1, &rv, 1, I2C_F_POLL)) {
    505 		aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
    506 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
    507 		return 0;
    508 	}
    509 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
    510 
    511 	return rv;
    512 }
    513 
    514 static void
    515 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
    516 {
    517 	int i;
    518 
    519 	sc->sc_sme = sysmon_envsys_create();
    520 
    521 	/* iterate over all regulators and register them as sensors */
    522 	for(i = 0; i < NTPS_REG; i++) {
    523 		/* set name */
    524 		strlcpy(sc->sc_sensor[i].desc, tps_regulators[i].name,
    525 		    sizeof(sc->sc_sensor[i].desc));
    526 		sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC;
    527 		sc->sc_sensor[i].state = ENVSYS_SINVALID;
    528 
    529 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i]))
    530 			aprint_error_dev(sc->sc_dev,
    531 			    "error attaching sensor %d\n", i);
    532 	}
    533 
    534 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    535 	sc->sc_sme->sme_cookie = sc;
    536 	sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
    537 
    538 	if (sysmon_envsys_register(sc->sc_sme)) {
    539 		aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
    540 		sysmon_envsys_destroy(sc->sc_sme);
    541 	}
    542 }
    543 
    544 static void
    545 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    546 {
    547 	struct tps65217pmic_softc *sc = sme->sme_cookie;
    548 
    549 	mutex_enter(&sc->sc_lock);
    550 
    551 	tps65217pmic_refresh(sc);
    552 
    553 	/* TODO: handle special cases like LS, XADJ... */
    554 	edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
    555 	edata->state = ENVSYS_SVALID;
    556 
    557 	mutex_exit(&sc->sc_lock);
    558 }
    559 
    560