static void port_setup(unsigned gpio, unsigned short usage) { #if defined(BF538_FAMILY) /* * BF538/9 Port C,D and E are special. * Inverted PORT_FER polarity on CDE and no PORF_FER on F * Regular PORT F GPIOs are handled here, CDE are exclusively * managed by GPIOLIB */ if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES) return; gpio -= MAX_BLACKFIN_GPIOS; if (usage == GPIO_USAGE) *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); else *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); SSYNC(); return; #endif if (check_gpio(gpio)) return; #if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \ defined(CONFIG_BF50x) if (usage == GPIO_USAGE) *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); #endif }
/* * ubi_gpio_get_port * Get the IO port associated with a certain gpio */ struct ubicom32_io_port *ubi_gpio_get_port(unsigned gpio) { if (gpio_bank(gpio) > NUM_GPIO_PORTS) { return NULL; } return gpio_bank_addr[gpio_bank(gpio)]; }
int gpio_set_value(unsigned gpio, int arg) { if (arg) gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); else gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); return 0; }
inline void portmux_setup(unsigned short per) { u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; pmux = *port_mux[gpio_bank(ident)]; pmux &= ~(3 << offset); pmux |= (function & 3) << offset; *port_mux[gpio_bank(ident)] = pmux; SSYNC(); }
/* * ubi_get_gpio_dir() */ static int ubi_get_gpio_dir(unsigned gpio) { if (gpio_bank_addr[gpio_bank(gpio)]->gpio_ctl & gpio_bit(gpio)) return 1; else return 0; }
/* * ubi_gpio_direction_output() */ static int ubi_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) { unsigned long flags; if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ubi_gpio_error(gpio); return -EINVAL; } local_irq_save(flags); /* Configure pin as gpio and set initial value in gpio_out register * so that when we enable it as an output, it will have the correct * initial value. */ ubi_port_setup(gpio, 1); if (value) { UBICOM32_GPIO_SET_PIN_HIGH(gpio); } else { UBICOM32_GPIO_SET_PIN_LOW(gpio); } /* Enable the pin as an output */ UBICOM32_GPIO_SET_PIN_OUTPUT(gpio); local_irq_restore(flags); return 0; }
/* If we are booting from SPI and our board lacks a strong enough pull up, * the core can reset and execute the bootrom faster than the resistor can * pull the signal logically high. To work around this (common) error in * board design, we explicitly set the pin back to GPIO mode, force /CS * high, and wait for the electrons to do their thing. * * This function only makes sense to be called from reset code, but it * lives here as we need to force all the GPIO states w/out going through * BUG() checks and such. */ void bfin_reset_boot_spi_cs(unsigned short pin) { unsigned short gpio = P_IDENT(pin); port_setup(gpio, GPIO_USAGE); gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); AWA_DUMMY_READ(data_set); udelay(1); }
int gpio_direction_output(unsigned gpio, int value) { unsigned long flags; if (!is_reserved(gpio, gpio, 0)) { gpio_error(gpio); return -EINVAL; } local_irq_save(flags); gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); AWA_DUMMY_READ(dir); local_irq_restore(flags); return 0; }
void set_gpio_toggle(unsigned gpio) { unsigned long flags; if (ANOMALY_05000311 || ANOMALY_05000323) local_irq_save(flags); gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); if (ANOMALY_05000311 || ANOMALY_05000323) { AWA_DUMMY_READ(toggle); local_irq_restore(flags); } }
/* * ubi_gpio_free() */ static void ubi_gpio_free(struct gpio_chip *chip, unsigned gpio) { unsigned long flags; if (check_gpio(gpio) < 0) return; local_irq_save(flags); if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { ubi_gpio_error(gpio); local_irq_restore(flags); return; } /* Assert the pin is no longer claimed */ reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); /* Revert port bit to use specified by port->function */ ubi_port_setup(gpio, 0); local_irq_restore(flags); }
/* * ubi_gpio_request() */ static int ubi_gpio_request(struct gpio_chip *chip, unsigned gpio) { unsigned long flags; if (check_gpio(gpio) < 0) return -EINVAL; local_irq_save(flags); if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { printk(KERN_ERR "ubi-gpio: GPIO %d is already reserved!\n", gpio); local_irq_restore(flags); return -EBUSY; } reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); ubi_port_setup(gpio, 1); local_irq_restore(flags); return 0; }
/* * gpio_proc_read() */ static int ubi_gpio_proc_read(char *buf, char **start, off_t offset, int len, int *unused_i, void *unused_v) { int c, outlen = 0; for (c = 0; c < MAX_UBICOM_GPIOS; c++) { if (!check_gpio(c) && (reserved_gpio_map[gpio_bank(c)] & gpio_bit(c))) { len = sprintf(buf, "GPIO_%d:\t\tGPIO %s\n", c, ubi_get_gpio_dir(c) ? "OUTPUT" : "INPUT"); } else { continue; } buf += len; outlen += len; } return outlen; }
/* * ubi_gpio_direction_input() */ static int ubi_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) { unsigned long flags; if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { ubi_gpio_error(gpio); return -EINVAL; } local_irq_save(flags); /* Configure pin as gpio */ ubi_port_setup(gpio, 1); /* Assert pin is an input */ UBICOM32_GPIO_SET_PIN_INPUT(gpio); local_irq_restore(flags); return 0; }
/* * ubi_gpio_get_value() */ static int ubi_gpio_get_value(struct gpio_chip *chip, unsigned gpio) { return 0 != (gpio_bank_addr[gpio_bank(gpio)]->gpio_in & gpio_bit(gpio)); }
static inline void __gpio_direction_input(unsigned gpio) { gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); }
/* * ubicom32bl_init_hw_pwm * Set the appropriate PWM registers */ static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud) { if (ud->pdata->pwm_channel > UBICOM32BL_NUM_PWM_CHANNELS) { return -ENODEV; } #if UBICOM32BL_NUM_PWM_CHANNELS # ifdef IP7000 { /* * bit 13: enable */ u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ; switch (ud->pdata->pwm_channel) { case 0: /* * Channel 0 is in the lower half of PORT C ctl0 and ctl1 (PA5) */ UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 &= ~0xFFFF; UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 |= pwm_cfg; UBICOM32_IO_PORT(IO_PORT_RC)->ctl1 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO/PWM */ if (!UBICOM32_IO_PORT(IO_PORT_RA)->function) { UBICOM32_IO_PORT(IO_PORT_RA)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RA_5); break; case 1: /* * Channel 1 is in the upper half of PORT C ctl0 and ctl2 (PE4) */ UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 &= ~0xFFFF0000; UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 |= (pwm_cfg << 16); UBICOM32_IO_PORT(IO_PORT_RC)->ctl2 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO/ExtIOInt */ if (!UBICOM32_IO_PORT(IO_PORT_RE)->function) { UBICOM32_IO_PORT(IO_PORT_RE)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RE_4); break; case 2: /* * Channel 2 is in PORT H ctl0 and ctl1 (PD0) */ UBICOM32_IO_PORT(IO_PORT_RH)->ctl0 &= ~0xFFFF0000; UBICOM32_IO_PORT(IO_PORT_RH)->ctl0 = pwm_cfg; UBICOM32_IO_PORT(IO_PORT_RH)->ctl1 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO */ if (!UBICOM32_IO_PORT(IO_PORT_RD)->function) { UBICOM32_IO_PORT(IO_PORT_RD)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RD_0); break; } } # elif IP8000 { struct ubicom32_io_port *port = UBICOM32_IO_PORT(IO_PORT_RQ + (ud->pdata->pwm_channel * 0x4000)); struct ubicom32_gpio_port *gpio = UBICOM32_PORT_NUM_TO_GPIO(gpio_bank(ud->pdata->gpio)); unsigned int mask = 0; /* * Check to see if the pin is busy so we don't clobber any functions */ u32_t fn_sel = gpio->fn_sel[0] | gpio->fn_sel[1] | gpio->fn_sel[2] | gpio->fn_sel[3]; if (fn_sel & gpio_bit(ud->pdata->gpio)) { printk(KERN_WARNING DRIVER_NAME ": GPIO %d in use %08x\n", ud->pdata->gpio, fn_sel); return -EBUSY; } switch (ud->pdata->pwm_channel) { case 0: /* * PWM Q can go on PG4[30](fn4), PG4[31](fn4), PG5[0](fn3), PG5[1](fn3) */ if (ud->pdata->gpio == GPIO_PG4_30) { mask = (1 << 30); gpio->fn_sel[3] |= mask; } else if (ud->pdata->gpio == GPIO_PG4_31) { mask = (1 << 31); gpio->fn_sel[3] |= mask; } else if (ud->pdata->gpio == GPIO_PG5_0) { mask = (1 << 0); gpio->fn_sel[2] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_1) { mask = (1 << 1); gpio->fn_sel[2] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 1: /* * PWM R can go on PG5[3](fn3), PG5[2](fn3) */ if (ud->pdata->gpio == GPIO_PG5_3) { mask = (1 << 3); gpio->fn_sel[2] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_2) { mask = (1 << 2); gpio->fn_sel[2] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 2: /* * PWM S can go on PG5[1](fn2), PG5[0](fn2) */ if (ud->pdata->gpio == GPIO_PG5_1) { mask = (1 << 1); gpio->fn_sel[1] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_0) { mask = (1 << 0); gpio->fn_sel[1] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 3: /* * PWM T can go on PG5[3](fn2), PG5[2](fn2) */ if (ud->pdata->gpio == GPIO_PG5_3) { mask = (1 << 3); gpio->fn_sel[1] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_2) { mask = (1 << 2); gpio->fn_sel[1] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; } /* * PWM is clocked at clk_core / (2 ^ pwm_prescale[3:0]) */ port->function = 1<<24 | 1; port->ctl0 = (ud->pdata->pwm_prescale << 8) ; gpio->gpio_ctl |= mask; } # endif #endif return 0; }