0001
0002
0003
0004
0005
0006
0007 #include <linux/gpio/driver.h>
0008 #include <linux/i2c.h>
0009 #include <linux/module.h>
0010 #include <linux/mutex.h>
0011
0012 #define TPIC2810_WS_COMMAND 0x44
0013
0014
0015
0016
0017
0018
0019
0020
0021 struct tpic2810 {
0022 struct gpio_chip chip;
0023 struct i2c_client *client;
0024 u8 buffer;
0025 struct mutex lock;
0026 };
0027
0028 static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value);
0029
0030 static int tpic2810_get_direction(struct gpio_chip *chip,
0031 unsigned offset)
0032 {
0033
0034 return GPIO_LINE_DIRECTION_OUT;
0035 }
0036
0037 static int tpic2810_direction_input(struct gpio_chip *chip,
0038 unsigned offset)
0039 {
0040
0041 return -EINVAL;
0042 }
0043
0044 static int tpic2810_direction_output(struct gpio_chip *chip,
0045 unsigned offset, int value)
0046 {
0047
0048 tpic2810_set(chip, offset, value);
0049 return 0;
0050 }
0051
0052 static void tpic2810_set_mask_bits(struct gpio_chip *chip, u8 mask, u8 bits)
0053 {
0054 struct tpic2810 *gpio = gpiochip_get_data(chip);
0055 u8 buffer;
0056 int err;
0057
0058 mutex_lock(&gpio->lock);
0059
0060 buffer = gpio->buffer & ~mask;
0061 buffer |= (mask & bits);
0062
0063 err = i2c_smbus_write_byte_data(gpio->client, TPIC2810_WS_COMMAND,
0064 buffer);
0065 if (!err)
0066 gpio->buffer = buffer;
0067
0068 mutex_unlock(&gpio->lock);
0069 }
0070
0071 static void tpic2810_set(struct gpio_chip *chip, unsigned offset, int value)
0072 {
0073 tpic2810_set_mask_bits(chip, BIT(offset), value ? BIT(offset) : 0);
0074 }
0075
0076 static void tpic2810_set_multiple(struct gpio_chip *chip, unsigned long *mask,
0077 unsigned long *bits)
0078 {
0079 tpic2810_set_mask_bits(chip, *mask, *bits);
0080 }
0081
0082 static const struct gpio_chip template_chip = {
0083 .label = "tpic2810",
0084 .owner = THIS_MODULE,
0085 .get_direction = tpic2810_get_direction,
0086 .direction_input = tpic2810_direction_input,
0087 .direction_output = tpic2810_direction_output,
0088 .set = tpic2810_set,
0089 .set_multiple = tpic2810_set_multiple,
0090 .base = -1,
0091 .ngpio = 8,
0092 .can_sleep = true,
0093 };
0094
0095 static const struct of_device_id tpic2810_of_match_table[] = {
0096 { .compatible = "ti,tpic2810" },
0097 { }
0098 };
0099 MODULE_DEVICE_TABLE(of, tpic2810_of_match_table);
0100
0101 static int tpic2810_probe(struct i2c_client *client,
0102 const struct i2c_device_id *id)
0103 {
0104 struct tpic2810 *gpio;
0105 int ret;
0106
0107 gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL);
0108 if (!gpio)
0109 return -ENOMEM;
0110
0111 i2c_set_clientdata(client, gpio);
0112
0113 gpio->chip = template_chip;
0114 gpio->chip.parent = &client->dev;
0115
0116 gpio->client = client;
0117
0118 mutex_init(&gpio->lock);
0119
0120 ret = gpiochip_add_data(&gpio->chip, gpio);
0121 if (ret < 0) {
0122 dev_err(&client->dev, "Unable to register gpiochip\n");
0123 return ret;
0124 }
0125
0126 return 0;
0127 }
0128
0129 static int tpic2810_remove(struct i2c_client *client)
0130 {
0131 struct tpic2810 *gpio = i2c_get_clientdata(client);
0132
0133 gpiochip_remove(&gpio->chip);
0134
0135 return 0;
0136 }
0137
0138 static const struct i2c_device_id tpic2810_id_table[] = {
0139 { "tpic2810", },
0140 { }
0141 };
0142 MODULE_DEVICE_TABLE(i2c, tpic2810_id_table);
0143
0144 static struct i2c_driver tpic2810_driver = {
0145 .driver = {
0146 .name = "tpic2810",
0147 .of_match_table = tpic2810_of_match_table,
0148 },
0149 .probe = tpic2810_probe,
0150 .remove = tpic2810_remove,
0151 .id_table = tpic2810_id_table,
0152 };
0153 module_i2c_driver(tpic2810_driver);
0154
0155 MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>");
0156 MODULE_DESCRIPTION("TPIC2810 8-Bit LED Driver GPIO Driver");
0157 MODULE_LICENSE("GPL v2");