avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
137
u-boot/drivers/power/pmic/Kconfig
Normal file
137
u-boot/drivers/power/pmic/Kconfig
Normal file
@@ -0,0 +1,137 @@
|
||||
config DM_PMIC
|
||||
bool "Enable Driver Model for PMIC drivers (UCLASS_PMIC)"
|
||||
depends on DM
|
||||
---help---
|
||||
This config enables the driver-model PMIC support.
|
||||
UCLASS_PMIC - designed to provide an I/O interface for PMIC devices.
|
||||
For the multi-function PMIC devices, this can be used as parent I/O
|
||||
device for each IC's interface. Then, each children uses its parent
|
||||
for read/write. For detailed description, please refer to the files:
|
||||
- 'drivers/power/pmic/pmic-uclass.c'
|
||||
- 'include/power/pmic.h'
|
||||
|
||||
config PMIC_CHILDREN
|
||||
bool "Allow child devices for PMICs"
|
||||
depends on DM_PMIC
|
||||
default y
|
||||
---help---
|
||||
This allows PMICs to support child devices (such as regulators) in
|
||||
SPL. This adds quite a bit of code so if you are not using this
|
||||
feature you can turn it off. Most likely you should turn it on for
|
||||
U-Boot proper.
|
||||
|
||||
config SPL_PMIC_CHILDREN
|
||||
bool "Allow child devices for PMICs in SPL"
|
||||
depends on DM_PMIC
|
||||
default y
|
||||
---help---
|
||||
This allows PMICs to support child devices (such as regulators) in
|
||||
SPL. This adds quite a bit of code so if you are not using this
|
||||
feature you can turn it off. In this case you may need a 'back door'
|
||||
to call your regulator code (e.g. see rk808.c for direct functions
|
||||
for use in SPL).
|
||||
|
||||
config PMIC_ACT8846
|
||||
bool "Enable support for the active-semi 8846 PMIC"
|
||||
depends on DM_PMIC && DM_I2C
|
||||
---help---
|
||||
This PMIC includes 4 DC/DC step-down buck regulators and 8 low-dropout
|
||||
regulators (LDOs). It also provides some GPIO, reset and battery
|
||||
functions. It uses an I2C interface and is designed for use with
|
||||
tablets and smartphones.
|
||||
|
||||
config DM_PMIC_PFUZE100
|
||||
bool "Enable Driver Model for PMIC PFUZE100"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
This config enables implementation of driver-model pmic uclass features
|
||||
for PMIC PFUZE100. The driver implements read/write operations.
|
||||
|
||||
config DM_PMIC_MAX77686
|
||||
bool "Enable Driver Model for PMIC MAX77686"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
This config enables implementation of driver-model pmic uclass features
|
||||
for PMIC MAX77686. The driver implements read/write operations.
|
||||
|
||||
config PMIC_PM8916
|
||||
bool "Enable Driver Model for Qualcomm PM8916 PMIC"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
The PM8916 is a PMIC connected to one (or several) processors
|
||||
with SPMI bus. It has 2 slaves with several peripherals:
|
||||
- 18x LDO
|
||||
- 4x GPIO
|
||||
- Power and Reset buttons
|
||||
- Watchdog
|
||||
- RTC
|
||||
- Vibrator drivers
|
||||
- Others
|
||||
|
||||
Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt
|
||||
|
||||
config PMIC_RK808
|
||||
bool "Enable support for Rockchip PMIC RK808"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
The Rockchip RK808 PMIC provides four buck DC-DC convertors, 8 LDOs,
|
||||
an RTC and two low Rds (resistance (drain to source)) switches. It is
|
||||
accessed via an I2C interface. The device is used with Rockchip SoCs.
|
||||
This driver implements register read/write operations.
|
||||
|
||||
config PMIC_S2MPS11
|
||||
bool "Enable Driver Model for PMIC Samsung S2MPS11"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
The Samsung S2MPS11 PMIC provides:
|
||||
- 38 adjustable LDO regulators
|
||||
- 9 High-Efficiency Buck Converters
|
||||
- 1 BuckBoost Converter
|
||||
- RTC with two alarms
|
||||
- Backup battery charger
|
||||
- I2C Configuration Interface
|
||||
This driver provides access to I/O interface only.
|
||||
Binding info: doc/device-tree-bindings/pmic/s2mps11.txt
|
||||
|
||||
config DM_PMIC_SANDBOX
|
||||
bool "Enable Driver Model for emulated Sandbox PMIC "
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
Enable the driver for Sandbox PMIC emulation. The emulated PMIC device
|
||||
depends on two drivers:
|
||||
- sandbox PMIC I/O driver - implements dm pmic operations
|
||||
- sandbox PMIC i2c emul driver - emulates the PMIC's I2C transmission
|
||||
|
||||
A detailed information can be found in header: '<power/sandbox_pmic.h>'
|
||||
|
||||
The Sandbox PMIC info:
|
||||
* I/O interface:
|
||||
- I2C chip address: 0x40
|
||||
- first register address: 0x0
|
||||
- register count: 0x10
|
||||
* Adjustable outputs:
|
||||
- 2x LDO
|
||||
- 2x BUCK
|
||||
- Each, with a different operating conditions (header).
|
||||
* Reset values:
|
||||
- set by i2c emul driver's probe() (defaults in header)
|
||||
|
||||
Driver binding info: doc/device-tree-bindings/pmic/sandbox.txt
|
||||
|
||||
config PMIC_S5M8767
|
||||
bool "Enable Driver Model for the Samsung S5M8767 PMIC"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
The S5M8767 PMIC provides a large array of LDOs and BUCKs for use
|
||||
as a SoC power controller. It also provides 32KHz clock outputs. This
|
||||
driver provides basic register access and sets up the attached
|
||||
regulators if regulator support is enabled.
|
||||
|
||||
config PMIC_TPS65090
|
||||
bool "Enable driver for Texas Instruments TPS65090 PMIC"
|
||||
depends on DM_PMIC
|
||||
---help---
|
||||
The TPS65090 is a PMIC containing several LDOs, DC to DC convertors,
|
||||
FETs and a battery charger. This driver provides register access
|
||||
only, and you can enable the regulator/charger drivers separately if
|
||||
required.
|
||||
31
u-boot/drivers/power/pmic/Makefile
Normal file
31
u-boot/drivers/power/pmic/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright (C) 2012 Samsung Electronics
|
||||
# Lukasz Majewski <l.majewski@samsung.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_DM_PMIC) += pmic-uclass.o
|
||||
obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
|
||||
obj-$(CONFIG_DM_PMIC_PFUZE100) += pfuze100.o
|
||||
obj-$(CONFIG_PMIC_S2MPS11) += s2mps11.o
|
||||
obj-$(CONFIG_DM_PMIC_SANDBOX) += sandbox.o i2c_pmic_emul.o
|
||||
obj-$(CONFIG_PMIC_ACT8846) += act8846.o
|
||||
obj-$(CONFIG_PMIC_PM8916) += pm8916.o
|
||||
obj-$(CONFIG_PMIC_RK808) += rk808.o
|
||||
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
|
||||
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
|
||||
|
||||
obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o
|
||||
obj-$(CONFIG_POWER_MAX77696) += pmic_max77696.o
|
||||
obj-$(CONFIG_POWER_MAX8998) += pmic_max8998.o
|
||||
obj-$(CONFIG_POWER_MAX8997) += pmic_max8997.o
|
||||
obj-$(CONFIG_POWER_MUIC_MAX8997) += muic_max8997.o
|
||||
obj-$(CONFIG_POWER_MAX77686) += pmic_max77686.o
|
||||
obj-$(CONFIG_POWER_PFUZE100) += pmic_pfuze100.o
|
||||
obj-$(CONFIG_POWER_PFUZE3000) += pmic_pfuze3000.o
|
||||
obj-$(CONFIG_POWER_TPS65217) += pmic_tps65217.o
|
||||
obj-$(CONFIG_POWER_TPS65218) += pmic_tps62362.o
|
||||
obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o
|
||||
obj-$(CONFIG_POWER_TPS65910) += pmic_tps65910.o
|
||||
obj-$(CONFIG_POWER_HI6553) += pmic_hi6553.o
|
||||
90
u-boot/drivers/power/pmic/act8846.c
Normal file
90
u-boot/drivers/power/pmic/act8846.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <libfdt.h>
|
||||
#include <power/act8846_pmic.h>
|
||||
#include <power/pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = "REG", .driver = "act8846_reg"},
|
||||
{ },
|
||||
};
|
||||
|
||||
static int act8846_reg_count(struct udevice *dev)
|
||||
{
|
||||
return ACT8846_NUM_OF_REGS;
|
||||
}
|
||||
|
||||
static int act8846_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
debug("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int act8846_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_read(dev, reg, buff, len)) {
|
||||
debug("read error from device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int act8846_bind(struct udevice *dev)
|
||||
{
|
||||
const void *blob = gd->fdt_blob;
|
||||
int regulators_node;
|
||||
int children;
|
||||
|
||||
regulators_node = fdt_subnode_offset(blob, dev->of_offset,
|
||||
"regulators");
|
||||
if (regulators_node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops act8846_ops = {
|
||||
.reg_count = act8846_reg_count,
|
||||
.read = act8846_read,
|
||||
.write = act8846_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id act8846_ids[] = {
|
||||
{ .compatible = "active-semi,act8846" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_act8846) = {
|
||||
.name = "act8846 pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = act8846_ids,
|
||||
.bind = act8846_bind,
|
||||
.ops = &act8846_ops,
|
||||
};
|
||||
142
u-boot/drivers/power/pmic/i2c_pmic_emul.c
Normal file
142
u-boot/drivers/power/pmic/i2c_pmic_emul.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/sandbox_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* struct sandbox_i2c_pmic_plat_data - platform data for the PMIC
|
||||
*
|
||||
* @rw_reg: PMICs register of the chip I/O transaction
|
||||
* @reg: PMICs registers array
|
||||
*/
|
||||
struct sandbox_i2c_pmic_plat_data {
|
||||
u8 rw_reg;
|
||||
u8 reg[SANDBOX_PMIC_REG_COUNT];
|
||||
};
|
||||
|
||||
static int sandbox_i2c_pmic_read_data(struct udevice *emul, uchar chip,
|
||||
uchar *buffer, int len)
|
||||
{
|
||||
struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul);
|
||||
|
||||
if (plat->rw_reg + len > SANDBOX_PMIC_REG_COUNT) {
|
||||
error("Request exceeds PMIC register range! Max register: %#x",
|
||||
SANDBOX_PMIC_REG_COUNT);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
debug("Read PMIC: %#x at register: %#x count: %d\n",
|
||||
(unsigned)chip & 0xff, plat->rw_reg, len);
|
||||
|
||||
memcpy(buffer, &plat->reg[plat->rw_reg], len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_pmic_write_data(struct udevice *emul, uchar chip,
|
||||
uchar *buffer, int len,
|
||||
bool next_is_read)
|
||||
{
|
||||
struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul);
|
||||
|
||||
/* Probe only */
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
/* Set PMIC register for I/O */
|
||||
plat->rw_reg = *buffer;
|
||||
|
||||
debug("Write PMIC: %#x at register: %#x count: %d\n",
|
||||
(unsigned)chip & 0xff, plat->rw_reg, len);
|
||||
|
||||
/* For read operation, set (write) only chip reg */
|
||||
if (next_is_read)
|
||||
return 0;
|
||||
|
||||
buffer++;
|
||||
len--;
|
||||
|
||||
if (plat->rw_reg + len > SANDBOX_PMIC_REG_COUNT) {
|
||||
error("Request exceeds PMIC register range! Max register: %#x",
|
||||
SANDBOX_PMIC_REG_COUNT);
|
||||
}
|
||||
|
||||
memcpy(&plat->reg[plat->rw_reg], buffer, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_pmic_xfer(struct udevice *emul, struct i2c_msg *msg,
|
||||
int nmsgs)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
for (; nmsgs > 0; nmsgs--, msg++) {
|
||||
bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
ret = sandbox_i2c_pmic_read_data(emul, msg->addr,
|
||||
msg->buf, msg->len);
|
||||
} else {
|
||||
ret = sandbox_i2c_pmic_write_data(emul, msg->addr,
|
||||
msg->buf, msg->len,
|
||||
next_is_read);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_pmic_ofdata_to_platdata(struct udevice *emul)
|
||||
{
|
||||
struct sandbox_i2c_pmic_plat_data *plat = dev_get_platdata(emul);
|
||||
const u8 *reg_defaults;
|
||||
|
||||
debug("%s:%d Setting PMIC default registers\n", __func__, __LINE__);
|
||||
|
||||
reg_defaults = fdtdec_locate_byte_array(gd->fdt_blob, emul->of_offset,
|
||||
"reg-defaults",
|
||||
SANDBOX_PMIC_REG_COUNT);
|
||||
|
||||
if (!reg_defaults) {
|
||||
error("Property \"reg-defaults\" not found for device: %s!",
|
||||
emul->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&plat->reg, reg_defaults, SANDBOX_PMIC_REG_COUNT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dm_i2c_ops sandbox_i2c_pmic_emul_ops = {
|
||||
.xfer = sandbox_i2c_pmic_xfer,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_i2c_pmic_ids[] = {
|
||||
{ .compatible = "sandbox,i2c-pmic" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_i2c_pmic_emul) = {
|
||||
.name = "sandbox_i2c_pmic_emul",
|
||||
.id = UCLASS_I2C_EMUL,
|
||||
.of_match = sandbox_i2c_pmic_ids,
|
||||
.ofdata_to_platdata = sandbox_i2c_pmic_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct sandbox_i2c_pmic_plat_data),
|
||||
.ops = &sandbox_i2c_pmic_emul_ops,
|
||||
};
|
||||
92
u-boot/drivers/power/pmic/max77686.c
Normal file
92
u-boot/drivers/power/pmic/max77686.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include <power/max77686_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = "LDO", .driver = MAX77686_LDO_DRIVER },
|
||||
{ .prefix = "BUCK", .driver = MAX77686_BUCK_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int max77686_reg_count(struct udevice *dev)
|
||||
{
|
||||
return MAX77686_NUM_OF_REGS;
|
||||
}
|
||||
|
||||
static int max77686_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77686_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_read(dev, reg, buff, len)) {
|
||||
error("read error from device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77686_bind(struct udevice *dev)
|
||||
{
|
||||
int regulators_node;
|
||||
const void *blob = gd->fdt_blob;
|
||||
int children;
|
||||
|
||||
regulators_node = fdt_subnode_offset(blob, dev->of_offset,
|
||||
"voltage-regulators");
|
||||
if (regulators_node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops max77686_ops = {
|
||||
.reg_count = max77686_reg_count,
|
||||
.read = max77686_read,
|
||||
.write = max77686_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id max77686_ids[] = {
|
||||
{ .compatible = "maxim,max77686" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_max77686) = {
|
||||
.name = "max77686_pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = max77686_ids,
|
||||
.bind = max77686_bind,
|
||||
.ops = &max77686_ops,
|
||||
};
|
||||
74
u-boot/drivers/power/pmic/muic_max8997.c
Normal file
74
u-boot/drivers/power/pmic/muic_max8997.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Lukasz Majewski <l.majewski@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/power_chrg.h>
|
||||
#include <power/max8997_muic.h>
|
||||
#include <i2c.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int power_chrg_get_type(struct pmic *p)
|
||||
{
|
||||
unsigned int val;
|
||||
unsigned char charge_type, charger;
|
||||
|
||||
if (pmic_probe(p))
|
||||
return CHARGER_NO;
|
||||
|
||||
pmic_reg_read(p, MAX8997_MUIC_STATUS2, &val);
|
||||
charge_type = val & MAX8997_MUIC_CHG_MASK;
|
||||
|
||||
switch (charge_type) {
|
||||
case MAX8997_MUIC_CHG_NO:
|
||||
charger = CHARGER_NO;
|
||||
break;
|
||||
case MAX8997_MUIC_CHG_USB:
|
||||
case MAX8997_MUIC_CHG_USB_D:
|
||||
charger = CHARGER_USB;
|
||||
break;
|
||||
case MAX8997_MUIC_CHG_TA:
|
||||
case MAX8997_MUIC_CHG_TA_1A:
|
||||
charger = CHARGER_TA;
|
||||
break;
|
||||
case MAX8997_MUIC_CHG_TA_500:
|
||||
charger = CHARGER_TA_500;
|
||||
break;
|
||||
default:
|
||||
charger = CHARGER_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return charger;
|
||||
}
|
||||
|
||||
static struct power_chrg power_chrg_muic_ops = {
|
||||
.chrg_type = power_chrg_get_type,
|
||||
};
|
||||
|
||||
int power_muic_init(unsigned int bus)
|
||||
{
|
||||
static const char name[] = "MAX8997_MUIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debug("Board Micro USB Interface Controller init\n");
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = MUIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = MAX8997_MUIC_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
p->chrg = &power_chrg_muic_ops;
|
||||
return 0;
|
||||
}
|
||||
96
u-boot/drivers/power/pmic/pfuze100.c
Normal file
96
u-boot/drivers/power/pmic/pfuze100.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freescale Semiconductor, Inc
|
||||
* Peng Fan <Peng.Fan@freescale.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include <power/pfuze100_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
/* sw[x], swbst */
|
||||
{ .prefix = "s", .driver = PFUZE100_REGULATOR_DRIVER },
|
||||
/* vgen[x], vsnvs, vcc, v33, vcc_sd */
|
||||
{ .prefix = "v", .driver = PFUZE100_REGULATOR_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int pfuze100_reg_count(struct udevice *dev)
|
||||
{
|
||||
return PFUZE100_NUM_OF_REGS;
|
||||
}
|
||||
|
||||
static int pfuze100_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pfuze100_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_read(dev, reg, buff, len)) {
|
||||
error("read error from device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pfuze100_bind(struct udevice *dev)
|
||||
{
|
||||
int children;
|
||||
int regulators_node;
|
||||
const void *blob = gd->fdt_blob;
|
||||
|
||||
regulators_node = fdt_subnode_offset(blob, dev->of_offset,
|
||||
"regulators");
|
||||
if (regulators_node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops pfuze100_ops = {
|
||||
.reg_count = pfuze100_reg_count,
|
||||
.read = pfuze100_read,
|
||||
.write = pfuze100_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id pfuze100_ids[] = {
|
||||
{ .compatible = "fsl,pfuze100", .data = PFUZE100, },
|
||||
{ .compatible = "fsl,pfuze200", .data = PFUZE200, },
|
||||
{ .compatible = "fsl,pfuze3000", .data = PFUZE3000, },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_pfuze100) = {
|
||||
.name = "pfuze100 pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = pfuze100_ids,
|
||||
.bind = pfuze100_bind,
|
||||
.ops = &pfuze100_ops,
|
||||
};
|
||||
96
u-boot/drivers/power/pmic/pm8916.c
Normal file
96
u-boot/drivers/power/pmic/pm8916.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Qualcomm pm8916 pmic driver
|
||||
*
|
||||
* (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dm/root.h>
|
||||
#include <power/pmic.h>
|
||||
#include <spmi/spmi.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define PID_SHIFT 8
|
||||
#define PID_MASK (0xFF << PID_SHIFT)
|
||||
#define REG_MASK 0xFF
|
||||
|
||||
struct pm8916_priv {
|
||||
uint32_t usid; /* Slave ID on SPMI bus */
|
||||
};
|
||||
|
||||
static int pm8916_reg_count(struct udevice *dev)
|
||||
{
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
struct pm8916_priv *priv = dev_get_priv(dev);
|
||||
|
||||
if (len != 1)
|
||||
return -EINVAL;
|
||||
|
||||
return spmi_reg_write(dev->parent, priv->usid,
|
||||
(reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK,
|
||||
*buff);
|
||||
}
|
||||
|
||||
static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
struct pm8916_priv *priv = dev_get_priv(dev);
|
||||
int val;
|
||||
|
||||
if (len != 1)
|
||||
return -EINVAL;
|
||||
|
||||
val = spmi_reg_read(dev->parent, priv->usid,
|
||||
(reg & PID_MASK) >> PID_SHIFT, reg & REG_MASK);
|
||||
|
||||
if (val < 0)
|
||||
return val;
|
||||
*buff = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops pm8916_ops = {
|
||||
.reg_count = pm8916_reg_count,
|
||||
.read = pm8916_read,
|
||||
.write = pm8916_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id pm8916_ids[] = {
|
||||
{ .compatible = "qcom,spmi-pmic" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int pm8916_probe(struct udevice *dev)
|
||||
{
|
||||
struct pm8916_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->usid = dev_get_addr(dev);
|
||||
|
||||
if (priv->usid == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int pm8916_bind(struct udevice *dev)
|
||||
{
|
||||
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(pmic_pm8916) = {
|
||||
.name = "pmic_pm8916",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = pm8916_ids,
|
||||
.bind = pm8916_bind,
|
||||
.probe = pm8916_probe,
|
||||
.ops = &pm8916_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct pm8916_priv),
|
||||
};
|
||||
171
u-boot/drivers/power/pmic/pmic-uclass.c
Normal file
171
u-boot/drivers/power/pmic/pmic-uclass.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <vsprintf.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <power/pmic.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
|
||||
int pmic_bind_children(struct udevice *pmic, int offset,
|
||||
const struct pmic_child_info *child_info)
|
||||
{
|
||||
const struct pmic_child_info *info;
|
||||
const void *blob = gd->fdt_blob;
|
||||
struct driver *drv;
|
||||
struct udevice *child;
|
||||
const char *node_name;
|
||||
int bind_count = 0;
|
||||
int node;
|
||||
int prefix_len;
|
||||
int ret;
|
||||
|
||||
debug("%s for '%s' at node offset: %d\n", __func__, pmic->name,
|
||||
pmic->of_offset);
|
||||
|
||||
for (node = fdt_first_subnode(blob, offset);
|
||||
node > 0;
|
||||
node = fdt_next_subnode(blob, node)) {
|
||||
node_name = fdt_get_name(blob, node, NULL);
|
||||
|
||||
debug("* Found child node: '%s' at offset:%d\n", node_name,
|
||||
node);
|
||||
|
||||
child = NULL;
|
||||
for (info = child_info; info->prefix && info->driver; info++) {
|
||||
debug(" - compatible prefix: '%s'\n", info->prefix);
|
||||
|
||||
prefix_len = strlen(info->prefix);
|
||||
if (strncmp(info->prefix, node_name, prefix_len))
|
||||
continue;
|
||||
|
||||
drv = lists_driver_lookup_name(info->driver);
|
||||
if (!drv) {
|
||||
debug(" - driver: '%s' not found!\n",
|
||||
info->driver);
|
||||
continue;
|
||||
}
|
||||
|
||||
debug(" - found child driver: '%s'\n", drv->name);
|
||||
|
||||
ret = device_bind(pmic, drv, node_name, NULL,
|
||||
node, &child);
|
||||
if (ret) {
|
||||
debug(" - child binding error: %d\n", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
debug(" - bound child device: '%s'\n", child->name);
|
||||
|
||||
child->driver_data = trailing_strtol(node_name);
|
||||
|
||||
debug(" - set 'child->driver_data': %lu\n",
|
||||
child->driver_data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (child)
|
||||
bind_count++;
|
||||
else
|
||||
debug(" - compatible prefix not found\n");
|
||||
}
|
||||
|
||||
debug("Bound: %d childs for PMIC: '%s'\n", bind_count, pmic->name);
|
||||
return bind_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
int pmic_get(const char *name, struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_name(UCLASS_PMIC, name, devp);
|
||||
}
|
||||
|
||||
int pmic_reg_count(struct udevice *dev)
|
||||
{
|
||||
const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!ops || !ops->reg_count)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->reg_count(dev);
|
||||
}
|
||||
|
||||
int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len)
|
||||
{
|
||||
const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!buffer)
|
||||
return -EFAULT;
|
||||
|
||||
if (!ops || !ops->read)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->read(dev, reg, buffer, len);
|
||||
}
|
||||
|
||||
int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len)
|
||||
{
|
||||
const struct dm_pmic_ops *ops = dev_get_driver_ops(dev);
|
||||
|
||||
if (!buffer)
|
||||
return -EFAULT;
|
||||
|
||||
if (!ops || !ops->write)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->write(dev, reg, buffer, len);
|
||||
}
|
||||
|
||||
int pmic_reg_read(struct udevice *dev, uint reg)
|
||||
{
|
||||
u8 byte;
|
||||
int ret;
|
||||
|
||||
debug("%s: reg=%x", __func__, reg);
|
||||
ret = pmic_read(dev, reg, &byte, 1);
|
||||
debug(", value=%x, ret=%d\n", byte, ret);
|
||||
|
||||
return ret ? ret : byte;
|
||||
}
|
||||
|
||||
int pmic_reg_write(struct udevice *dev, uint reg, uint value)
|
||||
{
|
||||
u8 byte = value;
|
||||
int ret;
|
||||
|
||||
debug("%s: reg=%x, value=%x", __func__, reg, value);
|
||||
ret = pmic_write(dev, reg, &byte, 1);
|
||||
debug(", ret=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
|
||||
{
|
||||
u8 byte;
|
||||
int ret;
|
||||
|
||||
ret = pmic_reg_read(dev, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
byte = (ret & ~clr) | set;
|
||||
|
||||
return pmic_reg_write(dev, reg, byte);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(pmic) = {
|
||||
.id = UCLASS_PMIC,
|
||||
.name = "pmic",
|
||||
};
|
||||
133
u-boot/drivers/power/pmic/pmic_hi6553.c
Normal file
133
u-boot/drivers/power/pmic/pmic_hi6553.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Linaro
|
||||
* Peter Griffin <peter.griffin@linaro.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <asm/io.h>
|
||||
#include <common.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/max8997_muic.h>
|
||||
#include <power/hi6553_pmic.h>
|
||||
#include <errno.h>
|
||||
|
||||
u8 *pmussi_base;
|
||||
|
||||
uint8_t hi6553_readb(u32 offset)
|
||||
{
|
||||
return readb(pmussi_base + (offset << 2));
|
||||
}
|
||||
|
||||
void hi6553_writeb(u32 offset, uint8_t value)
|
||||
{
|
||||
writeb(value, pmussi_base + (offset << 2));
|
||||
}
|
||||
|
||||
int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
|
||||
{
|
||||
if (check_reg(p, reg))
|
||||
return -1;
|
||||
|
||||
hi6553_writeb(reg, (uint8_t)val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
|
||||
{
|
||||
if (check_reg(p, reg))
|
||||
return -1;
|
||||
|
||||
*val = (u32)hi6553_readb(reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hi6553_init(void)
|
||||
{
|
||||
int data;
|
||||
|
||||
hi6553_writeb(HI6553_PERI_EN_MARK, 0x1e);
|
||||
hi6553_writeb(HI6553_NP_REG_ADJ1, 0);
|
||||
data = HI6553_DISABLE6_XO_CLK_CONN | HI6553_DISABLE6_XO_CLK_NFC |
|
||||
HI6553_DISABLE6_XO_CLK_RF1 | HI6553_DISABLE6_XO_CLK_RF2;
|
||||
hi6553_writeb(HI6553_DISABLE6_XO_CLK, data);
|
||||
|
||||
/* configure BUCK0 & BUCK1 */
|
||||
hi6553_writeb(HI6553_BUCK01_CTRL2, 0x5e);
|
||||
hi6553_writeb(HI6553_BUCK0_CTRL7, 0x10);
|
||||
hi6553_writeb(HI6553_BUCK1_CTRL7, 0x10);
|
||||
hi6553_writeb(HI6553_BUCK0_CTRL5, 0x1e);
|
||||
hi6553_writeb(HI6553_BUCK1_CTRL5, 0x1e);
|
||||
hi6553_writeb(HI6553_BUCK0_CTRL1, 0xfc);
|
||||
hi6553_writeb(HI6553_BUCK1_CTRL1, 0xfc);
|
||||
|
||||
/* configure BUCK2 */
|
||||
hi6553_writeb(HI6553_BUCK2_REG1, 0x4f);
|
||||
hi6553_writeb(HI6553_BUCK2_REG5, 0x99);
|
||||
hi6553_writeb(HI6553_BUCK2_REG6, 0x45);
|
||||
mdelay(1);
|
||||
hi6553_writeb(HI6553_VSET_BUCK2_ADJ, 0x22);
|
||||
mdelay(1);
|
||||
|
||||
/* configure BUCK3 */
|
||||
hi6553_writeb(HI6553_BUCK3_REG3, 0x02);
|
||||
hi6553_writeb(HI6553_BUCK3_REG5, 0x99);
|
||||
hi6553_writeb(HI6553_BUCK3_REG6, 0x41);
|
||||
hi6553_writeb(HI6553_VSET_BUCK3_ADJ, 0x02);
|
||||
mdelay(1);
|
||||
|
||||
/* configure BUCK4 */
|
||||
hi6553_writeb(HI6553_BUCK4_REG2, 0x9a);
|
||||
hi6553_writeb(HI6553_BUCK4_REG5, 0x99);
|
||||
hi6553_writeb(HI6553_BUCK4_REG6, 0x45);
|
||||
|
||||
/* configure LDO20 */
|
||||
hi6553_writeb(HI6553_LDO20_REG_ADJ, 0x50);
|
||||
|
||||
hi6553_writeb(HI6553_NP_REG_CHG, 0x0f);
|
||||
hi6553_writeb(HI6553_CLK_TOP0, 0x06);
|
||||
hi6553_writeb(HI6553_CLK_TOP3, 0xc0);
|
||||
hi6553_writeb(HI6553_CLK_TOP4, 0x00);
|
||||
|
||||
/* configure LDO7 & LDO10 for SD slot */
|
||||
data = hi6553_readb(HI6553_LDO7_REG_ADJ);
|
||||
data = (data & 0xf8) | 0x2;
|
||||
hi6553_writeb(HI6553_LDO7_REG_ADJ, data);
|
||||
mdelay(5);
|
||||
/* enable LDO7 */
|
||||
hi6553_writeb(HI6553_ENABLE2_LDO1_8, 1 << 6);
|
||||
mdelay(5);
|
||||
data = hi6553_readb(HI6553_LDO10_REG_ADJ);
|
||||
data = (data & 0xf8) | 0x5;
|
||||
hi6553_writeb(HI6553_LDO10_REG_ADJ, data);
|
||||
mdelay(5);
|
||||
/* enable LDO10 */
|
||||
hi6553_writeb(HI6553_ENABLE3_LDO9_16, 1 << 1);
|
||||
mdelay(5);
|
||||
|
||||
/* select 32.764KHz */
|
||||
hi6553_writeb(HI6553_CLK19M2_600_586_EN, 0x01);
|
||||
}
|
||||
|
||||
int power_hi6553_init(u8 *base)
|
||||
{
|
||||
static const char name[] = "HI6553 PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_NONE;
|
||||
p->number_of_regs = 44;
|
||||
pmussi_base = base;
|
||||
|
||||
hi6553_init();
|
||||
|
||||
puts("HI6553 PMIC init\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
u-boot/drivers/power/pmic/pmic_ltc3676.c
Normal file
32
u-boot/drivers/power/pmic/pmic_ltc3676.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Gateworks Corporation
|
||||
* Tim Harvey <tharvey@gateworks.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/ltc3676_pmic.h>
|
||||
|
||||
int power_ltc3676_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "LTC3676_PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = LTC3676_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = CONFIG_POWER_LTC3676_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
304
u-boot/drivers/power/pmic/pmic_max77686.c
Normal file
304
u-boot/drivers/power/pmic/pmic_max77686.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Rajeshwari Shinde <rajeshwari.s@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/max77686_pmic.h>
|
||||
#include <errno.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const char max77686_buck_addr[] = {
|
||||
0xff, 0x10, 0x12, 0x1c, 0x26, 0x30, 0x32, 0x34, 0x36, 0x38
|
||||
};
|
||||
|
||||
static unsigned int max77686_ldo_volt2hex(int ldo, ulong uV)
|
||||
{
|
||||
unsigned int hex = 0;
|
||||
|
||||
switch (ldo) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 15:
|
||||
hex = (uV - 800000) / 25000;
|
||||
break;
|
||||
default:
|
||||
hex = (uV - 800000) / 50000;
|
||||
}
|
||||
|
||||
if (hex >= 0 && hex <= MAX77686_LDO_VOLT_MAX_HEX)
|
||||
return hex;
|
||||
|
||||
debug("%s: %ld is wrong voltage value for LDO%d\n", __func__, uV, ldo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77686_buck_volt2hex(int buck, ulong uV)
|
||||
{
|
||||
int hex = 0;
|
||||
|
||||
if (buck < 5 || buck > 9) {
|
||||
debug("%s: buck %d is not supported\n", __func__, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hex = (uV - 750000) / 50000;
|
||||
|
||||
if (hex >= 0 && hex <= MAX77686_BUCK_VOLT_MAX_HEX)
|
||||
return hex;
|
||||
|
||||
debug("%s: %ld is wrong voltage value for BUCK%d\n",
|
||||
__func__, uV, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int max77686_set_ldo_voltage(struct pmic *p, int ldo, ulong uV)
|
||||
{
|
||||
unsigned int val, ret, hex, adr;
|
||||
|
||||
if (ldo < 1 || ldo > 26) {
|
||||
printf("%s: %d is wrong ldo number\n", __func__, ldo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
|
||||
hex = max77686_ldo_volt2hex(ldo, uV);
|
||||
|
||||
if (!hex)
|
||||
return -1;
|
||||
|
||||
ret = pmic_reg_read(p, adr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val &= ~MAX77686_LDO_VOLT_MASK;
|
||||
val |= hex;
|
||||
ret |= pmic_reg_write(p, adr, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int max77686_set_buck_voltage(struct pmic *p, int buck, ulong uV)
|
||||
{
|
||||
unsigned int val, adr;
|
||||
int hex, ret;
|
||||
|
||||
if (buck < 5 || buck > 9) {
|
||||
printf("%s: %d is an unsupported bucket number\n",
|
||||
__func__, buck);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adr = max77686_buck_addr[buck] + 1;
|
||||
hex = max77686_buck_volt2hex(buck, uV);
|
||||
|
||||
if (hex < 0)
|
||||
return hex;
|
||||
|
||||
ret = pmic_reg_read(p, adr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val &= ~MAX77686_BUCK_VOLT_MASK;
|
||||
ret |= pmic_reg_write(p, adr, val | hex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode)
|
||||
{
|
||||
unsigned int val, ret, adr, mode;
|
||||
|
||||
if (ldo < 1 || 26 < ldo) {
|
||||
printf("%s: %d is wrong ldo number\n", __func__, ldo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1;
|
||||
|
||||
/* mode */
|
||||
switch (opmode) {
|
||||
case OPMODE_OFF:
|
||||
mode = MAX77686_LDO_MODE_OFF;
|
||||
break;
|
||||
case OPMODE_STANDBY:
|
||||
switch (ldo) {
|
||||
case 2:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 14:
|
||||
case 15:
|
||||
case 16:
|
||||
mode = MAX77686_LDO_MODE_STANDBY;
|
||||
break;
|
||||
default:
|
||||
mode = 0xff;
|
||||
}
|
||||
break;
|
||||
case OPMODE_LPM:
|
||||
mode = MAX77686_LDO_MODE_LPM;
|
||||
break;
|
||||
case OPMODE_ON:
|
||||
mode = MAX77686_LDO_MODE_ON;
|
||||
break;
|
||||
default:
|
||||
mode = 0xff;
|
||||
}
|
||||
|
||||
if (mode == 0xff) {
|
||||
printf("%s: %d is not supported on LDO%d\n",
|
||||
__func__, opmode, ldo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pmic_reg_read(p, adr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val &= ~MAX77686_LDO_MODE_MASK;
|
||||
val |= mode;
|
||||
ret |= pmic_reg_write(p, adr, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int max77686_set_buck_mode(struct pmic *p, int buck, char opmode)
|
||||
{
|
||||
unsigned int val, ret, mask, adr, size, mode, mode_shift;
|
||||
|
||||
size = ARRAY_SIZE(max77686_buck_addr);
|
||||
if (buck >= size) {
|
||||
printf("%s: %d is wrong buck number\n", __func__, buck);
|
||||
return -1;
|
||||
}
|
||||
|
||||
adr = max77686_buck_addr[buck];
|
||||
|
||||
/* mask */
|
||||
switch (buck) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
mode_shift = MAX77686_BUCK_MODE_SHIFT_2;
|
||||
break;
|
||||
default:
|
||||
mode_shift = MAX77686_BUCK_MODE_SHIFT_1;
|
||||
}
|
||||
|
||||
mask = MAX77686_BUCK_MODE_MASK << mode_shift;
|
||||
|
||||
/* mode */
|
||||
switch (opmode) {
|
||||
case OPMODE_OFF:
|
||||
mode = MAX77686_BUCK_MODE_OFF << mode_shift;
|
||||
break;
|
||||
case OPMODE_STANDBY:
|
||||
switch (buck) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
mode = MAX77686_BUCK_MODE_STANDBY << mode_shift;
|
||||
break;
|
||||
default:
|
||||
mode = 0xff;
|
||||
}
|
||||
break;
|
||||
case OPMODE_LPM:
|
||||
switch (buck) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
mode = MAX77686_BUCK_MODE_LPM << mode_shift;
|
||||
break;
|
||||
default:
|
||||
mode = 0xff;
|
||||
}
|
||||
break;
|
||||
case OPMODE_ON:
|
||||
mode = MAX77686_BUCK_MODE_ON << mode_shift;
|
||||
break;
|
||||
default:
|
||||
mode = 0xff;
|
||||
}
|
||||
|
||||
if (mode == 0xff) {
|
||||
printf("%s: %d is not supported on BUCK%d\n",
|
||||
__func__, opmode, buck);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = pmic_reg_read(p, adr, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val &= ~mask;
|
||||
val |= mode;
|
||||
ret |= pmic_reg_write(p, adr, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pmic_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "MAX77686_PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
const void *blob = gd->fdt_blob;
|
||||
int node, parent, tmp;
|
||||
#endif
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_MAX77686_PMIC);
|
||||
if (node < 0) {
|
||||
debug("PMIC: No node for PMIC Chip in device tree\n");
|
||||
debug("node = %d\n", node);
|
||||
return -1;
|
||||
}
|
||||
|
||||
parent = fdt_parent_offset(blob, node);
|
||||
if (parent < 0) {
|
||||
debug("%s: Cannot find node parent\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* tmp since p->bus is unsigned */
|
||||
tmp = i2c_get_bus_num_fdt(parent);
|
||||
if (tmp < 0) {
|
||||
debug("%s: Cannot find I2C bus\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
p->bus = tmp;
|
||||
p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9);
|
||||
#else
|
||||
p->bus = bus;
|
||||
p->hw.i2c.addr = MAX77686_I2C_ADDR;
|
||||
#endif
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = MAX77686_NUM_OF_REGS;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
|
||||
puts("Board PMIC init\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
u-boot/drivers/power/pmic/pmic_max77696.c
Normal file
32
u-boot/drivers/power/pmic/pmic_max77696.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
* Fabio Estevam <fabio.estevam@freescale.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/max77696_pmic.h>
|
||||
|
||||
int power_max77696_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "MAX77696";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = PMIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = CONFIG_POWER_MAX77696_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
107
u-boot/drivers/power/pmic/pmic_max8997.c
Normal file
107
u-boot/drivers/power/pmic/pmic_max8997.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Samsung Electronics
|
||||
* Lukasz Majewski <l.majewski@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/max8997_pmic.h>
|
||||
#include <i2c.h>
|
||||
#include <errno.h>
|
||||
|
||||
unsigned char max8997_reg_ldo(int uV)
|
||||
{
|
||||
unsigned char ret;
|
||||
if (uV <= 800000)
|
||||
return 0;
|
||||
if (uV >= 3950000)
|
||||
return MAX8997_LDO_MAX_VAL;
|
||||
ret = (uV - 800000) / 50000;
|
||||
if (ret > MAX8997_LDO_MAX_VAL) {
|
||||
printf("MAX8997 LDO SETTING ERROR (%duV) -> %u\n", uV, ret);
|
||||
ret = MAX8997_LDO_MAX_VAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pmic_charger_state(struct pmic *p, int state, int current)
|
||||
{
|
||||
unsigned char fc;
|
||||
u32 val = 0;
|
||||
|
||||
if (pmic_probe(p))
|
||||
return -1;
|
||||
|
||||
if (state == PMIC_CHARGER_DISABLE) {
|
||||
puts("Disable the charger.\n");
|
||||
pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
|
||||
val &= ~(MBCHOSTEN | VCHGR_FC);
|
||||
pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) {
|
||||
printf("%s: Wrong charge current: %d [mA]\n",
|
||||
__func__, current);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fc = (current - CHARGER_MIN_CURRENT) / CHARGER_CURRENT_RESOLUTION;
|
||||
fc = fc & 0xf; /* up to 950 mA */
|
||||
|
||||
printf("Enable the charger @ %d [mA]\n", fc * CHARGER_CURRENT_RESOLUTION
|
||||
+ CHARGER_MIN_CURRENT);
|
||||
|
||||
val = fc | MBCICHFCSET;
|
||||
pmic_reg_write(p, MAX8997_REG_MBCCTRL4, val);
|
||||
|
||||
pmic_reg_read(p, MAX8997_REG_MBCCTRL2, &val);
|
||||
val = MBCHOSTEN | VCHGR_FC; /* enable charger & fast charge */
|
||||
pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pmic_charger_bat_present(struct pmic *p)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (pmic_probe(p))
|
||||
return -1;
|
||||
|
||||
pmic_reg_read(p, MAX8997_REG_STATUS4, &val);
|
||||
|
||||
return !(val & DETBAT);
|
||||
}
|
||||
|
||||
static struct power_chrg power_chrg_pmic_ops = {
|
||||
.chrg_bat_present = pmic_charger_bat_present,
|
||||
.chrg_state = pmic_charger_state,
|
||||
};
|
||||
|
||||
int pmic_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "MAX8997_PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debug("Board PMIC init\n");
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = PMIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = MAX8997_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
p->chrg = &power_chrg_pmic_ops;
|
||||
return 0;
|
||||
}
|
||||
33
u-boot/drivers/power/pmic/pmic_max8998.c
Normal file
33
u-boot/drivers/power/pmic/pmic_max8998.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Samsung Electronics
|
||||
* Lukasz Majewski <l.majewski@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/max8998_pmic.h>
|
||||
#include <errno.h>
|
||||
|
||||
int pmic_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "MAX8998_PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
puts("Board PMIC init\n");
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = PMIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = MAX8998_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
u-boot/drivers/power/pmic/pmic_pfuze100.c
Normal file
32
u-boot/drivers/power/pmic/pmic_pfuze100.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Gateworks Corporation
|
||||
* Tim Harvey <tharvey@gateworks.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/pfuze100_pmic.h>
|
||||
|
||||
int power_pfuze100_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "PFUZE100";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = PFUZE100_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = CONFIG_POWER_PFUZE100_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
32
u-boot/drivers/power/pmic/pmic_pfuze3000.c
Normal file
32
u-boot/drivers/power/pmic/pmic_pfuze3000.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freescale Semiconductor, Inc.
|
||||
* Peng Fan <Peng.Fan@freescale.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/pfuze3000_pmic.h>
|
||||
|
||||
int power_pfuze3000_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "PFUZE3000";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = PMIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = CONFIG_POWER_PFUZE3000_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
u-boot/drivers/power/pmic/pmic_tps62362.c
Normal file
47
u-boot/drivers/power/pmic/pmic_tps62362.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* (C) Copyright 2014 Texas Instruments Incorporated - http://www.ti.com
|
||||
* Author: Felipe Balbi <balbi@ti.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/errno.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/tps62362.h>
|
||||
|
||||
/**
|
||||
* tps62362_voltage_update() - Function to change a voltage level, as this
|
||||
* is a multi-step process.
|
||||
* @reg: Register address to write to
|
||||
* @volt_sel: Voltage register value to write
|
||||
* @return: 0 on success, 1 on failure
|
||||
*/
|
||||
int tps62362_voltage_update(unsigned char reg, unsigned char volt_sel)
|
||||
{
|
||||
if (reg > TPS62362_NUM_REGS)
|
||||
return 1;
|
||||
|
||||
return i2c_write(TPS62362_I2C_ADDR, reg, 1, &volt_sel, 1);
|
||||
}
|
||||
|
||||
int power_tps62362_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "TPS62362";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = TPS62362_NUM_REGS;
|
||||
p->hw.i2c.addr = TPS62362_I2C_ADDR;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
109
u-boot/drivers/power/pmic/pmic_tps65217.c
Normal file
109
u-boot/drivers/power/pmic/pmic_tps65217.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* (C) Copyright 2011-2013
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <power/tps65217.h>
|
||||
|
||||
/**
|
||||
* tps65217_reg_read() - Generic function that can read a TPS65217 register
|
||||
* @src_reg: Source register address
|
||||
* @src_val: Address of destination variable
|
||||
* @return: 0 for success, not 0 on failure.
|
||||
*/
|
||||
int tps65217_reg_read(uchar src_reg, uchar *src_val)
|
||||
{
|
||||
return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
|
||||
* register or bit field regardless of protection
|
||||
* level.
|
||||
*
|
||||
* @prot_level: Register password protection. Use
|
||||
* TPS65217_PROT_LEVEL_NONE,
|
||||
* TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
|
||||
* @dest_reg: Register address to write.
|
||||
* @dest_val: Value to write.
|
||||
* @mask: Bit mask (8 bits) to be applied. Function will only
|
||||
* change bits that are set in the bit mask.
|
||||
*
|
||||
* @return: 0 for success, not 0 on failure, as per the i2c API
|
||||
*/
|
||||
int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
uchar mask)
|
||||
{
|
||||
uchar read_val;
|
||||
uchar xor_reg;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If we are affecting only a bit field, read dest_reg and apply the
|
||||
* mask
|
||||
*/
|
||||
if (mask != TPS65217_MASK_ALL_BITS) {
|
||||
ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
read_val &= (~mask);
|
||||
read_val |= (dest_val & mask);
|
||||
dest_val = read_val;
|
||||
}
|
||||
|
||||
if (prot_level > 0) {
|
||||
xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
|
||||
ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (prot_level == TPS65217_PROT_LEVEL_2) {
|
||||
ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65217_voltage_update() - Function to change a voltage level, as this
|
||||
* is a multi-step process.
|
||||
* @dc_cntrl_reg: DC voltage control register to change.
|
||||
* @volt_sel: New value for the voltage register
|
||||
* @return: 0 for success, not 0 on failure.
|
||||
*/
|
||||
int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
|
||||
{
|
||||
if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
|
||||
(dc_cntrl_reg != TPS65217_DEFDCDC2) &&
|
||||
(dc_cntrl_reg != TPS65217_DEFDCDC3))
|
||||
return 1;
|
||||
|
||||
/* set voltage level */
|
||||
if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
|
||||
TPS65217_MASK_ALL_BITS))
|
||||
return 1;
|
||||
|
||||
/* set GO bit to initiate voltage transition */
|
||||
if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
|
||||
TPS65217_DCDC_GO, TPS65217_DCDC_GO))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
175
u-boot/drivers/power/pmic/pmic_tps65218.c
Normal file
175
u-boot/drivers/power/pmic/pmic_tps65218.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* (C) Copyright 2011-2013
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/errno.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/tps65218.h>
|
||||
|
||||
int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
|
||||
{
|
||||
uchar read_val;
|
||||
int ret;
|
||||
|
||||
ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*dest_val = read_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65218_reg_write() - Generic function that can write a TPS65218 PMIC
|
||||
* register or bit field regardless of protection
|
||||
* level.
|
||||
*
|
||||
* @prot_level: Register password protection. Use
|
||||
* TPS65218_PROT_LEVEL_NONE,
|
||||
* TPS65218_PROT_LEVEL_1 or TPS65218_PROT_LEVEL_2
|
||||
* @dest_reg: Register address to write.
|
||||
* @dest_val: Value to write.
|
||||
* @mask: Bit mask (8 bits) to be applied. Function will only
|
||||
* change bits that are set in the bit mask.
|
||||
*
|
||||
* @return: 0 for success, not 0 on failure, as per the i2c API
|
||||
*/
|
||||
int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
uchar mask)
|
||||
{
|
||||
uchar read_val;
|
||||
uchar xor_reg;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If we are affecting only a bit field, read dest_reg and apply the
|
||||
* mask
|
||||
*/
|
||||
if (mask != TPS65218_MASK_ALL_BITS) {
|
||||
ret = i2c_read(TPS65218_CHIP_PM, dest_reg, 1, &read_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
read_val &= (~mask);
|
||||
read_val |= (dest_val & mask);
|
||||
dest_val = read_val;
|
||||
}
|
||||
|
||||
if (prot_level > 0) {
|
||||
xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
|
||||
ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (prot_level == TPS65218_PROT_LEVEL_2) {
|
||||
ret = i2c_write(TPS65218_CHIP_PM, TPS65218_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_write(TPS65218_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65218_voltage_update() - Function to change a voltage level, as this
|
||||
* is a multi-step process.
|
||||
* @dc_cntrl_reg: DC voltage control register to change.
|
||||
* @volt_sel: New value for the voltage register
|
||||
* @return: 0 for success, not 0 on failure.
|
||||
*/
|
||||
int tps65218_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
|
||||
{
|
||||
if ((dc_cntrl_reg != TPS65218_DCDC1) &&
|
||||
(dc_cntrl_reg != TPS65218_DCDC2))
|
||||
return 1;
|
||||
|
||||
/* set voltage level */
|
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
|
||||
TPS65218_MASK_ALL_BITS))
|
||||
return 1;
|
||||
|
||||
/* set GO bit to initiate voltage transition */
|
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_2, TPS65218_SLEW,
|
||||
TPS65218_DCDC_GO, TPS65218_DCDC_GO))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65218_toggle_fseal() - Perform the sequence that toggles the FSEAL bit.
|
||||
*
|
||||
* @return: 0 on success, -EBADE if the sequence was broken
|
||||
*/
|
||||
int tps65218_toggle_fseal(void)
|
||||
{
|
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
|
||||
0xb1, TPS65218_MASK_ALL_BITS))
|
||||
return -EBADE;
|
||||
|
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
|
||||
0xfe, TPS65218_MASK_ALL_BITS))
|
||||
return -EBADE;
|
||||
|
||||
if (tps65218_reg_write(TPS65218_PROT_LEVEL_NONE, TPS65218_PASSWORD,
|
||||
0xa3, TPS65218_MASK_ALL_BITS))
|
||||
return -EBADE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tps65218_lock_fseal() - Perform the sequence that locks the FSEAL bit to 1.
|
||||
*
|
||||
* The FSEAL bit prevents the PMIC from turning off DCDC5 and DCDC6. It can be
|
||||
* toggled at most 3 times: 0->1, 1->0, and finally 0->1. After the third switch
|
||||
* its value is locked and can only be reset by powering off the PMIC entirely.
|
||||
*
|
||||
* @return: 0 on success, -EBADE if the sequence was broken
|
||||
*/
|
||||
int tps65218_lock_fseal(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (tps65218_toggle_fseal())
|
||||
return -EBADE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int power_tps65218_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "TPS65218_PMIC";
|
||||
struct pmic *p = pmic_alloc();
|
||||
|
||||
if (!p) {
|
||||
printf("%s: POWER allocation error!\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p->name = name;
|
||||
p->interface = PMIC_I2C;
|
||||
p->number_of_regs = TPS65218_PMIC_NUM_OF_REGS;
|
||||
p->hw.i2c.addr = TPS65218_CHIP_PM;
|
||||
p->hw.i2c.tx_num = 1;
|
||||
p->bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
83
u-boot/drivers/power/pmic/pmic_tps65910.c
Normal file
83
u-boot/drivers/power/pmic/pmic_tps65910.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* (C) Copyright 2011-2013
|
||||
* Texas Instruments, <www.ti.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <power/tps65910.h>
|
||||
|
||||
/*
|
||||
* tps65910_set_i2c_control() - Set the TPS65910 to be controlled via the I2C
|
||||
* interface.
|
||||
* @return: 0 on success, not 0 on failure
|
||||
*/
|
||||
int tps65910_set_i2c_control(void)
|
||||
{
|
||||
int ret;
|
||||
uchar buf;
|
||||
|
||||
/* VDD1/2 voltage selection register access by control i/f */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
|
||||
&buf, 1);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf |= TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
|
||||
|
||||
return i2c_write(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
|
||||
&buf, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* tps65910_voltage_update() - Voltage switching for MPU frequency switching.
|
||||
* @module: mpu - 0, core - 1
|
||||
* @vddx_op_vol_sel: vdd voltage to set
|
||||
* @return: 0 on success, not 0 on failure
|
||||
*/
|
||||
int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
|
||||
{
|
||||
uchar buf;
|
||||
unsigned int reg_offset;
|
||||
int ret;
|
||||
|
||||
if (module == MPU)
|
||||
reg_offset = TPS65910_VDD1_OP_REG;
|
||||
else
|
||||
reg_offset = TPS65910_VDD2_OP_REG;
|
||||
|
||||
/* Select VDDx OP */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf &= ~TPS65910_OP_REG_CMD_MASK;
|
||||
|
||||
ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Configure VDDx OP Voltage */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf &= ~TPS65910_OP_REG_SEL_MASK;
|
||||
buf |= vddx_op_vol_sel;
|
||||
|
||||
ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((buf & TPS65910_OP_REG_SEL_MASK) != vddx_op_vol_sel)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
102
u-boot/drivers/power/pmic/rk808.c
Normal file
102
u-boot/drivers/power/pmic/rk808.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <libfdt.h>
|
||||
#include <power/rk808_pmic.h>
|
||||
#include <power/pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = "DCDC_REG", .driver = "rk808_buck"},
|
||||
{ .prefix = "LDO_REG", .driver = "rk808_ldo"},
|
||||
{ .prefix = "SWITCH_REG", .driver = "rk808_switch"},
|
||||
{ },
|
||||
};
|
||||
|
||||
static int rk808_reg_count(struct udevice *dev)
|
||||
{
|
||||
return RK808_NUM_OF_REGS;
|
||||
}
|
||||
|
||||
static int rk808_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(dev, reg, buff, len);
|
||||
if (ret) {
|
||||
debug("write error to device: %p register: %#x!", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk808_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buff, len);
|
||||
if (ret) {
|
||||
debug("read error from device: %p register: %#x!", dev, reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
|
||||
static int rk808_bind(struct udevice *dev)
|
||||
{
|
||||
const void *blob = gd->fdt_blob;
|
||||
int regulators_node;
|
||||
int children;
|
||||
|
||||
regulators_node = fdt_subnode_offset(blob, dev->of_offset,
|
||||
"regulators");
|
||||
if (regulators_node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct dm_pmic_ops rk808_ops = {
|
||||
.reg_count = rk808_reg_count,
|
||||
.read = rk808_read,
|
||||
.write = rk808_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk808_ids[] = {
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_rk808) = {
|
||||
.name = "rk808 pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = rk808_ids,
|
||||
#if CONFIG_IS_ENABLED(PMIC_CHILDREN)
|
||||
.bind = rk808_bind,
|
||||
#endif
|
||||
.ops = &rk808_ops,
|
||||
};
|
||||
62
u-boot/drivers/power/pmic/s2mps11.c
Normal file
62
u-boot/drivers/power/pmic/s2mps11.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/s2mps11.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int s2mps11_reg_count(struct udevice *dev)
|
||||
{
|
||||
return S2MPS11_REG_COUNT;
|
||||
}
|
||||
|
||||
static int s2mps11_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_write(dev, reg, buff, len);
|
||||
if (ret)
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int s2mps11_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buff, len);
|
||||
if (ret)
|
||||
error("read error from device: %p register: %#x!", dev, reg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops s2mps11_ops = {
|
||||
.reg_count = s2mps11_reg_count,
|
||||
.read = s2mps11_read,
|
||||
.write = s2mps11_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id s2mps11_ids[] = {
|
||||
{ .compatible = "samsung,s2mps11-pmic" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_s2mps11) = {
|
||||
.name = "s2mps11_pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = s2mps11_ids,
|
||||
.ops = &s2mps11_ops,
|
||||
};
|
||||
95
u-boot/drivers/power/pmic/s5m8767.c
Normal file
95
u-boot/drivers/power/pmic/s5m8767.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include <power/s5m8767.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = "LDO", .driver = S5M8767_LDO_DRIVER },
|
||||
{ .prefix = "BUCK", .driver = S5M8767_BUCK_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int s5m8767_reg_count(struct udevice *dev)
|
||||
{
|
||||
return S5M8767_NUM_OF_REGS;
|
||||
}
|
||||
|
||||
static int s5m8767_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5m8767_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_read(dev, reg, buff, len)) {
|
||||
error("read error from device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s5m8767_enable_32khz_cp(struct udevice *dev)
|
||||
{
|
||||
return pmic_clrsetbits(dev, S5M8767_EN32KHZ_CP, 0, 1 << 1);
|
||||
}
|
||||
|
||||
static int s5m8767_bind(struct udevice *dev)
|
||||
{
|
||||
int node;
|
||||
const void *blob = gd->fdt_blob;
|
||||
int children;
|
||||
|
||||
node = fdt_subnode_offset(blob, dev->of_offset, "regulators");
|
||||
if (node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops s5m8767_ops = {
|
||||
.reg_count = s5m8767_reg_count,
|
||||
.read = s5m8767_read,
|
||||
.write = s5m8767_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id s5m8767_ids[] = {
|
||||
{ .compatible = "samsung,s5m8767-pmic" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_s5m8767) = {
|
||||
.name = "s5m8767_pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = s5m8767_ids,
|
||||
.bind = s5m8767_bind,
|
||||
.ops = &s5m8767_ops,
|
||||
};
|
||||
79
u-boot/drivers/power/pmic/sandbox.c
Normal file
79
u-boot/drivers/power/pmic/sandbox.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fdtdec.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/regulator.h>
|
||||
#include <power/sandbox_pmic.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = SANDBOX_OF_LDO_PREFIX, .driver = SANDBOX_LDO_DRIVER },
|
||||
{ .prefix = SANDBOX_OF_BUCK_PREFIX, .driver = SANDBOX_BUCK_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int sandbox_pmic_reg_count(struct udevice *dev)
|
||||
{
|
||||
return SANDBOX_PMIC_REG_COUNT;
|
||||
}
|
||||
|
||||
static int sandbox_pmic_write(struct udevice *dev, uint reg,
|
||||
const uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pmic_read(struct udevice *dev, uint reg,
|
||||
uint8_t *buff, int len)
|
||||
{
|
||||
if (dm_i2c_read(dev, reg, buff, len)) {
|
||||
error("read error from device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_pmic_bind(struct udevice *dev)
|
||||
{
|
||||
if (!pmic_bind_children(dev, dev->of_offset, pmic_children_info))
|
||||
error("%s:%d PMIC: %s - no child found!", __func__, __LINE__,
|
||||
dev->name);
|
||||
|
||||
/* Always return success for this device - allows for PMIC I/O */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops sandbox_pmic_ops = {
|
||||
.reg_count = sandbox_pmic_reg_count,
|
||||
.read = sandbox_pmic_read,
|
||||
.write = sandbox_pmic_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_pmic_ids[] = {
|
||||
{ .compatible = "sandbox,pmic" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_pmic) = {
|
||||
.name = "sandbox_pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = sandbox_pmic_ids,
|
||||
.bind = sandbox_pmic_bind,
|
||||
.ops = &sandbox_pmic_ops,
|
||||
};
|
||||
94
u-boot/drivers/power/pmic/tps65090.c
Normal file
94
u-boot/drivers/power/pmic/tps65090.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <power/pmic.h>
|
||||
#include <power/tps65090.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static const struct pmic_child_info pmic_children_info[] = {
|
||||
{ .prefix = "fet", .driver = TPS65090_FET_DRIVER },
|
||||
{ },
|
||||
};
|
||||
|
||||
static int tps65090_reg_count(struct udevice *dev)
|
||||
{
|
||||
return TPS65090_NUM_REGS;
|
||||
}
|
||||
|
||||
static int tps65090_write(struct udevice *dev, uint reg, const uint8_t *buff,
|
||||
int len)
|
||||
{
|
||||
if (dm_i2c_write(dev, reg, buff, len)) {
|
||||
error("write error to device: %p register: %#x!", dev, reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65090_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = dm_i2c_read(dev, reg, buff, len);
|
||||
if (ret) {
|
||||
error("read error %d from device: %p register: %#x!", ret, dev,
|
||||
reg);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps65090_bind(struct udevice *dev)
|
||||
{
|
||||
int regulators_node;
|
||||
const void *blob = gd->fdt_blob;
|
||||
int children;
|
||||
|
||||
regulators_node = fdt_subnode_offset(blob, dev->of_offset,
|
||||
"regulators");
|
||||
if (regulators_node <= 0) {
|
||||
debug("%s: %s regulators subnode not found!", __func__,
|
||||
dev->name);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
|
||||
|
||||
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
|
||||
if (!children)
|
||||
debug("%s: %s - no child found\n", __func__, dev->name);
|
||||
|
||||
/* Always return success for this device */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dm_pmic_ops tps65090_ops = {
|
||||
.reg_count = tps65090_reg_count,
|
||||
.read = tps65090_read,
|
||||
.write = tps65090_write,
|
||||
};
|
||||
|
||||
static const struct udevice_id tps65090_ids[] = {
|
||||
{ .compatible = "ti,tps65090" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pmic_tps65090) = {
|
||||
.name = "tps65090 pmic",
|
||||
.id = UCLASS_PMIC,
|
||||
.of_match = tps65090_ids,
|
||||
.bind = tps65090_bind,
|
||||
.ops = &tps65090_ops,
|
||||
};
|
||||
Reference in New Issue
Block a user