Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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);
	}
}
Ejemplo n.º 7
0
/*
 * 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;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
Archivo: uart.c Proyecto: ChuckM/libcpa
/*
 * 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);
}
Ejemplo n.º 13
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));
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
/*
 * 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;
}