The AS3722 provides a number of DC/DC converters and LDOs as well as 8 GPIOs. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Tom Warren <twarren@nvidia.com>master
parent
839e4f7c66
commit
6173c45b21
@ -0,0 +1,264 @@ |
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA Corporation |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#define pr_fmt(fmt) "as3722: " fmt |
||||
|
||||
#include <common.h> |
||||
#include <dm.h> |
||||
#include <errno.h> |
||||
#include <fdtdec.h> |
||||
#include <i2c.h> |
||||
|
||||
#include <power/as3722.h> |
||||
|
||||
#define AS3722_SD_VOLTAGE(n) (0x00 + (n)) |
||||
#define AS3722_GPIO_CONTROL(n) (0x08 + (n)) |
||||
#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0) |
||||
#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0) |
||||
#define AS3722_GPIO_CONTROL_INVERT (1 << 7) |
||||
#define AS3722_LDO_VOLTAGE(n) (0x10 + (n)) |
||||
#define AS3722_GPIO_SIGNAL_OUT 0x20 |
||||
#define AS3722_SD_CONTROL 0x4d |
||||
#define AS3722_LDO_CONTROL 0x4e |
||||
#define AS3722_ASIC_ID1 0x90 |
||||
#define AS3722_DEVICE_ID 0x0c |
||||
#define AS3722_ASIC_ID2 0x91 |
||||
|
||||
static int as3722_read(struct udevice *pmic, u8 reg, u8 *value) |
||||
{ |
||||
int err; |
||||
|
||||
err = i2c_read(pmic, reg, value, 1); |
||||
if (err < 0) |
||||
return err; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int as3722_write(struct udevice *pmic, u8 reg, u8 value) |
||||
{ |
||||
int err; |
||||
|
||||
err = i2c_write(pmic, reg, &value, 1); |
||||
if (err < 0) |
||||
return err; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision) |
||||
{ |
||||
int err; |
||||
|
||||
err = as3722_read(pmic, AS3722_ASIC_ID1, id); |
||||
if (err) { |
||||
error("failed to read ID1 register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
err = as3722_read(pmic, AS3722_ASIC_ID2, revision); |
||||
if (err) { |
||||
error("failed to read ID2 register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_sd_enable(struct udevice *pmic, unsigned int sd) |
||||
{ |
||||
u8 value; |
||||
int err; |
||||
|
||||
if (sd > 6) |
||||
return -EINVAL; |
||||
|
||||
err = as3722_read(pmic, AS3722_SD_CONTROL, &value); |
||||
if (err) { |
||||
error("failed to read SD control register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
value |= 1 << sd; |
||||
|
||||
err = as3722_write(pmic, AS3722_SD_CONTROL, value); |
||||
if (err < 0) { |
||||
error("failed to write SD control register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value) |
||||
{ |
||||
int err; |
||||
|
||||
if (sd > 6) |
||||
return -EINVAL; |
||||
|
||||
err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value); |
||||
if (err < 0) { |
||||
error("failed to write SD%u voltage register: %d", sd, err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo) |
||||
{ |
||||
u8 value; |
||||
int err; |
||||
|
||||
if (ldo > 11) |
||||
return -EINVAL; |
||||
|
||||
err = as3722_read(pmic, AS3722_LDO_CONTROL, &value); |
||||
if (err) { |
||||
error("failed to read LDO control register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
value |= 1 << ldo; |
||||
|
||||
err = as3722_write(pmic, AS3722_LDO_CONTROL, value); |
||||
if (err < 0) { |
||||
error("failed to write LDO control register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value) |
||||
{ |
||||
int err; |
||||
|
||||
if (ldo > 11) |
||||
return -EINVAL; |
||||
|
||||
err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value); |
||||
if (err < 0) { |
||||
error("failed to write LDO%u voltage register: %d", ldo, |
||||
err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, |
||||
unsigned long flags) |
||||
{ |
||||
u8 value = 0; |
||||
int err; |
||||
|
||||
if (flags & AS3722_GPIO_OUTPUT_VDDH) |
||||
value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; |
||||
|
||||
if (flags & AS3722_GPIO_INVERT) |
||||
value |= AS3722_GPIO_CONTROL_INVERT; |
||||
|
||||
err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); |
||||
if (err) { |
||||
error("failed to configure GPIO#%u: %d", gpio, err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio, |
||||
unsigned int level) |
||||
{ |
||||
const char *l; |
||||
u8 value; |
||||
int err; |
||||
|
||||
if (gpio > 7) |
||||
return -EINVAL; |
||||
|
||||
err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value); |
||||
if (err < 0) { |
||||
error("failed to read GPIO signal out register: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
if (level == 0) { |
||||
value &= ~(1 << gpio); |
||||
l = "low"; |
||||
} else { |
||||
value |= 1 << gpio; |
||||
l = "high"; |
||||
} |
||||
|
||||
err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); |
||||
if (err) { |
||||
error("failed to set GPIO#%u %s: %d", gpio, l, err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, |
||||
unsigned int level) |
||||
{ |
||||
u8 value; |
||||
int err; |
||||
|
||||
if (gpio > 7) |
||||
return -EINVAL; |
||||
|
||||
if (level == 0) |
||||
value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; |
||||
else |
||||
value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; |
||||
|
||||
err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value); |
||||
if (err) { |
||||
error("failed to configure GPIO#%u as output: %d", gpio, err); |
||||
return err; |
||||
} |
||||
|
||||
err = as3722_gpio_set(pmic, gpio, level); |
||||
if (err < 0) { |
||||
error("failed to set GPIO#%u high: %d", gpio, err); |
||||
return err; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int as3722_init(struct udevice **devp) |
||||
{ |
||||
struct udevice *pmic; |
||||
u8 id, revision; |
||||
const unsigned int bus = 0; |
||||
const unsigned int address = 0x40; |
||||
int err; |
||||
|
||||
err = i2c_get_chip_for_busnum(bus, address, &pmic); |
||||
if (err) |
||||
return err; |
||||
err = as3722_read_id(pmic, &id, &revision); |
||||
if (err < 0) { |
||||
error("failed to read ID: %d", err); |
||||
return err; |
||||
} |
||||
|
||||
if (id != AS3722_DEVICE_ID) { |
||||
error("unknown device"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
debug("AS3722 revision %#x found on I2C bus %u, address %#x\n", |
||||
revision, bus, address); |
||||
*devp = pmic; |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,27 @@ |
||||
/*
|
||||
* Copyright (C) 2014 NVIDIA Corporation |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __POWER_AS3722_H__ |
||||
#define __POWER_AS3722_H__ |
||||
|
||||
#include <asm/types.h> |
||||
|
||||
#define AS3722_GPIO_OUTPUT_VDDH (1 << 0) |
||||
#define AS3722_GPIO_INVERT (1 << 1) |
||||
|
||||
struct udevice; |
||||
|
||||
int as3722_init(struct udevice **devp); |
||||
int as3722_sd_enable(struct udevice *pmic, unsigned int sd); |
||||
int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value); |
||||
int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo); |
||||
int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value); |
||||
int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, |
||||
unsigned long flags); |
||||
int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio, |
||||
unsigned int level); |
||||
|
||||
#endif /* __POWER_AS3722_H__ */ |
Loading…
Reference in new issue