Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  htc-i2cpld.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Chip driver for an unknown CPLD chip found on omap850 HTC devices like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  the HTC Wizard and HTC Herald.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  The cpld is located on the i2c bus and acts as an input/output GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  extender.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  Based on work done in the linwizard project
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *  Copyright (C) 2008-2009 Angelo Arrifano <miknix@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/htcpld.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct htcpld_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	spinlock_t              lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	/* chip info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	u8                      reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	u8                      addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct device           *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct i2c_client	*client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	/* Output details */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	u8                      cache_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct gpio_chip        chip_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	/* Input details */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	u8                      cache_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	struct gpio_chip        chip_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	u16                     irqs_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	uint                    irq_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int                     nirqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	unsigned int		flow_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	 * Work structure to allow for setting values outside of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	 * possible interrupt context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct work_struct set_val_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) struct htcpld_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* irq info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u16                irqs_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	uint               irq_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	int                nirqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	uint               chained_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned int       int_reset_gpio_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	unsigned int       int_reset_gpio_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	/* htcpld info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct htcpld_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	unsigned int       nchips;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) /* There does not appear to be a way to proactively mask interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * on the htcpld chip itself.  So, we simply ignore interrupts that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * aren't desired. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static void htcpld_mask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static void htcpld_unmask(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	chip->irqs_enabled |= 1 << (data->irq - chip->irq_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static int htcpld_set_type(struct irq_data *data, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	if (flags & ~IRQ_TYPE_SENSE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	/* We only allow edge triggering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	chip->flow_type = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static struct irq_chip htcpld_muxed_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	.name         = "htcpld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	.irq_mask     = htcpld_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	.irq_unmask   = htcpld_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	.irq_set_type = htcpld_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* To properly dispatch IRQ events, we need to read from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * chip.  This is an I2C action that could possibly sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * (which is bad in interrupt context) -- so we use a threaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * interrupt handler to get around that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static irqreturn_t htcpld_handler(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	struct htcpld_data *htcpld = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	int irqpin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (!htcpld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		pr_debug("htcpld is null in ISR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 * For each chip, do a read of the chip and trigger any interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	 * desired.  The interrupts will be triggered from LSB to MSB (i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	 * bit 0 first, then bit 1, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * For chips that have no interrupt range specified, just skip 'em.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	for (i = 0; i < htcpld->nchips; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		struct htcpld_chip *chip = &htcpld->chip[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		unsigned long uval, old_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		if (!chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			pr_debug("chip %d is null in ISR\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		if (chip->nirqs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		if (!client) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			pr_debug("client %d is null in ISR\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		/* Scan the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		val = i2c_smbus_read_byte_data(client, chip->cache_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			/* Throw a warning and skip this chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			dev_warn(chip->dev, "Unable to read from chip: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 				 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		uval = (unsigned long)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		spin_lock_irqsave(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		/* Save away the old value so we can compare it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		old_val = chip->cache_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		/* Write the new value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		chip->cache_in = uval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		spin_unlock_irqrestore(&chip->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		 * For each bit in the data (starting at bit 0), trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		 * associated interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			unsigned oldb, newb, type = chip->flow_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			irq = chip->irq_start + irqpin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			/* Run the IRQ handler, but only if the bit value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			 * changed, and the proper flags are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			oldb = (old_val >> irqpin) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			newb = (uval >> irqpin) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			    (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 				pr_debug("fire IRQ %d\n", irqpin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 				generic_handle_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * In order to continue receiving interrupts, the int_reset_gpio must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 * be asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (htcpld->int_reset_gpio_hi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		gpio_set_value(htcpld->int_reset_gpio_hi, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (htcpld->int_reset_gpio_lo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		gpio_set_value(htcpld->int_reset_gpio_lo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * The GPIO set routines can be called from interrupt context, especially if,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * for example they're attached to the led-gpio framework and a trigger is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  * enabled.  As such, we declared work above in the htcpld_chip structure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * and that work is scheduled in the set routine.  The kernel can then run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  * the I2C functions, which will sleep, in process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	client = chip_data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (!client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	spin_lock_irqsave(&chip_data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		chip_data->cache_out |= (1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		chip_data->cache_out &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	spin_unlock_irqrestore(&chip_data->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	schedule_work(&(chip_data->set_val_work));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void htcpld_chip_set_ni(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	struct htcpld_chip *chip_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	chip_data = container_of(work, struct htcpld_chip, set_val_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	client = chip_data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	i2c_smbus_read_byte_data(client, chip_data->cache_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	u8 cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (!strncmp(chip->label, "htcpld-out", 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		cache = chip_data->cache_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	} else if (!strncmp(chip->label, "htcpld-in", 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		cache = chip_data->cache_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return (cache >> offset) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int htcpld_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 					unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	htcpld_chip_set(chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int htcpld_direction_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 					unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	 * No-op: this function can only be called on the input chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	 * We do however make sure the offset is within range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return (offset < chip->ngpio) ? 0 : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	struct htcpld_chip *chip_data = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (offset < chip_data->nirqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		return chip_data->irq_start + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void htcpld_chip_reset(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct htcpld_chip *chip_data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (!chip_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	i2c_smbus_read_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		client, (chip_data->cache_out = chip_data->reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int htcpld_setup_chip_irq(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		int chip_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	struct htcpld_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	unsigned int irq, irq_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	/* Get the platform and driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	htcpld = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	chip = &htcpld->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	/* Setup irq handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	irq_end = chip->irq_start + chip->nirqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	for (irq = chip->irq_start; irq < irq_end; irq++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		irq_set_chip_and_handler(irq, &htcpld_muxed_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 					 handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		irq_set_chip_data(irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int htcpld_register_chip_i2c(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		int chip_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	struct htcpld_core_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	struct htcpld_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct htcpld_chip_platform_data *plat_chip_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	struct i2c_adapter *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct i2c_board_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	/* Get the platform and driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	pdata = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	htcpld = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	chip = &htcpld->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	plat_chip_data = &pdata->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	adapter = i2c_get_adapter(pdata->i2c_adapter_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (!adapter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		/* Eek, no such I2C adapter!  Bail out. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		dev_warn(dev, "Chip at i2c address 0x%x: Invalid i2c adapter %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			 plat_chip_data->addr, pdata->i2c_adapter_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		dev_warn(dev, "i2c adapter %d non-functional\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			 pdata->i2c_adapter_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		i2c_put_adapter(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	memset(&info, 0, sizeof(struct i2c_board_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	info.addr = plat_chip_data->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	strlcpy(info.type, "htcpld-chip", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	info.platform_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	/* Add the I2C device.  This calls the probe() function. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	client = i2c_new_client_device(adapter, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (IS_ERR(client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		/* I2C device registration failed, contineu with the next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		dev_warn(dev, "Unable to add I2C device for 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			 plat_chip_data->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		i2c_put_adapter(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		return PTR_ERR(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	snprintf(client->name, I2C_NAME_SIZE, "Chip_0x%x", client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	chip->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	/* Reset the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	htcpld_chip_reset(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	chip->cache_in = i2c_smbus_read_byte_data(client, chip->cache_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static void htcpld_unregister_chip_i2c(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		int chip_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	struct htcpld_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/* Get the platform and driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	htcpld = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	chip = &htcpld->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	i2c_unregister_device(chip->client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int htcpld_register_chip_gpio(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		int chip_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	struct htcpld_core_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	struct htcpld_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	struct htcpld_chip_platform_data *plat_chip_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct gpio_chip *gpio_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/* Get the platform and driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	pdata = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	htcpld = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	chip = &htcpld->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	plat_chip_data = &pdata->chip[chip_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	/* Setup the GPIO chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	gpio_chip = &(chip->chip_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	gpio_chip->label           = "htcpld-out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	gpio_chip->parent             = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	gpio_chip->owner           = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	gpio_chip->get             = htcpld_chip_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	gpio_chip->set             = htcpld_chip_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	gpio_chip->direction_input = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	gpio_chip->direction_output = htcpld_direction_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	gpio_chip->base            = plat_chip_data->gpio_out_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	gpio_chip->ngpio           = plat_chip_data->num_gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	gpio_chip = &(chip->chip_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	gpio_chip->label           = "htcpld-in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	gpio_chip->parent             = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	gpio_chip->owner           = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	gpio_chip->get             = htcpld_chip_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	gpio_chip->set             = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	gpio_chip->direction_input = htcpld_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	gpio_chip->direction_output = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	gpio_chip->to_irq          = htcpld_chip_to_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	gpio_chip->base            = plat_chip_data->gpio_in_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	gpio_chip->ngpio           = plat_chip_data->num_gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	/* Add the GPIO chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	ret = gpiochip_add_data(&(chip->chip_out), chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		dev_warn(dev, "Unable to register output GPIOs for 0x%x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			 plat_chip_data->addr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	ret = gpiochip_add_data(&(chip->chip_in), chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		dev_warn(dev, "Unable to register input GPIOs for 0x%x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			 plat_chip_data->addr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		gpiochip_remove(&(chip->chip_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int htcpld_setup_chips(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	struct htcpld_core_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	/* Get the platform and driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	pdata = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	htcpld = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	/* Setup each chip's output GPIOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	htcpld->nchips = pdata->num_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	htcpld->chip = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 				    htcpld->nchips,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				    sizeof(struct htcpld_chip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 				    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	if (!htcpld->chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	/* Add the chips as best we can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	for (i = 0; i < htcpld->nchips; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		/* Setup the HTCPLD chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		htcpld->chip[i].reset = pdata->chip[i].reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		htcpld->chip[i].cache_out = pdata->chip[i].reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		htcpld->chip[i].cache_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		htcpld->chip[i].dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		htcpld->chip[i].irq_start = pdata->chip[i].irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		htcpld->chip[i].nirqs = pdata->chip[i].num_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		INIT_WORK(&(htcpld->chip[i].set_val_work), &htcpld_chip_set_ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		spin_lock_init(&(htcpld->chip[i].lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		/* Setup the interrupts for the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		if (htcpld->chained_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			ret = htcpld_setup_chip_irq(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		/* Register the chip with I2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		ret = htcpld_register_chip_i2c(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		/* Register the chips with the GPIO subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		ret = htcpld_register_chip_gpio(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			/* Unregister the chip from i2c and continue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			htcpld_unregister_chip_i2c(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		dev_info(dev, "Registered chip at 0x%x\n", pdata->chip[i].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int htcpld_core_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	struct htcpld_data *htcpld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	struct htcpld_core_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	pdata = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		dev_warn(dev, "Platform data not found for htcpld core!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	htcpld = devm_kzalloc(dev, sizeof(struct htcpld_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	if (!htcpld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	/* Find chained irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		htcpld->chained_irq = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		/* Setup the chained interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		ret = request_threaded_irq(htcpld->chained_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 					   NULL, htcpld_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 					   flags, pdev->name, htcpld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 			dev_warn(dev, "Unable to setup chained irq handler: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			device_init_wakeup(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	/* Set the driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	platform_set_drvdata(pdev, htcpld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	/* Setup the htcpld chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	ret = htcpld_setup_chips(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	/* Request the GPIO(s) for the int reset and set them up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (pdata->int_reset_gpio_hi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		ret = gpio_request(pdata->int_reset_gpio_hi, "htcpld-core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			 * If it failed, that sucks, but we can probably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			 * continue on without it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 			dev_warn(dev, "Unable to request int_reset_gpio_hi -- interrupts may not work\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			htcpld->int_reset_gpio_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			htcpld->int_reset_gpio_hi = pdata->int_reset_gpio_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			gpio_set_value(htcpld->int_reset_gpio_hi, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (pdata->int_reset_gpio_lo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		ret = gpio_request(pdata->int_reset_gpio_lo, "htcpld-core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			 * If it failed, that sucks, but we can probably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			 * continue on without it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 			dev_warn(dev, "Unable to request int_reset_gpio_lo -- interrupts may not work\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			htcpld->int_reset_gpio_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 			htcpld->int_reset_gpio_lo = pdata->int_reset_gpio_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			gpio_set_value(htcpld->int_reset_gpio_lo, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	dev_info(dev, "Initialized successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) /* The I2C Driver -- used internally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static const struct i2c_device_id htcpld_chip_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	{ "htcpld-chip", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static struct i2c_driver htcpld_chip_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		.name	= "htcpld-chip",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	.id_table = htcpld_chip_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* The Core Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static struct platform_driver htcpld_core_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		.name = "i2c-htcpld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int __init htcpld_core_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	/* Register the I2C Chip driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	ret = i2c_add_driver(&htcpld_chip_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	/* Probe for our chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) device_initcall(htcpld_core_init);