Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | // SPDX-License-Identifier: GPL-2.0 /* * slg7xl45106_i2c_gpo driver * * Copyright (C) 2021 Xilinx, Inc. */ #include <errno.h> #include <asm/io.h> #include <asm/gpio.h> #include <dm.h> #include <i2c.h> #include <dt-bindings/gpio/gpio.h> #include <asm/arch/hardware.h> #define SLG7XL45106_REG 0xdb static int slg7xl45106_i2c_gpo_direction_input(struct udevice *dev, unsigned int offset) { return 0; } static int slg7xl45106_i2c_gpo_xlate(struct udevice *dev, struct gpio_desc *desc, struct ofnode_phandle_args *args) { desc->offset = (unsigned int)args->args[0]; desc->flags = (args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0); return 0; } static int slg7xl45106_i2c_gpo_set_value(struct udevice *dev, unsigned int offset, int value) { int ret; u8 val; ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1); if (ret) return ret; if (value) val |= BIT(offset); else val &= ~BIT(offset); return dm_i2c_write(dev, SLG7XL45106_REG, &val, 1); } static int slg7xl45106_i2c_gpo_direction_output(struct udevice *dev, unsigned int offset, int value) { return slg7xl45106_i2c_gpo_set_value(dev, offset, value); } static int slg7xl45106_i2c_gpo_get_value(struct udevice *dev, unsigned int offset) { int ret; u8 val; ret = dm_i2c_read(dev, SLG7XL45106_REG, &val, 1); if (ret) return ret; return !!(val & BIT(offset)); } static int slg7xl45106_i2c_gpo_get_function(struct udevice *dev, unsigned int offset) { return GPIOF_OUTPUT; } static const struct dm_gpio_ops slg7xl45106_i2c_gpo_ops = { .direction_input = slg7xl45106_i2c_gpo_direction_input, .direction_output = slg7xl45106_i2c_gpo_direction_output, .get_value = slg7xl45106_i2c_gpo_get_value, .set_value = slg7xl45106_i2c_gpo_set_value, .get_function = slg7xl45106_i2c_gpo_get_function, .xlate = slg7xl45106_i2c_gpo_xlate, }; static int slg7xl45106_i2c_gpo_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); const void *label_ptr; label_ptr = dev_read_prop(dev, "label", NULL); if (label_ptr) { uc_priv->bank_name = strdup(label_ptr); if (!uc_priv->bank_name) return -ENOMEM; } else { uc_priv->bank_name = dev->name; } uc_priv->gpio_count = 8; return 0; } static const struct udevice_id slg7xl45106_i2c_gpo_ids[] = { { .compatible = "dlg,slg7xl45106",}, { } }; U_BOOT_DRIVER(slg7xl45106_i2c_gpo) = { .name = "slg7xl45106_i2c_gpo", .id = UCLASS_GPIO, .ops = &slg7xl45106_i2c_gpo_ops, .of_match = slg7xl45106_i2c_gpo_ids, .probe = slg7xl45106_i2c_gpo_probe, }; |