Beispiel #1
0
/**
 * gpio drive strength slector
 */
int gpio_drive_slector(unsigned gpio, enum GPIODriveSlector slector)
{
	struct rk_gpio_bank *bank = rk_gpio_get_bank(gpio);
	void __iomem *base;
	u32 val;

	if (bank == NULL) {
		return -1;
	}

	gpio = (gpio & RK_GPIO_PIN_MASK) >> RK_GPIO_PIN_OFFSET;
	if (gpio >= bank->ngpio) {
		return -1;
	}

#if (CONFIG_RKCHIPTYPE == CONFIG_RK3288)
	/*
	 * drive slector
	 * 2'b00: 2mA
	 * 2'b01: 4mA
	 * 2'b10: 8mA
	 * 2'b11: 12mA
	 */
	switch (slector) {
		case GPIODrv2mA:
			val = 0;
			break;
		case GPIODrv4mA:
			val = 1;
			break;
		case GPIODrv8mA:
			val = 2;
			break;
		case GPIODrv12mA:
			val = 3;
			break;
		default:
			return -EINVAL;
	}

	if (bank->id == 0) { /* gpio0, pmu control */
		if (gpio < (8+8+3)) { /* gpio0_a0-a8, gpio0_b0-b8, gpio0_c0-c2 */
			base = (void __iomem *)(RKIO_PMU_PHYS + PMU_GPIO0A_DRV + ((gpio / 8) * 4));
			gpio = (gpio % 8) * 2;
			__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
		}
	} else { /* gpio1-gpio8, grf control */
		base = (void __iomem *)((RKIO_GRF_PHYS + (GRF_GPIO1D_E - 0xC) + (bank->id - 1) * 16) + ((gpio / 8) * 4));
		gpio = (7 - (gpio % 8)) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	}
#else
	/* check chip if support gpio drive slector */
#endif

	return 0;
}
Beispiel #2
0
/**
 * Get value of the specified gpio
 */
int gpio_get_value(unsigned gpio)
{
	struct rk_gpio_bank *bank = rk_gpio_get_bank(gpio);

	if (bank == NULL) {
		return -1;
	}

	gpio = (gpio & RK_GPIO_PIN_MASK) >> RK_GPIO_PIN_OFFSET;
	if (gpio >= bank->ngpio) {
		return -1;
	}

	return rk_gpio_get_pin_level(bank->regbase, offset_to_bit(gpio));
}
Beispiel #3
0
/**
 * Set gpio direction as input
 */
int gpio_direction_input(unsigned gpio)
{
	struct rk_gpio_bank *bank = rk_gpio_get_bank(gpio);

	if (bank == NULL)
		return -1;

	gpio = (gpio & RK_GPIO_PIN_MASK) >> RK_GPIO_PIN_OFFSET;
	if (gpio >= bank->ngpio)
		return -1;

	rk_gpio_set_pin_direction(bank->regbase, offset_to_bit(gpio), GPIO_IN);

	return 0;
}
Beispiel #4
0
/**
 * Set gpio pull up or down mode
 */
int gpio_pull_updown(unsigned gpio, enum GPIOPullType type)
{
	struct rk_gpio_bank *bank = rk_gpio_get_bank(gpio);
	void __iomem *base;
	u32 val;

	if (bank == NULL) {
		return -1;
	}

	gpio = (gpio & RK_GPIO_PIN_MASK) >> RK_GPIO_PIN_OFFSET;
	if (gpio >= bank->ngpio) {
		return -1;
	}

#if defined(CONFIG_RKCHIP_RK3188)
	/*
	 * pull setting
	 * 2'b00: Z(Noraml operaton)
	 * 2'b01: weak 1(pull-up)
	 * 2'b10: weak 0(pull-down)
	 * 2'b11: Repeater(Bus keeper)
	 */
	switch (type) {
		case PullDisable:
			val = 0;
			break;
		case GPIOPullUp:
			val = 1;
			break;
		case GPIOPullDown:
			val = 2;
			break;
		default:
			return -EINVAL;
	}

	if (bank->id == 0 && gpio < 12) {
		base = (void __iomem *)(RKIO_PMU_PHYS + PMU_GPIO0A_PULL + ((gpio / 8) * 4));
		gpio = (gpio % 8) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	} else {
		base = (void __iomem *)(RKIO_GRF_PHYS + GRF_GPIO0B_PULL - 4 + bank->id * 16 + ((gpio / 8) * 4));
		gpio = (7 - (gpio % 8)) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	}
#elif defined(CONFIG_RKCHIP_RK3288)
	/*
	 * pull setting
	 * 2'b00: Z(Noraml operaton)
	 * 2'b01: weak 1(pull-up)
	 * 2'b10: weak 0(pull-down)
	 * 2'b11: Repeater(Bus keeper)
	 */
	switch (type) {
		case PullDisable:
			val = 0;
			break;
		case GPIOPullUp:
			val = 1;
			break;
		case GPIOPullDown:
			val = 2;
			break;
		default:
			return -EINVAL;
	}

	if (bank->id == 0) { /* gpio0, pmu control */
		if (gpio < (8+8+3)) { /* gpio0_a0-a8, gpio0_b0-b8, gpio0_c0-c2 */
			base = (void __iomem *)(RKIO_PMU_PHYS + PMU_GPIO0A_PULL + ((gpio / 8) * 4));
			gpio = (gpio % 8) * 2;
			__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
		}
	} else { /* gpio1-gpio8, grf control */
		base = (void __iomem *)((RKIO_GRF_PHYS + (GRF_GPIO1D_P - 0xC) + (bank->id - 1) * 16) + ((gpio / 8) * 4));
		gpio = (7 - (gpio % 8)) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	}
#elif defined(CONFIG_RKCHIP_RK3368)
	/*
	 * pull setting
	 * 2'b00: Z(Noraml operaton)
	 * 2'b01: weak 1(pull-up)
	 * 2'b10: weak 0(pull-down)
	 * 2'b11: Repeater(Bus keeper)
	 */
	switch (type) {
		case PullDisable:
			val = 0;
			break;
		case GPIOPullUp:
			val = 1;
			break;
		case GPIOPullDown:
			val = 2;
			break;
		default:
			return -EINVAL;
	}

	if (bank->id == 0) { /* gpio0, pmu grf control */
		base = (void __iomem *)(unsigned long)(RKIO_PMU_GRF_PHYS + PMU_GRF_GPIO0A_P + ((gpio / 8) * 4));
		gpio = (7 - (gpio % 8)) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	} else { /* gpio1-gpio3, grf control */
		base = (void __iomem *)(unsigned long)(RKIO_GRF_PHYS + GRF_GPIO1A_P + (bank->id - 1) * 16 + ((gpio / 8) * 4));
		gpio = (7 - (gpio % 8)) * 2;
		__raw_writel((0x3 << (16 + gpio)) | (val << gpio), base);
	}
#elif defined(CONFIG_RKCHIP_RK3168)
	/* rk3168 do nothing */

#elif defined(CONFIG_RKCHIP_RK3066) || defined(CONFIG_RKCHIP_RK3036) \
	|| defined(CONFIG_RKCHIP_RK3126) || defined(CONFIG_RKCHIP_RK3128)
	/* RK30XX && RK292X */
	/*
	 * Values written to this register independently
	 * control Pullup/Pulldown or not for the
	 * corresponding data bit in GPIO.
	 * 0: pull up/down enable, PAD type will decide
	 * to be up or down, not related with this value
	 * 1: pull up/down disable
	*/
	val = (type == PullDisable) ? 1 : 0;
	base = (void __iomem *)(RKIO_GRF_PHYS + GRF_GPIO0L_PULL + bank->id * 8 + ((gpio / 16) * 4));
	gpio = gpio % 16;
	__raw_writel((1 << (16 + gpio)) | (val << gpio), base);
#else
	#error "PLS config platform for gpio driver."
#endif

	return 0;
}