0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/spinlock.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/pci.h>
0014 #include <linux/gpio/driver.h>
0015 #include <linux/mfd/rdc321x.h>
0016 #include <linux/slab.h>
0017
0018 struct rdc321x_gpio {
0019 spinlock_t lock;
0020 struct pci_dev *sb_pdev;
0021 u32 data_reg[2];
0022 int reg1_ctrl_base;
0023 int reg1_data_base;
0024 int reg2_ctrl_base;
0025 int reg2_data_base;
0026 struct gpio_chip chip;
0027 };
0028
0029
0030 static int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
0031 {
0032 struct rdc321x_gpio *gpch;
0033 u32 value = 0;
0034 int reg;
0035
0036 gpch = gpiochip_get_data(chip);
0037 reg = gpio < 32 ? gpch->reg1_data_base : gpch->reg2_data_base;
0038
0039 spin_lock(&gpch->lock);
0040 pci_write_config_dword(gpch->sb_pdev, reg,
0041 gpch->data_reg[gpio < 32 ? 0 : 1]);
0042 pci_read_config_dword(gpch->sb_pdev, reg, &value);
0043 spin_unlock(&gpch->lock);
0044
0045 return (1 << (gpio & 0x1f)) & value ? 1 : 0;
0046 }
0047
0048 static void rdc_gpio_set_value_impl(struct gpio_chip *chip,
0049 unsigned gpio, int value)
0050 {
0051 struct rdc321x_gpio *gpch;
0052 int reg = (gpio < 32) ? 0 : 1;
0053
0054 gpch = gpiochip_get_data(chip);
0055
0056 if (value)
0057 gpch->data_reg[reg] |= 1 << (gpio & 0x1f);
0058 else
0059 gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f));
0060
0061 pci_write_config_dword(gpch->sb_pdev,
0062 reg ? gpch->reg2_data_base : gpch->reg1_data_base,
0063 gpch->data_reg[reg]);
0064 }
0065
0066
0067 static void rdc_gpio_set_value(struct gpio_chip *chip,
0068 unsigned gpio, int value)
0069 {
0070 struct rdc321x_gpio *gpch;
0071
0072 gpch = gpiochip_get_data(chip);
0073 spin_lock(&gpch->lock);
0074 rdc_gpio_set_value_impl(chip, gpio, value);
0075 spin_unlock(&gpch->lock);
0076 }
0077
0078 static int rdc_gpio_config(struct gpio_chip *chip,
0079 unsigned gpio, int value)
0080 {
0081 struct rdc321x_gpio *gpch;
0082 int err;
0083 u32 reg;
0084
0085 gpch = gpiochip_get_data(chip);
0086
0087 spin_lock(&gpch->lock);
0088 err = pci_read_config_dword(gpch->sb_pdev, gpio < 32 ?
0089 gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, ®);
0090 if (err)
0091 goto unlock;
0092
0093 reg |= 1 << (gpio & 0x1f);
0094
0095 err = pci_write_config_dword(gpch->sb_pdev, gpio < 32 ?
0096 gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, reg);
0097 if (err)
0098 goto unlock;
0099
0100 rdc_gpio_set_value_impl(chip, gpio, value);
0101
0102 unlock:
0103 spin_unlock(&gpch->lock);
0104
0105 return err;
0106 }
0107
0108
0109 static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
0110 {
0111 return rdc_gpio_config(chip, gpio, 1);
0112 }
0113
0114
0115
0116
0117 static int rdc321x_gpio_probe(struct platform_device *pdev)
0118 {
0119 int err;
0120 struct resource *r;
0121 struct rdc321x_gpio *rdc321x_gpio_dev;
0122 struct rdc321x_gpio_pdata *pdata;
0123
0124 pdata = dev_get_platdata(&pdev->dev);
0125 if (!pdata) {
0126 dev_err(&pdev->dev, "no platform data supplied\n");
0127 return -ENODEV;
0128 }
0129
0130 rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio),
0131 GFP_KERNEL);
0132 if (!rdc321x_gpio_dev)
0133 return -ENOMEM;
0134
0135 r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1");
0136 if (!r) {
0137 dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n");
0138 return -ENODEV;
0139 }
0140
0141 spin_lock_init(&rdc321x_gpio_dev->lock);
0142 rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev;
0143 rdc321x_gpio_dev->reg1_ctrl_base = r->start;
0144 rdc321x_gpio_dev->reg1_data_base = r->start + 0x4;
0145
0146 r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2");
0147 if (!r) {
0148 dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n");
0149 return -ENODEV;
0150 }
0151
0152 rdc321x_gpio_dev->reg2_ctrl_base = r->start;
0153 rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;
0154
0155 rdc321x_gpio_dev->chip.label = "rdc321x-gpio";
0156 rdc321x_gpio_dev->chip.owner = THIS_MODULE;
0157 rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;
0158 rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;
0159 rdc321x_gpio_dev->chip.get = rdc_gpio_get_value;
0160 rdc321x_gpio_dev->chip.set = rdc_gpio_set_value;
0161 rdc321x_gpio_dev->chip.base = 0;
0162 rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios;
0163
0164 platform_set_drvdata(pdev, rdc321x_gpio_dev);
0165
0166
0167
0168
0169 err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
0170 rdc321x_gpio_dev->reg1_data_base,
0171 &rdc321x_gpio_dev->data_reg[0]);
0172 if (err)
0173 return err;
0174
0175 err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
0176 rdc321x_gpio_dev->reg2_data_base,
0177 &rdc321x_gpio_dev->data_reg[1]);
0178 if (err)
0179 return err;
0180
0181 dev_info(&pdev->dev, "registering %d GPIOs\n",
0182 rdc321x_gpio_dev->chip.ngpio);
0183 return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip,
0184 rdc321x_gpio_dev);
0185 }
0186
0187 static struct platform_driver rdc321x_gpio_driver = {
0188 .driver.name = "rdc321x-gpio",
0189 .probe = rdc321x_gpio_probe,
0190 };
0191
0192 module_platform_driver(rdc321x_gpio_driver);
0193
0194 MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
0195 MODULE_DESCRIPTION("RDC321x GPIO driver");
0196 MODULE_LICENSE("GPL");
0197 MODULE_ALIAS("platform:rdc321x-gpio");