1// SPDX-License-Identifier: GPL-2.0 2/* 3 * max7320 I2C GPIO EXPANDER DRIVER 4 * 5 * Copyright (C) 2021 Hannes Schmelzer <oe5hpm@oevsv.at> 6 * B&R Industrial Automation GmbH - http://www.br-automation.com 7 * 8 */ 9 10#include <common.h> 11#include <dm.h> 12#include <i2c.h> 13#include <asm-generic/gpio.h> 14#include <linux/bitops.h> 15 16struct max7320_chip { 17 u32 outreg; 18}; 19 20static int max7320_direction_output(struct udevice *dev, 21 unsigned int offset, int value) 22{ 23 struct max7320_chip *plat = dev_get_plat(dev); 24 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 25 struct dm_i2c_chip *chip = dev_get_parent_plat(dev); 26 27 int ret; 28 29 if (value) 30 plat->outreg |= BIT(offset); 31 else 32 plat->outreg &= ~BIT(offset); 33 34 ret = dm_i2c_write(dev, 35 plat->outreg & 0xff, 36 (uint8_t *)&plat->outreg + 1, 37 uc_priv->gpio_count > 8 ? 1 : 0); 38 if (ret) 39 printf("%s i2c write failed to addr %x\n", __func__, 40 chip->chip_addr); 41 42 return ret; 43} 44 45static int max7320_get_value(struct udevice *dev, unsigned int offset) 46{ 47 struct max7320_chip *plat = dev_get_plat(dev); 48 49 return (plat->outreg >> offset) & 0x1; 50} 51 52static int max7320_set_value(struct udevice *dev, unsigned int offset, 53 int value) 54{ 55 return max7320_direction_output(dev, offset, value); 56} 57 58static int max7320_get_function(struct udevice *dev, unsigned int offset) 59{ 60 return GPIOF_OUTPUT; 61} 62 63static int max7320_ofdata_plat(struct udevice *dev) 64{ 65 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 66 67 uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios", 8); 68 if (uc_priv->gpio_count > 16) { 69 printf("%s: max7320 doesn't support more than 16 gpios!", 70 __func__); 71 return -EINVAL; 72 } 73 74 uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), 75 "gpio-bank-name", NULL); 76 if (!uc_priv->bank_name) 77 uc_priv->bank_name = fdt_get_name(gd->fdt_blob, 78 dev_of_offset(dev), NULL); 79 80 return 0; 81} 82 83static int max7320_gpio_probe(struct udevice *dev) 84{ 85 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 86 87 debug("%s GPIO controller with %d gpios probed\n", 88 uc_priv->bank_name, uc_priv->gpio_count); 89 90 return 0; 91} 92 93static const struct dm_gpio_ops max7320_gpio_ops = { 94 .direction_output = max7320_direction_output, 95 .set_value = max7320_set_value, 96 .get_value = max7320_get_value, 97 .get_function = max7320_get_function, 98}; 99 100static const struct udevice_id max7320_gpio_ids[] = { 101 { .compatible = "maxim,max7320" }, 102 { } 103}; 104 105U_BOOT_DRIVER(gpio_max7320) = { 106 .name = "gpio_max7320", 107 .id = UCLASS_GPIO, 108 .ops = &max7320_gpio_ops, 109 .of_match = max7320_gpio_ids, 110 .of_to_plat = max7320_ofdata_plat, 111 .probe = max7320_gpio_probe, 112 .plat_auto = sizeof(struct max7320_chip), 113}; 114