1 /* 2 * Copyright (C) 2014 NVIDIA Corporation 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <asm/gpio.h> 10 #include <power/as3722.h> 11 #include <power/pmic.h> 12 13 #define NUM_GPIOS 8 14 15 int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, 16 unsigned long flags) 17 { 18 u8 value = 0; 19 int err; 20 21 if (flags & AS3722_GPIO_OUTPUT_VDDH) 22 value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; 23 24 if (flags & AS3722_GPIO_INVERT) 25 value |= AS3722_GPIO_CONTROL_INVERT; 26 27 err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); 28 if (err) { 29 error("failed to configure GPIO#%u: %d", gpio, err); 30 return err; 31 } 32 33 return 0; 34 } 35 36 static int as3722_gpio_set_value(struct udevice *dev, unsigned int gpio, 37 int level) 38 { 39 struct udevice *pmic = dev_get_parent(dev); 40 const char *l; 41 u8 value; 42 int err; 43 44 if (gpio >= NUM_GPIOS) 45 return -EINVAL; 46 47 err = pmic_reg_read(pmic, AS3722_GPIO_SIGNAL_OUT); 48 if (err < 0) { 49 error("failed to read GPIO signal out register: %d", err); 50 return err; 51 } 52 value = err; 53 54 if (level == 0) { 55 value &= ~(1 << gpio); 56 l = "low"; 57 } else { 58 value |= 1 << gpio; 59 l = "high"; 60 } 61 62 err = pmic_reg_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); 63 if (err) { 64 error("failed to set GPIO#%u %s: %d", gpio, l, err); 65 return err; 66 } 67 68 return 0; 69 } 70 71 int as3722_gpio_direction_output(struct udevice *dev, unsigned int gpio, 72 int value) 73 { 74 struct udevice *pmic = dev_get_parent(dev); 75 int err; 76 77 if (gpio > 7) 78 return -EINVAL; 79 80 if (value == 0) 81 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; 82 else 83 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; 84 85 err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); 86 if (err) { 87 error("failed to configure GPIO#%u as output: %d", gpio, err); 88 return err; 89 } 90 91 err = as3722_gpio_set_value(pmic, gpio, value); 92 if (err < 0) { 93 error("failed to set GPIO#%u high: %d", gpio, err); 94 return err; 95 } 96 97 return 0; 98 } 99 100 static int as3722_gpio_probe(struct udevice *dev) 101 { 102 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 103 104 uc_priv->gpio_count = NUM_GPIOS; 105 uc_priv->bank_name = "as3722_"; 106 107 return 0; 108 } 109 110 static const struct dm_gpio_ops gpio_as3722_ops = { 111 .direction_output = as3722_gpio_direction_output, 112 .set_value = as3722_gpio_set_value, 113 }; 114 115 U_BOOT_DRIVER(gpio_as3722) = { 116 .name = "gpio_as3722", 117 .id = UCLASS_GPIO, 118 .ops = &gpio_as3722_ops, 119 .probe = as3722_gpio_probe, 120 }; 121