^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * RDC321x GPIO driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2008, Volker Weiss <dev@tintuc.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mfd/rdc321x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct rdc321x_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct pci_dev *sb_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u32 data_reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int reg1_ctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int reg1_data_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int reg2_ctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int reg2_data_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* read GPIO pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct rdc321x_gpio *gpch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) gpch = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) reg = gpio < 32 ? gpch->reg1_data_base : gpch->reg2_data_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) spin_lock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) pci_write_config_dword(gpch->sb_pdev, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) gpch->data_reg[gpio < 32 ? 0 : 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) pci_read_config_dword(gpch->sb_pdev, reg, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) spin_unlock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return (1 << (gpio & 0x1f)) & value ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static void rdc_gpio_set_value_impl(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned gpio, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct rdc321x_gpio *gpch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int reg = (gpio < 32) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) gpch = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) gpch->data_reg[reg] |= 1 << (gpio & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pci_write_config_dword(gpch->sb_pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) reg ? gpch->reg2_data_base : gpch->reg1_data_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) gpch->data_reg[reg]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* set GPIO pin to value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static void rdc_gpio_set_value(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned gpio, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct rdc321x_gpio *gpch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) gpch = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) spin_lock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) rdc_gpio_set_value_impl(chip, gpio, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) spin_unlock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int rdc_gpio_config(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned gpio, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct rdc321x_gpio *gpch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) gpch = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) spin_lock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) err = pci_read_config_dword(gpch->sb_pdev, gpio < 32 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) reg |= 1 << (gpio & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) err = pci_write_config_dword(gpch->sb_pdev, gpio < 32 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rdc_gpio_set_value_impl(chip, gpio, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) spin_unlock(&gpch->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* configure GPIO pin as input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return rdc_gpio_config(chip, gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Cache the initial value of both GPIO data registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int rdc321x_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct resource *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct rdc321x_gpio *rdc321x_gpio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct rdc321x_gpio_pdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (!pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_err(&pdev->dev, "no platform data supplied\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!rdc321x_gpio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spin_lock_init(&rdc321x_gpio_dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rdc321x_gpio_dev->reg1_ctrl_base = r->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) rdc321x_gpio_dev->reg1_data_base = r->start + 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rdc321x_gpio_dev->reg2_ctrl_base = r->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) rdc321x_gpio_dev->reg2_data_base = r->start + 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) rdc321x_gpio_dev->chip.label = "rdc321x-gpio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rdc321x_gpio_dev->chip.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) rdc321x_gpio_dev->chip.get = rdc_gpio_get_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) rdc321x_gpio_dev->chip.set = rdc_gpio_set_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) rdc321x_gpio_dev->chip.base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) platform_set_drvdata(pdev, rdc321x_gpio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* This might not be, what others (BIOS, bootloader, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) wrote to these registers before, but it's a good guess. Still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) better than just using 0xffffffff. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) rdc321x_gpio_dev->reg1_data_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) &rdc321x_gpio_dev->data_reg[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) rdc321x_gpio_dev->reg2_data_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) &rdc321x_gpio_dev->data_reg[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dev_info(&pdev->dev, "registering %d GPIOs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) rdc321x_gpio_dev->chip.ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rdc321x_gpio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static struct platform_driver rdc321x_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .driver.name = "rdc321x-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .probe = rdc321x_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) module_platform_driver(rdc321x_gpio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) MODULE_DESCRIPTION("RDC321x GPIO driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) MODULE_ALIAS("platform:rdc321x-gpio");