From 3f1662b300329a0788d8b9a113145db48b4a3ca6 Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Fri, 9 Oct 2026 22:45:32 +0300 Subject: [PATCH 1/2] novatek: pad-mux, reginfo and GPIO for NA51089 (#237) `ipctool reginfo` on an NT98566 said "Platform is not supported": the Novatek HAL never set chip_generation, and no Novatek table existed. The NA51089 selects a pad's function a fourth way: a location field per peripheral in the TOP block (SigmaStar's arrangement), plus a gate bit per pad that has to be cleared before any field reaches it. A new backend, src/hal/novatek_padmux.c, reads that as claims -- a name and the field values under which the pad carries it -- and takes the first that holds. set() writes the claim that changes least, clears the gate, and drops a competitor that still wins by zeroing a field the target does not need. There is no datasheet or pin table in the SDK, only the vendor driver's pinmux_config_*() functions. tools/gen_novatek_padmux.py compiles those on the host with every register write logged, runs every combination of up to four options (96,550 calls), attributes each gate write to the field writes of the blocks around it, and replays every state against the table. Names come from top.h's annotations and top.csv; three places where those disagree with the code are recorded as errata, one of them a vendor bug that makes PIN_MISC_CFG_SP2CLK_3RD do nothing. Also: - chip_generation is the TOP chip-ID word. - plain `reginfo` dumps the TOP mux registers and the eight gate bitmaps. - `gpio get/set/scan` and the IR-cut hint drive the NA51089 GPIO controller (DATA/DIR/SET/CLR at 0xF0070000). - pads may be given as the Linux GPIO number or the kernel's name (P_GPIO22, MC17, HSI_GPIO9); the HiSilicon 5_2 form is refused there. No Novatek board is in the lab: verified against vendor source, by reginfo_test's sweep and test_novatek(), and by the generator's replay. ipcinfo does not grow; ipctool grows 16 KB on arm32 (9 KB after UPX). --- .clang-format-hook-exclude | 1 + CLAUDE.md | 28 +- CMakeLists.txt | 15 +- docs/gpio.md | 16 + docs/padmux.md | 101 +- src/hal/novatek.c | 5 + src/hal/novatek_gpio.c | 78 ++ src/hal/novatek_gpio.h | 36 + src/hal/novatek_padmux.c | 452 +++++++ src/hal/novatek_padmux.h | 1117 +++++++++++++++++ src/hal/novatek_padmux_types.h | 73 ++ src/hal/novatek_reginfo.h | 39 + src/padmux.c | 12 + src/padmux.h | 20 +- src/padmux_names.c | 1080 ++++++++++++++++ src/padmux_names.h | 2164 +++++++++++++++++++++++++++++++- src/reginfo.c | 184 ++- src/reginfo_test.c | 169 +++ tools/gen_novatek_padmux.py | 1437 +++++++++++++++++++++ tools/gen_padmux_names.py | 14 +- 20 files changed, 7009 insertions(+), 32 deletions(-) create mode 100644 src/hal/novatek_gpio.c create mode 100644 src/hal/novatek_gpio.h create mode 100644 src/hal/novatek_padmux.c create mode 100644 src/hal/novatek_padmux.h create mode 100644 src/hal/novatek_padmux_types.h create mode 100644 src/hal/novatek_reginfo.h create mode 100755 tools/gen_novatek_padmux.py diff --git a/.clang-format-hook-exclude b/.clang-format-hook-exclude index e886ef63..2fd420db 100644 --- a/.clang-format-hook-exclude +++ b/.clang-format-hook-exclude @@ -1,4 +1,5 @@ src/hal/sstar_padmux\.h src/hal/ingenic_padmux\.h +src/hal/novatek_padmux\.h src/padmux_names\.h src/padmux_names\.c diff --git a/CLAUDE.md b/CLAUDE.md index 22ba5467..1dd61169 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,9 +76,10 @@ CMake knobs worth knowing: question the linker cannot answer — nothing here is dead code as far as it knows. - `-DIPCHW_PADMUX=all|none|"v1;v4;sstar"` selects which SoC families' pad-mux - tables go into `libipchw`. `sstar` and `ingenic` are families here too: the - vendor knob answers "can this build detect the SoC", this one answers "does - it carry the SoC's pad table", and they are deliberately separate. All of it + tables go into `libipchw`. `sstar`, `ingenic` and `novatek` are families + here too: the vendor knob answers "can this build detect the SoC", this one + answers "does it carry the SoC's pad table", and they are deliberately + separate. All of it is ~75 KB on arm32 and nothing is dropped by `--gc-sections`, because `regs_by_chip()` and `padmux_ops()` name every family from a single switch: a consumer that wants one family has to say so. `v4` is the expensive @@ -252,8 +253,8 @@ cJSON or prints diagnostics in those shared files must sit inside window in four file-statics, no lock -- so serialise every caller yourself. - Pad multiplexing spans `src/padmux.c` (the public entry points and the backend dispatch), `src/reginfo.c` (1333 hand-entered HiSilicon/Goke rows - plus their backend), `src/hal/sstar_padmux.*` and - `src/hal/ingenic_padmux.*`. The three vendors select a pad's function three + plus their backend), `src/hal/sstar_padmux.*`, `src/hal/ingenic_padmux.*` + and `src/hal/novatek_padmux.*`. The four vendors select a pad's function four different ways and only HiSilicon's is one register per pad, which is why there is a `padmux_ops_t` seam rather than one table format. `docs/padmux.md` has the mechanisms, the generators, and the traps -- read it before touching @@ -266,12 +267,21 @@ cJSON or prints diagnostics in those shared files must sit inside (hi3516ev300 has PWM2 and PWM3 on three pads each), and the spelling is not portable (`PWM_OUT0` on V1, `PWM0` from V2, `PWM0_OUT1` on V5, `PWM0_MODE_4` on SigmaStar; `SVB_PWM` and `PMC_PWM` are *different* controllers, so match - the prefix anchored, never anywhere in the string). The SigmaStar and - Ingenic tables are generated from vendor sources by `tools/gen_*_padmux.py` - and are in `.clang-format-hook-exclude`. `ipchw_padmux_by_func/_by_prefix/ - _by_pad` are safe to call concurrently once the SoC has been detected; + the prefix anchored, never anywhere in the string). The SigmaStar, + Ingenic and Novatek tables are generated from vendor sources by + `tools/gen_*_padmux.py` and are in `.clang-format-hook-exclude`. Novatek's + generator is the odd one: the NA51089 SDK has no pin table, only the + driver's `pinmux_config_*()` code, so it compiles that code on the host with + every register write logged and runs it -- it needs a C compiler and the + SDK, and its `--selftest` needs only the compiler. + `ipchw_padmux_by_func/_by_prefix/_by_pad` are safe to call concurrently once the SoC has been detected; detection itself is not, so call `getchipname()` once at startup. `ipchw_padmux_get/_set` touch `/dev/mem` and must stay on one thread. +- `gpio get/set/scan` reach a GPIO controller per vendor: HiSilicon's bank + words in `src/reginfo.c` (`get_chip_gpio_adress()`), SigmaStar Infinity6C's + per-pad registers in `src/hal/sstar_gpio.c`, and the NA51089's four + DATA/DIR/SET/CLR banks in `src/hal/novatek_gpio.c`. Ingenic has none, so + only `gpio mux` and `reginfo --pads` work there. - `src/fake_symbols.c` holds empty definitions of HiSilicon SDK audio symbols, added when the Hi3518EV100 SDK was linked in; nothing in the current tree references them. `src/stack.c` is a stack-protector shim and is not in the diff --git a/CMakeLists.txt b/CMakeLists.txt index dcc69e07..81506904 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,7 +72,7 @@ endif() # Same shape as IPCHW_VENDORS above, and for the same reason -- set(... CACHE) # here means a parent project has to FORCE it. set(IPCHW_PADMUX_FAMILIES v1 v2 v2a v3 v3a v4 v4a v5 3536c 3536d sstar - ingenic) + ingenic novatek) set(IPCHW_PADMUX "all" CACHE STRING "Pad-mux tables compiled into libipchw: 'all', 'none', or a subset of ${IPCHW_PADMUX_FAMILIES}") @@ -100,19 +100,20 @@ foreach(_f IN LISTS _padmux_selected) endforeach() message(STATUS "libipchw pad-mux tables: ${_padmux_selected}") -# The two vendors whose pad-mux is its own backend rather than a table in +# The vendors whose pad-mux is its own backend rather than a table in # reginfo.c. Selecting the family is what compiles the backend in; selecting # the vendor HAL is what makes chip_generation reach it. They are separate # questions, which is why they are separate knobs -- a consumer can carry the # SigmaStar tables in a build that detects nothing else, which is exactly what # reginfo_test does. set(IPCHW_PADMUX_BACKENDS "") -foreach(_f sstar ingenic) +foreach(_f sstar ingenic novatek) if(_f IN_LIST _padmux_selected) list(APPEND IPCHW_PADMUX_BACKENDS src/hal/${_f}_padmux.c) endif() endforeach() -set(IPCHW_PADMUX_BACKENDS_ALL src/hal/sstar_padmux.c src/hal/ingenic_padmux.c) +set(IPCHW_PADMUX_BACKENDS_ALL src/hal/sstar_padmux.c src/hal/ingenic_padmux.c + src/hal/novatek_padmux.c) # Which HiSilicon generations libipchw can identify. IPCHW_VENDORS does not # reach the CODE: chipid.c dispatches to the HiSilicon HAL directly rather @@ -279,7 +280,8 @@ set(_common_lib_src_tail # Full set, used by the ipctool executable set(COMMON_LIB_SRC_ALL ${_common_lib_src_head} ${IPCHW_HISI_SRC_ALL} ${_common_lib_src_tail} ${IPCHW_PADMUX_BACKENDS_ALL} - src/hal/sstar_gpio.c src/hal/sstar_gpio.h) + src/hal/sstar_gpio.c src/hal/sstar_gpio.h + src/hal/novatek_gpio.c src/hal/novatek_gpio.h) foreach(_v IN LISTS IPCHW_OPTIONAL_VENDORS) list(APPEND COMMON_LIB_SRC_ALL src/hal/${_v}.c src/hal/${_v}.h) string(TOUPPER ${_v} _V) @@ -299,6 +301,9 @@ foreach(_v IN LISTS _ipchw_selected) if(_v STREQUAL "sstar") list(APPEND COMMON_LIB_SRC src/hal/sstar_gpio.c src/hal/sstar_gpio.h) endif() + if(_v STREQUAL "novatek") + list(APPEND COMMON_LIB_SRC src/hal/novatek_gpio.c src/hal/novatek_gpio.h) + endif() string(TOUPPER ${_v} _V) list(APPEND IPCHW_VENDOR_DEFS IPCHW_VENDOR_${_V}) endforeach() diff --git a/docs/gpio.md b/docs/gpio.md index d3388b7f..350a5e01 100644 --- a/docs/gpio.md +++ b/docs/gpio.md @@ -23,6 +23,13 @@ GPIO pad, decoded from the pad's own one-byte register into what it reads (`in`), what the SoC is driving (`out`) and whether it drives at all (`oe_n`, 1 meaning input/Hi-Z) — rather than the per-group data and direction words. +On Novatek (NT98562/NT98566) the pad is the kernel's GPIO number as well, and +its name is accepted too: `gpio get P_GPIO22`, `gpio get 54` and +`/sys/class/gpio/gpio54` are one wire (`P_GPIO(n)` is `0x20 + n`, and so on in +steps of `0x20` through C, P, S, L, D, H, A and DSI). The `5_6` form is refused +there, because it would name a different pad. `gpio scan` prints one `Pad:` +line per GPIO pad with its name, data word and direction. + ## `gpio scan` It prints a baseline table of every GPIO pad, then polls in a loop and reports @@ -123,6 +130,9 @@ streamer maps the GPIO block, a board whose whole pad list holds only one or two driving pads gets exactly those, and without a streamer every pad currently driving low is reported. +Novatek does the same over its GPIO numbers: the controller is one page, so +"the streamer has it mapped" is one answer for every pad. + IR-cut is nearly always a *pair* of pads, driven in opposite directions to flip the filter between its two positions. To confirm a pair, run `gpio scan` and switch the camera between day and night mode in the web UI. Both pads change in @@ -184,6 +194,12 @@ one register per pad and this particular trap does not apply, but the general rule does: a pad on a working board is carrying something, and taking it away stops whatever that was. `docs/padmux.md` has the mechanisms per vendor. +Novatek has the SigmaStar trap and one of its own. Muxing I2C3 onto a new pad +moves the peripheral's location field, so the pads it was on are left handed +over to nothing (`gpio mux` reports them as `?`). And on a board with a +parallel sensor, `gpio mux H_GPIO4 GPIO` cannot take one data line back without +switching the sensor mode off, so it switches it off. + If you do re-mux something by accident, `gpio mux ` puts it back; on SigmaStar restoring a pad to "idle but not GPIO-asserted" also needs one `devmem` to clear the pad's GPIO-enable bit, which `gpio mux` has no diff --git a/docs/padmux.md b/docs/padmux.md index 1ba059cd..bb3d9d8e 100644 --- a/docs/padmux.md +++ b/docs/padmux.md @@ -23,10 +23,10 @@ puts the pad back. > pad to GPIO. A pad that a MISC-style table drop hides from `reginfo --pads` > still answers here, which is the one place to see it. -## Three vendors, three mechanisms +## Four vendors, four mechanisms This is the thing to understand before touching any of it. The API looks like -one question, and underneath it is three different pieces of silicon. +one question, and underneath it is four different pieces of silicon. ### HiSilicon and Goke -- a selector per pad @@ -285,6 +285,53 @@ Direction is part of the same nibble as the mux, so "make this GPIO" has to pick one: a pad already held as GPIO keeps what it had, one coming off a peripheral becomes an input. +### Novatek -- a field per peripheral, and a gate per pad + +NA51089 (NT98562, NT98566) is SigmaStar's arrangement with a second lock on +it. In the TOP block at `0xF0010000` each peripheral has a location field -- +`REG5[7:6]` is I2C3, and 1, 2 and 3 put it on `P_GPIO21/22`, `C_GPIO11/12` +or `DSI_GPIO8/9` -- and each pad has a **gate bit** in one of eight bitmaps +at `TOP + 0xA0..0xE8`, where 1 keeps the pad a GPIO whatever any field says. +The vendor's `pinmux_config_*()` sets both, every time: the field, then +`GPIO_ID_EMUM_FUNC` into the gate of each pad it uses. + +So a pad's alternatives are **claims**: a name and the field values under +which the pad carries it. `get()` takes the first claim that holds, with the +table sorted most specific first; `set()` writes a claim's fields and clears +the gate. Consequences: + +- No row carries `IPCHW_PADMUX_F_RMW` except a GPIO row. A function is a field + in one register and a bit in another, and a consumer that writes only the + field leaves the pad a GPIO -- harmless, which is why the row's + `address`/`func_mask`/`func` still describe the field. +- **Moving a peripheral orphans its old pads.** Put I2C3 on `P_GPIO21` while + `C_GPIO11` had it and `C_GPIO11` keeps its gate cleared with nothing + claiming it: `get()` says it cannot name it, which is the truth. The vendor + code does the same and never gives those gates back. +- `set()` changes as little as it can. Several claims can spell one name -- + `ETH_RMII` on `DSI_GPIO9` is one claim alone and another when `ETH_MDIO` is + also set -- and the one needing the fewest field changes from what is there + now wins. A competitor that still wins afterwards is dropped by zeroing a + field the target does not need: `ETH_MDIO` on `DSI_GPIO9`, the internal + PHY's management pin, clears `ETH` and so ends RMII. +- **The parallel and CCIR sensor modes ignore the gate.** They put pixel data + on the HSI pads while the vendor writes those gates to GPIO, so those claims + hold through it (`NVT_UNGATED` in the table). `gpio mux H_GPIO4 GPIO` on such + a board has to zero `SENSOR` to mean anything, and does -- the whole parallel + bus goes with it. The MIPI lanes on the same pads are the opposite: the gate + cleared and no field at all. +- Pads are the kernel's GPIO numbers and names: `C_GPIO(n)` is `n`, + `P_GPIO(n)` is `0x20 + n`, and so on through S, L, D, H, A and DSI. `gpio` + takes the number or the name (`P_GPIO22`, and the vendor's `MC17` and + `HSI_GPIO9` as well); the HiSilicon `5_2` form is refused, because it would + land on a different pad. + +Function names are the vendor's, from the `@PAD[NAME]` annotations in +`plat-na51089/top.h` and then `top.csv`: `I2C3_2_SCL`, `UART2_2_RTS`, `SB_CK` +for SIF. Where neither names a pad the name is the option's own -- `SENSOR_12BITS`, +`MIPI_LVDS_CLK0`, `ETH_RMII` -- which, like SigmaStar's `I2C1_MODE_3`, names a +bus and not a wire. + ## Pad numbers and names `gpio_pad` is the number the kernel uses, and it is the number to speak to @@ -295,6 +342,7 @@ every consumer: | HiSilicon/Goke | `bank * 8 + pin`, parsed out of the `GPIO_

` entry | `"GPIO5_2"` | | SigmaStar | the vendor pad id, which is the gpiochip index (base 0) | `"PAD_SR_IO03"` | | Ingenic | `port * 32 + pin` | `"PB25"` | +| Novatek | the Linux GPIO number, `group * 32 + pin` | `"P_GPIO22"` | Function names are the vendor's own and are **not portable**, not even within HiSilicon: `PWM_OUT0` on V1, `PWM0` from V2, `PWM0_OUT1` on V5. `"PWM"` also @@ -332,6 +380,41 @@ tools/gen_ingenic_padmux.py \ Each generated header carries the exact command that made it, so the recipe above is only the shape; the header is the record. +Novatek is generated differently, because its source is code and not a table: + +```sh +# Novatek: the SDK root, which has BSP/linux-kernel and build/nvt-tools +tools/gen_novatek_padmux.py --sdk /path/to/na51089_linux_sdk \ + > src/hal/novatek_padmux.h +``` + +There is no datasheet and no pin list in the NA51089 SDK, and +`na51089_pinmux_host.c` is 2200 lines of nested `if`/`else if`/`switch` with +the conflict checks interleaved. So the generator **runs** it: it cuts the +`pinmux_config_*()` functions out, wraps every `top_regN.bit.FIELD = value` +in a macro that logs the write, compiles that on the host against the SDK's +own `top_reg.h`/`top.h`, and calls every function with every combination of +up to four of its options (96,550 calls, about half a minute). A combination the +vendor refuses is retried after one option of another group, which is the +only way MIPI data lanes 1-3 appear at all: `pinmux_config_mipi_lvds()` +refuses them until the sensor group is in CSI mode. + +The source is read for one thing: which braces enclose each write. A gate +write's conditions are the field writes the same call made in the blocks +around it -- `SEN_MCLK=1` for `S_GPIO0`, not the sensor mode a sibling block +of the same call selected. Every state the vendor code produced is then +replayed against the table, and three answers are acceptable: the pad reads +as what the code meant; it reads as nothing because a later write of the same +call moved its field away; or two claims hold, and the table carries a more +specific claim for the one the code meant. Anything else is fatal. + +`top.h` and `top.csv` disagree with the code in three places, and +`ANNOTATION_ERRATA` in the generator says which side wins and why: the csv's +`P_GPIO29` for SIF CH2_2 (no such pad, the code uses `P_GPIO19`), `top.h`'s +`P_GPIO14` for PICNT2_1 (the code and the csv use `L_GPIO1`), and +`PIN_MISC_CFG_SP2CLK_3RD`, which does nothing at all, because +`pinmux_config_misc()` tests `PIN_SENSOR_CFG_SP2CLK_3RD` in its place. + Both generators take `--verify

`, which re-derives and diffs instead of writing. That needs the SDK, so CI cannot run it; `tools/gen_sstar_padmux.py --selftest` runs the vendor-source parsing against @@ -389,11 +472,23 @@ in. - **Other Ingenic parts.** T21, T23, T31 and T40 have tables. T10, T20, T30 and T41 do not, and would each need a source of one of the three kinds above -- which, for the parts checked so far, does not exist in the vendor releases. +- **Other Novatek parts, and NA51089's display.** NA51055, NA51084, NA51090 + and NA51103 have no table: their chip IDs are recognised and get none. + LCD, TV and HDMI on NA51089 are muxed by `pinmux_select_primary_lcd()` + from state the config functions only stash, and are not modelled; a pad + given to the display reads as cleared with nothing claiming it. +- **Novatek states two options create at once.** In 19,185 of the replayed + calls some pad is claimed twice -- a 12-bit sensor's pixel clock and MCLK2 + both on `S_GPIO1`, say. The vendor code checks for neither and no board + does it. The table answers by the vendor's last write, which is the best + evidence there is and not a measurement. - **Hardware.** Every claim here is verified against vendor source and on a host. On top of that, HiSilicon, SigmaStar infinity6/6b0/6c, and Ingenic T21, T23, T31 and SigmaStar infinity6e have been run on real cameras and checked against an independent decode of their live registers. Ingenic T40 - has not: nobody has had one. + and Novatek NA51089 have not: nobody here has had one. On a NA51089, + `/proc/nvt_info/nvt_pinmux/pinmux_summary` is the kernel's own decode of the + same registers and is the thing to compare `reginfo --pads` against. ## Adding a family diff --git a/src/hal/novatek.c b/src/hal/novatek.c index 6ca130bc..840ebf2d 100644 --- a/src/hal/novatek.c +++ b/src/hal/novatek.c @@ -32,6 +32,11 @@ static bool nvt_get_chip_id() { sizeof(buf))) { reg = (uint16_t)strtol(buf, &endptr, 16); + /* The TOP block's chip-ID word, which is what tells the pad-mux + * table and the GPIO controller which SoC this is. Set for every ID + * the kernel hands over, named or not: a part with no table gets no + * table, which padmux_ops() says rather than guessing one. */ + chip_generation = reg; switch (reg) { case 0x5021: strcpy(chip_name, "NT98562"); diff --git a/src/hal/novatek_gpio.c b/src/hal/novatek_gpio.c new file mode 100644 index 00000000..97faba37 --- /dev/null +++ b/src/hal/novatek_gpio.c @@ -0,0 +1,78 @@ +/* The NA51089 GPIO controller, as the vendor's gpio-nvt-na51089.c drives it. + * + * Four banks of eight words at 0xF0070000: DATA, DIR, SET and CLR, one word + * per pad group, so a pad's bit is its Linux GPIO number modulo 32 in word + * number / 32. SET and CLR are write-one aliases, which is how the kernel + * changes a level without a read-modify-write of the other pads; only DIR is + * read-modified-written, under the kernel's spinlock there and under the + * single-threaded contract of mem_reg() here. + * + * The per-group counts are nvt-gpio.h's *_GPIO_NUM: what the package bonds + * out, and so what the gpiochip accepts. */ + +#include "hal/novatek_gpio.h" + +#include "chipid.h" +#include "hal/novatek.h" +#include "tools.h" + +static const uint8_t group_pads[8] = { + 23, /* C_GPIO, the "MC" pads */ + 26, /* P_GPIO */ + 9, /* S_GPIO */ + 10, /* L_GPIO */ + 8, /* D_GPIO */ + 12, /* H_GPIO, the HSI pads */ + 3, /* A_GPIO */ + 11, /* DSI_GPIO */ +}; + +bool novatek_gpio_supported(void) { return chip_generation == CHIP_NA51089; } + +bool novatek_gpio_valid(int pad) { + if (!novatek_gpio_supported() || pad < 0 || pad >= NVT_GPIO_NPADS) + return false; + return (pad & 31) < group_pads[pad >> 5]; +} + +uint32_t novatek_gpio_reg(int pad, unsigned bank) { + if (!novatek_gpio_valid(pad) || bank > NVT_GPIO_CLR || bank % 0x20) + return 0; + return NVT_GPIO_BASE + bank + (uint32_t)(pad >> 5) * 4; +} + +bool novatek_gpio_window(uint32_t *base, uint32_t *len) { + if (!novatek_gpio_supported()) + return false; + *base = NVT_GPIO_BASE; + *len = NVT_GPIO_CLR + 0x20; + return true; +} + +bool novatek_gpio_read(int pad, bool *output, bool *level) { + uint32_t dir, data; + if (!novatek_gpio_valid(pad) || + !mem_reg(novatek_gpio_reg(pad, NVT_GPIO_DIR), &dir, OP_READ) || + !mem_reg(novatek_gpio_reg(pad, NVT_GPIO_DATA), &data, OP_READ)) + return false; + + uint32_t bit = 1u << (pad & 31); + *output = (dir & bit) != 0; + *level = (data & bit) != 0; + return true; +} + +bool novatek_gpio_write(int pad, bool level) { + uint32_t dir; + uint32_t bit = 1u << (pad & 31); + if (!novatek_gpio_valid(pad) || + !mem_reg(novatek_gpio_reg(pad, NVT_GPIO_DIR), &dir, OP_READ)) + return false; + if (!(dir & bit)) { + dir |= bit; + if (!mem_reg(novatek_gpio_reg(pad, NVT_GPIO_DIR), &dir, OP_WRITE)) + return false; + } + return mem_reg(novatek_gpio_reg(pad, level ? NVT_GPIO_SET : NVT_GPIO_CLR), + &bit, OP_WRITE); +} diff --git a/src/hal/novatek_gpio.h b/src/hal/novatek_gpio.h new file mode 100644 index 00000000..6c8aeeee --- /dev/null +++ b/src/hal/novatek_gpio.h @@ -0,0 +1,36 @@ +#ifndef HAL_NOVATEK_GPIO_H +#define HAL_NOVATEK_GPIO_H + +#include +#include + +/* The NA51089 GPIO controller. Pads are numbered as the kernel numbers them: + * C_GPIO(n) is n, P_GPIO(n) 0x20 + n, and so on in steps of 0x20 through S, + * L, D, H, A and DSI. Every group is one 32-bit word in each bank. */ +#define NVT_GPIO_BASE 0xF0070000u +#define NVT_GPIO_DATA 0x00 /* the pin's level */ +#define NVT_GPIO_DIR 0x20 /* 1: output */ +#define NVT_GPIO_SET 0x40 /* write 1 to drive high */ +#define NVT_GPIO_CLR 0x60 /* write 1 to drive low */ +#define NVT_GPIO_NPADS 0x100 + +bool novatek_gpio_supported(void); + +/* Whether the kernel's gpiochip answers to `pad`: the package bonds it out. + * The holes between groups are not pads. */ +bool novatek_gpio_valid(int pad); + +/* The register of `pad` in one bank, 0 when there is none. */ +uint32_t novatek_gpio_reg(int pad, unsigned bank); + +/* The window a daemon has to have mapped to be holding the pads. */ +bool novatek_gpio_window(uint32_t *base, uint32_t *len); + +/* One pad through /dev/mem. Writing makes the pad an output first, as the + * kernel's direction_output does, then drives it through SET or CLR so the + * other 31 pads of the word are never written. Serialise the callers: + * mem_reg() is single-threaded by contract. */ +bool novatek_gpio_read(int pad, bool *output, bool *level); +bool novatek_gpio_write(int pad, bool level); + +#endif /* HAL_NOVATEK_GPIO_H */ diff --git a/src/hal/novatek_padmux.c b/src/hal/novatek_padmux.c new file mode 100644 index 00000000..da69a7a4 --- /dev/null +++ b/src/hal/novatek_padmux.c @@ -0,0 +1,452 @@ +/* Novatek NA51089 (NT98562/NT98566): the pad-mux backend. + * + * Two things decide what a pad carries, and they are in different places: + * + * - a location field per PERIPHERAL in the TOP block. REG5[7:6] is I2C3, + * and 1, 2 and 3 put it on P_GPIO21/22, C_GPIO11/12 or DSI_GPIO8/9. It + * is SigmaStar's arrangement: the field belongs to the peripheral, and + * names a group of pads. + * - a gate bit per PAD, in one of eight bitmaps at TOP + 0xA0..0xE8, the + * pad's group's word at its pin's position. 1 keeps the pad a GPIO; 0 + * hands it to whichever peripheral's field names it. + * + * The vendor's pinmux_config_*() functions set both, every time. So a pad is + * GPIO when its gate is set, and otherwise it is whatever the TOP fields say + * -- which the generated table states as claims: a name, and the field + * values under which the pad carries it. The first claim that holds wins; + * the table is sorted most specific first, and the generator replayed every + * state the vendor code can produce to make that rule agree with it. + * + * Two exceptions the claims carry. The parallel and CCIR sensor modes put + * pixel data on the HSI pads and leave their gate bits at GPIO, so those + * claims hold through the gate (NVT_UNGATED). And a gate cleared with no + * claim holding is a pad whose peripheral moved elsewhere afterwards: get() + * says it cannot name it, which is the truth. + * + * Putting a function on a pad is therefore never one write: the claim's + * fields, then the gate. None of these rows carries IPCHW_PADMUX_F_RMW + * except the GPIO row of a pad nothing ungated can claim, where setting the + * gate bit is the whole of it. + * + * Registers are in the TOP block at 0xF0010000, which is the DT's + * "nvt,nvt_top" reg[0]; the table is generated from the vendor's own driver + * by tools/gen_novatek_padmux.py. */ + +#include +#include +#include +#include + +#include "chipid.h" +#include "hal/novatek.h" +#include "hal/novatek_padmux.h" +#include "padmux.h" + +#define TOP_BASE 0xF0010000u + +/* A pad's gate register is its group's: the Linux GPIO number's upper three + * bits pick the group (C, P, S, L, D, H, A, DSI) and the lower five are the + * bit. */ +static const uint8_t gate_regs[8] = {0xA0, 0xA8, 0xB0, 0xB8, + 0xD0, 0xD8, 0xE0, 0xE8}; + +/* What one call needs to know about the TOP block, read once each. */ +#define TOP_WORDS (0x100 / 4) + +typedef struct { + const padmux_io_t *io; + uint32_t val[TOP_WORDS]; + uint8_t have[TOP_WORDS]; +} top_t; + +static const novatek_soc_t *nvt_soc(void) { + switch (chip_generation) { + case CHIP_NA51089: + return &NA51089_padmux; + default: + return NULL; + } +} + +static const novatek_pad_t *find_pad(const novatek_soc_t *soc, int pad) { + for (int i = 0; i < soc->npads; i++) + if (soc->pads[i].pad == pad) + return &soc->pads[i]; + + return NULL; +} + +static uint32_t gate_addr(int pad) { return TOP_BASE + gate_regs[pad >> 5]; } + +static uint32_t gate_bit(int pad) { return 1u << (pad & 31); } + +static uint32_t field_mask(unsigned shift, unsigned width) { + return ((1u << width) - 1) << shift; +} + +static bool top_read(top_t *t, unsigned reg, uint32_t *val) { + unsigned w = reg / 4; + if (!t->have[w]) { + if (!t->io->read(TOP_BASE + reg, &t->val[w], 32)) + return false; + t->have[w] = 1; + } + *val = t->val[w]; + return true; +} + +static bool top_write_field(top_t *t, unsigned reg, uint32_t mask, + uint32_t bits) { + uint32_t val; + if (!top_read(t, reg, &val)) + return false; + val = (val & ~mask) | (bits & mask); + if (!t->io->write(TOP_BASE + reg, val, 32)) + return false; + t->val[reg / 4] = val; + return true; +} + +/* 1 when every condition of `c` holds, 0 when one does not, or + * IPCHW_PADMUX_IO. */ +static int claim_holds(const novatek_soc_t *soc, const novatek_claim_t *c, + top_t *t) { + for (int i = 0; i < c->ncond; i++) { + const novatek_cond_t *k = &soc->conds[c->cond + i]; + uint32_t val; + if (!top_read(t, k->reg, &val)) + return IPCHW_PADMUX_IO; + if (((val >> k->shift) & ((1u << k->width) - 1)) != k->value) + return 0; + } + return 1; +} + +/* The claims of `pad`, which the table keeps together. */ +static const novatek_claim_t *pad_claims(const novatek_soc_t *soc, int pad, + int *n) { + *n = 0; + for (int i = 0; i < soc->nclaims; i++) { + if (soc->claims[i].pad != pad) + continue; + int j = i; + while (j < soc->nclaims && soc->claims[j].pad == pad) + j++; + *n = j - i; + return &soc->claims[i]; + } + return NULL; +} + +/* What the pad carries now: the claim that wins, or NULL with *gpio set for + * plain GPIO and clear for a gate cleared with nothing claiming the pad. + * Negative is IPCHW_PADMUX_IO. */ +static int resolve(const novatek_soc_t *soc, int pad, top_t *t, + const novatek_claim_t **win, bool *gpio) { + uint32_t gate; + if (!top_read(t, gate_regs[pad >> 5], &gate)) + return IPCHW_PADMUX_IO; + bool gated = (gate & gate_bit(pad)) != 0; + + *win = NULL; + *gpio = gated; + + int n; + const novatek_claim_t *c = pad_claims(soc, pad, &n); + for (int i = 0; i < n; i++) { + if (gated && !(c[i].flags & NVT_UNGATED)) + continue; + int res = claim_holds(soc, &c[i], t); + if (res < 0) + return res; + if (res) { + *win = &c[i]; + *gpio = false; + return 0; + } + } + return 0; +} + +static bool has_ungated(const novatek_soc_t *soc, int pad) { + int n; + const novatek_claim_t *c = pad_claims(soc, pad, &n); + for (int i = 0; i < n; i++) + if (c[i].flags & NVT_UNGATED) + return true; + return false; +} + +static ipchw_padmux_t gpio_row(const novatek_soc_t *soc, + const novatek_pad_t *pd) { + uint32_t bit = gate_bit(pd->pad); + + return (ipchw_padmux_t){ + .address = gate_addr(pd->pad), + .func_mask = bit, + .func = (int)bit, + .func_name = IPCHW_PADMUX_GPIO, + .gpio_name = padmux_name(pd->name), + .gpio_pad = pd->pad, + .gpio_func = (int)bit, + /* Setting the gate is the whole operation -- unless a sensor mode + * can hold the pad through it, and then it is not. */ + .flags = IPCHW_PADMUX_F_GPIO | + (has_ungated(soc, pd->pad) ? 0 : IPCHW_PADMUX_F_RMW), + }; +} + +static ipchw_padmux_t func_row(const novatek_pad_t *pd, + const novatek_sel_t *s) { + ipchw_padmux_t row = { + .func_name = padmux_name(s->name), + .gpio_name = padmux_name(pd->name), + .gpio_pad = pd->pad, + .gpio_func = -1, + .flags = 0, + }; + + if (s->reg == NVT_GATE) { + /* Told apart from the pad's other names by nothing but the gate + * being clear -- the MIPI lanes, which no field selects. */ + row.address = gate_addr(pd->pad); + row.func_mask = gate_bit(pd->pad); + row.func = 0; + } else { + row.address = TOP_BASE + s->reg; + row.func_mask = field_mask(s->shift, s->width); + row.func = (int)((uint32_t)s->value << s->shift); + } + return row; +} + +static const novatek_sel_t *find_sel(const novatek_soc_t *soc, int pad, + uint16_t name) { + for (int i = 0; i < soc->nsels; i++) + if (soc->sels[i].pad == pad && soc->sels[i].name == name) + return &soc->sels[i]; + + return NULL; +} + +static int nvt_walk(padmux_match_fn match, const void *arg, int pad, + ipchw_padmux_t *out, int max) { + const novatek_soc_t *soc = nvt_soc(); + if (soc == NULL) + return IPCHW_PADMUX_NO_TABLE; + + int found = 0; + for (int i = 0; i < soc->npads; i++) { + const novatek_pad_t *pd = &soc->pads[i]; + if (pad >= 0 && pd->pad != pad) + continue; + + if (match == NULL || match(IPCHW_PADMUX_GPIO, arg)) { + if (found < max) + out[found] = gpio_row(soc, pd); + found++; + } + + for (int s = 0; s < soc->nsels; s++) { + const novatek_sel_t *sel = &soc->sels[s]; + if (sel->pad != pd->pad) + continue; + if (match != NULL && !match(padmux_name(sel->name), arg)) + continue; + + if (found < max) + out[found] = func_row(pd, sel); + found++; + } + } + + return found; +} + +static int nvt_get(int pad, ipchw_padmux_t *out, const padmux_io_t *io) { + const novatek_soc_t *soc = nvt_soc(); + if (soc == NULL) + return IPCHW_PADMUX_NO_TABLE; + + const novatek_pad_t *pd = find_pad(soc, pad); + if (pd == NULL) + return IPCHW_PADMUX_NO_PAD; + + top_t t = {.io = io}; + const novatek_claim_t *win; + bool gpio; + int res = resolve(soc, pad, &t, &win, &gpio); + if (res < 0) + return res; + + if (win != NULL) { + const novatek_sel_t *s = find_sel(soc, pad, win->name); + if (s == NULL) + return 0; + *out = func_row(pd, s); + return 1; + } + if (gpio) { + *out = gpio_row(soc, pd); + return 1; + } + return 0; /* handed over, and nothing claims it */ +} + +/* Whether `k` is one of `keep`'s conditions: a field the function being put + * on the pad needs, and so one no competitor may be dropped through. */ +static bool pinned(const novatek_soc_t *soc, const novatek_claim_t *keep, + const novatek_cond_t *k) { + if (keep == NULL) + return false; + for (int i = 0; i < keep->ncond; i++) { + const novatek_cond_t *p = &soc->conds[keep->cond + i]; + if (p->reg == k->reg && p->shift == k->shift && p->width == k->width) + return true; + } + return false; +} + +/* Get `pad` to read as `target` (NULL: plain GPIO) once the target's own + * writes are done. Whatever still wins instead is a claim of something + * else, and it is dropped by clearing one of its fields that the target does + * not need -- SigmaStar drops a competing mode the same way. Bounded, + * because each pass clears a field for good. */ +static int drop_competitors(const novatek_soc_t *soc, int pad, top_t *t, + const novatek_claim_t *target) { + for (int pass = 0; pass < 8; pass++) { + const novatek_claim_t *win; + bool gpio; + int res = resolve(soc, pad, t, &win, &gpio); + if (res < 0) + return res; + if (target == NULL ? gpio : (win && win->name == target->name)) + return 0; + if (win == NULL) + return IPCHW_PADMUX_NO_FUNC; /* only the gate could; it can't */ + + const novatek_cond_t *drop = NULL; + for (int i = 0; i < win->ncond && drop == NULL; i++) { + const novatek_cond_t *k = &soc->conds[win->cond + i]; + if (k->value != 0 && !pinned(soc, target, k)) + drop = k; + } + if (drop == NULL) + return IPCHW_PADMUX_NO_FUNC; + if (!top_write_field(t, drop->reg, field_mask(drop->shift, drop->width), + 0)) + return IPCHW_PADMUX_IO; + } + return IPCHW_PADMUX_NO_FUNC; +} + +/* How many of `c`'s conditions do not hold now; negative on I/O error. */ +static int unmet(const novatek_soc_t *soc, const novatek_claim_t *c, top_t *t) { + int n = 0; + for (int i = 0; i < c->ncond; i++) { + const novatek_cond_t *k = &soc->conds[c->cond + i]; + uint32_t val; + if (!top_read(t, k->reg, &val)) + return IPCHW_PADMUX_IO; + if (((val >> k->shift) & ((1u << k->width) - 1)) != k->value) + n++; + } + return n; +} + +static int nvt_set(int pad, const char *func_name, const padmux_io_t *io) { + const novatek_soc_t *soc = nvt_soc(); + if (soc == NULL) + return IPCHW_PADMUX_NO_TABLE; + + const novatek_pad_t *pd = find_pad(soc, pad); + if (pd == NULL) + return IPCHW_PADMUX_NO_PAD; + + top_t t = {.io = io}; + unsigned gr = gate_regs[pad >> 5]; + + if (!strcmp(func_name, IPCHW_PADMUX_GPIO) || + !strcmp(func_name, padmux_name(pd->name))) { + if (!top_write_field(&t, gr, gate_bit(pad), gate_bit(pad))) + return IPCHW_PADMUX_IO; + return drop_competitors(soc, pad, &t, NULL); + } + + /* Of the claims that spell this name, the one that changes least: on a + * MIPI board SENSOR_MCLK is the claim made under the CSI sensor mode, and + * the one made under the parallel mode would switch the sensor off. */ + int n; + const novatek_claim_t *c = pad_claims(soc, pad, &n); + const novatek_claim_t *best = NULL; + int best_unmet = 0; + for (int i = 0; i < n; i++) { + if (strcmp(padmux_name(c[i].name), func_name) != 0) + continue; + int u = unmet(soc, &c[i], &t); + if (u < 0) + return u; + if (best == NULL || u < best_unmet || + (u == best_unmet && c[i].ncond < best->ncond)) { + best = &c[i]; + best_unmet = u; + } + } + if (best == NULL) + return IPCHW_PADMUX_NO_FUNC; + + for (int i = 0; i < best->ncond; i++) { + const novatek_cond_t *k = &soc->conds[best->cond + i]; + if (!top_write_field(&t, k->reg, field_mask(k->shift, k->width), + (uint32_t)k->value << k->shift)) + return IPCHW_PADMUX_IO; + } + if (!(best->flags & NVT_UNGATED) && + !top_write_field(&t, gr, gate_bit(pad), 0)) + return IPCHW_PADMUX_IO; + + return drop_competitors(soc, pad, &t, best); +} + +/* "P_GPIO22", "C_GPIO17" or the vendor's other spellings of it, "MC17" and + * "HSI_GPIO9", or the Linux GPIO number. Not "5_2": that is HiSilicon's + * bank-of-eight numbering and would land on a different pad here. */ +static int nvt_parse_pad(const char *spec) { + static const struct { + const char *prefix; + int base; + } groups[] = { + {"C_GPIO", 0x00}, {"MC", 0x00}, {"P_GPIO", 0x20}, + {"S_GPIO", 0x40}, {"L_GPIO", 0x60}, {"D_GPIO", 0x80}, + {"H_GPIO", 0xA0}, {"HSI_GPIO", 0xA0}, {"A_GPIO", 0xC0}, + {"DSI_GPIO", 0xE0}, + }; + + for (size_t i = 0; i < sizeof(groups) / sizeof(*groups); i++) { + size_t len = strlen(groups[i].prefix); + if (strncasecmp(spec, groups[i].prefix, len) != 0) + continue; + char *tail; + long n = strtol(spec + len, &tail, 10); + if (tail == spec + len || *tail || n < 0 || n > 31) + return -1; + return groups[i].base + (int)n; + } + + if (strchr(spec, '_')) + return -1; + + char *tail; + long n = strtol(spec, &tail, 10); + if (tail == spec || *tail || n < 0 || n > 0xff) + return -1; + return (int)n; +} + +const padmux_ops_t PADMUX_OPS_NOVATEK = { + .name = "novatek", + .walk = nvt_walk, + .get = nvt_get, + .set = nvt_set, + .parse_pad = nvt_parse_pad, +}; diff --git a/src/hal/novatek_padmux.h b/src/hal/novatek_padmux.h new file mode 100644 index 00000000..ad20949e --- /dev/null +++ b/src/hal/novatek_padmux.h @@ -0,0 +1,1117 @@ +/* Generated by tools/gen_novatek_padmux.py -- do not edit. + * + * What the vendor's pinmux_config_*() functions do to each pad of the + * NA51089, found by running them: see the generator for how, and + * src/hal/novatek_padmux.c for how the table is read. 96550 vendor states + * were replayed against it; in 19185 of them two claims hold at once and the + * table carries the one the vendor code meant, and 478 leave a pad cleared + * with its field moved elsewhere, which reads as unnamed. + * + * Regenerate with: + * tools/gen_novatek_padmux.py --sdk + */ + +#ifndef HAL_NOVATEK_PADMUX_H +#define HAL_NOVATEK_PADMUX_H + +#include "hal/novatek_padmux_types.h" + +/* Every pad the package bonds out, by Linux GPIO number. */ +static const novatek_pad_t NA51089_pads[] = { + {0, PMX_C_GPIO0}, + {1, PMX_C_GPIO1}, + {2, PMX_C_GPIO2}, + {3, PMX_C_GPIO3}, + {4, PMX_C_GPIO4}, + {5, PMX_C_GPIO5}, + {6, PMX_C_GPIO6}, + {7, PMX_C_GPIO7}, + {8, PMX_C_GPIO8}, + {9, PMX_C_GPIO9}, + {10, PMX_C_GPIO10}, + {11, PMX_C_GPIO11}, + {12, PMX_C_GPIO12}, + {13, PMX_C_GPIO13}, + {14, PMX_C_GPIO14}, + {15, PMX_C_GPIO15}, + {16, PMX_C_GPIO16}, + {17, PMX_C_GPIO17}, + {18, PMX_C_GPIO18}, + {19, PMX_C_GPIO19}, + {20, PMX_C_GPIO20}, + {21, PMX_C_GPIO21}, + {22, PMX_C_GPIO22}, + {32, PMX_P_GPIO0}, + {33, PMX_P_GPIO1}, + {34, PMX_P_GPIO2}, + {35, PMX_P_GPIO3}, + {36, PMX_P_GPIO4}, + {37, PMX_P_GPIO5}, + {38, PMX_P_GPIO6}, + {39, PMX_P_GPIO7}, + {40, PMX_P_GPIO8}, + {41, PMX_P_GPIO9}, + {42, PMX_P_GPIO10}, + {43, PMX_P_GPIO11}, + {44, PMX_P_GPIO12}, + {45, PMX_P_GPIO13}, + {46, PMX_P_GPIO14}, + {47, PMX_P_GPIO15}, + {48, PMX_P_GPIO16}, + {49, PMX_P_GPIO17}, + {50, PMX_P_GPIO18}, + {51, PMX_P_GPIO19}, + {52, PMX_P_GPIO20}, + {53, PMX_P_GPIO21}, + {54, PMX_P_GPIO22}, + {55, PMX_P_GPIO23}, + {56, PMX_P_GPIO24}, + {57, PMX_P_GPIO25}, + {64, PMX_S_GPIO0}, + {65, PMX_S_GPIO1}, + {66, PMX_S_GPIO2}, + {67, PMX_S_GPIO3}, + {68, PMX_S_GPIO4}, + {69, PMX_S_GPIO5}, + {70, PMX_S_GPIO6}, + {71, PMX_S_GPIO7}, + {72, PMX_S_GPIO8}, + {96, PMX_L_GPIO0}, + {97, PMX_L_GPIO1}, + {98, PMX_L_GPIO2}, + {99, PMX_L_GPIO3}, + {100, PMX_L_GPIO4}, + {101, PMX_L_GPIO5}, + {102, PMX_L_GPIO6}, + {103, PMX_L_GPIO7}, + {104, PMX_L_GPIO8}, + {105, PMX_L_GPIO9}, + {128, PMX_D_GPIO0}, + {129, PMX_D_GPIO1}, + {130, PMX_D_GPIO2}, + {131, PMX_D_GPIO3}, + {132, PMX_D_GPIO4}, + {133, PMX_D_GPIO5}, + {134, PMX_D_GPIO6}, + {135, PMX_D_GPIO7}, + {160, PMX_H_GPIO0}, + {161, PMX_H_GPIO1}, + {162, PMX_H_GPIO2}, + {163, PMX_H_GPIO3}, + {164, PMX_H_GPIO4}, + {165, PMX_H_GPIO5}, + {166, PMX_H_GPIO6}, + {167, PMX_H_GPIO7}, + {168, PMX_H_GPIO8}, + {169, PMX_H_GPIO9}, + {170, PMX_H_GPIO10}, + {171, PMX_H_GPIO11}, + {192, PMX_A_GPIO0}, + {193, PMX_A_GPIO1}, + {194, PMX_A_GPIO2}, + {224, PMX_DSI_GPIO0}, + {225, PMX_DSI_GPIO1}, + {226, PMX_DSI_GPIO2}, + {227, PMX_DSI_GPIO3}, + {228, PMX_DSI_GPIO4}, + {229, PMX_DSI_GPIO5}, + {230, PMX_DSI_GPIO6}, + {231, PMX_DSI_GPIO7}, + {232, PMX_DSI_GPIO8}, + {233, PMX_DSI_GPIO9}, + {234, PMX_DSI_GPIO10}, +}; + +/* TOP register offset, field shift, width, value. */ +static const novatek_cond_t NA51089_conds[] = { + {0x04, 17, 1, 1}, + {0x04, 17, 1, 1}, + {0x04, 31, 1, 1}, + {0x1C, 0, 3, 4}, + {0x1C, 3, 3, 4}, + {0x1C, 6, 3, 4}, + {0x1C, 9, 3, 4}, + {0x18, 10, 2, 2}, + {0x18, 5, 1, 1}, + {0x18, 6, 1, 1}, + {0x18, 30, 2, 3}, + {0x14, 6, 2, 2}, + {0x18, 2, 2, 2}, + {0x1C, 12, 3, 2}, + {0x04, 14, 1, 1}, + {0x14, 12, 2, 2}, + {0x18, 0, 2, 2}, + {0x1C, 15, 3, 2}, + {0x24, 2, 2, 2}, + {0x24, 8, 2, 1}, + {0x1C, 0, 3, 2}, + {0x14, 12, 2, 2}, + {0x14, 18, 1, 1}, + {0x24, 2, 2, 2}, + {0x24, 8, 2, 2}, + {0x1C, 3, 3, 2}, + {0x18, 7, 2, 2}, + {0x18, 7, 2, 2}, + {0x1C, 24, 2, 2}, + {0x14, 12, 2, 2}, + {0x14, 14, 2, 2}, + {0x1C, 6, 3, 2}, + {0x24, 2, 2, 2}, + {0x1C, 9, 3, 2}, + {0x14, 4, 2, 2}, + {0x1C, 18, 3, 2}, + {0x04, 18, 2, 1}, + {0x14, 8, 2, 1}, + {0x1C, 21, 3, 2}, + {0x24, 4, 3, 2}, + {0x24, 10, 2, 1}, + {0x18, 16, 3, 2}, + {0x14, 8, 2, 1}, + {0x14, 16, 1, 1}, + {0x24, 4, 3, 2}, + {0x24, 10, 2, 2}, + {0x18, 19, 3, 2}, + {0x18, 22, 3, 2}, + {0x24, 4, 3, 2}, + {0x18, 25, 3, 2}, + {0x14, 30, 2, 2}, + {0x1C, 0, 3, 1}, + {0x0C, 4, 2, 1}, + {0x0C, 4, 2, 2}, + {0x0C, 0, 3, 2}, + {0x0C, 0, 3, 4}, + {0x14, 10, 2, 2}, + {0x24, 2, 2, 3}, + {0x1C, 3, 3, 1}, + {0x24, 2, 2, 3}, + {0x24, 8, 2, 1}, + {0x24, 2, 2, 3}, + {0x24, 8, 2, 2}, + {0x1C, 6, 3, 1}, + {0x14, 10, 2, 2}, + {0x14, 17, 1, 1}, + {0x1C, 9, 3, 1}, + {0x1C, 12, 3, 1}, + {0x14, 12, 2, 3}, + {0x24, 4, 3, 3}, + {0x1C, 15, 3, 1}, + {0x24, 4, 3, 3}, + {0x24, 10, 2, 1}, + {0x24, 4, 3, 3}, + {0x24, 10, 2, 2}, + {0x1C, 18, 3, 1}, + {0x14, 30, 2, 2}, + {0x18, 28, 1, 1}, + {0x14, 12, 2, 3}, + {0x14, 18, 1, 1}, + {0x1C, 21, 3, 1}, + {0x14, 26, 1, 1}, + {0x14, 12, 2, 3}, + {0x14, 14, 2, 3}, + {0x18, 2, 2, 1}, + {0x18, 16, 3, 1}, + {0x14, 2, 2, 2}, + {0x14, 30, 2, 2}, + {0x14, 2, 2, 2}, + {0x18, 0, 2, 1}, + {0x18, 19, 3, 1}, + {0x18, 22, 3, 1}, + {0x14, 24, 2, 1}, + {0x18, 25, 3, 1}, + {0x0C, 4, 2, 1}, + {0x0C, 16, 1, 1}, + {0x14, 12, 2, 1}, + {0x14, 14, 2, 1}, + {0x1C, 26, 2, 1}, + {0x0C, 16, 1, 1}, + {0x18, 5, 1, 1}, + {0x18, 6, 1, 1}, + {0x18, 30, 2, 1}, + {0x1C, 30, 2, 1}, + {0x18, 7, 2, 1}, + {0x14, 24, 2, 2}, + {0x14, 12, 2, 1}, + {0x24, 2, 2, 1}, + {0x18, 7, 2, 1}, + {0x1C, 24, 2, 1}, + {0x1C, 26, 2, 2}, + {0x24, 2, 2, 1}, + {0x24, 8, 2, 1}, + {0x24, 2, 2, 1}, + {0x24, 8, 2, 2}, + {0x1C, 28, 2, 2}, + {0x18, 9, 1, 1}, + {0x14, 12, 2, 1}, + {0x14, 18, 1, 1}, + {0x1C, 30, 2, 2}, + {0x0C, 18, 2, 1}, + {0x14, 6, 2, 1}, + {0x18, 10, 2, 1}, + {0x24, 0, 1, 1}, + {0x04, 18, 2, 2}, + {0x0C, 8, 2, 1}, + {0x24, 4, 3, 4}, + {0x0C, 0, 3, 4}, + {0x0C, 6, 2, 0}, + {0x0C, 12, 2, 1}, + {0x0C, 0, 3, 4}, + {0x0C, 6, 2, 0}, + {0x0C, 0, 3, 1}, + {0x0C, 12, 2, 1}, + {0x0C, 0, 3, 3}, + {0x0C, 12, 2, 1}, + {0x1C, 0, 3, 3}, + {0x0C, 0, 3, 1}, + {0x0C, 0, 3, 3}, + {0x0C, 12, 2, 1}, + {0x1C, 3, 3, 3}, + {0x0C, 10, 2, 1}, + {0x1C, 6, 3, 3}, + {0x14, 22, 1, 1}, + {0x14, 4, 2, 1}, + {0x1C, 9, 3, 3}, + {0x0C, 14, 2, 1}, + {0x24, 4, 3, 5}, + {0x14, 8, 2, 2}, + {0x14, 16, 1, 1}, + {0x1C, 12, 3, 3}, + {0x1C, 15, 3, 3}, + {0x14, 20, 1, 1}, + {0x14, 8, 2, 2}, + {0x14, 0, 2, 1}, + {0x1C, 18, 3, 3}, + {0x1C, 21, 3, 3}, + {0x0C, 12, 2, 2}, + {0x18, 25, 3, 5}, + {0x1C, 28, 2, 1}, + {0x0C, 18, 2, 2}, + {0x18, 13, 2, 1}, + {0x1C, 12, 3, 4}, + {0x14, 24, 2, 3}, + {0x0C, 18, 2, 3}, + {0x1C, 15, 3, 4}, + {0x18, 10, 2, 3}, + {0x18, 13, 2, 2}, + {0x1C, 18, 3, 4}, + {0x1C, 21, 3, 4}, + {0x18, 25, 3, 4}, + {0x0C, 0, 3, 4}, + {0x0C, 6, 2, 1}, + {0x18, 16, 3, 3}, + {0x18, 19, 3, 3}, + {0x0C, 10, 2, 2}, + {0x18, 22, 3, 3}, + {0x14, 0, 2, 2}, + {0x18, 25, 3, 3}, + {0x0C, 0, 3, 4}, + {0x0C, 6, 2, 1}, + {0x0C, 8, 2, 2}, + {0x0C, 0, 3, 1}, + {0x0C, 8, 2, 2}, + {0x0C, 0, 3, 3}, + {0x0C, 8, 2, 2}, + {0x0C, 8, 2, 2}, + {0x14, 2, 2, 1}, + {0x1C, 0, 3, 5}, + {0x24, 4, 3, 1}, + {0x1C, 3, 3, 5}, + {0x24, 4, 3, 1}, + {0x24, 10, 2, 1}, + {0x24, 4, 3, 1}, + {0x24, 10, 2, 2}, + {0x14, 30, 2, 1}, + {0x1C, 6, 3, 5}, + {0x04, 18, 2, 3}, + {0x1C, 9, 3, 5}, + {0x1C, 12, 3, 5}, + {0x14, 10, 2, 1}, + {0x1C, 15, 3, 5}, + {0x1C, 18, 3, 5}, + {0x14, 10, 2, 1}, + {0x14, 17, 1, 1}, + {0x1C, 21, 3, 5}, + {0x18, 5, 1, 1}, + {0x18, 6, 1, 1}, + {0x18, 30, 2, 2}, + {0x14, 6, 2, 3}, + {0x18, 16, 3, 5}, + {0x14, 2, 2, 1}, + {0x14, 30, 2, 1}, + {0x18, 19, 3, 5}, + {0x18, 28, 1, 1}, + {0x18, 22, 3, 5}, +}; + +/* Per pad, most conditions first: the first claim that holds + * is what the pad carries. {pad, flags, name, first + * condition, how many}. */ +static const novatek_claim_t NA51089_claims[] = { + {0, 0, PMX_SDIO3_D0, 0, 1}, /* C_GPIO0 */ + {0, 0, PMX_FSPI_DO, 1, 0}, /* C_GPIO0 */ + {1, 0, PMX_SDIO3_D1, 0, 1}, /* C_GPIO1 */ + {1, 0, PMX_FSPI_DI, 1, 0}, /* C_GPIO1 */ + {2, 0, PMX_SDIO3_D2, 0, 1}, /* C_GPIO2 */ + {2, 0, PMX_FSPI_WP, 1, 0}, /* C_GPIO2 */ + {3, 0, PMX_SDIO3_D3, 0, 1}, /* C_GPIO3 */ + {3, 0, PMX_FSPI_HOLD, 1, 0}, /* C_GPIO3 */ + {4, 0, PMX_SDIO3_D4, 1, 2}, /* C_GPIO4 */ + {4, 0, PMX_PWM0_4, 3, 1}, /* C_GPIO4 */ + {5, 0, PMX_SDIO3_D5, 1, 2}, /* C_GPIO5 */ + {5, 0, PMX_PWM1_4, 4, 1}, /* C_GPIO5 */ + {6, 0, PMX_SDIO3_D6, 1, 2}, /* C_GPIO6 */ + {6, 0, PMX_PWM2_4, 5, 1}, /* C_GPIO6 */ + {7, 0, PMX_SDIO3_D7, 1, 2}, /* C_GPIO7 */ + {7, 0, PMX_PWM3_4, 6, 1}, /* C_GPIO7 */ + {8, 0, PMX_SDIO3_CLK, 0, 1}, /* C_GPIO8 */ + {8, 0, PMX_FSPI_CLK, 1, 0}, /* C_GPIO8 */ + {9, 0, PMX_SDIO3_CMD, 0, 1}, /* C_GPIO9 */ + {9, 0, PMX_SP_CLK2_2, 7, 1}, /* C_GPIO9 */ + {10, 0, PMX_FSPI_CS, 1, 0}, /* C_GPIO10 */ + {11, 0, PMX_DMCLK_3, 8, 3}, /* C_GPIO11 */ + {11, 0, PMX_I2C3_2_SCL, 11, 1}, /* C_GPIO11 */ + {11, 0, PMX_I2S_MCLK_2, 12, 1}, /* C_GPIO11 */ + {11, 0, PMX_PWM4_2, 13, 1}, /* C_GPIO11 */ + {11, 0, PMX_SDIO_CLK, 14, 1}, /* C_GPIO11 */ + {11, 0, PMX_SPI3_2_CLK, 15, 1}, /* C_GPIO11 */ + {12, 0, PMX_DMDAT0_3, 8, 3}, /* C_GPIO12 */ + {12, 0, PMX_I2C3_2_SDA, 11, 1}, /* C_GPIO12 */ + {12, 0, PMX_I2S_BCLK_2, 16, 1}, /* C_GPIO12 */ + {12, 0, PMX_PWM5_2, 17, 1}, /* C_GPIO12 */ + {12, 0, PMX_SDIO_CMD, 14, 1}, /* C_GPIO12 */ + {12, 0, PMX_SPI3_2_DO, 15, 1}, /* C_GPIO12 */ + {13, 0, PMX_DMDAT1_3, 8, 3}, /* C_GPIO13 */ + {13, 0, PMX_UART2_2_CTS, 18, 2}, /* C_GPIO13 */ + {13, 0, PMX_I2S_SYNC_2, 16, 1}, /* C_GPIO13 */ + {13, 0, PMX_PWM0_2, 20, 1}, /* C_GPIO13 */ + {13, 0, PMX_SDIO_D0, 14, 1}, /* C_GPIO13 */ + {13, 0, PMX_SPI3_2_CS, 15, 1}, /* C_GPIO13 */ + {14, 0, PMX_SPI3_2_DI, 21, 2}, /* C_GPIO14 */ + {14, 0, PMX_UART2_2_RTS, 18, 2}, /* C_GPIO14 */ + {14, 0, PMX_UART2_2_RTS, 23, 2}, /* C_GPIO14 */ + {14, 0, PMX_I2S_SDATAO_2, 16, 1}, /* C_GPIO14 */ + {14, 0, PMX_PWM1_2, 25, 1}, /* C_GPIO14 */ + {14, 0, PMX_REMOTE_IN_2, 26, 1}, /* C_GPIO14 */ + {14, 0, PMX_SDIO_D1, 14, 1}, /* C_GPIO14 */ + {15, 0, PMX_REMOTE_EXT, 27, 2}, /* C_GPIO15 */ + {15, 0, PMX_SPI_CH3_RDY, 29, 2}, /* C_GPIO15 */ + {15, 0, PMX_I2S_SDATAI_2, 16, 1}, /* C_GPIO15 */ + {15, 0, PMX_PWM2_2, 31, 1}, /* C_GPIO15 */ + {15, 0, PMX_SDIO_D2, 14, 1}, /* C_GPIO15 */ + {15, 0, PMX_UART2_2_TX, 32, 1}, /* C_GPIO15 */ + {16, 0, PMX_PWM3_2, 33, 1}, /* C_GPIO16 */ + {16, 0, PMX_SDIO_D3, 14, 1}, /* C_GPIO16 */ + {16, 0, PMX_UART2_2_RX, 32, 1}, /* C_GPIO16 */ + {17, 0, PMX_I2C2_2_SCL, 34, 1}, /* C_GPIO17 */ + {17, 0, PMX_PWM6_2, 35, 1}, /* C_GPIO17 */ + {17, 0, PMX_SDIO2_CLK, 36, 1}, /* C_GPIO17 */ + {17, 0, PMX_SPI_1_CLK, 37, 1}, /* C_GPIO17 */ + {18, 0, PMX_I2C2_2_SDA, 34, 1}, /* C_GPIO18 */ + {18, 0, PMX_PWM7_2, 38, 1}, /* C_GPIO18 */ + {18, 0, PMX_SDIO2_CMD, 36, 1}, /* C_GPIO18 */ + {18, 0, PMX_SPI_1_DO, 37, 1}, /* C_GPIO18 */ + {19, 0, PMX_UART3_2_CTS, 39, 2}, /* C_GPIO19 */ + {19, 0, PMX_PWM8_2, 41, 1}, /* C_GPIO19 */ + {19, 0, PMX_SDIO2_D0, 36, 1}, /* C_GPIO19 */ + {19, 0, PMX_SPI_1_CS, 37, 1}, /* C_GPIO19 */ + {20, 0, PMX_SPI_1_DI, 42, 2}, /* C_GPIO20 */ + {20, 0, PMX_UART3_2_RTS, 39, 2}, /* C_GPIO20 */ + {20, 0, PMX_UART3_2_RTS, 44, 2}, /* C_GPIO20 */ + {20, 0, PMX_PWM9_2, 46, 1}, /* C_GPIO20 */ + {20, 0, PMX_SDIO2_D1, 36, 1}, /* C_GPIO20 */ + {21, 0, PMX_PWM10_2, 47, 1}, /* C_GPIO21 */ + {21, 0, PMX_SDIO2_D2, 36, 1}, /* C_GPIO21 */ + {21, 0, PMX_UART3_2_TX, 48, 1}, /* C_GPIO21 */ + {22, 0, PMX_PWM11_2, 49, 1}, /* C_GPIO22 */ + {22, 0, PMX_SDIO2_D3, 36, 1}, /* C_GPIO22 */ + {22, 0, PMX_UART3_2_RX, 48, 1}, /* C_GPIO22 */ + {32, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO0 */ + {32, 0, PMX_PWM0_1, 51, 1}, /* P_GPIO0 */ + {32, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO0 */ + {32, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO0 */ + {32, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO0 */ + {32, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO0 */ + {32, 0, PMX_SPI2_2_CS, 56, 1}, /* P_GPIO0 */ + {32, 0, PMX_UART2_3_TX, 57, 1}, /* P_GPIO0 */ + {33, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO1 */ + {33, 0, PMX_PWM1_1, 58, 1}, /* P_GPIO1 */ + {33, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO1 */ + {33, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO1 */ + {33, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO1 */ + {33, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO1 */ + {33, 0, PMX_SPI2_2_CLK, 56, 1}, /* P_GPIO1 */ + {33, 0, PMX_UART2_3_RX, 57, 1}, /* P_GPIO1 */ + {34, 0, PMX_UART2_3_RTS, 59, 2}, /* P_GPIO2 */ + {34, 0, PMX_UART2_3_RTS, 61, 2}, /* P_GPIO2 */ + {34, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO2 */ + {34, 0, PMX_PWM2_1, 63, 1}, /* P_GPIO2 */ + {34, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO2 */ + {34, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO2 */ + {34, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO2 */ + {34, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO2 */ + {34, 0, PMX_SPI2_2_DO, 56, 1}, /* P_GPIO2 */ + {35, 0, PMX_SPI2_2_DI, 64, 2}, /* P_GPIO3 */ + {35, 0, PMX_UART2_3_CTS, 59, 2}, /* P_GPIO3 */ + {35, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO3 */ + {35, 0, PMX_PWM3_1, 66, 1}, /* P_GPIO3 */ + {35, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO3 */ + {35, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO3 */ + {35, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO3 */ + {35, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO3 */ + {36, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO4 */ + {36, 0, PMX_PWM4_1, 67, 1}, /* P_GPIO4 */ + {36, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO4 */ + {36, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO4 */ + {36, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO4 */ + {36, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO4 */ + {36, 0, PMX_SPI3_3_CS, 68, 1}, /* P_GPIO4 */ + {36, 0, PMX_UART3_3_TX, 69, 1}, /* P_GPIO4 */ + {37, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO5 */ + {37, 0, PMX_PWM5_1, 70, 1}, /* P_GPIO5 */ + {37, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO5 */ + {37, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO5 */ + {37, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO5 */ + {37, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO5 */ + {37, 0, PMX_SPI3_3_CLK, 68, 1}, /* P_GPIO5 */ + {37, 0, PMX_UART3_3_RX, 69, 1}, /* P_GPIO5 */ + {38, 0, PMX_UART3_3_RTS, 71, 2}, /* P_GPIO6 */ + {38, 0, PMX_UART3_3_RTS, 73, 2}, /* P_GPIO6 */ + {38, 0, PMX_PWM6_1, 75, 1}, /* P_GPIO6 */ + {38, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO6 */ + {38, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO6 */ + {38, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO6 */ + {38, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO6 */ + {38, 0, PMX_SPI3_3_DO, 68, 1}, /* P_GPIO6 */ + {39, 0, PMX_ETH_EXTPHYCLK, 76, 2}, /* P_GPIO7 */ + {39, 0, PMX_SPI3_3_DI, 78, 2}, /* P_GPIO7 */ + {39, 0, PMX_UART3_3_CTS, 71, 2}, /* P_GPIO7 */ + {39, 0, PMX_PWM7_1, 80, 1}, /* P_GPIO7 */ + {39, 0, PMX_SB4_CS, 81, 1}, /* P_GPIO7 */ + {39, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO7 */ + {39, NVT_UNGATED, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO7 */ + {39, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO7 */ + {39, 0, PMX_SENSOR_CCIR16BITS, 55, 1}, /* P_GPIO7 */ + {40, 0, PMX_SPI_CH3_RDY, 82, 2}, /* P_GPIO8 */ + {40, 0, PMX_ETH_RMII_2, 50, 1}, /* P_GPIO8 */ + {40, 0, PMX_I2S_MCLK_1, 84, 1}, /* P_GPIO8 */ + {40, 0, PMX_PWM8_1, 85, 1}, /* P_GPIO8 */ + {40, 0, PMX_SB4_CK, 81, 1}, /* P_GPIO8 */ + {40, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO8 */ + {40, 0, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO8 */ + {40, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO8 */ + {41, 0, PMX_ETH_MDIO_2, 86, 2}, /* P_GPIO9 */ + {41, 0, PMX_ETH_MDIO_2, 88, 1}, /* P_GPIO9 */ + {41, 0, PMX_I2S_BCLK_1, 89, 1}, /* P_GPIO9 */ + {41, 0, PMX_PWM9_1, 90, 1}, /* P_GPIO9 */ + {41, 0, PMX_SB4_DAT, 81, 1}, /* P_GPIO9 */ + {41, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO9 */ + {41, 0, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO9 */ + {41, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO9 */ + {42, 0, PMX_ETH_MDIO_2, 86, 2}, /* P_GPIO10 */ + {42, 0, PMX_ETH_MDIO_2, 88, 1}, /* P_GPIO10 */ + {42, 0, PMX_I2S_SYNC_1, 89, 1}, /* P_GPIO10 */ + {42, 0, PMX_PWM10_1, 91, 1}, /* P_GPIO10 */ + {42, 0, PMX_SB3_1_CS, 92, 1}, /* P_GPIO10 */ + {42, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO10 */ + {42, 0, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO10 */ + {42, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO10 */ + {43, 0, PMX_I2S_SDATAO_1, 89, 1}, /* P_GPIO11 */ + {43, 0, PMX_PWM11_1, 93, 1}, /* P_GPIO11 */ + {43, 0, PMX_SB3_1_CK, 92, 1}, /* P_GPIO11 */ + {43, NVT_UNGATED, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO11 */ + {43, 0, PMX_SENSOR2_CCIR8BITS, 53, 1}, /* P_GPIO11 */ + {43, NVT_UNGATED, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO11 */ + {44, 0, PMX_SENSOR2_SN3_MCLK, 94, 2}, /* P_GPIO12 */ + {44, 0, PMX_SPI_CH3_RDY, 96, 2}, /* P_GPIO12 */ + {44, 0, PMX_I2S_SDATAI_1, 89, 1}, /* P_GPIO12 */ + {44, 0, PMX_PICNT_1, 98, 1}, /* P_GPIO12 */ + {44, 0, PMX_SB3_1_DAT, 92, 1}, /* P_GPIO12 */ + {44, 0, PMX_SENSOR2_12BITS, 52, 1}, /* P_GPIO12 */ + {44, 0, PMX_SENSOR2_SN3_MCLK, 99, 1}, /* P_GPIO12 */ + {44, 0, PMX_SENSOR_12BITS_2ND, 54, 1}, /* P_GPIO12 */ + {49, 0, PMX_DMDAT0_1, 100, 3}, /* P_GPIO17 */ + {49, 0, PMX_PICNT3_1, 103, 1}, /* P_GPIO17 */ + {49, 0, PMX_REMOTE_IN_1, 104, 1}, /* P_GPIO17 */ + {49, 0, PMX_SB3_2_CS, 105, 1}, /* P_GPIO17 */ + {49, 0, PMX_SPI3_1_CS, 106, 1}, /* P_GPIO17 */ + {49, 0, PMX_UART2_1_TX, 107, 1}, /* P_GPIO17 */ + {50, 0, PMX_DMDAT1_1, 100, 3}, /* P_GPIO18 */ + {50, 0, PMX_REMOTE_EXT, 108, 2}, /* P_GPIO18 */ + {50, 0, PMX_PICNT_2, 110, 1}, /* P_GPIO18 */ + {50, 0, PMX_SB3_2_CK, 105, 1}, /* P_GPIO18 */ + {50, 0, PMX_SPI3_1_CLK, 106, 1}, /* P_GPIO18 */ + {50, 0, PMX_UART2_1_RX, 107, 1}, /* P_GPIO18 */ + {51, 0, PMX_DMCLK_1, 100, 3}, /* P_GPIO19 */ + {51, 0, PMX_UART2_1_RTS, 111, 2}, /* P_GPIO19 */ + {51, 0, PMX_UART2_1_RTS, 113, 2}, /* P_GPIO19 */ + {51, 0, PMX_PICNT2_2, 115, 1}, /* P_GPIO19 */ + {51, 0, PMX_RTC_CLK, 116, 1}, /* P_GPIO19 */ + {51, 0, PMX_SB3_2_DAT, 105, 1}, /* P_GPIO19 */ + {51, 0, PMX_SPI3_1_DO, 106, 1}, /* P_GPIO19 */ + {52, 0, PMX_SPI3_1_DI, 117, 2}, /* P_GPIO20 */ + {52, 0, PMX_UART2_1_CTS, 111, 2}, /* P_GPIO20 */ + {52, 0, PMX_PICNT3_2, 119, 1}, /* P_GPIO20 */ + {52, 0, PMX_SP_CLK_1, 120, 1}, /* P_GPIO20 */ + {53, 0, PMX_I2C3_1_SDA, 121, 1}, /* P_GPIO21 */ + {53, 0, PMX_SP_CLK2_1, 122, 1}, /* P_GPIO21 */ + {54, 0, PMX_I2C3_1_SCL, 121, 1}, /* P_GPIO22 */ + {55, 0, PMX_UART_TX, 123, 1}, /* P_GPIO23 */ + {56, 0, PMX_UART_RX, 123, 1}, /* P_GPIO24 */ + {64, 0, PMX_SDIO2_CLK, 124, 1}, /* S_GPIO0 */ + {64, 0, PMX_SENSOR_MCLK, 125, 1}, /* S_GPIO0 */ + {64, 0, PMX_UART3_4_TX, 126, 1}, /* S_GPIO0 */ + {65, 0, PMX_SENSOR_MCLK2, 127, 3}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_CCIR16BITS, 130, 2}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_MCLK2, 132, 2}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_MCLK2, 134, 2}, /* S_GPIO1 */ + {65, 0, PMX_PWM0_3, 136, 1}, /* S_GPIO1 */ + {65, 0, PMX_SDIO2_CMD, 124, 1}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_12BITS, 137, 1}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_CCIR8BITS, 138, 1}, /* S_GPIO1 */ + {65, 0, PMX_SENSOR_MCLK2, 139, 1}, /* S_GPIO1 */ + {65, 0, PMX_UART3_4_RX, 126, 1}, /* S_GPIO1 */ + {66, 0, PMX_SENSOR_CCIR16BITS, 130, 2}, /* S_GPIO2 */ + {66, 0, PMX_PWM1_3, 140, 1}, /* S_GPIO2 */ + {66, 0, PMX_SDIO2_D0, 124, 1}, /* S_GPIO2 */ + {66, 0, PMX_SENSOR_12BITS, 137, 1}, /* S_GPIO2 */ + {66, 0, PMX_SENSOR_12BITS_2ND, 54, 1}, /* S_GPIO2 */ + {66, 0, PMX_SENSOR_CCIR8BITS, 138, 1}, /* S_GPIO2 */ + {66, 0, PMX_SENSOR_LVDS_VDHD, 141, 1}, /* S_GPIO2 */ + {67, 0, PMX_SENSOR_CCIR16BITS, 130, 2}, /* S_GPIO3 */ + {67, 0, PMX_PWM2_3, 142, 1}, /* S_GPIO3 */ + {67, 0, PMX_SB2_CS, 143, 1}, /* S_GPIO3 */ + {67, 0, PMX_SDIO2_D1, 124, 1}, /* S_GPIO3 */ + {67, 0, PMX_SENSOR_12BITS, 137, 1}, /* S_GPIO3 */ + {67, 0, PMX_SENSOR_12BITS_2ND, 54, 1}, /* S_GPIO3 */ + {67, 0, PMX_SENSOR_CCIR8BITS, 138, 1}, /* S_GPIO3 */ + {67, 0, PMX_SENSOR_LVDS_VDHD, 141, 1}, /* S_GPIO3 */ + {68, 0, PMX_I2C2_1_SCL, 144, 1}, /* S_GPIO4 */ + {68, 0, PMX_PWM3_3, 145, 1}, /* S_GPIO4 */ + {68, 0, PMX_SB2_CK, 143, 1}, /* S_GPIO4 */ + {68, 0, PMX_SENSOR2_12BITS, 52, 1}, /* S_GPIO4 */ + {68, 0, PMX_SENSOR2_LVDS_VDHD, 146, 1}, /* S_GPIO4 */ + {68, 0, PMX_UART3_5_TX, 147, 1}, /* S_GPIO4 */ + {69, 0, PMX_SPI_2_DI, 148, 2}, /* S_GPIO5 */ + {69, 0, PMX_I2C2_1_SDA, 144, 1}, /* S_GPIO5 */ + {69, 0, PMX_PWM4_3, 150, 1}, /* S_GPIO5 */ + {69, 0, PMX_SB2_DAT, 143, 1}, /* S_GPIO5 */ + {69, 0, PMX_SENSOR2_12BITS, 52, 1}, /* S_GPIO5 */ + {69, 0, PMX_SENSOR2_LVDS_VDHD, 146, 1}, /* S_GPIO5 */ + {69, 0, PMX_UART3_5_RX, 147, 1}, /* S_GPIO5 */ + {70, 0, PMX_PWM5_3, 151, 1}, /* S_GPIO6 */ + {70, 0, PMX_SB_CS, 152, 1}, /* S_GPIO6 */ + {70, 0, PMX_SPI_2_CS, 153, 1}, /* S_GPIO6 */ + {71, 0, PMX_SENSOR_CCIR16BITS, 130, 2}, /* S_GPIO7 */ + {71, 0, PMX_I2C_SCL_1, 154, 1}, /* S_GPIO7 */ + {71, 0, PMX_PWM6_3, 155, 1}, /* S_GPIO7 */ + {71, 0, PMX_SB_CK, 152, 1}, /* S_GPIO7 */ + {71, 0, PMX_SDIO2_D2, 124, 1}, /* S_GPIO7 */ + {71, 0, PMX_SENSOR_CCIR8BITS, 138, 1}, /* S_GPIO7 */ + {71, 0, PMX_SPI_2_CLK, 153, 1}, /* S_GPIO7 */ + {72, 0, PMX_I2C_SDA_1, 154, 1}, /* S_GPIO8 */ + {72, 0, PMX_PWM7_3, 156, 1}, /* S_GPIO8 */ + {72, 0, PMX_SB_DAT, 152, 1}, /* S_GPIO8 */ + {72, 0, PMX_SDIO2_D3, 124, 1}, /* S_GPIO8 */ + {72, 0, PMX_SENSOR2_MCLK_2ND, 157, 1}, /* S_GPIO8 */ + {72, 0, PMX_SPI_2_DO, 153, 1}, /* S_GPIO8 */ + {96, 0, PMX_PWM11_5, 158, 1}, /* L_GPIO0 */ + {97, 0, PMX_PICNT2_1, 159, 1}, /* L_GPIO1 */ + {98, 0, PMX_SP_CLK_2, 160, 1}, /* L_GPIO2 */ + {128, 0, PMX_ETH_LED1, 161, 1}, /* D_GPIO0 */ + {129, 0, PMX_ETH_LED1, 161, 1}, /* D_GPIO1 */ + {131, 0, PMX_PWM4_4, 162, 1}, /* D_GPIO3 */ + {131, 0, PMX_SB3_3_CS, 163, 1}, /* D_GPIO3 */ + {131, 0, PMX_SP_CLK_3, 164, 1}, /* D_GPIO3 */ + {132, 0, PMX_PWM5_4, 165, 1}, /* D_GPIO4 */ + {132, 0, PMX_SB3_3_CK, 163, 1}, /* D_GPIO4 */ + {132, 0, PMX_SP_CLK2_3, 166, 1}, /* D_GPIO4 */ + {133, 0, PMX_ETH_LED2, 167, 1}, /* D_GPIO5 */ + {133, 0, PMX_PWM6_4, 168, 1}, /* D_GPIO5 */ + {133, 0, PMX_SB3_3_DAT, 163, 1}, /* D_GPIO5 */ + {134, 0, PMX_ETH_LED2, 167, 1}, /* D_GPIO6 */ + {134, 0, PMX_PWM7_4, 169, 1}, /* D_GPIO6 */ + {135, 0, PMX_PWM11_4, 170, 1}, /* D_GPIO7 */ + {160, 0, PMX_SENSOR_CCIR_2, 171, 2}, /* H_GPIO0 */ + {160, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO0 */ + {160, 0, PMX_SENSOR_CCIR_2, 138, 1}, /* H_GPIO0 */ + {160, 0, PMX_MIPI_LVDS_DAT0, 1, 0}, /* H_GPIO0 */ + {161, 0, PMX_SENSOR_CCIR_2, 171, 2}, /* H_GPIO1 */ + {161, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO1 */ + {161, 0, PMX_SENSOR_CCIR_2, 138, 1}, /* H_GPIO1 */ + {161, 0, PMX_MIPI_LVDS_DAT0, 1, 0}, /* H_GPIO1 */ + {162, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO2 */ + {162, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO2 */ + {162, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO2 */ + {162, 0, PMX_MIPI_LVDS_DAT1, 1, 0}, /* H_GPIO2 */ + {163, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO3 */ + {163, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO3 */ + {163, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO3 */ + {163, 0, PMX_MIPI_LVDS_DAT1, 1, 0}, /* H_GPIO3 */ + {164, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO4 */ + {164, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO4 */ + {164, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO4 */ + {164, 0, PMX_MIPI_LVDS_CLK0, 1, 0}, /* H_GPIO4 */ + {165, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO5 */ + {165, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO5 */ + {165, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO5 */ + {165, 0, PMX_MIPI_LVDS_CLK0, 1, 0}, /* H_GPIO5 */ + {166, 0, PMX_PWM8_3, 173, 1}, /* H_GPIO6 */ + {166, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO6 */ + {166, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO6 */ + {166, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO6 */ + {166, 0, PMX_MIPI_LVDS_DAT2, 1, 0}, /* H_GPIO6 */ + {167, 0, PMX_PWM9_3, 174, 1}, /* H_GPIO7 */ + {167, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO7 */ + {167, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO7 */ + {167, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO7 */ + {167, 0, PMX_SENSOR_LVDS_VDHD2, 175, 1}, /* H_GPIO7 */ + {167, 0, PMX_MIPI_LVDS_DAT2, 1, 0}, /* H_GPIO7 */ + {168, 0, PMX_PWM10_3, 176, 1}, /* H_GPIO8 */ + {168, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO8 */ + {168, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO8 */ + {168, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO8 */ + {168, 0, PMX_SENSOR_LVDS_VDHD2, 175, 1}, /* H_GPIO8 */ + {168, 0, PMX_MIPI_LVDS_DAT3, 1, 0}, /* H_GPIO8 */ + {169, 0, PMX_I2C_2_SCL, 177, 1}, /* H_GPIO9 */ + {169, 0, PMX_PWM11_3, 178, 1}, /* H_GPIO9 */ + {169, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO9 */ + {169, NVT_UNGATED, PMX_SENSOR_CCIR16BITS, 55, 1}, /* H_GPIO9 */ + {169, NVT_UNGATED, PMX_SENSOR_CCIR8BITS, 138, 1}, /* H_GPIO9 */ + {169, 0, PMX_MIPI_LVDS_DAT3, 1, 0}, /* H_GPIO9 */ + {170, 0, PMX_SENSOR_CCIR_2, 171, 2}, /* H_GPIO10 */ + {170, 0, PMX_I2C_2_SDA, 177, 1}, /* H_GPIO10 */ + {170, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO10 */ + {170, 0, PMX_SENSOR_CCIR_2, 138, 1}, /* H_GPIO10 */ + {170, 0, PMX_MIPI_LVDS_CLK1, 1, 0}, /* H_GPIO10 */ + {171, 0, PMX_SENSOR_MCLK_2ND, 179, 3}, /* H_GPIO11 */ + {171, 0, PMX_SENSOR_CCIR_2, 171, 2}, /* H_GPIO11 */ + {171, 0, PMX_SENSOR_MCLK_2ND, 182, 2}, /* H_GPIO11 */ + {171, 0, PMX_SENSOR_MCLK_2ND, 184, 2}, /* H_GPIO11 */ + {171, NVT_UNGATED, PMX_SENSOR_12BITS, 137, 1}, /* H_GPIO11 */ + {171, 0, PMX_SENSOR_CCIR_2, 138, 1}, /* H_GPIO11 */ + {171, 0, PMX_SENSOR_MCLK_2ND, 186, 1}, /* H_GPIO11 */ + {171, 0, PMX_MIPI_LVDS_CLK1, 1, 0}, /* H_GPIO11 */ + {224, 0, PMX_ETH_MDIO, 187, 1}, /* DSI_GPIO0 */ + {224, 0, PMX_PWM0_5, 188, 1}, /* DSI_GPIO0 */ + {224, 0, PMX_UART3_1_TX, 189, 1}, /* DSI_GPIO0 */ + {225, 0, PMX_ETH_MDIO, 187, 1}, /* DSI_GPIO1 */ + {225, 0, PMX_PWM1_5, 190, 1}, /* DSI_GPIO1 */ + {225, 0, PMX_UART3_1_RX, 189, 1}, /* DSI_GPIO1 */ + {226, 0, PMX_UART3_1_RTS, 191, 2}, /* DSI_GPIO2 */ + {226, 0, PMX_UART3_1_RTS, 193, 2}, /* DSI_GPIO2 */ + {226, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO2 */ + {226, 0, PMX_PWM2_5, 196, 1}, /* DSI_GPIO2 */ + {226, 0, PMX_SDIO2_D0, 197, 1}, /* DSI_GPIO2 */ + {227, 0, PMX_UART3_1_CTS, 191, 2}, /* DSI_GPIO3 */ + {227, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO3 */ + {227, 0, PMX_PWM3_5, 198, 1}, /* DSI_GPIO3 */ + {227, 0, PMX_SDIO2_D1, 197, 1}, /* DSI_GPIO3 */ + {228, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO4 */ + {228, 0, PMX_PWM4_5, 199, 1}, /* DSI_GPIO4 */ + {228, 0, PMX_SDIO2_D2, 197, 1}, /* DSI_GPIO4 */ + {228, 0, PMX_SPI2_1_CS, 200, 1}, /* DSI_GPIO4 */ + {229, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO5 */ + {229, 0, PMX_PWM5_5, 201, 1}, /* DSI_GPIO5 */ + {229, 0, PMX_SDIO2_D3, 197, 1}, /* DSI_GPIO5 */ + {229, 0, PMX_SPI2_1_CLK, 200, 1}, /* DSI_GPIO5 */ + {230, 0, PMX_PWM6_5, 202, 1}, /* DSI_GPIO6 */ + {230, 0, PMX_SDIO2_CMD, 197, 1}, /* DSI_GPIO6 */ + {230, 0, PMX_SPI2_1_DO, 200, 1}, /* DSI_GPIO6 */ + {231, 0, PMX_SPI2_1_DI, 203, 2}, /* DSI_GPIO7 */ + {231, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO7 */ + {231, 0, PMX_PWM7_5, 205, 1}, /* DSI_GPIO7 */ + {231, 0, PMX_SDIO2_CLK, 197, 1}, /* DSI_GPIO7 */ + {232, 0, PMX_DMDAT0_2, 206, 3}, /* DSI_GPIO8 */ + {232, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO8 */ + {232, 0, PMX_I2C3_3_SDA, 209, 1}, /* DSI_GPIO8 */ + {232, 0, PMX_PWM8_5, 210, 1}, /* DSI_GPIO8 */ + {233, 0, PMX_DMDAT1_2, 206, 3}, /* DSI_GPIO9 */ + {233, 0, PMX_ETH_RMII, 211, 2}, /* DSI_GPIO9 */ + {233, 0, PMX_ETH_MDIO, 187, 1}, /* DSI_GPIO9 */ + {233, 0, PMX_ETH_RMII, 195, 1}, /* DSI_GPIO9 */ + {233, 0, PMX_I2C3_3_SCL, 209, 1}, /* DSI_GPIO9 */ + {233, 0, PMX_PWM9_5, 213, 1}, /* DSI_GPIO9 */ + {234, 0, PMX_DMCLK_2, 206, 3}, /* DSI_GPIO10 */ + {234, 0, PMX_ETH_EXTPHYCLK, 214, 1}, /* DSI_GPIO10 */ + {234, 0, PMX_ETH_MDIO, 187, 1}, /* DSI_GPIO10 */ + {234, 0, PMX_PWM10_5, 215, 1}, /* DSI_GPIO10 */ +}; + +/* The field each function's walk row shows: {pad, name, reg, + * shift, width, value}, reg NVT_GATE for the pad's gate bit. */ +static const novatek_sel_t NA51089_sels[] = { + {0, PMX_SDIO3_D0, 0x04, 17, 1, 1}, + {0, PMX_FSPI_DO, NVT_GATE, 0, 0, 0}, + {1, PMX_SDIO3_D1, 0x04, 17, 1, 1}, + {1, PMX_FSPI_DI, NVT_GATE, 0, 0, 0}, + {2, PMX_SDIO3_D2, 0x04, 17, 1, 1}, + {2, PMX_FSPI_WP, NVT_GATE, 0, 0, 0}, + {3, PMX_SDIO3_D3, 0x04, 17, 1, 1}, + {3, PMX_FSPI_HOLD, NVT_GATE, 0, 0, 0}, + {4, PMX_SDIO3_D4, 0x04, 17, 1, 1}, + {4, PMX_PWM0_4, 0x1C, 0, 3, 4}, + {5, PMX_SDIO3_D5, 0x04, 17, 1, 1}, + {5, PMX_PWM1_4, 0x1C, 3, 3, 4}, + {6, PMX_SDIO3_D6, 0x04, 17, 1, 1}, + {6, PMX_PWM2_4, 0x1C, 6, 3, 4}, + {7, PMX_SDIO3_D7, 0x04, 17, 1, 1}, + {7, PMX_PWM3_4, 0x1C, 9, 3, 4}, + {8, PMX_SDIO3_CLK, 0x04, 17, 1, 1}, + {8, PMX_FSPI_CLK, NVT_GATE, 0, 0, 0}, + {9, PMX_SDIO3_CMD, 0x04, 17, 1, 1}, + {9, PMX_SP_CLK2_2, 0x18, 10, 2, 2}, + {10, PMX_FSPI_CS, NVT_GATE, 0, 0, 0}, + {11, PMX_DMCLK_3, 0x18, 5, 1, 1}, + {11, PMX_I2C3_2_SCL, 0x14, 6, 2, 2}, + {11, PMX_I2S_MCLK_2, 0x18, 2, 2, 2}, + {11, PMX_PWM4_2, 0x1C, 12, 3, 2}, + {11, PMX_SDIO_CLK, 0x04, 14, 1, 1}, + {11, PMX_SPI3_2_CLK, 0x14, 12, 2, 2}, + {12, PMX_DMDAT0_3, 0x18, 5, 1, 1}, + {12, PMX_I2C3_2_SDA, 0x14, 6, 2, 2}, + {12, PMX_I2S_BCLK_2, 0x18, 0, 2, 2}, + {12, PMX_PWM5_2, 0x1C, 15, 3, 2}, + {12, PMX_SDIO_CMD, 0x04, 14, 1, 1}, + {12, PMX_SPI3_2_DO, 0x14, 12, 2, 2}, + {13, PMX_DMDAT1_3, 0x18, 5, 1, 1}, + {13, PMX_UART2_2_CTS, 0x24, 2, 2, 2}, + {13, PMX_I2S_SYNC_2, 0x18, 0, 2, 2}, + {13, PMX_PWM0_2, 0x1C, 0, 3, 2}, + {13, PMX_SDIO_D0, 0x04, 14, 1, 1}, + {13, PMX_SPI3_2_CS, 0x14, 12, 2, 2}, + {14, PMX_SPI3_2_DI, 0x14, 12, 2, 2}, + {14, PMX_UART2_2_RTS, 0x24, 2, 2, 2}, + {14, PMX_I2S_SDATAO_2, 0x18, 0, 2, 2}, + {14, PMX_PWM1_2, 0x1C, 3, 3, 2}, + {14, PMX_REMOTE_IN_2, 0x18, 7, 2, 2}, + {14, PMX_SDIO_D1, 0x04, 14, 1, 1}, + {15, PMX_REMOTE_EXT, 0x18, 7, 2, 2}, + {15, PMX_SPI_CH3_RDY, 0x14, 12, 2, 2}, + {15, PMX_I2S_SDATAI_2, 0x18, 0, 2, 2}, + {15, PMX_PWM2_2, 0x1C, 6, 3, 2}, + {15, PMX_SDIO_D2, 0x04, 14, 1, 1}, + {15, PMX_UART2_2_TX, 0x24, 2, 2, 2}, + {16, PMX_PWM3_2, 0x1C, 9, 3, 2}, + {16, PMX_SDIO_D3, 0x04, 14, 1, 1}, + {16, PMX_UART2_2_RX, 0x24, 2, 2, 2}, + {17, PMX_I2C2_2_SCL, 0x14, 4, 2, 2}, + {17, PMX_PWM6_2, 0x1C, 18, 3, 2}, + {17, PMX_SDIO2_CLK, 0x04, 18, 2, 1}, + {17, PMX_SPI_1_CLK, 0x14, 8, 2, 1}, + {18, PMX_I2C2_2_SDA, 0x14, 4, 2, 2}, + {18, PMX_PWM7_2, 0x1C, 21, 3, 2}, + {18, PMX_SDIO2_CMD, 0x04, 18, 2, 1}, + {18, PMX_SPI_1_DO, 0x14, 8, 2, 1}, + {19, PMX_UART3_2_CTS, 0x24, 4, 3, 2}, + {19, PMX_PWM8_2, 0x18, 16, 3, 2}, + {19, PMX_SDIO2_D0, 0x04, 18, 2, 1}, + {19, PMX_SPI_1_CS, 0x14, 8, 2, 1}, + {20, PMX_SPI_1_DI, 0x14, 8, 2, 1}, + {20, PMX_UART3_2_RTS, 0x24, 4, 3, 2}, + {20, PMX_PWM9_2, 0x18, 19, 3, 2}, + {20, PMX_SDIO2_D1, 0x04, 18, 2, 1}, + {21, PMX_PWM10_2, 0x18, 22, 3, 2}, + {21, PMX_SDIO2_D2, 0x04, 18, 2, 1}, + {21, PMX_UART3_2_TX, 0x24, 4, 3, 2}, + {22, PMX_PWM11_2, 0x18, 25, 3, 2}, + {22, PMX_SDIO2_D3, 0x04, 18, 2, 1}, + {22, PMX_UART3_2_RX, 0x24, 4, 3, 2}, + {32, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {32, PMX_PWM0_1, 0x1C, 0, 3, 1}, + {32, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {32, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {32, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {32, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {32, PMX_SPI2_2_CS, 0x14, 10, 2, 2}, + {32, PMX_UART2_3_TX, 0x24, 2, 2, 3}, + {33, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {33, PMX_PWM1_1, 0x1C, 3, 3, 1}, + {33, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {33, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {33, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {33, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {33, PMX_SPI2_2_CLK, 0x14, 10, 2, 2}, + {33, PMX_UART2_3_RX, 0x24, 2, 2, 3}, + {34, PMX_UART2_3_RTS, 0x24, 2, 2, 3}, + {34, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {34, PMX_PWM2_1, 0x1C, 6, 3, 1}, + {34, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {34, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {34, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {34, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {34, PMX_SPI2_2_DO, 0x14, 10, 2, 2}, + {35, PMX_SPI2_2_DI, 0x14, 10, 2, 2}, + {35, PMX_UART2_3_CTS, 0x24, 2, 2, 3}, + {35, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {35, PMX_PWM3_1, 0x1C, 9, 3, 1}, + {35, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {35, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {35, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {35, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {36, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {36, PMX_PWM4_1, 0x1C, 12, 3, 1}, + {36, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {36, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {36, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {36, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {36, PMX_SPI3_3_CS, 0x14, 12, 2, 3}, + {36, PMX_UART3_3_TX, 0x24, 4, 3, 3}, + {37, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {37, PMX_PWM5_1, 0x1C, 15, 3, 1}, + {37, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {37, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {37, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {37, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {37, PMX_SPI3_3_CLK, 0x14, 12, 2, 3}, + {37, PMX_UART3_3_RX, 0x24, 4, 3, 3}, + {38, PMX_UART3_3_RTS, 0x24, 4, 3, 3}, + {38, PMX_PWM6_1, 0x1C, 18, 3, 1}, + {38, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {38, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {38, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {38, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {38, PMX_SPI3_3_DO, 0x14, 12, 2, 3}, + {39, PMX_ETH_EXTPHYCLK, 0x14, 30, 2, 2}, + {39, PMX_SPI3_3_DI, 0x14, 12, 2, 3}, + {39, PMX_UART3_3_CTS, 0x24, 4, 3, 3}, + {39, PMX_PWM7_1, 0x1C, 21, 3, 1}, + {39, PMX_SB4_CS, 0x14, 26, 1, 1}, + {39, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {39, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {39, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {39, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {40, PMX_SPI_CH3_RDY, 0x14, 12, 2, 3}, + {40, PMX_ETH_RMII_2, 0x14, 30, 2, 2}, + {40, PMX_I2S_MCLK_1, 0x18, 2, 2, 1}, + {40, PMX_PWM8_1, 0x18, 16, 3, 1}, + {40, PMX_SB4_CK, 0x14, 26, 1, 1}, + {40, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {40, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {40, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {41, PMX_ETH_MDIO_2, 0x14, 2, 2, 2}, + {41, PMX_I2S_BCLK_1, 0x18, 0, 2, 1}, + {41, PMX_PWM9_1, 0x18, 19, 3, 1}, + {41, PMX_SB4_DAT, 0x14, 26, 1, 1}, + {41, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {41, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {41, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {42, PMX_ETH_MDIO_2, 0x14, 2, 2, 2}, + {42, PMX_I2S_SYNC_1, 0x18, 0, 2, 1}, + {42, PMX_PWM10_1, 0x18, 22, 3, 1}, + {42, PMX_SB3_1_CS, 0x14, 24, 2, 1}, + {42, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {42, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {42, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {43, PMX_I2S_SDATAO_1, 0x18, 0, 2, 1}, + {43, PMX_PWM11_1, 0x18, 25, 3, 1}, + {43, PMX_SB3_1_CK, 0x14, 24, 2, 1}, + {43, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {43, PMX_SENSOR2_CCIR8BITS, 0x0C, 4, 2, 2}, + {43, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {44, PMX_SENSOR2_SN3_MCLK, 0x0C, 16, 1, 1}, + {44, PMX_SPI_CH3_RDY, 0x14, 12, 2, 1}, + {44, PMX_I2S_SDATAI_1, 0x18, 0, 2, 1}, + {44, PMX_PICNT_1, 0x1C, 26, 2, 1}, + {44, PMX_SB3_1_DAT, 0x14, 24, 2, 1}, + {44, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {44, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {49, PMX_DMDAT0_1, 0x18, 5, 1, 1}, + {49, PMX_PICNT3_1, 0x1C, 30, 2, 1}, + {49, PMX_REMOTE_IN_1, 0x18, 7, 2, 1}, + {49, PMX_SB3_2_CS, 0x14, 24, 2, 2}, + {49, PMX_SPI3_1_CS, 0x14, 12, 2, 1}, + {49, PMX_UART2_1_TX, 0x24, 2, 2, 1}, + {50, PMX_DMDAT1_1, 0x18, 5, 1, 1}, + {50, PMX_REMOTE_EXT, 0x18, 7, 2, 1}, + {50, PMX_PICNT_2, 0x1C, 26, 2, 2}, + {50, PMX_SB3_2_CK, 0x14, 24, 2, 2}, + {50, PMX_SPI3_1_CLK, 0x14, 12, 2, 1}, + {50, PMX_UART2_1_RX, 0x24, 2, 2, 1}, + {51, PMX_DMCLK_1, 0x18, 5, 1, 1}, + {51, PMX_UART2_1_RTS, 0x24, 2, 2, 1}, + {51, PMX_PICNT2_2, 0x1C, 28, 2, 2}, + {51, PMX_RTC_CLK, 0x18, 9, 1, 1}, + {51, PMX_SB3_2_DAT, 0x14, 24, 2, 2}, + {51, PMX_SPI3_1_DO, 0x14, 12, 2, 1}, + {52, PMX_SPI3_1_DI, 0x14, 12, 2, 1}, + {52, PMX_UART2_1_CTS, 0x24, 2, 2, 1}, + {52, PMX_PICNT3_2, 0x1C, 30, 2, 2}, + {52, PMX_SP_CLK_1, 0x0C, 18, 2, 1}, + {53, PMX_I2C3_1_SDA, 0x14, 6, 2, 1}, + {53, PMX_SP_CLK2_1, 0x18, 10, 2, 1}, + {54, PMX_I2C3_1_SCL, 0x14, 6, 2, 1}, + {55, PMX_UART_TX, 0x24, 0, 1, 1}, + {56, PMX_UART_RX, 0x24, 0, 1, 1}, + {64, PMX_SDIO2_CLK, 0x04, 18, 2, 2}, + {64, PMX_SENSOR_MCLK, 0x0C, 8, 2, 1}, + {64, PMX_UART3_4_TX, 0x24, 4, 3, 4}, + {65, PMX_SENSOR_MCLK2, 0x0C, 12, 2, 1}, + {65, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {65, PMX_PWM0_3, 0x1C, 0, 3, 3}, + {65, PMX_SDIO2_CMD, 0x04, 18, 2, 2}, + {65, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {65, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {65, PMX_UART3_4_RX, 0x24, 4, 3, 4}, + {66, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {66, PMX_PWM1_3, 0x1C, 3, 3, 3}, + {66, PMX_SDIO2_D0, 0x04, 18, 2, 2}, + {66, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {66, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {66, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {66, PMX_SENSOR_LVDS_VDHD, 0x0C, 10, 2, 1}, + {67, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {67, PMX_PWM2_3, 0x1C, 6, 3, 3}, + {67, PMX_SB2_CS, 0x14, 22, 1, 1}, + {67, PMX_SDIO2_D1, 0x04, 18, 2, 2}, + {67, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {67, PMX_SENSOR_12BITS_2ND, 0x0C, 0, 3, 2}, + {67, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {67, PMX_SENSOR_LVDS_VDHD, 0x0C, 10, 2, 1}, + {68, PMX_I2C2_1_SCL, 0x14, 4, 2, 1}, + {68, PMX_PWM3_3, 0x1C, 9, 3, 3}, + {68, PMX_SB2_CK, 0x14, 22, 1, 1}, + {68, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {68, PMX_SENSOR2_LVDS_VDHD, 0x0C, 14, 2, 1}, + {68, PMX_UART3_5_TX, 0x24, 4, 3, 5}, + {69, PMX_SPI_2_DI, 0x14, 8, 2, 2}, + {69, PMX_I2C2_1_SDA, 0x14, 4, 2, 1}, + {69, PMX_PWM4_3, 0x1C, 12, 3, 3}, + {69, PMX_SB2_DAT, 0x14, 22, 1, 1}, + {69, PMX_SENSOR2_12BITS, 0x0C, 4, 2, 1}, + {69, PMX_SENSOR2_LVDS_VDHD, 0x0C, 14, 2, 1}, + {69, PMX_UART3_5_RX, 0x24, 4, 3, 5}, + {70, PMX_PWM5_3, 0x1C, 15, 3, 3}, + {70, PMX_SB_CS, 0x14, 20, 1, 1}, + {70, PMX_SPI_2_CS, 0x14, 8, 2, 2}, + {71, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {71, PMX_I2C_SCL_1, 0x14, 0, 2, 1}, + {71, PMX_PWM6_3, 0x1C, 18, 3, 3}, + {71, PMX_SB_CK, 0x14, 20, 1, 1}, + {71, PMX_SDIO2_D2, 0x04, 18, 2, 2}, + {71, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {71, PMX_SPI_2_CLK, 0x14, 8, 2, 2}, + {72, PMX_I2C_SDA_1, 0x14, 0, 2, 1}, + {72, PMX_PWM7_3, 0x1C, 21, 3, 3}, + {72, PMX_SB_DAT, 0x14, 20, 1, 1}, + {72, PMX_SDIO2_D3, 0x04, 18, 2, 2}, + {72, PMX_SENSOR2_MCLK_2ND, 0x0C, 12, 2, 2}, + {72, PMX_SPI_2_DO, 0x14, 8, 2, 2}, + {96, PMX_PWM11_5, 0x18, 25, 3, 5}, + {97, PMX_PICNT2_1, 0x1C, 28, 2, 1}, + {98, PMX_SP_CLK_2, 0x0C, 18, 2, 2}, + {128, PMX_ETH_LED1, 0x18, 13, 2, 1}, + {129, PMX_ETH_LED1, 0x18, 13, 2, 1}, + {131, PMX_PWM4_4, 0x1C, 12, 3, 4}, + {131, PMX_SB3_3_CS, 0x14, 24, 2, 3}, + {131, PMX_SP_CLK_3, 0x0C, 18, 2, 3}, + {132, PMX_PWM5_4, 0x1C, 15, 3, 4}, + {132, PMX_SB3_3_CK, 0x14, 24, 2, 3}, + {132, PMX_SP_CLK2_3, 0x18, 10, 2, 3}, + {133, PMX_ETH_LED2, 0x18, 13, 2, 2}, + {133, PMX_PWM6_4, 0x1C, 18, 3, 4}, + {133, PMX_SB3_3_DAT, 0x14, 24, 2, 3}, + {134, PMX_ETH_LED2, 0x18, 13, 2, 2}, + {134, PMX_PWM7_4, 0x1C, 21, 3, 4}, + {135, PMX_PWM11_4, 0x18, 25, 3, 4}, + {160, PMX_SENSOR_CCIR_2, 0x0C, 0, 3, 3}, + {160, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {160, PMX_MIPI_LVDS_DAT0, NVT_GATE, 0, 0, 0}, + {161, PMX_SENSOR_CCIR_2, 0x0C, 0, 3, 3}, + {161, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {161, PMX_MIPI_LVDS_DAT0, NVT_GATE, 0, 0, 0}, + {162, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {162, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {162, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {162, PMX_MIPI_LVDS_DAT1, NVT_GATE, 0, 0, 0}, + {163, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {163, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {163, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {163, PMX_MIPI_LVDS_DAT1, NVT_GATE, 0, 0, 0}, + {164, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {164, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {164, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {164, PMX_MIPI_LVDS_CLK0, NVT_GATE, 0, 0, 0}, + {165, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {165, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {165, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {165, PMX_MIPI_LVDS_CLK0, NVT_GATE, 0, 0, 0}, + {166, PMX_PWM8_3, 0x18, 16, 3, 3}, + {166, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {166, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {166, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {166, PMX_MIPI_LVDS_DAT2, NVT_GATE, 0, 0, 0}, + {167, PMX_PWM9_3, 0x18, 19, 3, 3}, + {167, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {167, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {167, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {167, PMX_SENSOR_LVDS_VDHD2, 0x0C, 10, 2, 2}, + {167, PMX_MIPI_LVDS_DAT2, NVT_GATE, 0, 0, 0}, + {168, PMX_PWM10_3, 0x18, 22, 3, 3}, + {168, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {168, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {168, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {168, PMX_SENSOR_LVDS_VDHD2, 0x0C, 10, 2, 2}, + {168, PMX_MIPI_LVDS_DAT3, NVT_GATE, 0, 0, 0}, + {169, PMX_I2C_2_SCL, 0x14, 0, 2, 2}, + {169, PMX_PWM11_3, 0x18, 25, 3, 3}, + {169, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {169, PMX_SENSOR_CCIR16BITS, 0x0C, 0, 3, 4}, + {169, PMX_SENSOR_CCIR8BITS, 0x0C, 0, 3, 3}, + {169, PMX_MIPI_LVDS_DAT3, NVT_GATE, 0, 0, 0}, + {170, PMX_SENSOR_CCIR_2, 0x0C, 0, 3, 3}, + {170, PMX_I2C_2_SDA, 0x14, 0, 2, 2}, + {170, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {170, PMX_MIPI_LVDS_CLK1, NVT_GATE, 0, 0, 0}, + {171, PMX_SENSOR_MCLK_2ND, 0x0C, 8, 2, 2}, + {171, PMX_SENSOR_CCIR_2, 0x0C, 0, 3, 3}, + {171, PMX_SENSOR_12BITS, 0x0C, 0, 3, 1}, + {171, PMX_MIPI_LVDS_CLK1, NVT_GATE, 0, 0, 0}, + {224, PMX_ETH_MDIO, 0x14, 2, 2, 1}, + {224, PMX_PWM0_5, 0x1C, 0, 3, 5}, + {224, PMX_UART3_1_TX, 0x24, 4, 3, 1}, + {225, PMX_ETH_MDIO, 0x14, 2, 2, 1}, + {225, PMX_PWM1_5, 0x1C, 3, 3, 5}, + {225, PMX_UART3_1_RX, 0x24, 4, 3, 1}, + {226, PMX_UART3_1_RTS, 0x24, 4, 3, 1}, + {226, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {226, PMX_PWM2_5, 0x1C, 6, 3, 5}, + {226, PMX_SDIO2_D0, 0x04, 18, 2, 3}, + {227, PMX_UART3_1_CTS, 0x24, 4, 3, 1}, + {227, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {227, PMX_PWM3_5, 0x1C, 9, 3, 5}, + {227, PMX_SDIO2_D1, 0x04, 18, 2, 3}, + {228, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {228, PMX_PWM4_5, 0x1C, 12, 3, 5}, + {228, PMX_SDIO2_D2, 0x04, 18, 2, 3}, + {228, PMX_SPI2_1_CS, 0x14, 10, 2, 1}, + {229, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {229, PMX_PWM5_5, 0x1C, 15, 3, 5}, + {229, PMX_SDIO2_D3, 0x04, 18, 2, 3}, + {229, PMX_SPI2_1_CLK, 0x14, 10, 2, 1}, + {230, PMX_PWM6_5, 0x1C, 18, 3, 5}, + {230, PMX_SDIO2_CMD, 0x04, 18, 2, 3}, + {230, PMX_SPI2_1_DO, 0x14, 10, 2, 1}, + {231, PMX_SPI2_1_DI, 0x14, 10, 2, 1}, + {231, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {231, PMX_PWM7_5, 0x1C, 21, 3, 5}, + {231, PMX_SDIO2_CLK, 0x04, 18, 2, 3}, + {232, PMX_DMDAT0_2, 0x18, 5, 1, 1}, + {232, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {232, PMX_I2C3_3_SDA, 0x14, 6, 2, 3}, + {232, PMX_PWM8_5, 0x18, 16, 3, 5}, + {233, PMX_DMDAT1_2, 0x18, 5, 1, 1}, + {233, PMX_ETH_RMII, 0x14, 30, 2, 1}, + {233, PMX_ETH_MDIO, 0x14, 2, 2, 1}, + {233, PMX_I2C3_3_SCL, 0x14, 6, 2, 3}, + {233, PMX_PWM9_5, 0x18, 19, 3, 5}, + {234, PMX_DMCLK_2, 0x18, 5, 1, 1}, + {234, PMX_ETH_EXTPHYCLK, 0x18, 28, 1, 1}, + {234, PMX_ETH_MDIO, 0x14, 2, 2, 1}, + {234, PMX_PWM10_5, 0x18, 22, 3, 5}, +}; + +static const novatek_soc_t NA51089_padmux = { + NA51089_pads, 102, NA51089_claims, 388, NA51089_conds, + NA51089_sels, 368, +}; + +#endif /* HAL_NOVATEK_PADMUX_H */ diff --git a/src/hal/novatek_padmux_types.h b/src/hal/novatek_padmux_types.h new file mode 100644 index 00000000..93b0eca5 --- /dev/null +++ b/src/hal/novatek_padmux_types.h @@ -0,0 +1,73 @@ +#ifndef HAL_NOVATEK_PADMUX_TYPES_H +#define HAL_NOVATEK_PADMUX_TYPES_H + +#include + +#include "padmux_names.h" + +/* The shape of the generated table in novatek_padmux.h. Separate from it so + * the generator emits data and nothing else. + * + * A NA51089 pad is not a selector. What it carries is the answer to two + * questions in two places: which peripheral's location field in the TOP block + * names it, and whether the pad's own gate bit has been cleared to hand it + * over. So a pad's alternatives are CLAIMS -- a name, and the field values + * under which the pad carries it -- and the first claim whose fields hold is + * the answer. See src/hal/novatek_padmux.c. + * + * Names are offsets into padmux_names, as everywhere else: a pointer here is + * a relocation in a position-independent consumer. */ + +/* A claim that holds whatever the pad's gate bit says. The parallel sensor + * modes put pixel data on the HSI pads and leave the gate at GPIO. */ +#define NVT_UNGATED 0x01 + +/* novatek_sel_t.reg for a walk row whose selector is the gate bit itself. */ +#define NVT_GATE 0xFF + +/* One TOP-block field and the value it must hold: TOP + reg, `width` bits + * at `shift`. */ +typedef const struct { + uint8_t reg; + uint8_t shift; + uint8_t width; + uint8_t value; +} novatek_cond_t; + +/* One way `pad` can be `name`: conds[cond .. cond + ncond) all hold. */ +typedef const struct { + uint8_t pad; /* Linux GPIO number */ + uint8_t flags; /* NVT_UNGATED */ + uint16_t name; + uint16_t cond; + uint8_t ncond; +} novatek_claim_t; + +typedef const struct { + uint8_t pad; /* Linux GPIO number */ + uint16_t name; /* "P_GPIO22", the kernel's own macro */ +} novatek_pad_t; + +/* What a walk row shows as address, mask and value for `name` on `pad`: one + * field that tells it apart from the pad's other names. Information only -- + * get() and set() read the claims. */ +typedef const struct { + uint8_t pad; + uint16_t name; + uint8_t reg; /* or NVT_GATE */ + uint8_t shift; + uint8_t width; + uint8_t value; +} novatek_sel_t; + +typedef const struct { + const novatek_pad_t *pads; + uint16_t npads; + const novatek_claim_t *claims; /* sorted by pad */ + uint16_t nclaims; + const novatek_cond_t *conds; + const novatek_sel_t *sels; /* sorted by pad */ + uint16_t nsels; +} novatek_soc_t; + +#endif /* HAL_NOVATEK_PADMUX_TYPES_H */ diff --git a/src/hal/novatek_reginfo.h b/src/hal/novatek_reginfo.h new file mode 100644 index 00000000..05305a4f --- /dev/null +++ b/src/hal/novatek_reginfo.h @@ -0,0 +1,39 @@ +#ifndef HAL_NOVATEK_REGINFO_H +#define HAL_NOVATEK_REGINFO_H + +#include "reginfo.h" + +/* What plain `reginfo` dumps on a NA51089: the TOP block's pad-mux state, + * whole. The first eleven are the per-peripheral location fields -- REG5 + * holds I2C, SPI, SIF and ETH, REG9 the UARTs, and so on; the vendor's + * plat-na51089/top_reg.h has the bit layout. The last eight are the per-pad + * gate bitmaps, one per pad group, where a set bit keeps the pad a GPIO. + * `reginfo --pads` is the same state read pad by pad. */ +MUXCTRL(NA51089_reg0, 0xF0010000, PMX_TOP_REG0) +MUXCTRL(NA51089_reg1, 0xF0010004, PMX_TOP_REG1) +MUXCTRL(NA51089_reg2, 0xF0010008, PMX_TOP_REG2) +MUXCTRL(NA51089_reg3, 0xF001000C, PMX_TOP_REG3) +MUXCTRL(NA51089_reg4, 0xF0010010, PMX_TOP_REG4) +MUXCTRL(NA51089_reg5, 0xF0010014, PMX_TOP_REG5) +MUXCTRL(NA51089_reg6, 0xF0010018, PMX_TOP_REG6) +MUXCTRL(NA51089_reg7, 0xF001001C, PMX_TOP_REG7) +MUXCTRL(NA51089_reg8, 0xF0010020, PMX_TOP_REG8) +MUXCTRL(NA51089_reg9, 0xF0010024, PMX_TOP_REG9) +MUXCTRL(NA51089_reg10, 0xF0010028, PMX_TOP_REG10) +MUXCTRL(NA51089_reg11, 0xF00100A0, PMX_TOP_CGPIO) +MUXCTRL(NA51089_reg12, 0xF00100A8, PMX_TOP_PGPIO) +MUXCTRL(NA51089_reg13, 0xF00100B0, PMX_TOP_SGPIO) +MUXCTRL(NA51089_reg14, 0xF00100B8, PMX_TOP_LGPIO) +MUXCTRL(NA51089_reg15, 0xF00100D0, PMX_TOP_DGPIO) +MUXCTRL(NA51089_reg16, 0xF00100D8, PMX_TOP_HGPIO) +MUXCTRL(NA51089_reg17, 0xF00100E0, PMX_TOP_AGPIO) +MUXCTRL(NA51089_reg18, 0xF00100E8, PMX_TOP_DSIGPIO) + +static const muxctrl_reg_t *NA51089_regs[] = { + &NA51089_reg0, &NA51089_reg1, &NA51089_reg2, &NA51089_reg3, + &NA51089_reg4, &NA51089_reg5, &NA51089_reg6, &NA51089_reg7, + &NA51089_reg8, &NA51089_reg9, &NA51089_reg10, &NA51089_reg11, + &NA51089_reg12, &NA51089_reg13, &NA51089_reg14, &NA51089_reg15, + &NA51089_reg16, &NA51089_reg17, &NA51089_reg18, 0}; + +#endif /* HAL_NOVATEK_REGINFO_H */ diff --git a/src/padmux.c b/src/padmux.c index 494df000..d213599c 100644 --- a/src/padmux.c +++ b/src/padmux.c @@ -13,6 +13,7 @@ #include "chipid.h" #include "hal/ingenic.h" +#include "hal/novatek.h" #include "hal/sstar.h" #include "tools.h" @@ -61,6 +62,10 @@ const padmux_ops_t *padmux_ops(void) { case T31: case T40: return &PADMUX_OPS_INGENIC; +#endif +#ifdef IPCHW_PADMUX_NOVATEK + case CHIP_NA51089: + return &PADMUX_OPS_NOVATEK; #endif default: break; @@ -182,6 +187,13 @@ int padmux_parse_pad(const char *spec) { if (spec == NULL || !*spec) return -1; + /* Only once the SoC is known: before that every spelling is the + * generic one, which is what a caller that has not detected anything + * has always had. */ + const padmux_ops_t *ops = chip_generation ? padmux_ops() : NULL; + if (ops != NULL && ops->parse_pad != NULL) + return ops->parse_pad(spec); + int bank, pin, end = 0; if (sscanf(spec, "%d_%d%n", &bank, &pin, &end) == 2) { /* %n has to land on the terminator. Without it "5_2junk" and "1_2_3" diff --git a/src/padmux.h b/src/padmux.h index dc4ca6c1..36ccff24 100644 --- a/src/padmux.h +++ b/src/padmux.h @@ -10,7 +10,7 @@ * The inside of the pad-mux API. include/ipchw.h has the contract a consumer * sees; this is the seam the three vendors meet at. * - * They select a pad's function three different ways, and only the first of + * They select a pad's function four different ways, and only the first of * them is one register per pad: * * HiSilicon/Goke one register per pad, a selector nibble indexing the list @@ -22,6 +22,10 @@ * Ingenic four bits at the pin's own position in four different * registers (INT, MSK, PAT1, PAT0), so no single write * selects a function at all. + * Novatek SigmaStar's per-peripheral fields, plus a gate bit per + * pad that has to be cleared before any of them reaches + * it. One pad's function is a field in one register and a + * bit in another. * * What a caller sees is a flat ipchw_padmux_t in every case. * ---------------------------------------------------------------------- */ @@ -49,7 +53,7 @@ const padmux_io_t *padmux_set_io(const padmux_io_t *io); typedef bool (*padmux_match_fn)(const char *func_name, const void *arg); typedef struct { - const char *name; /* "hisi", "sstar", "ingenic" */ + const char *name; /* "hisi", "sstar", "ingenic", "novatek" */ /* The same counting contract as the public lookups: the return value is * the number of MATCHES, which may exceed `max`; at most `max` rows are @@ -63,6 +67,10 @@ typedef struct { /* Put `func_name` on `pad`: 0, or IPCHW_PADMUX_*. */ int (*set)(int pad, const char *func_name, const padmux_io_t *io); + + /* The vendor's own spellings of a pad, to its number, or -1. NULL where + * the two generic ones in padmux_parse_pad() are all there is. */ + int (*parse_pad)(const char *spec); } padmux_ops_t; /* Always present: reginfo.c is compiled into every configuration, and its @@ -75,6 +83,9 @@ extern const padmux_ops_t PADMUX_OPS_SSTAR; #ifdef IPCHW_PADMUX_INGENIC extern const padmux_ops_t PADMUX_OPS_INGENIC; #endif +#ifdef IPCHW_PADMUX_NOVATEK +extern const padmux_ops_t PADMUX_OPS_NOVATEK; +#endif /* The backend for the SoC that has been detected, or NULL when this build * carries no pad-mux table that could serve it. */ @@ -85,8 +96,9 @@ const padmux_ops_t *padmux_ops(void); * wants: "not known to be free" rather than "free". */ bool padmux_pad_is_gpio(int pad); -/* "5_2" or "42" -> 42, the two spellings every gpio subcommand accepts. - * -1 for anything else. */ +/* "5_2" or "42" -> 42, the two spellings every gpio subcommand accepts, or + * the detected SoC's own: "P_GPIO22" on Novatek, where "5_2" is refused + * because the bank-of-eight numbering is HiSilicon's. -1 for anything else. */ int padmux_parse_pad(const char *spec); #endif /* PADMUX_H */ diff --git a/src/padmux_names.c b/src/padmux_names.c index 6fcba314..043c56fd 100644 --- a/src/padmux_names.c +++ b/src/padmux_names.c @@ -10,6 +10,15 @@ const struct padmux_names padmux_names = { ._none = "", +#if defined(IPCHW_PADMUX_NOVATEK) + .A_GPIO0 = "A_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .A_GPIO1 = "A_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .A_GPIO2 = "A_GPIO2", +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) .BOOTROM_SEL = "BOOTROM_SEL", #endif @@ -70,6 +79,75 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) .CS2 = "CS2", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO0 = "C_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO1 = "C_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO10 = "C_GPIO10", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO11 = "C_GPIO11", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO12 = "C_GPIO12", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO13 = "C_GPIO13", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO14 = "C_GPIO14", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO15 = "C_GPIO15", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO16 = "C_GPIO16", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO17 = "C_GPIO17", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO18 = "C_GPIO18", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO19 = "C_GPIO19", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO2 = "C_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO20 = "C_GPIO20", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO21 = "C_GPIO21", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO22 = "C_GPIO22", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO3 = "C_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO4 = "C_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO5 = "C_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO6 = "C_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO7 = "C_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO8 = "C_GPIO8", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .C_GPIO9 = "C_GPIO9", +#endif #if defined(IPCHW_PADMUX_SSTAR) .DLA_EJ_MODE_1 = "DLA_EJ_MODE_1", #endif @@ -79,6 +157,33 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .DLA_EJ_MODE_3 = "DLA_EJ_MODE_3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMCLK_1 = "DMCLK_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMCLK_2 = "DMCLK_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMCLK_3 = "DMCLK_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT0_1 = "DMDAT0_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT0_2 = "DMDAT0_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT0_3 = "DMDAT0_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT1_1 = "DMDAT1_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT1_2 = "DMDAT1_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DMDAT1_3 = "DMDAT1_3", +#endif #if defined(IPCHW_PADMUX_SSTAR) .DMIC_4CH_MODE_1 = "DMIC_4CH_MODE_1", #endif @@ -202,6 +307,39 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .DSI_D3P = "DSI_D3P", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO0 = "DSI_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO1 = "DSI_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO10 = "DSI_GPIO10", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO2 = "DSI_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO3 = "DSI_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO4 = "DSI_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO5 = "DSI_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO6 = "DSI_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO7 = "DSI_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO8 = "DSI_GPIO8", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .DSI_GPIO9 = "DSI_GPIO9", +#endif #if defined(IPCHW_PADMUX_INGENIC) .DVP_D10 = "DVP_D10", #endif @@ -235,6 +373,30 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) .DVP_VSYNC = "DVP_VSYNC", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO0 = "D_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO1 = "D_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO2 = "D_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO3 = "D_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO4 = "D_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO5 = "D_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO6 = "D_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .D_GPIO7 = "D_GPIO7", +#endif #if defined(IPCHW_PADMUX_SSTAR) .EJ_MODE_1 = "EJ_MODE_1", #endif @@ -331,6 +493,15 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) .EPHY_RSTN = "EPHY_RSTN", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_EXTPHYCLK = "ETH_EXTPHYCLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_LED1 = "ETH_LED1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_LED2 = "ETH_LED2", +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) .ETH_LINK_ACT_LED = "ETH_LINK_ACT_LED", #endif @@ -340,6 +511,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) .ETH_LINK_STA_LED = "ETH_LINK_STA_LED", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_MDIO = "ETH_MDIO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_MDIO_2 = "ETH_MDIO_2", +#endif #if defined(IPCHW_PADMUX_SSTAR) .ETH_MODE = "ETH_MODE", #endif @@ -352,6 +529,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .ETH_MODE_3 = "ETH_MODE_3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_RMII = "ETH_RMII", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .ETH_RMII_2 = "ETH_RMII_2", +#endif #if defined(IPCHW_PADMUX_3536D) .ETH_SPD_LED = "ETH_SPD_LED", #endif @@ -367,6 +550,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .FMC_STARTUP_DISABLE = "FMC_STARTUP_DISABLE", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_CLK = "FSPI_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_CS = "FSPI_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_DI = "FSPI_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_DO = "FSPI_DO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_HOLD = "FSPI_HOLD", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .FSPI_WP = "FSPI_WP", +#endif #if defined(IPCHW_PADMUX_SSTAR) .FUART_2W_MODE_1 = "FUART_2W_MODE_1", #endif @@ -829,6 +1030,42 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4A) .HDMI_SDA = "HDMI_SDA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO0 = "H_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO1 = "H_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO10 = "H_GPIO10", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO11 = "H_GPIO11", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO2 = "H_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO3 = "H_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO4 = "H_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO5 = "H_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO6 = "H_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO7 = "H_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO8 = "H_GPIO8", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .H_GPIO9 = "H_GPIO9", +#endif #if defined(IPCHW_PADMUX_SSTAR) .I2C0_MODE_1 = "I2C0_MODE_1", #endif @@ -895,6 +1132,18 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .I2C1_SDA = "I2C1_SDA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C2_1_SCL = "I2C2_1_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C2_1_SDA = "I2C2_1_SDA", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C2_2_SCL = "I2C2_2_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C2_2_SDA = "I2C2_2_SDA", +#endif #if defined(IPCHW_PADMUX_SSTAR) .I2C2_MODE_1 = "I2C2_MODE_1", #endif @@ -925,6 +1174,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .I2C2_SDA = "I2C2_SDA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_1_SCL = "I2C3_1_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_1_SDA = "I2C3_1_SDA", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_2_SCL = "I2C3_2_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_2_SDA = "I2C3_2_SDA", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_3_SCL = "I2C3_3_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C3_3_SDA = "I2C3_3_SDA", +#endif #if defined(IPCHW_PADMUX_INGENIC) .I2C3_PA = "I2C3_PA", #endif @@ -964,12 +1231,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .I2C7_SDA = "I2C7_SDA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C_2_SCL = "I2C_2_SCL", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C_2_SDA = "I2C_2_SDA", +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) .I2C_SCL = "I2C_SCL", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C_SCL_1 = "I2C_SCL_1", +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) .I2C_SDA = "I2C_SDA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2C_SDA_1 = "I2C_SDA_1", +#endif #if defined(IPCHW_PADMUX_V5) .I2S0_BCLK = "I2S0_BCLK", #endif @@ -1018,6 +1297,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) .I2S_BCLK = "I2S_BCLK", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_BCLK_1 = "I2S_BCLK_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_BCLK_2 = "I2S_BCLK_2", +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) .I2S_BCLK_RX = "I2S_BCLK_RX", #endif @@ -1048,6 +1333,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .I2S_MCLK = "I2S_MCLK", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_MCLK_1 = "I2S_MCLK_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_MCLK_2 = "I2S_MCLK_2", +#endif #if defined(IPCHW_PADMUX_SSTAR) .I2S_MODE_1 = "I2S_MODE_1", #endif @@ -1090,6 +1381,18 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .I2S_RX_MODE_4 = "I2S_RX_MODE_4", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SDATAI_1 = "I2S_SDATAI_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SDATAI_2 = "I2S_SDATAI_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SDATAO_1 = "I2S_SDATAO_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SDATAO_2 = "I2S_SDATAO_2", +#endif #if defined(IPCHW_PADMUX_INGENIC) .I2S_SDTI = "I2S_SDTI", #endif @@ -1102,6 +1405,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .I2S_SD_TX = "I2S_SD_TX", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SYNC_1 = "I2S_SYNC_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .I2S_SYNC_2 = "I2S_SYNC_2", +#endif #if defined(IPCHW_PADMUX_SSTAR) .I2S_TX_MODE_1 = "I2S_TX_MODE_1", #endif @@ -1279,6 +1588,36 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .LSADC_CH3 = "LSADC_CH3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO0 = "L_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO1 = "L_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO2 = "L_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO3 = "L_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO4 = "L_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO5 = "L_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO6 = "L_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO7 = "L_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO8 = "L_GPIO8", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .L_GPIO9 = "L_GPIO9", +#endif #if defined(IPCHW_PADMUX_INGENIC) .MAC0_RMII_P0_NORMAL = "MAC0_RMII_P0_NORMAL", #endif @@ -1363,6 +1702,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) .MII_TXER = "MII_TXER", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_CLK0 = "MIPI_LVDS_CLK0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_CLK1 = "MIPI_LVDS_CLK1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_DAT0 = "MIPI_LVDS_DAT0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_DAT1 = "MIPI_LVDS_DAT1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_DAT2 = "MIPI_LVDS_DAT2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .MIPI_LVDS_DAT3 = "MIPI_LVDS_DAT3", +#endif #if defined(IPCHW_PADMUX_SSTAR) .MIPI_PAD_IN_1 = "MIPI_PAD_IN_1", #endif @@ -3427,6 +3784,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) .PFPUENS = "PFPUENS", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT2_1 = "PICNT2_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT2_2 = "PICNT2_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT3_1 = "PICNT3_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT3_2 = "PICNT3_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT_1 = "PICNT_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PICNT_2 = "PICNT_2", +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) .PLL_TEST_OUT0 = "PLL_TEST_OUT0", #endif @@ -3640,6 +4015,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) .PWM0 = "PWM0", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM0_1 = "PWM0_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM0_2 = "PWM0_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM0_3 = "PWM0_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM0_4 = "PWM0_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM0_5 = "PWM0_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM0_MODE_1 = "PWM0_MODE_1", #endif @@ -3676,6 +4066,18 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .PWM10 = "PWM10", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM10_1 = "PWM10_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM10_2 = "PWM10_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM10_3 = "PWM10_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM10_5 = "PWM10_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM10_MODE_1 = "PWM10_MODE_1", #endif @@ -3691,6 +4093,36 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .PWM11 = "PWM11", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM11_1 = "PWM11_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM11_2 = "PWM11_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM11_3 = "PWM11_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM11_4 = "PWM11_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM11_5 = "PWM11_5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM1_1 = "PWM1_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM1_2 = "PWM1_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM1_3 = "PWM1_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM1_4 = "PWM1_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM1_5 = "PWM1_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM1_MODE_1 = "PWM1_MODE_1", #endif @@ -3739,6 +4171,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM2 = "PWM2", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM2_1 = "PWM2_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM2_2 = "PWM2_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM2_3 = "PWM2_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM2_4 = "PWM2_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM2_5 = "PWM2_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM2_MODE_1 = "PWM2_MODE_1", #endif @@ -3763,6 +4210,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM3 = "PWM3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM3_1 = "PWM3_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM3_2 = "PWM3_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM3_3 = "PWM3_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM3_4 = "PWM3_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM3_5 = "PWM3_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM3_MODE_1 = "PWM3_MODE_1", #endif @@ -3787,6 +4249,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM4 = "PWM4", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM4_1 = "PWM4_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM4_2 = "PWM4_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM4_3 = "PWM4_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM4_4 = "PWM4_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM4_5 = "PWM4_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM4_MODE_1 = "PWM4_MODE_1", #endif @@ -3811,6 +4288,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM5 = "PWM5", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM5_1 = "PWM5_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM5_2 = "PWM5_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM5_3 = "PWM5_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM5_4 = "PWM5_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM5_5 = "PWM5_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM5_MODE_1 = "PWM5_MODE_1", #endif @@ -3835,6 +4327,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM6 = "PWM6", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM6_1 = "PWM6_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM6_2 = "PWM6_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM6_3 = "PWM6_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM6_4 = "PWM6_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM6_5 = "PWM6_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM6_MODE_1 = "PWM6_MODE_1", #endif @@ -3859,6 +4366,21 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) .PWM7 = "PWM7", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM7_1 = "PWM7_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM7_2 = "PWM7_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM7_3 = "PWM7_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM7_4 = "PWM7_4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM7_5 = "PWM7_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM7_MODE_1 = "PWM7_MODE_1", #endif @@ -3883,6 +4405,18 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .PWM8 = "PWM8", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM8_1 = "PWM8_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM8_2 = "PWM8_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM8_3 = "PWM8_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM8_5 = "PWM8_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM8_MODE_1 = "PWM8_MODE_1", #endif @@ -3910,6 +4444,18 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .PWM9 = "PWM9", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM9_1 = "PWM9_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM9_2 = "PWM9_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM9_3 = "PWM9_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .PWM9_5 = "PWM9_5", +#endif #if defined(IPCHW_PADMUX_SSTAR) .PWM9_MODE_1 = "PWM9_MODE_1", #endif @@ -4006,9 +4552,96 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) .PZPAT1S = "PZPAT1S", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO0 = "P_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO1 = "P_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO10 = "P_GPIO10", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO11 = "P_GPIO11", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO12 = "P_GPIO12", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO13 = "P_GPIO13", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO14 = "P_GPIO14", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO15 = "P_GPIO15", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO16 = "P_GPIO16", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO17 = "P_GPIO17", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO18 = "P_GPIO18", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO19 = "P_GPIO19", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO2 = "P_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO20 = "P_GPIO20", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO21 = "P_GPIO21", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO22 = "P_GPIO22", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO23 = "P_GPIO23", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO24 = "P_GPIO24", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO25 = "P_GPIO25", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO3 = "P_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO4 = "P_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO5 = "P_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO6 = "P_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO7 = "P_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO8 = "P_GPIO8", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .P_GPIO9 = "P_GPIO9", +#endif #if defined(IPCHW_PADMUX_INGENIC) .RD = "RD", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .REMOTE_EXT = "REMOTE_EXT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .REMOTE_IN_1 = "REMOTE_IN_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .REMOTE_IN_2 = "REMOTE_IN_2", +#endif #if defined(IPCHW_PADMUX_SSTAR) .RGB8_MODE_1 = "RGB8_MODE_1", #endif @@ -4261,6 +4894,9 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V4) .RST_N = "RST_N", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .RTC_CLK = "RTC_CLK", +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) .RTC_TEST_CLK = "RTC_TEST_CLK", #endif @@ -4306,6 +4942,60 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536C) .SATA_LED_N1 = "SATA_LED_N1", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB2_CK = "SB2_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB2_CS = "SB2_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB2_DAT = "SB2_DAT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_1_CK = "SB3_1_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_1_CS = "SB3_1_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_1_DAT = "SB3_1_DAT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_2_CK = "SB3_2_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_2_CS = "SB3_2_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_2_DAT = "SB3_2_DAT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_3_CK = "SB3_3_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_3_CS = "SB3_3_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB3_3_DAT = "SB3_3_DAT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB4_CK = "SB4_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB4_CS = "SB4_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB4_DAT = "SB4_DAT", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB_CK = "SB_CK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB_CS = "SB_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SB_DAT = "SB_DAT", +#endif #if defined(IPCHW_PADMUX_INGENIC) .SD0 = "SD0", #endif @@ -4450,6 +5140,54 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V3) .SDIO2_CDATA3 = "SDIO2_CDATA3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_CLK = "SDIO2_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_CMD = "SDIO2_CMD", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_D0 = "SDIO2_D0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_D1 = "SDIO2_D1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_D2 = "SDIO2_D2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO2_D3 = "SDIO2_D3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_CLK = "SDIO3_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_CMD = "SDIO3_CMD", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D0 = "SDIO3_D0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D1 = "SDIO3_D1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D2 = "SDIO3_D2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D3 = "SDIO3_D3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D4 = "SDIO3_D4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D5 = "SDIO3_D5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D6 = "SDIO3_D6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO3_D7 = "SDIO3_D7", +#endif #if defined(IPCHW_PADMUX_V1) .SDIO_CARD_DETECT = "SDIO_CARD_DETECT", #endif @@ -4483,9 +5221,27 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .SDIO_CDZ_MODE_3 = "SDIO_CDZ_MODE_3", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_CLK = "SDIO_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_CMD = "SDIO_CMD", +#endif #if defined(IPCHW_PADMUX_V1) .SDIO_CWPR = "SDIO_CWPR", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_D0 = "SDIO_D0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_D1 = "SDIO_D1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_D2 = "SDIO_D2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SDIO_D3 = "SDIO_D3", +#endif #if defined(IPCHW_PADMUX_SSTAR) .SDIO_MODE = "SDIO_MODE", #endif @@ -4537,18 +5293,63 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V5) .SENSOR1_VS = "SENSOR1_VS", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR2_12BITS = "SENSOR2_12BITS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR2_CCIR8BITS = "SENSOR2_CCIR8BITS", +#endif #if defined(IPCHW_PADMUX_V5) .SENSOR2_CLK = "SENSOR2_CLK", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR2_LVDS_VDHD = "SENSOR2_LVDS_VDHD", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR2_MCLK_2ND = "SENSOR2_MCLK_2ND", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR2_SN3_MCLK = "SENSOR2_SN3_MCLK", +#endif #if defined(IPCHW_PADMUX_V5) .SENSOR3_CLK = "SENSOR3_CLK", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_12BITS = "SENSOR_12BITS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_12BITS_2ND = "SENSOR_12BITS_2ND", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_CCIR16BITS = "SENSOR_CCIR16BITS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_CCIR8BITS = "SENSOR_CCIR8BITS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_CCIR_2 = "SENSOR_CCIR_2", +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) .SENSOR_CLK = "SENSOR_CLK", #endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) .SENSOR_HS = "SENSOR_HS", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_LVDS_VDHD = "SENSOR_LVDS_VDHD", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_LVDS_VDHD2 = "SENSOR_LVDS_VDHD2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_MCLK = "SENSOR_MCLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_MCLK2 = "SENSOR_MCLK2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SENSOR_MCLK_2ND = "SENSOR_MCLK_2ND", +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) .SENSOR_RSTN = "SENSOR_RSTN", #endif @@ -4798,6 +5599,30 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .SPI1_SDO = "SPI1_SDO", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_1_CLK = "SPI2_1_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_1_CS = "SPI2_1_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_1_DI = "SPI2_1_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_1_DO = "SPI2_1_DO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_2_CLK = "SPI2_2_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_2_CS = "SPI2_2_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_2_DI = "SPI2_2_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI2_2_DO = "SPI2_2_DO", +#endif #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .SPI2_CSN = "SPI2_CSN", #endif @@ -4816,6 +5641,42 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .SPI2_SDO = "SPI2_SDO", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_1_CLK = "SPI3_1_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_1_CS = "SPI3_1_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_1_DI = "SPI3_1_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_1_DO = "SPI3_1_DO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_2_CLK = "SPI3_2_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_2_CS = "SPI3_2_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_2_DI = "SPI3_2_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_2_DO = "SPI3_2_DO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_3_CLK = "SPI3_3_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_3_CS = "SPI3_3_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_3_DI = "SPI3_3_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI3_3_DO = "SPI3_3_DO", +#endif #if defined(IPCHW_PADMUX_V3A) .SPI3_CSN = "SPI3_CSN", #endif @@ -4858,6 +5719,30 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .SPIWPN_MODE = "SPIWPN_MODE", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_1_CLK = "SPI_1_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_1_CS = "SPI_1_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_1_DI = "SPI_1_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_1_DO = "SPI_1_DO", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_2_CLK = "SPI_2_CLK", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_2_CS = "SPI_2_CS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_2_DI = "SPI_2_DI", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_2_DO = "SPI_2_DO", +#endif #if defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4A) .SPI_3LINE_CSN = "SPI_3LINE_CSN", #endif @@ -4876,6 +5761,9 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V5) .SPI_3WIRE_DATA = "SPI_3WIRE_DATA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SPI_CH3_RDY = "SPI_CH3_RDY", +#endif #if defined(IPCHW_PADMUX_3536C) .SPI_CSN0 = "SPI_CSN0", #endif @@ -4927,6 +5815,24 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V5) .SPI_TFT_DATA = "SPI_TFT_DATA", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK2_1 = "SP_CLK2_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK2_2 = "SP_CLK2_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK2_3 = "SP_CLK2_3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK_1 = "SP_CLK_1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK_2 = "SP_CLK_2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .SP_CLK_3 = "SP_CLK_3", +#endif #if defined(IPCHW_PADMUX_SSTAR) .SR00_CTRL_MODE = "SR00_CTRL_MODE", #endif @@ -5173,6 +6079,33 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) .SYS_RSTN_OUT = "SYS_RSTN_OUT", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO0 = "S_GPIO0", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO1 = "S_GPIO1", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO2 = "S_GPIO2", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO3 = "S_GPIO3", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO4 = "S_GPIO4", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO5 = "S_GPIO5", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO6 = "S_GPIO6", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO7 = "S_GPIO7", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .S_GPIO8 = "S_GPIO8", +#endif #if defined(IPCHW_PADMUX_INGENIC) .TCK = "TCK", #endif @@ -5269,6 +6202,63 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_INGENIC) .TMS = "TMS", #endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_AGPIO = "TOP_AGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_CGPIO = "TOP_CGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_DGPIO = "TOP_DGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_DSIGPIO = "TOP_DSIGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_HGPIO = "TOP_HGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_LGPIO = "TOP_LGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_PGPIO = "TOP_PGPIO", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG0 = "TOP_REG0", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG1 = "TOP_REG1", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG10 = "TOP_REG10", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG2 = "TOP_REG2", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG3 = "TOP_REG3", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG4 = "TOP_REG4", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG5 = "TOP_REG5", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG6 = "TOP_REG6", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG7 = "TOP_REG7", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG8 = "TOP_REG8", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_REG9 = "TOP_REG9", +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + .TOP_SGPIO = "TOP_SGPIO", +#endif #if defined(IPCHW_PADMUX_SSTAR) .TTL16_MODE_1 = "TTL16_MODE_1", #endif @@ -5380,6 +6370,42 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .UART1_TXD = "UART1_TXD", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_1_CTS = "UART2_1_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_1_RTS = "UART2_1_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_1_RX = "UART2_1_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_1_TX = "UART2_1_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_2_CTS = "UART2_2_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_2_RTS = "UART2_2_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_2_RX = "UART2_2_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_2_TX = "UART2_2_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_3_CTS = "UART2_3_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_3_RTS = "UART2_3_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_3_RX = "UART2_3_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART2_3_TX = "UART2_3_TX", +#endif #if defined(IPCHW_PADMUX_INGENIC) .UART2_CTS = "UART2_CTS", #endif @@ -5419,6 +6445,54 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) .UART2_TXD = "UART2_TXD", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_1_CTS = "UART3_1_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_1_RTS = "UART3_1_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_1_RX = "UART3_1_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_1_TX = "UART3_1_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_2_CTS = "UART3_2_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_2_RTS = "UART3_2_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_2_RX = "UART3_2_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_2_TX = "UART3_2_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_3_CTS = "UART3_3_CTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_3_RTS = "UART3_3_RTS", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_3_RX = "UART3_3_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_3_TX = "UART3_3_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_4_RX = "UART3_4_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_4_TX = "UART3_4_TX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_5_RX = "UART3_5_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART3_5_TX = "UART3_5_TX", +#endif #if defined(IPCHW_PADMUX_V4A) .UART3_CTSN = "UART3_CTSN", #endif @@ -5449,6 +6523,12 @@ const struct padmux_names padmux_names = { #if defined(IPCHW_PADMUX_SSTAR) .UART_IS_GPIO_0 = "UART_IS_GPIO_0", #endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART_RX = "UART_RX", +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + .UART_TX = "UART_TX", +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) .UPDATE_MODE = "UPDATE_MODE", #endif diff --git a/src/padmux_names.h b/src/padmux_names.h index d955dc72..8c692698 100644 --- a/src/padmux_names.h +++ b/src/padmux_names.h @@ -16,6 +16,15 @@ struct padmux_names { /* Offset 0 is the empty string, which is what makes 0 usable * as the end of a row's function list. */ char _none[1]; +#if defined(IPCHW_PADMUX_NOVATEK) + char A_GPIO0[sizeof "A_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char A_GPIO1[sizeof "A_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char A_GPIO2[sizeof "A_GPIO2"]; +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) char BOOTROM_SEL[sizeof "BOOTROM_SEL"]; #endif @@ -76,6 +85,75 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) char CS2[sizeof "CS2"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO0[sizeof "C_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO1[sizeof "C_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO10[sizeof "C_GPIO10"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO11[sizeof "C_GPIO11"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO12[sizeof "C_GPIO12"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO13[sizeof "C_GPIO13"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO14[sizeof "C_GPIO14"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO15[sizeof "C_GPIO15"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO16[sizeof "C_GPIO16"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO17[sizeof "C_GPIO17"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO18[sizeof "C_GPIO18"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO19[sizeof "C_GPIO19"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO2[sizeof "C_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO20[sizeof "C_GPIO20"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO21[sizeof "C_GPIO21"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO22[sizeof "C_GPIO22"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO3[sizeof "C_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO4[sizeof "C_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO5[sizeof "C_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO6[sizeof "C_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO7[sizeof "C_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO8[sizeof "C_GPIO8"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char C_GPIO9[sizeof "C_GPIO9"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char DLA_EJ_MODE_1[sizeof "DLA_EJ_MODE_1"]; #endif @@ -85,6 +163,33 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char DLA_EJ_MODE_3[sizeof "DLA_EJ_MODE_3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMCLK_1[sizeof "DMCLK_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMCLK_2[sizeof "DMCLK_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMCLK_3[sizeof "DMCLK_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT0_1[sizeof "DMDAT0_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT0_2[sizeof "DMDAT0_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT0_3[sizeof "DMDAT0_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT1_1[sizeof "DMDAT1_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT1_2[sizeof "DMDAT1_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DMDAT1_3[sizeof "DMDAT1_3"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char DMIC_4CH_MODE_1[sizeof "DMIC_4CH_MODE_1"]; #endif @@ -208,6 +313,39 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char DSI_D3P[sizeof "DSI_D3P"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO0[sizeof "DSI_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO1[sizeof "DSI_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO10[sizeof "DSI_GPIO10"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO2[sizeof "DSI_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO3[sizeof "DSI_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO4[sizeof "DSI_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO5[sizeof "DSI_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO6[sizeof "DSI_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO7[sizeof "DSI_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO8[sizeof "DSI_GPIO8"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char DSI_GPIO9[sizeof "DSI_GPIO9"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char DVP_D10[sizeof "DVP_D10"]; #endif @@ -241,6 +379,30 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) char DVP_VSYNC[sizeof "DVP_VSYNC"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO0[sizeof "D_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO1[sizeof "D_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO2[sizeof "D_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO3[sizeof "D_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO4[sizeof "D_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO5[sizeof "D_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO6[sizeof "D_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char D_GPIO7[sizeof "D_GPIO7"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char EJ_MODE_1[sizeof "EJ_MODE_1"]; #endif @@ -337,6 +499,15 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) char EPHY_RSTN[sizeof "EPHY_RSTN"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_EXTPHYCLK[sizeof "ETH_EXTPHYCLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_LED1[sizeof "ETH_LED1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_LED2[sizeof "ETH_LED2"]; +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) char ETH_LINK_ACT_LED[sizeof "ETH_LINK_ACT_LED"]; #endif @@ -346,6 +517,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) char ETH_LINK_STA_LED[sizeof "ETH_LINK_STA_LED"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_MDIO[sizeof "ETH_MDIO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_MDIO_2[sizeof "ETH_MDIO_2"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char ETH_MODE[sizeof "ETH_MODE"]; #endif @@ -358,6 +535,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char ETH_MODE_3[sizeof "ETH_MODE_3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_RMII[sizeof "ETH_RMII"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char ETH_RMII_2[sizeof "ETH_RMII_2"]; +#endif #if defined(IPCHW_PADMUX_3536D) char ETH_SPD_LED[sizeof "ETH_SPD_LED"]; #endif @@ -373,6 +556,24 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char FMC_STARTUP_DISABLE[sizeof "FMC_STARTUP_DISABLE"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_CLK[sizeof "FSPI_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_CS[sizeof "FSPI_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_DI[sizeof "FSPI_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_DO[sizeof "FSPI_DO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_HOLD[sizeof "FSPI_HOLD"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char FSPI_WP[sizeof "FSPI_WP"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char FUART_2W_MODE_1[sizeof "FUART_2W_MODE_1"]; #endif @@ -835,6 +1036,42 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4A) char HDMI_SDA[sizeof "HDMI_SDA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO0[sizeof "H_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO1[sizeof "H_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO10[sizeof "H_GPIO10"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO11[sizeof "H_GPIO11"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO2[sizeof "H_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO3[sizeof "H_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO4[sizeof "H_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO5[sizeof "H_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO6[sizeof "H_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO7[sizeof "H_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO8[sizeof "H_GPIO8"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char H_GPIO9[sizeof "H_GPIO9"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char I2C0_MODE_1[sizeof "I2C0_MODE_1"]; #endif @@ -901,6 +1138,18 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char I2C1_SDA[sizeof "I2C1_SDA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C2_1_SCL[sizeof "I2C2_1_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C2_1_SDA[sizeof "I2C2_1_SDA"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C2_2_SCL[sizeof "I2C2_2_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C2_2_SDA[sizeof "I2C2_2_SDA"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char I2C2_MODE_1[sizeof "I2C2_MODE_1"]; #endif @@ -931,6 +1180,24 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char I2C2_SDA[sizeof "I2C2_SDA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_1_SCL[sizeof "I2C3_1_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_1_SDA[sizeof "I2C3_1_SDA"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_2_SCL[sizeof "I2C3_2_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_2_SDA[sizeof "I2C3_2_SDA"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_3_SCL[sizeof "I2C3_3_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C3_3_SDA[sizeof "I2C3_3_SDA"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char I2C3_PA[sizeof "I2C3_PA"]; #endif @@ -970,12 +1237,24 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char I2C7_SDA[sizeof "I2C7_SDA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C_2_SCL[sizeof "I2C_2_SCL"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C_2_SDA[sizeof "I2C_2_SDA"]; +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) char I2C_SCL[sizeof "I2C_SCL"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C_SCL_1[sizeof "I2C_SCL_1"]; +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) char I2C_SDA[sizeof "I2C_SDA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2C_SDA_1[sizeof "I2C_SDA_1"]; +#endif #if defined(IPCHW_PADMUX_V5) char I2S0_BCLK[sizeof "I2S0_BCLK"]; #endif @@ -1024,6 +1303,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) char I2S_BCLK[sizeof "I2S_BCLK"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_BCLK_1[sizeof "I2S_BCLK_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_BCLK_2[sizeof "I2S_BCLK_2"]; +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) char I2S_BCLK_RX[sizeof "I2S_BCLK_RX"]; #endif @@ -1054,6 +1339,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char I2S_MCLK[sizeof "I2S_MCLK"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_MCLK_1[sizeof "I2S_MCLK_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_MCLK_2[sizeof "I2S_MCLK_2"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char I2S_MODE_1[sizeof "I2S_MODE_1"]; #endif @@ -1096,6 +1387,18 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char I2S_RX_MODE_4[sizeof "I2S_RX_MODE_4"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SDATAI_1[sizeof "I2S_SDATAI_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SDATAI_2[sizeof "I2S_SDATAI_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SDATAO_1[sizeof "I2S_SDATAO_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SDATAO_2[sizeof "I2S_SDATAO_2"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char I2S_SDTI[sizeof "I2S_SDTI"]; #endif @@ -1108,6 +1411,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char I2S_SD_TX[sizeof "I2S_SD_TX"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SYNC_1[sizeof "I2S_SYNC_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char I2S_SYNC_2[sizeof "I2S_SYNC_2"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char I2S_TX_MODE_1[sizeof "I2S_TX_MODE_1"]; #endif @@ -1285,6 +1594,36 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char LSADC_CH3[sizeof "LSADC_CH3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO0[sizeof "L_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO1[sizeof "L_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO2[sizeof "L_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO3[sizeof "L_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO4[sizeof "L_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO5[sizeof "L_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO6[sizeof "L_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO7[sizeof "L_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO8[sizeof "L_GPIO8"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char L_GPIO9[sizeof "L_GPIO9"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char MAC0_RMII_P0_NORMAL[sizeof "MAC0_RMII_P0_NORMAL"]; #endif @@ -1369,6 +1708,24 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) char MII_TXER[sizeof "MII_TXER"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_CLK0[sizeof "MIPI_LVDS_CLK0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_CLK1[sizeof "MIPI_LVDS_CLK1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_DAT0[sizeof "MIPI_LVDS_DAT0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_DAT1[sizeof "MIPI_LVDS_DAT1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_DAT2[sizeof "MIPI_LVDS_DAT2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char MIPI_LVDS_DAT3[sizeof "MIPI_LVDS_DAT3"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char MIPI_PAD_IN_1[sizeof "MIPI_PAD_IN_1"]; #endif @@ -3433,6 +3790,24 @@ struct padmux_names { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) char PFPUENS[sizeof "PFPUENS"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT2_1[sizeof "PICNT2_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT2_2[sizeof "PICNT2_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT3_1[sizeof "PICNT3_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT3_2[sizeof "PICNT3_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT_1[sizeof "PICNT_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PICNT_2[sizeof "PICNT_2"]; +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) char PLL_TEST_OUT0[sizeof "PLL_TEST_OUT0"]; #endif @@ -3646,6 +4021,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) char PWM0[sizeof "PWM0"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM0_1[sizeof "PWM0_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM0_2[sizeof "PWM0_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM0_3[sizeof "PWM0_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM0_4[sizeof "PWM0_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM0_5[sizeof "PWM0_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM0_MODE_1[sizeof "PWM0_MODE_1"]; #endif @@ -3682,6 +4072,18 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char PWM10[sizeof "PWM10"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM10_1[sizeof "PWM10_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM10_2[sizeof "PWM10_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM10_3[sizeof "PWM10_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM10_5[sizeof "PWM10_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM10_MODE_1[sizeof "PWM10_MODE_1"]; #endif @@ -3697,6 +4099,36 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char PWM11[sizeof "PWM11"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM11_1[sizeof "PWM11_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM11_2[sizeof "PWM11_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM11_3[sizeof "PWM11_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM11_4[sizeof "PWM11_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM11_5[sizeof "PWM11_5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM1_1[sizeof "PWM1_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM1_2[sizeof "PWM1_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM1_3[sizeof "PWM1_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM1_4[sizeof "PWM1_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM1_5[sizeof "PWM1_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM1_MODE_1[sizeof "PWM1_MODE_1"]; #endif @@ -3745,6 +4177,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM2[sizeof "PWM2"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM2_1[sizeof "PWM2_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM2_2[sizeof "PWM2_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM2_3[sizeof "PWM2_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM2_4[sizeof "PWM2_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM2_5[sizeof "PWM2_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM2_MODE_1[sizeof "PWM2_MODE_1"]; #endif @@ -3769,6 +4216,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM3[sizeof "PWM3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM3_1[sizeof "PWM3_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM3_2[sizeof "PWM3_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM3_3[sizeof "PWM3_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM3_4[sizeof "PWM3_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM3_5[sizeof "PWM3_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM3_MODE_1[sizeof "PWM3_MODE_1"]; #endif @@ -3793,6 +4255,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM4[sizeof "PWM4"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM4_1[sizeof "PWM4_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM4_2[sizeof "PWM4_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM4_3[sizeof "PWM4_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM4_4[sizeof "PWM4_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM4_5[sizeof "PWM4_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM4_MODE_1[sizeof "PWM4_MODE_1"]; #endif @@ -3817,6 +4294,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM5[sizeof "PWM5"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM5_1[sizeof "PWM5_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM5_2[sizeof "PWM5_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM5_3[sizeof "PWM5_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM5_4[sizeof "PWM5_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM5_5[sizeof "PWM5_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM5_MODE_1[sizeof "PWM5_MODE_1"]; #endif @@ -3841,6 +4333,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM6[sizeof "PWM6"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM6_1[sizeof "PWM6_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM6_2[sizeof "PWM6_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM6_3[sizeof "PWM6_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM6_4[sizeof "PWM6_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM6_5[sizeof "PWM6_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM6_MODE_1[sizeof "PWM6_MODE_1"]; #endif @@ -3865,6 +4372,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) char PWM7[sizeof "PWM7"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM7_1[sizeof "PWM7_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM7_2[sizeof "PWM7_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM7_3[sizeof "PWM7_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM7_4[sizeof "PWM7_4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM7_5[sizeof "PWM7_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM7_MODE_1[sizeof "PWM7_MODE_1"]; #endif @@ -3889,6 +4411,18 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char PWM8[sizeof "PWM8"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM8_1[sizeof "PWM8_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM8_2[sizeof "PWM8_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM8_3[sizeof "PWM8_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM8_5[sizeof "PWM8_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM8_MODE_1[sizeof "PWM8_MODE_1"]; #endif @@ -3916,6 +4450,18 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char PWM9[sizeof "PWM9"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM9_1[sizeof "PWM9_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM9_2[sizeof "PWM9_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM9_3[sizeof "PWM9_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char PWM9_5[sizeof "PWM9_5"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char PWM9_MODE_1[sizeof "PWM9_MODE_1"]; #endif @@ -4012,9 +4558,96 @@ struct padmux_names { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) char PZPAT1S[sizeof "PZPAT1S"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO0[sizeof "P_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO1[sizeof "P_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO10[sizeof "P_GPIO10"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO11[sizeof "P_GPIO11"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO12[sizeof "P_GPIO12"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO13[sizeof "P_GPIO13"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO14[sizeof "P_GPIO14"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO15[sizeof "P_GPIO15"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO16[sizeof "P_GPIO16"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO17[sizeof "P_GPIO17"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO18[sizeof "P_GPIO18"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO19[sizeof "P_GPIO19"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO2[sizeof "P_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO20[sizeof "P_GPIO20"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO21[sizeof "P_GPIO21"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO22[sizeof "P_GPIO22"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO23[sizeof "P_GPIO23"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO24[sizeof "P_GPIO24"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO25[sizeof "P_GPIO25"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO3[sizeof "P_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO4[sizeof "P_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO5[sizeof "P_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO6[sizeof "P_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO7[sizeof "P_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO8[sizeof "P_GPIO8"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char P_GPIO9[sizeof "P_GPIO9"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char RD[sizeof "RD"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char REMOTE_EXT[sizeof "REMOTE_EXT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char REMOTE_IN_1[sizeof "REMOTE_IN_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char REMOTE_IN_2[sizeof "REMOTE_IN_2"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char RGB8_MODE_1[sizeof "RGB8_MODE_1"]; #endif @@ -4267,6 +4900,9 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) char RST_N[sizeof "RST_N"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char RTC_CLK[sizeof "RTC_CLK"]; +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) char RTC_TEST_CLK[sizeof "RTC_TEST_CLK"]; #endif @@ -4312,6 +4948,60 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536C) char SATA_LED_N1[sizeof "SATA_LED_N1"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB2_CK[sizeof "SB2_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB2_CS[sizeof "SB2_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB2_DAT[sizeof "SB2_DAT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_1_CK[sizeof "SB3_1_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_1_CS[sizeof "SB3_1_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_1_DAT[sizeof "SB3_1_DAT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_2_CK[sizeof "SB3_2_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_2_CS[sizeof "SB3_2_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_2_DAT[sizeof "SB3_2_DAT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_3_CK[sizeof "SB3_3_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_3_CS[sizeof "SB3_3_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB3_3_DAT[sizeof "SB3_3_DAT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB4_CK[sizeof "SB4_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB4_CS[sizeof "SB4_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB4_DAT[sizeof "SB4_DAT"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB_CK[sizeof "SB_CK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB_CS[sizeof "SB_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SB_DAT[sizeof "SB_DAT"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char SD0[sizeof "SD0"]; #endif @@ -4456,6 +5146,54 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V3) char SDIO2_CDATA3[sizeof "SDIO2_CDATA3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_CLK[sizeof "SDIO2_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_CMD[sizeof "SDIO2_CMD"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_D0[sizeof "SDIO2_D0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_D1[sizeof "SDIO2_D1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_D2[sizeof "SDIO2_D2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO2_D3[sizeof "SDIO2_D3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_CLK[sizeof "SDIO3_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_CMD[sizeof "SDIO3_CMD"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D0[sizeof "SDIO3_D0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D1[sizeof "SDIO3_D1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D2[sizeof "SDIO3_D2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D3[sizeof "SDIO3_D3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D4[sizeof "SDIO3_D4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D5[sizeof "SDIO3_D5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D6[sizeof "SDIO3_D6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO3_D7[sizeof "SDIO3_D7"]; +#endif #if defined(IPCHW_PADMUX_V1) char SDIO_CARD_DETECT[sizeof "SDIO_CARD_DETECT"]; #endif @@ -4489,9 +5227,27 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char SDIO_CDZ_MODE_3[sizeof "SDIO_CDZ_MODE_3"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_CLK[sizeof "SDIO_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_CMD[sizeof "SDIO_CMD"]; +#endif #if defined(IPCHW_PADMUX_V1) char SDIO_CWPR[sizeof "SDIO_CWPR"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_D0[sizeof "SDIO_D0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_D1[sizeof "SDIO_D1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_D2[sizeof "SDIO_D2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SDIO_D3[sizeof "SDIO_D3"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char SDIO_MODE[sizeof "SDIO_MODE"]; #endif @@ -4543,11 +5299,41 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V5) char SENSOR1_VS[sizeof "SENSOR1_VS"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR2_12BITS[sizeof "SENSOR2_12BITS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR2_CCIR8BITS[sizeof "SENSOR2_CCIR8BITS"]; +#endif #if defined(IPCHW_PADMUX_V5) char SENSOR2_CLK[sizeof "SENSOR2_CLK"]; #endif -#if defined(IPCHW_PADMUX_V5) - char SENSOR3_CLK[sizeof "SENSOR3_CLK"]; +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR2_LVDS_VDHD[sizeof "SENSOR2_LVDS_VDHD"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR2_MCLK_2ND[sizeof "SENSOR2_MCLK_2ND"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR2_SN3_MCLK[sizeof "SENSOR2_SN3_MCLK"]; +#endif +#if defined(IPCHW_PADMUX_V5) + char SENSOR3_CLK[sizeof "SENSOR3_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_12BITS[sizeof "SENSOR_12BITS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_12BITS_2ND[sizeof "SENSOR_12BITS_2ND"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_CCIR16BITS[sizeof "SENSOR_CCIR16BITS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_CCIR8BITS[sizeof "SENSOR_CCIR8BITS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_CCIR_2[sizeof "SENSOR_CCIR_2"]; #endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) char SENSOR_CLK[sizeof "SENSOR_CLK"]; @@ -4555,6 +5341,21 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) char SENSOR_HS[sizeof "SENSOR_HS"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_LVDS_VDHD[sizeof "SENSOR_LVDS_VDHD"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_LVDS_VDHD2[sizeof "SENSOR_LVDS_VDHD2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_MCLK[sizeof "SENSOR_MCLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_MCLK2[sizeof "SENSOR_MCLK2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SENSOR_MCLK_2ND[sizeof "SENSOR_MCLK_2ND"]; +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) char SENSOR_RSTN[sizeof "SENSOR_RSTN"]; #endif @@ -4804,6 +5605,30 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char SPI1_SDO[sizeof "SPI1_SDO"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_1_CLK[sizeof "SPI2_1_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_1_CS[sizeof "SPI2_1_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_1_DI[sizeof "SPI2_1_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_1_DO[sizeof "SPI2_1_DO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_2_CLK[sizeof "SPI2_2_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_2_CS[sizeof "SPI2_2_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_2_DI[sizeof "SPI2_2_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI2_2_DO[sizeof "SPI2_2_DO"]; +#endif #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char SPI2_CSN[sizeof "SPI2_CSN"]; #endif @@ -4822,6 +5647,42 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char SPI2_SDO[sizeof "SPI2_SDO"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_1_CLK[sizeof "SPI3_1_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_1_CS[sizeof "SPI3_1_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_1_DI[sizeof "SPI3_1_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_1_DO[sizeof "SPI3_1_DO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_2_CLK[sizeof "SPI3_2_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_2_CS[sizeof "SPI3_2_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_2_DI[sizeof "SPI3_2_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_2_DO[sizeof "SPI3_2_DO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_3_CLK[sizeof "SPI3_3_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_3_CS[sizeof "SPI3_3_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_3_DI[sizeof "SPI3_3_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI3_3_DO[sizeof "SPI3_3_DO"]; +#endif #if defined(IPCHW_PADMUX_V3A) char SPI3_CSN[sizeof "SPI3_CSN"]; #endif @@ -4864,6 +5725,30 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char SPIWPN_MODE[sizeof "SPIWPN_MODE"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_1_CLK[sizeof "SPI_1_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_1_CS[sizeof "SPI_1_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_1_DI[sizeof "SPI_1_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_1_DO[sizeof "SPI_1_DO"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_2_CLK[sizeof "SPI_2_CLK"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_2_CS[sizeof "SPI_2_CS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_2_DI[sizeof "SPI_2_DI"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_2_DO[sizeof "SPI_2_DO"]; +#endif #if defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4A) char SPI_3LINE_CSN[sizeof "SPI_3LINE_CSN"]; #endif @@ -4882,6 +5767,9 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V5) char SPI_3WIRE_DATA[sizeof "SPI_3WIRE_DATA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SPI_CH3_RDY[sizeof "SPI_CH3_RDY"]; +#endif #if defined(IPCHW_PADMUX_3536C) char SPI_CSN0[sizeof "SPI_CSN0"]; #endif @@ -4933,6 +5821,24 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V5) char SPI_TFT_DATA[sizeof "SPI_TFT_DATA"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK2_1[sizeof "SP_CLK2_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK2_2[sizeof "SP_CLK2_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK2_3[sizeof "SP_CLK2_3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK_1[sizeof "SP_CLK_1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK_2[sizeof "SP_CLK_2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char SP_CLK_3[sizeof "SP_CLK_3"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char SR00_CTRL_MODE[sizeof "SR00_CTRL_MODE"]; #endif @@ -5179,6 +6085,33 @@ struct padmux_names { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) char SYS_RSTN_OUT[sizeof "SYS_RSTN_OUT"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO0[sizeof "S_GPIO0"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO1[sizeof "S_GPIO1"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO2[sizeof "S_GPIO2"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO3[sizeof "S_GPIO3"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO4[sizeof "S_GPIO4"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO5[sizeof "S_GPIO5"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO6[sizeof "S_GPIO6"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO7[sizeof "S_GPIO7"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char S_GPIO8[sizeof "S_GPIO8"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char TCK[sizeof "TCK"]; #endif @@ -5275,6 +6208,63 @@ struct padmux_names { #if defined(IPCHW_PADMUX_INGENIC) char TMS[sizeof "TMS"]; #endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_AGPIO[sizeof "TOP_AGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_CGPIO[sizeof "TOP_CGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_DGPIO[sizeof "TOP_DGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_DSIGPIO[sizeof "TOP_DSIGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_HGPIO[sizeof "TOP_HGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_LGPIO[sizeof "TOP_LGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_PGPIO[sizeof "TOP_PGPIO"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG0[sizeof "TOP_REG0"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG1[sizeof "TOP_REG1"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG10[sizeof "TOP_REG10"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG2[sizeof "TOP_REG2"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG3[sizeof "TOP_REG3"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG4[sizeof "TOP_REG4"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG5[sizeof "TOP_REG5"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG6[sizeof "TOP_REG6"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG7[sizeof "TOP_REG7"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG8[sizeof "TOP_REG8"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_REG9[sizeof "TOP_REG9"]; +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) + char TOP_SGPIO[sizeof "TOP_SGPIO"]; +#endif #if defined(IPCHW_PADMUX_SSTAR) char TTL16_MODE_1[sizeof "TTL16_MODE_1"]; #endif @@ -5386,6 +6376,42 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char UART1_TXD[sizeof "UART1_TXD"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_1_CTS[sizeof "UART2_1_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_1_RTS[sizeof "UART2_1_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_1_RX[sizeof "UART2_1_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_1_TX[sizeof "UART2_1_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_2_CTS[sizeof "UART2_2_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_2_RTS[sizeof "UART2_2_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_2_RX[sizeof "UART2_2_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_2_TX[sizeof "UART2_2_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_3_CTS[sizeof "UART2_3_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_3_RTS[sizeof "UART2_3_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_3_RX[sizeof "UART2_3_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART2_3_TX[sizeof "UART2_3_TX"]; +#endif #if defined(IPCHW_PADMUX_INGENIC) char UART2_CTS[sizeof "UART2_CTS"]; #endif @@ -5425,6 +6451,54 @@ struct padmux_names { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) char UART2_TXD[sizeof "UART2_TXD"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_1_CTS[sizeof "UART3_1_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_1_RTS[sizeof "UART3_1_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_1_RX[sizeof "UART3_1_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_1_TX[sizeof "UART3_1_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_2_CTS[sizeof "UART3_2_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_2_RTS[sizeof "UART3_2_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_2_RX[sizeof "UART3_2_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_2_TX[sizeof "UART3_2_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_3_CTS[sizeof "UART3_3_CTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_3_RTS[sizeof "UART3_3_RTS"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_3_RX[sizeof "UART3_3_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_3_TX[sizeof "UART3_3_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_4_RX[sizeof "UART3_4_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_4_TX[sizeof "UART3_4_TX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_5_RX[sizeof "UART3_5_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART3_5_TX[sizeof "UART3_5_TX"]; +#endif #if defined(IPCHW_PADMUX_V4A) char UART3_CTSN[sizeof "UART3_CTSN"]; #endif @@ -5455,6 +6529,12 @@ struct padmux_names { #if defined(IPCHW_PADMUX_SSTAR) char UART_IS_GPIO_0[sizeof "UART_IS_GPIO_0"]; #endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART_RX[sizeof "UART_RX"]; +#endif +#if defined(IPCHW_PADMUX_NOVATEK) + char UART_TX[sizeof "UART_TX"]; +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) char UPDATE_MODE[sizeof "UPDATE_MODE"]; #endif @@ -6094,6 +7174,15 @@ static inline const char *padmux_name(uint16_t off) { return (const char *)&padmux_names + off; } +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_A_GPIO0 ((uint16_t)offsetof(struct padmux_names, A_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_A_GPIO1 ((uint16_t)offsetof(struct padmux_names, A_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_A_GPIO2 ((uint16_t)offsetof(struct padmux_names, A_GPIO2)) +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) #define PMX_BOOTROM_SEL ((uint16_t)offsetof(struct padmux_names, BOOTROM_SEL)) #endif @@ -6154,6 +7243,75 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) #define PMX_CS2 ((uint16_t)offsetof(struct padmux_names, CS2)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO0 ((uint16_t)offsetof(struct padmux_names, C_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO1 ((uint16_t)offsetof(struct padmux_names, C_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO10 ((uint16_t)offsetof(struct padmux_names, C_GPIO10)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO11 ((uint16_t)offsetof(struct padmux_names, C_GPIO11)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO12 ((uint16_t)offsetof(struct padmux_names, C_GPIO12)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO13 ((uint16_t)offsetof(struct padmux_names, C_GPIO13)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO14 ((uint16_t)offsetof(struct padmux_names, C_GPIO14)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO15 ((uint16_t)offsetof(struct padmux_names, C_GPIO15)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO16 ((uint16_t)offsetof(struct padmux_names, C_GPIO16)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO17 ((uint16_t)offsetof(struct padmux_names, C_GPIO17)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO18 ((uint16_t)offsetof(struct padmux_names, C_GPIO18)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO19 ((uint16_t)offsetof(struct padmux_names, C_GPIO19)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO2 ((uint16_t)offsetof(struct padmux_names, C_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO20 ((uint16_t)offsetof(struct padmux_names, C_GPIO20)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO21 ((uint16_t)offsetof(struct padmux_names, C_GPIO21)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO22 ((uint16_t)offsetof(struct padmux_names, C_GPIO22)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO3 ((uint16_t)offsetof(struct padmux_names, C_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO4 ((uint16_t)offsetof(struct padmux_names, C_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO5 ((uint16_t)offsetof(struct padmux_names, C_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO6 ((uint16_t)offsetof(struct padmux_names, C_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO7 ((uint16_t)offsetof(struct padmux_names, C_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO8 ((uint16_t)offsetof(struct padmux_names, C_GPIO8)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_C_GPIO9 ((uint16_t)offsetof(struct padmux_names, C_GPIO9)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_DLA_EJ_MODE_1 ((uint16_t)offsetof(struct padmux_names, DLA_EJ_MODE_1)) #endif @@ -6163,6 +7321,33 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_DLA_EJ_MODE_3 ((uint16_t)offsetof(struct padmux_names, DLA_EJ_MODE_3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMCLK_1 ((uint16_t)offsetof(struct padmux_names, DMCLK_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMCLK_2 ((uint16_t)offsetof(struct padmux_names, DMCLK_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMCLK_3 ((uint16_t)offsetof(struct padmux_names, DMCLK_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT0_1 ((uint16_t)offsetof(struct padmux_names, DMDAT0_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT0_2 ((uint16_t)offsetof(struct padmux_names, DMDAT0_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT0_3 ((uint16_t)offsetof(struct padmux_names, DMDAT0_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT1_1 ((uint16_t)offsetof(struct padmux_names, DMDAT1_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT1_2 ((uint16_t)offsetof(struct padmux_names, DMDAT1_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DMDAT1_3 ((uint16_t)offsetof(struct padmux_names, DMDAT1_3)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_DMIC_4CH_MODE_1 ((uint16_t)offsetof(struct padmux_names, DMIC_4CH_MODE_1)) #endif @@ -6286,6 +7471,39 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_DSI_D3P ((uint16_t)offsetof(struct padmux_names, DSI_D3P)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO0 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO1 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO10 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO10)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO2 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO3 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO4 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO5 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO6 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO7 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO8 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO8)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_DSI_GPIO9 ((uint16_t)offsetof(struct padmux_names, DSI_GPIO9)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_DVP_D10 ((uint16_t)offsetof(struct padmux_names, DVP_D10)) #endif @@ -6319,6 +7537,30 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) #define PMX_DVP_VSYNC ((uint16_t)offsetof(struct padmux_names, DVP_VSYNC)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO0 ((uint16_t)offsetof(struct padmux_names, D_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO1 ((uint16_t)offsetof(struct padmux_names, D_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO2 ((uint16_t)offsetof(struct padmux_names, D_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO3 ((uint16_t)offsetof(struct padmux_names, D_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO4 ((uint16_t)offsetof(struct padmux_names, D_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO5 ((uint16_t)offsetof(struct padmux_names, D_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO6 ((uint16_t)offsetof(struct padmux_names, D_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_D_GPIO7 ((uint16_t)offsetof(struct padmux_names, D_GPIO7)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_EJ_MODE_1 ((uint16_t)offsetof(struct padmux_names, EJ_MODE_1)) #endif @@ -6415,6 +7657,15 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) #define PMX_EPHY_RSTN ((uint16_t)offsetof(struct padmux_names, EPHY_RSTN)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_EXTPHYCLK ((uint16_t)offsetof(struct padmux_names, ETH_EXTPHYCLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_LED1 ((uint16_t)offsetof(struct padmux_names, ETH_LED1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_LED2 ((uint16_t)offsetof(struct padmux_names, ETH_LED2)) +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) #define PMX_ETH_LINK_ACT_LED ((uint16_t)offsetof(struct padmux_names, ETH_LINK_ACT_LED)) #endif @@ -6424,6 +7675,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) #define PMX_ETH_LINK_STA_LED ((uint16_t)offsetof(struct padmux_names, ETH_LINK_STA_LED)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_MDIO ((uint16_t)offsetof(struct padmux_names, ETH_MDIO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_MDIO_2 ((uint16_t)offsetof(struct padmux_names, ETH_MDIO_2)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_ETH_MODE ((uint16_t)offsetof(struct padmux_names, ETH_MODE)) #endif @@ -6436,6 +7693,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_ETH_MODE_3 ((uint16_t)offsetof(struct padmux_names, ETH_MODE_3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_RMII ((uint16_t)offsetof(struct padmux_names, ETH_RMII)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_ETH_RMII_2 ((uint16_t)offsetof(struct padmux_names, ETH_RMII_2)) +#endif #if defined(IPCHW_PADMUX_3536D) #define PMX_ETH_SPD_LED ((uint16_t)offsetof(struct padmux_names, ETH_SPD_LED)) #endif @@ -6451,6 +7714,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_FMC_STARTUP_DISABLE ((uint16_t)offsetof(struct padmux_names, FMC_STARTUP_DISABLE)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_CLK ((uint16_t)offsetof(struct padmux_names, FSPI_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_CS ((uint16_t)offsetof(struct padmux_names, FSPI_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_DI ((uint16_t)offsetof(struct padmux_names, FSPI_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_DO ((uint16_t)offsetof(struct padmux_names, FSPI_DO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_HOLD ((uint16_t)offsetof(struct padmux_names, FSPI_HOLD)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_FSPI_WP ((uint16_t)offsetof(struct padmux_names, FSPI_WP)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_FUART_2W_MODE_1 ((uint16_t)offsetof(struct padmux_names, FUART_2W_MODE_1)) #endif @@ -6913,6 +8194,42 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4A) #define PMX_HDMI_SDA ((uint16_t)offsetof(struct padmux_names, HDMI_SDA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO0 ((uint16_t)offsetof(struct padmux_names, H_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO1 ((uint16_t)offsetof(struct padmux_names, H_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO10 ((uint16_t)offsetof(struct padmux_names, H_GPIO10)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO11 ((uint16_t)offsetof(struct padmux_names, H_GPIO11)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO2 ((uint16_t)offsetof(struct padmux_names, H_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO3 ((uint16_t)offsetof(struct padmux_names, H_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO4 ((uint16_t)offsetof(struct padmux_names, H_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO5 ((uint16_t)offsetof(struct padmux_names, H_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO6 ((uint16_t)offsetof(struct padmux_names, H_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO7 ((uint16_t)offsetof(struct padmux_names, H_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO8 ((uint16_t)offsetof(struct padmux_names, H_GPIO8)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_H_GPIO9 ((uint16_t)offsetof(struct padmux_names, H_GPIO9)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_I2C0_MODE_1 ((uint16_t)offsetof(struct padmux_names, I2C0_MODE_1)) #endif @@ -6979,6 +8296,18 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_I2C1_SDA ((uint16_t)offsetof(struct padmux_names, I2C1_SDA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C2_1_SCL ((uint16_t)offsetof(struct padmux_names, I2C2_1_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C2_1_SDA ((uint16_t)offsetof(struct padmux_names, I2C2_1_SDA)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C2_2_SCL ((uint16_t)offsetof(struct padmux_names, I2C2_2_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C2_2_SDA ((uint16_t)offsetof(struct padmux_names, I2C2_2_SDA)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_I2C2_MODE_1 ((uint16_t)offsetof(struct padmux_names, I2C2_MODE_1)) #endif @@ -7009,6 +8338,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_I2C2_SDA ((uint16_t)offsetof(struct padmux_names, I2C2_SDA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_1_SCL ((uint16_t)offsetof(struct padmux_names, I2C3_1_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_1_SDA ((uint16_t)offsetof(struct padmux_names, I2C3_1_SDA)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_2_SCL ((uint16_t)offsetof(struct padmux_names, I2C3_2_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_2_SDA ((uint16_t)offsetof(struct padmux_names, I2C3_2_SDA)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_3_SCL ((uint16_t)offsetof(struct padmux_names, I2C3_3_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C3_3_SDA ((uint16_t)offsetof(struct padmux_names, I2C3_3_SDA)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_I2C3_PA ((uint16_t)offsetof(struct padmux_names, I2C3_PA)) #endif @@ -7048,12 +8395,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_I2C7_SDA ((uint16_t)offsetof(struct padmux_names, I2C7_SDA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C_2_SCL ((uint16_t)offsetof(struct padmux_names, I2C_2_SCL)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C_2_SDA ((uint16_t)offsetof(struct padmux_names, I2C_2_SDA)) +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) #define PMX_I2C_SCL ((uint16_t)offsetof(struct padmux_names, I2C_SCL)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C_SCL_1 ((uint16_t)offsetof(struct padmux_names, I2C_SCL_1)) +#endif #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) #define PMX_I2C_SDA ((uint16_t)offsetof(struct padmux_names, I2C_SDA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2C_SDA_1 ((uint16_t)offsetof(struct padmux_names, I2C_SDA_1)) +#endif #if defined(IPCHW_PADMUX_V5) #define PMX_I2S0_BCLK ((uint16_t)offsetof(struct padmux_names, I2S0_BCLK)) #endif @@ -7102,6 +8461,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V5) #define PMX_I2S_BCLK ((uint16_t)offsetof(struct padmux_names, I2S_BCLK)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_BCLK_1 ((uint16_t)offsetof(struct padmux_names, I2S_BCLK_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_BCLK_2 ((uint16_t)offsetof(struct padmux_names, I2S_BCLK_2)) +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) #define PMX_I2S_BCLK_RX ((uint16_t)offsetof(struct padmux_names, I2S_BCLK_RX)) #endif @@ -7132,6 +8497,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_I2S_MCLK ((uint16_t)offsetof(struct padmux_names, I2S_MCLK)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_MCLK_1 ((uint16_t)offsetof(struct padmux_names, I2S_MCLK_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_MCLK_2 ((uint16_t)offsetof(struct padmux_names, I2S_MCLK_2)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_I2S_MODE_1 ((uint16_t)offsetof(struct padmux_names, I2S_MODE_1)) #endif @@ -7174,6 +8545,18 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_I2S_RX_MODE_4 ((uint16_t)offsetof(struct padmux_names, I2S_RX_MODE_4)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SDATAI_1 ((uint16_t)offsetof(struct padmux_names, I2S_SDATAI_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SDATAI_2 ((uint16_t)offsetof(struct padmux_names, I2S_SDATAI_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SDATAO_1 ((uint16_t)offsetof(struct padmux_names, I2S_SDATAO_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SDATAO_2 ((uint16_t)offsetof(struct padmux_names, I2S_SDATAO_2)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_I2S_SDTI ((uint16_t)offsetof(struct padmux_names, I2S_SDTI)) #endif @@ -7186,6 +8569,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_I2S_SD_TX ((uint16_t)offsetof(struct padmux_names, I2S_SD_TX)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SYNC_1 ((uint16_t)offsetof(struct padmux_names, I2S_SYNC_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_I2S_SYNC_2 ((uint16_t)offsetof(struct padmux_names, I2S_SYNC_2)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_I2S_TX_MODE_1 ((uint16_t)offsetof(struct padmux_names, I2S_TX_MODE_1)) #endif @@ -7363,6 +8752,36 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_LSADC_CH3 ((uint16_t)offsetof(struct padmux_names, LSADC_CH3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO0 ((uint16_t)offsetof(struct padmux_names, L_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO1 ((uint16_t)offsetof(struct padmux_names, L_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO2 ((uint16_t)offsetof(struct padmux_names, L_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO3 ((uint16_t)offsetof(struct padmux_names, L_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO4 ((uint16_t)offsetof(struct padmux_names, L_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO5 ((uint16_t)offsetof(struct padmux_names, L_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO6 ((uint16_t)offsetof(struct padmux_names, L_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO7 ((uint16_t)offsetof(struct padmux_names, L_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO8 ((uint16_t)offsetof(struct padmux_names, L_GPIO8)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_L_GPIO9 ((uint16_t)offsetof(struct padmux_names, L_GPIO9)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_MAC0_RMII_P0_NORMAL ((uint16_t)offsetof(struct padmux_names, MAC0_RMII_P0_NORMAL)) #endif @@ -7447,6 +8866,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_V1) #define PMX_MII_TXER ((uint16_t)offsetof(struct padmux_names, MII_TXER)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_CLK0 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_CLK0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_CLK1 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_CLK1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_DAT0 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_DAT0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_DAT1 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_DAT1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_DAT2 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_DAT2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_MIPI_LVDS_DAT3 ((uint16_t)offsetof(struct padmux_names, MIPI_LVDS_DAT3)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_MIPI_PAD_IN_1 ((uint16_t)offsetof(struct padmux_names, MIPI_PAD_IN_1)) #endif @@ -9511,6 +10948,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) #define PMX_PFPUENS ((uint16_t)offsetof(struct padmux_names, PFPUENS)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT2_1 ((uint16_t)offsetof(struct padmux_names, PICNT2_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT2_2 ((uint16_t)offsetof(struct padmux_names, PICNT2_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT3_1 ((uint16_t)offsetof(struct padmux_names, PICNT3_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT3_2 ((uint16_t)offsetof(struct padmux_names, PICNT3_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT_1 ((uint16_t)offsetof(struct padmux_names, PICNT_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PICNT_2 ((uint16_t)offsetof(struct padmux_names, PICNT_2)) +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) #define PMX_PLL_TEST_OUT0 ((uint16_t)offsetof(struct padmux_names, PLL_TEST_OUT0)) #endif @@ -9724,6 +11179,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) #define PMX_PWM0 ((uint16_t)offsetof(struct padmux_names, PWM0)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM0_1 ((uint16_t)offsetof(struct padmux_names, PWM0_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM0_2 ((uint16_t)offsetof(struct padmux_names, PWM0_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM0_3 ((uint16_t)offsetof(struct padmux_names, PWM0_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM0_4 ((uint16_t)offsetof(struct padmux_names, PWM0_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM0_5 ((uint16_t)offsetof(struct padmux_names, PWM0_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM0_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM0_MODE_1)) #endif @@ -9760,6 +11230,18 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_PWM10 ((uint16_t)offsetof(struct padmux_names, PWM10)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM10_1 ((uint16_t)offsetof(struct padmux_names, PWM10_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM10_2 ((uint16_t)offsetof(struct padmux_names, PWM10_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM10_3 ((uint16_t)offsetof(struct padmux_names, PWM10_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM10_5 ((uint16_t)offsetof(struct padmux_names, PWM10_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM10_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM10_MODE_1)) #endif @@ -9775,6 +11257,36 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_PWM11 ((uint16_t)offsetof(struct padmux_names, PWM11)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM11_1 ((uint16_t)offsetof(struct padmux_names, PWM11_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM11_2 ((uint16_t)offsetof(struct padmux_names, PWM11_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM11_3 ((uint16_t)offsetof(struct padmux_names, PWM11_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM11_4 ((uint16_t)offsetof(struct padmux_names, PWM11_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM11_5 ((uint16_t)offsetof(struct padmux_names, PWM11_5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM1_1 ((uint16_t)offsetof(struct padmux_names, PWM1_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM1_2 ((uint16_t)offsetof(struct padmux_names, PWM1_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM1_3 ((uint16_t)offsetof(struct padmux_names, PWM1_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM1_4 ((uint16_t)offsetof(struct padmux_names, PWM1_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM1_5 ((uint16_t)offsetof(struct padmux_names, PWM1_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM1_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM1_MODE_1)) #endif @@ -9823,6 +11335,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM2 ((uint16_t)offsetof(struct padmux_names, PWM2)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM2_1 ((uint16_t)offsetof(struct padmux_names, PWM2_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM2_2 ((uint16_t)offsetof(struct padmux_names, PWM2_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM2_3 ((uint16_t)offsetof(struct padmux_names, PWM2_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM2_4 ((uint16_t)offsetof(struct padmux_names, PWM2_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM2_5 ((uint16_t)offsetof(struct padmux_names, PWM2_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM2_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM2_MODE_1)) #endif @@ -9847,6 +11374,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM3 ((uint16_t)offsetof(struct padmux_names, PWM3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM3_1 ((uint16_t)offsetof(struct padmux_names, PWM3_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM3_2 ((uint16_t)offsetof(struct padmux_names, PWM3_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM3_3 ((uint16_t)offsetof(struct padmux_names, PWM3_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM3_4 ((uint16_t)offsetof(struct padmux_names, PWM3_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM3_5 ((uint16_t)offsetof(struct padmux_names, PWM3_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM3_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM3_MODE_1)) #endif @@ -9871,6 +11413,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM4 ((uint16_t)offsetof(struct padmux_names, PWM4)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM4_1 ((uint16_t)offsetof(struct padmux_names, PWM4_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM4_2 ((uint16_t)offsetof(struct padmux_names, PWM4_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM4_3 ((uint16_t)offsetof(struct padmux_names, PWM4_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM4_4 ((uint16_t)offsetof(struct padmux_names, PWM4_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM4_5 ((uint16_t)offsetof(struct padmux_names, PWM4_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM4_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM4_MODE_1)) #endif @@ -9895,6 +11452,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM5 ((uint16_t)offsetof(struct padmux_names, PWM5)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM5_1 ((uint16_t)offsetof(struct padmux_names, PWM5_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM5_2 ((uint16_t)offsetof(struct padmux_names, PWM5_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM5_3 ((uint16_t)offsetof(struct padmux_names, PWM5_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM5_4 ((uint16_t)offsetof(struct padmux_names, PWM5_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM5_5 ((uint16_t)offsetof(struct padmux_names, PWM5_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM5_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM5_MODE_1)) #endif @@ -9919,6 +11491,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM6 ((uint16_t)offsetof(struct padmux_names, PWM6)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM6_1 ((uint16_t)offsetof(struct padmux_names, PWM6_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM6_2 ((uint16_t)offsetof(struct padmux_names, PWM6_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM6_3 ((uint16_t)offsetof(struct padmux_names, PWM6_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM6_4 ((uint16_t)offsetof(struct padmux_names, PWM6_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM6_5 ((uint16_t)offsetof(struct padmux_names, PWM6_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM6_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM6_MODE_1)) #endif @@ -9943,6 +11530,21 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) #define PMX_PWM7 ((uint16_t)offsetof(struct padmux_names, PWM7)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM7_1 ((uint16_t)offsetof(struct padmux_names, PWM7_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM7_2 ((uint16_t)offsetof(struct padmux_names, PWM7_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM7_3 ((uint16_t)offsetof(struct padmux_names, PWM7_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM7_4 ((uint16_t)offsetof(struct padmux_names, PWM7_4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM7_5 ((uint16_t)offsetof(struct padmux_names, PWM7_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM7_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM7_MODE_1)) #endif @@ -9967,6 +11569,18 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_PWM8 ((uint16_t)offsetof(struct padmux_names, PWM8)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM8_1 ((uint16_t)offsetof(struct padmux_names, PWM8_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM8_2 ((uint16_t)offsetof(struct padmux_names, PWM8_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM8_3 ((uint16_t)offsetof(struct padmux_names, PWM8_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM8_5 ((uint16_t)offsetof(struct padmux_names, PWM8_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM8_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM8_MODE_1)) #endif @@ -9994,6 +11608,18 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_PWM9 ((uint16_t)offsetof(struct padmux_names, PWM9)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM9_1 ((uint16_t)offsetof(struct padmux_names, PWM9_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM9_2 ((uint16_t)offsetof(struct padmux_names, PWM9_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM9_3 ((uint16_t)offsetof(struct padmux_names, PWM9_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_PWM9_5 ((uint16_t)offsetof(struct padmux_names, PWM9_5)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_PWM9_MODE_1 ((uint16_t)offsetof(struct padmux_names, PWM9_MODE_1)) #endif @@ -10090,9 +11716,96 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_VENDOR_INGENIC) && !defined(STANDALONE_LIBRARY) #define PMX_PZPAT1S ((uint16_t)offsetof(struct padmux_names, PZPAT1S)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO0 ((uint16_t)offsetof(struct padmux_names, P_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO1 ((uint16_t)offsetof(struct padmux_names, P_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO10 ((uint16_t)offsetof(struct padmux_names, P_GPIO10)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO11 ((uint16_t)offsetof(struct padmux_names, P_GPIO11)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO12 ((uint16_t)offsetof(struct padmux_names, P_GPIO12)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO13 ((uint16_t)offsetof(struct padmux_names, P_GPIO13)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO14 ((uint16_t)offsetof(struct padmux_names, P_GPIO14)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO15 ((uint16_t)offsetof(struct padmux_names, P_GPIO15)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO16 ((uint16_t)offsetof(struct padmux_names, P_GPIO16)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO17 ((uint16_t)offsetof(struct padmux_names, P_GPIO17)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO18 ((uint16_t)offsetof(struct padmux_names, P_GPIO18)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO19 ((uint16_t)offsetof(struct padmux_names, P_GPIO19)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO2 ((uint16_t)offsetof(struct padmux_names, P_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO20 ((uint16_t)offsetof(struct padmux_names, P_GPIO20)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO21 ((uint16_t)offsetof(struct padmux_names, P_GPIO21)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO22 ((uint16_t)offsetof(struct padmux_names, P_GPIO22)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO23 ((uint16_t)offsetof(struct padmux_names, P_GPIO23)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO24 ((uint16_t)offsetof(struct padmux_names, P_GPIO24)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO25 ((uint16_t)offsetof(struct padmux_names, P_GPIO25)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO3 ((uint16_t)offsetof(struct padmux_names, P_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO4 ((uint16_t)offsetof(struct padmux_names, P_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO5 ((uint16_t)offsetof(struct padmux_names, P_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO6 ((uint16_t)offsetof(struct padmux_names, P_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO7 ((uint16_t)offsetof(struct padmux_names, P_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO8 ((uint16_t)offsetof(struct padmux_names, P_GPIO8)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_P_GPIO9 ((uint16_t)offsetof(struct padmux_names, P_GPIO9)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_RD ((uint16_t)offsetof(struct padmux_names, RD)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_REMOTE_EXT ((uint16_t)offsetof(struct padmux_names, REMOTE_EXT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_REMOTE_IN_1 ((uint16_t)offsetof(struct padmux_names, REMOTE_IN_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_REMOTE_IN_2 ((uint16_t)offsetof(struct padmux_names, REMOTE_IN_2)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_RGB8_MODE_1 ((uint16_t)offsetof(struct padmux_names, RGB8_MODE_1)) #endif @@ -10345,6 +12058,9 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V4) #define PMX_RST_N ((uint16_t)offsetof(struct padmux_names, RST_N)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_RTC_CLK ((uint16_t)offsetof(struct padmux_names, RTC_CLK)) +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2A) #define PMX_RTC_TEST_CLK ((uint16_t)offsetof(struct padmux_names, RTC_TEST_CLK)) #endif @@ -10390,6 +12106,60 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536C) #define PMX_SATA_LED_N1 ((uint16_t)offsetof(struct padmux_names, SATA_LED_N1)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB2_CK ((uint16_t)offsetof(struct padmux_names, SB2_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB2_CS ((uint16_t)offsetof(struct padmux_names, SB2_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB2_DAT ((uint16_t)offsetof(struct padmux_names, SB2_DAT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_1_CK ((uint16_t)offsetof(struct padmux_names, SB3_1_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_1_CS ((uint16_t)offsetof(struct padmux_names, SB3_1_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_1_DAT ((uint16_t)offsetof(struct padmux_names, SB3_1_DAT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_2_CK ((uint16_t)offsetof(struct padmux_names, SB3_2_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_2_CS ((uint16_t)offsetof(struct padmux_names, SB3_2_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_2_DAT ((uint16_t)offsetof(struct padmux_names, SB3_2_DAT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_3_CK ((uint16_t)offsetof(struct padmux_names, SB3_3_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_3_CS ((uint16_t)offsetof(struct padmux_names, SB3_3_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB3_3_DAT ((uint16_t)offsetof(struct padmux_names, SB3_3_DAT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB4_CK ((uint16_t)offsetof(struct padmux_names, SB4_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB4_CS ((uint16_t)offsetof(struct padmux_names, SB4_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB4_DAT ((uint16_t)offsetof(struct padmux_names, SB4_DAT)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB_CK ((uint16_t)offsetof(struct padmux_names, SB_CK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB_CS ((uint16_t)offsetof(struct padmux_names, SB_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SB_DAT ((uint16_t)offsetof(struct padmux_names, SB_DAT)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_SD0 ((uint16_t)offsetof(struct padmux_names, SD0)) #endif @@ -10534,6 +12304,54 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V3) #define PMX_SDIO2_CDATA3 ((uint16_t)offsetof(struct padmux_names, SDIO2_CDATA3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_CLK ((uint16_t)offsetof(struct padmux_names, SDIO2_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_CMD ((uint16_t)offsetof(struct padmux_names, SDIO2_CMD)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_D0 ((uint16_t)offsetof(struct padmux_names, SDIO2_D0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_D1 ((uint16_t)offsetof(struct padmux_names, SDIO2_D1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_D2 ((uint16_t)offsetof(struct padmux_names, SDIO2_D2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO2_D3 ((uint16_t)offsetof(struct padmux_names, SDIO2_D3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_CLK ((uint16_t)offsetof(struct padmux_names, SDIO3_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_CMD ((uint16_t)offsetof(struct padmux_names, SDIO3_CMD)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D0 ((uint16_t)offsetof(struct padmux_names, SDIO3_D0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D1 ((uint16_t)offsetof(struct padmux_names, SDIO3_D1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D2 ((uint16_t)offsetof(struct padmux_names, SDIO3_D2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D3 ((uint16_t)offsetof(struct padmux_names, SDIO3_D3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D4 ((uint16_t)offsetof(struct padmux_names, SDIO3_D4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D5 ((uint16_t)offsetof(struct padmux_names, SDIO3_D5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D6 ((uint16_t)offsetof(struct padmux_names, SDIO3_D6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO3_D7 ((uint16_t)offsetof(struct padmux_names, SDIO3_D7)) +#endif #if defined(IPCHW_PADMUX_V1) #define PMX_SDIO_CARD_DETECT ((uint16_t)offsetof(struct padmux_names, SDIO_CARD_DETECT)) #endif @@ -10567,9 +12385,27 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_SDIO_CDZ_MODE_3 ((uint16_t)offsetof(struct padmux_names, SDIO_CDZ_MODE_3)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_CLK ((uint16_t)offsetof(struct padmux_names, SDIO_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_CMD ((uint16_t)offsetof(struct padmux_names, SDIO_CMD)) +#endif #if defined(IPCHW_PADMUX_V1) #define PMX_SDIO_CWPR ((uint16_t)offsetof(struct padmux_names, SDIO_CWPR)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_D0 ((uint16_t)offsetof(struct padmux_names, SDIO_D0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_D1 ((uint16_t)offsetof(struct padmux_names, SDIO_D1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_D2 ((uint16_t)offsetof(struct padmux_names, SDIO_D2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SDIO_D3 ((uint16_t)offsetof(struct padmux_names, SDIO_D3)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_SDIO_MODE ((uint16_t)offsetof(struct padmux_names, SDIO_MODE)) #endif @@ -10621,18 +12457,63 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V5) #define PMX_SENSOR1_VS ((uint16_t)offsetof(struct padmux_names, SENSOR1_VS)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR2_12BITS ((uint16_t)offsetof(struct padmux_names, SENSOR2_12BITS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR2_CCIR8BITS ((uint16_t)offsetof(struct padmux_names, SENSOR2_CCIR8BITS)) +#endif #if defined(IPCHW_PADMUX_V5) #define PMX_SENSOR2_CLK ((uint16_t)offsetof(struct padmux_names, SENSOR2_CLK)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR2_LVDS_VDHD ((uint16_t)offsetof(struct padmux_names, SENSOR2_LVDS_VDHD)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR2_MCLK_2ND ((uint16_t)offsetof(struct padmux_names, SENSOR2_MCLK_2ND)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR2_SN3_MCLK ((uint16_t)offsetof(struct padmux_names, SENSOR2_SN3_MCLK)) +#endif #if defined(IPCHW_PADMUX_V5) #define PMX_SENSOR3_CLK ((uint16_t)offsetof(struct padmux_names, SENSOR3_CLK)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_12BITS ((uint16_t)offsetof(struct padmux_names, SENSOR_12BITS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_12BITS_2ND ((uint16_t)offsetof(struct padmux_names, SENSOR_12BITS_2ND)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_CCIR16BITS ((uint16_t)offsetof(struct padmux_names, SENSOR_CCIR16BITS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_CCIR8BITS ((uint16_t)offsetof(struct padmux_names, SENSOR_CCIR8BITS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_CCIR_2 ((uint16_t)offsetof(struct padmux_names, SENSOR_CCIR_2)) +#endif #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) #define PMX_SENSOR_CLK ((uint16_t)offsetof(struct padmux_names, SENSOR_CLK)) #endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) #define PMX_SENSOR_HS ((uint16_t)offsetof(struct padmux_names, SENSOR_HS)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_LVDS_VDHD ((uint16_t)offsetof(struct padmux_names, SENSOR_LVDS_VDHD)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_LVDS_VDHD2 ((uint16_t)offsetof(struct padmux_names, SENSOR_LVDS_VDHD2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_MCLK ((uint16_t)offsetof(struct padmux_names, SENSOR_MCLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_MCLK2 ((uint16_t)offsetof(struct padmux_names, SENSOR_MCLK2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SENSOR_MCLK_2ND ((uint16_t)offsetof(struct padmux_names, SENSOR_MCLK_2ND)) +#endif #if defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4) #define PMX_SENSOR_RSTN ((uint16_t)offsetof(struct padmux_names, SENSOR_RSTN)) #endif @@ -10882,6 +12763,30 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_SPI1_SDO ((uint16_t)offsetof(struct padmux_names, SPI1_SDO)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_1_CLK ((uint16_t)offsetof(struct padmux_names, SPI2_1_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_1_CS ((uint16_t)offsetof(struct padmux_names, SPI2_1_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_1_DI ((uint16_t)offsetof(struct padmux_names, SPI2_1_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_1_DO ((uint16_t)offsetof(struct padmux_names, SPI2_1_DO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_2_CLK ((uint16_t)offsetof(struct padmux_names, SPI2_2_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_2_CS ((uint16_t)offsetof(struct padmux_names, SPI2_2_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_2_DI ((uint16_t)offsetof(struct padmux_names, SPI2_2_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI2_2_DO ((uint16_t)offsetof(struct padmux_names, SPI2_2_DO)) +#endif #if defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_SPI2_CSN ((uint16_t)offsetof(struct padmux_names, SPI2_CSN)) #endif @@ -10900,6 +12805,42 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_SPI2_SDO ((uint16_t)offsetof(struct padmux_names, SPI2_SDO)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_1_CLK ((uint16_t)offsetof(struct padmux_names, SPI3_1_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_1_CS ((uint16_t)offsetof(struct padmux_names, SPI3_1_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_1_DI ((uint16_t)offsetof(struct padmux_names, SPI3_1_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_1_DO ((uint16_t)offsetof(struct padmux_names, SPI3_1_DO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_2_CLK ((uint16_t)offsetof(struct padmux_names, SPI3_2_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_2_CS ((uint16_t)offsetof(struct padmux_names, SPI3_2_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_2_DI ((uint16_t)offsetof(struct padmux_names, SPI3_2_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_2_DO ((uint16_t)offsetof(struct padmux_names, SPI3_2_DO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_3_CLK ((uint16_t)offsetof(struct padmux_names, SPI3_3_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_3_CS ((uint16_t)offsetof(struct padmux_names, SPI3_3_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_3_DI ((uint16_t)offsetof(struct padmux_names, SPI3_3_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI3_3_DO ((uint16_t)offsetof(struct padmux_names, SPI3_3_DO)) +#endif #if defined(IPCHW_PADMUX_V3A) #define PMX_SPI3_CSN ((uint16_t)offsetof(struct padmux_names, SPI3_CSN)) #endif @@ -10942,6 +12883,30 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_SPIWPN_MODE ((uint16_t)offsetof(struct padmux_names, SPIWPN_MODE)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_1_CLK ((uint16_t)offsetof(struct padmux_names, SPI_1_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_1_CS ((uint16_t)offsetof(struct padmux_names, SPI_1_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_1_DI ((uint16_t)offsetof(struct padmux_names, SPI_1_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_1_DO ((uint16_t)offsetof(struct padmux_names, SPI_1_DO)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_2_CLK ((uint16_t)offsetof(struct padmux_names, SPI_2_CLK)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_2_CS ((uint16_t)offsetof(struct padmux_names, SPI_2_CS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_2_DI ((uint16_t)offsetof(struct padmux_names, SPI_2_DI)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_2_DO ((uint16_t)offsetof(struct padmux_names, SPI_2_DO)) +#endif #if defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V4A) #define PMX_SPI_3LINE_CSN ((uint16_t)offsetof(struct padmux_names, SPI_3LINE_CSN)) #endif @@ -10960,6 +12925,9 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V5) #define PMX_SPI_3WIRE_DATA ((uint16_t)offsetof(struct padmux_names, SPI_3WIRE_DATA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SPI_CH3_RDY ((uint16_t)offsetof(struct padmux_names, SPI_CH3_RDY)) +#endif #if defined(IPCHW_PADMUX_3536C) #define PMX_SPI_CSN0 ((uint16_t)offsetof(struct padmux_names, SPI_CSN0)) #endif @@ -11011,6 +12979,24 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V5) #define PMX_SPI_TFT_DATA ((uint16_t)offsetof(struct padmux_names, SPI_TFT_DATA)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK2_1 ((uint16_t)offsetof(struct padmux_names, SP_CLK2_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK2_2 ((uint16_t)offsetof(struct padmux_names, SP_CLK2_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK2_3 ((uint16_t)offsetof(struct padmux_names, SP_CLK2_3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK_1 ((uint16_t)offsetof(struct padmux_names, SP_CLK_1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK_2 ((uint16_t)offsetof(struct padmux_names, SP_CLK_2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_SP_CLK_3 ((uint16_t)offsetof(struct padmux_names, SP_CLK_3)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_SR00_CTRL_MODE ((uint16_t)offsetof(struct padmux_names, SR00_CTRL_MODE)) #endif @@ -11257,6 +13243,33 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) #define PMX_SYS_RSTN_OUT ((uint16_t)offsetof(struct padmux_names, SYS_RSTN_OUT)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO0 ((uint16_t)offsetof(struct padmux_names, S_GPIO0)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO1 ((uint16_t)offsetof(struct padmux_names, S_GPIO1)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO2 ((uint16_t)offsetof(struct padmux_names, S_GPIO2)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO3 ((uint16_t)offsetof(struct padmux_names, S_GPIO3)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO4 ((uint16_t)offsetof(struct padmux_names, S_GPIO4)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO5 ((uint16_t)offsetof(struct padmux_names, S_GPIO5)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO6 ((uint16_t)offsetof(struct padmux_names, S_GPIO6)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO7 ((uint16_t)offsetof(struct padmux_names, S_GPIO7)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_S_GPIO8 ((uint16_t)offsetof(struct padmux_names, S_GPIO8)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_TCK ((uint16_t)offsetof(struct padmux_names, TCK)) #endif @@ -11353,6 +13366,63 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_INGENIC) #define PMX_TMS ((uint16_t)offsetof(struct padmux_names, TMS)) #endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_AGPIO ((uint16_t)offsetof(struct padmux_names, TOP_AGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_CGPIO ((uint16_t)offsetof(struct padmux_names, TOP_CGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_DGPIO ((uint16_t)offsetof(struct padmux_names, TOP_DGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_DSIGPIO ((uint16_t)offsetof(struct padmux_names, TOP_DSIGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_HGPIO ((uint16_t)offsetof(struct padmux_names, TOP_HGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_LGPIO ((uint16_t)offsetof(struct padmux_names, TOP_LGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_PGPIO ((uint16_t)offsetof(struct padmux_names, TOP_PGPIO)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG0 ((uint16_t)offsetof(struct padmux_names, TOP_REG0)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG1 ((uint16_t)offsetof(struct padmux_names, TOP_REG1)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG10 ((uint16_t)offsetof(struct padmux_names, TOP_REG10)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG2 ((uint16_t)offsetof(struct padmux_names, TOP_REG2)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG3 ((uint16_t)offsetof(struct padmux_names, TOP_REG3)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG4 ((uint16_t)offsetof(struct padmux_names, TOP_REG4)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG5 ((uint16_t)offsetof(struct padmux_names, TOP_REG5)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG6 ((uint16_t)offsetof(struct padmux_names, TOP_REG6)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG7 ((uint16_t)offsetof(struct padmux_names, TOP_REG7)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG8 ((uint16_t)offsetof(struct padmux_names, TOP_REG8)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_REG9 ((uint16_t)offsetof(struct padmux_names, TOP_REG9)) +#endif +#if defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY) +#define PMX_TOP_SGPIO ((uint16_t)offsetof(struct padmux_names, TOP_SGPIO)) +#endif #if defined(IPCHW_PADMUX_SSTAR) #define PMX_TTL16_MODE_1 ((uint16_t)offsetof(struct padmux_names, TTL16_MODE_1)) #endif @@ -11464,6 +13534,42 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_UART1_TXD ((uint16_t)offsetof(struct padmux_names, UART1_TXD)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_1_CTS ((uint16_t)offsetof(struct padmux_names, UART2_1_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_1_RTS ((uint16_t)offsetof(struct padmux_names, UART2_1_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_1_RX ((uint16_t)offsetof(struct padmux_names, UART2_1_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_1_TX ((uint16_t)offsetof(struct padmux_names, UART2_1_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_2_CTS ((uint16_t)offsetof(struct padmux_names, UART2_2_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_2_RTS ((uint16_t)offsetof(struct padmux_names, UART2_2_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_2_RX ((uint16_t)offsetof(struct padmux_names, UART2_2_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_2_TX ((uint16_t)offsetof(struct padmux_names, UART2_2_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_3_CTS ((uint16_t)offsetof(struct padmux_names, UART2_3_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_3_RTS ((uint16_t)offsetof(struct padmux_names, UART2_3_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_3_RX ((uint16_t)offsetof(struct padmux_names, UART2_3_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART2_3_TX ((uint16_t)offsetof(struct padmux_names, UART2_3_TX)) +#endif #if defined(IPCHW_PADMUX_INGENIC) #define PMX_UART2_CTS ((uint16_t)offsetof(struct padmux_names, UART2_CTS)) #endif @@ -11503,6 +13609,54 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_3536C) || defined(IPCHW_PADMUX_3536D) || defined(IPCHW_PADMUX_INGENIC) || defined(IPCHW_PADMUX_V1) || defined(IPCHW_PADMUX_V2) || defined(IPCHW_PADMUX_V2A) || defined(IPCHW_PADMUX_V3) || defined(IPCHW_PADMUX_V3A) || defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) || defined(IPCHW_PADMUX_V5) #define PMX_UART2_TXD ((uint16_t)offsetof(struct padmux_names, UART2_TXD)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_1_CTS ((uint16_t)offsetof(struct padmux_names, UART3_1_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_1_RTS ((uint16_t)offsetof(struct padmux_names, UART3_1_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_1_RX ((uint16_t)offsetof(struct padmux_names, UART3_1_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_1_TX ((uint16_t)offsetof(struct padmux_names, UART3_1_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_2_CTS ((uint16_t)offsetof(struct padmux_names, UART3_2_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_2_RTS ((uint16_t)offsetof(struct padmux_names, UART3_2_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_2_RX ((uint16_t)offsetof(struct padmux_names, UART3_2_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_2_TX ((uint16_t)offsetof(struct padmux_names, UART3_2_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_3_CTS ((uint16_t)offsetof(struct padmux_names, UART3_3_CTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_3_RTS ((uint16_t)offsetof(struct padmux_names, UART3_3_RTS)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_3_RX ((uint16_t)offsetof(struct padmux_names, UART3_3_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_3_TX ((uint16_t)offsetof(struct padmux_names, UART3_3_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_4_RX ((uint16_t)offsetof(struct padmux_names, UART3_4_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_4_TX ((uint16_t)offsetof(struct padmux_names, UART3_4_TX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_5_RX ((uint16_t)offsetof(struct padmux_names, UART3_5_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART3_5_TX ((uint16_t)offsetof(struct padmux_names, UART3_5_TX)) +#endif #if defined(IPCHW_PADMUX_V4A) #define PMX_UART3_CTSN ((uint16_t)offsetof(struct padmux_names, UART3_CTSN)) #endif @@ -11533,6 +13687,12 @@ static inline const char *padmux_name(uint16_t off) { #if defined(IPCHW_PADMUX_SSTAR) #define PMX_UART_IS_GPIO_0 ((uint16_t)offsetof(struct padmux_names, UART_IS_GPIO_0)) #endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART_RX ((uint16_t)offsetof(struct padmux_names, UART_RX)) +#endif +#if defined(IPCHW_PADMUX_NOVATEK) +#define PMX_UART_TX ((uint16_t)offsetof(struct padmux_names, UART_TX)) +#endif #if defined(IPCHW_PADMUX_V4) || defined(IPCHW_PADMUX_V4A) #define PMX_UPDATE_MODE ((uint16_t)offsetof(struct padmux_names, UPDATE_MODE)) #endif diff --git a/src/reginfo.c b/src/reginfo.c index f16e3c39..59f6f3a8 100644 --- a/src/reginfo.c +++ b/src/reginfo.c @@ -2,6 +2,8 @@ #include "chipid.h" #include "hal/hisi/hal_hisi.h" #include "hal/ingenic.h" +#include "hal/novatek.h" +#include "hal/novatek_gpio.h" #include "hal/sstar.h" #include "hal/sstar_gpio.h" #include "padmux.h" @@ -3394,6 +3396,9 @@ uint32_t gpio_windows_in_mapping(unsigned long off, unsigned long len, #ifdef IPCHW_VENDOR_SSTAR #include "hal/sstar_reginfo.h" #endif +#ifdef IPCHW_VENDOR_NOVATEK +#include "hal/novatek_reginfo.h" +#endif static int gpio_mux_by(const char *gpio_number, int func_num, const char *set_func); @@ -3401,6 +3406,9 @@ static int padmux_refuse(int code, const char *pad_spec, const char *func); static int sstar_gpio_getset(char **argv, bool set_op); static int sstar_gpio_scan_cmd(void); static char *sstar_gpio_possible_ircut(char *outbuf, size_t outlen); +static int novatek_gpio_getset(char **argv, bool set_op); +static int novatek_gpio_scan_cmd(void); +static char *novatek_gpio_possible_ircut(char *outbuf, size_t outlen); static void show_function(const uint16_t *func, unsigned val) { for (size_t i = 0; func[i]; i++) @@ -3412,7 +3420,9 @@ static void show_function(const uint16_t *func, unsigned val) { * On SigmaStar and Ingenic it is the GPIO controller's own registers, which is * what those two lists have always been -- per-pad direction and level on one, * the port INT/MSK/PAT/pull/drive registers on the other. Useful, and not - * pin-mux: `reginfo --pads` is the pin-mux view on every family. */ + * pin-mux: `reginfo --pads` is the pin-mux view on every family. On Novatek + * it is the TOP block's pad-mux registers whole, the raw form of what + * `--pads` decodes. */ static const muxctrl_reg_t **dump_regs_by_chip(void) { switch (chip_generation) { #ifdef IPCHW_VENDOR_SSTAR @@ -3433,6 +3443,10 @@ static const muxctrl_reg_t **dump_regs_by_chip(void) { case T31: /* Three, and the list these two have always dumped. */ return T31_regs; +#endif +#ifdef IPCHW_VENDOR_NOVATEK + case CHIP_NA51089: + return NA51089_regs; #endif default: break; @@ -3459,8 +3473,9 @@ static uint32_t dump_mask(void) { case T23: case T31: case T40: - /* Not a selector at all: these are whole 32-bit controller registers - * and every bit of them is worth printing. */ + case CHIP_NA51089: + /* Not a selector at all: these are whole 32-bit registers and every + * bit of them is worth printing. */ return 0xffffffff; default: return padmux_func_mask(); @@ -3661,6 +3676,8 @@ static int gpio_manipulate(char **argv, bool set_op) { getchipname(); if (sstar_gpio_supported()) return sstar_gpio_getset(argv, set_op); + if (novatek_gpio_supported()) + return novatek_gpio_getset(argv, set_op); if (!get_chip_gpio_adress(&GPIO_Base, &GPIO_Offset, &GPIO_Groups)) { fprintf(stderr, "Chip is not supported\n"); return EXIT_FAILURE; @@ -3779,14 +3796,15 @@ static int padmux_refuse(int code, const char *pad_spec, const char *func) { * the two other vendors have. */ static int gpio_mux_by(const char *gpio_number, int func_num, const char *set_func) { + /* Detection first: how a pad may be spelled is the SoC's to say. */ + getchipname(); + int pad = padmux_parse_pad(gpio_number); if (pad < 0) { fprintf(stderr, "Not a GPIO number: %s\n", gpio_number); return EXIT_FAILURE; } - getchipname(); - const char *want = set_func; if (func_num >= 0) { ipchw_padmux_t rows[64]; @@ -3966,6 +3984,8 @@ char *gpio_possible_ircut(char *outbuf, size_t outlen) { *outbuf = 0; if (sstar_gpio_supported()) return sstar_gpio_possible_ircut(outbuf, outlen); + if (novatek_gpio_supported()) + return novatek_gpio_possible_ircut(outbuf, outlen); if (!get_chip_gpio_adress(&GPIO_Base, &GPIO_Offset, &GPIO_Groups)) return NULL; @@ -4211,6 +4231,158 @@ static int sstar_gpio_scan_cmd(void) { return EXIT_SUCCESS; } +/* `gpio get/set ` on Novatek: the pad is the Linux GPIO number or its + * kernel name, and its bit sits in one word of each of the controller's four + * banks. The mux line is printed first, as on the other vendors. */ +static int novatek_gpio_getset(char **argv, bool set_op) { + const char *gpio_num = argv[1]; + + gpio_mux_by(gpio_num, -1, NULL); + + int pad = padmux_parse_pad(gpio_num); + if (!novatek_gpio_valid(pad)) { + fprintf(stderr, "GPIO %s is out of range\n", gpio_num); + return EXIT_FAILURE; + } + + if (set_op) { + /* Refused before any register changes. */ + unsigned level; + if (!parse_gpio_level(argv[2], &level)) { + fprintf(stderr, "Level '%s' is not 0 or 1\n", argv[2]); + return EXIT_FAILURE; + } + if (!novatek_gpio_write(pad, level)) { + fprintf(stderr, "write reg %#x error\n", + novatek_gpio_reg(pad, NVT_GPIO_DIR)); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } + + bool output, level; + if (!novatek_gpio_read(pad, &output, &level)) { + fprintf(stderr, "read reg %#x error\n", + novatek_gpio_reg(pad, NVT_GPIO_DATA)); + return EXIT_FAILURE; + } + printf("%d\n", level); + return EXIT_SUCCESS; +} + +/* Whether a daemon holds the GPIO controller in a /dev/mem mapping of its + * own. The four banks share one page. */ +static bool novatek_gpio_streamer_mapped(void) { + uint32_t base, len; + if (!novatek_gpio_window(&base, &len)) + return false; + return dev_mem_windows_marked(base, len, 1) != 0; +} + +/* The IR-cut question on Novatek, the SigmaStar heuristic over Linux GPIO + * numbers: output pads muxed to GPIO, all of them when a daemon holds the + * controller and drives at most two, otherwise the ones standing low. */ +static char *novatek_gpio_possible_ircut(char *outbuf, size_t outlen) { + if (ipchw_padmux_by_prefix("", NULL, 0) < 0) + return NULL; + + bool level[NVT_GPIO_NPADS], is_out[NVT_GPIO_NPADS]; + memset(is_out, 0, sizeof(is_out)); + + int output_count = 0; + for (int pad = 0; pad < NVT_GPIO_NPADS; pad++) { + if (!novatek_gpio_valid(pad) || !padmux_pad_is_gpio(pad)) + continue; + bool output; + if (!novatek_gpio_read(pad, &output, &level[pad])) { + fprintf(stderr, "Error at %#x\n", + novatek_gpio_reg(pad, NVT_GPIO_DATA)); + return NULL; + } + is_out[pad] = output; + if (output) + output_count++; + } + + bool streamer = novatek_gpio_streamer_mapped(); + char *ptr = outbuf; + + for (int pad = 0; pad < NVT_GPIO_NPADS; pad++) { + if (!is_out[pad]) + continue; + if (streamer && output_count > 2) + continue; + if (!streamer && level[pad]) + continue; + + int nlen = snprintf(ptr, outlen, ",%d", pad); + outlen -= nlen; + ptr += nlen; + } + + if (strlen(outbuf) > 0) + return outbuf + 1; + return NULL; +} + +/* `gpio scan` on Novatek: watch every pad muxed to plain GPIO, one line per + * pad, by its kernel name and number. */ +static int novatek_gpio_scan_cmd(void) { + ipchw_padmux_t rows[NVT_GPIO_NPADS]; + int n = ipchw_padmux_by_func(IPCHW_PADMUX_GPIO, rows, NVT_GPIO_NPADS); + if (n < 0) { + fprintf(stderr, "Platform is not supported\n"); + return EXIT_FAILURE; + } + if (n > NVT_GPIO_NPADS) + n = NVT_GPIO_NPADS; + + bool watch[NVT_GPIO_NPADS], state[NVT_GPIO_NPADS]; + const char *names[NVT_GPIO_NPADS]; + memset(watch, 0, sizeof(watch)); + + for (int i = 0; i < n; i++) { + int pad = rows[i].gpio_pad; + if (!novatek_gpio_valid(pad) || !padmux_pad_is_gpio(pad)) + continue; + bool output; + if (!novatek_gpio_read(pad, &output, &state[pad])) { + fprintf(stderr, "Error at %#x\n", + novatek_gpio_reg(pad, NVT_GPIO_DATA)); + return EXIT_FAILURE; + } + watch[pad] = true; + names[pad] = rows[i].gpio_name; + printf("Pad:%3d %-11s Data:0x%08x bit %2d = %d, Dir:%s\n", pad, + names[pad], novatek_gpio_reg(pad, NVT_GPIO_DATA), pad & 31, + state[pad], output ? "Output" : "Input"); + } + + print_line(86); + printf("Waiting for while something changes...\n"); + while (1) { + for (int pad = 0; pad < NVT_GPIO_NPADS; pad++) { + if (!watch[pad]) + continue; + bool output, level; + if (!novatek_gpio_read(pad, &output, &level)) { + /* A /dev/mem that has stopped reading will not start again. */ + fprintf(stderr, "Error at %#x\n", + novatek_gpio_reg(pad, NVT_GPIO_DATA)); + return EXIT_FAILURE; + } + if (level == state[pad]) + continue; + printf("Pad:%d %s, %d --> %d, Dir:%s\n", pad, names[pad], + state[pad], level, output ? "Output" : "Input"); + state[pad] = level; + } + usleep(100000); + } + + return EXIT_SUCCESS; +} + static int gpio_scan_cmd() { int GPIO_Groups = 0; size_t GPIO_Base = 0; @@ -4225,6 +4397,8 @@ static int gpio_scan_cmd() { getchipname(); if (sstar_gpio_supported()) return sstar_gpio_scan_cmd(); + if (novatek_gpio_supported()) + return novatek_gpio_scan_cmd(); if (!get_chip_gpio_adress(&GPIO_Base, &GPIO_Offset, &GPIO_Groups)) return EXIT_FAILURE; diff --git a/src/reginfo_test.c b/src/reginfo_test.c index 2ee97256..0d42082c 100644 --- a/src/reginfo_test.c +++ b/src/reginfo_test.c @@ -12,6 +12,8 @@ #include "chipid.h" #include "hal/hisi/hal_hisi.h" #include "hal/ingenic.h" +#include "hal/novatek.h" +#include "hal/novatek_gpio.h" #include "hal/sstar.h" #include "hal/sstar_gpio.h" #include "ipchw.h" @@ -892,6 +894,164 @@ static void test_ingenic(void) { } #endif +#ifdef IPCHW_PADMUX_NOVATEK +/* The NA51089 TOP block, as the vendor's top_reg.h lays it out. */ +#define NVT_REG3 0xF001000Cu /* SENSOR[2:0] */ +#define NVT_REG5 0xF0010014u /* I2C3[7:6], ETH_MDIO[3:2], ETH[31:30] */ +#define NVT_REG9 0xF0010024u /* UART2[3:2], UART2_CTSRTS[9:8] */ +#define NVT_CGPIO 0xF00100A0u /* gate bits: 1 keeps the pad a GPIO */ +#define NVT_HGPIO 0xF00100D8u +#define NVT_DSIGPIO 0xF00100E8u + +/* Every pad a GPIO and every field 0: what pinmux_init() starts from. */ +static void nvt_boot_state(void) { + regs_reset(); + for (uint32_t r = 0xF00100A0u; r <= 0xF00100E8u; r += 8) + fake_write(r, 0xFFFFFFFFu, 32); +} + +static void test_novatek(void) { + puts("Novatek: a location field per peripheral and a gate bit per pad"); + as_chip(CHIP_NA51089, "NT98566"); + + /* The kernel's own numbers and names; "5_2" is HiSilicon's banking and + * would land on a different pad. */ + CHECK(padmux_parse_pad("P_GPIO22") == 0x20 + 22); + CHECK(padmux_parse_pad("MC17") == 17); + CHECK(padmux_parse_pad("hsi_gpio9") == 0xA0 + 9); + CHECK(padmux_parse_pad("DSI_GPIO9") == 0xE0 + 9); + CHECK(padmux_parse_pad("54") == 54); + CHECK(padmux_parse_pad("5_2") == -1); + CHECK(padmux_parse_pad("P_GPIO") == -1); + CHECK(padmux_parse_pad("P_GPIO22x") == -1); + + /* P_GPIO22 is I2C3's SCL on its first location, REG5 I2C3 = 1. */ + ipchw_padmux_t rows[16]; + int n = ipchw_padmux_by_pad(54, rows, 16); + CHECK(n >= 2); + CHECK((rows[0].flags & IPCHW_PADMUX_F_GPIO) != 0); + CHECK(rows[0].gpio_name && !strcmp(rows[0].gpio_name, "P_GPIO22")); + CHECK(rows[0].address == 0xF00100A8u && rows[0].func_mask == 1u << 22); + bool found = false; + for (int i = 1; i < n && i < 16; i++) { + if (strcmp(rows[i].func_name, "I2C3_1_SCL") != 0) + continue; + found = true; + CHECK(rows[i].address == NVT_REG5); + CHECK(rows[i].func_mask == 0xC0); + CHECK(rows[i].func == 0x40); + /* A field and a gate: never one write. */ + CHECK((rows[i].flags & IPCHW_PADMUX_F_RMW) == 0); + } + CHECK(found); + + /* A pad the package does not bond out is not a pad. */ + ipchw_padmux_t r; + CHECK(ipchw_padmux_get(23, &r) == IPCHW_PADMUX_NO_PAD); /* C_GPIO23 */ + CHECK(ipchw_padmux_get(0x80 + 8, &r) == IPCHW_PADMUX_NO_PAD); + + puts("Novatek: the field, then the gate, and a moved field orphans"); + nvt_boot_state(); + CHECK(ipchw_padmux_get(11, &r) == 1 && (r.flags & IPCHW_PADMUX_F_GPIO)); + /* pinmux_config_i2c(), PIN_I2C_CFG_CH3_2ND_PINMUX: CGPIO_11 and 12 to + * function, I2C3 = I2C_3_ENUM_I2C_2ND. */ + CHECK(ipchw_padmux_set(11, "I2C3_2_SCL") == 0); + CHECK((reg_of(NVT_REG5) & 0xC0) == 0x80); + CHECK(reg_of(NVT_CGPIO) == ~(1u << 11)); + CHECK(ipchw_padmux_get(11, &r) == 1 && !strcmp(r.func_name, "I2C3_2_SCL")); + /* Only the pad asked about: SDA's gate is its own business. */ + CHECK(ipchw_padmux_get(12, &r) == 1 && (r.flags & IPCHW_PADMUX_F_GPIO)); + + /* Moving I2C3 to P_GPIO21 leaves C_GPIO11 handed over to nothing. */ + CHECK(ipchw_padmux_set(0x20 + 21, "I2C3_1_SDA") == 0); + CHECK((reg_of(NVT_REG5) & 0xC0) == 0x40); + CHECK(ipchw_padmux_get(11, &r) == 0); + + /* Back to GPIO is the gate bit and nothing else. */ + uint32_t reg5 = reg_of(NVT_REG5); + CHECK(ipchw_padmux_set(11, IPCHW_PADMUX_GPIO) == 0); + CHECK(reg_of(NVT_CGPIO) == 0xFFFFFFFFu); + CHECK(reg_of(NVT_REG5) == reg5); + + puts("Novatek: a modifier needs its location too"); + nvt_boot_state(); + /* pinmux_config_uart(), CH2 | CH2_2ND | CH2_CTSRTS: CGPIO_13 and 14, + * UART2_CTSRTS = UART_CTSRTS_PINMUX, UART2 = UART2_ENUM_2ND_PINMUX. */ + CHECK(ipchw_padmux_set(13, "UART2_2_CTS") == 0); + CHECK(reg_of(NVT_REG9) == ((2u << 2) | (1u << 8))); + CHECK(ipchw_padmux_get(13, &r) == 1 && !strcmp(r.func_name, "UART2_2_CTS")); + + puts("Novatek: parallel sensor data holds through the gate"); + nvt_boot_state(); + fake_write(NVT_REG3, 1, 32); /* SENSOR_ENUM_12BITS_1ST */ + CHECK(ipchw_padmux_get(0xA0 + 4, &r) == 1); + CHECK(!strcmp(r.func_name, "SENSOR_12BITS")); + /* MIPI lane: the gate cleared and no field. */ + nvt_boot_state(); + fake_write(NVT_HGPIO, ~(3u << 4), 32); + CHECK(ipchw_padmux_get(0xA0 + 4, &r) == 1); + CHECK(!strcmp(r.func_name, "MIPI_LVDS_CLK0")); + /* GPIO on a parallel data pad has to take the sensor mode down with it: + * the gate alone does not stop the bus. */ + nvt_boot_state(); + fake_write(NVT_REG3, 1, 32); + CHECK(ipchw_padmux_set(0xA0 + 4, IPCHW_PADMUX_GPIO) == 0); + CHECK((reg_of(NVT_REG3) & 7) == 0); + CHECK(ipchw_padmux_get(0xA0 + 4, &r) == 1 && + (r.flags & IPCHW_PADMUX_F_GPIO)); + + puts("Novatek: RMII and MDIO overlap on DSI_GPIO9 and RMII wins"); + nvt_boot_state(); + fake_write(NVT_DSIGPIO, ~(1u << 9), 32); + fake_write(NVT_REG5, (1u << 30) | (1u << 2), 32); /* ETH RMII, ETH_MDIO */ + CHECK(ipchw_padmux_get(0xE0 + 9, &r) == 1 && + !strcmp(r.func_name, "ETH_RMII")); + /* The internal PHY's MDIO there means RMII has to go. */ + CHECK(ipchw_padmux_set(0xE0 + 9, "ETH_MDIO") == 0); + CHECK(reg_of(NVT_REG5) == (1u << 2)); + CHECK(ipchw_padmux_get(0xE0 + 9, &r) == 1 && + !strcmp(r.func_name, "ETH_MDIO")); + /* And back: of RMII's two claims the one that changes least, leaving + * ETH_MDIO where it is. */ + CHECK(ipchw_padmux_set(0xE0 + 9, "ETH_RMII") == 0); + CHECK(reg_of(NVT_REG5) == ((1u << 30) | (1u << 2))); + CHECK(ipchw_padmux_get(0xE0 + 9, &r) == 1 && + !strcmp(r.func_name, "ETH_RMII")); + + CHECK(ipchw_padmux_set(54, "UART2_2_TX") == IPCHW_PADMUX_NO_FUNC); + as_chip(T31, "T31"); +} +#endif + +#ifdef IPCHW_VENDOR_NOVATEK +/* The controller's four banks, one word per pad group, as the vendor's + * gpio-nvt-na51089.c addresses them. */ +static void test_novatek_gpio_regs(void) { + puts("Novatek: GPIO controller registers"); + as_chip(CHIP_NA51089, "NT98566"); + + CHECK(novatek_gpio_supported()); + CHECK(novatek_gpio_reg(0, NVT_GPIO_DATA) == 0xF0070000u); + CHECK(novatek_gpio_reg(0x20 + 22, NVT_GPIO_DATA) == 0xF0070004u); + CHECK(novatek_gpio_reg(0x20 + 22, NVT_GPIO_DIR) == 0xF0070024u); + CHECK(novatek_gpio_reg(0xE0 + 10, NVT_GPIO_SET) == 0xF007005Cu); + CHECK(novatek_gpio_reg(0xE0 + 10, NVT_GPIO_CLR) == 0xF007007Cu); + CHECK(novatek_gpio_valid(22) && !novatek_gpio_valid(23)); + CHECK(novatek_gpio_valid(0x80 + 7) && !novatek_gpio_valid(0x80 + 8)); + CHECK(!novatek_gpio_valid(0xE0 + 11) && !novatek_gpio_valid(-1)); + CHECK(novatek_gpio_reg(23, NVT_GPIO_DATA) == 0); + CHECK(novatek_gpio_reg(0, 0x10) == 0); + + uint32_t base, len; + CHECK(novatek_gpio_window(&base, &len)); + CHECK(base == 0xF0070000u && len == 0x80); + + as_chip(0, "none"); + CHECK(!novatek_gpio_supported()); + CHECK(novatek_gpio_reg(0, NVT_GPIO_DATA) == 0); +} +#endif + /* Everything the table says a pad can be, put on it and read back. * * This is the whole self-consistency proof, and the only one the families @@ -1081,6 +1241,9 @@ static void test_table_integrity(void) { {T23, "T23N"}, {T31, "T31"}, {T40, "T40"}, +#endif +#ifdef IPCHW_PADMUX_NOVATEK + {CHIP_NA51089, "NT98566"}, #endif }; @@ -1225,6 +1388,12 @@ int main(void) { test_gpio_windows_in_mapping(); #ifdef IPCHW_PADMUX_INGENIC test_ingenic(); +#endif +#ifdef IPCHW_PADMUX_NOVATEK + test_novatek(); +#endif +#ifdef IPCHW_VENDOR_NOVATEK + test_novatek_gpio_regs(); #endif test_refusals_do_not_exit(); test_table_integrity(); diff --git a/tools/gen_novatek_padmux.py b/tools/gen_novatek_padmux.py new file mode 100755 index 00000000..5175b868 --- /dev/null +++ b/tools/gen_novatek_padmux.py @@ -0,0 +1,1437 @@ +#!/usr/bin/env python3 +"""Generate src/hal/novatek_padmux.h from a Novatek NA51089 SDK. + +WHAT THE HARDWARE DOES + +A NA51089 pad carries a peripheral when two things agree: + + * a per-PERIPHERAL field in the TOP block (0xF0010000 + 0x00..0x24) whose + value picks which group of pads the peripheral uses -- REG5[7:6] is I2C3, + and 1, 2, 3 put it on P_GPIO21/22, C_GPIO11/12 or DSI_GPIO8/9; + * a per-PAD gate bit in one of eight bitmaps at TOP + 0xA0..0xE8, where 1 + keeps the pad a GPIO and 0 hands it to whichever function claims it. + +Not every claim needs the gate. The parallel and CCIR sensor modes put pixel +data on the HSI pads, and the vendor driver writes GPIO_ID_EMUM_GPIO to their +gate bits while doing it. Those claims are "ungated": they hold whatever the +gate says. + +WHERE THE TABLE COMES FROM + +There is no datasheet and no pin list in the SDK. The truth is the vendor's +kernel driver, drivers/pinctrl/novatek/na51089/na51089_pinmux_host.c, and in +it the pinmux_config_() functions: one per peripheral group, each +taking a bitmask of PIN__CFG_* options and writing fields and gate +bits. They are 2200 lines of nested if/else-if/switch with conflict checks +interleaved -- too irregular to read with patterns, and too easy to misread +by hand. So this RUNS them: + + 1. The config functions and the globals they use are cut out of host.c, + every `top_regN.bit.FIELD = value;` is wrapped in a macro that logs the + register, the field's mask, the value and which assignment it was, and + the result is compiled on the host against the SDK's own top_reg.h, + top.h and na51089_pinmux.h, with empty stand-ins for the Linux headers. + 2. Every function is called with every combination of up to four of its + option bits, from the state pinmux_init() leaves: every field 0, every + gate bit 1. A call that returns an error is a combination the vendor + refuses, and is dropped. + 3. The source is read for one thing only: which braces enclose each + assignment, and which options the `if (config & ...)` or `case` that + opens each of them names. A gate write's CONDITIONS are the field + writes the same call made in the blocks enclosing it: SEN_MCLK=1 for + S_GPIO0 under PIN_SENSOR_CFG_MCLK, and not the sensor mode the same call + happened to select in a sibling block. + +A pad's NAME comes from the `@PAD[NAME]|...` and `&&PAD[NAME]` annotations on +the option enums in top.h, looked up for the enclosing options innermost +first, then from build/nvt-tools/nvt_pinctrl_tool/top.csv, which is the only +source for SDIO and NAND. A pad nothing names gets its option's own name -- +SENSOR_12BITS, MIPI_LVDS_CLK0, ETH_RMII -- which names a bus rather than a +wire, the way SigmaStar's I2C1_MODE_3 does. + +WHAT IS CHECKED + +src/hal/novatek_padmux.c answers "what is this pad" by walking the pad's +claims in table order and taking the first whose conditions all hold and +which is ungated or has its gate bit clear. Claims are sorted most conditions +first. That rule is replayed here over every state the vendor code produced: + + * a pad the call gave a function must read as that function -- unless a + later write in the same call moved its field away (MCLK_2ND after MCLK + leaves S_GPIO0 cleared and claimed by nothing), in which case it must + read as nothing; + * a pad the call left alone must not read as anything; + * where two claims hold at once the vendor code says which one it meant, + by the gate write that came last, and a claim specific to that overlap + is added: ETH_RMII on DSI_GPIO9 when ETH_MDIO is also set. + +Every annotation is also checked against the code: a pad an annotation names +for an option whose code never touches it is a disagreement between two +vendor sources, fatal unless ANNOTATION_ERRATA says which one is right. + +USAGE + tools/gen_novatek_padmux.py --sdk > src/hal/novatek_padmux.h + tools/gen_novatek_padmux.py --sdk --verify src/hal/novatek_padmux.h + tools/gen_novatek_padmux.py --selftest + +Needs a host C compiler (cc, or $CC). +""" + +import argparse +import collections +import difflib +import os +import re +import shutil +import subprocess +import sys +import tempfile + +# The groups, in the vendor's pinmux_config_hdl[] order, with the enum type +# of each one's options. LCD and TV are not here: they only stash their +# argument for pinmux_select_primary_lcd() and write no register. +FUNCS = [ + ("sdio", "PIN_SDIO_CFG"), + ("sdio2", "PIN_SDIO_CFG"), + ("sdio3", "PIN_SDIO_CFG"), + ("nand", "PIN_NAND_CFG"), + ("sensor", "PIN_SENSOR_CFG"), + ("sensor2", "PIN_SENSOR2_CFG"), + ("mipi_lvds", "PIN_MIPI_LVDS_CFG"), + ("i2c", "PIN_I2C_CFG"), + ("sif", "PIN_SIF_CFG"), + ("uart", "PIN_UART_CFG"), + ("spi", "PIN_SPI_CFG"), + ("sdp", "PIN_SDP_CFG"), + ("remote", "PIN_REMOTE_CFG"), + ("pwm", "PIN_PWM_CFG"), + ("pwm2", "PIN_PWM_CFG2"), + ("ccnt", "PIN_CCNT_CFG"), + ("audio", "PIN_AUDIO_CFG"), + ("eth", "PINMUX_ETH_CFG"), + ("misc", "PINMUX_MISC_CFG"), +] + +# The groups whose GPIO writes are claims rather than releases. sensor and +# sensor2 write GPIO_ID_EMUM_GPIO to the pads they put pixel data on; every +# other GPIO write gives a pad back (SPI's DI-only mode releases CLK, DO and +# CS that way). +UNGATED_FUNCS = {"sensor", "sensor2"} + +# The most options combined in one call. UART2's DIR/OE on its 2nd location +# is CH2 | CH2_2ND | CH2_DIROE; a fourth leaves room for one more on top. +MAX_COMBO = 4 + +# Pad groups: (gate register offset, kernel prefix, Linux GPIO base, the +# nvt-gpio.h macro saying how many are bonded out). A pad's gate register is +# GATE_REGS[pad >> 5]; src/hal/novatek_padmux.c relies on that. +GROUPS = [ + (0xA0, "C_GPIO", 0x00, "C_GPIO_NUM"), + (0xA8, "P_GPIO", 0x20, "P_GPIO_NUM"), + (0xB0, "S_GPIO", 0x40, "S_GPIO_NUM"), + (0xB8, "L_GPIO", 0x60, "L_GPIO_NUM"), + (0xD0, "D_GPIO", 0x80, "D_GPIO_NUM"), + (0xD8, "H_GPIO", 0xA0, "H_GPIO_NUM"), + (0xE0, "A_GPIO", 0xC0, "A_GPIO_NUM"), + (0xE8, "DSI_GPIO", 0xE0, "DSI_GPIO_NUM"), +] +GATE_REGS = {g[0]: g for g in GROUPS} + +# How the two name sources spell a pad, and the kernel macro it is. +PAD_SPELLINGS = [ + (re.compile(r"^MC(\d+)$"), "C_GPIO"), + (re.compile(r"^C_GPIO(\d+)$"), "C_GPIO"), + (re.compile(r"^P_GPIO(\d+)$"), "P_GPIO"), + (re.compile(r"^S_GPIO(\d+)$"), "S_GPIO"), + (re.compile(r"^L_GPIO(\d+)$"), "L_GPIO"), + (re.compile(r"^D_GPIO(\d+)$"), "D_GPIO"), + (re.compile(r"^(?:HSI_GPIO|H_GPIO)(\d+)$"), "H_GPIO"), + (re.compile(r"^A_GPIO(\d+)$"), "A_GPIO"), + (re.compile(r"^DSI_GPIO(\d+)$"), "DSI_GPIO"), +] + +# Where the two vendor sources disagree with the code, and what was decided. +# Key: (option, pad as the source spells it). Value: the (option, pad) it +# means, or None to drop the annotation. +ANNOTATION_ERRATA = { + # top.csv only; top.h has P_GPIO19, and so does the code. + ("PIN_SIF_CFG_CH2_2ND_PINMUX", "P_GPIO29"): + ("PIN_SIF_CFG_CH2_2ND_PINMUX", "P_GPIO19"), + # top.h only; the code and top.csv both put PICNT2_1 on L_GPIO1. + ("PIN_PWM_CFG_CCNT2", "P_GPIO14"): ("PIN_PWM_CFG_CCNT2", "L_GPIO1"), + # pinmux_config_misc() tests PIN_SENSOR_CFG_SP2CLK_3RD where it means + # this option, so this option does nothing at all. The same pad and field + # are reached through the sensor group's SP2CLK_3RD, which top.h does not + # annotate; the name goes there. + ("PIN_MISC_CFG_SP2CLK_3RD", "D_GPIO4"): + ("PIN_SENSOR_CFG_SP2CLK_3RD", "D_GPIO4"), +} + +# One annotation: PAD[NAME]. The csv has unclosed brackets and stray +# parentheses; both are tolerated, and a name that still is not an +# identifier afterwards is refused. +ANNOT = re.compile(r"([A-Za-z_]+[0-9]+)\s*\[([^\]|,@&]+)\]?") + + +def die(msg): + raise SystemExit("gen_novatek_padmux: " + msg) + + +def norm_name(raw): + name = raw.strip().upper().replace("(BS)", "").rstrip(")").strip() + if not re.match(r"^[A-Z][A-Z0-9_]*$", name): + die("cannot use %r as a function name" % raw) + return name + + +def norm_pad(raw): + raw = raw.strip().upper() + for rx, prefix in PAD_SPELLINGS: + m = rx.match(raw) + if m: + return "%s%d" % (prefix, int(m.group(1))) + return None + + +def pad_number(name): + for _, prefix, base, _ in GROUPS: + m = re.match(r"^%s(\d+)$" % prefix, name) + if m: + return base + int(m.group(1)) + die("not a pad: %s" % name) + + +def option_label(option): + """PIN_SENSOR_CFG_12BITS -> SENSOR_12BITS.""" + m = re.match(r"^PIN_(\w+?)_CFG2?_(\w+)$", option) + if not m: + die("cannot make a name of %s" % option) + return "%s_%s" % (m.group(1), m.group(2)) + + +# ---------------------------------------------------------------- sources + + +class Sources: + """The SDK files this reads, located from the SDK root.""" + + def __init__(self, sdk): + kernel = os.path.join(sdk, "BSP", "linux-kernel") + self.drv = os.path.join(kernel, "drivers", "pinctrl", "novatek", + "na51089") + self.host_c = os.path.join(self.drv, "na51089_pinmux_host.c") + self.plat = os.path.join(kernel, "arch", "arm", "plat-novatek", + "include", "plat-na51089") + self.mach = os.path.join(kernel, "arch", "arm", "mach-nvt-ivot", + "include", "mach") + self.top_h = os.path.join(self.plat, "top.h") + self.gpio_h = os.path.join(self.plat, "nvt-gpio.h") + self.csv = os.path.join(sdk, "build", "nvt-tools", + "nvt_pinctrl_tool", "top.csv") + for path in (self.host_c, self.top_h, self.gpio_h, + os.path.join(self.mach, "rcw_macro.h")): + if not os.path.isfile(path): + die("not an NA51089 SDK: no %s" % path) + if not os.path.isfile(self.csv): + self.csv = None + + +def read(path): + with open(path, encoding="utf-8", errors="replace") as f: + return f.read() + + +def parse_enums(text): + """enum type -> [(member, value or None, trailing comment)].""" + out = {} + for m in re.finditer(r"typedef\s+enum\s*\{(.*?)\}\s*(\w+)\s*;", text, + re.S): + members = [] + for line in m.group(1).splitlines(): + mm = re.match(r"\s*([A-Z][A-Z0-9_]*)\s*(?:=\s*([^,/]+?))?\s*," + r"\s*(.*)$", line) + if not mm or mm.group(1).startswith("ENUM_DUMMY"): + continue + try: + val = int(mm.group(2), 0) if mm.group(2) else None + except ValueError: + val = None + members.append((mm.group(1), val, mm.group(3))) + out[m.group(2)] = members + return out + + +def option_bits(enums, enum_name): + """The options of one group that are a bit of their own, in order.""" + if enum_name not in enums: + die("top.h has no enum %s" % enum_name) + seen = set() + bits = [] + for name, val, _ in enums[enum_name]: + if val and val not in seen: + seen.add(val) + bits.append(name) + return bits + + +def annotations(enums, csv_text): + """{(func or None, option, pad): name} and the list of what was found. + + top.h annotations hold for every group that takes the option; the csv's + may be filed under one controller, because SDIO, SDIO2 and SDIO3 share + their option names and the csv lists each under a sub-row.""" + names = {} + found = [] + + def add(func, option, pad_raw, name_raw): + key = (option, pad_raw.strip().upper()) + if key in ANNOTATION_ERRATA: + if ANNOTATION_ERRATA[key] is None: + return + option, pad_raw = ANNOTATION_ERRATA[key] + pad = norm_pad(pad_raw) + if pad is None: + return # "LCD0~LCD10": a range, not a pad + names.setdefault((func, option, pad), norm_name(name_raw)) + found.append((option, pad)) + + for members in enums.values(): + for option, _, comment in members: + if option.startswith("PIN_"): + for part in re.split(r"@|&&", comment)[1:]: + for m in ANNOT.finditer(part): + add(None, option, m.group(1), m.group(2)) + + option = sub = None + for row in (csv_text or "").splitlines(): + cells = row.split(",", 2) + if cells[0].startswith("PIN_"): + option, sub = cells[0], None + elif cells[0] == "" and len(cells) > 2 and option: + sub = {"SDIO1": "sdio", "SDIO2": "sdio2", + "SDIO3": "sdio3"}.get(cells[1].strip()) + else: + option = None + continue + for m in ANNOT.finditer(cells[2] if len(cells) > 2 else ""): + pad = norm_pad(m.group(1)) + if pad is not None and (None, option, pad) in names: + continue # top.h is the cleaner of the two and wins + add(sub, option, m.group(1), m.group(2)) + return names, found + + +def bonded_pads(gpio_h_text): + pads = [] + for _, prefix, _, macro in GROUPS: + m = re.search(r"#define\s+%s\s+(\d+)" % macro, gpio_h_text) + if not m: + die("nvt-gpio.h has no %s" % macro) + pads.extend("%s%d" % (prefix, i) for i in range(int(m.group(1)))) + return pads + + +# ---------------------------------------------------------------- the code + +ASSIGN = re.compile(r"\b(top_reg\w+)\.bit\.(\w+)\s*=(?!=)\s*([^;]+);") +OTHER_WRITE = re.compile( + r"\btop_reg\w+\.(?:bit\.\w+|reg)\s*(?:[-+*/&|^]|<<|>>)?=(?!=)") +CASE = re.compile(r"\bcase\s+(PIN_\w+)\s*:") + +Rec = collections.namedtuple("Rec", "func path chain") + + +def blank(text): + """Comments and string literals as spaces, offsets unchanged -- a brace + in a pr_err() message is not a block.""" + def spaces(m): + return re.sub(r"[^\n]", " ", m.group(0)) + return re.sub(r'/\*.*?\*/|//[^\n]*|"(?:[^"\\\n]|\\.)*"', spaces, text, + flags=re.S) + + +def extract_function(text, name): + m = re.search(r"^static int %s\(uint32_t config\)\s*\{" % name, text, + re.M) + if not m: + die("host.c has no %s()" % name) + clean = blank(text) + depth = 0 + for i in range(m.end() - 1, len(text)): + if clean[i] == "{": + depth += 1 + elif clean[i] == "}": + depth -= 1 + if depth == 0: + return text[m.start():i + 1] + die("%s() never closes" % name) + + +def instrument(func, body, recs): + """`body` with every field assignment logged, and recs[] extended with + where each one sits: the blocks around it, and the options that open + them innermost first.""" + clean = blank(body) + tokens = [] + for i, ch in enumerate(clean): + if ch in "{}": + tokens.append((i, ch, None)) + for m in CASE.finditer(clean): + tokens.append((m.start(), "case", m.group(1))) + for m in ASSIGN.finditer(clean): + tokens.append((m.start(), "assign", m)) + tokens.sort(key=lambda t: t[0]) + + stack = [] # [block start, options in its header, current case] + boundary = 0 # where the current statement started + sites = {} + for pos, kind, arg in tokens: + if kind == "{": + header = clean[boundary:pos] + stack.append([pos, re.findall(r"\bPIN_\w+", header), None]) + boundary = pos + 1 + elif kind == "}": + if not stack: + die("%s(): unbalanced braces" % func) + stack.pop() + boundary = pos + 1 + elif kind == "case": + if stack: + stack[-1][2] = arg + else: + chain = [] + for _, opts, case in reversed(stack): + if case: + chain.append(case) + chain.extend(opts) + sites[pos] = Rec(func, tuple((func, s[0]) for s in stack), + tuple(chain)) + boundary = arg.end() + + out = [] + last = 0 + for m in ASSIGN.finditer(clean): + recs.append(sites[m.start()]) + out.append(body[last:m.start()]) + out.append("REC(%s, %s, %s, %d);" % (m.group(1), m.group(2), + body[m.start(3):m.end(3)], + len(recs) - 1)) + last = m.end() + out.append(body[last:]) + body = "".join(out) + + leftover = OTHER_WRITE.findall(blank(body)) + if leftover: + die("%s() writes a register a way this does not log: %s" + % (func, leftover[0])) + return body + + +PRELUDE = r""" +#include +#include +#include +#include +#include +typedef uint64_t u64; typedef int64_t s64; typedef uint32_t u32; +typedef int32_t s32; typedef uint16_t u16; typedef int16_t s16; +typedef uint8_t u8; typedef int8_t s8; +typedef struct { int unused; } spinlock_t; +struct device; struct seq_file; +#define __iomem +#include "na51089_pinmux.h" +#undef pr_err +#define pr_err(...) ((void)0) +#define pr_info(...) ((void)0) +#define pr_warn(...) ((void)0) +#define spin_lock_irqsave(l, f) ((void)(f)) +#define spin_unlock_irqrestore(l, f) ((void)(f)) +#define pad_set_pull_updown(p, t) ((void)0) + +static void rec(const void *reg, uint32_t mask, uint32_t val, int id); +#define REC(R, F, V, ID) do { \ + __typeof__(R) m_; memset(&m_, 0, sizeof m_); m_.bit.F = -1; \ + (R).bit.F = (V); rec(&(R), m_.reg, (R).reg & m_.reg, ID); \ +} while (0) +""" + + +def build_harness(src, enums, recs): + host = read(src.host_c) + start = host.index('#include "na51089_pinmux.h"') + start = host.index("\n", start) + 1 + end = host.index("struct nvt_pinctrl_info info_get_id") + region = host[start:end] + + unions = re.findall(r"^union\s+(TOP_REG\w+)\s+(top_reg\w+)\s*;", region, + re.M) + if not unions: + die("host.c declares no TOP register globals") + statics = re.findall( + r"^(?:static\s+)?(?:uint32_t|int|u32)\s+(\w+)\s*(?:\[[^\]]*\])*\s*=", + region, re.M) + + c = [PRELUDE, region] + # Every handler in the vendor's table has to exist for it to compile, + # LCD and TV included. + for name in re.findall(r"^static int (pinmux_config_\w+)\(uint32_t " + r"config\);", region, re.M): + func = name[len("pinmux_config_"):] + c.append(instrument(func, extract_function(host, name), recs)) + if not recs: + die("found no register writes to log") + + c.append("static const struct { const void *p; uint32_t ofs; } " + "REGS[] = {") + for utype, var in unions: + c.append(" {&%s, %s_OFS}," % (var, utype)) + c.append("};") + c.append(r""" +static char buf[1 << 16]; +static size_t blen; + +static void rec(const void *reg, uint32_t mask, uint32_t val, int id) { + const char *fmt = "W ? %x %x %d\n"; + uint32_t ofs = 0; + for (size_t i = 0; i < sizeof REGS / sizeof *REGS; i++) + if (REGS[i].p == reg) { + fmt = "W %x %x %x %d\n"; + ofs = REGS[i].ofs; + } + if (fmt[2] == '?') + blen += snprintf(buf + blen, sizeof buf - blen, fmt, mask, val, id); + else + blen += snprintf(buf + blen, sizeof buf - blen, fmt, ofs, mask, val, + id); + if (blen >= sizeof buf - 64) { + fprintf(stderr, "log overflow\n"); + _exit(1); + } +} +""") + # Every call starts from the same globals. + c.append("static void reset(void) {") + c.append(" static int saved;") + for i, var in enumerate(statics): + c.append(" static unsigned char s%d[sizeof %s];" % (i, var)) + c.append(" if (!saved) {") + for i, var in enumerate(statics): + c.append(" memcpy(s%d, &%s, sizeof %s);" % (i, var, var)) + c.append(" saved = 1;") + c.append(" }") + for i, var in enumerate(statics): + c.append(" memcpy(&%s, s%d, sizeof %s);" % (var, i, var)) + for utype, var in unions: + c.append(" %s.reg = %s;" % ( + var, "0xFFFFFFFFu" if "GPIO" in utype else "0")) + c.append("}") + + nfuncs = len(FUNCS) + for fi, (func, enum_name) in enumerate(FUNCS): + c.append("static const uint32_t bits%d[] = {%s};" + % (fi, ", ".join(option_bits(enums, enum_name)))) + c.append("static int (*const fns[])(uint32_t) = {%s};" % ", ".join( + "pinmux_config_%s" % f for f, _ in FUNCS)) + c.append("static const uint32_t *const bits[] = {%s};" % ", ".join( + "bits%d" % i for i in range(nfuncs))) + c.append("static const int nbits[] = {%s};" % ", ".join( + "sizeof bits%d / sizeof *bits%d" % (i, i) for i in range(nfuncs))) + c.append(r""" +/* One combination of one group: on its own, or -- when the vendor refuses + * it on its own -- after the first single option of another group that + * makes it acceptable. MIPI data lanes 1-3 want the sensor group in CSI + * mode first, and that is the only way to see them. */ +static void one(int fi, const int *idx, int k) { + uint32_t cfg = 0; + for (int i = 0; i < k; i++) + cfg |= bits[fi][idx[i]]; + reset(); + blen = 0; + int ret = fns[fi](cfg); + int pg = -1, pb = -1; + for (int g = 0; ret != 0 && g < %d; g++) { + if (g == fi) + continue; + for (int b = 0; ret != 0 && b < nbits[g]; b++) { + reset(); + blen = 0; + if (fns[g](bits[g][b]) != 0) + continue; + ret = fns[fi](cfg); + pg = g; + pb = b; + } + } + if (ret != 0) + return; + printf("R %%d", fi); + for (int i = 0; i < k; i++) + printf(" %%d", idx[i]); + printf("\n"); + if (pg >= 0) + printf("P %%d %%d\n", pg, pb); + fwrite(buf, 1, blen, stdout); + printf("E 0\n"); +} +""" % nfuncs) + c.append("int main(void) {") + for utype, var in unions: + c.append(' printf("U %%x %s\\n", %s_OFS);' % (var, utype)) + c.append(""" for (int fi = 0; fi < %d; fi++) { + const int n = nbits[fi]; + int idx[%d]; + for (int k = 1; k <= %d && k <= n; k++) { + for (int i = 0; i < k; i++) idx[i] = i; + for (;;) { + one(fi, idx, k); + int i = k - 1; + while (i >= 0 && idx[i] == n - k + i) i--; + if (i < 0) break; + idx[i]++; + for (int j = i + 1; j < k; j++) idx[j] = idx[j - 1] + 1; + } + } + }""" % (nfuncs, MAX_COMBO, MAX_COMBO)) + c.append(" return 0;") + c.append("}") + return "\n".join(c) + "\n" + + +SHIM_EMPTY = ["linux/types.h", "linux/irq.h", "linux/spinlock.h", + "linux/slab.h", "linux/of.h", "asm/types.h", "mach/nvt-io.h"] + + +def run_harness(src, enums, recs): + cc = os.environ.get("CC", "cc") + tmp = tempfile.mkdtemp(prefix="nvt_padmux_") + try: + shim = os.path.join(tmp, "shim") + for rel in SHIM_EMPTY: + path = os.path.join(shim, rel) + os.makedirs(os.path.dirname(path), exist_ok=True) + open(path, "w").close() + for name in ("rcw_macro.h", "nvt_type.h"): + path = os.path.join(src.mach, name) + if os.path.isfile(path): + shutil.copy(path, os.path.join(shim, "mach")) + os.symlink(src.plat, os.path.join(shim, "plat")) + + csrc = os.path.join(tmp, "harness.c") + with open(csrc, "w") as f: + f.write(build_harness(src, enums, recs)) + exe = os.path.join(tmp, "harness") + res = subprocess.run([cc, "-std=gnu99", "-w", "-O1", "-o", exe, csrc, + "-I", shim, "-I", src.drv], + capture_output=True, text=True) + if res.returncode != 0: + die("the harness does not compile:\n" + res.stderr[-4000:]) + res = subprocess.run([exe], capture_output=True, text=True) + if res.returncode != 0: + die("the harness failed: %s" % res.stderr[-2000:]) + return res.stdout + finally: + shutil.rmtree(tmp, ignore_errors=True) + + +# ---------------------------------------------------------------- analysis + +Field = collections.namedtuple("Field", "reg mask") + + +def field_shift(mask): + return (mask & -mask).bit_length() - 1 + + +class Run: + """One call: what it ended up writing, and where each write was.""" + + def __init__(self, func, opts): + self.func = func + self.opts = opts # option names, declaration order + self.prefix = None # another group's option called first + self.fields = {} # Field -> final value in place + self.blocks = {} # block -> {Field: last value written in it} + self.gates = {} # pad -> (0 function / 1 GPIO, rec id) + self.regs = None # register offset -> final value + + +def parse_runs(out, enums, recs): + runs = [] + cur = None + func_bits = [option_bits(enums, e) for _, e in FUNCS] + for line in out.splitlines(): + tag, _, rest = line.partition(" ") + if tag == "U": + ofs, var = rest.split() + if "gpio" in var and int(ofs, 16) not in GATE_REGS: + die("a gate register at %s this does not know" % ofs) + elif tag == "R": + parts = [int(x) for x in rest.split()] + fi = parts[0] + cur = Run(FUNCS[fi][0], + tuple(func_bits[fi][i] for i in sorted(parts[1:]))) + elif tag == "P": + gi, bi = (int(x) for x in rest.split()) + cur.prefix = func_bits[gi][bi] + elif tag == "W": + ofs, mask, val, rid = rest.split() + if ofs == "?": + die("a register write the harness cannot place") + ofs, mask, val, rid = (int(ofs, 16), int(mask, 16), int(val, 16), + int(rid)) + if ofs in GATE_REGS: + if mask & (mask - 1): + die("a multi-bit gate write at %#x" % ofs) + pad = "%s%d" % (GATE_REGS[ofs][1], field_shift(mask)) + cur.gates[pad] = (1 if val else 0, rid) + else: + f = Field(ofs, mask) + cur.fields[f] = val + cur.blocks.setdefault(recs[rid].path[-1], {})[f] = val + elif tag == "E": + if int(rest) == 0: + regs = collections.defaultdict(int) + for f, v in cur.fields.items(): + regs[f.reg] = (regs[f.reg] & ~f.mask) | v + cur.regs = regs + runs.append(cur) + cur = None + return runs + + +class Claim: + __slots__ = ("pad", "name", "conds", "ungated") + + def __init__(self, pad, name, conds, ungated): + self.pad = pad + self.name = name + self.conds = conds # tuple of (Field, value), sorted + self.ungated = ungated + + def sort_key(self): + return (pad_number(self.pad), -len(self.conds), self.name, + self.conds, self.ungated) + + def holds(self, regs, gate): + return (self.ungated or gate == 0) and all( + (regs[f.reg] & f.mask) == v for f, v in self.conds) + + +# A pad the other group's option wrote, in a call that needed one first: what +# that option does to it is that group's run to say, not this one's. +PREFIX = "prefix" + + +class Model: + def __init__(self, runs, recs, names, bonded): + self.runs = runs + self.recs = recs + self.names = names + self.bonded = set(bonded) + self.order = {f: i for i, (f, _) in enumerate(FUNCS)} + self.claims = {} # pad -> [Claim], resolver order + self.chosen = {} # (pad, conds, ungated) -> (unnamed?, name) + self.explained = set() # (option, pad) the code touches + self.problems = [] + self.conflicts = 0 # states where two claims hold at once + self.orphans = 0 # pads cleared and then claimed by nothing + + def own(self, run, pad): + """The claim the last gate write of `pad` in `run` makes: + (conds, ungated, rec), or None for a pad it leaves a GPIO.""" + if pad not in run.gates: + return None + val, rid = run.gates[pad] + rec = self.recs[rid] + if rec.func != run.func: + return PREFIX + if val == 1 and run.func not in UNGATED_FUNCS: + return None + conds = {} + for blk in rec.path: + conds.update(run.blocks.get(blk, {})) + return tuple(sorted(conds.items())), val == 1, rec + + def name_for(self, run, pad, rec): + """(unnamed?, name): the enclosing options innermost first, then the + options of the call; failing both, the innermost option's label.""" + for opt in rec.chain + run.opts[::-1]: + for sub in (run.func, None): + n = self.names.get((sub, opt, pad)) + if n: + return (False, n) + if rec.chain: + return (True, option_label(rec.chain[0])) + return (True, option_label(run.opts[-1])) + + def add(self, pad, name, conds, ungated): + """Add a claim. Returns True when it is new, False when it was + there, and the clashing claim when one has the same conditions and + another name.""" + lst = self.claims.setdefault(pad, []) + for c in lst: + if c.conds == conds and c.ungated == ungated: + return c if c.name != name else False + lst.append(Claim(pad, name, conds, ungated)) + lst.sort(key=Claim.sort_key) + return True + + def build(self): + seen = collections.defaultdict(set) + for run in self.runs: + for pad in run.gates: + own = self.own(run, pad) + if own is None or own is PREFIX: + continue + conds, ungated, rec = own + for opt in rec.chain + run.opts: + self.explained.add((opt, pad)) + if pad in self.bonded: + unnamed, name = self.name_for(run, pad, rec) + seen[(pad, conds, ungated)].add( + (unnamed, self.order[run.func], name)) + + # One field reached from two groups -- SEN_MCLK is set by both + # PIN_SENSOR_CFG_MCLK and PIN_SENSOR2_CFG_SN_MCLK -- takes the name + # the group earlier in the vendor's table gives it. + for key, cands in seen.items(): + named = {n for u, _, n in cands if not u} + if len(named) > 1: + self.problems.append("%s is %s under the same writes" + % (key[0], " and ".join(sorted(named)))) + u, _, n = min(cands) + self.chosen[key] = (u, n) + + # A state nothing names inherits the name of the state it extends: + # SPI_CFG_CH1_2BITS on its own does everything CH1 does plus SPI_DAT, + # and C_GPIO17 is still SPI_1_CLK. Only from a strict subset of the + # same pad's conditions, the largest, so a name never moves sideways. + for key, (unnamed, _) in list(self.chosen.items()): + if not unnamed: + continue + pad, conds, ungated = key + best = None + for other, (u, name) in self.chosen.items(): + if (not u and other[0] == pad and other[2] == ungated and + len(other[1]) < len(conds) and + set(other[1]) <= set(conds) and + (best is None or len(other[1]) > best[0])): + best = (len(other[1]), name) + if best: + self.chosen[key] = (False, best[1]) + + for (pad, conds, ungated), (_, name) in self.chosen.items(): + res = self.add(pad, name, conds, ungated) + if isinstance(res, Claim): + self.problems.append("%s is %s and %s under the same writes" + % (pad, res.name, name)) + + for _ in range(8): + if not self.replay(): + break + else: + self.problems.append("the replay did not settle") + + def replay(self): + """Check every state the vendor code produced; add a claim for each + overlap the code resolves. Returns how many were added.""" + added = 0 + self.conflicts = self.orphans = 0 + ungated_pads = {p for p, lst in self.claims.items() + if any(c.ungated for c in lst)} + for run in self.runs: + for pad in sorted((set(run.gates) | ungated_pads) & self.bonded): + gate = run.gates.get(pad, (1, None))[0] + held = [c for c in self.claims.get(pad, ()) + if c.holds(run.regs, gate)] + held_names = {c.name for c in held} + own = self.own(run, pad) + if own is PREFIX: + continue + want = None + if own is not None: + conds, ungated, _ = own + if all((run.regs[f.reg] & f.mask) == v for f, v in conds): + want = self.chosen[(pad, conds, ungated)][1] + else: + self.orphans += 1 + if want is None: + if held_names: + # Cleared, its own claim moved away, and something + # else's conditions happen to hold: the vendor code + # says nothing about what that pad is. + self.conflicts += 1 + continue + if len(held_names) > 1: + self.conflicts += 1 + if held[0].name == want: + continue + if want not in held_names: + self.problems.append( + "%s after %s: the code means %s, the claims say %s" + % (pad, list(run.opts), want, + sorted(held_names) or "nothing")) + continue + # Two hold; the code meant `want`. Make that the more + # specific claim: its own conditions and the others'. + conds = dict(own[0]) + for c in held: + for f, _ in c.conds: + conds[f] = run.regs[f.reg] & f.mask + conds = tuple(sorted(conds.items())) + res = self.add(pad, want, conds, own[1]) + if isinstance(res, Claim): + self.problems.append( + "%s after %s is both %s and %s" + % (pad, list(run.opts), res.name, want)) + elif res: + added += 1 + return added + + def check_annotations(self, found): + for opt, pad in found: + if (opt, pad) in self.explained: + continue + # An option the vendor refuses in every combination explains + # nothing and contradicts nothing. + if not any(opt in r.opts for r in self.runs): + continue + self.problems.append( + "%s names %s, which the code never touches for it" + % (opt, pad)) + + +# ---------------------------------------------------------------- output + + +def pick_selectors(claims): + """For each (pad, name): the condition its walk row shows as address, + mask and value, or None for the gate bit. + + It is information only -- get() and set() read the claims -- but a + consumer that sees two rows of one pad with the same selector cannot + tell them apart, so no pad may show one twice. Candidates are the + conditions every claim of the name shares, least shared with the pad's + other names first; then the rest of its conditions; then the gate bit. + Picked as a bipartite matching: greedy gets stuck on the HSI pads.""" + out = {} + for pad, lst in claims.items(): + by_name = collections.OrderedDict() + for c in sorted(lst, key=lambda c: (len(c.conds), c.name)): + by_name.setdefault(c.name, []).append(c) + + def shared(cond, name): + return sum(1 for n, cs in by_name.items() + if n != name and any(cond in c.conds for c in cs)) + + cands = {} + for name, cs in by_name.items(): + common = set(cs[0].conds) + for c in cs[1:]: + common &= set(c.conds) + rest = {f for c in cs for f in c.conds} - common + order = sorted(common, key=lambda f: (shared(f, name), f)) + order += sorted(rest, key=lambda f: (shared(f, name), f)) + cands[name] = [(f.reg, f.mask, v) for f, v in order] + [None] + + match = {} + + def augment(name, tried): + for sel in cands[name]: + if sel in tried: + continue + tried.add(sel) + if sel not in match or augment(match[sel], tried): + match[sel] = name + return True + return False + + for name in by_name: + if not augment(name, set()): + die("%s: no selector left for %s" % (pad, name)) + for sel, name in match.items(): + out[(pad, name)] = sel + return out + + +def packed(f, v): + """reg, shift, width, value: what novatek_cond_t holds.""" + shift = field_shift(f.mask) + width = bin(f.mask).count("1") + if f.mask != ((1 << width) - 1) << shift: + die("a field that is not contiguous: %#x" % f.mask) + if width > 8 or f.reg > 0xFF: + die("a field too wide for the table: %#x at %#x" % (f.mask, f.reg)) + return f.reg, shift, width, v >> shift + + +def render(model, bonded, regen): + pads = sorted(model.claims, key=pad_number) + conds = [] + index = {} + rows = [] + for pad in pads: + for c in model.claims[pad]: + if c.conds not in index: + index[c.conds] = len(conds) + conds.extend(c.conds) + rows.append((c, index[c.conds])) + if len(conds) > 0xFFFF: + die("too many conditions for a uint16_t index") + sel = pick_selectors(model.claims) + + o = [] + o.append("""/* Generated by tools/gen_novatek_padmux.py -- do not edit. + * + * What the vendor's pinmux_config_*() functions do to each pad of the + * NA51089, found by running them: see the generator for how, and + * src/hal/novatek_padmux.c for how the table is read. %d vendor states + * were replayed against it; in %d of them two claims hold at once and the + * table carries the one the vendor code meant, and %d leave a pad cleared + * with its field moved elsewhere, which reads as unnamed. + * + * Regenerate with: + * %s + */ + +#ifndef HAL_NOVATEK_PADMUX_H +#define HAL_NOVATEK_PADMUX_H + +#include "hal/novatek_padmux_types.h" +""" % (len(model.runs), model.conflicts, model.orphans, regen)) + o.append("/* Every pad the package bonds out, by Linux GPIO number. */") + o.append("static const novatek_pad_t NA51089_pads[] = {") + for p in bonded: + o.append(" {%d, PMX_%s}," % (pad_number(p), p)) + o.append("};") + o.append("") + o.append("/* TOP register offset, field shift, width, value. */") + o.append("static const novatek_cond_t NA51089_conds[] = {") + for f, v in conds: + o.append(" {0x%02X, %d, %d, %d}," % packed(f, v)) + o.append("};") + o.append("") + o.append("/* Per pad, most conditions first: the first claim that holds") + o.append(" * is what the pad carries. {pad, flags, name, first") + o.append(" * condition, how many}. */") + o.append("static const novatek_claim_t NA51089_claims[] = {") + for c, idx in rows: + o.append(" {%d, %s, PMX_%s, %d, %d}, /* %s */" % ( + pad_number(c.pad), "NVT_UNGATED" if c.ungated else "0", + c.name, idx, len(c.conds), c.pad)) + o.append("};") + o.append("") + o.append("/* The field each function's walk row shows: {pad, name, reg,") + o.append(" * shift, width, value}, reg NVT_GATE for the pad's gate bit. */") + o.append("static const novatek_sel_t NA51089_sels[] = {") + nsels = 0 + for pad in pads: + done = set() + for c in model.claims[pad]: + if c.name in done: + continue + done.add(c.name) + s = sel[(pad, c.name)] + if s is None: + o.append(" {%d, PMX_%s, NVT_GATE, 0, 0, 0}," % ( + pad_number(pad), c.name)) + else: + f = Field(s[0], s[1]) + o.append(" {%d, PMX_%s, 0x%02X, %d, %d, %d}," % ( + (pad_number(pad), c.name) + packed(f, s[2]))) + nsels += 1 + o.append("};") + o.append("") + o.append("static const novatek_soc_t NA51089_padmux = {") + o.append(" NA51089_pads, %d, NA51089_claims, %d, NA51089_conds," + % (len(bonded), len(rows))) + o.append(" NA51089_sels, %d," % nsels) + o.append("};") + o.append("") + o.append("#endif /* HAL_NOVATEK_PADMUX_H */") + return "\n".join(o) + "\n" + + +REGEN = "tools/gen_novatek_padmux.py --sdk " + + +def generate(sdk): + src = Sources(sdk) + enums = parse_enums(read(src.top_h)) + bonded = bonded_pads(read(src.gpio_h)) + names, found = annotations(enums, read(src.csv) if src.csv else "") + recs = [] + out = run_harness(src, enums, recs) + runs = parse_runs(out, enums, recs) + model = Model(runs, recs, names, bonded) + model.build() + model.check_annotations(found) + if model.problems: + die("the sources disagree:\n " + "\n ".join(model.problems[:40])) + return render(model, bonded, REGEN), model + + +# ---------------------------------------------------------------- selftest + +# A fake SDK in the shapes that matter: a location field with two values, +# a modifier that only counts inside its base option's block, an ungated data +# bus and a gated claim overlapping it, a field written to zero on purpose, +# a field moved away by a later option, a GPIO write that is a release, a +# claim the code resolves between two that hold, a brace inside a string, +# and a csv typo. +FIXTURE = { + "BSP/linux-kernel/arch/arm/mach-nvt-ivot/include/mach/rcw_macro.h": """ +enum { E_OK = 0, E_PAR = -1, E_OBJ = -2 }; +""", + "BSP/linux-kernel/arch/arm/mach-nvt-ivot/include/mach/nvt_type.h": "", + "BSP/linux-kernel/arch/arm/plat-novatek/include/plat-na51089/top_reg.h": + """ +#include +#define TOP_REG3_OFS 0x0C +union TOP_REG3 { uint32_t reg; struct { + unsigned int SENSOR:3; unsigned int r0:3; + unsigned int SEN_CCIR_VSHS:1; unsigned int r1:1; + unsigned int SEN_MCLK:2; unsigned int r2:22; } bit; }; +#define TOP_REG5_OFS 0x14 +union TOP_REG5 { uint32_t reg; struct { + unsigned int r0:2; unsigned int ETH_MDIO:2; + unsigned int r1:2; unsigned int I2C3:2; unsigned int r2:22; + unsigned int ETH:2; } bit; }; +#define TOP_REG9_OFS 0x24 +union TOP_REG9 { uint32_t reg; struct { + unsigned int r0:2; unsigned int UART2:2; unsigned int r1:4; + unsigned int UART2_CTSRTS:2; unsigned int r2:22; } bit; }; +#define TOP_REGCGPIO0_OFS 0xA0 +union TOP_REGCGPIO0 { uint32_t reg; struct { + unsigned int CGPIO_0:1; unsigned int r:10; unsigned int CGPIO_11:1; + unsigned int CGPIO_12:1; unsigned int CGPIO_13:1; unsigned int r2:18; + } bit; }; +#define TOP_REGPGPIO0_OFS 0xA8 +union TOP_REGPGPIO0 { uint32_t reg; struct { + unsigned int PGPIO_0:1; unsigned int PGPIO_1:1; unsigned int PGPIO_2:1; + unsigned int r:29; } bit; }; +#define TOP_REGHGPIO0_OFS 0xD8 +union TOP_REGHGPIO0 { uint32_t reg; struct { + unsigned int HSIGPIO_0:1; unsigned int HSIGPIO_1:1; unsigned int r:30; + } bit; }; +""", + "BSP/linux-kernel/arch/arm/plat-novatek/include/plat-na51089/top.h": """ +typedef enum { + PIN_I2C_CFG_NONE, + PIN_I2C_CFG_CH3 = 0x40, ///< @P_GPIO1[I2C3_1_SCL]|P_GPIO0[I2C3_1_SDA] + PIN_I2C_CFG_CH3_2ND_PINMUX = 0x80, ///< @MC11[I2C3_2_SCL]|MC12[I2C3_2_SDA] +} PIN_I2C_CFG; +typedef enum { + PIN_UART_CFG_NONE, + PIN_UART_CFG_CH2 = 0x04, ///< @P_GPIO2[Uart2_1_TX] + PIN_UART_CFG_CH2_CTSRTS = 0x08, ///< flow control + PIN_UART_CFG_CH2_2ND = 0x10, ///< @MC11[Uart2_2_TX]. RTS &&MC13[Uart2_2_RTS] +} PIN_UART_CFG; +typedef enum { + PIN_SENSOR_CFG_NONE, + PIN_SENSOR_CFG_12BITS = 0x04, ///< parallel on HSI_GPI[0..1] + PIN_SENSOR_CFG_CCIR8BITS = 0x08, ///< no annotation + PIN_SENSOR_CFG_MCLK = 0x10, ///< mclk on C0 + PIN_SENSOR_CFG_MCLK_2ND = 0x20, ///< mclk on HSI1 +} PIN_SENSOR_CFG; +typedef enum { + PIN_SPI_CFG_NONE, + PIN_SPI_CFG_CH1 = 1, + PIN_SPI_CFG_DI_ONLY = 2, +} PIN_SPI_CFG; +typedef enum { + PIN_ETH_CFG_NONE, + PIN_ETH_CFG_RMII = 1, + PIN_ETH_CFG_INTERANL = 2, + PIN_ETH_CFG_MDIO = 4, +} PINMUX_ETH_CFG; +""", + "BSP/linux-kernel/arch/arm/plat-novatek/include/plat-na51089/" + "nvt-gpio.h": """ +#define C_GPIO_NUM 14 +#define P_GPIO_NUM 3 +#define S_GPIO_NUM 0 +#define L_GPIO_NUM 0 +#define D_GPIO_NUM 0 +#define H_GPIO_NUM 2 +#define A_GPIO_NUM 0 +#define DSI_GPIO_NUM 0 +""", + "BSP/linux-kernel/drivers/pinctrl/novatek/na51089/na51089_pinmux.h": """ +#include +#include +enum { GPIO_ID_EMUM_FUNC, GPIO_ID_EMUM_GPIO }; +""", + "BSP/linux-kernel/drivers/pinctrl/novatek/na51089/" + "na51089_pinmux_host.c": r""" +#include "na51089_pinmux.h" + +static int pinmux_config_i2c(uint32_t config); +static int pinmux_config_uart(uint32_t config); +static int pinmux_config_sensor(uint32_t config); +static int pinmux_config_spi(uint32_t config); +static int pinmux_config_eth(uint32_t config); +static int sticky = 0; + +union TOP_REG3 top_reg3; +union TOP_REG5 top_reg5; +union TOP_REG9 top_reg9; +union TOP_REGCGPIO0 top_reg_cgpio0; +union TOP_REGPGPIO0 top_reg_pgpio0; +union TOP_REGHGPIO0 top_reg_hgpio0; + +struct nvt_pinctrl_info info_get_id[1]; + +static int pinmux_config_i2c(uint32_t config) +{ + if (config & PIN_I2C_CFG_CH3) { + top_reg_pgpio0.bit.PGPIO_1 = GPIO_ID_EMUM_FUNC; + top_reg_pgpio0.bit.PGPIO_0 = GPIO_ID_EMUM_FUNC; + top_reg5.bit.I2C3 = 1; + } + if (config & PIN_I2C_CFG_CH3_2ND_PINMUX) { + if (top_reg9.bit.UART2 == 2) { + pr_err("conflict with UART2_2 }\n"); + return E_OBJ; + } + top_reg_cgpio0.bit.CGPIO_11 = GPIO_ID_EMUM_FUNC; + top_reg_cgpio0.bit.CGPIO_12 = GPIO_ID_EMUM_FUNC; + top_reg5.bit.I2C3 = 2; + } + return E_OK; +} + +static int pinmux_config_uart(uint32_t config) +{ + if (config & PIN_UART_CFG_CH2) { + if (config & PIN_UART_CFG_CH2_2ND) { + if (config & PIN_UART_CFG_CH2_CTSRTS) { + top_reg_cgpio0.bit.CGPIO_13 = GPIO_ID_EMUM_FUNC; + top_reg9.bit.UART2_CTSRTS = 1; + } + top_reg_cgpio0.bit.CGPIO_11 = GPIO_ID_EMUM_FUNC; + top_reg9.bit.UART2 = 2; + } else { + top_reg_pgpio0.bit.PGPIO_2 = GPIO_ID_EMUM_FUNC; + top_reg9.bit.UART2 = 1; + } + } + return E_OK; +} + +static int pinmux_config_sensor(uint32_t config) +{ + uint32_t tmp = config & (PIN_SENSOR_CFG_12BITS | PIN_SENSOR_CFG_CCIR8BITS); + + sticky++; + switch (tmp) { + case PIN_SENSOR_CFG_12BITS: + top_reg3.bit.SENSOR = 1; + top_reg_hgpio0.bit.HSIGPIO_0 = GPIO_ID_EMUM_GPIO; + top_reg_hgpio0.bit.HSIGPIO_1 = GPIO_ID_EMUM_GPIO; + break; + case PIN_SENSOR_CFG_CCIR8BITS: + top_reg3.bit.SENSOR = 3; + top_reg3.bit.SEN_CCIR_VSHS = 0; + top_reg_hgpio0.bit.HSIGPIO_0 = GPIO_ID_EMUM_FUNC; + break; + default: + return E_PAR; + } + if (config & PIN_SENSOR_CFG_MCLK) { + top_reg_cgpio0.bit.CGPIO_0 = GPIO_ID_EMUM_FUNC; + top_reg3.bit.SEN_MCLK = 1; + } + if (config & PIN_SENSOR_CFG_MCLK_2ND) { + top_reg_hgpio0.bit.HSIGPIO_1 = GPIO_ID_EMUM_FUNC; + top_reg3.bit.SEN_MCLK = 2; + } + return sticky > 1000000 ? E_PAR : E_OK; +} + +static int pinmux_config_spi(uint32_t config) +{ + if (config & PIN_SPI_CFG_DI_ONLY) { + top_reg_pgpio0.bit.PGPIO_2 = GPIO_ID_EMUM_GPIO; + } else if (config & PIN_SPI_CFG_CH1) { + top_reg_pgpio0.bit.PGPIO_2 = GPIO_ID_EMUM_FUNC; + } + return E_OK; +} + +static int pinmux_config_eth(uint32_t config) +{ + if (config & PIN_ETH_CFG_INTERANL) { + if (config & PIN_ETH_CFG_MDIO) { + top_reg_pgpio0.bit.PGPIO_1 = GPIO_ID_EMUM_FUNC; + top_reg5.bit.ETH_MDIO = 1; + } + } else if (config & PIN_ETH_CFG_RMII) { + if (config & PIN_ETH_CFG_RMII) { + top_reg_pgpio0.bit.PGPIO_1 = GPIO_ID_EMUM_FUNC; + top_reg5.bit.ETH = 1; + } + if (config & PIN_ETH_CFG_MDIO) { + top_reg_pgpio0.bit.PGPIO_0 = GPIO_ID_EMUM_FUNC; + top_reg5.bit.ETH_MDIO = 1; + } + } + return E_OK; +} +""", + "build/nvt-tools/nvt_pinctrl_tool/top.csv": """\ +PIN_SPI_CFG_CH1,1,P_GPIO2[spi_clk(BS)], +PIN_I2C_CFG_CH3,64,P_GPIO29[I2C3_1_SCL], +""", +} + +SELFTEST_FUNCS = [("i2c", "PIN_I2C_CFG"), ("uart", "PIN_UART_CFG"), + ("sensor", "PIN_SENSOR_CFG"), ("spi", "PIN_SPI_CFG"), + ("eth", "PINMUX_ETH_CFG")] + + +def selftest(): + global FUNCS + tmp = tempfile.mkdtemp(prefix="nvt_padmux_selftest_") + saved = FUNCS, dict(ANNOTATION_ERRATA) + failures = [] + + def check(cond, what): + if not cond: + failures.append(what) + + try: + for rel, text in FIXTURE.items(): + path = os.path.join(tmp, rel) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w") as f: + f.write(text) + FUNCS = SELFTEST_FUNCS + + # The csv's P_GPIO29 is a typo. Without an erratum the sources + # disagree and the generator has to say so rather than guess. + try: + generate(tmp) + check(False, "a csv pad the code never touches was accepted") + except SystemExit as e: + check("PIN_I2C_CFG_CH3 names P_GPIO29" in str(e), + "refusal names the pad: %s" % e) + + ANNOTATION_ERRATA[("PIN_I2C_CFG_CH3", "P_GPIO29")] = ( + "PIN_I2C_CFG_CH3", "P_GPIO1") + text, model = generate(tmp) + claims = model.claims + + def names(pad): + return {c.name for c in claims.get(pad, [])} + + def read_as(pad, writes, gate): + regs = collections.defaultdict(int) + for (reg, mask), v in writes.items(): + regs[reg] = (regs[reg] & ~mask) | v + for c in claims.get(pad, ()): + if c.holds(regs, gate): + return c.name + return None if gate else "?" + + # Names: top.h, case folded; the csv, "(BS)" dropped; else a label. + check(names("C_GPIO12") == {"I2C3_2_SDA"}, "C12 %s" + % names("C_GPIO12")) + check(names("C_GPIO11") == {"I2C3_2_SCL", "UART2_2_TX"}, + "C11 %s" % names("C_GPIO11")) + # A modifier's pad, named from the && list of its enclosing option, + # and conditioned on both blocks' fields. + rts = claims.get("C_GPIO13", []) + check([c.name for c in rts] == ["UART2_2_RTS"], "C13 %s" + % [c.name for c in rts]) + check(rts and len(rts[0].conds) == 2, "C13 needs UART2 and CTSRTS") + check(names("P_GPIO2") == {"UART2_1_TX", "SPI_CLK"}, "P2 %s" + % names("P_GPIO2")) + check("SENSOR_12BITS" in names("H_GPIO0"), "H0 %s" % names("H_GPIO0")) + # MCLK depends on SEN_MCLK alone, not on the sensor mode the same + # call selected in another block. + mclk = claims.get("C_GPIO0", []) + check([len(c.conds) for c in mclk] == [1], "MCLK conds %s" + % [c.conds for c in mclk]) + + u = [c for c in claims["H_GPIO0"] if c.name == "SENSOR_12BITS"] + check(u and u[0].ungated, "12BITS data is ungated") + cc = [c for c in claims["H_GPIO0"] if c.name == "SENSOR_CCIR8BITS"] + check(cc and any(f.mask == 0x40 and v == 0 for f, v in cc[0].conds), + "SEN_CCIR_VSHS=0 is kept as a condition") + check(all(not c.ungated for c in claims["P_GPIO2"]), + "a release is not a claim") + + I2C3, UART2, SENSOR, MCLK = (0x14, 0xC0), (0x24, 0x0C), (0x0C, 0x07), \ + (0x0C, 0x300) + ETH, MDIO = (0x14, 0xC0000000), (0x14, 0x0C) + check(read_as("C_GPIO11", {I2C3: 0x80}, 0) == "I2C3_2_SCL", + "C11 under I2C3=2") + check(read_as("C_GPIO11", {UART2: 0x08}, 0) == "UART2_2_TX", + "C11 under UART2=2") + check(read_as("C_GPIO11", {I2C3: 0x80}, 1) is None, "the gate wins") + check(read_as("C_GPIO11", {}, 0) == "?", "cleared, claimed by none") + check(read_as("H_GPIO0", {SENSOR: 1}, 1) == "SENSOR_12BITS", + "ungated holds through the gate") + check(read_as("H_GPIO1", {SENSOR: 1, MCLK: 0x200}, 0) == + "SENSOR_MCLK_2ND", "H1 %s" + % read_as("H_GPIO1", {SENSOR: 1, MCLK: 0x200}, 0)) + # MCLK then MCLK_2ND: C_GPIO0 is cleared and its field went away. + check(read_as("C_GPIO0", {SENSOR: 1, MCLK: 0x200}, 0) == "?", + "orphan reads as nothing") + check(model.orphans > 0, "orphans counted") + # P_GPIO1 is RMII data and internal-PHY MDIO; with RMII and MDIO + # both set the code meant RMII. + both = {ETH: 0x40000000, MDIO: 0x4} + check(read_as("P_GPIO1", both, 0) == "ETH_RMII", "P1 RMII+MDIO %s" + % read_as("P_GPIO1", both, 0)) + check(read_as("P_GPIO1", {MDIO: 0x4}, 0) == "ETH_MDIO", "P1 MDIO") + + check("PMX_C_GPIO13" in text and "NA51089_claims" in text, "render") + finally: + FUNCS = saved[0] + ANNOTATION_ERRATA.clear() + ANNOTATION_ERRATA.update(saved[1]) + shutil.rmtree(tmp, ignore_errors=True) + + for f in failures: + print("selftest FAIL: %s" % f, file=sys.stderr) + if failures: + return 1 + print("selftest: ok") + return 0 + + +def main(): + ap = argparse.ArgumentParser( + description=__doc__.split("\n\n")[0], + formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("--sdk", help="NA51089 SDK root (has BSP/linux-kernel)") + ap.add_argument("--verify", metavar="HEADER", + help="regenerate and diff against HEADER instead") + ap.add_argument("--selftest", action="store_true", + help="run against a built-in fixture SDK; needs a C " + "compiler and nothing else") + args = ap.parse_args() + + if args.selftest: + return selftest() + if not args.sdk: + ap.error("--sdk is required") + + text, _ = generate(args.sdk) + if args.verify: + have = read(args.verify) + if have != text: + sys.stdout.writelines(difflib.unified_diff( + have.splitlines(True), text.splitlines(True), args.verify, + "regenerated")) + return 1 + print("%s: up to date" % args.verify) + return 0 + sys.stdout.write(text) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/gen_padmux_names.py b/tools/gen_padmux_names.py index c5789f73..0ec1327b 100644 --- a/tools/gen_padmux_names.py +++ b/tools/gen_padmux_names.py @@ -49,8 +49,8 @@ # Each table file, and the condition under which its rows are compiled. # # reginfo.c is split into per-family `#if defined(IPCHW_PADMUX_Vx)` blocks and -# is parsed for them. The other two are pad-free register dumps for the -# `reginfo` subcommand: they carry no family blocks, and the whole file is +# is parsed for them. The *_reginfo.h files are pad-free register dumps for +# the `reginfo` subcommand: they carry no family blocks, and the whole file is # behind one condition -- including `!STANDALONE_LIBRARY`, because libipchw # does not include them at all and must not pay for their names. # The third field is how names are spelled in the file. @@ -58,7 +58,7 @@ # "muxctrl" -- MUXCTRL(name, addr, ...) rows, one per line or wrapped. # "table" -- a generated C initialiser where EVERY string literal is a # pad or function name. Comments are stripped first, because -# the banner in both of those files quotes example names and +# the banners in those files quote example names and # interning a name nothing indexes would be a silent leak # into the blob. SOURCES = [ @@ -75,6 +75,12 @@ ), ("src/hal/ingenic_padmux.h", "defined(IPCHW_PADMUX_INGENIC)", "table"), ("src/hal/sstar_padmux.h", "defined(IPCHW_PADMUX_SSTAR)", "table"), + ("src/hal/novatek_padmux.h", "defined(IPCHW_PADMUX_NOVATEK)", "table"), + ( + "src/hal/novatek_reginfo.h", + "defined(IPCHW_VENDOR_NOVATEK) && !defined(STANDALONE_LIBRARY)", + "muxctrl", + ), ] FAMILY_OPEN = re.compile(r"^#if defined\((IPCHW_PADMUX_[A-Z0-9_]+)\)") @@ -132,7 +138,7 @@ def map_code(line, in_block, fn): identity the line comes back byte for byte, which is what makes it safe to run over a whole file. - Only good enough for these five files -- it does not know about a `/*` + Only good enough for these files -- it does not know about a `/*` inside a string literal, and none of them has one. It exists because a name quoted in a banner comment ("PB25", the spelling the datasheet uses) must not reach the blob, and because the generated SigmaStar table ends From 8df45dd8a4d4c83bba711d0d403212b411a2d18a Mon Sep 17 00:00:00 2001 From: Dmitry Ilyin <6576495+widgetii@users.noreply.github.com> Date: Fri, 9 Oct 2026 23:02:16 +0300 Subject: [PATCH 2/2] novatek: undo a refused set, no one-write GPIO hint where a sensor holds the pad From review of #239: - set() that refuses after writing a claim's fields now writes back every TOP word it touched, so a refusal never leaves a peripheral moved half-way. - the GPIO row of a pad an ungated sensor claim can hold carries gpio_func -1, since setting the gate alone does not free it. - gpio usage text names the pad spellings each vendor takes. - reginfo_test sets every function of a pad from every claim's own state (2110 sets) and checks it reads back, or that a refusal changed nothing. --- src/hal/novatek_padmux.c | 38 ++++++++++++++++------ src/reginfo.c | 24 ++++++++------ src/reginfo_test.c | 69 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 18 deletions(-) diff --git a/src/hal/novatek_padmux.c b/src/hal/novatek_padmux.c index da69a7a4..e68af4c7 100644 --- a/src/hal/novatek_padmux.c +++ b/src/hal/novatek_padmux.c @@ -57,6 +57,8 @@ typedef struct { const padmux_io_t *io; uint32_t val[TOP_WORDS]; uint8_t have[TOP_WORDS]; + uint32_t orig[TOP_WORDS]; /* what a written word held before, to undo */ + uint8_t dirty[TOP_WORDS]; } top_t; static const novatek_soc_t *nvt_soc(void) { @@ -100,6 +102,10 @@ static bool top_write_field(top_t *t, unsigned reg, uint32_t mask, uint32_t val; if (!top_read(t, reg, &val)) return false; + if (!t->dirty[reg / 4]) { + t->orig[reg / 4] = val; + t->dirty[reg / 4] = 1; + } val = (val & ~mask) | (bits & mask); if (!t->io->write(TOP_BASE + reg, val, 32)) return false; @@ -107,6 +113,17 @@ static bool top_write_field(top_t *t, unsigned reg, uint32_t mask, return true; } +/* Put back every word this call wrote, for a set() that is refusing: having + * moved a peripheral's location field half-way to a function it then says it + * cannot put on the pad would unmux that peripheral from every other pad it + * was on. Best effort -- an I/O error that stopped the set may stop this. */ +static int top_undo(top_t *t, int res) { + for (unsigned w = 0; w < TOP_WORDS; w++) + if (t->dirty[w]) + t->io->write(TOP_BASE + w * 4, t->orig[w], 32); + return res; +} + /* 1 when every condition of `c` holds, 0 when one does not, or * IPCHW_PADMUX_IO. */ static int claim_holds(const novatek_soc_t *soc, const novatek_claim_t *c, @@ -180,6 +197,7 @@ static bool has_ungated(const novatek_soc_t *soc, int pad) { static ipchw_padmux_t gpio_row(const novatek_soc_t *soc, const novatek_pad_t *pd) { uint32_t bit = gate_bit(pd->pad); + bool ungated = has_ungated(soc, pd->pad); return (ipchw_padmux_t){ .address = gate_addr(pd->pad), @@ -188,11 +206,11 @@ static ipchw_padmux_t gpio_row(const novatek_soc_t *soc, .func_name = IPCHW_PADMUX_GPIO, .gpio_name = padmux_name(pd->name), .gpio_pad = pd->pad, - .gpio_func = (int)bit, /* Setting the gate is the whole operation -- unless a sensor mode - * can hold the pad through it, and then it is not. */ - .flags = IPCHW_PADMUX_F_GPIO | - (has_ungated(soc, pd->pad) ? 0 : IPCHW_PADMUX_F_RMW), + * can hold the pad through it, and then it is not, and a consumer + * has to go through ipchw_padmux_set(). */ + .gpio_func = ungated ? -1 : (int)bit, + .flags = IPCHW_PADMUX_F_GPIO | (ungated ? 0 : IPCHW_PADMUX_F_RMW), }; } @@ -369,8 +387,9 @@ static int nvt_set(int pad, const char *func_name, const padmux_io_t *io) { if (!strcmp(func_name, IPCHW_PADMUX_GPIO) || !strcmp(func_name, padmux_name(pd->name))) { if (!top_write_field(&t, gr, gate_bit(pad), gate_bit(pad))) - return IPCHW_PADMUX_IO; - return drop_competitors(soc, pad, &t, NULL); + return top_undo(&t, IPCHW_PADMUX_IO); + int res = drop_competitors(soc, pad, &t, NULL); + return res ? top_undo(&t, res) : 0; } /* Of the claims that spell this name, the one that changes least: on a @@ -399,13 +418,14 @@ static int nvt_set(int pad, const char *func_name, const padmux_io_t *io) { const novatek_cond_t *k = &soc->conds[best->cond + i]; if (!top_write_field(&t, k->reg, field_mask(k->shift, k->width), (uint32_t)k->value << k->shift)) - return IPCHW_PADMUX_IO; + return top_undo(&t, IPCHW_PADMUX_IO); } if (!(best->flags & NVT_UNGATED) && !top_write_field(&t, gr, gate_bit(pad), 0)) - return IPCHW_PADMUX_IO; + return top_undo(&t, IPCHW_PADMUX_IO); - return drop_competitors(soc, pad, &t, best); + int res = drop_competitors(soc, pad, &t, best); + return res ? top_undo(&t, res) : 0; } /* "P_GPIO22", "C_GPIO17" or the vendor's other spellings of it, "MC17" and diff --git a/src/reginfo.c b/src/reginfo.c index 59f6f3a8..0b837687 100644 --- a/src/reginfo.c +++ b/src/reginfo.c @@ -3740,8 +3740,10 @@ static int gpio_manipulate(char **argv, bool set_op) { static int gpio_get_cmd(int argc, char **argv) { if (argc != 2) { - printf("Usage: ipctool gpio %s %s\n%s", "get", "", - "where: either number in 5_6 or 46 format\n"); + printf( + "Usage: ipctool gpio %s %s\n%s", "get", "", + "where: is 46, 5_6 on HiSilicon, or the pad's name " + "(P_GPIO22 on Novatek)\n"); return EXIT_FAILURE; } @@ -3750,8 +3752,10 @@ static int gpio_get_cmd(int argc, char **argv) { static int gpio_set_cmd(int argc, char **argv) { if (argc != 3) { - printf("Usage: ipctool gpio %s %s\n%s", "set", " ", - "where: either number in 5_6 or 46 format\n"); + printf( + "Usage: ipctool gpio %s %s\n%s", "set", " ", + "where: is 46, 5_6 on HiSilicon, or the pad's name " + "(P_GPIO22 on Novatek)\n"); return EXIT_FAILURE; } @@ -3886,11 +3890,13 @@ static int gpio_mux_by(const char *gpio_number, int func_num, static int gpio_mux_cmd(int argc, char **argv) { if (argc < 2 || argc > 3) { - printf("Usage: ipctool gpio %s %s\n%s%s", "mux", - " [function name or number]", - "where: either number in 5_6 or 46 format\n", - " with no function, reports what the pad carries;\n" - " pass GPIO to mux it back to plain GPIO\n"); + printf( + "Usage: ipctool gpio %s %s\n%s%s", "mux", + " [function name or number]", + "where: is 46, 5_6 on HiSilicon, or the pad's name " + "(P_GPIO22 on Novatek)\n", + " with no function, reports what the pad carries;\n" + " pass GPIO to mux it back to plain GPIO\n"); return EXIT_FAILURE; } diff --git a/src/reginfo_test.c b/src/reginfo_test.c index 0d42082c..99b5c32f 100644 --- a/src/reginfo_test.c +++ b/src/reginfo_test.c @@ -1021,6 +1021,74 @@ static void test_novatek(void) { CHECK(ipchw_padmux_set(54, "UART2_2_TX") == IPCHW_PADMUX_NO_FUNC); as_chip(T31, "T31"); } + +/* set() from every state the table knows, not only from zeroed registers: + * each claim's own conditions, with its pad handed over, and from there every + * function that pad offers. A set that succeeds has to read back; one that + * refuses has to leave every register as it found it, because a location + * field moved half-way unmuxes the peripheral from its other pads. */ +#include "hal/novatek_padmux.h" + +static void test_novatek_set_from_every_state(void) { + puts("Novatek: set() from every claim's state reads back or undoes"); + as_chip(CHIP_NA51089, "NT98566"); + const novatek_soc_t *soc = &NA51089_padmux; + int done = 0, refused = 0; + + for (int i = 0; i < soc->nclaims; i++) { + const novatek_claim_t *c = &soc->claims[i]; + for (int j = 0; j < soc->nsels; j++) { + if (soc->sels[j].pad != c->pad) + continue; + const char *want = padmux_name(soc->sels[j].name); + + nvt_boot_state(); + for (int k = 0; k < c->ncond; k++) { + const novatek_cond_t *f = &soc->conds[c->cond + k]; + uint32_t a = 0xF0010000u + f->reg; + uint32_t m = ((1u << f->width) - 1) << f->shift; + fake_write( + a, (reg_of(a) & ~m) | ((uint32_t)f->value << f->shift), 32); + } + uint32_t gate = 0xF00100A0u + (uint32_t)((c->pad >> 5) * 8); + if (c->pad >> 5 >= 4) + gate += 0x10; /* D, H, A, DSI sit after a gap at 0xC0 */ + fake_write(gate, reg_of(gate) & ~(1u << (c->pad & 31)), 32); + + uint32_t before[256]; + int nbefore = NREGS; + for (int r = 0; r < NREGS; r++) + before[r] = REGS[r].val; + + int res = ipchw_padmux_set(c->pad, want); + ipchw_padmux_t got; + if (res == 0) { + done++; + if (ipchw_padmux_get(c->pad, &got) != 1 || + strcmp(got.func_name, want) != 0) { + fprintf(stderr, " FAIL pad %d from %s: set %s reads %s\n", + c->pad, padmux_name(c->name), want, got.func_name); + failures++; + } + } else { + refused++; + bool same = true; + for (int r = 0; r < nbefore; r++) + same = same && REGS[r].val == before[r]; + if (!same) { + fprintf(stderr, + " FAIL pad %d from %s: refused %s (%d) " + "and left registers changed\n", + c->pad, padmux_name(c->name), want, res); + failures++; + } + } + } + } + printf(" (%d set, %d refused and undone)\n", done, refused); + CHECK(done > 0); + as_chip(T31, "T31"); +} #endif #ifdef IPCHW_VENDOR_NOVATEK @@ -1391,6 +1459,7 @@ int main(void) { #endif #ifdef IPCHW_PADMUX_NOVATEK test_novatek(); + test_novatek_set_from_every_state(); #endif #ifdef IPCHW_VENDOR_NOVATEK test_novatek_gpio_regs();