Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * GPIO driver for Exar XR17V35X chip
0004  *
0005  * Copyright (C) 2015 Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
0006  */
0007 
0008 #include <linux/bitops.h>
0009 #include <linux/device.h>
0010 #include <linux/gpio/driver.h>
0011 #include <linux/idr.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/pci.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/regmap.h>
0018 
0019 #define EXAR_OFFSET_MPIOLVL_LO 0x90
0020 #define EXAR_OFFSET_MPIOSEL_LO 0x93
0021 #define EXAR_OFFSET_MPIOLVL_HI 0x96
0022 #define EXAR_OFFSET_MPIOSEL_HI 0x99
0023 
0024 #define DRIVER_NAME "gpio_exar"
0025 
0026 static DEFINE_IDA(ida_index);
0027 
0028 struct exar_gpio_chip {
0029     struct gpio_chip gpio_chip;
0030     struct regmap *regmap;
0031     int index;
0032     char name[20];
0033     unsigned int first_pin;
0034 };
0035 
0036 static unsigned int
0037 exar_offset_to_sel_addr(struct exar_gpio_chip *exar_gpio, unsigned int offset)
0038 {
0039     return (offset + exar_gpio->first_pin) / 8 ? EXAR_OFFSET_MPIOSEL_HI
0040                            : EXAR_OFFSET_MPIOSEL_LO;
0041 }
0042 
0043 static unsigned int
0044 exar_offset_to_lvl_addr(struct exar_gpio_chip *exar_gpio, unsigned int offset)
0045 {
0046     return (offset + exar_gpio->first_pin) / 8 ? EXAR_OFFSET_MPIOLVL_HI
0047                            : EXAR_OFFSET_MPIOLVL_LO;
0048 }
0049 
0050 static unsigned int
0051 exar_offset_to_bit(struct exar_gpio_chip *exar_gpio, unsigned int offset)
0052 {
0053     return (offset + exar_gpio->first_pin) % 8;
0054 }
0055 
0056 static int exar_get_direction(struct gpio_chip *chip, unsigned int offset)
0057 {
0058     struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
0059     unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset);
0060     unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
0061 
0062     if (regmap_test_bits(exar_gpio->regmap, addr, BIT(bit)))
0063         return GPIO_LINE_DIRECTION_IN;
0064 
0065     return GPIO_LINE_DIRECTION_OUT;
0066 }
0067 
0068 static int exar_get_value(struct gpio_chip *chip, unsigned int offset)
0069 {
0070     struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
0071     unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset);
0072     unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
0073 
0074     return !!(regmap_test_bits(exar_gpio->regmap, addr, BIT(bit)));
0075 }
0076 
0077 static void exar_set_value(struct gpio_chip *chip, unsigned int offset,
0078                int value)
0079 {
0080     struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
0081     unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset);
0082     unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
0083 
0084     if (value)
0085         regmap_set_bits(exar_gpio->regmap, addr, BIT(bit));
0086     else
0087         regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit));
0088 }
0089 
0090 static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
0091                  int value)
0092 {
0093     struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
0094     unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset);
0095     unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
0096 
0097     exar_set_value(chip, offset, value);
0098     regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit));
0099 
0100     return 0;
0101 }
0102 
0103 static int exar_direction_input(struct gpio_chip *chip, unsigned int offset)
0104 {
0105     struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
0106     unsigned int addr = exar_offset_to_sel_addr(exar_gpio, offset);
0107     unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
0108 
0109     regmap_set_bits(exar_gpio->regmap, addr, BIT(bit));
0110 
0111     return 0;
0112 }
0113 
0114 static void exar_devm_ida_free(void *data)
0115 {
0116     struct exar_gpio_chip *exar_gpio = data;
0117 
0118     ida_free(&ida_index, exar_gpio->index);
0119 }
0120 
0121 static const struct regmap_config exar_regmap_config = {
0122     .name       = "exar-gpio",
0123     .reg_bits   = 16,
0124     .val_bits   = 8,
0125 };
0126 
0127 static int gpio_exar_probe(struct platform_device *pdev)
0128 {
0129     struct device *dev = &pdev->dev;
0130     struct pci_dev *pcidev = to_pci_dev(dev->parent);
0131     struct exar_gpio_chip *exar_gpio;
0132     u32 first_pin, ngpios;
0133     void __iomem *p;
0134     int index, ret;
0135 
0136     /*
0137      * The UART driver must have mapped region 0 prior to registering this
0138      * device - use it.
0139      */
0140     p = pcim_iomap_table(pcidev)[0];
0141     if (!p)
0142         return -ENOMEM;
0143 
0144     ret = device_property_read_u32(dev, "exar,first-pin", &first_pin);
0145     if (ret)
0146         return ret;
0147 
0148     ret = device_property_read_u32(dev, "ngpios", &ngpios);
0149     if (ret)
0150         return ret;
0151 
0152     exar_gpio = devm_kzalloc(dev, sizeof(*exar_gpio), GFP_KERNEL);
0153     if (!exar_gpio)
0154         return -ENOMEM;
0155 
0156     /*
0157      * We don't need to check the return values of mmio regmap operations (unless
0158      * the regmap has a clock attached which is not the case here).
0159      */
0160     exar_gpio->regmap = devm_regmap_init_mmio(dev, p, &exar_regmap_config);
0161     if (IS_ERR(exar_gpio->regmap))
0162         return PTR_ERR(exar_gpio->regmap);
0163 
0164     index = ida_alloc(&ida_index, GFP_KERNEL);
0165     if (index < 0)
0166         return index;
0167 
0168     ret = devm_add_action_or_reset(dev, exar_devm_ida_free, exar_gpio);
0169     if (ret)
0170         return ret;
0171 
0172     sprintf(exar_gpio->name, "exar_gpio%d", index);
0173     exar_gpio->gpio_chip.label = exar_gpio->name;
0174     exar_gpio->gpio_chip.parent = dev;
0175     exar_gpio->gpio_chip.direction_output = exar_direction_output;
0176     exar_gpio->gpio_chip.direction_input = exar_direction_input;
0177     exar_gpio->gpio_chip.get_direction = exar_get_direction;
0178     exar_gpio->gpio_chip.get = exar_get_value;
0179     exar_gpio->gpio_chip.set = exar_set_value;
0180     exar_gpio->gpio_chip.base = -1;
0181     exar_gpio->gpio_chip.ngpio = ngpios;
0182     exar_gpio->index = index;
0183     exar_gpio->first_pin = first_pin;
0184 
0185     ret = devm_gpiochip_add_data(dev, &exar_gpio->gpio_chip, exar_gpio);
0186     if (ret)
0187         return ret;
0188 
0189     platform_set_drvdata(pdev, exar_gpio);
0190 
0191     return 0;
0192 }
0193 
0194 static struct platform_driver gpio_exar_driver = {
0195     .probe  = gpio_exar_probe,
0196     .driver = {
0197         .name = DRIVER_NAME,
0198     },
0199 };
0200 
0201 module_platform_driver(gpio_exar_driver);
0202 
0203 MODULE_ALIAS("platform:" DRIVER_NAME);
0204 MODULE_DESCRIPTION("Exar GPIO driver");
0205 MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");
0206 MODULE_LICENSE("GPL");