예제 #1
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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
}
예제 #2
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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)];
}
예제 #3
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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;
}
예제 #4
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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();
}
예제 #5
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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;
}
예제 #6
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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;
}
예제 #7
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
/* 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);
}
예제 #8
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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;
}
예제 #9
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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);
	}
}
예제 #10
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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);
}
예제 #11
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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;
}
예제 #12
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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;
}
예제 #13
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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;
}
예제 #14
0
파일: ubi32-gpio.c 프로젝트: 7LK/McWRT
/*
 * 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));
}
예제 #15
0
파일: gpio.c 프로젝트: 0s4l/u-boot-xlnx
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);
}
예제 #16
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;
}