uboot/drivers/power/as3722.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014 NVIDIA Corporation
   3 *
   4 * SPDX-License-Identifier: GPL-2.0+
   5 */
   6
   7#define pr_fmt(fmt) "as3722: " fmt
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <fdtdec.h>
  13#include <i2c.h>
  14
  15#include <power/as3722.h>
  16
  17#define AS3722_SD_VOLTAGE(n) (0x00 + (n))
  18#define AS3722_GPIO_CONTROL(n) (0x08 + (n))
  19#define  AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0)
  20#define  AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL (7 << 0)
  21#define  AS3722_GPIO_CONTROL_INVERT (1 << 7)
  22#define AS3722_LDO_VOLTAGE(n) (0x10 + (n))
  23#define AS3722_GPIO_SIGNAL_OUT 0x20
  24#define AS3722_SD_CONTROL 0x4d
  25#define AS3722_LDO_CONTROL 0x4e
  26#define AS3722_ASIC_ID1 0x90
  27#define  AS3722_DEVICE_ID 0x0c
  28#define AS3722_ASIC_ID2 0x91
  29
  30int as3722_read(struct udevice *pmic, u8 reg, u8 *value)
  31{
  32        int err;
  33
  34        err = dm_i2c_read(pmic, reg, value, 1);
  35        if (err < 0)
  36                return err;
  37
  38        return 0;
  39}
  40
  41int as3722_write(struct udevice *pmic, u8 reg, u8 value)
  42{
  43        int err;
  44
  45        err = dm_i2c_write(pmic, reg, &value, 1);
  46        if (err < 0)
  47                return err;
  48
  49        return 0;
  50}
  51
  52static int as3722_read_id(struct udevice *pmic, u8 *id, u8 *revision)
  53{
  54        int err;
  55
  56        err = as3722_read(pmic, AS3722_ASIC_ID1, id);
  57        if (err) {
  58                error("failed to read ID1 register: %d", err);
  59                return err;
  60        }
  61
  62        err = as3722_read(pmic, AS3722_ASIC_ID2, revision);
  63        if (err) {
  64                error("failed to read ID2 register: %d", err);
  65                return err;
  66        }
  67
  68        return 0;
  69}
  70
  71int as3722_sd_enable(struct udevice *pmic, unsigned int sd)
  72{
  73        u8 value;
  74        int err;
  75
  76        if (sd > 6)
  77                return -EINVAL;
  78
  79        err = as3722_read(pmic, AS3722_SD_CONTROL, &value);
  80        if (err) {
  81                error("failed to read SD control register: %d", err);
  82                return err;
  83        }
  84
  85        value |= 1 << sd;
  86
  87        err = as3722_write(pmic, AS3722_SD_CONTROL, value);
  88        if (err < 0) {
  89                error("failed to write SD control register: %d", err);
  90                return err;
  91        }
  92
  93        return 0;
  94}
  95
  96int as3722_sd_set_voltage(struct udevice *pmic, unsigned int sd, u8 value)
  97{
  98        int err;
  99
 100        if (sd > 6)
 101                return -EINVAL;
 102
 103        err = as3722_write(pmic, AS3722_SD_VOLTAGE(sd), value);
 104        if (err < 0) {
 105                error("failed to write SD%u voltage register: %d", sd, err);
 106                return err;
 107        }
 108
 109        return 0;
 110}
 111
 112int as3722_ldo_enable(struct udevice *pmic, unsigned int ldo)
 113{
 114        u8 value;
 115        int err;
 116
 117        if (ldo > 11)
 118                return -EINVAL;
 119
 120        err = as3722_read(pmic, AS3722_LDO_CONTROL, &value);
 121        if (err) {
 122                error("failed to read LDO control register: %d", err);
 123                return err;
 124        }
 125
 126        value |= 1 << ldo;
 127
 128        err = as3722_write(pmic, AS3722_LDO_CONTROL, value);
 129        if (err < 0) {
 130                error("failed to write LDO control register: %d", err);
 131                return err;
 132        }
 133
 134        return 0;
 135}
 136
 137int as3722_ldo_set_voltage(struct udevice *pmic, unsigned int ldo, u8 value)
 138{
 139        int err;
 140
 141        if (ldo > 11)
 142                return -EINVAL;
 143
 144        err = as3722_write(pmic, AS3722_LDO_VOLTAGE(ldo), value);
 145        if (err < 0) {
 146                error("failed to write LDO%u voltage register: %d", ldo,
 147                      err);
 148                return err;
 149        }
 150
 151        return 0;
 152}
 153
 154int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio,
 155                          unsigned long flags)
 156{
 157        u8 value = 0;
 158        int err;
 159
 160        if (flags & AS3722_GPIO_OUTPUT_VDDH)
 161                value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
 162
 163        if (flags & AS3722_GPIO_INVERT)
 164                value |= AS3722_GPIO_CONTROL_INVERT;
 165
 166        err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
 167        if (err) {
 168                error("failed to configure GPIO#%u: %d", gpio, err);
 169                return err;
 170        }
 171
 172        return 0;
 173}
 174
 175static int as3722_gpio_set(struct udevice *pmic, unsigned int gpio,
 176                           unsigned int level)
 177{
 178        const char *l;
 179        u8 value;
 180        int err;
 181
 182        if (gpio > 7)
 183                return -EINVAL;
 184
 185        err = as3722_read(pmic, AS3722_GPIO_SIGNAL_OUT, &value);
 186        if (err < 0) {
 187                error("failed to read GPIO signal out register: %d", err);
 188                return err;
 189        }
 190
 191        if (level == 0) {
 192                value &= ~(1 << gpio);
 193                l = "low";
 194        } else {
 195                value |= 1 << gpio;
 196                l = "high";
 197        }
 198
 199        err = as3722_write(pmic, AS3722_GPIO_SIGNAL_OUT, value);
 200        if (err) {
 201                error("failed to set GPIO#%u %s: %d", gpio, l, err);
 202                return err;
 203        }
 204
 205        return 0;
 206}
 207
 208int as3722_gpio_direction_output(struct udevice *pmic, unsigned int gpio,
 209                                 unsigned int level)
 210{
 211        u8 value;
 212        int err;
 213
 214        if (gpio > 7)
 215                return -EINVAL;
 216
 217        if (level == 0)
 218                value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL;
 219        else
 220                value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
 221
 222        err = as3722_write(pmic, AS3722_GPIO_CONTROL(gpio), value);
 223        if (err) {
 224                error("failed to configure GPIO#%u as output: %d", gpio, err);
 225                return err;
 226        }
 227
 228        err = as3722_gpio_set(pmic, gpio, level);
 229        if (err < 0) {
 230                error("failed to set GPIO#%u high: %d", gpio, err);
 231                return err;
 232        }
 233
 234        return 0;
 235}
 236
 237/* Temporary function until we get the pmic framework */
 238int as3722_get(struct udevice **devp)
 239{
 240        int bus = 0;
 241        int address = 0x40;
 242
 243        return i2c_get_chip_for_busnum(bus, address, 1, devp);
 244}
 245
 246int as3722_init(struct udevice **devp)
 247{
 248        struct udevice *pmic;
 249        u8 id, revision;
 250        const unsigned int bus = 0;
 251        const unsigned int address = 0x40;
 252        int err;
 253
 254        err = i2c_get_chip_for_busnum(bus, address, 1, &pmic);
 255        if (err)
 256                return err;
 257        err = as3722_read_id(pmic, &id, &revision);
 258        if (err < 0) {
 259                error("failed to read ID: %d", err);
 260                return err;
 261        }
 262
 263        if (id != AS3722_DEVICE_ID) {
 264                error("unknown device");
 265                return -ENOENT;
 266        }
 267
 268        debug("AS3722 revision %#x found on I2C bus %u, address %#x\n",
 269              revision, bus, address);
 270        if (devp)
 271                *devp = pmic;
 272
 273        return 0;
 274}
 275