in gpio-pcf857x.c [233:393]
static int pcf857x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *np = client->dev.of_node;
struct pcf857x *gpio;
unsigned int n_latch = 0;
int status;
if (IS_ENABLED(CONFIG_OF) && np)
of_property_read_u32(np, "lines-initial-states", &n_latch);
else if (pdata)
n_latch = pdata->n_latch;
else
dev_dbg(&client->dev, "no platform data\n");
/* Allocate, initialize, and register this gpio_chip. */
gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
if (!gpio)
return -ENOMEM;
mutex_init(&gpio->lock);
gpio->chip.base = pdata ? pdata->gpio_base : -1;
gpio->chip.can_sleep = true;
gpio->chip.parent = &client->dev;
gpio->chip.owner = THIS_MODULE;
gpio->chip.get = pcf857x_get;
gpio->chip.set = pcf857x_set;
gpio->chip.direction_input = pcf857x_input;
gpio->chip.direction_output = pcf857x_output;
gpio->chip.ngpio = id->driver_data;
/* NOTE: the OnSemi jlc1562b is also largely compatible with
* these parts, notably for output. It has a low-resolution
* DAC instead of pin change IRQs; and its inputs can be the
* result of comparators.
*/
/* 8574 addresses are 0x20..0x27; 8574a uses 0x38..0x3f;
* 9670, 9672, 9764, and 9764a use quite a variety.
*
* NOTE: we don't distinguish here between *4 and *4a parts.
*/
if (gpio->chip.ngpio == 8) {
gpio->write = i2c_write_le8;
gpio->read = i2c_read_le8;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE))
status = -EIO;
/* fail if there's no chip present */
else
status = i2c_smbus_read_byte(client);
/* '75/'75c addresses are 0x20..0x27, just like the '74;
* the '75c doesn't have a current source pulling high.
* 9671, 9673, and 9765 use quite a variety of addresses.
*
* NOTE: we don't distinguish here between '75 and '75c parts.
*/
} else if (gpio->chip.ngpio == 16) {
gpio->write = i2c_write_le16;
gpio->read = i2c_read_le16;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
status = -EIO;
/* fail if there's no chip present */
else
status = i2c_read_le16(client);
} else {
dev_dbg(&client->dev, "unsupported number of gpios\n");
status = -EINVAL;
}
if (status < 0)
goto fail;
gpio->chip.label = client->name;
gpio->client = client;
i2c_set_clientdata(client, gpio);
/* NOTE: these chips have strange "quasi-bidirectional" I/O pins.
* We can't actually know whether a pin is configured (a) as output
* and driving the signal low, or (b) as input and reporting a low
* value ... without knowing the last value written since the chip
* came out of reset (if any). We can't read the latched output.
*
* In short, the only reliable solution for setting up pin direction
* is to do it explicitly. The setup() method can do that, but it
* may cause transient glitching since it can't know the last value
* written (some pins may need to be driven low).
*
* Using n_latch avoids that trouble. When left initialized to zero,
* our software copy of the "latch" then matches the chip's all-ones
* reset state. Otherwise it flags pins to be driven low.
*/
gpio->out = ~n_latch;
gpio->status = gpio->read(gpio->client);
/* Enable irqchip if we have an interrupt */
if (client->irq) {
struct gpio_irq_chip *girq;
gpio->irqchip.name = "pcf857x";
gpio->irqchip.irq_enable = pcf857x_irq_enable;
gpio->irqchip.irq_disable = pcf857x_irq_disable;
gpio->irqchip.irq_ack = noop;
gpio->irqchip.irq_mask = noop;
gpio->irqchip.irq_unmask = noop;
gpio->irqchip.irq_set_wake = pcf857x_irq_set_wake;
gpio->irqchip.irq_bus_lock = pcf857x_irq_bus_lock;
gpio->irqchip.irq_bus_sync_unlock = pcf857x_irq_bus_sync_unlock;
status = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf857x_irq, IRQF_ONESHOT |
IRQF_TRIGGER_FALLING | IRQF_SHARED,
dev_name(&client->dev), gpio);
if (status)
goto fail;
girq = &gpio->chip.irq;
girq->chip = &gpio->irqchip;
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
girq->parents = NULL;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_level_irq;
girq->threaded = true;
}
status = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio);
if (status < 0)
goto fail;
/* Let platform code set up the GPIOs and their users.
* Now is the first time anyone could use them.
*/
if (pdata && pdata->setup) {
status = pdata->setup(client,
gpio->chip.base, gpio->chip.ngpio,
pdata->context);
if (status < 0)
dev_warn(&client->dev, "setup --> %d\n", status);
}
dev_info(&client->dev, "probed\n");
return 0;
fail:
dev_dbg(&client->dev, "probe error %d for '%s'\n", status,
client->name);
return status;
}