static int __devinit pca953x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pca953x_platform_data *pdata; struct pca953x_chip *chip; int ret; pdata = client->dev.platform_data; if (pdata == NULL) { dev_dbg(&client->dev, "no platform data\n"); return -EINVAL; } chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->client = client; chip->gpio_start = pdata->gpio_base; /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ pca953x_setup_gpio(chip, id->driver_data); ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); if (ret) goto out_failed; ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); if (ret) goto out_failed; /* set platform specific polarity inversion */ ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); if (ret) goto out_failed; ret = gpiochip_add(&chip->gpio_chip); if (ret) goto out_failed; if (pdata->setup) { ret = pdata->setup(client, chip->gpio_chip.base, chip->gpio_chip.ngpio, pdata->context); if (ret < 0) dev_warn(&client->dev, "setup failed, %d\n", ret); } i2c_set_clientdata(client, chip); return 0; out_failed: kfree(chip); return ret; }
static int pca953x_suspend(struct i2c_client *client, pm_message_t state) { struct pca953x_platform_data *pdata = client->dev.platform_data; struct pca953x_chip *chip = i2c_get_clientdata(client); int ret; ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); if (ret) return ret; ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); return ret; }
static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) { uint16_t cur_stat; uint16_t old_stat; uint16_t pending; uint16_t trigger; int ret; ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat); if (ret) return 0; /* Remove output pins from the equation */ cur_stat &= chip->reg_direction; old_stat = chip->irq_stat; trigger = (cur_stat ^ old_stat) & chip->irq_mask; if (!trigger) return 0; chip->irq_stat = cur_stat; pending = (old_stat & chip->irq_trig_fall) | (cur_stat & chip->irq_trig_raise); pending &= trigger; return pending; }
static int pca953x_irq_setup(struct pca953x_chip *chip, const struct i2c_device_id *id) { struct i2c_client *client = chip->client; struct pca953x_platform_data *pdata = client->dev.platform_data; int ret; if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT)) { int lvl; ret = pca953x_read_reg(chip, PCA953X_INPUT, &chip->irq_stat); if (ret) goto out_failed; /* * There is no way to know which GPIO line generated the * interrupt. We have to rely on the previous read for * this purpose. */ chip->irq_stat &= chip->reg_direction; chip->irq_base = pdata->irq_base; mutex_init(&chip->irq_lock); for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { int irq = lvl + chip->irq_base; irq_set_chip_data(irq, chip); irq_set_chip_and_handler(irq, &pca953x_irq_chip, handle_edge_irq); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else irq_set_noprobe(irq); #endif } ret = request_threaded_irq(client->irq, NULL, pca953x_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(&client->dev), chip); if (ret) { dev_err(&client->dev, "failed to request irq %d\n", client->irq); goto out_failed; } chip->gpio_chip.to_irq = pca953x_gpio_to_irq; } return 0; out_failed: chip->irq_base = -1; return ret; }
static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { struct pca953x_chip *chip; uint16_t reg_val; int ret; chip = container_of(gc, struct pca953x_chip, gpio_chip); ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); if (ret < 0) { /* NOTE: diagnostic already emitted; that's all we should * do unless gpio_*_value_cansleep() calls become different * from their nonsleeping siblings (and report faults). */ return 0; } return (reg_val & (1u << off)) ? 1 : 0; }
static int pca953x_resume(struct i2c_client *client) { struct pca953x_platform_data *pdata = client->dev.platform_data; struct pca953x_chip *chip = i2c_get_clientdata(client); uint16_t reg_val; int ret = 0; /* set platform specific polarity inversion */ ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); if (ret) return ret; ret = pca953x_write_reg(chip, PCA953X_OUTPUT, chip->reg_output); if (ret) return ret; ret = pca953x_write_reg(chip, PCA953X_DIRECTION, chip->reg_direction); if (ret) return ret; ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); return ret; }
static int __devinit pca953x_probe(struct i2c_client *client) { struct pca953x_platform_data *pdata; struct pca953x_chip *chip; int ret, i; const struct pca953x_desc *id = NULL; pdata = client->dev.platform_data; if (pdata == NULL) return -ENODEV; /* this loop vanishes when we get i2c_device_id */ for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++) if (!strcmp(pca953x_descs[i].name, client->name)) { id = pca953x_descs + i; break; } if (!id) return -ENODEV; chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; chip->client = client; chip->gpio_start = pdata->gpio_base; /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ pca953x_setup_gpio(chip, id->driver_data); ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); if (ret) goto out_failed; ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); if (ret) goto out_failed; /* set platform specific polarity inversion */ ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); if (ret) goto out_failed; ret = gpiochip_add(&chip->gpio_chip); if (ret) goto out_failed; if (pdata->setup) { ret = pdata->setup(client, chip->gpio_chip.base, chip->gpio_chip.ngpio, pdata->context); if (ret < 0) dev_warn(&client->dev, "setup failed, %d\n", ret); } i2c_set_clientdata(client, chip); return 0; out_failed: kfree(chip); return ret; }
static int __devinit pca953x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pca953x_platform_data *pdata; struct pca953x_chip *chip; int ret; chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; pdata = client->dev.platform_data; if (pdata == NULL) { pdata = pca953x_get_alt_pdata(client); /* * Unlike normal platform_data, this is allocated * dynamically and must be freed in the driver */ chip->dyn_pdata = pdata; } if (pdata == NULL) { dev_dbg(&client->dev, "no platform data\n"); ret = -EINVAL; goto out_failed; } chip->client = client; chip->gpio_start = pdata->gpio_base; chip->names = pdata->names; mutex_init(&chip->i2c_lock); /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS); ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); if (ret) goto out_failed; ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); if (ret) goto out_failed; /* set platform specific polarity inversion */ ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); if (ret) goto out_failed; ret = pca953x_irq_setup(chip, id); if (ret) goto out_failed; ret = gpiochip_add(&chip->gpio_chip); if (ret) goto out_failed_irq; if (pdata->setup) { ret = pdata->setup(client, chip->gpio_chip.base, chip->gpio_chip.ngpio, pdata->context); if (ret < 0) dev_warn(&client->dev, "setup failed, %d\n", ret); } i2c_set_clientdata(client, chip); return 0; out_failed_irq: pca953x_irq_teardown(chip); out_failed: kfree(chip->dyn_pdata); kfree(chip); return ret; }