root/drivers/gpio/gpio-lp3943.c

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

DEFINITIONS

This source file includes following definitions.
  1. lp3943_gpio_request
  2. lp3943_gpio_free
  3. lp3943_gpio_set_mode
  4. lp3943_gpio_direction_input
  5. lp3943_get_gpio_in_status
  6. lp3943_get_gpio_out_status
  7. lp3943_gpio_get
  8. lp3943_gpio_set
  9. lp3943_gpio_direction_output
  10. lp3943_gpio_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * TI/National Semiconductor LP3943 GPIO driver
   4  *
   5  * Copyright 2013 Texas Instruments
   6  *
   7  * Author: Milo Kim <milo.kim@ti.com>
   8  */
   9 
  10 #include <linux/bitops.h>
  11 #include <linux/err.h>
  12 #include <linux/gpio/driver.h>
  13 #include <linux/i2c.h>
  14 #include <linux/mfd/lp3943.h>
  15 #include <linux/module.h>
  16 #include <linux/platform_device.h>
  17 #include <linux/slab.h>
  18 
  19 enum lp3943_gpios {
  20         LP3943_GPIO1,
  21         LP3943_GPIO2,
  22         LP3943_GPIO3,
  23         LP3943_GPIO4,
  24         LP3943_GPIO5,
  25         LP3943_GPIO6,
  26         LP3943_GPIO7,
  27         LP3943_GPIO8,
  28         LP3943_GPIO9,
  29         LP3943_GPIO10,
  30         LP3943_GPIO11,
  31         LP3943_GPIO12,
  32         LP3943_GPIO13,
  33         LP3943_GPIO14,
  34         LP3943_GPIO15,
  35         LP3943_GPIO16,
  36         LP3943_MAX_GPIO,
  37 };
  38 
  39 struct lp3943_gpio {
  40         struct gpio_chip chip;
  41         struct lp3943 *lp3943;
  42         u16 input_mask;         /* 1 = GPIO is input direction, 0 = output */
  43 };
  44 
  45 static int lp3943_gpio_request(struct gpio_chip *chip, unsigned offset)
  46 {
  47         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
  48         struct lp3943 *lp3943 = lp3943_gpio->lp3943;
  49 
  50         /* Return an error if the pin is already assigned */
  51         if (test_and_set_bit(offset, &lp3943->pin_used))
  52                 return -EBUSY;
  53 
  54         return 0;
  55 }
  56 
  57 static void lp3943_gpio_free(struct gpio_chip *chip, unsigned offset)
  58 {
  59         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
  60         struct lp3943 *lp3943 = lp3943_gpio->lp3943;
  61 
  62         clear_bit(offset, &lp3943->pin_used);
  63 }
  64 
  65 static int lp3943_gpio_set_mode(struct lp3943_gpio *lp3943_gpio, u8 offset,
  66                                 u8 val)
  67 {
  68         struct lp3943 *lp3943 = lp3943_gpio->lp3943;
  69         const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
  70 
  71         return lp3943_update_bits(lp3943, mux[offset].reg, mux[offset].mask,
  72                                   val << mux[offset].shift);
  73 }
  74 
  75 static int lp3943_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  76 {
  77         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
  78 
  79         lp3943_gpio->input_mask |= BIT(offset);
  80 
  81         return lp3943_gpio_set_mode(lp3943_gpio, offset, LP3943_GPIO_IN);
  82 }
  83 
  84 static int lp3943_get_gpio_in_status(struct lp3943_gpio *lp3943_gpio,
  85                                      struct gpio_chip *chip, unsigned offset)
  86 {
  87         u8 addr, read;
  88         int err;
  89 
  90         switch (offset) {
  91         case LP3943_GPIO1 ... LP3943_GPIO8:
  92                 addr = LP3943_REG_GPIO_A;
  93                 break;
  94         case LP3943_GPIO9 ... LP3943_GPIO16:
  95                 addr = LP3943_REG_GPIO_B;
  96                 offset = offset - 8;
  97                 break;
  98         default:
  99                 return -EINVAL;
 100         }
 101 
 102         err = lp3943_read_byte(lp3943_gpio->lp3943, addr, &read);
 103         if (err)
 104                 return err;
 105 
 106         return !!(read & BIT(offset));
 107 }
 108 
 109 static int lp3943_get_gpio_out_status(struct lp3943_gpio *lp3943_gpio,
 110                                       struct gpio_chip *chip, unsigned offset)
 111 {
 112         struct lp3943 *lp3943 = lp3943_gpio->lp3943;
 113         const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
 114         u8 read;
 115         int err;
 116 
 117         err = lp3943_read_byte(lp3943, mux[offset].reg, &read);
 118         if (err)
 119                 return err;
 120 
 121         read = (read & mux[offset].mask) >> mux[offset].shift;
 122 
 123         if (read == LP3943_GPIO_OUT_HIGH)
 124                 return 1;
 125         else if (read == LP3943_GPIO_OUT_LOW)
 126                 return 0;
 127         else
 128                 return -EINVAL;
 129 }
 130 
 131 static int lp3943_gpio_get(struct gpio_chip *chip, unsigned offset)
 132 {
 133         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
 134 
 135         /*
 136          * Limitation:
 137          *   LP3943 doesn't have the GPIO direction register. It provides
 138          *   only input and output status registers.
 139          *   So, direction info is required to handle the 'get' operation.
 140          *   This variable is updated whenever the direction is changed and
 141          *   it is used here.
 142          */
 143 
 144         if (lp3943_gpio->input_mask & BIT(offset))
 145                 return lp3943_get_gpio_in_status(lp3943_gpio, chip, offset);
 146         else
 147                 return lp3943_get_gpio_out_status(lp3943_gpio, chip, offset);
 148 }
 149 
 150 static void lp3943_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 151 {
 152         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
 153         u8 data;
 154 
 155         if (value)
 156                 data = LP3943_GPIO_OUT_HIGH;
 157         else
 158                 data = LP3943_GPIO_OUT_LOW;
 159 
 160         lp3943_gpio_set_mode(lp3943_gpio, offset, data);
 161 }
 162 
 163 static int lp3943_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
 164                                         int value)
 165 {
 166         struct lp3943_gpio *lp3943_gpio = gpiochip_get_data(chip);
 167 
 168         lp3943_gpio_set(chip, offset, value);
 169         lp3943_gpio->input_mask &= ~BIT(offset);
 170 
 171         return 0;
 172 }
 173 
 174 static const struct gpio_chip lp3943_gpio_chip = {
 175         .label                  = "lp3943",
 176         .owner                  = THIS_MODULE,
 177         .request                = lp3943_gpio_request,
 178         .free                   = lp3943_gpio_free,
 179         .direction_input        = lp3943_gpio_direction_input,
 180         .get                    = lp3943_gpio_get,
 181         .direction_output       = lp3943_gpio_direction_output,
 182         .set                    = lp3943_gpio_set,
 183         .base                   = -1,
 184         .ngpio                  = LP3943_MAX_GPIO,
 185         .can_sleep              = 1,
 186 };
 187 
 188 static int lp3943_gpio_probe(struct platform_device *pdev)
 189 {
 190         struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent);
 191         struct lp3943_gpio *lp3943_gpio;
 192 
 193         lp3943_gpio = devm_kzalloc(&pdev->dev, sizeof(*lp3943_gpio),
 194                                 GFP_KERNEL);
 195         if (!lp3943_gpio)
 196                 return -ENOMEM;
 197 
 198         lp3943_gpio->lp3943 = lp3943;
 199         lp3943_gpio->chip = lp3943_gpio_chip;
 200         lp3943_gpio->chip.parent = &pdev->dev;
 201 
 202         platform_set_drvdata(pdev, lp3943_gpio);
 203 
 204         return devm_gpiochip_add_data(&pdev->dev, &lp3943_gpio->chip,
 205                                       lp3943_gpio);
 206 }
 207 
 208 static const struct of_device_id lp3943_gpio_of_match[] = {
 209         { .compatible = "ti,lp3943-gpio", },
 210         { }
 211 };
 212 MODULE_DEVICE_TABLE(of, lp3943_gpio_of_match);
 213 
 214 static struct platform_driver lp3943_gpio_driver = {
 215         .probe = lp3943_gpio_probe,
 216         .driver = {
 217                 .name = "lp3943-gpio",
 218                 .of_match_table = lp3943_gpio_of_match,
 219         },
 220 };
 221 module_platform_driver(lp3943_gpio_driver);
 222 
 223 MODULE_DESCRIPTION("LP3943 GPIO driver");
 224 MODULE_ALIAS("platform:lp3943-gpio");
 225 MODULE_AUTHOR("Milo Kim");
 226 MODULE_LICENSE("GPL");

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