1187767Sluigi// SPDX-License-Identifier: GPL-2.0-or-later 2187767Sluigi/* 3187767Sluigi * RDC321x GPIO driver 4187767Sluigi * 5187767Sluigi * Copyright (C) 2008, Volker Weiss <dev@tintuc.de> 6187767Sluigi * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org> 7187767Sluigi */ 8187767Sluigi#include <linux/module.h> 9187767Sluigi#include <linux/kernel.h> 10187767Sluigi#include <linux/init.h> 11187767Sluigi#include <linux/spinlock.h> 12187767Sluigi#include <linux/platform_device.h> 13187767Sluigi#include <linux/pci.h> 14187767Sluigi#include <linux/gpio/driver.h> 15187767Sluigi#include <linux/mfd/rdc321x.h> 16187767Sluigi#include <linux/slab.h> 17187767Sluigi 18187767Sluigistruct rdc321x_gpio { 19187767Sluigi spinlock_t lock; 20187767Sluigi struct pci_dev *sb_pdev; 21187767Sluigi u32 data_reg[2]; 22187767Sluigi int reg1_ctrl_base; 23187767Sluigi int reg1_data_base; 24187767Sluigi int reg2_ctrl_base; 25187767Sluigi int reg2_data_base; 26187767Sluigi struct gpio_chip chip; 27187767Sluigi}; 28187767Sluigi 29187767Sluigi/* read GPIO pin */ 30187767Sluigistatic int rdc_gpio_get_value(struct gpio_chip *chip, unsigned gpio) 31187767Sluigi{ 32187767Sluigi struct rdc321x_gpio *gpch; 33187767Sluigi u32 value = 0; 34187767Sluigi int reg; 35187767Sluigi 36187767Sluigi gpch = gpiochip_get_data(chip); 37187767Sluigi reg = gpio < 32 ? gpch->reg1_data_base : gpch->reg2_data_base; 38204591Sluigi 39187767Sluigi spin_lock(&gpch->lock); 40187767Sluigi pci_write_config_dword(gpch->sb_pdev, reg, 41187767Sluigi gpch->data_reg[gpio < 32 ? 0 : 1]); 42187767Sluigi pci_read_config_dword(gpch->sb_pdev, reg, &value); 43187767Sluigi spin_unlock(&gpch->lock); 44187767Sluigi 45187767Sluigi return (1 << (gpio & 0x1f)) & value ? 1 : 0; 46187767Sluigi} 47187767Sluigi 48187767Sluigistatic void rdc_gpio_set_value_impl(struct gpio_chip *chip, 49346205Sae unsigned gpio, int value) 50346205Sae{ 51187767Sluigi struct rdc321x_gpio *gpch; 52187767Sluigi int reg = (gpio < 32) ? 0 : 1; 53187767Sluigi 54187767Sluigi gpch = gpiochip_get_data(chip); 55187767Sluigi 56187767Sluigi if (value) 57187767Sluigi gpch->data_reg[reg] |= 1 << (gpio & 0x1f); 58187767Sluigi else 59332400Sae gpch->data_reg[reg] &= ~(1 << (gpio & 0x1f)); 60332400Sae 61332400Sae pci_write_config_dword(gpch->sb_pdev, 62332400Sae reg ? gpch->reg2_data_base : gpch->reg1_data_base, 63332400Sae gpch->data_reg[reg]); 64332400Sae} 65187767Sluigi 66187767Sluigi/* set GPIO pin to value */ 67187767Sluigistatic void rdc_gpio_set_value(struct gpio_chip *chip, 68187767Sluigi unsigned gpio, int value) 69187767Sluigi{ 70187767Sluigi struct rdc321x_gpio *gpch; 71187767Sluigi 72187767Sluigi gpch = gpiochip_get_data(chip); 73187767Sluigi spin_lock(&gpch->lock); 74187767Sluigi rdc_gpio_set_value_impl(chip, gpio, value); 75187767Sluigi spin_unlock(&gpch->lock); 76187767Sluigi} 77187767Sluigi 78187767Sluigistatic int rdc_gpio_config(struct gpio_chip *chip, 79187767Sluigi unsigned gpio, int value) 80270424Smelifaro{ 81270424Smelifaro struct rdc321x_gpio *gpch; 82187769Sluigi int err; 83187769Sluigi u32 reg; 84187769Sluigi 85187769Sluigi gpch = gpiochip_get_data(chip); 86187769Sluigi 87187769Sluigi spin_lock(&gpch->lock); 88187769Sluigi err = pci_read_config_dword(gpch->sb_pdev, gpio < 32 ? 89187769Sluigi gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, ®); 90332229Stuexen if (err) 91332229Stuexen goto unlock; 92187769Sluigi 93187769Sluigi reg |= 1 << (gpio & 0x1f); 94298016Sae 95187769Sluigi err = pci_write_config_dword(gpch->sb_pdev, gpio < 32 ? 96204591Sluigi gpch->reg1_ctrl_base : gpch->reg2_ctrl_base, reg); 97187769Sluigi if (err) 98204591Sluigi goto unlock; 99204591Sluigi 100187769Sluigi rdc_gpio_set_value_impl(chip, gpio, value); 101187769Sluigi 102187769Sluigiunlock: 103187769Sluigi spin_unlock(&gpch->lock); 104187769Sluigi 105187769Sluigi return err; 106187769Sluigi} 107187769Sluigi 108187769Sluigi/* configure GPIO pin as input */ 109187769Sluigistatic int rdc_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) 110187769Sluigi{ 111187769Sluigi return rdc_gpio_config(chip, gpio, 1); 112190633Spiso} 113223666Sae 114223666Sae/* 115187769Sluigi * Cache the initial value of both GPIO data registers 116187769Sluigi */ 117187769Sluigistatic int rdc321x_gpio_probe(struct platform_device *pdev) 118187769Sluigi{ 119187769Sluigi int err; 120187769Sluigi struct resource *r; 121187769Sluigi struct rdc321x_gpio *rdc321x_gpio_dev; 122187769Sluigi struct rdc321x_gpio_pdata *pdata; 123187769Sluigi 124187769Sluigi pdata = dev_get_platdata(&pdev->dev); 125187769Sluigi if (!pdata) { 126187769Sluigi dev_err(&pdev->dev, "no platform data supplied\n"); 127337461Sae return -ENODEV; 128187769Sluigi } 129337461Sae 130187769Sluigi rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio), 131187769Sluigi GFP_KERNEL); 132187769Sluigi if (!rdc321x_gpio_dev) 133187769Sluigi return -ENOMEM; 134187769Sluigi 135187769Sluigi r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1"); 136187769Sluigi if (!r) { 137187769Sluigi dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n"); 138187769Sluigi return -ENODEV; 139187769Sluigi } 140187769Sluigi 141187769Sluigi spin_lock_init(&rdc321x_gpio_dev->lock); 142187769Sluigi rdc321x_gpio_dev->sb_pdev = pdata->sb_pdev; 143205169Sluigi rdc321x_gpio_dev->reg1_ctrl_base = r->start; 144187769Sluigi rdc321x_gpio_dev->reg1_data_base = r->start + 0x4; 145187769Sluigi 146187769Sluigi r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2"); 147187769Sluigi if (!r) { 148187769Sluigi dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n"); 149187769Sluigi return -ENODEV; 150187769Sluigi } 151187769Sluigi 152187769Sluigi rdc321x_gpio_dev->reg2_ctrl_base = r->start; 153187769Sluigi rdc321x_gpio_dev->reg2_data_base = r->start + 0x4; 154349573Sae 155187769Sluigi rdc321x_gpio_dev->chip.label = "rdc321x-gpio"; 156187769Sluigi rdc321x_gpio_dev->chip.owner = THIS_MODULE; 157187769Sluigi rdc321x_gpio_dev->chip.direction_input = rdc_gpio_direction_input; 158187769Sluigi rdc321x_gpio_dev->chip.direction_output = rdc_gpio_config; 159187769Sluigi rdc321x_gpio_dev->chip.get = rdc_gpio_get_value; 160187769Sluigi rdc321x_gpio_dev->chip.set = rdc_gpio_set_value; 161187769Sluigi rdc321x_gpio_dev->chip.base = 0; 162187769Sluigi rdc321x_gpio_dev->chip.ngpio = pdata->max_gpios; 163187769Sluigi 164187769Sluigi platform_set_drvdata(pdev, rdc321x_gpio_dev); 165187769Sluigi 166187769Sluigi /* This might not be, what others (BIOS, bootloader, etc.) 167187769Sluigi wrote to these registers before, but it's a good guess. Still 168187769Sluigi better than just using 0xffffffff. */ 169187769Sluigi err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev, 170187769Sluigi rdc321x_gpio_dev->reg1_data_base, 171187769Sluigi &rdc321x_gpio_dev->data_reg[0]); 172187769Sluigi if (err) 173187769Sluigi return err; 174204591Sluigi 175204591Sluigi err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev, 176187769Sluigi rdc321x_gpio_dev->reg2_data_base, 177187769Sluigi &rdc321x_gpio_dev->data_reg[1]); 178204591Sluigi if (err) 179194930Soleg return err; 180187769Sluigi 181187769Sluigi dev_info(&pdev->dev, "registering %d GPIOs\n", 182266941Shiren rdc321x_gpio_dev->chip.ngpio); 183187769Sluigi return devm_gpiochip_add_data(&pdev->dev, &rdc321x_gpio_dev->chip, 184187769Sluigi rdc321x_gpio_dev); 185300779Struckman} 186300779Struckman 187300779Struckmanstatic struct platform_driver rdc321x_gpio_driver = { 188300779Struckman .driver.name = "rdc321x-gpio", 189300779Struckman .probe = rdc321x_gpio_probe, 190300779Struckman}; 191300779Struckman 192300779Struckmanmodule_platform_driver(rdc321x_gpio_driver); 193300779Struckman 194300779StruckmanMODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 195300779StruckmanMODULE_DESCRIPTION("RDC321x GPIO driver"); 196300779StruckmanMODULE_LICENSE("GPL"); 197300779StruckmanMODULE_ALIAS("platform:rdc321x-gpio"); 198300779Struckman