1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2014 NVIDIA Corporation 4 */ 5 6 #include <common.h> 7 #include <dm.h> 8 #include <asm/gpio.h> 9 #include <power/as3722.h> 10 #include <power/pmic.h> 11 12 #define NUM_GPIOS 8 13 14 int as3722_gpio_configure(struct udevice *pmic, unsigned int gpio, 15 unsigned long flags) 16 { 17 u8 value = 0; 18 int err; 19 20 if (flags & AS3722_GPIO_OUTPUT_VDDH) 21 value |= AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; 22 23 if (flags & AS3722_GPIO_INVERT) 24 value |= AS3722_GPIO_CONTROL_INVERT; 25 26 err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); 27 if (err) { 28 pr_err("failed to configure GPIO#%u: %d\n", gpio, err); 29 return err; 30 } 31 32 return 0; 33 } 34 35 static int as3722_gpio_set_value(struct udevice *dev, unsigned int gpio, 36 int level) 37 { 38 struct udevice *pmic = dev_get_parent(dev); 39 const char *l; 40 u8 value; 41 int err; 42 43 if (gpio >= NUM_GPIOS) 44 return -EINVAL; 45 46 err = pmic_reg_read(pmic, AS3722_GPIO_SIGNAL_OUT); 47 if (err < 0) { 48 pr_err("failed to read GPIO signal out register: %d\n", err); 49 return err; 50 } 51 value = err; 52 53 if (level == 0) { 54 value &= ~(1 << gpio); 55 l = "low"; 56 } else { 57 value |= 1 << gpio; 58 l = "high"; 59 } 60 61 err = pmic_reg_write(pmic, AS3722_GPIO_SIGNAL_OUT, value); 62 if (err) { 63 pr_err("failed to set GPIO#%u %s: %d\n", gpio, l, err); 64 return err; 65 } 66 67 return 0; 68 } 69 70 int as3722_gpio_direction_output(struct udevice *dev, unsigned int gpio, 71 int value) 72 { 73 struct udevice *pmic = dev_get_parent(dev); 74 int err; 75 76 if (gpio > 7) 77 return -EINVAL; 78 79 if (value == 0) 80 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL; 81 else 82 value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH; 83 84 err = pmic_reg_write(pmic, AS3722_GPIO_CONTROL(gpio), value); 85 if (err) { 86 pr_err("failed to configure GPIO#%u as output: %d\n", gpio, 87 err); 88 return err; 89 } 90 91 err = as3722_gpio_set_value(pmic, gpio, value); 92 if (err < 0) { 93 pr_err("failed to set GPIO#%u high: %d\n", 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