root/drivers/gpio/gpio-tpic2810.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tpic2810_get_direction
  2. tpic2810_direction_input
  3. tpic2810_direction_output
  4. tpic2810_set_mask_bits
  5. tpic2810_set
  6. tpic2810_set_multiple
  7. tpic2810_probe
  8. tpic2810_remove

   1 /*
   2  * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
   3  *      Andrew F. Davis <afd@ti.com>
   4  *
   5  * This program is free software; you can redistribute it and/or
   6  * modify it under the terms of the GNU General Public License version 2 as
   7  * published by the Free Software Foundation.
   8  *
   9  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  10  * kind, whether expressed or implied; without even the implied warranty
  11  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  * GNU General Public License version 2 for more details.
  13  */
  14 
  15 #include <linux/gpio/driver.h>
  16 #include <linux/i2c.h>
  17 #include <linux/module.h>
  18 #include <linux/mutex.h>
  19 
  20 #define TPIC2810_WS_COMMAND 0x44
  21 
  22 /**
  23  * struct tpic2810 - GPIO driver data
  24  * @chip: GPIO controller chip
  25  * @client: I2C device pointer
  26  * @buffer: Buffer for device register
  27  * @lock: Protects write sequences
  28  */
  29 struct tpic2810 {
  30         struct gpio_chip chip;
  31         struct i2c_client *client;
  32         u8 buffer;
  33         struct mutex lock;
  34 };
  35 
  36 static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value);
  37 
  38 static int tpic2810_get_direction(struct gpio_chip *chip,
  39                                   unsigned offset)
  40 {
  41         /* This device always output */
  42         return 0;
  43 }
  44 
  45 static int tpic2810_direction_input(struct gpio_chip *chip,
  46                                     unsigned offset)
  47 {
  48         /* This device is output only */
  49         return -EINVAL;
  50 }
  51 
  52 static int tpic2810_direction_output(struct gpio_chip *chip,
  53                                      unsigned offset, int value)
  54 {
  55         /* This device always output */
  56         tpic2810_set(chip, offset, value);
  57         return 0;
  58 }
  59 
  60 static void tpic2810_set_mask_bits(struct gpio_chip *chip, u8 mask, u8 bits)
  61 {
  62         struct tpic2810 *gpio = gpiochip_get_data(chip);
  63         u8 buffer;
  64         int err;
  65 
  66         mutex_lock(&gpio->lock);
  67 
  68         buffer = gpio->buffer & ~mask;
  69         buffer |= (mask & bits);
  70 
  71         err = i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
  72                                         buffer);
  73         if (!err)
  74                 gpio->buffer = buffer;
  75 
  76         mutex_unlock(&gpio->lock);
  77 }
  78 
  79 static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value)
  80 {
  81         tpic2810_set_mask_bits(chip, BIT(offset), value ? BIT(offset) : 0);
  82 }
  83 
  84 static void tpic2810_set_multiple(struct gpio_chip *chip, unsigned long *mask,
  85                                   unsigned long *bits)
  86 {
  87         tpic2810_set_mask_bits(chip, *mask, *bits);
  88 }
  89 
  90 static const struct gpio_chip template_chip = {
  91         .label                  = "tpic2810",
  92         .owner                  = THIS_MODULE,
  93         .get_direction          = tpic2810_get_direction,
  94         .direction_input        = tpic2810_direction_input,
  95         .direction_output       = tpic2810_direction_output,
  96         .set                    = tpic2810_set,
  97         .set_multiple           = tpic2810_set_multiple,
  98         .base                   = -1,
  99         .ngpio                  = 8,
 100         .can_sleep              = true,
 101 };
 102 
 103 static const struct of_device_id tpic2810_of_match_table[] = {
 104         { .compatible = "ti,tpic2810" },
 105         { /* sentinel */ }
 106 };
 107 MODULE_DEVICE_TABLE(of, tpic2810_of_match_table);
 108 
 109 static int tpic2810_probe(struct i2c_client *client,
 110                           const struct i2c_device_id *id)
 111 {
 112         struct tpic2810 *gpio;
 113         int ret;
 114 
 115         gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
 116         if (!gpio)
 117                 return -ENOMEM;
 118 
 119         i2c_set_clientdata(client, gpio);
 120 
 121         gpio->chip = template_chip;
 122         gpio->chip.parent = &client->dev;
 123 
 124         gpio->client = client;
 125 
 126         mutex_init(&gpio->lock);
 127 
 128         ret = gpiochip_add_data(&gpio->chip, gpio);
 129         if (ret < 0) {
 130                 dev_err(&client->dev, "Unable to register gpiochip\n");
 131                 return ret;
 132         }
 133 
 134         return 0;
 135 }
 136 
 137 static int tpic2810_remove(struct i2c_client *client)
 138 {
 139         struct tpic2810 *gpio = i2c_get_clientdata(client);
 140 
 141         gpiochip_remove(&gpio->chip);
 142 
 143         return 0;
 144 }
 145 
 146 static const struct i2c_device_id tpic2810_id_table[] = {
 147         { "tpic2810", },
 148         { /* sentinel */ }
 149 };
 150 MODULE_DEVICE_TABLE(i2c, tpic2810_id_table);
 151 
 152 static struct i2c_driver tpic2810_driver = {
 153         .driver = {
 154                 .name = "tpic2810",
 155                 .of_match_table = tpic2810_of_match_table,
 156         },
 157         .probe = tpic2810_probe,
 158         .remove = tpic2810_remove,
 159         .id_table = tpic2810_id_table,
 160 };
 161 module_i2c_driver(tpic2810_driver);
 162 
 163 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
 164 MODULE_DESCRIPTION("TPIC2810 8-Bit LED Driver GPIO Driver");
 165 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */