Esempio n. 1
0
static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
{
	static unsigned int slpm[NUM_BANKS];
	unsigned long flags;
	bool glitch = false;
	int ret = 0;
	int i;

	for (i = 0; i < num; i++) {
		if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
			glitch = true;
			break;
		}
	}

	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);

	if (glitch) {
		memset(slpm, 0xff, sizeof(slpm));

		for (i = 0; i < num; i++) {
			int pin = PIN_NUM(cfgs[i]);
			int offset = pin % NMK_GPIO_PER_CHIP;

			if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
				slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
		}

		nmk_gpio_glitch_slpm_init(slpm);
	}

	for (i = 0; i < num; i++) {
		struct nmk_gpio_chip *nmk_chip;
		int pin = PIN_NUM(cfgs[i]);

		nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP];
		if (!nmk_chip) {
			ret = -EINVAL;
			break;
		}

		clk_enable(nmk_chip->clk);
		spin_lock(&nmk_chip->lock);
		__nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP,
				 cfgs[i], sleep, glitch ? slpm : NULL);
		spin_unlock(&nmk_chip->lock);
		clk_disable(nmk_chip->clk);
	}

	if (glitch)
		nmk_gpio_glitch_slpm_restore(slpm);

	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);

	return ret;
}
Esempio n. 2
0
static int pin_read(struct rt_device *device, rt_base_t pin)
{
    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
    {
        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
        return 0;
    }

    return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin);
}
Esempio n. 3
0
static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
    {
        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
        return;
    }

    gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value);
}
Esempio n. 4
0
static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
    {
        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
        return RT_ERROR;
    }

    gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin);

    return RT_EOK;
}
Esempio n. 5
0
static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
    {
        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
        return RT_ERROR;
    }

    gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args);
    gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode);
    return RT_EOK;
}
Esempio n. 6
0
void mcp2515_init(void)
{
	// Aktivieren der Pins fuer das SPI Interface
	PORT_SPI &=  ~((1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI)));
	DDR_SPI |= (1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI));
	
	SET(MCP2515_CS);
	SET_OUTPUT(MCP2515_CS);
	
	// Aktivieren des SPI Master Interfaces
	SPCR = (1 << SPE) | (1 << MSTR) | R_SPCR;
	SPSR = R_SPSR;
	
	_delay_us(1);
	
	// MCP2515 per Software Reset zuruecksetzten,
	// danach ist er automatisch im Konfigurations Modus
	RESET(MCP2515_CS);
	spi_putc(SPI_RESET);
	SET(MCP2515_CS);
	
	// ein bisschen warten bis der MCP2515 sich neu gestartet hat
	_delay_ms(0.1);
	
	// Filter usw. setzen
	RESET(MCP2515_CS);
	spi_putc(SPI_WRITE);
	spi_putc(RXF0SIDH);
	for (uint8_t i = 0; i < sizeof(mcp2515_register_map); i++) {
		spi_putc(pgm_read_byte(&mcp2515_register_map[i]));
	}
	SET(MCP2515_CS);
	
	// nur Standard IDs, Message Rollover nach Puffer 1
	mcp2515_write_register(RXB0CTRL, (0 << RXM1) | (1 << RXM0) | (1 << BUKT));
	mcp2515_write_register(RXB1CTRL, (0 << RXM1) | (1 << RXM0));
	
	// MCP2515 zurueck in den normalen Modus versetzten
	mcp2515_write_register(CANCTRL, CLKOUT_PRESCALER_);
}
Esempio n. 7
0
rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
    if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
    {
        dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin);
        return RT_ERROR;
    }

    if (enabled)
        gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin);
    else
        gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin);

    return RT_EOK;
}
Esempio n. 8
0
/**
 * config_pin - configure a pin's mux attributes
 * @cfg: pin confguration
 *
 * Configures a pin's mode (alternate function or GPIO), its pull up status,
 * and its sleep mode based on the specified configuration.  The @cfg is
 * usually one of the SoC specific macros defined in mach/<soc>-pins.h.  These
 * are constructed using, and can be further enhanced with, the macros in
 * plat/pincfg.h.
 *
 * If a pin's mode is set to GPIO, it is configured as an input to avoid
 * side-effects.  The gpio can be manipulated later using standard GPIO API
 * calls.
 */
static void config_pin(pin_cfg_t cfg)
{
    int pin = PIN_NUM(cfg);
    int pull = PIN_PULL(cfg);
    int af = PIN_ALT(cfg);
    int output = PIN_DIR(cfg);
    int val = PIN_VAL(cfg);

    if (output)
        db8500_gpio_make_output(pin, val);
    else {
        db8500_gpio_make_input(pin);
        db8500_gpio_set_pull(pin, pull);
    }

    gpio_set_mode(pin, af);
}
Esempio n. 9
0
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
			     pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
{
	static const char *afnames[] = {
		[NMK_GPIO_ALT_GPIO]	= "GPIO",
		[NMK_GPIO_ALT_A]	= "A",
		[NMK_GPIO_ALT_B]	= "B",
		[NMK_GPIO_ALT_C]	= "C"
	};
	static const char *pullnames[] = {
		[NMK_GPIO_PULL_NONE]	= "none",
		[NMK_GPIO_PULL_UP]	= "up",
		[NMK_GPIO_PULL_DOWN]	= "down",
		[3] /* illegal */	= "??"
	};
	static const char *slpmnames[] = {
		[NMK_GPIO_SLPM_INPUT]		= "input/wakeup",
		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change/no-wakeup",
	};

	int pin = PIN_NUM(cfg);
	int pull = PIN_PULL(cfg);
	int af = PIN_ALT(cfg);
	int slpm = PIN_SLPM(cfg);
	int output = PIN_DIR(cfg);
	int val = PIN_VAL(cfg);
	bool glitch = af == NMK_GPIO_ALT_C;

	dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
		pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
		output ? "output " : "input",
		output ? (val ? "high" : "low") : "");

	if (sleep) {
		int slpm_pull = PIN_SLPM_PULL(cfg);
		int slpm_output = PIN_SLPM_DIR(cfg);
		int slpm_val = PIN_SLPM_VAL(cfg);

		af = NMK_GPIO_ALT_GPIO;

		/*
		 * The SLPM_* values are normal values + 1 to allow zero to
		 * mean "same as normal".
		 */
		if (slpm_pull)
			pull = slpm_pull - 1;
		if (slpm_output)
			output = slpm_output - 1;
		if (slpm_val)
			val = slpm_val - 1;

		dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
			pin,
			slpm_pull ? pullnames[pull] : "same",
			slpm_output ? (output ? "output" : "input") : "same",
			slpm_val ? (val ? "high" : "low") : "same");
	}

	if (output)
		__nmk_gpio_make_output(nmk_chip, offset, val);
	else {
		__nmk_gpio_make_input(nmk_chip, offset);
		__nmk_gpio_set_pull(nmk_chip, offset, pull);
	}

	__nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg));

	/*
	 * If the pin is switching to altfunc, and there was an interrupt
	 * installed on it which has been lazy disabled, actually mask the
	 * interrupt to prevent spurious interrupts that would occur while the
	 * pin is under control of the peripheral.  Only SKE does this.
	 */
	if (af != NMK_GPIO_ALT_GPIO)
		nmk_gpio_disable_lazy_irq(nmk_chip, offset);

	/*
	 * If we've backed up the SLPM registers (glitch workaround), modify
	 * the backups since they will be restored.
	 */
	if (slpmregs) {
		if (slpm == NMK_GPIO_SLPM_NOCHANGE)
			slpmregs[nmk_chip->bank] |= BIT(offset);
		else
			slpmregs[nmk_chip->bank] &= ~BIT(offset);
	} else
		__nmk_gpio_set_slpm(nmk_chip, offset, slpm);

	__nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
}
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
			     pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
{
	static const char *afnames[] = {
		[NMK_GPIO_ALT_GPIO]	= "GPIO",
		[NMK_GPIO_ALT_A]	= "A",
		[NMK_GPIO_ALT_B]	= "B",
		[NMK_GPIO_ALT_C]	= "C"
	};
	static const char *pullnames[] = {
		[NMK_GPIO_PULL_NONE]	= "none",
		[NMK_GPIO_PULL_UP]	= "up",
		[NMK_GPIO_PULL_DOWN]	= "down",
		[3] /* illegal */	= "??"
	};
	static const char *slpmnames[] = {
		[NMK_GPIO_SLPM_INPUT]		= "input/wakeup",
		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change/no-wakeup",
	};

	int pin = PIN_NUM(cfg);
	int pull = PIN_PULL(cfg);
	int af = PIN_ALT(cfg);
	int slpm = PIN_SLPM(cfg);
	int output = PIN_DIR(cfg);
	int val = PIN_VAL(cfg);
	bool glitch = af == NMK_GPIO_ALT_C;

	dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
		pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
		output ? "output " : "input",
		output ? (val ? "high" : "low") : "");

	if (sleep) {
		int slpm_pull = PIN_SLPM_PULL(cfg);
		int slpm_output = PIN_SLPM_DIR(cfg);
		int slpm_val = PIN_SLPM_VAL(cfg);

		af = NMK_GPIO_ALT_GPIO;

		/*
		 * The SLPM_* values are normal values + 1 to allow zero to
		 * mean "same as normal".
		 */
		if (slpm_pull)
			pull = slpm_pull - 1;
		if (slpm_output)
			output = slpm_output - 1;
		if (slpm_val)
			val = slpm_val - 1;

		dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
			pin,
			slpm_pull ? pullnames[pull] : "same",
			slpm_output ? (output ? "output" : "input") : "same",
			slpm_val ? (val ? "high" : "low") : "same");
	}

	if (output)
		__nmk_gpio_make_output(nmk_chip, offset, val);
	else {
		__nmk_gpio_make_input(nmk_chip, offset);
		__nmk_gpio_set_pull(nmk_chip, offset, pull);
	}

	/*
	 * If we've backed up the SLPM registers (glitch workaround), modify
	 * the backups since they will be restored.
	 */
	if (slpmregs) {
		if (slpm == NMK_GPIO_SLPM_NOCHANGE)
			slpmregs[nmk_chip->bank] |= BIT(offset);
		else
			slpmregs[nmk_chip->bank] &= ~BIT(offset);
	} else
		__nmk_gpio_set_slpm(nmk_chip, offset, slpm);

	__nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
}