^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // http://www.samsung.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright 2008 Openmoko, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Copyright 2008 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) // http://armlinux.simtec.co.uk/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) // Samsung - GPIOlib support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <mach/irqs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "regs-gpio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "gpio-samsung.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "cpu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "gpio-core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "gpio-cfg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "gpio-cfg-helpers.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int off, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void __iomem *reg = chip->base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int shift = off * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u32 pup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pup = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) pup &= ~(3 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pup |= pull << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) __raw_writel(pup, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void __iomem *reg = chip->base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int shift = off * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u32 pup = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) pup >>= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) pup &= 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return (__force samsung_gpio_pull_t)pup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int off, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) switch (pull) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case S3C_GPIO_PULL_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) pull = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case S3C_GPIO_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pull = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case S3C_GPIO_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pull = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return samsung_gpio_setpull_updown(chip, off, pull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) samsung_gpio_pull_t pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) pull = samsung_gpio_getpull_updown(chip, off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) switch (pull) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) pull = S3C_GPIO_PULL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case 0x03:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) pull = S3C_GPIO_PULL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) pull = S3C_GPIO_PULL_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int off, samsung_gpio_pull_t pull,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) samsung_gpio_pull_t updown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) void __iomem *reg = chip->base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 pup = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (pull == updown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pup &= ~(1 << off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) else if (pull == S3C_GPIO_PULL_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) pup |= (1 << off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __raw_writel(pup, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) unsigned int off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) samsung_gpio_pull_t updown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void __iomem *reg = chip->base + 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u32 pup = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) pup &= (1 << off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return pup ? S3C_GPIO_PULL_NONE : updown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned int off, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int off, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * @cfg: The configuration value to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * This helper deal with the GPIO cases where the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * has two bits of configuration per gpio, which have the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * functions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * 00 = input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * 01 = output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * 1x = special function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned int off, unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) void __iomem *reg = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int shift = off * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (samsung_gpio_is_cfg_special(cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) cfg &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (cfg > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) cfg <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) con = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) con &= ~(0x3 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) con |= cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) __raw_writel(con, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * S3C_GPIO_SPECIAL() macro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) con = __raw_readl(chip->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) con >>= off * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) con &= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* this conversion works for IN and OUT as well as special mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return S3C_GPIO_SPECIAL(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * @cfg: The configuration value to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * This helper deal with the GPIO cases where the control register has 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * of control per GPIO, generally in the form of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * 0000 = Input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * 0001 = Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * others = Special functions (dependent on bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * Note, since the code to deal with the case where there are two control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * registers instead of one, we do not have a separate set of functions for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * each case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned int off, unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void __iomem *reg = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) unsigned int shift = (off & 7) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (off < 8 && chip->chip.ngpio > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) reg -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (samsung_gpio_is_cfg_special(cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) cfg &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) cfg <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) con = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) con &= ~(0xf << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) con |= cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) __raw_writel(con, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * register setting into a value the software can use, such as could be passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * to samsung_gpio_setcfg_4bit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @sa samsung_gpio_getcfg_2bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) void __iomem *reg = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) unsigned int shift = (off & 7) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (off < 8 && chip->chip.ngpio > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) reg -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) con = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) con >>= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) con &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* this conversion works for IN and OUT as well as special mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return S3C_GPIO_SPECIAL(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * @cfg: The configuration value to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * This helper deal with the GPIO cases where the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * has one bit of configuration for the gpio, where setting the bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * means the pin is in special function mode and unset means output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned int off, unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) void __iomem *reg = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int shift = off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (samsung_gpio_is_cfg_special(cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) cfg &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Map output to 0, and SFN2 to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cfg -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (cfg > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) cfg <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) con = __raw_readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) con &= ~(0x1 << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) con |= cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) __raw_writel(con, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * @off: The offset for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * GPIO configuration value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * @sa samsung_gpio_getcfg_2bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * @sa samsung_gpio_getcfg_4bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned int off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u32 con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) con = __raw_readl(chip->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) con >>= off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) con &= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) con++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return S3C_GPIO_SFN(con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int nr_chips)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) for (; nr_chips > 0; nr_chips--, chipcfg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (!chipcfg->set_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) chipcfg->set_config = samsung_gpio_setcfg_4bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (!chipcfg->get_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) chipcfg->get_config = samsung_gpio_getcfg_4bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!chipcfg->set_pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) chipcfg->set_pull = samsung_gpio_setpull_updown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!chipcfg->get_pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) chipcfg->get_pull = samsung_gpio_getpull_updown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .set_config = samsung_gpio_setcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .get_config = samsung_gpio_getcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .set_config = s3c24xx_gpio_setcfg_abank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .get_config = s3c24xx_gpio_getcfg_abank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) [0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .cfg_eint = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) [1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .cfg_eint = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) [2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .cfg_eint = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) [3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .cfg_eint = 0xF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) [4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .cfg_eint = 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .set_config = samsung_gpio_setcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .get_config = samsung_gpio_getcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) [5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .cfg_eint = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .set_config = samsung_gpio_setcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .get_config = samsung_gpio_getcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) [6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .cfg_eint = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .set_config = samsung_gpio_setcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .get_config = samsung_gpio_getcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) [7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .set_config = samsung_gpio_setcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .get_config = samsung_gpio_getcfg_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * Default routines for controlling GPIO, based on the original S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * GPIO functions which deal with the case where each gpio bank of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * chip is as following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * base + 0x00: Control register, 2 bits per gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * gpio n: 2 bits starting at (2*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * 00 = input, 01 = output, others mean special-function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * base + 0x04: Data register, 1 bit per gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * bit n: data bit n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) samsung_gpio_lock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) con = __raw_readl(base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) con &= ~(3 << (offset * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) __raw_writel(con, base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) samsung_gpio_unlock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) unsigned long dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) samsung_gpio_lock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dat = __raw_readl(base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dat &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dat |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) __raw_writel(dat, base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) con = __raw_readl(base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) con &= ~(3 << (offset * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) con |= 1 << (offset * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) __raw_writel(con, base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) __raw_writel(dat, base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) samsung_gpio_unlock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * The samsung_gpiolib_4bit routines are to control the gpio banks where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * following example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * base + 0x00: Control register, 4 bits per gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * gpio n: 4 bits starting at (4*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * 0000 = input, 0001 = output, others mean special-function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * base + 0x04: Data register, 1 bit per gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * bit n: data bit n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * Note, since the data register is one bit per gpio and is at base + 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * state of the output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) con = __raw_readl(base + GPIOCON_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ourchip->bitmap_gpio_int & BIT(offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) con |= 0xf << con_4bit_shift(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) con &= ~(0xf << con_4bit_shift(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) __raw_writel(con, base + GPIOCON_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) unsigned int offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned long dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) con = __raw_readl(base + GPIOCON_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) con &= ~(0xf << con_4bit_shift(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) con |= 0x1 << con_4bit_shift(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dat = __raw_readl(base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dat |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dat &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) __raw_writel(dat, base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) __raw_writel(con, base + GPIOCON_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) __raw_writel(dat, base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * The next set of routines are for the case where the GPIO configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * registers are 4 bits per GPIO but there is more than one register (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * bank has more than 8 GPIOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * This case is the similar to the 4 bit case, but the registers are as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * gpio n: 4 bits starting at (4*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * 0000 = input, 0001 = output, others mean special-function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * gpio n: 4 bits starting at (4*n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * 0000 = input, 0001 = output, others mean special-function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * base + 0x08: Data register, 1 bit per gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * bit n: data bit n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * routines we store the 'base + 0x4' address so that these routines see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * the data register at ourchip->base + 0x04.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) void __iomem *regcon = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (offset > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) offset -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) regcon -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) con = __raw_readl(regcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) con &= ~(0xf << con_4bit_shift(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) __raw_writel(con, regcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) unsigned int offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) void __iomem *regcon = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned long dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) unsigned con_offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (con_offset > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) con_offset -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) regcon -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) con = __raw_readl(regcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) con &= ~(0xf << con_4bit_shift(con_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) con |= 0x1 << con_4bit_shift(con_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dat = __raw_readl(base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dat |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) dat &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) __raw_writel(dat, base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) __raw_writel(con, regcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) __raw_writel(dat, base + GPIODAT_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* The next set of routines are for the case of s3c24xx bank a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) unsigned long dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) unsigned long con;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) con = __raw_readl(base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dat = __raw_readl(base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dat &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dat |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) __raw_writel(dat, base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) con &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) __raw_writel(con, base + 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) __raw_writel(dat, base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void samsung_gpiolib_set(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) void __iomem *base = ourchip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) unsigned long dat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) samsung_gpio_lock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dat = __raw_readl(base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dat &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) dat |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) __raw_writel(dat, base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) samsung_gpio_unlock(ourchip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) val = __raw_readl(ourchip->base + 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) val >>= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) val &= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * for use with the configuration calls, and other parts of the s3c gpiolib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * support code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * Not all s3c support code will need this, as some configurations of cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * may only support one or two different configuration options and have an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * the machine support file should provide its own samsung_gpiolib_getchip()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * and any other necessary functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) #ifdef CONFIG_S3C_GPIO_TRACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned int gpn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) gpn = chip->chip.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) s3c_gpios[gpn] = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #endif /* CONFIG_S3C_GPIO_TRACK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * samsung_gpiolib_add() - add the Samsung gpio_chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * @chip: The chip to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * This is a wrapper to gpiochip_add() that takes our specific gpio chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * information and makes the necessary alterations for the platform and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * notes the information for use with the configuration systems and any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * other parts of the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct gpio_chip *gc = &chip->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) BUG_ON(!chip->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) BUG_ON(!gc->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) BUG_ON(!gc->ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (!gc->direction_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) gc->direction_input = samsung_gpiolib_2bit_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (!gc->direction_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) gc->direction_output = samsung_gpiolib_2bit_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!gc->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) gc->set = samsung_gpiolib_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (!gc->get)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) gc->get = samsung_gpiolib_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (chip->pm != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (!chip->pm->save || !chip->pm->resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) pr_err("gpio: %s has missing PM functions\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) gc->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) pr_err("gpio: %s has no PM function\n", gc->label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* gpiochip_add() prints own failure message on error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ret = gpiochip_add_data(gc, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) s3c_gpiolib_track(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int nr_chips, void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct gpio_chip *gc = &chip->chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) for (i = 0 ; i < nr_chips; i++, chip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* skip banks not present on SoC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (chip->chip.base >= S3C_GPIO_END)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (!chip->config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) chip->config = &s3c24xx_gpiocfg_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!chip->pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if ((base != NULL) && (chip->base == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) chip->base = base + ((i) * 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!gc->direction_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) gc->direction_input = samsung_gpiolib_2bit_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (!gc->direction_output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) gc->direction_output = samsung_gpiolib_2bit_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) samsung_gpiolib_add(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int nr_chips, void __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) for (i = 0 ; i < nr_chips; i++, chip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) chip->chip.direction_input = samsung_gpiolib_2bit_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) chip->chip.direction_output = samsung_gpiolib_2bit_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (!chip->config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) chip->config = &samsung_gpio_cfgs[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (!chip->pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if ((base != NULL) && (chip->base == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) chip->base = base + ((i) * offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) samsung_gpiolib_add(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * @chip: The gpio chip that is being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * This helper deal with the GPIO cases where the control register has 4 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * of control per GPIO, generally in the form of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * 0000 = Input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * 0001 = Output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * others = Special functions (dependent on bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * Note, since the code to deal with the case where there are two control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * registers instead of one, we do not have a separate set of function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * (samsung_gpiolib_add_4bit2_chips)for each case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int nr_chips, void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) for (i = 0 ; i < nr_chips; i++, chip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) chip->chip.direction_input = samsung_gpiolib_4bit_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) chip->chip.direction_output = samsung_gpiolib_4bit_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (!chip->config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) chip->config = &samsung_gpio_cfgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!chip->pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if ((base != NULL) && (chip->base == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) chip->base = base + ((i) * 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) chip->bitmap_gpio_int = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) samsung_gpiolib_add(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int nr_chips)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) for (; nr_chips > 0; nr_chips--, chip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) chip->chip.direction_input = samsung_gpiolib_4bit2_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) chip->chip.direction_output = samsung_gpiolib_4bit2_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (!chip->config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) chip->config = &samsung_gpio_cfgs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (!chip->pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) samsung_gpiolib_add(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return samsung_chip->irq_base + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (offset < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (soc_is_s3c2412())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return IRQ_EINT0_2412 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return IRQ_EINT0 + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (offset < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return IRQ_EINT4 + offset - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) #ifdef CONFIG_ARCH_S3C64XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct samsung_gpio_chip s3c24xx_gpios[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .config = &s3c24xx_gpiocfg_banka,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .base = S3C2410_GPA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .label = "GPIOA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .ngpio = 27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .direction_input = s3c24xx_gpiolib_banka_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) .direction_output = s3c24xx_gpiolib_banka_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .base = S3C2410_GPB(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .label = "GPIOB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .ngpio = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .base = S3C2410_GPC(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .label = "GPIOC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .base = S3C2410_GPD(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .label = "GPIOD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .base = S3C2410_GPE(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .label = "GPIOE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .base = S3C2410_GPF(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .label = "GPIOF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .ngpio = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .to_irq = s3c24xx_gpiolib_fbank_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .irq_base = IRQ_EINT8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .base = S3C2410_GPG(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .label = "GPIOG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .to_irq = samsung_gpiolib_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .base = S3C2410_GPH(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .label = "GPIOH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .ngpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /* GPIOS for the S3C2443 and later devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .base = S3C2440_GPJCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .base = S3C2410_GPJ(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .label = "GPIOJ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .base = S3C2443_GPKCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .base = S3C2410_GPK(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .label = "GPIOK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .ngpio = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .base = S3C2443_GPLCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .base = S3C2410_GPL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .label = "GPIOL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .ngpio = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) .base = S3C2443_GPMCON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .base = S3C2410_GPM(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .label = "GPIOM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .ngpio = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * GPIO bank summary:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * Bank GPIOs Style SlpCon ExtInt Group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * A 8 4Bit Yes 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * B 7 4Bit Yes 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * C 8 4Bit Yes 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * D 5 4Bit Yes 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * E 5 4Bit Yes None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * F 16 2Bit Yes 4 [1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * G 7 4Bit Yes 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * H 10 4Bit[2] Yes 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * I 16 2Bit Yes None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * J 12 2Bit Yes None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * K 16 4Bit[2] No None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * L 15 4Bit[2] No None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * M 6 4Bit No IRQ_EINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * N 16 2Bit No IRQ_EINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * O 16 2Bit Yes 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * P 15 2Bit Yes 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * Q 9 2Bit Yes 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * [1] BANKF pins 14,15 do not form part of the external interrupt sources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * [2] BANK has two control registers, GPxCON0 and GPxCON1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) #ifdef CONFIG_ARCH_S3C64XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .base = S3C64XX_GPA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .ngpio = S3C64XX_GPIO_A_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .label = "GPA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .base = S3C64XX_GPB(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .ngpio = S3C64XX_GPIO_B_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .label = "GPB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .base = S3C64XX_GPC(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) .ngpio = S3C64XX_GPIO_C_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) .label = "GPC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .base = S3C64XX_GPD(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .ngpio = S3C64XX_GPIO_D_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .label = "GPD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .config = &samsung_gpio_cfgs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .base = S3C64XX_GPE(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .ngpio = S3C64XX_GPIO_E_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .label = "GPE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .base = S3C64XX_GPG_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .base = S3C64XX_GPG(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .ngpio = S3C64XX_GPIO_G_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .label = "GPG",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .base = S3C64XX_GPM_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .config = &samsung_gpio_cfgs[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .base = S3C64XX_GPM(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .ngpio = S3C64XX_GPIO_M_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .label = "GPM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .to_irq = s3c64xx_gpiolib_mbank_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) #ifdef CONFIG_ARCH_S3C64XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .base = S3C64XX_GPH_BASE + 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .base = S3C64XX_GPH(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .ngpio = S3C64XX_GPIO_H_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .label = "GPH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .base = S3C64XX_GPK_BASE + 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .config = &samsung_gpio_cfgs[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .base = S3C64XX_GPK(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .ngpio = S3C64XX_GPIO_K_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .label = "GPK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .base = S3C64XX_GPL_BASE + 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .config = &samsung_gpio_cfgs[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .base = S3C64XX_GPL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .ngpio = S3C64XX_GPIO_L_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .label = "GPL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .to_irq = s3c64xx_gpiolib_lbank_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) #ifdef CONFIG_ARCH_S3C64XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) .base = S3C64XX_GPF_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) .config = &samsung_gpio_cfgs[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .base = S3C64XX_GPF(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .ngpio = S3C64XX_GPIO_F_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .label = "GPF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .config = &samsung_gpio_cfgs[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) .base = S3C64XX_GPI(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) .ngpio = S3C64XX_GPIO_I_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .label = "GPI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .config = &samsung_gpio_cfgs[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .base = S3C64XX_GPJ(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .ngpio = S3C64XX_GPIO_J_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .label = "GPJ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .config = &samsung_gpio_cfgs[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) .base = S3C64XX_GPO(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .ngpio = S3C64XX_GPIO_O_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .label = "GPO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .config = &samsung_gpio_cfgs[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) .base = S3C64XX_GPP(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) .ngpio = S3C64XX_GPIO_P_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) .label = "GPP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .config = &samsung_gpio_cfgs[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) .base = S3C64XX_GPQ(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .ngpio = S3C64XX_GPIO_Q_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .label = "GPQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) .base = S3C64XX_GPN_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) .irq_base = IRQ_EINT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) .config = &samsung_gpio_cfgs[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) .chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) .base = S3C64XX_GPN(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) .ngpio = S3C64XX_GPIO_N_NR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) .label = "GPN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) .to_irq = samsung_gpiolib_to_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /* TODO: cleanup soc_is_* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static __init int samsung_gpiolib_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * Currently there are two drivers that can provide GPIO support for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * Samsung SoCs. For device tree enabled platforms, the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * pinctrl-samsung driver is used, providing both GPIO and pin control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * interfaces. For legacy (non-DT) platforms this driver is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (of_have_populated_dt())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (soc_is_s3c24xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ARRAY_SIZE(samsung_gpio_cfgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) } else if (soc_is_s3c64xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ARRAY_SIZE(samsung_gpio_cfgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ARRAY_SIZE(s3c64xx_gpios_2bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) S3C64XX_VA_GPIO + 0xE0, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ARRAY_SIZE(s3c64xx_gpios_4bit),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) S3C64XX_VA_GPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ARRAY_SIZE(s3c64xx_gpios_4bit2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) core_initcall(samsung_gpiolib_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) offset = pin - chip->chip.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) samsung_gpio_lock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ret = samsung_gpio_do_setcfg(chip, offset, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) samsung_gpio_unlock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) EXPORT_SYMBOL(s3c_gpio_cfgpin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) for (; nr > 0; nr--, start++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ret = s3c_gpio_cfgpin(start, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) unsigned int cfg, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) for (; nr > 0; nr--, start++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) s3c_gpio_setpull(start, pull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = s3c_gpio_cfgpin(start, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) unsigned s3c_gpio_getcfg(unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) unsigned ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) offset = pin - chip->chip.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) samsung_gpio_lock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ret = samsung_gpio_do_getcfg(chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) samsung_gpio_unlock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) EXPORT_SYMBOL(s3c_gpio_getcfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int offset, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) offset = pin - chip->chip.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) samsung_gpio_lock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ret = samsung_gpio_do_setpull(chip, offset, pull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) samsung_gpio_unlock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) EXPORT_SYMBOL(s3c_gpio_setpull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) u32 pup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) offset = pin - chip->chip.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) samsung_gpio_lock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) pup = samsung_gpio_do_getpull(chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) samsung_gpio_unlock(chip, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return (__force samsung_gpio_pull_t)pup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) EXPORT_SYMBOL(s3c_gpio_getpull);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) #ifdef CONFIG_PLAT_S3C24XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) unsigned long misccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) misccr = __raw_readl(S3C24XX_MISCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) misccr &= ~clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) misccr ^= change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) __raw_writel(misccr, S3C24XX_MISCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return misccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) EXPORT_SYMBOL(s3c2410_modify_misccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) #endif