#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/gpio/driver.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT)
static unsigned int base[MAX_NUM_GPIOMM];
static unsigned int num_gpiomm;
module_param_hw_array(base, uint, ioport, &num_gpiomm, 0);
MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses");
unsigned char io_state[6];
unsigned char out_state[6];
unsigned char control[2];
static int gpiomm_gpio_get_direction(struct gpio_chip *chip,
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
const unsigned int port = offset / 8;
const unsigned int mask = BIT(offset % 8);
return !!(gpiommgpio->io_state[port] & mask);
static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
const unsigned int io_port = offset / 8;
const unsigned int control_port = io_port / 3;
const unsigned int control_addr = gpiommgpio->base + 3 + control_port*4;
spin_lock_irqsave(&gpiommgpio->lock, flags);
if (io_port == 2 || io_port == 5) {
gpiommgpio->io_state[io_port] |= 0xF0;
gpiommgpio->control[control_port] |= BIT(3);
gpiommgpio->io_state[io_port] |= 0x0F;
gpiommgpio->control[control_port] |= BIT(0);
gpiommgpio->io_state[io_port] |= 0xFF;
if (io_port == 0 || io_port == 3)
gpiommgpio->control[control_port] |= BIT(4);