|
@@ -108,3 +108,54 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
|
|
|
|
|
|
pio = gpio_to_pio(pin);
|
|
pio = gpio_to_pio(pin);
|
|
if (unlikely(!pio)) {
|
|
if (unlikely(!pio)) {
|
|
|
|
+ printk("pio: invalid pin %u\n", pin);
|
|
|
|
+ goto fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
|
|
|
|
+ printk("%s: pin %u is busy\n", pio->name, pin_index);
|
|
|
|
+ goto fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (flags & AT32_GPIOF_OUTPUT) {
|
|
|
|
+ if (flags & AT32_GPIOF_HIGH)
|
|
|
|
+ pio_writel(pio, SODR, mask);
|
|
|
|
+ else
|
|
|
|
+ pio_writel(pio, CODR, mask);
|
|
|
|
+ if (flags & AT32_GPIOF_MULTIDRV)
|
|
|
|
+ pio_writel(pio, MDER, mask);
|
|
|
|
+ else
|
|
|
|
+ pio_writel(pio, MDDR, mask);
|
|
|
|
+ pio_writel(pio, PUDR, mask);
|
|
|
|
+ pio_writel(pio, OER, mask);
|
|
|
|
+ } else {
|
|
|
|
+ if (flags & AT32_GPIOF_PULLUP)
|
|
|
|
+ pio_writel(pio, PUER, mask);
|
|
|
|
+ else
|
|
|
|
+ pio_writel(pio, PUDR, mask);
|
|
|
|
+ if (flags & AT32_GPIOF_DEGLITCH)
|
|
|
|
+ pio_writel(pio, IFER, mask);
|
|
|
|
+ else
|
|
|
|
+ pio_writel(pio, IFDR, mask);
|
|
|
|
+ pio_writel(pio, ODR, mask);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pio_writel(pio, PER, mask);
|
|
|
|
+
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+fail:
|
|
|
|
+ dump_stack();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Undo a previous pin reservation. Will not affect the hardware
|
|
|
|
+ * configuration.
|
|
|
|
+ */
|
|
|
|
+void at32_deselect_pin(unsigned int pin)
|
|
|
|
+{
|
|
|
|
+ struct pio_device *pio;
|
|
|
|
+ unsigned int pin_index = pin & 0x1f;
|
|
|
|
+
|
|
|
|
+ pio = gpio_to_pio(pin);
|
|
|
|
+ if (unlikely(!pio)) {
|