void StaticParam_Init(void) { int i; for(i = 0; i < GPIO_I2C_NUM; i ++) { GPIO_I2C_DIR[i] = IO_ADDRESS(GPIO_DIR(GPIOGRP[i])); GPIO_I2C_BIT[i][PINI2C_SCL] = GPIOSCL[i]; GPIO_I2C_BIT[i][PINI2C_SDA] = GPIOSDA[i]; GPIO_I2C_BIT[i][PINI2C_DAT] = GPIOSCL[i] | GPIOSDA[i]; GPIO_I2C_PIN[i][PINI2C_SCL] = IO_ADDRESS(GPIO_BASE(GPIOGRP[i]) + (GPIO_I2C_BIT[i][PINI2C_SCL] << 2)); GPIO_I2C_PIN[i][PINI2C_SDA] = IO_ADDRESS(GPIO_BASE(GPIOGRP[i]) + (GPIO_I2C_BIT[i][PINI2C_SDA] << 2)); GPIO_I2C_PIN[i][PINI2C_DAT] = IO_ADDRESS(GPIO_BASE(GPIOGRP[i]) + (GPIO_I2C_BIT[i][PINI2C_DAT] << 2)); spin_lock_init(&i2c_sem[i]); } #if 0 for(i = 0; i < GPIO_I2C_NUM; i ++) { printk("------>GPIO_I2C_DIR[%d] == 0x%08X\n", i, GPIO_I2C_DIR[i]); printk("------>GPIO_I2C_BIT[%d][%d] == 0x%08X\n", i, PINI2C_SCL, GPIO_I2C_BIT[i][PINI2C_SCL]); printk("------>GPIO_I2C_BIT[%d][%d] == 0x%08X\n", i, PINI2C_SDA, GPIO_I2C_BIT[i][PINI2C_SDA]); printk("------>GPIO_I2C_BIT[%d][%d] == 0x%08X\n", i, PINI2C_DAT, GPIO_I2C_BIT[i][PINI2C_DAT]); printk("------>GPIO_I2C_PIN[%d][%d] == 0x%08X\n", i, PINI2C_SCL, GPIO_I2C_PIN[i][PINI2C_SCL]); printk("------>GPIO_I2C_PIN[%d][%d] == 0x%08X\n", i, PINI2C_SDA, GPIO_I2C_PIN[i][PINI2C_SDA]); printk("------>GPIO_I2C_PIN[%d][%d] == 0x%08X\n", i, PINI2C_DAT, GPIO_I2C_PIN[i][PINI2C_DAT]); } #endif }
static void samsung_irq_gpio_unmask(unsigned int irq) { struct s3c_gpio_chip *chip = get_irq_chip_data(irq); int group, n, offset, value; group = chip->group; n = samsung_irq_gpio_get_bit(irq, group); offset = (group < 16) ? REG_OFFSET(group) : REG_OFFSET(group - 16); value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + offset); value &= ~BIT(n); __raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + offset); }
static void gpio_ack_irq(struct irq_data *d) { unsigned int gpio = irq_to_gpio(d->irq); void __iomem *base = GPIO_BASE(gpio / 32); __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR); }
static void gpio_unmask_irq(unsigned int irq) { unsigned int gpio = irq_to_gpio(irq); unsigned int base = GPIO_BASE(gpio / 32); _set_gpio_irqenable(base, gpio % 32, 1); }
static void gpio_ack_irq(unsigned int irq) { unsigned int gpio = irq_to_gpio(irq); unsigned int base = GPIO_BASE(gpio / 32); __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR); }
static void gpio_unmask_irq(struct irq_data *d) { unsigned int gpio = irq_to_gpio(d->irq); void __iomem *base = GPIO_BASE(gpio / 32); _set_gpio_irqenable(base, gpio % 32, 1); }
static void gpio_mask_irq(struct irq_data *d) { unsigned int gpio = irq_to_gpio(d->irq); unsigned int base = GPIO_BASE(gpio / 32); _set_gpio_irqenable(base, gpio % 32, 0); }
static int samsung_irq_gpio_set_type(unsigned int irq, unsigned int type) { struct s3c_gpio_chip *chip = get_irq_chip_data(irq); int group, bit, offset, value, eint_con; struct irq_desc *desc = irq_to_desc(irq); group = chip->group; bit = samsung_irq_gpio_get_bit(irq, group); switch (type) { case IRQ_TYPE_EDGE_RISING: eint_con = SAMSUNG_IRQ_GPIO_EDGE_RISING; break; case IRQ_TYPE_EDGE_FALLING: eint_con = SAMSUNG_IRQ_GPIO_EDGE_FALLING; break; case IRQ_TYPE_EDGE_BOTH: eint_con = SAMSUNG_IRQ_GPIO_EDGE_BOTH; break; case IRQ_TYPE_LEVEL_HIGH: eint_con = SAMSUNG_IRQ_GPIO_LEVEL_HIGH; break; case IRQ_TYPE_LEVEL_LOW: eint_con = SAMSUNG_IRQ_GPIO_LEVEL_LOW; break; case IRQ_TYPE_NONE: printk(KERN_WARNING "No irq type\n"); default: return -EINVAL; } offset = (group < 16) ? REG_OFFSET(group) : REG_OFFSET(group - 16); bit = bit << 2; /* 4 bits offset */ value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + offset); value &= ~(0xf << bit); value |= (eint_con << bit); __raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + offset); if (type & IRQ_TYPE_EDGE_BOTH) desc->handle_irq = handle_edge_irq; else desc->handle_irq = handle_level_irq; return 0; }
static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { void __iomem *base = GPIO_BASE(offset / 32); if (value) __raw_writel(1 << (offset % 32), base + GPIO_DATA_SET); else __raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR); }
void bl1_platform_setup(void) { int i; generic_delay_timer_init(); pl061_gpio_init(); for (i = 0; i < GPIO_MAX; i++) pl061_gpio_register(GPIO_BASE(i), i); plat_io_setup(); }
void gpio_init(void) { int i; for (i = 0; i < sizeof(gpio_info)/sizeof(GPIO_INFO); i ++) { const GPIO_INFO *gpio = &gpio_info[i]; GPIO_InitTypeDef GPIO_InitStruct; // enable the peripheral clock: __GPIOx_CLK_ENABLE() RCC->AHB1ENR |= (1 << GPIO_PORT(gpio->num)); // setup the gpio port/pin GPIO_InitStruct.Pin = GPIO_BIT(gpio->num); GPIO_InitStruct.Mode = gpio->mode; GPIO_InitStruct.Pull = gpio->pull; GPIO_InitStruct.Speed = gpio->speed; GPIO_InitStruct.Alternate = gpio->alt; HAL_GPIO_Init(GPIO_BASE(gpio->num), &GPIO_InitStruct); // set any initial value if (gpio->init >= 0) { HAL_GPIO_WritePin(GPIO_BASE(gpio->num), GPIO_BIT(gpio->num), gpio->init); } } }
static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, int dir) { void __iomem *base = GPIO_BASE(offset / 32); unsigned int reg; reg = __raw_readl(base + GPIO_DIR); if (dir) reg |= 1 << (offset % 32); else reg &= ~(1 << (offset % 32)); __raw_writel(reg, base + GPIO_DIR); }
void __init gemini_gpio_init(void) { int i, j; for (i = 0; i < GPIO_PORT_NUM; i++) { /* disable, unmask and clear all interrupts */ __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN); __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK); __raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR); for (j = GPIO_IRQ_BASE + i * 32; j < GPIO_IRQ_BASE + (i + 1) * 32; j++) { irq_set_chip_and_handler(j, &gpio_irq_chip, handle_edge_irq); set_irq_flags(j, IRQF_VALID); } irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler); irq_set_handler_data(IRQ_GPIO(i), (void *)i); } BUG_ON(gpiochip_add(&gemini_gpio_chip)); }
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int port = (unsigned int)irq_desc_get_handler_data(desc); unsigned int gpio_irq_no, irq_stat; irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); gpio_irq_no = GPIO_IRQ_BASE + port * 32; for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { if ((irq_stat & 1) == 0) continue; generic_handle_irq(gpio_irq_no); } }
static int gpio_set_irq_type(struct irq_data *d, unsigned int type) { unsigned int gpio = irq_to_gpio(d->irq); unsigned int gpio_mask = 1 << (gpio % 32); void __iomem *base = GPIO_BASE(gpio / 32); unsigned int reg_both, reg_level, reg_type; reg_type = __raw_readl(base + GPIO_INT_TYPE); reg_level = __raw_readl(base + GPIO_INT_LEVEL); reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE); switch (type) { case IRQ_TYPE_EDGE_BOTH: reg_type &= ~gpio_mask; reg_both |= gpio_mask; break; case IRQ_TYPE_EDGE_RISING: reg_type &= ~gpio_mask; reg_both &= ~gpio_mask; reg_level &= ~gpio_mask; break; case IRQ_TYPE_EDGE_FALLING: reg_type &= ~gpio_mask; reg_both &= ~gpio_mask; reg_level |= gpio_mask; break; case IRQ_TYPE_LEVEL_HIGH: reg_type |= gpio_mask; reg_level &= ~gpio_mask; break; case IRQ_TYPE_LEVEL_LOW: reg_type |= gpio_mask; reg_level |= gpio_mask; break; default: return -EINVAL; } __raw_writel(reg_type, base + GPIO_INT_TYPE); __raw_writel(reg_level, base + GPIO_INT_LEVEL); __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); gpio_ack_irq(d); return 0; }
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int gpio_irq_no, irq_stat; unsigned int port = (unsigned int)get_irq_data(irq); irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT); gpio_irq_no = GPIO_IRQ_BASE + port * 32; for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { if ((irq_stat & 1) == 0) continue; BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, &irq_desc[gpio_irq_no]); } }
__LINK_C bool hw_gpio_get_in(pin_id_t pin_id) { return GPIO_HAL_ReadPinInput(GPIO_BASE(pin_id.port), pin_id.pin); }
__LINK_C error_t hw_gpio_toggle(pin_id_t pin_id) { GPIO_HAL_TogglePinOutput(GPIO_BASE(pin_id.port), pin_id.pin); return SUCCESS; }
__LINK_C error_t hw_gpio_clr(pin_id_t pin_id) { GPIO_HAL_WritePinOutput(GPIO_BASE(pin_id.port), pin_id.pin, 0); return SUCCESS; }
static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset) { void __iomem *base = GPIO_BASE(offset / 32); return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1; }