0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/device.h>
0010 #include <linux/errno.h>
0011 #include <linux/gpio/driver.h>
0012 #include <linux/io.h>
0013 #include <linux/ioport.h>
0014 #include <linux/isa.h>
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/moduleparam.h>
0018
0019 #include "gpio-i8255.h"
0020
0021 MODULE_IMPORT_NS(I8255);
0022
0023 #define GPIOMM_EXTENT 8
0024 #define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT)
0025
0026 static unsigned int base[MAX_NUM_GPIOMM];
0027 static unsigned int num_gpiomm;
0028 module_param_hw_array(base, uint, ioport, &num_gpiomm, 0);
0029 MODULE_PARM_DESC(base, "Diamond Systems GPIO-MM base addresses");
0030
0031 #define GPIOMM_NUM_PPI 2
0032
0033
0034
0035
0036
0037
0038
0039 struct gpiomm_gpio {
0040 struct gpio_chip chip;
0041 struct i8255_state ppi_state[GPIOMM_NUM_PPI];
0042 struct i8255 __iomem *ppi;
0043 };
0044
0045 static int gpiomm_gpio_get_direction(struct gpio_chip *chip,
0046 unsigned int offset)
0047 {
0048 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0049
0050 if (i8255_get_direction(gpiommgpio->ppi_state, offset))
0051 return GPIO_LINE_DIRECTION_IN;
0052
0053 return GPIO_LINE_DIRECTION_OUT;
0054 }
0055
0056 static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
0057 unsigned int offset)
0058 {
0059 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0060
0061 i8255_direction_input(gpiommgpio->ppi, gpiommgpio->ppi_state, offset);
0062
0063 return 0;
0064 }
0065
0066 static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
0067 unsigned int offset, int value)
0068 {
0069 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0070
0071 i8255_direction_output(gpiommgpio->ppi, gpiommgpio->ppi_state, offset,
0072 value);
0073
0074 return 0;
0075 }
0076
0077 static int gpiomm_gpio_get(struct gpio_chip *chip, unsigned int offset)
0078 {
0079 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0080
0081 return i8255_get(gpiommgpio->ppi, offset);
0082 }
0083
0084 static int gpiomm_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
0085 unsigned long *bits)
0086 {
0087 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0088
0089 i8255_get_multiple(gpiommgpio->ppi, mask, bits, chip->ngpio);
0090
0091 return 0;
0092 }
0093
0094 static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
0095 int value)
0096 {
0097 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0098
0099 i8255_set(gpiommgpio->ppi, gpiommgpio->ppi_state, offset, value);
0100 }
0101
0102 static void gpiomm_gpio_set_multiple(struct gpio_chip *chip,
0103 unsigned long *mask, unsigned long *bits)
0104 {
0105 struct gpiomm_gpio *const gpiommgpio = gpiochip_get_data(chip);
0106
0107 i8255_set_multiple(gpiommgpio->ppi, gpiommgpio->ppi_state, mask, bits,
0108 chip->ngpio);
0109 }
0110
0111 #define GPIOMM_NGPIO 48
0112 static const char *gpiomm_names[GPIOMM_NGPIO] = {
0113 "Port 1A0", "Port 1A1", "Port 1A2", "Port 1A3", "Port 1A4", "Port 1A5",
0114 "Port 1A6", "Port 1A7", "Port 1B0", "Port 1B1", "Port 1B2", "Port 1B3",
0115 "Port 1B4", "Port 1B5", "Port 1B6", "Port 1B7", "Port 1C0", "Port 1C1",
0116 "Port 1C2", "Port 1C3", "Port 1C4", "Port 1C5", "Port 1C6", "Port 1C7",
0117 "Port 2A0", "Port 2A1", "Port 2A2", "Port 2A3", "Port 2A4", "Port 2A5",
0118 "Port 2A6", "Port 2A7", "Port 2B0", "Port 2B1", "Port 2B2", "Port 2B3",
0119 "Port 2B4", "Port 2B5", "Port 2B6", "Port 2B7", "Port 2C0", "Port 2C1",
0120 "Port 2C2", "Port 2C3", "Port 2C4", "Port 2C5", "Port 2C6", "Port 2C7",
0121 };
0122
0123 static void gpiomm_init_dio(struct i8255 __iomem *const ppi,
0124 struct i8255_state *const ppi_state)
0125 {
0126 const unsigned long ngpio = 24;
0127 const unsigned long mask = GENMASK(ngpio - 1, 0);
0128 const unsigned long bits = 0;
0129 unsigned long i;
0130
0131
0132 for (i = 0; i < GPIOMM_NUM_PPI; i++) {
0133 i8255_mode0_output(&ppi[i]);
0134 i8255_set_multiple(&ppi[i], &ppi_state[i], &mask, &bits, ngpio);
0135 }
0136 }
0137
0138 static int gpiomm_probe(struct device *dev, unsigned int id)
0139 {
0140 struct gpiomm_gpio *gpiommgpio;
0141 const char *const name = dev_name(dev);
0142 int err;
0143
0144 gpiommgpio = devm_kzalloc(dev, sizeof(*gpiommgpio), GFP_KERNEL);
0145 if (!gpiommgpio)
0146 return -ENOMEM;
0147
0148 if (!devm_request_region(dev, base[id], GPIOMM_EXTENT, name)) {
0149 dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
0150 base[id], base[id] + GPIOMM_EXTENT);
0151 return -EBUSY;
0152 }
0153
0154 gpiommgpio->ppi = devm_ioport_map(dev, base[id], GPIOMM_EXTENT);
0155 if (!gpiommgpio->ppi)
0156 return -ENOMEM;
0157
0158 gpiommgpio->chip.label = name;
0159 gpiommgpio->chip.parent = dev;
0160 gpiommgpio->chip.owner = THIS_MODULE;
0161 gpiommgpio->chip.base = -1;
0162 gpiommgpio->chip.ngpio = GPIOMM_NGPIO;
0163 gpiommgpio->chip.names = gpiomm_names;
0164 gpiommgpio->chip.get_direction = gpiomm_gpio_get_direction;
0165 gpiommgpio->chip.direction_input = gpiomm_gpio_direction_input;
0166 gpiommgpio->chip.direction_output = gpiomm_gpio_direction_output;
0167 gpiommgpio->chip.get = gpiomm_gpio_get;
0168 gpiommgpio->chip.get_multiple = gpiomm_gpio_get_multiple;
0169 gpiommgpio->chip.set = gpiomm_gpio_set;
0170 gpiommgpio->chip.set_multiple = gpiomm_gpio_set_multiple;
0171
0172 i8255_state_init(gpiommgpio->ppi_state, GPIOMM_NUM_PPI);
0173 gpiomm_init_dio(gpiommgpio->ppi, gpiommgpio->ppi_state);
0174
0175 err = devm_gpiochip_add_data(dev, &gpiommgpio->chip, gpiommgpio);
0176 if (err) {
0177 dev_err(dev, "GPIO registering failed (%d)\n", err);
0178 return err;
0179 }
0180
0181 return 0;
0182 }
0183
0184 static struct isa_driver gpiomm_driver = {
0185 .probe = gpiomm_probe,
0186 .driver = {
0187 .name = "gpio-mm"
0188 },
0189 };
0190
0191 module_isa_driver(gpiomm_driver, num_gpiomm);
0192
0193 MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
0194 MODULE_DESCRIPTION("Diamond Systems GPIO-MM GPIO driver");
0195 MODULE_LICENSE("GPL v2");