static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; uint16_t reg_val; int ret; chip = container_of(gc, struct pca953x_chip, gpio_chip); /* set output level */ if (val) reg_val = chip->reg_output | (1u << off); else reg_val = chip->reg_output & ~(1u << off); ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); if (ret) return ret; chip->reg_output = reg_val; /* then direction */ reg_val = chip->reg_direction & ~(1u << off); ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); if (ret) return ret; chip->reg_direction = reg_val; return 0; }
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_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 pca953x_gpio_direction_input(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); reg_val = chip->reg_direction | (1u << off); ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); if (ret) return ret; chip->reg_direction = reg_val; return 0; }
static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { struct pca953x_chip *chip; uint16_t reg_val; int ret; chip = container_of(gc, struct pca953x_chip, gpio_chip); if (val) reg_val = chip->reg_output | (1u << off); else reg_val = chip->reg_output & ~(1u << off); ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); if (ret) return; chip->reg_output = reg_val; }
static int pca953x_gpio_direction_input(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); mutex_lock(&chip->i2c_lock); reg_val = chip->reg_direction | (1u << off); ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); if (ret) goto exit; chip->reg_direction = reg_val; ret = 0; exit: mutex_unlock(&chip->i2c_lock); 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; }