1.1 --- a/pkg/devices/lib/gpio/src/jz4780.cc Fri Sep 22 21:56:34 2023 +0200
1.2 +++ b/pkg/devices/lib/gpio/src/jz4780.cc Sun Sep 24 01:53:43 2023 +0200
1.3 @@ -2,7 +2,7 @@
1.4 * GPIO driver for Ingenic JZ4780.
1.5 * (See below for additional copyright and licensing notices.)
1.6 *
1.7 - * Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk>
1.8 + * Copyright (C) 2017, 2023 Paul Boddie <paul@boddie.org.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License as
1.12 @@ -47,20 +47,20 @@
1.13 */
1.14
1.15 enum Regs
1.16 -{
1.17 +{
1.18 Pin_level = 0x000, // PxPIN (read-only)
1.19 -
1.20 +
1.21 Port_int = 0x010, // PxINT
1.22 Port_int_set = 0x014, // PxINTS
1.23 Port_int_clear = 0x018, // PxINTC
1.24 -
1.25 +
1.26 Irq_mask = 0x020, // PxMSK (for PxINT == 1)
1.27 Irq_mask_set = 0x024, // PxMSKS
1.28 Irq_mask_clear = 0x028, // PxMSKC
1.29 Port_gpio = 0x020, // PxMSK (for PxINT == 0)
1.30 Port_gpio_set = 0x024, // PxMSKS
1.31 Port_gpio_clear = 0x028, // PxMSKC
1.32 -
1.33 +
1.34 Port_trigger = 0x030, // PxPAT1 (for PxINT == 1)
1.35 Port_trigger_set = 0x034, // PxPAT1S
1.36 Port_trigger_clear = 0x038, // PxPAT1C
1.37 @@ -70,7 +70,7 @@
1.38 Port_group1 = 0x030, // PxPAT1 (for PxINT == 0, PxMSK == 0)
1.39 Port_group1_set = 0x034, // PxPAT1S
1.40 Port_group1_clear = 0x038, // PxPAT1C
1.41 -
1.42 +
1.43 Port_level = 0x040, // PxPAT0 (for PxINT == 1)
1.44 Port_level_set = 0x044, // PxPAT0S
1.45 Port_level_clear = 0x048, // PxPAT0C
1.46 @@ -80,10 +80,10 @@
1.47 Port_group0 = 0x040, // PxPAT0 (for PxINT == 0, PxMSK == 0)
1.48 Port_group0_set = 0x044, // PxPAT0S
1.49 Port_group0_clear = 0x048, // PxPAT0C
1.50 -
1.51 +
1.52 Irq_flag = 0x050, // PxFLG (read-only)
1.53 Irq_flag_clear = 0x058, // PxFLGC
1.54 -
1.55 +
1.56 Pull_disable = 0x070, // PxPE
1.57 Pull_disable_set = 0x074, // PxPES
1.58 Pull_disable_clear = 0x078, // PxPEC
1.59 @@ -317,7 +317,7 @@
1.60 if (pin >= _nr_pins)
1.61 throw -L4_EINVAL;
1.62
1.63 - if (value > 1)
1.64 + if (value > 3)
1.65 throw -L4_EINVAL;
1.66
1.67 switch (func)
1.68 @@ -354,6 +354,45 @@
1.69 *value = (_regs[reg] >> _pin_shift(pin)) & 1;
1.70 }
1.71
1.72 +// Return function and function-specific configuration for a pin.
1.73 +
1.74 +void
1.75 +Gpio_jz4780_chip::config_pad_get(unsigned pin, unsigned *func, unsigned *value)
1.76 +{
1.77 + unsigned direction, gpio, group0, group1, interrupt, level, trigger;
1.78 +
1.79 + config_get(pin, Port_int, &interrupt);
1.80 +
1.81 + if (interrupt)
1.82 + {
1.83 + config_get(pin, Port_trigger, &trigger);
1.84 + config_get(pin, Port_level, &level);
1.85 +
1.86 + *func = Hw::Gpio_chip::Function_irq;
1.87 + *value = (trigger ? (level ? L4_IRQ_F_POS_EDGE : L4_IRQ_F_NEG_EDGE)
1.88 + : (level ? L4_IRQ_F_LEVEL_HIGH : L4_IRQ_F_LEVEL_LOW));
1.89 + return;
1.90 + }
1.91 +
1.92 + config_get(pin, Port_gpio, &gpio);
1.93 +
1.94 + if (gpio)
1.95 + {
1.96 + config_get(pin, Port_dir, &direction);
1.97 +
1.98 + *func = Hw::Gpio_chip::Function_gpio;
1.99 + *value = direction ? Input : Output;
1.100 + return;
1.101 + }
1.102 +
1.103 + *func = Hw::Gpio_chip::Function_alt;
1.104 +
1.105 + config_get(pin, Port_group0, &group0);
1.106 + config_get(pin, Port_group1, &group1);
1.107 +
1.108 + *value = (group1 << 1) | group0;
1.109 +}
1.110 +
1.111 // Obtain an IRQ abstraction for a pin.
1.112
1.113 Hw::Gpio_irq_pin *
1.114 @@ -417,6 +456,11 @@
1.115 static_cast<Gpio_jz4780_chip *>(gpio)->config_get(pin, reg, value);
1.116 }
1.117
1.118 +void jz4780_gpio_config_pad_get(void *gpio, unsigned pin, unsigned *func, unsigned *value)
1.119 +{
1.120 + static_cast<Gpio_jz4780_chip *>(gpio)->config_pad_get(pin, func, value);
1.121 +}
1.122 +
1.123 void jz4780_gpio_multi_setup(void *gpio, Pin_slice const *mask, unsigned mode, unsigned outvalues)
1.124 {
1.125 static_cast<Gpio_jz4780_chip *>(gpio)->multi_setup(*mask, mode, outvalues);