123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /*
- * 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
- int as3722_read(struct udevice *pmic, u8 reg, u8 *value)
- {
- int err;
- err = dm_i2c_read(pmic, reg, value, 1);
- if (err < 0)
- return err;
- return 0;
- }
- int as3722_write(struct udevice *pmic, u8 reg, u8 value)
- {
- int err;
- err = dm_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;
- }
- /* Temporary function until we get the pmic framework */
- int as3722_get(struct udevice **devp)
- {
- int bus = 0;
- int address = 0x40;
- return i2c_get_chip_for_busnum(bus, address, 1, devp);
- }
- 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, 1, &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);
- if (devp)
- *devp = pmic;
- return 0;
- }
|