uboot/drivers/gpio/pcf8575_gpio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * PCF8575 I2C GPIO EXPANDER DRIVER
   4 *
   5 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
   6 *
   7 * Vignesh R <vigneshr@ti.com>
   8 *
   9 *
  10 * Driver for TI PCF-8575 16-bit I2C gpio expander. Based on
  11 * gpio-pcf857x Linux Kernel(v4.7) driver.
  12 *
  13 * Copyright (C) 2007 David Brownell
  14 *
  15 * Add support for 8 bit expanders - like pca8574
  16 * Copyright (C) 2021 Lukasz Majewski - DENX Software Engineering
  17 *
  18 */
  19
  20#include <common.h>
  21#include <dm.h>
  22#include <i2c.h>
  23#include <log.h>
  24#include <asm-generic/gpio.h>
  25#include <asm/global_data.h>
  26#include <linux/bitops.h>
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30struct pcf8575_chip {
  31        /* NOTE:  these chips have strange "quasi-bidirectional" I/O pins.
  32         * We can't actually know whether a pin is configured (a) as output
  33         * and driving the signal low, or (b) as input and reporting a low
  34         * value ... without knowing the last value written since the chip
  35         * came out of reset (if any).  We can't read the latched output.
  36         * In short, the only reliable solution for setting up pin direction
  37         * is to do it explicitly.
  38         *
  39         * Using "out" avoids that trouble.  When left initialized to zero,
  40         * our software copy of the "latch" then matches the chip's all-ones
  41         * reset state.  Otherwise it flags pins to be driven low.
  42         */
  43        unsigned int out;       /* software latch */
  44};
  45
  46/* Read/Write to I/O expander */
  47
  48static int pcf8575_i2c_write(struct udevice *dev, unsigned int word)
  49{
  50        struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
  51        u8 buf[2] = { word & 0xff, word >> 8, };
  52        int ret;
  53
  54        ret = dm_i2c_write(dev, 0, buf, dev_get_driver_data(dev));
  55        if (ret)
  56                printf("%s i2c write failed to addr %x\n", __func__,
  57                       chip->chip_addr);
  58
  59        return ret;
  60}
  61
  62static int pcf8575_i2c_read(struct udevice *dev)
  63{
  64        struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
  65        u8 buf[2] = {0x00, 0x00};
  66        int ret;
  67
  68        ret = dm_i2c_read(dev, 0, buf, dev_get_driver_data(dev));
  69        if (ret) {
  70                printf("%s i2c read failed from addr %x\n", __func__,
  71                       chip->chip_addr);
  72                return ret;
  73        }
  74
  75        return (buf[1] << 8) | buf[0];
  76}
  77
  78static int pcf8575_direction_input(struct udevice *dev, unsigned offset)
  79{
  80        struct pcf8575_chip *plat = dev_get_plat(dev);
  81        int status;
  82
  83        plat->out |= BIT(offset);
  84        status = pcf8575_i2c_write(dev, plat->out);
  85
  86        return status;
  87}
  88
  89static int pcf8575_direction_output(struct udevice *dev,
  90                                    unsigned int offset, int value)
  91{
  92        struct pcf8575_chip *plat = dev_get_plat(dev);
  93        int ret;
  94
  95        if (value)
  96                plat->out |= BIT(offset);
  97        else
  98                plat->out &= ~BIT(offset);
  99
 100        ret = pcf8575_i2c_write(dev, plat->out);
 101
 102        return ret;
 103}
 104
 105static int pcf8575_get_value(struct udevice *dev, unsigned int offset)
 106{
 107        int             value;
 108
 109        value = pcf8575_i2c_read(dev);
 110
 111        return (value < 0) ? value : ((value & BIT(offset)) >> offset);
 112}
 113
 114static int pcf8575_set_value(struct udevice *dev, unsigned int offset,
 115                             int value)
 116{
 117        return pcf8575_direction_output(dev, offset, value);
 118}
 119
 120static int pcf8575_ofdata_plat(struct udevice *dev)
 121{
 122        struct pcf8575_chip *plat = dev_get_plat(dev);
 123        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 124
 125        int n_latch;
 126
 127        /*
 128         * Number of pins depends on the expander device and is specified
 129         * in the struct udevice_id (as in the Linue kernel).
 130         */
 131        uc_priv->gpio_count = dev_get_driver_data(dev) * 8;
 132        uc_priv->bank_name = fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
 133                                         "gpio-bank-name", NULL);
 134        if (!uc_priv->bank_name)
 135                uc_priv->bank_name = fdt_get_name(gd->fdt_blob,
 136                                                  dev_of_offset(dev), NULL);
 137
 138        n_latch = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
 139                                  "lines-initial-states", 0);
 140        plat->out = ~n_latch;
 141
 142        return 0;
 143}
 144
 145static int pcf8575_gpio_probe(struct udevice  *dev)
 146{
 147        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 148
 149        debug("%s GPIO controller with %d gpios probed\n",
 150              uc_priv->bank_name, uc_priv->gpio_count);
 151
 152        return 0;
 153}
 154
 155static const struct dm_gpio_ops pcf8575_gpio_ops = {
 156        .direction_input        = pcf8575_direction_input,
 157        .direction_output       = pcf8575_direction_output,
 158        .get_value              = pcf8575_get_value,
 159        .set_value              = pcf8575_set_value,
 160};
 161
 162static const struct udevice_id pcf8575_gpio_ids[] = {
 163        { .compatible = "nxp,pcf8575", .data = 2 },
 164        { .compatible = "ti,pcf8575", .data = 2 },
 165        { .compatible = "nxp,pca8574", .data = 1 },
 166        { }
 167};
 168
 169U_BOOT_DRIVER(gpio_pcf8575) = {
 170        .name   = "gpio_pcf8575",
 171        .id     = UCLASS_GPIO,
 172        .ops    = &pcf8575_gpio_ops,
 173        .of_match = pcf8575_gpio_ids,
 174        .of_to_plat = pcf8575_ofdata_plat,
 175        .probe  = pcf8575_gpio_probe,
 176        .plat_auto      = sizeof(struct pcf8575_chip),
 177};
 178