Skip to content

Commit

Permalink
cs5535-gpio: request function, mask & names added
Browse files Browse the repository at this point in the history
Changed number of gpio pins to 32 (according to datasheet)

Added mask to disable some pins

Added gpio_request for checking mask and disabling special pin functions

Added pin names

[dilinger@collabora.co.uk: make printk usage consistent]
Signed-off-by: Tobias Mueller <Tobias_Mueller@twam.info>
Signed-off-by: Andres Salomon <dilinger@collabora.co.uk>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Jordan Crouse <jordan@cosmicpenguin.net>
Cc: David Brownell <david-b@pacbell.net>
Cc: Alessandro Zummo <alessandro.zummo@towertech.it>
Signed-off-by: Andres Salomon <dilinger@collabora.co.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
twam authored and torvalds committed Dec 15, 2009
1 parent 5f0a96b commit 1ea3fa7
Showing 1 changed file with 78 additions and 5 deletions.
83 changes: 78 additions & 5 deletions drivers/gpio/cs5535-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,29 @@
#define DRV_NAME "cs5535-gpio"
#define GPIO_BAR 1

/*
* Some GPIO pins
* 31-29,23 : reserved (always mask out)
* 28 : Power Button
* 26 : PME#
* 22-16 : LPC
* 14,15 : SMBus
* 9,8 : UART1
* 7 : PCI INTB
* 3,4 : UART2/DDC
* 2 : IDE_IRQ0
* 1 : AC_BEEP
* 0 : PCI INTA
*
* If a mask was not specified, allow all except
* reserved and Power Button
*/
#define GPIO_DEFAULT_MASK 0x0F7FFFFF

static ulong mask = GPIO_DEFAULT_MASK;
module_param_named(mask, mask, ulong, 0444);
MODULE_PARM_DESC(mask, "GPIO channel mask.");

static struct cs5535_gpio_chip {
struct gpio_chip chip;
resource_size_t base;
Expand Down Expand Up @@ -102,6 +125,33 @@ EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
* Generic gpio_chip API support.
*/

static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
{
struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
unsigned long flags;

spin_lock_irqsave(&chip->lock, flags);

/* check if this pin is available */
if ((mask & (1 << offset)) == 0) {
dev_info(&chip->pdev->dev,
"pin %u is not available (check mask)\n", offset);
spin_unlock_irqrestore(&chip->lock, flags);
return -EINVAL;
}

/* disable output aux 1 & 2 on this pin */
__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);

/* disable input aux 1 on this pin */
__cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);

spin_unlock_irqrestore(&chip->lock, flags);

return 0;
}

static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
{
return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
Expand Down Expand Up @@ -145,13 +195,26 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
return 0;
}

static char *cs5535_gpio_names[] = {
"GPIO0", "GPIO1", "GPIO2", "GPIO3",
"GPIO4", "GPIO5", "GPIO6", "GPIO7",
"GPIO8", "GPIO9", "GPIO10", "GPIO11",
"GPIO12", "GPIO13", "GPIO14", "GPIO15",
"GPIO16", "GPIO17", "GPIO18", "GPIO19",
"GPIO20", "GPIO21", "GPIO22", NULL,
"GPIO24", "GPIO25", "GPIO26", "GPIO27",
"GPIO28", NULL, NULL, NULL,
};

static struct cs5535_gpio_chip cs5535_gpio_chip = {
.chip = {
.owner = THIS_MODULE,
.label = DRV_NAME,

.base = 0,
.ngpio = 28,
.ngpio = 32,
.names = cs5535_gpio_names,
.request = chip_gpio_request,

.get = chip_gpio_get,
.set = chip_gpio_set,
Expand All @@ -165,6 +228,7 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int err;
ulong mask_orig = mask;

/* There are two ways to get the GPIO base address; one is by
* fetching it from MSR_LBAR_GPIO, the other is by reading the
Expand Down Expand Up @@ -193,14 +257,23 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
(unsigned long long) cs5535_gpio_chip.base);

/* mask out reserved pins */
mask &= 0x1F7FFFFF;

/* do not allow pin 28, Power Button, as there's special handling
* in the PMC needed. (note 12, p. 48) */
mask &= ~(1 << 28);

if (mask_orig != mask)
dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
mask_orig, mask);

/* finally, register with the generic GPIO API */
err = gpiochip_add(&cs5535_gpio_chip.chip);
if (err) {
dev_err(&pdev->dev, "failed to register gpio chip\n");
if (err)
goto release_region;
}

printk(KERN_INFO DRV_NAME ": GPIO support successfully loaded.\n");
dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
return 0;

release_region:
Expand Down

0 comments on commit 1ea3fa7

Please sign in to comment.