linux/drivers/gpio/gpio-pca953x.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  PCA953x 4/8/16/24/40 bit I/O ports
 *
 *  Copyright (C) 2005 Ben Gardner <[email protected]>
 *  Copyright (C) 2007 Marvell International Ltd.
 *
 *  Derived from drivers/i2c/chips/pca9539.c
 */

#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/seq_file.h>
#include <linux/slab.h>

#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>

#include <linux/pinctrl/pinconf-generic.h>

#include <linux/platform_data/pca953x.h>

#define PCA953X_INPUT
#define PCA953X_OUTPUT
#define PCA953X_INVERT
#define PCA953X_DIRECTION

#define REG_ADDR_MASK
#define REG_ADDR_EXT
#define REG_ADDR_AI

#define PCA957X_IN
#define PCA957X_INVRT
#define PCA957X_BKEN
#define PCA957X_PUPD
#define PCA957X_CFG
#define PCA957X_OUT
#define PCA957X_MSK
#define PCA957X_INTS

#define PCAL953X_OUT_STRENGTH
#define PCAL953X_IN_LATCH
#define PCAL953X_PULL_EN
#define PCAL953X_PULL_SEL
#define PCAL953X_INT_MASK
#define PCAL953X_INT_STAT
#define PCAL953X_OUT_CONF

#define PCAL6524_INT_EDGE
#define PCAL6524_INT_CLR
#define PCAL6524_IN_STATUS
#define PCAL6524_OUT_INDCONF
#define PCAL6524_DEBOUNCE

#define PCA_GPIO_MASK

#define PCAL_GPIO_MASK
#define PCAL_PINCTRL_MASK

#define PCA_INT
#define PCA_PCAL
#define PCA_LATCH_INT
#define PCA953X_TYPE
#define PCA957X_TYPE
#define PCAL653X_TYPE
#define PCA_TYPE_MASK

#define PCA_CHIP_TYPE(x)

static const struct i2c_device_id pca953x_id[] =;
MODULE_DEVICE_TABLE(i2c, pca953x_id);

#ifdef CONFIG_GPIO_PCA953X_IRQ

#include <linux/acpi.h>
#include <linux/dmi.h>

static const struct acpi_gpio_params pca953x_irq_gpios =;

static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] =;

static int pca953x_acpi_get_irq(struct device *dev)
{}

static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] =;
#endif

static const struct acpi_device_id pca953x_acpi_ids[] =;
MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);

#define MAX_BANK
#define BANK_SZ
#define MAX_LINE

#define NBANK(chip)

struct pca953x_reg_config {};

static const struct pca953x_reg_config pca953x_regs =;

static const struct pca953x_reg_config pca957x_regs =;

struct pca953x_chip {};

static int pca953x_bank_shift(struct pca953x_chip *chip)
{}

#define PCA953x_BANK_INPUT
#define PCA953x_BANK_OUTPUT
#define PCA953x_BANK_POLARITY
#define PCA953x_BANK_CONFIG

#define PCA957x_BANK_INPUT
#define PCA957x_BANK_POLARITY
#define PCA957x_BANK_BUSHOLD
#define PCA957x_BANK_CONFIG
#define PCA957x_BANK_OUTPUT

#define PCAL9xxx_BANK_IN_LATCH
#define PCAL9xxx_BANK_PULL_EN
#define PCAL9xxx_BANK_PULL_SEL
#define PCAL9xxx_BANK_IRQ_MASK
#define PCAL9xxx_BANK_IRQ_STAT

/*
 * We care about the following registers:
 * - Standard set, below 0x40, each port can be replicated up to 8 times
 *   - PCA953x standard
 *     Input port			0x00 + 0 * bank_size	R
 *     Output port			0x00 + 1 * bank_size	RW
 *     Polarity Inversion port		0x00 + 2 * bank_size	RW
 *     Configuration port		0x00 + 3 * bank_size	RW
 *   - PCA957x with mixed up registers
 *     Input port			0x00 + 0 * bank_size	R
 *     Polarity Inversion port		0x00 + 1 * bank_size	RW
 *     Bus hold port			0x00 + 2 * bank_size	RW
 *     Configuration port		0x00 + 4 * bank_size	RW
 *     Output port			0x00 + 5 * bank_size	RW
 *
 * - Extended set, above 0x40, often chip specific.
 *   - PCAL6524/PCAL9555A with custom PCAL IRQ handling:
 *     Input latch register		0x40 + 2 * bank_size	RW
 *     Pull-up/pull-down enable reg	0x40 + 3 * bank_size    RW
 *     Pull-up/pull-down select reg	0x40 + 4 * bank_size    RW
 *     Interrupt mask register		0x40 + 5 * bank_size	RW
 *     Interrupt status register	0x40 + 6 * bank_size	R
 *
 * - Registers with bit 0x80 set, the AI bit
 *   The bit is cleared and the registers fall into one of the
 *   categories above.
 */

static bool pca953x_check_register(struct pca953x_chip *chip, unsigned int reg,
				   u32 checkbank)
{}

/*
 * Unfortunately, whilst the PCAL6534 chip (and compatibles) broadly follow the
 * same register layout as the PCAL6524, the spacing of the registers has been
 * fundamentally altered by compacting them and thus does not obey the same
 * rules, including being able to use bit shifting to determine bank. These
 * chips hence need special handling here.
 */
static bool pcal6534_check_register(struct pca953x_chip *chip, unsigned int reg,
				    u32 checkbank)
{}

static bool pca953x_readable_register(struct device *dev, unsigned int reg)
{}

static bool pca953x_writeable_register(struct device *dev, unsigned int reg)
{}

static bool pca953x_volatile_register(struct device *dev, unsigned int reg)
{}

static const struct regmap_config pca953x_i2c_regmap =;

static const struct regmap_config pca953x_ai_i2c_regmap =;

static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off)
{}

/*
 * The PCAL6534 and compatible chips have altered bank alignment that doesn't
 * fit within the bit shifting scheme used for other devices.
 */
static u8 pcal6534_recalc_addr(struct pca953x_chip *chip, int reg, int off)
{}

static int pca953x_write_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
{}

static int pca953x_read_regs(struct pca953x_chip *chip, int reg, unsigned long *val)
{}

static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
{}

static int pca953x_gpio_direction_output(struct gpio_chip *gc,
		unsigned off, int val)
{}

static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
{}

static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
{}

static int pca953x_gpio_get_direction(struct gpio_chip *gc, unsigned off)
{}

static int pca953x_gpio_get_multiple(struct gpio_chip *gc,
				     unsigned long *mask, unsigned long *bits)
{}

static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
				      unsigned long *mask, unsigned long *bits)
{}

static int pca953x_gpio_set_pull_up_down(struct pca953x_chip *chip,
					 unsigned int offset,
					 unsigned long config)
{}

static int pca953x_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
				   unsigned long config)
{}

static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
{}

#ifdef CONFIG_GPIO_PCA953X_IRQ
static void pca953x_irq_mask(struct irq_data *d)
{}

static void pca953x_irq_unmask(struct irq_data *d)
{}

static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on)
{}

static void pca953x_irq_bus_lock(struct irq_data *d)
{}

static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
{}

static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
{}

static void pca953x_irq_shutdown(struct irq_data *d)
{}

static void pca953x_irq_print_chip(struct irq_data *data, struct seq_file *p)
{}

static const struct irq_chip pca953x_irq_chip =;

static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending)
{}

static irqreturn_t pca953x_irq_handler(int irq, void *devid)
{}

static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
{}

#else /* CONFIG_GPIO_PCA953X_IRQ */
static int pca953x_irq_setup(struct pca953x_chip *chip, int irq_base)
{
	struct i2c_client *client = chip->client;
	struct device *dev = &client->dev;

	if (client->irq && irq_base != -1 && (chip->driver_data & PCA_INT))
		dev_warn(dev, "interrupt support not compiled in\n");

	return 0;
}
#endif

static int device_pca95xx_init(struct pca953x_chip *chip)
{}

static int device_pca957x_init(struct pca953x_chip *chip)
{}

static void pca953x_disable_regulator(void *reg)
{}

static int pca953x_get_and_enable_regulator(struct pca953x_chip *chip)
{}

static int pca953x_probe(struct i2c_client *client)
{}

static int pca953x_regcache_sync(struct pca953x_chip *chip)
{}

static int pca953x_restore_context(struct pca953x_chip *chip)
{}

static void pca953x_save_context(struct pca953x_chip *chip)
{}

static int pca953x_suspend(struct device *dev)
{}

static int pca953x_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(pca953x_pm_ops, pca953x_suspend, pca953x_resume);

/* convenience to stop overlong match-table lines */
#define OF_653X(__nrgpio, __int)
#define OF_953X(__nrgpio, __int)
#define OF_957X(__nrgpio, __int)

static const struct of_device_id pca953x_dt_ids[] =;

MODULE_DEVICE_TABLE(of, pca953x_dt_ids);

static struct i2c_driver pca953x_driver =;

static int __init pca953x_init(void)
{}
/* register after i2c postcore initcall and before
 * subsys initcalls that may rely on these GPIOs
 */
subsys_initcall(pca953x_init);

static void __exit pca953x_exit(void)
{}
module_exit(pca953x_exit);

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();