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 }
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; }
/* * 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); }
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_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; }
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; }
/* * 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_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); }
/* * uart_init(tx pin, rx pin, baudrate); * * Initialize a UART that will talk on the tx/rx pin pair at a given baudrate * Curently only 8n1 format, no-hw flow control, only. * * Returns channel unumber (0 - MAX_UART_CHANNELS) or -1 on error */ int uart_init(enum GPIO_PORT_PIN tx, enum GPIO_PORT_PIN rx, int baudrate) { uint32_t my_uart = uart_pin_map(tx, USART); int i; if (uart_pin_map(rx, USART) != my_uart) { /* Both pins are not connected to same serial port */ return -1; } if (nxt_channel >= MAX_UART_CHANNELS) { /* Need more channel configured */ return -2; } if (my_uart == 0) { /* neither pin connects to a USART? */ return -3; } /* Enable Clock for the USART/UART involved */ rcc_peripheral_enable_clock((uint32_t *)uart_pin_map(tx, APB_REG), uart_pin_map(tx, APB_ENA)); /* Enable Clock for the GPIOs we are using */ gpio_enable_clock(tx); gpio_enable_clock(rx); /* GPIO pins */ /* Both AF Mode */ gpio_mode_setup(gpio_base(tx), GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_bit(tx)); gpio_mode_setup(gpio_base(rx), GPIO_MODE_AF, GPIO_PUPD_NONE, gpio_bit(rx)); gpio_set_af(gpio_base(tx), uart_pin_map(tx, AF), gpio_bit(tx)); gpio_set_af(gpio_base(rx), uart_pin_map(rx, AF), gpio_bit(rx)); /* Transmit pin set to an output */ gpio_set_output_options(gpio_base(tx), GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, gpio_bit(tx)); /* Set up UART parameters */ usart_set_baudrate(my_uart, baudrate); usart_set_databits(my_uart, 8); usart_set_stopbits(my_uart, USART_STOPBITS_1); usart_set_mode(my_uart, USART_MODE_TX_RX); usart_set_parity(my_uart, USART_PARITY_NONE); usart_set_flow_control(my_uart, USART_FLOWCONTROL_NONE); usart_enable(my_uart); nxt_recv_ndx[nxt_channel] = cur_recv_ndx[nxt_channel] = 0; nxt_xmit_ndx[nxt_channel] = cur_xmit_ndx[nxt_channel] = 0; /* * This was done to try to get it to run under GDB with the Black * Magic debug probe but it didn't have any effect (interrupts * are still masked) */ nvic_set_priority(uart_pin_map(tx, IRQ), 0); // highest priority nvic_enable_irq(uart_pin_map(tx, IRQ)); USART_DR(my_uart) = 0; usart_enable_rx_interrupt(my_uart); /* Now create two mappings, channel => usart, and usart => channel */ channel_to_uart_map[nxt_channel] = my_uart; for (i = 0; i < NUARTS; i++) { if (UART_MAP[i] == my_uart) { uart_to_channel_map[i] = nxt_channel; break; } } nxt_channel++; return (nxt_channel - 1); }
/* * 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; }