diff options
Diffstat (limited to 'drivers/staging/vme/devices/vme_pio2_gpio.c')
-rw-r--r-- | drivers/staging/vme/devices/vme_pio2_gpio.c | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/drivers/staging/vme/devices/vme_pio2_gpio.c b/drivers/staging/vme/devices/vme_pio2_gpio.c deleted file mode 100644 index ba9fe3bc2642..000000000000 --- a/drivers/staging/vme/devices/vme_pio2_gpio.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * GE PIO2 GPIO Driver - * - * Author: Martyn Welch <martyn.welch@ge.com> - * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/device.h> -#include <linux/platform_device.h> -#include <linux/ctype.h> -#include <linux/gpio/driver.h> -#include <linux/slab.h> -#include <linux/vme.h> - -#include "vme_pio2.h" - -static const char driver_name[] = "pio2_gpio"; - -static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset) -{ - u8 reg; - int retval; - struct pio2_card *card = gpiochip_get_data(chip); - - if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not available as input\n"); - return 0; - } - - retval = vme_master_read(card->window, ®, 1, - PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); - if (retval < 0) { - dev_err(&card->vdev->dev, "Unable to read from GPIO\n"); - return 0; - } - - /* - * Remember, input on channels configured as both input and output - * are inverted! - */ - if (reg & PIO2_CHANNEL_BIT[offset]) { - if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH) - return 0; - - return 1; - } - - if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH) - return 1; - - return 0; -} - -static void pio2_gpio_set(struct gpio_chip *chip, - unsigned int offset, int value) -{ - u8 reg; - int retval; - struct pio2_card *card = gpiochip_get_data(chip); - - if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, "Channel not available as output\n"); - return; - } - - if (value) - reg = card->bank[PIO2_CHANNEL_BANK[offset]].value | - PIO2_CHANNEL_BIT[offset]; - else - reg = card->bank[PIO2_CHANNEL_BANK[offset]].value & - ~PIO2_CHANNEL_BIT[offset]; - - retval = vme_master_write(card->window, ®, 1, - PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]); - if (retval < 0) { - dev_err(&card->vdev->dev, "Unable to write to GPIO\n"); - return; - } - - card->bank[PIO2_CHANNEL_BANK[offset]].value = reg; -} - -/* Directionality configured at board build - send appropriate response */ -static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned int offset) -{ - int data; - struct pio2_card *card = gpiochip_get_data(chip); - - if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, - "Channel directionality not configurable at runtime\n"); - - data = -EINVAL; - } else { - data = 0; - } - - return data; -} - -/* Directionality configured at board build - send appropriate response */ -static int pio2_gpio_dir_out(struct gpio_chip *chip, - unsigned int offset, int value) -{ - int data; - struct pio2_card *card = gpiochip_get_data(chip); - - if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) | - (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) { - dev_err(&card->vdev->dev, - "Channel directionality not configurable at runtime\n"); - - data = -EINVAL; - } else { - data = 0; - } - - return data; -} - -/* - * We return whether this has been successful - this is used in the probe to - * ensure we have a valid card. - */ -int pio2_gpio_reset(struct pio2_card *card) -{ - int retval = 0; - int i, j; - - u8 data = 0; - - /* Zero output registers */ - for (i = 0; i < 4; i++) { - retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_DATA[i]); - if (retval < 0) - return retval; - card->bank[i].value = 0; - } - - /* Set input interrupt masks */ - for (i = 0; i < 4; i++) { - retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_INT_MASK[i * 2]); - if (retval < 0) - return retval; - - retval = vme_master_write(card->window, &data, 1, - PIO2_REGS_INT_MASK[(i * 2) + 1]); - if (retval < 0) - return retval; - - for (j = 0; j < 8; j++) - card->bank[i].irq[j] = NONE; - } - - /* Ensure all I/O interrupts are cleared */ - for (i = 0; i < 4; i++) { - do { - retval = vme_master_read(card->window, &data, 1, - PIO2_REGS_INT_STAT[i]); - if (retval < 0) - return retval; - } while (data != 0); - } - - return 0; -} - -int pio2_gpio_init(struct pio2_card *card) -{ - int retval = 0; - char *label; - - label = kasprintf(GFP_KERNEL, - "%s@%s", driver_name, dev_name(&card->vdev->dev)); - if (!label) - return -ENOMEM; - - card->gc.label = label; - - card->gc.ngpio = PIO2_NUM_CHANNELS; - /* Dynamic allocation of base */ - card->gc.base = -1; - /* Setup pointers to chip functions */ - card->gc.direction_input = pio2_gpio_dir_in; - card->gc.direction_output = pio2_gpio_dir_out; - card->gc.get = pio2_gpio_get; - card->gc.set = pio2_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = gpiochip_add_data(&card->gc, card); - if (retval) { - dev_err(&card->vdev->dev, "Unable to register GPIO\n"); - kfree(card->gc.label); - } - - return retval; -}; - -void pio2_gpio_exit(struct pio2_card *card) -{ - const char *label = card->gc.label; - - gpiochip_remove(&card->gc); - kfree(label); -} - |