* Re: [PATCH v2 1/2] dt-bindings: power: supply: Add TI BQ25630 charger
From: Waqar Hameed @ 2026-06-25 11:27 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
kernel, linux-pm, devicetree, linux-kernel
In-Reply-To: <20260622-whimsical-inescapable-pronghorn-5f94bb@quoll>
On Mon, Jun 22, 2026 at 13:06 +0200 Krzysztof Kozlowski <krzk@kernel.org> wrote:
> On Thu, Jun 18, 2026 at 03:37:59PM +0200, Waqar Hameed wrote:
>> +allOf:
>> + - $ref: power-supply.yaml#
>> +
>> +properties:
>> + compatible:
>> + const: ti,bq25630
>> +
>> + reg:
>> + const: 0x6b
>> + description:
>> + Device I2C address.
>
> Drop description, obvious.
I see that several others actually don't have a description for this
property. I'll drop it!
>
>> +
>> + interrupts:
>> + maxItems: 1
>> + description: |
>
> Do not need '|' unless you need to preserve formatting.
Right, let's remove it.
>
>> + Device sends active low 256 µs pulse. Type should therefore be
>> + IRQ_TYPE_EDGE_FALLING.
>> +
>> + monitored-battery: true
>
> Drop this one
I was actually unsure about this one, but several other bindings had
this one. We can remove it.
>
>> +
>> +required:
>> + - compatible
>> + - reg
>> + - interrupts
>> + - monitored-battery
>> +
>> +additionalProperties: false
>
> And here use 'unevaluatedProperties: false' instead.
Hm, reading the documentation [1], `unevaluatedProperties` should be
used, because of the "include" of `power-supply.yaml`. I'll change to
that.
However, there are tons of other places where `additionalProperties` is
used instead _with_ a reference to `power-supply.yaml` (which is what I
followed). Are all of them actually "wrong" then?
>
> With these fixed:
>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Thank you for your review Krzysztof!
[1] `Documentation/devicetree/bindings/writing-schema.rst`
^ permalink raw reply
* [PATCH v4] dt-bindings: pwm: st,sti-pwm: convert to DT schema
From: Charan Pedumuru @ 2026-06-25 11:24 UTC (permalink / raw)
To: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lee Jones
Cc: linux-pwm, devicetree, linux-kernel, Charan Pedumuru
Convert STMicroelectronics STiH41x PWM/Capture controller binding
to DT schema.
Changes during conversion:
- Fix compatible string from "st,pwm" to "st,sti-pwm" to match the
actual hardware variant naming convention used across STi bindings.
- Drop pinctrl-names from the required list as pinctrl properties are
inherited and validated by the pinctrl schema.
Signed-off-by: Charan Pedumuru <charan.pedumuru@gmail.com>
---
Changes in v4:
- Fix compatible to "st,sti-pwm" in examples.
- Modify subject line to point to the correct YAML file.
- Link to v3: https://patch.msgid.link/20260625-st-pwm-v3-1-ace9bff88529@gmail.com
Changes in v3:
- Fix compatible to "st,sti-pwm".
- Drop pinctrl-names from required.
- Modify the commit message to explain the changes made.
- Change maintainer to "Lee Jones <lee.jones@linaro.org>".
- Link to v2: https://patch.msgid.link/20260618-st-pwm-v2-1-c792d5795ce2@gmail.com
Changes in v2:
- Add the missing interrupts to the required following the old binding.
- Modify the commit message to explain the changes made.
- Link to v1: https://patch.msgid.link/20260613-st-pwm-v1-1-458c2c89709a@gmail.com
---
Documentation/devicetree/bindings/pwm/pwm-st.txt | 43 ----------
.../devicetree/bindings/pwm/st,sti-pwm.yaml | 92 ++++++++++++++++++++++
2 files changed, 92 insertions(+), 43 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-st.txt b/Documentation/devicetree/bindings/pwm/pwm-st.txt
deleted file mode 100644
index 19fce774cafa..000000000000
--- a/Documentation/devicetree/bindings/pwm/pwm-st.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-STMicroelectronics PWM driver bindings
---------------------------------------
-
-Required parameters:
-- compatible : "st,pwm"
-- #pwm-cells : Number of cells used to specify a PWM. First cell
- specifies the per-chip index of the PWM to use and the
- second cell is the period in nanoseconds - fixed to 2
- for STiH41x.
-- reg : Physical base address and length of the controller's
- registers.
-- pinctrl-names: Set to "default".
-- pinctrl-0: List of phandles pointing to pin configuration nodes
- for PWM module.
- For Pinctrl properties, please refer to [1].
-- clock-names: Valid entries are "pwm" and/or "capture".
-- clocks: phandle of the clock used by the PWM module.
- For Clk properties, please refer to [2].
-- interrupts: IRQ for the Capture device
-
-Optional properties:
-- st,pwm-num-chan: Number of available PWM channels. Default is 0.
-- st,capture-num-chan: Number of available Capture channels. Default is 0.
-
-[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
-[2] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Example:
-
-pwm1: pwm@fe510000 {
- compatible = "st,pwm";
- reg = <0xfe510000 0x68>;
- #pwm-cells = <2>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm1_chan0_default
- &pinctrl_pwm1_chan1_default
- &pinctrl_pwm1_chan2_default
- &pinctrl_pwm1_chan3_default>;
- clocks = <&clk_sysin>;
- clock-names = "pwm";
- st,pwm-num-chan = <4>;
- st,capture-num-chan = <2>;
-};
diff --git a/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml b/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml
new file mode 100644
index 000000000000..e980c76b54e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/st,sti-pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STiH41x PWM/Capture controller
+
+maintainers:
+ - Lee Jones <lee.jones@linaro.org>
+
+description:
+ The STiH41x PWM controller supports both PWM output and input capture
+ functionality. It provides multiple PWM output channels for generating
+ variable duty-cycle waveforms, and multiple input capture channels for
+ measuring external signal periods and pulse widths. PWM output channels
+ and input capture channels are configured independently via
+ st,pwm-num-chan and st,capture-num-chan respectively.
+
+allOf:
+ - $ref: pwm.yaml#
+
+properties:
+ compatible:
+ const: st,sti-pwm
+
+ reg:
+ maxItems: 1
+
+ "#pwm-cells":
+ const: 2
+
+ pinctrl-names:
+ const: default
+
+ clock-names:
+ items:
+ enum: [pwm, capture]
+ minItems: 1
+ maxItems: 2
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ description: IRQ line for the capture device.
+ maxItems: 1
+
+ st,pwm-num-chan:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of available PWM output channels.
+ minimum: 0
+ maximum: 4
+ default: 0
+
+ st,capture-num-chan:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of available input capture channels.
+ minimum: 0
+ maximum: 4
+ default: 0
+
+required:
+ - reg
+ - compatible
+ - "#pwm-cells"
+ - clock-names
+ - clocks
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ pwm@fe510000 {
+ compatible = "st,sti-pwm";
+ reg = <0xfe510000 0x68>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1_chan0_default
+ &pinctrl_pwm1_chan1_default
+ &pinctrl_pwm1_chan2_default
+ &pinctrl_pwm1_chan3_default>;
+ clocks = <&clk_sysin>;
+ clock-names = "pwm";
+ st,pwm-num-chan = <4>;
+ st,capture-num-chan = <2>;
+ };
+...
---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260613-st-pwm-1feade6cfea3
Best regards,
--
Charan Pedumuru <charan.pedumuru@gmail.com>
^ permalink raw reply related
* Re: [PATCH 2/2] iio: adc: Add Nuvoton MA35D1 EADC driver
From: sashiko-bot @ 2026-06-25 11:20 UTC (permalink / raw)
To: Chi-Wen Weng; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260625110638.38438-3-cwweng.linux@gmail.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] Multi-channel buffered scans read stale or actively converting data for subsequent channels due to premature interrupt mapping.
- [High] Unpaced software re-triggering loop in the buffer interrupt handler causes an IRQ storm and livelock.
- [High] Missing sign-extension and incorrect scan type for negative differential readings.
- [High] Device suspend does not synchronize with ongoing direct conversions, leading to potential hardware aborts.
- [Medium] Differential negative channel configuration from device tree is accepted but completely ignored by hardware configuration.
--
commit 71778e9c3ef41a6d7da62ab5f861733a638e3f61
Author: Chi-Wen Weng <cwweng@nuvoton.com>
iio: adc: Add Nuvoton MA35D1 EADC driver
This patch adds an IIO driver for the Nuvoton MA35D1 Enhanced ADC
controller, supporting both direct reads and triggered buffered capture.
> diff --git a/drivers/iio/adc/ma35d1_eadc.c b/drivers/iio/adc/ma35d1_eadc.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/iio/adc/ma35d1_eadc.c
[ ... ]
> +static void ma35d1_adc_config_sample(struct ma35d1_adc *adc,
> + unsigned int sample, unsigned int channel)
> +{
> + u32 reg = MA35D1_EADC_SCTL(sample);
> +
> + ma35d1_adc_rmw(adc, reg,
> + MA35D1_EADC_SCTL_CHSEL_MASK |
> + MA35D1_EADC_SCTL_TRGSEL_MASK,
> + FIELD_PREP(MA35D1_EADC_SCTL_CHSEL_MASK, channel) |
> + MA35D1_EADC_SCTL_TRGSEL_ADINT0);
> +}
[Severity: Medium]
Will the hardware properly sample differential pairs if only the positive
channel is configured here?
The driver parses differential configurations using diff-channels and stores
the negative channel in chan->channel2, but only the positive channel is ever
written to the hardware CHSEL mask here.
If the hardware relies on arbitrary negative channel configurations rather
than fixed hardware pairings, the negative pin won't be sampled correctly.
Additionally, ma35d1_adc_parse_channels() doesn't seem to validate against
any fixed hardware pair requirements.
[ ... ]
> +static irqreturn_t ma35d1_adc_trigger_handler(int irq, void *p)
> +{
> + struct iio_poll_func *pf = p;
> + struct iio_dev *indio_dev = pf->indio_dev;
> + struct ma35d1_adc *adc = iio_priv(indio_dev);
> + int i;
> +
> + for (i = 0; i < adc->scan_chancnt; i++)
> + adc->scan.channels[i] =
> + ma35d1_adc_read(adc, MA35D1_EADC_DAT(i)) &
> + MA35D1_EADC_DAT_MASK;
[Severity: High]
Will this loop read stale or actively converting data for channels 1 through N
during multi-channel scans?
In ma35d1_adc_buffer_postenable(), the interrupt source is hardcoded to sample
module 0:
ma35d1_adc_rmw(adc, MA35D1_EADC_INTSRC0,
MA35D1_EADC_INTSRC0_ADINT0,
MA35D1_EADC_INTSRC0_ADINT0);
This means the interrupt fires as soon as the first channel finishes
converting. When this threaded handler wakes up and immediately reads all
DAT(i) registers, the subsequent sample modules may not have completed their
conversions yet.
> +
> + iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan, pf->timestamp);
> + iio_trigger_notify_done(adc->trig);
> +
> + ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCIEN0,
> + MA35D1_EADC_CTL_ADCIEN0);
> + ma35d1_adc_write(adc, MA35D1_EADC_SWTRG, 1);
[Severity: High]
Does unconditionally triggering the next conversion here cause an interrupt
storm?
Since the driver starts the conversion in postenable by writing SWTRG = 1,
and then unconditionally restarts it immediately at the end of the handler,
this creates a 0-delay free-running loop without any hardware timer or
pacing mechanism. This can livelock the system by flooding the CPU with
interrupts as fast as the ADC converts.
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int ma35d1_adc_read_conversion(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan,
> + int *val)
> +{
[ ... ]
> + timeout = wait_for_completion_interruptible_timeout(&adc->completion,
> + MA35D1_EADC_TIMEOUT);
> + ma35d1_adc_disable_irq(adc);
> +
> + if (timeout < 0)
> + return timeout;
> + if (!timeout)
> + return -ETIMEDOUT;
> +
> + *val = ma35d1_adc_read(adc, MA35D1_EADC_DAT(0)) & MA35D1_EADC_DAT_MASK;
[Severity: High]
Will this return massive positive values for negative differential readings?
Differential channels return two's complement values. Without using
sign_extend32() before assigning to the 32-bit *val, negative voltage
differences will be incorrectly returned to userspace as large positive
integers instead of signed values.
[ ... ]
> +static void ma35d1_adc_init_channel(struct ma35d1_adc *adc,
> + struct iio_chan_spec *chan, u32 vinp,
> + u32 vinn, int scan_index, bool differential)
> +{
[ ... ]
> + chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
> + chan->scan_type.sign = 'u';
[Severity: High]
Should differential channels be marked as signed instead of unsigned?
When differential is true, this forces the scan type sign to 'u', which
incorrectly informs the IIO subsystem that the differential data is unsigned
instead of two's complement.
[ ... ]
> +static int ma35d1_adc_suspend(struct device *dev)
> +{
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> + struct ma35d1_adc *adc = iio_priv(indio_dev);
> +
> + if (iio_buffer_enabled(indio_dev))
> + return -EBUSY;
> +
> + ma35d1_adc_hw_disable(adc);
> + clk_disable_unprepare(adc->clk);
[Severity: High]
Can this race with active direct conversions and cause a bus fault?
ma35d1_adc_suspend() disables the peripheral clock without acquiring
adc->lock or checking iio_device_claim_direct_mode().
If a concurrent direct read is waiting in ma35d1_adc_read_conversion():
timeout = wait_for_completion_interruptible_timeout(&adc->completion,
MA35D1_EADC_TIMEOUT);
ma35d1_adc_disable_irq(adc);
and suspend disables the clock, the wait may time out or be interrupted.
Accessing the ADC registers immediately afterward in ma35d1_adc_disable_irq()
with the clock disabled could result in a synchronous external abort.
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625110638.38438-1-cwweng.linux@gmail.com?part=2
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: iio: adc: Add Nuvoton MA35D1 EADC
From: sashiko-bot @ 2026-06-25 11:18 UTC (permalink / raw)
To: Chi-Wen Weng; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260625110638.38438-2-cwweng.linux@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Missing `resets` property for a hardware block that has a dedicated reset line.
--
commit 1f48c0ec2f3eb7b2358c1e0e2db87a26859d5fc5
Author: Chi-Wen Weng <cwweng@nuvoton.com>
dt-bindings: iio: adc: Add Nuvoton MA35D1 EADC
This commit adds the devicetree binding for the Enhanced ADC controller
found on Nuvoton MA35D1 SoCs. It describes the register region, interrupt,
functional clock, and standard channel child nodes.
> diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
> new file mode 100644
> index 0000000000000..ae7ad0f7689ab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
[ ... ]
> +properties:
> + compatible:
> + const: nuvoton,ma35d1-eadc
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + clocks:
> + maxItems: 1
[Severity: Low]
Is the resets property missing from this binding? The Nuvoton MA35D1 SoC
explicitly provides a reset line for the Enhanced ADC block (defined as
MA35D1_RESET_EADC0 in include/dt-bindings/reset/nuvoton,ma35d1-reset.h).
Should the resets property be declared here and added to the required list
to accurately reflect the hardware dependencies and avoid dt-schema
validation errors if a board uses the reset line?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625110638.38438-1-cwweng.linux@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v8 2/2] hwmon: Add Eswin EIC7700 PVT sensor driver
From: Julian Braha @ 2026-06-25 11:16 UTC (permalink / raw)
To: hehuan1, linux, robh, krzk+dt, conor+dt, p.zabel, linux-hwmon,
devicetree, linux-kernel
Cc: ningyu, linmin, pinkesh.vaghela, luyulin, dongxuyang
In-Reply-To: <20260625061214.1648-1-hehuan1@eswincomputing.com>
Hi Huan,
On 6/25/26 07:12, hehuan1@eswincomputing.com wrote:
> +config SENSORS_EIC7700_PVT
> + tristate "Eswin EIC7700 Voltage, Temperature sensor driver"
> + depends on ARCH_ESWIN || COMPILE_TEST
> + depends on HWMON
You already put SENSORS_EIC7700_PVT inside the 'if HWMON .. endif', so
you don't need the 'depends on HWMON'. It creates a duplicate
dependency.
- Julian Braha
^ permalink raw reply
* Re: [RFC PATCH 2/3] pinctrl: mediatek: mt8516/mt8167: Migrate driver to pinctrl-paris platform
From: sashiko-bot @ 2026-06-25 11:16 UTC (permalink / raw)
To: Luca Leonardo Scorcia; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260625104742.113803-3-l.scorcia@gmail.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [Critical] Pinmux mode field spacing is incorrectly changed from 4 bits to 3 bits per pin, corrupting all pinmux configurations.
- [High] Incorrect register bit offsets and widths for Drive Strength (DRV) and Slew Rate (SR) corrupt hardware configuration.
- [High] SMT register bit mappings are swapped between pins 106 and 109.
- [High] SMT bit mappings for MT8516 pins 70-73 (MSDC2 DAT) are incorrectly assigned the MT8167 layout, breaking MT8516 SD/eMMC.
- [High] Driver drops support for `mediatek,pctl-regmap` without providing a fallback, breaking ABI backward compatibility with existing device trees.
--
commit b99ee859c088809165f9a4794ca1471b372efd64
Author: Luca Leonardo Scorcia <l.scorcia@gmail.com>
pinctrl: mediatek: mt8516/mt8167: Migrate driver to pinctrl-paris platform
Migrate the mt8516/mt8167 pinctrl driver to the paris platform driver.
This change lets us correctly describe the two base addresses (GPIO/EINT)
used by the SoCs in their device tree. It also adds support for driving
strength capability and R1R0 pullup-pulldown on pins.
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8516.c b/drivers/pinctrl/mediatek/pinctrl-mt8516.c
> --- a/drivers/pinctrl/mediatek/pinctrl-mt8516.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8516.c
[ ... ]
> +static const struct mtk_pin_field_calc mt8516_pin_mode_range[] = {
> + PIN_FIELD15(0, 124, 0x300, 0x10, 0, 3),
> +};
[Severity: Critical]
Does this configuration cause a regression in pin multiplexing across the SoC?
The legacy driver used a 4-bit shift per pin to pack 5 pins per 32-bit
register. By passing 3 as the width here, the framework calculates mode
offsets using 3 bits per pin. This causes pinmux writes to align with
the wrong bits and can overwrite the configurations of adjacent pins.
[ ... ]
> +static const struct mtk_pin_field_calc mt8516_pin_smt_range[] = {
[ ... ]
> + PIN_FIELD16(70, 70, 0xa30, 0x10, 3, 1),
> + PIN_FIELD16(71, 71, 0xa30, 0x10, 4, 1),
> + PIN_FIELD16(72, 72, 0xa30, 0x10, 5, 1),
> + PIN_FIELD16(73, 73, 0xa30, 0x10, 6, 1),
[Severity: High]
Does this break the SMT configuration for the MT8516 MSDC2 interface?
The unified array assigns the MT8167 layout to pins 70-73 (bits 3, 4, 5, 6).
The MT8516 requires bits 6, 5, 4, 3, as defined in its IES layout and the
legacy driver.
[ ... ]
> + PIN_FIELD16(106, 106, 0xa20, 0x10, 13, 1),
> + PIN_FIELD16(107, 107, 0xa20, 0x10, 14, 1),
> + PIN_FIELD16(108, 108, 0xa20, 0x10, 15, 1),
> + PIN_FIELD16(109, 109, 0xa30, 0x10, 0, 1),
[Severity: High]
Are the SMT bits for pins 106 and 109 swapped?
In the IES range, pin 106 maps to 0x930 bit 0 and pin 109 maps to 0x920
bit 13. SMT layouts typically mirror IES layouts offset by 0x100.
The mappings here write to the wrong hardware bits for these pins.
[ ... ]
> +static const struct mtk_pin_field_calc mt8516_pin_drv_range[] = {
> + PINS_FIELD16(0, 4, 0xd00, 0x10, 0, 2),
[ ... ]
> +static const struct mtk_pin_field_calc mt8516_pin_sr_range[] = {
> + PINS_FIELD16(0, 4, 0xd00, 0x10, 3, 1),
[Severity: High]
Can this corrupt the Slew Rate hardware configuration?
Setting the Slew Rate offset to 3, and using a 2-bit width starting at bit 0
for the Drive Strength of these pins, differs from the hardware requirements.
Additionally, a 2-bit mask restricts DRV_GRP4 pins (such as MSDC) from
supporting drive strengths greater than 8mA, causing the framework to reject
higher values.
[ ... ]
> +static struct platform_driver mt8516_pinctrl_driver = {
> .driver = {
> .name = "mediatek-mt8516-pinctrl",
> - .of_match_table = mt8516_pctrl_match,
> - .pm = pm_sleep_ptr(&mtk_eint_pm_ops),
> + .of_match_table = mt8516_pinctrl_of_match,
> + .pm = pm_sleep_ptr(&mtk_paris_pinctrl_pm_ops),
> },
> + .probe = mtk_paris_pinctrl_probe,
> };
[Severity: High]
Will this migration cause probing to fail on older device trees?
The paris framework probe relies on devm_platform_ioremap_resource_byname
which strictly requires a reg-names property. The legacy driver supported a
mediatek,pctl-regmap fallback. Dropping this fallback might introduce a
regression with existing device trees lacking the reg-names property.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625104742.113803-1-l.scorcia@gmail.com?part=2
^ permalink raw reply
* Re: [PATCH v19 6/7] coresight: ctcu: enable byte-cntr for TMC ETR devices
From: sashiko-bot @ 2026-06-25 11:09 UTC (permalink / raw)
To: Jie Gan; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-6-8fbbf22e8381@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 11 potential issue(s) to consider:
- [Critical] Global function pointer accessed locklessly leads to Use-After-Free on driver unload
- [Critical] Global sysfs ops pointer triggers NULL pointer dereference on ETR without CTCU
- [High] Driver remove/unbind blocks indefinitely waiting for userspace file closure
- [High] ctcu_byte_cntr_stop() skips setting enable=false for SYSFS mode, causing infinite read hangs
- [High] TOCTOU race re-enables ETR hardware after framework disables it
- [High] Missing wake_up() in error path deadlocks driver remove()
- [High] Unsynchronized checks of irq_enabled lead to resource leaks and driver unbind hangs
- [High] Data race on concurrent read() calls causes NULL pointer dereference
- [Medium] Spurious Interrupt Handling due to missing hardware status check in shared IRQ
- [Medium] Error codes (-ERESTARTSYS) from byte_cntr_ops are swallowed and convert to EOF
- [Medium] Masked error code breaks sysfs reading fallback on memory failure
--
commit 128ffef0065b7b8a8c73e5e3f9b0ce8bebea0593
Author: Jie Gan <jie.gan@oss.qualcomm.com>
coresight: ctcu: enable byte-cntr for TMC ETR devices
This patch introduces the byte-cntr function provided by the CTCU device to
transfer data from the ETR buffer to userspace. It sets up an interrupt
handler to track data size thresholds and switches buffers when full or on
timeout. It also integrates with the TMC ETR framework via sysfs ops.
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
> new file mode 100644
> index 0000000000000..5ab97a71f02f6
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
[ ... ]
> +static irqreturn_t byte_cntr_handler(int irq, void *data)
> +{
> + struct ctcu_byte_cntr *byte_cntr_data = data;
> +
> + atomic_inc(&byte_cntr_data->irq_cnt);
> + wake_up(&byte_cntr_data->wq);
> +
> + return IRQ_HANDLED;
> +}
[Severity: Medium]
Is this handler missing a hardware status check?
Since the IRQ is registered with IRQF_SHARED, another device sharing the line
could fire an interrupt. By unconditionally returning IRQ_HANDLED without
verifying the interrupt source, the kernel's spurious interrupt detection
might be suppressed, and the CTCU buffer switch logic could be triggered
prematurely.
[ ... ]
> +static struct ctcu_byte_cntr *ctcu_get_byte_cntr(struct coresight_device *ctcu,
> + struct coresight_device *etr)
> +{
> + struct ctcu_drvdata *drvdata = dev_get_drvdata(ctcu->dev.parent);
[Severity: Critical]
Could this dereference a NULL pointer if an ETR without a connected CTCU
is used?
If the system has multiple ETRs and one lacks a CTCU, the globally registered
byte_cntr_sysfs_ops might pass a NULL ctcu pointer here. This would cause a
panic when ctcu->dev.parent is accessed.
[ ... ]
> +static bool ctcu_byte_cntr_switch_buffer(struct tmc_drvdata *etr_drvdata,
> + struct ctcu_byte_cntr *byte_cntr_data)
> +{
[ ... ]
> + raw_spin_unlock_irqrestore(&etr_drvdata->spinlock, flags);
> +
> + /* Restart the ETR once a free buffer is available */
> + if (found_free_buf &&
> + coresight_get_mode(etr_drvdata->csdev) != CS_MODE_DISABLED)
> + tmc_etr_enable_disable_hw(etr_drvdata, true);
> +
> + return found_free_buf;
> +}
[Severity: High]
Does this lockless check introduce a race condition?
If a concurrent operation disables the trace session and drops the lock before
setting the mode to CS_MODE_DISABLED, this code might incorrectly re-enable
the hardware after the framework has explicitly disabled it.
[ ... ]
> +static ssize_t tmc_byte_cntr_get_data(struct tmc_drvdata *etr_drvdata, loff_t pos,
> + size_t len, char **bufpp)
> +{
[ ... ]
> + pos = byte_cntr_data->buf_node->pos;
> + sysfs_buf = byte_cntr_data->buf_node->sysfs_buf;
> + actual = tmc_etr_read_sysfs_buf(sysfs_buf, pos, len, bufpp);
> + if (actual <= 0) {
> + /* Reset buf_node upon reading is finished or failed */
> + byte_cntr_data->buf_node->reading = false;
> + byte_cntr_data->buf_node = NULL;
[Severity: High]
Can concurrent read operations cause a NULL pointer dereference here?
If two threads read from the same ETR file descriptor, they could concurrently
access and modify byte_cntr_data->buf_node without serialization, causing one
thread to clear the pointer while the other is still using it.
[ ... ]
> +static int tmc_read_prepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int ret = 0;
> +
> + /* byte-cntr is operating with SYSFS mode being enabled only */
> + if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_SYSFS)
> + return -EINVAL;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
> + return -EINVAL;
> +
> + raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
[Severity: High]
Does checking irq_enabled outside the spinlock create a race?
A concurrent sysfs write could set irq_enabled to 0 immediately before the
lock is acquired. If reading is then set to true, read_unprepare() will later
abort early upon seeing irq_enabled is 0. This would leak the buffer list and
leave reading permanently true, causing the driver unbind to hang forever.
[ ... ]
> + byte_cntr_data->reading = true;
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + /* Setup an available etr_buf_list for byte-cntr */
> + ret = tmc_create_etr_buf_list(etr_drvdata, 2);
> + if (ret) {
> + byte_cntr_data->reading = false;
> + return ret;
> + }
[Severity: High]
Is this error path missing a wake_up() call?
If this allocation fails, the reading flag is cleared, but concurrent readers
waiting in the driver's remove function won't be notified, potentially
deadlocking the unbind process.
[ ... ]
> +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path)
> +{
> + struct coresight_device *sink = coresight_get_sink(path);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + if (coresight_get_mode(sink) == CS_MODE_SYSFS)
> + return;
[Severity: High]
Should the enable flag be cleared for SYSFS mode here?
By returning early, enable remains true. Readers waiting in
tmc_byte_cntr_get_data() might never receive the EOF condition when the
trace is stopped, causing them to loop indefinitely.
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index e8720026c9e3f..2da1a6f3d29f4 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
[ ... ]
> +static void ctcu_platform_remove(struct platform_device *pdev)
> +{
> + struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int i;
> +
> + if (WARN_ON(!drvdata))
> + return;
> +
> + /*
> + * Signal all active byte-cntr readers to exit, then wait for them to
> + * finish before resetting the ops pointer and freeing driver data.
> + * Without this, a reader blocked in wait_event_interruptible_timeout()
> + * would access the freed ctcu_drvdata wait-queue head (use-after-free).
> + */
> + for (i = 0; i < ETR_MAX_NUM; i++) {
> + byte_cntr_data = &drvdata->byte_cntr_data[i];
> + raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
> + /* Set enable=false for all ports to signal teardown to racing readers */
> + byte_cntr_data->enable = false;
> + if (!byte_cntr_data->reading) {
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + continue;
> + }
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> + wake_up_all(&byte_cntr_data->wq);
> + wait_event(byte_cntr_data->wq, !byte_cntr_data->reading);
> + }
[Severity: High]
Could this wait indefinitely during driver remove?
The reading flag is only cleared when the userspace file is closed. A
userspace process leaving the file descriptor open could permanently block
module unload or device unbind.
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 2b26ce6455a7b..e78f8891f11e0 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
[ ... ]
> +ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
> + loff_t pos, size_t len, char **bufpp)
> +{
> + ssize_t ret;
> + const struct tmc_sysfs_ops *byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> +
> + if (byte_cntr_ops) {
> + ret = byte_cntr_ops->get_trace_data(drvdata, pos, len, bufpp);
> + /* Return the filled buffer */
> + if (ret > 0 || ret == -ENOMEM)
> + return ret;
> + }
> +
> + return tmc_etr_read_sysfs_buf(drvdata->sysfs_buf, pos, len, bufpp);
> +}
[Severity: Medium]
Does this silently swallow -ERESTARTSYS?
If a signal interrupts the wait inside tmc_byte_cntr_get_data(), it returns
-ERESTARTSYS, which falls through here to a normal sysfs buffer read. This
might convert the signal into an EOF or return unsynced data instead of
letting userspace handle the signal cleanly.
[ ... ]
> +int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
> +{
> + int ret = 0;
> + unsigned long flags;
> + const struct tmc_sysfs_ops *byte_cntr_ops;
>
> /* config types are set a boot time and never change */
> if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
> return -EINVAL;
>
> + byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> + if (byte_cntr_ops) {
> + ret = byte_cntr_ops->read_prepare(drvdata);
[Severity: Critical]
Is it safe to access this global function pointer locklessly?
If the trace file is opened and the CTCU module is concurrently unloaded, the
memory backing byte_cntr_ops could be freed before read_prepare() executes,
leading to a use-after-free regression.
> + if (!ret || ret == -EBUSY)
> + return ret;
> +
> + ret = 0;
> + }
[Severity: Medium]
Why are errors like -ENOMEM from read_prepare() masked here?
If the memory allocation fails inside tmc_read_prepare_byte_cntr(), hiding the
error breaks the fallback sysfs reading path, leading to delays and hanging
operations instead of propagating the failure properly.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com?part=6
^ permalink raw reply
* Re: [RFC PATCH 3/3] arm64: dts: mt8516/mt8167: Update pinctrl nodes for the new paris driver
From: sashiko-bot @ 2026-06-25 11:07 UTC (permalink / raw)
To: Luca Leonardo Scorcia; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260625104742.113803-4-l.scorcia@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `gpio-ranges` property incorrectly specifies a count of 124, which excludes the final pin (GPIO 124) from being mapped to the GPIO subsystem, as the drivers define exactly 125 pins.
--
commit 36a8d0bd5d2cccdc70b499936029deb0499393de
Author: Luca Leonardo Scorcia <l.scorcia@gmail.com>
arm64: dts: mt8516/mt8167: Update pinctrl nodes for the new paris driver
This patch updates the MediaTek mt8516 and mt8167 SoC descriptions to
respect the constraints of the Paris pinctrl driver. It sets separate base
and eint registers and removes the deprecated syscfg_pctl syscon node.
> diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> index b5e753759465d..63f36df4d1b48 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
[ ... ]
> @@ -231,17 +231,13 @@ keypad: keypad@10002000 {
> status = "disabled";
> };
>
> - syscfg_pctl: syscfg-pctl@10005000 {
> - compatible = "syscon";
> - reg = <0 0x10005000 0 0x1000>;
> - };
> -
> - pio: pinctrl@1000b000 {
> + pio: pinctrl@10005000 {
> compatible = "mediatek,mt8516-pinctrl";
> - reg = <0 0x1000b000 0 0x1000>;
> - mediatek,pctl-regmap = <&syscfg_pctl>;
> + reg = <0 0x10005000 0 0x1000>, <0 0x1000b000 0 0x1000>;
> + reg-names = "base", "eint";
> gpio-controller;
> #gpio-cells = <2>;
> + gpio-ranges = <&pio 0 0 124>;
[Severity: Medium]
Does this count parameter accidentally exclude the final pin (GPIO 124) from
being mapped to the GPIO subsystem?
Looking at the driver definitions for the MT8516 and MT8167 platforms, there
are exactly 125 pins defined. A count of 124 will prevent the mapping of the
final pin, causing any driver or application attempting to request GPIO 124 to
fail. Since mt8167.dtsi includes mt8516.dtsi, this affects both SoCs.
Should this count parameter be 125 instead?
> interrupt-controller;
> #interrupt-cells = <2>;
> interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625104742.113803-1-l.scorcia@gmail.com?part=3
^ permalink raw reply
* Re: [PATCH v19 1/7] coresight: core: refactor ctcu_get_active_port and make it generic
From: sashiko-bot @ 2026-06-25 11:07 UTC (permalink / raw)
To: Jie Gan; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-1-8fbbf22e8381@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] Lockless iteration over `pdata->in_conns` array introduces a TOCTOU race condition and potential Use-After-Free.
Pre-existing issues:
- [High] Missing bounds check for Device Tree-provided `port_num` leads to out-of-bounds array access in CTCU trace ID configuration.
- [High] Unsafe direct dereference of sparse array elements in `tpda_get_element_size`.
--
commit f655e6df0885045f179728cb52f455717556ac67
Author: Jie Gan <jie.gan@oss.qualcomm.com>
coresight: core: refactor ctcu_get_active_port and make it generic
This patch removes ctcu_get_active_port from the CTCU module and adds it to
the core framework as coresight_get_in_port. It allows retrieving the active
input port number generically for a given device.
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index 6d65c43d574fd..7a7a85acdca0d 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -773,6 +773,33 @@ struct coresight_device *coresight_get_sink(struct coresight_path *path)
[ ... ]
> +int coresight_get_in_port(struct coresight_device *csdev,
> + struct coresight_device *remote)
> +{
> + struct coresight_platform_data *pdata = remote->pdata;
> + int i;
> +
> + for (i = 0; i < pdata->nr_inconns; ++i) {
> + if (!pdata->in_conns[i])
> + continue;
> +
> + if (pdata->in_conns[i]->src_dev == csdev)
[Severity: High]
Can this sequence cause a race condition leading to a NULL pointer
dereference?
The array element is read twice. First, to check if it's NULL, and then
again to access src_dev. If a concurrent device unbind operation like
coresight_remove_conns() sets the element to NULL between these reads, the
second access might trigger a panic.
Should we use READ_ONCE() to load the pointer into a local variable first?
> + return pdata->in_conns[i]->dest_port;
> + }
> +
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL_GPL(coresight_get_in_port);
> +
> u32 coresight_get_sink_id(struct coresight_device *csdev)
> {
> if (!csdev->ea)
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index 9043cad42f01e..e8720026c9e3f 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
[ ... ]
> @@ -145,7 +128,7 @@ static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight
> return -EINVAL;
> }
>
> - port_num = ctcu_get_active_port(sink, csdev);
> + port_num = coresight_get_in_port(sink, csdev);
> if (port_num < 0)
> return -EINVAL;
[Severity: High]
This isn't a bug introduced by this patch, but does the returned
port_num need to be bounds-checked before being used?
The port_num originates from device tree properties, and if it exceeds
ETR_MAX_NUM (2), it leads to out-of-bounds array accesses in
__ctcu_set_etr_traceid() when indexing into drvdata->atid_offset and
drvdata->traceid_refcnt:
__ctcu_set_etr_traceid()
...
atid_offset = drvdata->atid_offset[port_num];
...
refcnt = drvdata->traceid_refcnt[port_num][traceid];
Would it be safer to validate port_num against the array bounds after
retrieving it?
>
[ ... ]
[Severity: High]
This is a pre-existing issue not introduced by this patch, but while
looking at the sparse in_conns array usage, I noticed a similar issue in
tpda_get_element_size().
Does this code dereference the sparse array element before checking if it
is valid?
drivers/hwtracing/coresight/coresight-tpda.c:tpda_get_element_size() {
...
for (i = 0; i < csdev->pdata->nr_inconns; i++) {
in = csdev->pdata->in_conns[i]->src_dev;
if (!in)
continue;
...
}
If a component is unbound and the connection is removed by
coresight_remove_conns(), csdev->pdata->in_conns[i] could be NULL,
causing a panic before the check is reached.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com?part=1
^ permalink raw reply
* [PATCH 2/2] iio: adc: Add Nuvoton MA35D1 EADC driver
From: Chi-Wen Weng @ 2026-06-25 11:06 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: dlechner, nuno.sa, andy, linux-arm-kernel, linux-iio, devicetree,
linux-kernel, cwweng, cwweng.linux
In-Reply-To: <20260625110638.38438-1-cwweng.linux@gmail.com>
From: Chi-Wen Weng <cwweng@nuvoton.com>
Add an IIO driver for the Nuvoton MA35D1 Enhanced ADC controller.
The driver supports direct raw reads and triggered buffered capture. The
controller end-of-conversion interrupt is exposed as the device trigger
and is used to push samples into the IIO buffer.
Channels are described by firmware child nodes and can be configured as
single-ended or differential inputs. Since the differential enable bit is
global, mixed single-ended and differential buffered scans are rejected.
DMA support is intentionally not included in this initial upstream driver;
conversions are handled through the interrupt-driven path.
Signed-off-by: Chi-Wen Weng <cwweng@nuvoton.com>
---
drivers/iio/adc/Kconfig | 10 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/ma35d1_eadc.c | 636 ++++++++++++++++++++++++++++++++++
3 files changed, 647 insertions(+)
create mode 100644 drivers/iio/adc/ma35d1_eadc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 1c663c98c6c9..43409999a94b 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -981,6 +981,16 @@ config LTC2497
To compile this driver as a module, choose M here: the module will be
called ltc2497.
+config MA35D1_EADC
+ tristate "MA35D1 EADC driver"
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for MA35D1 EADC.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ma35d1.
+
config MAX1027
tristate "Maxim max1027 ADC driver"
depends on SPI
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 707dd708912f..7b9b38688223 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_LTC2471) += ltc2471.o
obj-$(CONFIG_LTC2485) += ltc2485.o
obj-$(CONFIG_LTC2496) += ltc2496.o ltc2497-core.o
obj-$(CONFIG_LTC2497) += ltc2497.o ltc2497-core.o
+obj-$(CONFIG_MA35D1_EADC) += ma35d1_eadc.o
obj-$(CONFIG_MAX1027) += max1027.o
obj-$(CONFIG_MAX11100) += max11100.o
obj-$(CONFIG_MAX1118) += max1118.o
diff --git a/drivers/iio/adc/ma35d1_eadc.c b/drivers/iio/adc/ma35d1_eadc.c
new file mode 100644
index 000000000000..0c075126e139
--- /dev/null
+++ b/drivers/iio/adc/ma35d1_eadc.c
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Nuvoton MA35D1 EADC driver
+ *
+ * Copyright (c) 2026 Nuvoton Technology Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/bitmap.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/property.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define MA35D1_EADC_DAT(n) (0x00 + (n) * 0x04)
+#define MA35D1_EADC_CTL 0x50
+#define MA35D1_EADC_SWTRG 0x54
+#define MA35D1_EADC_SCTL(n) (0x80 + (n) * 0x04)
+#define MA35D1_EADC_INTSRC0 0xd0
+#define MA35D1_EADC_STATUS2 0xf8
+#define MA35D1_EADC_SELSMP0 0x140
+#define MA35D1_EADC_REFADJCTL 0x150
+
+#define MA35D1_EADC_CTL_ADCEN BIT(0)
+#define MA35D1_EADC_CTL_ADCIEN0 BIT(2)
+#define MA35D1_EADC_CTL_DIFFEN BIT(8)
+
+#define MA35D1_EADC_SCTL_CHSEL_MASK GENMASK(3, 0)
+#define MA35D1_EADC_SCTL_TRGDLY_MASK GENMASK(15, 8)
+#define MA35D1_EADC_SCTL_TRGSEL_MASK GENMASK(21, 16)
+#define MA35D1_EADC_SCTL_TRGSEL_ADINT0 \
+ FIELD_PREP(MA35D1_EADC_SCTL_TRGSEL_MASK, 2)
+
+#define MA35D1_EADC_DAT_MASK GENMASK(11, 0)
+#define MA35D1_EADC_STATUS2_ADIF0 BIT(0)
+#define MA35D1_EADC_INTSRC0_ADINT0 BIT(0)
+#define MA35D1_EADC_REFADJCTL_EXT_VREF BIT(0)
+
+#define MA35D1_EADC_MAX_CHANNELS 9
+#define MA35D1_EADC_MAX_SAMPLE_MODULES 16
+#define MA35D1_EADC_CHAN_NAME_LEN 16
+#define MA35D1_EADC_TIMEOUT msecs_to_jiffies(1000)
+
+struct ma35d1_adc {
+ struct device *dev;
+ void __iomem *regs;
+ struct clk *clk;
+ struct completion completion;
+ /* Protects direct conversions against concurrent register access. */
+ struct mutex lock;
+ struct iio_trigger *trig;
+ unsigned int scan_chancnt;
+ bool scan_differential;
+ char chan_name[MA35D1_EADC_MAX_CHANNELS][MA35D1_EADC_CHAN_NAME_LEN];
+ struct {
+ u16 channels[MA35D1_EADC_MAX_SAMPLE_MODULES];
+ aligned_s64 timestamp;
+ } scan;
+};
+
+static inline u32 ma35d1_adc_read(struct ma35d1_adc *adc, u32 reg)
+{
+ return readl(adc->regs + reg);
+}
+
+static inline void ma35d1_adc_write(struct ma35d1_adc *adc, u32 reg, u32 val)
+{
+ writel(val, adc->regs + reg);
+}
+
+static void ma35d1_adc_rmw(struct ma35d1_adc *adc, u32 reg, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ tmp = ma35d1_adc_read(adc, reg);
+ tmp &= ~mask;
+ tmp |= val;
+ ma35d1_adc_write(adc, reg, tmp);
+}
+
+static void ma35d1_adc_set_diff(struct ma35d1_adc *adc, bool differential)
+{
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_DIFFEN,
+ differential ? MA35D1_EADC_CTL_DIFFEN : 0);
+}
+
+static void ma35d1_adc_config_sample(struct ma35d1_adc *adc,
+ unsigned int sample, unsigned int channel)
+{
+ u32 reg = MA35D1_EADC_SCTL(sample);
+
+ ma35d1_adc_rmw(adc, reg,
+ MA35D1_EADC_SCTL_CHSEL_MASK |
+ MA35D1_EADC_SCTL_TRGSEL_MASK,
+ FIELD_PREP(MA35D1_EADC_SCTL_CHSEL_MASK, channel) |
+ MA35D1_EADC_SCTL_TRGSEL_ADINT0);
+}
+
+static void ma35d1_adc_disable_irq(struct ma35d1_adc *adc)
+{
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCIEN0, 0);
+}
+
+static void ma35d1_adc_hw_init(struct ma35d1_adc *adc)
+{
+ ma35d1_adc_disable_irq(adc);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL,
+ MA35D1_EADC_CTL_ADCEN, MA35D1_EADC_CTL_ADCEN);
+ ma35d1_adc_write(adc, MA35D1_EADC_STATUS2, MA35D1_EADC_STATUS2_ADIF0);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_INTSRC0,
+ MA35D1_EADC_INTSRC0_ADINT0,
+ MA35D1_EADC_INTSRC0_ADINT0);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_REFADJCTL,
+ MA35D1_EADC_REFADJCTL_EXT_VREF,
+ MA35D1_EADC_REFADJCTL_EXT_VREF);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_SELSMP0, GENMASK(1, 0), 3);
+}
+
+static void ma35d1_adc_hw_disable(void *data)
+{
+ struct ma35d1_adc *adc = data;
+
+ ma35d1_adc_disable_irq(adc);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCEN, 0);
+}
+
+static irqreturn_t ma35d1_adc_isr(int irq, void *data)
+{
+ struct iio_dev *indio_dev = data;
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ u32 status;
+
+ status = ma35d1_adc_read(adc, MA35D1_EADC_STATUS2);
+ if (!(status & MA35D1_EADC_STATUS2_ADIF0))
+ return IRQ_NONE;
+
+ ma35d1_adc_write(adc, MA35D1_EADC_STATUS2, MA35D1_EADC_STATUS2_ADIF0);
+
+ if (iio_buffer_enabled(indio_dev)) {
+ ma35d1_adc_disable_irq(adc);
+ iio_trigger_poll(adc->trig);
+ } else {
+ complete(&adc->completion);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ma35d1_adc_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int i;
+
+ for (i = 0; i < adc->scan_chancnt; i++)
+ adc->scan.channels[i] =
+ ma35d1_adc_read(adc, MA35D1_EADC_DAT(i)) &
+ MA35D1_EADC_DAT_MASK;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan, pf->timestamp);
+ iio_trigger_notify_done(adc->trig);
+
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCIEN0,
+ MA35D1_EADC_CTL_ADCIEN0);
+ ma35d1_adc_write(adc, MA35D1_EADC_SWTRG, 1);
+
+ return IRQ_HANDLED;
+}
+
+static int ma35d1_adc_read_conversion(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ long timeout;
+
+ reinit_completion(&adc->completion);
+
+ ma35d1_adc_write(adc, MA35D1_EADC_STATUS2, MA35D1_EADC_STATUS2_ADIF0);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_SCTL(0),
+ MA35D1_EADC_SCTL_CHSEL_MASK |
+ MA35D1_EADC_SCTL_TRGSEL_MASK,
+ FIELD_PREP(MA35D1_EADC_SCTL_CHSEL_MASK,
+ chan->channel));
+ ma35d1_adc_set_diff(adc, chan->differential);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCIEN0,
+ MA35D1_EADC_CTL_ADCIEN0);
+ ma35d1_adc_write(adc, MA35D1_EADC_SWTRG, 1);
+
+ timeout = wait_for_completion_interruptible_timeout(&adc->completion,
+ MA35D1_EADC_TIMEOUT);
+ ma35d1_adc_disable_irq(adc);
+
+ if (timeout < 0)
+ return timeout;
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ *val = ma35d1_adc_read(adc, MA35D1_EADC_DAT(0)) & MA35D1_EADC_DAT_MASK;
+
+ return 0;
+}
+
+static int ma35d1_adc_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (!iio_device_claim_direct(indio_dev))
+ return -EBUSY;
+
+ mutex_lock(&adc->lock);
+ ret = ma35d1_adc_read_conversion(indio_dev, chan, val);
+ mutex_unlock(&adc->lock);
+
+ iio_device_release_direct(indio_dev);
+ if (ret)
+ return ret;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int ma35d1_adc_validate_scan(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ const struct iio_chan_spec *chan;
+ bool have_single = false;
+ bool have_diff = false;
+ unsigned int count = 0;
+ unsigned long bit;
+
+ for_each_set_bit(bit, scan_mask, indio_dev->masklength) {
+ chan = &indio_dev->channels[bit];
+
+ if (chan->type == IIO_TIMESTAMP)
+ continue;
+ count++;
+ if (chan->differential)
+ have_diff = true;
+ else
+ have_single = true;
+ }
+
+ if (!count || count > MA35D1_EADC_MAX_SAMPLE_MODULES)
+ return -EINVAL;
+
+ if (have_single && have_diff)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ma35d1_adc_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *scan_mask)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ const struct iio_chan_spec *chan;
+ unsigned int sample = 0;
+ unsigned long bit;
+ bool differential = false;
+ int ret;
+
+ ret = ma35d1_adc_validate_scan(indio_dev, scan_mask);
+ if (ret)
+ return ret;
+
+ for_each_set_bit(bit, scan_mask, indio_dev->masklength) {
+ chan = &indio_dev->channels[bit];
+ if (chan->type == IIO_TIMESTAMP)
+ continue;
+
+ if (!sample)
+ differential = chan->differential;
+
+ ma35d1_adc_config_sample(adc, sample, chan->channel);
+ sample++;
+ }
+
+ adc->scan_chancnt = sample;
+ adc->scan_differential = differential;
+
+ return 0;
+}
+
+static int ma35d1_adc_buffer_postenable(struct iio_dev *indio_dev)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int i;
+
+ if (!adc->scan_chancnt)
+ return -EINVAL;
+
+ ma35d1_adc_write(adc, MA35D1_EADC_STATUS2, MA35D1_EADC_STATUS2_ADIF0);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_INTSRC0,
+ MA35D1_EADC_INTSRC0_ADINT0,
+ MA35D1_EADC_INTSRC0_ADINT0);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_REFADJCTL,
+ MA35D1_EADC_REFADJCTL_EXT_VREF,
+ MA35D1_EADC_REFADJCTL_EXT_VREF);
+ ma35d1_adc_rmw(adc, MA35D1_EADC_SELSMP0, GENMASK(1, 0), 3);
+ ma35d1_adc_set_diff(adc, adc->scan_differential);
+
+ for (i = 0; i < adc->scan_chancnt; i++)
+ ma35d1_adc_rmw(adc, MA35D1_EADC_SCTL(i),
+ MA35D1_EADC_SCTL_TRGDLY_MASK,
+ MA35D1_EADC_SCTL_TRGDLY_MASK);
+
+ ma35d1_adc_rmw(adc, MA35D1_EADC_CTL, MA35D1_EADC_CTL_ADCIEN0,
+ MA35D1_EADC_CTL_ADCIEN0);
+ ma35d1_adc_write(adc, MA35D1_EADC_SWTRG, 1);
+
+ return 0;
+}
+
+static int ma35d1_adc_buffer_predisable(struct iio_dev *indio_dev)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int i;
+
+ ma35d1_adc_disable_irq(adc);
+ for (i = 0; i < adc->scan_chancnt; i++)
+ ma35d1_adc_rmw(adc, MA35D1_EADC_SCTL(i),
+ MA35D1_EADC_SCTL_TRGSEL_MASK, 0);
+
+ return 0;
+}
+
+static const struct iio_buffer_setup_ops ma35d1_adc_buffer_ops = {
+ .postenable = ma35d1_adc_buffer_postenable,
+ .predisable = ma35d1_adc_buffer_predisable,
+};
+
+static const struct iio_info ma35d1_adc_info = {
+ .read_raw = ma35d1_adc_read_raw,
+ .update_scan_mode = ma35d1_adc_update_scan_mode,
+};
+
+static const struct iio_trigger_ops ma35d1_adc_trigger_ops = {
+ .validate_device = iio_trigger_validate_own_device,
+};
+
+static void ma35d1_adc_init_channel(struct ma35d1_adc *adc,
+ struct iio_chan_spec *chan, u32 vinp,
+ u32 vinn, int scan_index, bool differential)
+{
+ char *name = adc->chan_name[vinp];
+
+ chan->type = IIO_VOLTAGE;
+ chan->indexed = 1;
+ chan->channel = vinp;
+ chan->address = vinp;
+ chan->scan_index = scan_index;
+ chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+ chan->scan_type.sign = 'u';
+ chan->scan_type.realbits = 12;
+ chan->scan_type.storagebits = 16;
+ chan->scan_type.endianness = IIO_CPU;
+
+ if (differential) {
+ chan->differential = 1;
+ chan->channel2 = vinn;
+ snprintf(name, MA35D1_EADC_CHAN_NAME_LEN, "in%d-in%d", vinp,
+ vinn);
+ } else {
+ snprintf(name, MA35D1_EADC_CHAN_NAME_LEN, "in%d", vinp);
+ }
+
+ chan->datasheet_name = name;
+}
+
+static int ma35d1_adc_parse_channels(struct iio_dev *indio_dev,
+ struct device *dev)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ DECLARE_BITMAP(used_channels, MA35D1_EADC_MAX_CHANNELS);
+ struct fwnode_handle *child;
+ struct iio_chan_spec *channels;
+ int num_channels;
+ int scan_index = 0;
+ int ret;
+
+ bitmap_zero(used_channels, MA35D1_EADC_MAX_CHANNELS);
+
+ num_channels = device_get_child_node_count(dev);
+ if (!num_channels)
+ return dev_err_probe(dev, -ENODATA,
+ "no ADC channels configured\n");
+
+ if (num_channels > MA35D1_EADC_MAX_CHANNELS)
+ return dev_err_probe(dev, -EINVAL, "too many ADC channels\n");
+
+ channels = devm_kcalloc(dev, num_channels + 1, sizeof(*channels),
+ GFP_KERNEL);
+ if (!channels)
+ return -ENOMEM;
+
+ device_for_each_child_node(dev, child) {
+ u32 diff[2];
+ u32 reg;
+ bool differential = false;
+
+ ret = fwnode_property_read_u32(child, "reg", ®);
+ if (ret) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, ret,
+ "missing channel reg property\n");
+ }
+
+ if (reg >= MA35D1_EADC_MAX_CHANNELS) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, -EINVAL,
+ "invalid ADC channel %u\n", reg);
+ }
+
+ if (test_and_set_bit(reg, used_channels)) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, -EINVAL,
+ "duplicate ADC channel %u\n", reg);
+ }
+
+ if (fwnode_property_present(child, "diff-channels")) {
+ ret = fwnode_property_read_u32_array(child,
+ "diff-channels",
+ diff,
+ ARRAY_SIZE(diff));
+ if (ret) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, ret,
+ "invalid diff-channels for channel %u\n",
+ reg);
+ }
+
+ if (diff[0] != reg ||
+ diff[1] >= MA35D1_EADC_MAX_CHANNELS ||
+ diff[0] == diff[1]) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, -EINVAL,
+ "invalid differential ADC channel %u-%u\n",
+ diff[0], diff[1]);
+ }
+
+ if (test_and_set_bit(diff[1], used_channels)) {
+ fwnode_handle_put(child);
+ return dev_err_probe(dev, -EINVAL,
+ "ADC channel %u already used\n",
+ diff[1]);
+ }
+
+ differential = true;
+ }
+
+ ma35d1_adc_init_channel(adc, &channels[scan_index], reg,
+ differential ? diff[1] : 0,
+ scan_index, differential);
+ scan_index++;
+ }
+
+ channels[scan_index] = (struct iio_chan_spec)
+ IIO_CHAN_SOFT_TIMESTAMP(scan_index);
+
+ indio_dev->channels = channels;
+ indio_dev->num_channels = scan_index + 1;
+ indio_dev->masklength = indio_dev->num_channels;
+
+ return 0;
+}
+
+static int ma35d1_adc_setup_trigger(struct iio_dev *indio_dev,
+ struct device *dev)
+{
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int ret;
+
+ adc->trig = devm_iio_trigger_alloc(dev, "%s-trigger", dev_name(dev));
+ if (!adc->trig)
+ return -ENOMEM;
+
+ adc->trig->ops = &ma35d1_adc_trigger_ops;
+ iio_trigger_set_drvdata(adc->trig, indio_dev);
+
+ ret = devm_iio_trigger_register(dev, adc->trig);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register trigger\n");
+
+ ret = iio_trigger_set_immutable(indio_dev, adc->trig);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to set trigger\n");
+
+ return 0;
+}
+
+static int ma35d1_adc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct iio_dev *indio_dev;
+ struct ma35d1_adc *adc;
+ int irq;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+ if (!indio_dev)
+ return -ENOMEM;
+ adc = iio_priv(indio_dev);
+ adc->dev = dev;
+ mutex_init(&adc->lock);
+ init_completion(&adc->completion);
+
+ adc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(adc->regs))
+ return dev_err_probe(dev, PTR_ERR(adc->regs),
+ "failed to map registers\n");
+
+ adc->clk = devm_clk_get_enabled(dev, NULL);
+ if (IS_ERR(adc->clk))
+ return dev_err_probe(dev, PTR_ERR(adc->clk),
+ "failed to get and enable ADC clock\n");
+
+ indio_dev->name = "ma35d1-eadc";
+ indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
+ indio_dev->info = &ma35d1_adc_info;
+
+ ret = ma35d1_adc_parse_channels(indio_dev, dev);
+ if (ret)
+ return ret;
+
+ ma35d1_adc_hw_init(adc);
+
+ ret = devm_add_action_or_reset(dev, ma35d1_adc_hw_disable, adc);
+ if (ret)
+ return ret;
+
+ ret = ma35d1_adc_setup_trigger(indio_dev, dev);
+ if (ret)
+ return ret;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_irq(dev, irq, ma35d1_adc_isr, 0, dev_name(dev),
+ indio_dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to request IRQ %d\n", irq);
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
+ iio_pollfunc_store_time,
+ ma35d1_adc_trigger_handler,
+ &ma35d1_adc_buffer_ops);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "failed to setup triggered buffer\n");
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ ret = devm_iio_device_register(dev, indio_dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to register IIO device\n");
+
+ return 0;
+}
+
+static int ma35d1_adc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+
+ if (iio_buffer_enabled(indio_dev))
+ return -EBUSY;
+
+ ma35d1_adc_hw_disable(adc);
+ clk_disable_unprepare(adc->clk);
+
+ return 0;
+}
+
+static int ma35d1_adc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct ma35d1_adc *adc = iio_priv(indio_dev);
+ int ret;
+
+ ret = clk_prepare_enable(adc->clk);
+ if (ret)
+ return ret;
+
+ ma35d1_adc_hw_init(adc);
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(ma35d1_adc_pm_ops,
+ ma35d1_adc_suspend, ma35d1_adc_resume);
+
+static const struct of_device_id ma35d1_adc_of_match[] = {
+ { .compatible = "nuvoton,ma35d1-eadc" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ma35d1_adc_of_match);
+
+static struct platform_driver ma35d1_adc_driver = {
+ .probe = ma35d1_adc_probe,
+ .driver = {
+ .name = "ma35d1-eadc",
+ .of_match_table = ma35d1_adc_of_match,
+ .pm = pm_sleep_ptr(&ma35d1_adc_pm_ops),
+ },
+};
+module_platform_driver(ma35d1_adc_driver);
+
+MODULE_AUTHOR("Chi-Wen Weng <cwweng@nuvoton.com>");
+MODULE_DESCRIPTION("Nuvoton MA35D1 EADC driver");
+MODULE_LICENSE("GPL");
--
2.25.1
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: iio: adc: Add Nuvoton MA35D1 EADC
From: Chi-Wen Weng @ 2026-06-25 11:06 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: dlechner, nuno.sa, andy, linux-arm-kernel, linux-iio, devicetree,
linux-kernel, cwweng, cwweng.linux
In-Reply-To: <20260625110638.38438-1-cwweng.linux@gmail.com>
From: Chi-Wen Weng <cwweng@nuvoton.com>
Add devicetree binding for the Enhanced ADC controller found on
Nuvoton MA35D1 SoCs.
The controller has one register region, one interrupt and one functional
clock. ADC inputs are described using standard channel child nodes,
including optional differential channel pairs.
Signed-off-by: Chi-Wen Weng <cwweng@nuvoton.com>
---
.../bindings/iio/adc/nuvoton,ma35d1-eadc.yaml | 100 ++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
diff --git a/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml b/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
new file mode 100644
index 000000000000..ae7ad0f7689a
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/nuvoton,ma35d1-eadc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton MA35D1 Enhanced Analog to Digital Converter
+
+maintainers:
+ - Chi-Wen Weng <cwweng@nuvoton.com>
+
+description: |
+ The Nuvoton MA35D1 Enhanced Analog to Digital Converter (EADC) is a
+ 12-bit ADC controller integrated in the MA35D1 SoC. Each enabled ADC
+ input is described by a child channel node.
+
+properties:
+ compatible:
+ const: nuvoton,ma35d1-eadc
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+patternProperties:
+ '^channel@[0-8]$':
+ type: object
+ $ref: adc.yaml
+ unevaluatedProperties: false
+
+ properties:
+ reg:
+ minimum: 0
+ maximum: 8
+
+ diff-channels:
+ minItems: 2
+ maxItems: 2
+ items:
+ minimum: 0
+ maximum: 8
+
+ required:
+ - reg
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - '#address-cells'
+ - '#size-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ adc@40430000 {
+ compatible = "nuvoton,ma35d1-eadc";
+ reg = <0x0 0x40430000 0x0 0x10000>;
+ interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clk EADC_GATE>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0>;
+ };
+
+ channel@1 {
+ reg = <1>;
+ };
+
+ channel@2 {
+ reg = <2>;
+ diff-channels = <2 3>;
+ };
+ };
+ };
+...
--
2.25.1
^ permalink raw reply related
* [PATCH 0/2] iio: adc: Add Nuvoton MA35D1 EADC support
From: Chi-Wen Weng @ 2026-06-25 11:06 UTC (permalink / raw)
To: jic23, robh, krzk+dt, conor+dt
Cc: dlechner, nuno.sa, andy, linux-arm-kernel, linux-iio, devicetree,
linux-kernel, cwweng, cwweng.linux
From: Chi-Wen Weng <cwweng@nuvoton.com>
This series adds devicetree binding and IIO driver support for the
Nuvoton MA35D1 Enhanced ADC controller.
The MA35D1 EADC controller supports multiple ADC input channels. This
initial upstream driver supports direct raw reads and triggered buffered
capture using the controller end-of-conversion interrupt as the IIO
device trigger.
ADC channels are described using standard firmware child nodes. Both
single-ended and differential channels are supported. Since the
differential enable bit is global in the controller, mixed single-ended
and differential buffered scans are rejected.
DMA support is intentionally not included in this initial version. The
driver uses the interrupt-driven conversion path to keep the first
upstream submission small and easier to review.
Patch 1 adds the devicetree binding.
Patch 2 adds the MA35D1 EADC IIO driver.
Chi-Wen Weng (2):
dt-bindings: iio: adc: Add Nuvoton MA35D1 EADC
iio: adc: Add Nuvoton MA35D1 EADC driver
.../bindings/iio/adc/nuvoton,ma35d1-eadc.yaml | 100 +++
drivers/iio/adc/Kconfig | 10 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/ma35d1_eadc.c | 636 ++++++++++++++++++
4 files changed, 747 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/nuvoton,ma35d1-eadc.yaml
create mode 100644 drivers/iio/adc/ma35d1_eadc.c
--
2.25.1
^ permalink raw reply
* Re: [PATCH v19 2/7] coresight: tmc: add create/clean functions for etr_buf_list
From: sashiko-bot @ 2026-06-25 11:06 UTC (permalink / raw)
To: Jie Gan; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-2-8fbbf22e8381@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Lockless read of `drvdata->sysfs_buf` in `tmc_create_etr_buf_list` leads to a Time-of-Check to Time-of-Use race condition, resulting in a Double-Free or Use-After-Free.
- [Medium] The error path in `tmc_create_etr_buf_list` destructively frees the pre-existing `drvdata->sysfs_buf` if the device becomes inactive, leading to the irreversible loss of previously captured trace data.
- [Medium] `tmc_clean_etr_buf_list` leaks `drvdata->sysfs_buf` if called when the device is active in a non-SYSFS mode (e.g., `CS_MODE_PERF`).
--
commit efe04b42620438e6e268cf24ebf0538327ca8629
Author: Jie Gan <jie.gan@oss.qualcomm.com>
coresight: tmc: add create/clean functions for etr_buf_list
This commit introduces functions for creating and cleaning a list of
etr_buf_node elements to manage etr_buf entries. It is intended to support
byte-counter functionality which requires multiple trace data buffers.
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 361a433e6f0c5..9b3ef73e9cf27 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
[ ... ]
> @@ -1918,6 +1918,132 @@ const struct coresight_ops tmc_etr_cs_ops = {
> .panic_ops = &tmc_etr_sync_ops,
> };
>
> +/**
> + * tmc_clean_etr_buf_list - clean the etr_buf_list.
> + * @drvdata: driver data of the TMC device.
> + *
> + * Remove all nodes from @drvdata->etr_buf_list and free their buffers.
> + * If a node holds the live sysfs_buf and the device is active, the node is
> + * removed but the buffer is not freed; ownership stays with drvdata->sysfs_buf.
> + *
> + * Locking: callers must guarantee exclusive access to @drvdata->etr_buf_list
> + * and must not hold @drvdata->spinlock. The spinlock is taken internally only
> + * to serialise the @drvdata->sysfs_buf accesses against the ETR sink
> + * enable/disable paths. Must be called from process context: buffers are freed
> + * with the lock released.
> + */
> +void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata)
> +{
> + struct etr_buf_node *nd, *next;
> + unsigned long flags;
> +
> + list_for_each_entry_safe(nd, next, &drvdata->etr_buf_list, link) {
> + raw_spin_lock_irqsave(&drvdata->spinlock, flags);
> + if (nd->sysfs_buf == drvdata->sysfs_buf) {
> + if (coresight_get_mode(drvdata->csdev) != CS_MODE_DISABLED)
> + /*
> + * The device is still active. Keep the live
> + * buffer owned by drvdata->sysfs_buf and only
> + * drop the list's reference to it.
> + */
> + nd->sysfs_buf = NULL;
[Severity: Medium]
Will this leak drvdata->sysfs_buf if the device mode is active in a non-SYSFS
mode (such as CS_MODE_PERF)?
If the mode changes to CS_MODE_PERF concurrently during the
tmc_create_etr_buf_list() error path, this condition evaluates to true and
abandons the pointer by setting nd->sysfs_buf to NULL.
Since PERF mode tracing exclusively manages drvdata->perf_buf, does its
teardown path ever free drvdata->sysfs_buf?
> + else
> + /* Free the buffer below through nd->sysfs_buf */
> + drvdata->sysfs_buf = NULL;
[Severity: Medium]
If tmc_create_etr_buf_list() encounters an allocation failure and calls
tmc_clean_etr_buf_list() to roll back, and the device happens to be inactive,
will this unconditionally clear and free the pre-existing drvdata->sysfs_buf?
Should an initialization error path only clean up the resources it allocated,
rather than destroying a preserved external resource and losing previously
captured trace data?
> + }
> + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
> +
> + /* Free the buffer (NULL is ignored) and the node out of the lock */
> + tmc_etr_free_sysfs_buf(nd->sysfs_buf);
> + list_del(&nd->link);
> + kfree(nd);
> + }
> +}
> +EXPORT_SYMBOL_GPL(tmc_clean_etr_buf_list);
> +
> +/**
> + * tmc_create_etr_buf_list - create a list to manage the etr_buf_node.
> + * @drvdata: driver data of the TMC device.
> + * @num_nodes: number of nodes want to create with the list.
> + *
> + * Locking: callers must guarantee exclusive access to @drvdata->etr_buf_list
> + * and must not hold @drvdata->spinlock. The spinlock is taken internally only
> + * to serialise the @drvdata->sysfs_buf accesses against the ETR sink
> + * enable/disable paths. Must be called from process context: buffers and nodes
> + * are allocated with the lock released.
> + *
> + * Return 0 upon success and return the error number if fail.
> + */
> +int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes)
> +{
> + struct etr_buf_node *new_node;
> + struct etr_buf *sysfs_buf;
> + unsigned long flags;
> + int i = 0, ret = 0;
> +
> + /* We don't need a list if there is only one node */
> + if (num_nodes < 2)
> + return -EINVAL;
> +
> + /*
> + * We expect that sysfs_buf in drvdata has already been allocated.
> + * Wrap the live sysfs_buf into the first node so the captured trace
> + * data is preserved. The list is owned by the caller, so no lock is
> + * needed to read sysfs_buf or to add the node here.
> + */
> + if (drvdata->sysfs_buf) {
> + new_node = kzalloc_obj(*new_node, GFP_KERNEL);
> + if (!new_node)
> + return -ENOMEM;
> +
> + new_node->sysfs_buf = drvdata->sysfs_buf;
[Severity: High]
Does this lockless read of drvdata->sysfs_buf introduce a race condition?
If a concurrent hardware disable/enable path (like tmc_etr_get_sysfs_buffer())
clears and frees drvdata->sysfs_buf immediately after this lockless check,
wouldn't new_node->sysfs_buf be left as a dangling pointer, leading to a
use-after-free or double free?
> + new_node->is_free = false;
> + list_add(&new_node->link, &drvdata->etr_buf_list);
> + i++;
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com?part=2
^ permalink raw reply
* Re: [RFC PATCH 1/3] dt-bindings: pinctrl: mt8516/mt8167: Move compatibles from mt66xx to mt6795
From: sashiko-bot @ 2026-06-25 11:04 UTC (permalink / raw)
To: Luca Leonardo Scorcia; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260625104742.113803-2-l.scorcia@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] The patch series permanently breaks Device Tree backward compatibility (ABI breakage). By moving the mt8167 and mt8516 SoCs to the mt6795 bindings and pinctrl-paris.c driver, the schema now unconditionally requires `reg-names` and `gpio-ranges` and forbids the legacy `mediatek,pctl-regmap` layout. Furthermore, the updated driver calls `devm_platform_ioremap_resource_byname(pdev, "base")` and fails with `-EINVAL` if `reg-names` is absent. Booting a new kernel with an older, previously valid device tree will fail to probe the pinctrl driver, breaking all GPIO-dependent devices.
--
commit ae4fde26bd3f120a43beccf98009171f05144eee
Author: Luca Leonardo Scorcia <l.scorcia@gmail.com>
dt-bindings: pinctrl: mt8516/mt8167: Move compatibles from mt66xx to mt6795
Pinctrl settings for MediaTek mt8516-mt8167 SoCs use two reg base
addresses, one for GPIO and the other for EINT, as it is common in the
"Paris" pinctrl platform. This commit moves the mediatek,mt8516-pinctrl and
mediatek,mt8167-pinctrl compatible strings to the mt6795-pinctrl binding.
[ ... ]
> diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
> index 9a937f414cc98..c703de72e1d52 100644
> --- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
> @@ -15,7 +15,10 @@ description:
>
> properties:
> compatible:
> - const: mediatek,mt6795-pinctrl
> + enum:
> + - mediatek,mt6795-pinctrl
> + - mediatek,mt8167-pinctrl
> + - mediatek,mt8516-pinctrl
[Severity: Critical]
Does moving these compatibles to this binding break Device Tree backward
compatibility?
The schema now unconditionally requires properties like reg-names and
gpio-ranges, and forbids the legacy mediatek,pctl-regmap layout without an
allOf: if-then conditional to accommodate older hardware descriptions.
Furthermore, the updated driver unconditionally requires the reg-names
property:
drivers/pinctrl/mediatek/pinctrl-paris.c:mtk_paris_pinctrl_probe() {
...
hw->base[i] = devm_platform_ioremap_resource_byname(pdev,
hw->soc->base_names[i]);
...
}
Because older device trees lack the reg-names property, this call returns
-EINVAL and fails the probe.
Will booting a new kernel with an older device tree fail to probe the
pinctrl driver, breaking all GPIO-dependent peripherals?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625104742.113803-1-l.scorcia@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v19 3/7] coresight: tmc: introduce tmc_sysfs_ops to wrap sysfs read operations
From: sashiko-bot @ 2026-06-25 11:00 UTC (permalink / raw)
To: Jie Gan; +Cc: devicetree, conor+dt, robh
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-3-8fbbf22e8381@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] The error handling path in `__tmc_probe()` at the `out:` label unconditionally accesses `drvdata->csdev` and attempts to register the crash metadata interface, leading to NULL pointer dereference, error pointer dereference, or Use-After-Free.
--
commit 0e2c5d1f36c04454695412377951547f5c57c845
Author: Jie Gan <jie.gan@oss.qualcomm.com>
coresight: tmc: introduce tmc_sysfs_ops to wrap sysfs read operations
Introduce tmc_sysfs_ops as a wrapper, wrap sysfs read operations,
for reading trace data from the TMC buffer.
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index bc7dd676da473..4b40b692be4d8 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
[ ... ]
> @@ -835,6 +826,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> idr_init(&drvdata->idr);
> mutex_init(&drvdata->idr_mutex);
> dev_list = "tmc_etr";
> + drvdata->sysfs_ops = &etr_sysfs_ops;
> INIT_LIST_HEAD(&drvdata->etr_buf_list);
> break;
> case TMC_CONFIG_TYPE_ETF:
> @@ -844,6 +836,7 @@ static int __tmc_probe(struct device *dev, struct resource *res)
> desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO;
> desc.ops = &tmc_etf_cs_ops;
> dev_list = "tmc_etf";
> + drvdata->sysfs_ops = &etb_sysfs_ops;
> break;
> default:
> pr_err("%s: Unsupported TMC config\n", desc.name);
[Severity: High]
This isn't a bug introduced by this patch, but looking at __tmc_probe(),
is it safe to unconditionally call the crashdata functions at the out: label
if probe fails?
If an error occurs during probe (for example, coresight_alloc_device_name()
returns NULL, or coresight_register() returns an ERR_PTR), the code jumps
to out:
out:
if (is_tmc_crashdata_valid(drvdata) &&
!tmc_prepare_crashdata(drvdata))
register_crash_dev_interface(drvdata, desc.name);
is_tmc_crashdata_valid() then attempts to access drvdata->csdev->dev:
drivers/hwtracing/coresight/coresight-tmc-core.c:is_tmc_crashdata_valid() {
...
/* Check for valid metadata */
if (!mdata->valid) {
dev_dbg(&drvdata->csdev->dev,
"Data invalid in tmc crash metadata\n");
...
}
Will this cause a NULL pointer or ERR_PTR dereference if drvdata->csdev
hasn't been successfully registered?
Furthermore, if misc_register() fails, coresight_unregister() frees csdev,
potentially leading to a use-after-free. If register_crash_dev_interface()
succeeds on an error path, could the driver core subsequently free drvdata
via devres cleanup, leaving a dangling pointer in the global miscdevice list?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com?part=3
^ permalink raw reply
* Re: [PATCH v16 04/14] lib: kstrtox: add initial value to _parse_integer_limit()
From: Jonathan Cameron @ 2026-06-25 10:58 UTC (permalink / raw)
To: Rodrigo Alencar
Cc: rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
linux, David Lechner, Andy Shevchenko, Lars-Peter Clausen,
Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, Andrew Morton, Petr Mladek, Steven Rostedt,
Andy Shevchenko, Rasmus Villemoes, Sergey Senozhatsky, Shuah Khan
In-Reply-To: <ssrckqgv3rqpfgxwpx4ca3m5m2mp3frxs6sd673chvsorhsjiq@63t3eosivg3a>
On Thu, 25 Jun 2026 08:30:07 +0100
Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
> On 24/06/26 15:54, Jonathan Cameron wrote:
> > On Sun, 14 Jun 2026 21:00:44 +0100
> > Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > > On Thu, 4 Jun 2026 11:09:33 +0100
> > > Rodrigo Alencar <455.rodrigo.alencar@gmail.com> wrote:
> > >
> > > > On 26/06/04 10:58AM, Rodrigo Alencar via B4 Relay wrote:
> > > > > From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> > > > >
> > > > > Add init parameter to _parse_integer_limit() that defines an initial
> > > > > value for the accumulated result when parsing an 64-bit integer. The
> > > > > new function prototype is adjusted so that the _parse_integer() macros
> > > > > stay consistent allowing for one more argument, which defaults to 0.
> > > >
> > > > ...
> > > >
> > > > > noinline
> > > > > unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p,
> > > > > - size_t max_chars)
> > > > > + size_t max_chars, unsigned long long init)
> > > > > {
> > > > > unsigned long long res;
> > > > > unsigned int rv;
> > > > >
> > > > > - res = 0;
> > > > > + res = init;
> > > >
> > > > This might generate conflict, as the code around have changed in linux-next.
> > > > It is an easy fix though.
> > > >
> > > Thanks for the heads up. Hopefully that will all fall out when I rebase testing
> > > on rc1 once that is out.
> > I've done a mid merge cycle rebase as the char-misc branches have merged.
> > So this should be resolve on my testing branch now.
>
> https://lore.kernel.org/oe-kbuild-all/202606250230.etPGuolf-lkp@intel.com/
>
> Apparently, the documentation header now includes parameter descriptions.
> The new one is missing.
I'm snowed under for next few days so if you have time to spin me a fixup patch
that I can just apply that would be great.
If not I'll get to it next week probably.
Jonathan
>
^ permalink raw reply
* Re: [PATCH v3 4/4] edac: xilinx: Add EDAC support for Versal XilSem
From: Julian Braha @ 2026-06-25 10:57 UTC (permalink / raw)
To: Rama devi Veggalam, bp, tony.luck, michal.simek, robh, krzk+dt,
conor+dt
Cc: linux-kernel, linux-edac, devicetree, james.morse, mchehab, rric,
git
In-Reply-To: <20260624212545.2850787-5-rama.devi.veggalam@amd.com>
Hi Rama,
On 6/24/26 22:25, Rama devi Veggalam wrote:
> config EDAC_VERSAL
> - tristate "Xilinx Versal DDR Memory Controller"
> + tristate "Xilinx Versal DDR Memory Controller and XilSEM"
> depends on ARCH_ZYNQMP || COMPILE_TEST
> help
> Support for error detection and correction on the Xilinx Versal DDR
> - memory controller.
> + memory controller and configuration memory of the programmable logic (PL) fabric. Support detection of errors in Network on Chip (NoC) peripheral interconnect (NPI) Registers.
This line of kconfig 'help' is far too long. See
Documentation/process/coding-style.rst
and
Documentation/kbuild/kconfig-language.rst
- Julian Braha
^ permalink raw reply
* Re: [PATCH v3] dt-bindings: pwm: st,pwm: convert to DT schema
From: sashiko-bot @ 2026-06-25 10:57 UTC (permalink / raw)
To: Charan Pedumuru; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260625-st-pwm-v3-1-ace9bff88529@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The example device tree node uses an outdated compatible string ('st,pwm') that violates the schema's own constraints ('st,sti-pwm'), causing dt_binding_check to fail.
--
commit d33b98ff54df0af652aa50944ad631d378f78938
Author: Charan Pedumuru <charan.pedumuru@gmail.com>
dt-bindings: pwm: st,pwm: convert to DT schema
This commit converts the STMicroelectronics STiH41x PWM/Capture controller
binding to DT schema. It changes the compatible string to "st,sti-pwm"
to match the hardware variant naming convention and removes pinctrl-names
from the required properties list.
> diff --git a/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml b/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml
> new file mode 100644
> index 0000000000000..c69073e79ce97
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/st,sti-pwm.yaml
[ ... ]
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + pwm@fe510000 {
> + compatible = "st,pwm";
[Severity: Low]
Does this compatible string match the new schema?
The schema constraints above define the compatible property as "st,sti-pwm",
but the example node here still uses "st,pwm". Will this regression cause
the dt_binding_check validation to fail?
> + reg = <0xfe510000 0x68>;
> + interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
> + #pwm-cells = <2>;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625-st-pwm-v3-1-ace9bff88529@gmail.com?part=1
^ permalink raw reply
* Re: [PATCH v5 2/3] pwm: add Andes PWM driver support
From: Ben Zong-You Xie @ 2026-06-25 10:32 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, linux-pwm,
devicetree, linux-kernel
In-Reply-To: <ahajkcejv71TwV5f@monoceros>
Hi Uwe,
On Wed, May 27, 2026 at 10:55:32AM +0200, Uwe Kleine-König wrote:
> From: Uwe Kleine-König <ukleinek@kernel.org>
>
> Hello Ben,
>
> On Mon, Mar 30, 2026 at 03:45:44PM +0800, Ben Zong-You Xie via B4 Relay wrote:
> > From: Ben Zong-You Xie <ben717@andestech.com>
> >
> > Add a driver for the PWM controller found in Andes AE350 platforms and
> > QiLai SoCs.
> >
> > The Andes PWM controller features:
> > - 4 independent channels.
> > - Dual clock source support (APB clock and external clock) to provide
> > a flexible range of frequencies.
> > - Support for normal and inversed polarity.
> >
> > The driver implements the .apply() and .get_state() callbacks. Since the
> > clock source of each channel can be selected by programming the
> > register, clock selection logic is implemented to prioritize the
> > external clock to maximize the supported period range, falling back to
> > the APB clock for higher frequency requirements.
> >
> > Signed-off-by: Ben Zong-You Xie <ben717@andestech.com>
> > ---
> > drivers/pwm/Kconfig | 10 ++
> > drivers/pwm/Makefile | 1 +
> > drivers/pwm/pwm-andes.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 317 insertions(+)
> >
> > diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> > index 6f3147518376..b82f2c857ada 100644
> > --- a/drivers/pwm/Kconfig
> > +++ b/drivers/pwm/Kconfig
> > @@ -73,6 +73,16 @@ config PWM_AIROHA
> > To compile this driver as a module, choose M here: the module
> > will be called pwm-airoha.
> >
> > +config PWM_ANDES
> > + tristate "Andes PWM support"
> > + depends on ARCH_ANDES || COMPILE_TEST
> > + help
> > + Generic PWM framework driver for Andes platform, such as QiLai SoC
> > + and AE350 platform.
> > +
> > + To compile this driver as a module, choose M here: the module
> > + will be called pwm-andes.
> > +
> > config PWM_APPLE
> > tristate "Apple SoC PWM support"
> > depends on ARCH_APPLE || COMPILE_TEST
> > diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> > index 0dc0d2b69025..858f225289cc 100644
> > --- a/drivers/pwm/Makefile
> > +++ b/drivers/pwm/Makefile
> > @@ -3,6 +3,7 @@ obj-$(CONFIG_PWM) += core.o
> > obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
> > obj-$(CONFIG_PWM_ADP5585) += pwm-adp5585.o
> > obj-$(CONFIG_PWM_AIROHA) += pwm-airoha.o
> > +obj-$(CONFIG_PWM_ANDES) += pwm-andes.o
> > obj-$(CONFIG_PWM_APPLE) += pwm-apple.o
> > obj-$(CONFIG_PWM_ARGON_FAN_HAT) += pwm-argon-fan-hat.o
> > obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o
> > diff --git a/drivers/pwm/pwm-andes.c b/drivers/pwm/pwm-andes.c
> > new file mode 100644
> > index 000000000000..835c8db55987
> > --- /dev/null
> > +++ b/drivers/pwm/pwm-andes.c
> > @@ -0,0 +1,306 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Driver for Andes PWM, used in Andes AE350 platform and QiLai SoC
> > + *
> > + * Copyright (C) 2026 Andes Technology Corporation.
> > + *
> > + * Limitations:
> > + * - When disabling a channel, the current period will not be completed, and the
> > + * output will be constant zero.
>
> You could use that to simulate a 0% relative duty cycle instead of
> erroring out.
>
> Just to be sure: A disabled channel emits zero independant of
> ANDES_PWM_CH_CTRL_PARK being set or not?!
>
No, a disabled channel does not always emit zero. Its output is held at
the "park level" selected by the ANDES_PWM_CH_CTRL_PARK field: the
output is driven LOW when the bit is 0 and HIGH when it is 1. So the
"constant zero" wording was wrong; I have corrected the limitation
comment in v6. And yes, as you suggested, v6 uses exactly this to
emulate the duty-cycle extremes instead of erroring out: a 0% relative
duty cycle parks the channel low (PARK=0) and a 100% relative duty cycle
parks it high (PARK=1).
> > + * - The current period will be completed first if reconfiguring.
> > + * - Further, if the reconfiguration changes the clock source, the output will
> > + * not be the old one nor the new one. And the output will be the new one
> > + * until writing to the reload register.
> > + * - The hardware can neither do a 0% nor a 100% relative duty cycle.
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/math64.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pwm.h>
> > +#include <linux/regmap.h>
> > +#include <linux/time.h>
> > +#include <linux/types.h>
> > +
> > +#define ANDES_PWM_CH_ENABLE 0x1C
> > +#define ANDES_PWM_CH_ENABLE_PWM(ch) BIT(3 + (4 * (ch)))
> > +
> > +#define ANDES_PWM_CH_CTRL(ch) (0x20 + (0x10 * (ch)))
> > +#define ANDES_PWM_CH_CTRL_MODE_PWM BIT(2)
> > +#define ANDES_PWM_CH_CTRL_CLK BIT(3)
> > +#define ANDES_PWM_CH_CTRL_PARK BIT(4)
> > +#define ANDES_PWM_CH_CTRL_MASK GENMASK(4, 0)
> > +
> > +#define ANDES_PWM_CH_RELOAD(ch) (0x24 + (0x10 * (ch)))
> > +#define ANDES_PWM_CH_RELOAD_HIGH GENMASK(31, 16)
> > +#define ANDES_PWM_CH_RELOAD_LOW GENMASK(15, 0)
> > +
> > +#define ANDES_PWM_CH_COUNTER(ch) (0x28 + (0x10 * (ch)))
> > +
> > +#define ANDES_PWM_CH_MAX 4
> > +#define ANDES_PWM_CYCLE_MIN 1
> > +#define ANDES_PWM_CYCLE_MAX 0x10000
> > +
> > +struct andes_pwm {
> > + struct regmap *regmap;
> > + struct clk *pclk;
> > + struct clk *extclk;
> > + unsigned int pclk_rate;
> > + unsigned int extclk_rate;
> > +};
> > +
> > +static const struct regmap_config andes_pwm_regmap_config = {
> > + .name = "andes_pwm",
> > + .reg_bits = 32,
> > + .reg_stride = 4,
> > + .val_bits = 32,
> > + .pad_bits = 0,
> > + .max_register = ANDES_PWM_CH_COUNTER(ANDES_PWM_CH_MAX - 1),
> > + .cache_type = REGCACHE_NONE,
> > +};
> > +
> > +static inline struct andes_pwm *to_andes_pwm(struct pwm_chip *chip)
>
> If you rename this to andes_pwm_from_chip this function has the driver's
> function name prefix, too.
>
Renamed in v6.
> > +{
> > + return pwmchip_get_drvdata(chip);
> > +}
> > +
> > +static int andes_pwm_enable(struct pwm_chip *chip, unsigned int channel,
> > + bool enable)
> > +{
> > + struct andes_pwm *ap = to_andes_pwm(chip);
> > +
> > + return regmap_assign_bits(ap->regmap, ANDES_PWM_CH_ENABLE,
> > + ANDES_PWM_CH_ENABLE_PWM(channel), enable);
> > +}
> > +
> > +static int andes_pwm_config(struct pwm_chip *chip, unsigned int channel,
> > + const struct pwm_state *state)
> > +{
> > + struct andes_pwm *ap = to_andes_pwm(chip);
> > + unsigned int clk_rate = ap->extclk_rate;
> > + unsigned int try = 2;
> > + u64 high_ns = state->duty_cycle;
> > + u64 low_ns = state->period - high_ns;
>
> This results in rounding errors. Consider:
>
> clk_rate = 500000000
> state->duty_cycle = 17
> state->period = 32
>
> then you configure
>
> high_cycles = 8
> low_cycles = 7
>
> which corresponds to a period = 30 ns, while you can do 32 ns. So you
> have to convert state->period to ticks and do the subtraction in the
> tick domain.
>
Fixed in v6.
> > + unsigned int ctrl = ANDES_PWM_CH_CTRL_MODE_PWM;
> > + u64 high_cycles;
> > + u64 low_cycles;
> > + u32 reload;
> > +
> > + /*
> > + * Reload register for PWM mode:
> > + *
> > + * 31 : 16 15 : 0
> > + * PWM16_Hi | PWM16_Lo
> > + *
> > + * The high duration is (PWM16_Hi + 1) cycles and the low duration is
> > + * (PWM16_Lo + 1) cycles. For a duty cycle of 10 cycles and a total
> > + * period of 30 cycles in normal polarity, PWM16_Hi is set to
> > + * 9 (10 - 1) and PWM16_Lo to 19 (30 - 10 - 1). Also, PWM16_Hi is set to
> > + * 19 and PWM16_Lo is set to 9 in inversed polarity.
> > + *
> > + * Because the register stores "cycles - 1", the valid range for
> > + * each phase is 1 to 65536 (0x10000) cycles. This implies the hardware
> > + * cannot achieve a true 0% or 100% duty cycle.
> > + *
> > + * The controller supports two clock sources: the APB clock and an
> > + * external clock. The driver first attempts to use the external clock
> > + * to widest possible range of supported periods. If the requests
> > + * exceeds the valid range of the register, it falls back to the APB
> > + * clock. The request is rejected if the timing cannot be met by either
> > + * source.
> > + */
> > + if (state->polarity == PWM_POLARITY_INVERSED)
> > + swap(high_ns, low_ns);
> > +
> > + while (try) {
> > + high_cycles = mul_u64_u64_div_u64(clk_rate, high_ns,
> > + NSEC_PER_SEC);
> > + low_cycles = mul_u64_u64_div_u64(clk_rate, low_ns,
> > + NSEC_PER_SEC);
> > + if (high_cycles > ANDES_PWM_CYCLE_MAX)
> > + high_cycles = ANDES_PWM_CYCLE_MAX;
> > +
> > + if (low_cycles > ANDES_PWM_CYCLE_MAX)
> > + low_cycles = ANDES_PWM_CYCLE_MAX;
> > +
> > + if (high_cycles >= ANDES_PWM_CYCLE_MIN &&
> > + low_cycles >= ANDES_PWM_CYCLE_MIN)
> > + break;
> > +
> > + try--;
> > + clk_rate = ap->pclk_rate;
> > + }
>
> This loop implements:
>
> if extclk_rate is too high:
> if pclk is too high:
> error out
> else:
> use pclk
> else:
> use extclk
>
> This might be surprising for a user because the emitted period depends
> on the requested duty_cycle.
>
Agreed, that was wrong. In v6 both the clock source and the period are
derived from the requested period alone:
- The driver computes the period in external-clock ticks and uses the
external clock unless that resolves fewer than two ticks (i.e. the period
is too short for it), in which case it uses the APB clock. So the clock
choice depends only on state->period.
- The period is then rounded down to the largest value that stays
representable for every duty split -- at most
ANDES_PWM_CYCLE_MAX + ANDES_PWM_CYCLE_MIN ticks, so both phases always fit
the 16-bit reload fields. The requested duty cycle is split within that
fixed period afterwards.
So changing only the duty cycle no longer moves the emitted period, and an
out-of-range period or duty is now rounded down instead of rejected.
> > +
> > + /*
> > + * try == 0 : no clock is valid
> > + * try == 1 : use APB clock
> > + * try == 2 : use external clock
> > + */
> > + if (!try)
> > + return -EINVAL;
> > +
> > + /*
> > + * If changing the clock source here, the output will not be the old one
> > + * nor the new one. And the output will be the new one until writing to
> > + * the reload register.
>
> And the output will be the new one *after* writing to the reload register?
>
Correct, "until" was a typo for "after". When the clock source changes,
it settles to the new waveform only "after"" the reload register is
written. Fixed in v6.
> > + */
> > + ctrl |= (try == 1) ? ANDES_PWM_CH_CTRL_CLK : 0;
> > + ctrl |= (state->polarity == PWM_POLARITY_INVERSED) ?
> > + ANDES_PWM_CH_CTRL_PARK : 0;
> > + regmap_update_bits(ap->regmap, ANDES_PWM_CH_CTRL(channel),
> > + ANDES_PWM_CH_CTRL_MASK, ctrl);
> > + reload = FIELD_PREP(ANDES_PWM_CH_RELOAD_HIGH, high_cycles - 1) |
> > + FIELD_PREP(ANDES_PWM_CH_RELOAD_LOW, low_cycles - 1);
> > +
> > + return regmap_write(ap->regmap, ANDES_PWM_CH_RELOAD(channel), reload);
> > +}
> > +
> > +static int andes_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> > + const struct pwm_state *state)
> > +{
> > + unsigned int channel = pwm->hwpwm;
> > + int ret;
> > +
> > + if (!state->enabled) {
> > + if (pwm->state.enabled)
> > + andes_pwm_enable(chip, channel, false);
> > +
> > + return 0;
> > + }
> > +
> > + ret = andes_pwm_config(chip, channel, state);
> > + if (ret)
> > + return ret;
> > +
> > + return andes_pwm_enable(chip, channel, true);
> > +}
> > +
> > +static int andes_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
> > + struct pwm_state *state)
> > +{
> > + struct andes_pwm *ap = to_andes_pwm(chip);
> > + unsigned int channel = pwm->hwpwm;
> > + unsigned int ctrl;
> > + unsigned int clk_rate;
> > + unsigned int reload;
> > + u64 high_cycles;
> > + u64 low_cycles;
> > +
> > + regmap_read(ap->regmap, ANDES_PWM_CH_CTRL(channel), &ctrl);
> > + clk_rate = FIELD_GET(ANDES_PWM_CH_CTRL_CLK, ctrl) ? ap->pclk_rate
> > + : ap->extclk_rate;
> > + state->enabled = regmap_test_bits(ap->regmap, ANDES_PWM_CH_ENABLE,
> > + ANDES_PWM_CH_ENABLE_PWM(channel));
> > + state->polarity = regmap_test_bits(ap->regmap,
> > + ANDES_PWM_CH_CTRL(channel),
> > + ANDES_PWM_CH_CTRL_PARK);
>
> This can be simplified to use FIELD_GET(..., ctrl);
>
Done in v6.
> > + regmap_read(ap->regmap, ANDES_PWM_CH_RELOAD(channel), &reload);
> > + high_cycles = FIELD_GET(ANDES_PWM_CH_RELOAD_HIGH, reload) + 1;
> > + low_cycles = FIELD_GET(ANDES_PWM_CH_RELOAD_LOW, reload) + 1;
> > +
> > + /*
> > + * high_cycles and low_cycles are both 16 bits, and NSEC_PER_SEC is 30
> > + * bits. Thus, the multiplication is safe from overflow
>
> Missing . at the end.
>
Fixed in v6.
> > + */
> > + if (state->polarity == PWM_POLARITY_NORMAL) {
> > + state->duty_cycle = DIV_ROUND_UP_ULL(high_cycles * NSEC_PER_SEC,
> > + clk_rate);
> > + state->period = state->duty_cycle +
> > + DIV_ROUND_UP_ULL(low_cycles * NSEC_PER_SEC,
> > + clk_rate);
> > + } else {
> > + state->duty_cycle = DIV_ROUND_UP_ULL(low_cycles * NSEC_PER_SEC,
> > + clk_rate);
> > + state->period = state->duty_cycle +
> > + DIV_ROUND_UP_ULL(high_cycles * NSEC_PER_SEC,
> > + clk_rate);
>
> Here is a rounding error. You need
>
> state->period = DIV_ROUND_UP_ULL((low_cycles + high_cycles) * NSEC_PER_SEC, clk_rate);
>
> (for both polarities, so it can be moved out of the if).
>
> To see the difference, consider clk_rate = 2 * NSEC_PER_SEC,
> high_cycles = 15 and low_cycles = 15.
>
Fixed in v6.
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static const struct pwm_ops andes_pwm_ops = {
> > + .apply = andes_pwm_apply,
> > + .get_state = andes_pwm_get_state,
> > +};
> > +
> > +static int andes_pwm_probe(struct platform_device *pdev)
> > +{
> > + struct device *dev = &pdev->dev;
> > + struct pwm_chip *chip;
> > + struct andes_pwm *ap;
> > + void __iomem *reg_base;
> > + int ret;
> > +
> > + chip = devm_pwmchip_alloc(dev, ANDES_PWM_CH_MAX, sizeof(*ap));
> > + if (IS_ERR(chip))
> > + return PTR_ERR(chip);
> > +
> > + ap = to_andes_pwm(chip);
> > + reg_base = devm_platform_ioremap_resource(pdev, 0);
> > + if (IS_ERR(reg_base))
> > + return dev_err_probe(dev, PTR_ERR(reg_base),
> > + "failed to map I/O space\n");
> > +
> > + ap->pclk = devm_clk_get_enabled(dev, "pclk");
> > + if (IS_ERR(ap->pclk))
> > + return dev_err_probe(dev, PTR_ERR(ap->pclk),
> > + "failed to get APB clock\n");
> > +
> > + ap->extclk = devm_clk_get_optional_enabled(dev, "extclk");
> > + if (IS_ERR(ap->extclk))
> > + return dev_err_probe(dev, PTR_ERR(ap->extclk),
> > + "failed to get external clock\n");
> > +
> > + /*
> > + * If the clock rate is greater than 10^9, there may be an overflow when
> > + * calculating the cycles in andes_pwm_config()
> > + */
> > + ap->pclk_rate = clk_get_rate(ap->pclk);
> > + if (ap->pclk_rate > NSEC_PER_SEC)
> > + ap->pclk = NULL;
>
> This is not enough to prevent that pclk is used.
>
Right -- the clock selection keys off the rate, not the pointer, so nulling
ap->pclk left the out-of-range pclk_rate in place and the clock could still
be picked. v6 caps the rate itself to 0 instead:
ap->pclk_rate = pclk_rate > NSEC_PER_SEC ? 0 : pclk_rate;
ap->extclk_rate = extclk_rate > NSEC_PER_SEC ? 0 : extclk_rate;
A 0 rate resolves to zero ticks in .apply(), so that source is never selected.
> > + ap->extclk_rate = ap->extclk ? clk_get_rate(ap->extclk) : 0;
> > + if (ap->extclk_rate > NSEC_PER_SEC)
> > + ap->extclk = NULL;
> > +
> > + if (!ap->pclk && !ap->extclk)
> > + return dev_err_probe(dev, -EINVAL, "clocks are out of range\n");
>
> If you mention the clk rates in the error message, the problem to fix
> becomes easier to identify.
>
Done in v6.
> > + ap->regmap = devm_regmap_init_mmio(dev, reg_base,
> > + &andes_pwm_regmap_config);
> > + if (IS_ERR(ap->regmap)) {
> > + return dev_err_probe(dev, PTR_ERR(ap->regmap),
> > + "failed to initialize regmap\n");
> > + }
>
> Don't use { ... } for single statements. Please start error messages
> with a capital letter.
>
Done in v6.
> > +
> > + chip->ops = &andes_pwm_ops;
> > + ret = devm_pwmchip_add(dev, chip);
> > + if (ret)
> > + return dev_err_probe(dev, ret, "failed to add pwm chip\n");
> > +
> > + return 0;
> > +}
> > +
> > +static const struct of_device_id andes_pwm_of_match[] = {
> > + { .compatible = "andestech,ae350-pwm" },
> > + { /* sentinel */ }
> > +};
> > +MODULE_DEVICE_TABLE(of, andes_pwm_of_match);
> > +
> > +static struct platform_driver andes_pwm_driver = {
> > + .driver = {
> > + .name = "andes_pwm",
> > + .of_match_table = andes_pwm_of_match,
> > + },
> > + .probe = andes_pwm_probe,
> > +};
> > +module_platform_driver(andes_pwm_driver);
> > +
> > +MODULE_AUTHOR("Ben Zong-You Xie <ben717@andestech.com>");
> > +MODULE_DESCRIPTION("Andes PWM driver");
> > +MODULE_LICENSE("GPL");
>
> Best regards
> Uwe
Thanks,
Ben
^ permalink raw reply
* [RFC PATCH 3/3] arm64: dts: mt8516/mt8167: Update pinctrl nodes for the new paris driver
From: Luca Leonardo Scorcia @ 2026-06-25 10:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260625104742.113803-1-l.scorcia@gmail.com>
Update the MediaTek mt8516-mt8167 SoCs descriptions to respect the
constraints of the Paris pinctrl driver.
In those SoCs the pinctrl has base address 0x10005000 for gpio settings
while 0x1000b000 is used for eint configuration.
This change also drops the no longer required syscfg_pctl syscon node
that was used before to access the gpio regmap, fixing the following
dtbs_check errors:
mt8167-pumpkin.dtb: syscfg-pctl@10005000 (syscon): compatible: ['syscon']
is too short
mt8516-pumpkin.dtb: syscfg-pctl@10005000 (syscon): compatible: ['syscon']
is too short
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
arch/arm64/boot/dts/mediatek/mt8167.dtsi | 15 ++++-----------
arch/arm64/boot/dts/mediatek/mt8516.dtsi | 12 ++++--------
2 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8167.dtsi b/arch/arm64/boot/dts/mediatek/mt8167.dtsi
index 27cf32d7ae35..65da6c0538b1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8167.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8167.dtsi
@@ -95,17 +95,6 @@ power-domain@MT8167_POWER_DOMAIN_CONN {
};
};
- pio: pinctrl@1000b000 {
- compatible = "mediatek,mt8167-pinctrl";
- reg = <0 0x1000b000 0 0x1000>;
- mediatek,pctl-regmap = <&syscfg_pctl>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
- };
-
apmixedsys: apmixedsys@10018000 {
compatible = "mediatek,mt8167-apmixedsys", "syscon";
reg = <0 0x10018000 0 0x710>;
@@ -178,3 +167,7 @@ larb2: larb@16010000 {
};
};
};
+
+&pio {
+ compatible = "mediatek,mt8167-pinctrl";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8516.dtsi b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
index b5e753759465..63f36df4d1b4 100644
--- a/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -231,17 +231,13 @@ keypad: keypad@10002000 {
status = "disabled";
};
- syscfg_pctl: syscfg-pctl@10005000 {
- compatible = "syscon";
- reg = <0 0x10005000 0 0x1000>;
- };
-
- pio: pinctrl@1000b000 {
+ pio: pinctrl@10005000 {
compatible = "mediatek,mt8516-pinctrl";
- reg = <0 0x1000b000 0 0x1000>;
- mediatek,pctl-regmap = <&syscfg_pctl>;
+ reg = <0 0x10005000 0 0x1000>, <0 0x1000b000 0 0x1000>;
+ reg-names = "base", "eint";
gpio-controller;
#gpio-cells = <2>;
+ gpio-ranges = <&pio 0 0 124>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 2/3] pinctrl: mediatek: mt8516/mt8167: Migrate driver to pinctrl-paris platform
From: Luca Leonardo Scorcia @ 2026-06-25 10:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260625104742.113803-1-l.scorcia@gmail.com>
Migrate the mt8516/mt8167 pinctrl driver to the paris platform driver.
This change lets us correctly describe the two base addresses (GPIO/EINT)
used by the SoCs in their device tree. It also adds support for driving
strength capability and R1R0 pullup-pulldown on pins.
Since the driver for mt8167 pinctrl is identical to the mt8516 one except
for pin definitions there is no need for a separate driver, so drop it and
add a compatible to the other one.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
drivers/pinctrl/mediatek/Kconfig | 11 +-
drivers/pinctrl/mediatek/Makefile | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8167.c | 345 --------
drivers/pinctrl/mediatek/pinctrl-mt8516.c | 770 +++++++++++-------
drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h | 562 +++++++------
drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h | 512 ++++++------
6 files changed, 1006 insertions(+), 1195 deletions(-)
delete mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8167.c
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 97980cc28b9c..28edd53f12ed 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -214,13 +214,6 @@ config PINCTRL_MT7988
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_MOORE
-config PINCTRL_MT8167
- bool "MediaTek MT8167 pin control"
- depends on OF
- depends on ARM64 || COMPILE_TEST
- default ARM64 && ARCH_MEDIATEK
- select PINCTRL_MTK
-
config PINCTRL_MT8173
bool "MediaTek MT8173 pin control"
depends on OF
@@ -300,11 +293,11 @@ config PINCTRL_MT8365
select PINCTRL_MTK
config PINCTRL_MT8516
- bool "MediaTek MT8516 pin control"
+ bool "MediaTek MT8516/MT8167 pin control"
depends on OF
depends on ARM64 || COMPILE_TEST
default ARM64 && ARCH_MEDIATEK
- select PINCTRL_MTK
+ select PINCTRL_MTK_PARIS
# For PMIC
config PINCTRL_MT6397
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 6dc17b0c23f9..1533a93b14d3 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o
-obj-$(CONFIG_PINCTRL_MT8167) += pinctrl-mt8167.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
obj-$(CONFIG_PINCTRL_MT8186) += pinctrl-mt8186.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8167.c b/drivers/pinctrl/mediatek/pinctrl-mt8167.c
deleted file mode 100644
index c812d614e9d4..000000000000
--- a/drivers/pinctrl/mediatek/pinctrl-mt8167.c
+++ /dev/null
@@ -1,345 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2020 MediaTek Inc.
- * Author: Min.Guo <min.guo@mediatek.com>
- */
-
-#include <dt-bindings/pinctrl/mt65xx.h>
-#include <linux/of.h>
-#include <linux/module.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#include "pinctrl-mtk-common.h"
-#include "pinctrl-mtk-mt8167.h"
-
-static const struct mtk_drv_group_desc mt8167_drv_grp[] = {
- /* 0E4E8SR 4/8/12/16 */
- MTK_DRV_GRP(4, 16, 1, 2, 4),
- /* 0E2E4SR 2/4/6/8 */
- MTK_DRV_GRP(2, 8, 1, 2, 2),
- /* E8E4E2 2/4/6/8/10/12/14/16 */
- MTK_DRV_GRP(2, 16, 0, 2, 2)
-};
-
-static const struct mtk_pin_drv_grp mt8167_pin_drv[] = {
- MTK_PIN_DRV_GRP(0, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(1, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(2, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(3, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(4, 0xd00, 0, 0),
-
- MTK_PIN_DRV_GRP(5, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(6, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(7, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(8, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(9, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(10, 0xd00, 4, 0),
-
- MTK_PIN_DRV_GRP(11, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(12, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(13, 0xd00, 8, 0),
-
- MTK_PIN_DRV_GRP(14, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(15, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(16, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(17, 0xd00, 12, 2),
-
- MTK_PIN_DRV_GRP(18, 0xd10, 0, 0),
- MTK_PIN_DRV_GRP(19, 0xd10, 0, 0),
- MTK_PIN_DRV_GRP(20, 0xd10, 0, 0),
-
- MTK_PIN_DRV_GRP(21, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(22, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(23, 0xd00, 12, 2),
-
- MTK_PIN_DRV_GRP(24, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(25, 0xd00, 8, 0),
-
- MTK_PIN_DRV_GRP(26, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(27, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(28, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(29, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(30, 0xd10, 4, 1),
-
- MTK_PIN_DRV_GRP(31, 0xd10, 8, 1),
- MTK_PIN_DRV_GRP(32, 0xd10, 8, 1),
- MTK_PIN_DRV_GRP(33, 0xd10, 8, 1),
-
- MTK_PIN_DRV_GRP(34, 0xd10, 12, 0),
- MTK_PIN_DRV_GRP(35, 0xd10, 12, 0),
-
- MTK_PIN_DRV_GRP(36, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(37, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(38, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(39, 0xd20, 0, 0),
-
- MTK_PIN_DRV_GRP(40, 0xd20, 4, 1),
-
- MTK_PIN_DRV_GRP(41, 0xd20, 8, 1),
- MTK_PIN_DRV_GRP(42, 0xd20, 8, 1),
- MTK_PIN_DRV_GRP(43, 0xd20, 8, 1),
-
- MTK_PIN_DRV_GRP(44, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(45, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(46, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(47, 0xd20, 12, 1),
-
- MTK_PIN_DRV_GRP(48, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(49, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(50, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(51, 0xd30, 0, 1),
-
- MTK_PIN_DRV_GRP(54, 0xd30, 8, 1),
-
- MTK_PIN_DRV_GRP(55, 0xd30, 12, 1),
- MTK_PIN_DRV_GRP(56, 0xd30, 12, 1),
- MTK_PIN_DRV_GRP(57, 0xd30, 12, 1),
-
- MTK_PIN_DRV_GRP(62, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(63, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(64, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(65, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(66, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(67, 0xd40, 8, 1),
-
- MTK_PIN_DRV_GRP(68, 0xd40, 12, 2),
-
- MTK_PIN_DRV_GRP(69, 0xd50, 0, 2),
-
- MTK_PIN_DRV_GRP(70, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(71, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(72, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(73, 0xd50, 4, 2),
-
- MTK_PIN_DRV_GRP(100, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(101, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(102, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(103, 0xd50, 8, 1),
-
- MTK_PIN_DRV_GRP(104, 0xd50, 12, 2),
-
- MTK_PIN_DRV_GRP(105, 0xd60, 0, 2),
-
- MTK_PIN_DRV_GRP(106, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(107, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(108, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(109, 0xd60, 4, 2),
-
- MTK_PIN_DRV_GRP(110, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(111, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(112, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(113, 0xd70, 0, 2),
-
- MTK_PIN_DRV_GRP(114, 0xd70, 4, 2),
-
- MTK_PIN_DRV_GRP(115, 0xd60, 12, 2),
-
- MTK_PIN_DRV_GRP(116, 0xd60, 8, 2),
-
- MTK_PIN_DRV_GRP(117, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(118, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(119, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(120, 0xd70, 0, 2),
-};
-
-static const struct mtk_pin_spec_pupd_set_samereg mt8167_spec_pupd[] = {
- MTK_PIN_PUPD_SPEC_SR(14, 0xe50, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(15, 0xe60, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(16, 0xe60, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(17, 0xe60, 10, 9, 8),
-
- MTK_PIN_PUPD_SPEC_SR(21, 0xe60, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(22, 0xe70, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(23, 0xe70, 6, 5, 4),
-
- MTK_PIN_PUPD_SPEC_SR(40, 0xe80, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(41, 0xe80, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(42, 0xe90, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(43, 0xe90, 6, 5, 4),
-
- MTK_PIN_PUPD_SPEC_SR(68, 0xe50, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(69, 0xe50, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(70, 0xe40, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(71, 0xe40, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(72, 0xe40, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(73, 0xe50, 2, 1, 0),
-
- MTK_PIN_PUPD_SPEC_SR(104, 0xe40, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(105, 0xe30, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(106, 0xe20, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(107, 0xe30, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(108, 0xe30, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(109, 0xe30, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(110, 0xe10, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(111, 0xe10, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(112, 0xe10, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(113, 0xe10, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(114, 0xe20, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(115, 0xe20, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(116, 0xe20, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(117, 0xe00, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(118, 0xe00, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 2, 1, 0),
-};
-
-static const struct mtk_pin_ies_smt_set mt8167_ies_set[] = {
- MTK_PIN_IES_SMT_SPEC(0, 6, 0x900, 2),
- MTK_PIN_IES_SMT_SPEC(7, 10, 0x900, 3),
- MTK_PIN_IES_SMT_SPEC(11, 13, 0x900, 12),
- MTK_PIN_IES_SMT_SPEC(14, 17, 0x900, 13),
- MTK_PIN_IES_SMT_SPEC(18, 20, 0x910, 10),
- MTK_PIN_IES_SMT_SPEC(21, 23, 0x900, 13),
- MTK_PIN_IES_SMT_SPEC(24, 25, 0x900, 12),
- MTK_PIN_IES_SMT_SPEC(26, 30, 0x900, 0),
- MTK_PIN_IES_SMT_SPEC(31, 33, 0x900, 1),
- MTK_PIN_IES_SMT_SPEC(34, 39, 0x900, 2),
- MTK_PIN_IES_SMT_SPEC(40, 40, 0x910, 11),
- MTK_PIN_IES_SMT_SPEC(41, 43, 0x900, 10),
- MTK_PIN_IES_SMT_SPEC(44, 47, 0x900, 11),
- MTK_PIN_IES_SMT_SPEC(48, 51, 0x900, 14),
- MTK_PIN_IES_SMT_SPEC(52, 53, 0x910, 0),
- MTK_PIN_IES_SMT_SPEC(54, 54, 0x910, 2),
- MTK_PIN_IES_SMT_SPEC(55, 57, 0x910, 4),
- MTK_PIN_IES_SMT_SPEC(58, 59, 0x900, 15),
- MTK_PIN_IES_SMT_SPEC(60, 61, 0x910, 1),
- MTK_PIN_IES_SMT_SPEC(62, 65, 0x910, 5),
- MTK_PIN_IES_SMT_SPEC(66, 67, 0x910, 6),
- MTK_PIN_IES_SMT_SPEC(68, 68, 0x930, 2),
- MTK_PIN_IES_SMT_SPEC(69, 69, 0x930, 1),
- MTK_PIN_IES_SMT_SPEC(70, 70, 0x930, 6),
- MTK_PIN_IES_SMT_SPEC(71, 71, 0x930, 5),
- MTK_PIN_IES_SMT_SPEC(72, 72, 0x930, 4),
- MTK_PIN_IES_SMT_SPEC(73, 73, 0x930, 3),
- MTK_PIN_IES_SMT_SPEC(100, 103, 0x910, 7),
- MTK_PIN_IES_SMT_SPEC(104, 104, 0x920, 12),
- MTK_PIN_IES_SMT_SPEC(105, 105, 0x920, 11),
- MTK_PIN_IES_SMT_SPEC(106, 106, 0x930, 0),
- MTK_PIN_IES_SMT_SPEC(107, 107, 0x920, 15),
- MTK_PIN_IES_SMT_SPEC(108, 108, 0x920, 14),
- MTK_PIN_IES_SMT_SPEC(109, 109, 0x920, 13),
- MTK_PIN_IES_SMT_SPEC(110, 110, 0x920, 9),
- MTK_PIN_IES_SMT_SPEC(111, 111, 0x920, 8),
- MTK_PIN_IES_SMT_SPEC(112, 112, 0x920, 7),
- MTK_PIN_IES_SMT_SPEC(113, 113, 0x920, 6),
- MTK_PIN_IES_SMT_SPEC(114, 114, 0x920, 10),
- MTK_PIN_IES_SMT_SPEC(115, 115, 0x920, 1),
- MTK_PIN_IES_SMT_SPEC(116, 116, 0x920, 0),
- MTK_PIN_IES_SMT_SPEC(117, 117, 0x920, 5),
- MTK_PIN_IES_SMT_SPEC(118, 118, 0x920, 4),
- MTK_PIN_IES_SMT_SPEC(119, 119, 0x920, 3),
- MTK_PIN_IES_SMT_SPEC(120, 120, 0x920, 2),
- MTK_PIN_IES_SMT_SPEC(121, 124, 0x910, 9),
-};
-
-static const struct mtk_pin_ies_smt_set mt8167_smt_set[] = {
- MTK_PIN_IES_SMT_SPEC(0, 6, 0xA00, 2),
- MTK_PIN_IES_SMT_SPEC(7, 10, 0xA00, 3),
- MTK_PIN_IES_SMT_SPEC(11, 13, 0xA00, 12),
- MTK_PIN_IES_SMT_SPEC(14, 17, 0xA00, 13),
- MTK_PIN_IES_SMT_SPEC(18, 20, 0xA10, 10),
- MTK_PIN_IES_SMT_SPEC(21, 23, 0xA00, 13),
- MTK_PIN_IES_SMT_SPEC(24, 25, 0xA00, 12),
- MTK_PIN_IES_SMT_SPEC(26, 30, 0xA00, 0),
- MTK_PIN_IES_SMT_SPEC(31, 33, 0xA00, 1),
- MTK_PIN_IES_SMT_SPEC(34, 39, 0xA00, 2),
- MTK_PIN_IES_SMT_SPEC(40, 40, 0xA10, 11),
- MTK_PIN_IES_SMT_SPEC(41, 43, 0xA00, 10),
- MTK_PIN_IES_SMT_SPEC(44, 47, 0xA00, 11),
- MTK_PIN_IES_SMT_SPEC(48, 51, 0xA00, 14),
- MTK_PIN_IES_SMT_SPEC(52, 53, 0xA10, 0),
- MTK_PIN_IES_SMT_SPEC(54, 54, 0xA10, 2),
- MTK_PIN_IES_SMT_SPEC(55, 57, 0xA10, 4),
- MTK_PIN_IES_SMT_SPEC(58, 59, 0xA00, 15),
- MTK_PIN_IES_SMT_SPEC(60, 61, 0xA10, 1),
- MTK_PIN_IES_SMT_SPEC(62, 65, 0xA10, 5),
- MTK_PIN_IES_SMT_SPEC(66, 67, 0xA10, 6),
- MTK_PIN_IES_SMT_SPEC(68, 68, 0xA30, 2),
- MTK_PIN_IES_SMT_SPEC(69, 69, 0xA30, 1),
- MTK_PIN_IES_SMT_SPEC(70, 70, 0xA30, 3),
- MTK_PIN_IES_SMT_SPEC(71, 71, 0xA30, 4),
- MTK_PIN_IES_SMT_SPEC(72, 72, 0xA30, 5),
- MTK_PIN_IES_SMT_SPEC(73, 73, 0xA30, 6),
-
- MTK_PIN_IES_SMT_SPEC(100, 103, 0xA10, 7),
- MTK_PIN_IES_SMT_SPEC(104, 104, 0xA20, 12),
- MTK_PIN_IES_SMT_SPEC(105, 105, 0xA20, 11),
- MTK_PIN_IES_SMT_SPEC(106, 106, 0xA30, 13),
- MTK_PIN_IES_SMT_SPEC(107, 107, 0xA20, 14),
- MTK_PIN_IES_SMT_SPEC(108, 108, 0xA20, 15),
- MTK_PIN_IES_SMT_SPEC(109, 109, 0xA30, 0),
- MTK_PIN_IES_SMT_SPEC(110, 110, 0xA20, 9),
- MTK_PIN_IES_SMT_SPEC(111, 111, 0xA20, 8),
- MTK_PIN_IES_SMT_SPEC(112, 112, 0xA20, 7),
- MTK_PIN_IES_SMT_SPEC(113, 113, 0xA20, 6),
- MTK_PIN_IES_SMT_SPEC(114, 114, 0xA20, 10),
- MTK_PIN_IES_SMT_SPEC(115, 115, 0xA20, 1),
- MTK_PIN_IES_SMT_SPEC(116, 116, 0xA20, 0),
- MTK_PIN_IES_SMT_SPEC(117, 117, 0xA20, 5),
- MTK_PIN_IES_SMT_SPEC(118, 118, 0xA20, 4),
- MTK_PIN_IES_SMT_SPEC(119, 119, 0xA20, 3),
- MTK_PIN_IES_SMT_SPEC(120, 120, 0xA20, 2),
- MTK_PIN_IES_SMT_SPEC(121, 124, 0xA10, 9),
-};
-
-static const struct mtk_pinctrl_devdata mt8167_pinctrl_data = {
- .pins = mtk_pins_mt8167,
- .npins = ARRAY_SIZE(mtk_pins_mt8167),
- .grp_desc = mt8167_drv_grp,
- .n_grp_cls = ARRAY_SIZE(mt8167_drv_grp),
- .pin_drv_grp = mt8167_pin_drv,
- .n_pin_drv_grps = ARRAY_SIZE(mt8167_pin_drv),
- .spec_ies = mt8167_ies_set,
- .n_spec_ies = ARRAY_SIZE(mt8167_ies_set),
- .spec_pupd = mt8167_spec_pupd,
- .n_spec_pupd = ARRAY_SIZE(mt8167_spec_pupd),
- .spec_smt = mt8167_smt_set,
- .n_spec_smt = ARRAY_SIZE(mt8167_smt_set),
- .spec_pull_set = mtk_pctrl_spec_pull_set_samereg,
- .spec_ies_smt_set = mtk_pconf_spec_set_ies_smt_range,
- .dir_offset = 0x0000,
- .pullen_offset = 0x0500,
- .pullsel_offset = 0x0600,
- .dout_offset = 0x0100,
- .din_offset = 0x0200,
- .pinmux_offset = 0x0300,
- .type1_start = 125,
- .type1_end = 125,
- .port_shf = 4,
- .port_mask = 0xf,
- .port_align = 4,
- .mode_mask = 0xf,
- .mode_per_reg = 5,
- .mode_shf = 4,
- .eint_hw = {
- .port_mask = 7,
- .ports = 6,
- .ap_num = 169,
- .db_cnt = 64,
- .db_time = debounce_time_mt6795,
- },
-};
-
-static const struct of_device_id mt8167_pctrl_match[] = {
- { .compatible = "mediatek,mt8167-pinctrl", .data = &mt8167_pinctrl_data },
- {}
-};
-
-MODULE_DEVICE_TABLE(of, mt8167_pctrl_match);
-
-static struct platform_driver mtk_pinctrl_driver = {
- .probe = mtk_pctrl_common_probe,
- .driver = {
- .name = "mediatek-mt8167-pinctrl",
- .of_match_table = mt8167_pctrl_match,
- .pm = pm_sleep_ptr(&mtk_eint_pm_ops),
- },
-};
-
-static int __init mtk_pinctrl_init(void)
-{
- return platform_driver_register(&mtk_pinctrl_driver);
-}
-arch_initcall(mtk_pinctrl_init);
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8516.c b/drivers/pinctrl/mediatek/pinctrl-mt8516.c
index 68d6638e7f4b..e00b5633bc67 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8516.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8516.c
@@ -1,345 +1,517 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2019 MediaTek Inc.
* Author: Min.Guo <min.guo@mediatek.com>
+ * Author: Luca Leonardo Scorcia <l.scorcia@gmail.com>
*/
-#include <dt-bindings/pinctrl/mt65xx.h>
-#include <linux/of.h>
-#include <linux/module.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-
-#include "pinctrl-mtk-common.h"
+#include "pinctrl-mtk-mt8167.h"
#include "pinctrl-mtk-mt8516.h"
+#include "pinctrl-paris.h"
-static const struct mtk_drv_group_desc mt8516_drv_grp[] = {
- /* 0E4E8SR 4/8/12/16 */
- MTK_DRV_GRP(4, 16, 1, 2, 4),
- /* 0E2E4SR 2/4/6/8 */
- MTK_DRV_GRP(2, 8, 1, 2, 2),
- /* E8E4E2 2/4/6/8/10/12/14/16 */
- MTK_DRV_GRP(2, 16, 0, 2, 2)
-};
-
-static const struct mtk_pin_drv_grp mt8516_pin_drv[] = {
- MTK_PIN_DRV_GRP(0, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(1, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(2, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(3, 0xd00, 0, 0),
- MTK_PIN_DRV_GRP(4, 0xd00, 0, 0),
-
- MTK_PIN_DRV_GRP(5, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(6, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(7, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(8, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(9, 0xd00, 4, 0),
- MTK_PIN_DRV_GRP(10, 0xd00, 4, 0),
-
- MTK_PIN_DRV_GRP(11, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(12, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(13, 0xd00, 8, 0),
-
- MTK_PIN_DRV_GRP(14, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(15, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(16, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(17, 0xd00, 12, 2),
-
- MTK_PIN_DRV_GRP(18, 0xd10, 0, 0),
- MTK_PIN_DRV_GRP(19, 0xd10, 0, 0),
- MTK_PIN_DRV_GRP(20, 0xd10, 0, 0),
-
- MTK_PIN_DRV_GRP(21, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(22, 0xd00, 12, 2),
- MTK_PIN_DRV_GRP(23, 0xd00, 12, 2),
-
- MTK_PIN_DRV_GRP(24, 0xd00, 8, 0),
- MTK_PIN_DRV_GRP(25, 0xd00, 8, 0),
+#define PIN_FIELD15(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 15, 0)
- MTK_PIN_DRV_GRP(26, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(27, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(28, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(29, 0xd10, 4, 1),
- MTK_PIN_DRV_GRP(30, 0xd10, 4, 1),
+#define PIN_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 16, 0)
- MTK_PIN_DRV_GRP(31, 0xd10, 8, 1),
- MTK_PIN_DRV_GRP(32, 0xd10, 8, 1),
- MTK_PIN_DRV_GRP(33, 0xd10, 8, 1),
+#define PINS_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)\
+ PIN_FIELD_CALC(_s_pin, _e_pin, 0, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 16, 1)
- MTK_PIN_DRV_GRP(34, 0xd10, 12, 0),
- MTK_PIN_DRV_GRP(35, 0xd10, 12, 0),
-
- MTK_PIN_DRV_GRP(36, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(37, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(38, 0xd20, 0, 0),
- MTK_PIN_DRV_GRP(39, 0xd20, 0, 0),
-
- MTK_PIN_DRV_GRP(40, 0xd20, 4, 1),
-
- MTK_PIN_DRV_GRP(41, 0xd20, 8, 1),
- MTK_PIN_DRV_GRP(42, 0xd20, 8, 1),
- MTK_PIN_DRV_GRP(43, 0xd20, 8, 1),
-
- MTK_PIN_DRV_GRP(44, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(45, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(46, 0xd20, 12, 1),
- MTK_PIN_DRV_GRP(47, 0xd20, 12, 1),
-
- MTK_PIN_DRV_GRP(48, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(49, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(50, 0xd30, 0, 1),
- MTK_PIN_DRV_GRP(51, 0xd30, 0, 1),
-
- MTK_PIN_DRV_GRP(54, 0xd30, 8, 1),
-
- MTK_PIN_DRV_GRP(55, 0xd30, 12, 1),
- MTK_PIN_DRV_GRP(56, 0xd30, 12, 1),
- MTK_PIN_DRV_GRP(57, 0xd30, 12, 1),
+static const struct mtk_pin_field_calc mt8516_pin_dir_range[] = {
+ PIN_FIELD16(0, 124, 0x000, 0x10, 0, 1),
+};
- MTK_PIN_DRV_GRP(62, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(63, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(64, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(65, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(66, 0xd40, 8, 1),
- MTK_PIN_DRV_GRP(67, 0xd40, 8, 1),
+static const struct mtk_pin_field_calc mt8516_pin_do_range[] = {
+ PIN_FIELD16(0, 124, 0x100, 0x10, 0, 1),
+};
- MTK_PIN_DRV_GRP(68, 0xd40, 12, 2),
+static const struct mtk_pin_field_calc mt8516_pin_di_range[] = {
+ PIN_FIELD16(0, 124, 0x200, 0x10, 0, 1),
+};
- MTK_PIN_DRV_GRP(69, 0xd50, 0, 2),
+static const struct mtk_pin_field_calc mt8516_pin_mode_range[] = {
+ PIN_FIELD15(0, 124, 0x300, 0x10, 0, 3),
+};
- MTK_PIN_DRV_GRP(70, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(71, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(72, 0xd50, 4, 2),
- MTK_PIN_DRV_GRP(73, 0xd50, 4, 2),
+static const struct mtk_pin_field_calc mt8516_pin_pullen_range[] = {
+ PIN_FIELD16(0, 124, 0x500, 0x10, 0, 1),
+};
- MTK_PIN_DRV_GRP(100, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(101, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(102, 0xd50, 8, 1),
- MTK_PIN_DRV_GRP(103, 0xd50, 8, 1),
+static const struct mtk_pin_field_calc mt8516_pin_pullsel_range[] = {
+ PIN_FIELD16(0, 124, 0x600, 0x10, 0, 1),
+};
- MTK_PIN_DRV_GRP(104, 0xd50, 12, 2),
+static const struct mtk_pin_field_calc mt8516_pin_ies_range[] = {
+ PINS_FIELD16(0, 6, 0x900, 0x10, 2, 1),
+ PINS_FIELD16(7, 10, 0x900, 0x10, 3, 1),
+ PINS_FIELD16(11, 13, 0x900, 0x10, 12, 1),
+ PINS_FIELD16(14, 17, 0x900, 0x10, 13, 1),
+ PINS_FIELD16(18, 20, 0x910, 0x10, 10, 1),
+ PINS_FIELD16(21, 23, 0x900, 0x10, 13, 1),
+ PINS_FIELD16(24, 25, 0x900, 0x10, 12, 1),
+ PINS_FIELD16(26, 30, 0x900, 0x10, 0, 1),
+ PINS_FIELD16(31, 33, 0x900, 0x10, 1, 1),
+ PINS_FIELD16(34, 39, 0x900, 0x10, 2, 1),
+ PIN_FIELD16(40, 40, 0x910, 0x10, 11, 1),
+ PINS_FIELD16(41, 43, 0x900, 0x10, 10, 1),
+ PINS_FIELD16(44, 47, 0x900, 0x10, 11, 1),
+ PINS_FIELD16(48, 51, 0x900, 0x10, 14, 1),
+ PINS_FIELD16(52, 53, 0x910, 0x10, 0, 1),
+ PIN_FIELD16(54, 54, 0x910, 0x10, 2, 1),
+ PINS_FIELD16(55, 57, 0x910, 0x10, 4, 1),
+ PINS_FIELD16(58, 59, 0x900, 0x10, 15, 1),
+ PINS_FIELD16(60, 61, 0x910, 0x10, 1, 1),
+ PINS_FIELD16(62, 65, 0x910, 0x10, 5, 1),
+ PINS_FIELD16(66, 67, 0x910, 0x10, 6, 1),
+ PIN_FIELD16(68, 68, 0x930, 0x10, 2, 1),
+ PIN_FIELD16(69, 69, 0x930, 0x10, 1, 1),
+ PIN_FIELD16(70, 70, 0x930, 0x10, 6, 1),
+ PIN_FIELD16(71, 71, 0x930, 0x10, 5, 1),
+ PIN_FIELD16(72, 72, 0x930, 0x10, 4, 1),
+ PIN_FIELD16(73, 73, 0x930, 0x10, 3, 1),
+ PINS_FIELD16(100, 103, 0x910, 0x10, 7, 1),
+ PIN_FIELD16(104, 104, 0x920, 0x10, 12, 1),
+ PIN_FIELD16(105, 105, 0x920, 0x10, 11, 1),
+ PIN_FIELD16(106, 106, 0x930, 0x10, 0, 1),
+ PIN_FIELD16(107, 107, 0x920, 0x10, 15, 1),
+ PIN_FIELD16(108, 108, 0x920, 0x10, 14, 1),
+ PIN_FIELD16(109, 109, 0x920, 0x10, 13, 1),
+ PIN_FIELD16(110, 110, 0x920, 0x10, 9, 1),
+ PIN_FIELD16(111, 111, 0x920, 0x10, 8, 1),
+ PIN_FIELD16(112, 112, 0x920, 0x10, 7, 1),
+ PIN_FIELD16(113, 113, 0x920, 0x10, 6, 1),
+ PIN_FIELD16(114, 114, 0x920, 0x10, 10, 1),
+ PIN_FIELD16(115, 115, 0x920, 0x10, 1, 1),
+ PIN_FIELD16(116, 116, 0x920, 0x10, 0, 1),
+ PIN_FIELD16(117, 117, 0x920, 0x10, 5, 1),
+ PIN_FIELD16(118, 118, 0x920, 0x10, 4, 1),
+ PIN_FIELD16(119, 119, 0x920, 0x10, 3, 1),
+ PIN_FIELD16(120, 120, 0x920, 0x10, 2, 1),
+ PINS_FIELD16(121, 124, 0x910, 0x10, 9, 1),
+};
- MTK_PIN_DRV_GRP(105, 0xd60, 0, 2),
+static const struct mtk_pin_field_calc mt8516_pin_smt_range[] = {
+ PINS_FIELD16(0, 6, 0xa00, 0x10, 2, 1),
+ PINS_FIELD16(7, 10, 0xa00, 0x10, 3, 1),
+ PINS_FIELD16(11, 13, 0xa00, 0x10, 12, 1),
+ PINS_FIELD16(14, 17, 0xa00, 0x10, 13, 1),
+ PINS_FIELD16(18, 20, 0xa10, 0x10, 10, 1),
+ PINS_FIELD16(21, 23, 0xa00, 0x10, 13, 1),
+ PINS_FIELD16(24, 25, 0xa00, 0x10, 12, 1),
+ PINS_FIELD16(26, 30, 0xa00, 0x10, 0, 1),
+ PINS_FIELD16(31, 33, 0xa00, 0x10, 1, 1),
+ PINS_FIELD16(34, 39, 0xa00, 0x10, 2, 1),
+ PIN_FIELD16(40, 40, 0xa10, 0x10, 11, 1),
+ PINS_FIELD16(41, 43, 0xa00, 0x10, 10, 1),
+ PINS_FIELD16(44, 47, 0xa00, 0x10, 11, 1),
+ PINS_FIELD16(48, 51, 0xa00, 0x10, 14, 1),
+ PINS_FIELD16(52, 53, 0xa10, 0x10, 0, 1),
+ PIN_FIELD16(54, 54, 0xa10, 0x10, 2, 1),
+ PINS_FIELD16(55, 57, 0xa10, 0x10, 4, 1),
+ PINS_FIELD16(58, 59, 0xa00, 0x10, 15, 1),
+ PINS_FIELD16(60, 61, 0xa10, 0x10, 1, 1),
+ PINS_FIELD16(62, 65, 0xa10, 0x10, 5, 1),
+ PINS_FIELD16(66, 67, 0xa10, 0x10, 6, 1),
+ PIN_FIELD16(68, 68, 0xa30, 0x10, 2, 1),
+ PIN_FIELD16(69, 69, 0xa30, 0x10, 1, 1),
+ PIN_FIELD16(70, 70, 0xa30, 0x10, 3, 1),
+ PIN_FIELD16(71, 71, 0xa30, 0x10, 4, 1),
+ PIN_FIELD16(72, 72, 0xa30, 0x10, 5, 1),
+ PIN_FIELD16(73, 73, 0xa30, 0x10, 6, 1),
+ PINS_FIELD16(100, 103, 0xa10, 0x10, 7, 1),
+ PIN_FIELD16(104, 104, 0xa20, 0x10, 12, 1),
+ PIN_FIELD16(105, 105, 0xa20, 0x10, 11, 1),
+ PIN_FIELD16(106, 106, 0xa20, 0x10, 13, 1),
+ PIN_FIELD16(107, 107, 0xa20, 0x10, 14, 1),
+ PIN_FIELD16(108, 108, 0xa20, 0x10, 15, 1),
+ PIN_FIELD16(109, 109, 0xa30, 0x10, 0, 1),
+ PIN_FIELD16(110, 110, 0xa20, 0x10, 9, 1),
+ PIN_FIELD16(111, 111, 0xa20, 0x10, 8, 1),
+ PIN_FIELD16(112, 112, 0xa20, 0x10, 7, 1),
+ PIN_FIELD16(113, 113, 0xa20, 0x10, 6, 1),
+ PIN_FIELD16(114, 114, 0xa20, 0x10, 10, 1),
+ PIN_FIELD16(115, 115, 0xa20, 0x10, 1, 1),
+ PIN_FIELD16(116, 116, 0xa20, 0x10, 0, 1),
+ PIN_FIELD16(117, 117, 0xa20, 0x10, 5, 1),
+ PIN_FIELD16(118, 118, 0xa20, 0x10, 4, 1),
+ PIN_FIELD16(119, 119, 0xa20, 0x10, 3, 1),
+ PIN_FIELD16(120, 120, 0xa20, 0x10, 2, 1),
+ PINS_FIELD16(121, 124, 0xa10, 0x10, 9, 1),
+};
- MTK_PIN_DRV_GRP(106, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(107, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(108, 0xd60, 4, 2),
- MTK_PIN_DRV_GRP(109, 0xd60, 4, 2),
+static const struct mtk_pin_field_calc mt8516_pin_pupd_range[] = {
+ /* EINT */
+ PIN_FIELD16(14, 14, 0xe50, 0x10, 14, 1), /* EINT14 */
+ PIN_FIELD16(15, 15, 0xe60, 0x10, 2, 1), /* EINT15 */
+ PIN_FIELD16(16, 16, 0xe60, 0x10, 6, 1), /* EINT16 */
+ PIN_FIELD16(17, 17, 0xe60, 0x10, 10, 1), /* EINT17 */
+ PIN_FIELD16(21, 21, 0xe60, 0x10, 14, 1), /* EINT21 */
+ PIN_FIELD16(22, 22, 0xe70, 0x10, 2, 1), /* EINT22 */
+ PIN_FIELD16(23, 23, 0xe70, 0x10, 6, 1), /* EINT23 */
+
+ /* KPROW */
+ PIN_FIELD16(40, 40, 0xe80, 0x10, 2, 1), /* KPROW0 */
+ PIN_FIELD16(41, 41, 0xe80, 0x10, 6, 1), /* KPROW1 */
+
+ PIN_FIELD16(42, 42, 0xe90, 0x10, 2, 1), /* KPCOL0 */
+ PIN_FIELD16(43, 43, 0xe90, 0x10, 6, 1), /* KPCOL1 */
+
+ /* MSDC2 */
+ PIN_FIELD16(68, 68, 0xe50, 0x10, 10, 1), /* MSDC2_CMD */
+ PIN_FIELD16(69, 69, 0xe50, 0x10, 6, 1), /* MSDC2_CLK */
+ PIN_FIELD16(70, 70, 0xe40, 0x10, 6, 1), /* MSDC2_DAT0 */
+ PIN_FIELD16(71, 71, 0xe40, 0x10, 10, 1), /* MSDC2_DAT1 */
+ PIN_FIELD16(72, 72, 0xe40, 0x10, 14, 1), /* MSDC2_DAT2 */
+ PIN_FIELD16(73, 73, 0xe50, 0x10, 2, 1), /* MSDC2_DAT3 */
+
+ /* MSDC1 */
+ PIN_FIELD16(104, 104, 0xe40, 0x10, 2, 1), /* MSDC1_CMD */
+ PIN_FIELD16(105, 105, 0xe30, 0x10, 14, 1), /* MSDC1_CLK */
+ PIN_FIELD16(106, 106, 0xe20, 0x10, 14, 1), /* MSDC1_DAT0 */
+ PIN_FIELD16(107, 107, 0xe30, 0x10, 2, 1), /* MSDC1_DAT1 */
+ PIN_FIELD16(108, 108, 0xe30, 0x10, 6, 1), /* MSDC1_DAT2 */
+ PIN_FIELD16(109, 109, 0xe30, 0x10, 10, 1), /* MSDC1_DAT3 */
+
+ /* MSDC0 */
+ PIN_FIELD16(110, 110, 0xe10, 0x10, 14, 1), /* MSDC0_DAT7 */
+ PIN_FIELD16(111, 111, 0xe10, 0x10, 10, 1), /* MSDC0_DAT6 */
+ PIN_FIELD16(112, 112, 0xe10, 0x10, 6, 1), /* MSDC0_DAT5 */
+ PIN_FIELD16(113, 113, 0xe10, 0x10, 2, 1), /* MSDC0_DAT4 */
+ PIN_FIELD16(114, 114, 0xe20, 0x10, 10, 1), /* MSDC0_RSTB */
+ PIN_FIELD16(115, 115, 0xe20, 0x10, 2, 1), /* MSDC0_CMD */
+ PIN_FIELD16(116, 116, 0xe20, 0x10, 6, 1), /* MSDC0_CLK */
+ PIN_FIELD16(117, 117, 0xe00, 0x10, 14, 1), /* MSDC0_DAT3 */
+ PIN_FIELD16(118, 118, 0xe00, 0x10, 10, 1), /* MSDC0_DAT2 */
+ PIN_FIELD16(119, 119, 0xe00, 0x10, 6, 1), /* MSDC0_DAT1 */
+ PIN_FIELD16(120, 120, 0xe00, 0x10, 2, 1), /* MSDC0_DAT0 */
+};
- MTK_PIN_DRV_GRP(110, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(111, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(112, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(113, 0xd70, 0, 2),
+static const struct mtk_pin_field_calc mt8516_pin_r0_range[] = {
+ /* EINT */
+ PIN_FIELD16(14, 14, 0xe50, 0x10, 12, 1), /* EINT14 */
+ PIN_FIELD16(15, 15, 0xe60, 0x10, 0, 1), /* EINT15 */
+ PIN_FIELD16(16, 16, 0xe60, 0x10, 4, 1), /* EINT16 */
+ PIN_FIELD16(17, 17, 0xe60, 0x10, 8, 1), /* EINT17 */
+ PIN_FIELD16(21, 21, 0xe60, 0x10, 12, 1), /* EINT21 */
+ PIN_FIELD16(22, 22, 0xe70, 0x10, 0, 1), /* EINT22 */
+ PIN_FIELD16(23, 23, 0xe70, 0x10, 4, 1), /* EINT23 */
+
+ /* KPROW */
+ PIN_FIELD16(40, 40, 0xe80, 0x10, 0, 1), /* KPROW0 */
+ PIN_FIELD16(41, 41, 0xe80, 0x10, 4, 1), /* KPROW1 */
+ PIN_FIELD16(42, 42, 0xe90, 0x10, 0, 1), /* KPCOL0 */
+ PIN_FIELD16(43, 43, 0xe90, 0x10, 4, 1), /* KPCOL1 */
+
+ /* MSDC2 */
+ PIN_FIELD16(68, 68, 0xe50, 0x10, 8, 1), /* MSDC2_CMD */
+ PIN_FIELD16(69, 69, 0xe50, 0x10, 4, 1), /* MSDC2_CLK */
+ PIN_FIELD16(70, 70, 0xe40, 0x10, 4, 1), /* MSDC2_DAT0 */
+ PIN_FIELD16(71, 71, 0xe40, 0x10, 8, 1), /* MSDC2_DAT1 */
+ PIN_FIELD16(72, 72, 0xe40, 0x10, 12, 1), /* MSDC2_DAT2 */
+ PIN_FIELD16(73, 73, 0xe50, 0x10, 0, 1), /* MSDC2_DAT3 */
+
+ /* MSDC1 */
+ PIN_FIELD16(104, 104, 0xe40, 0x10, 0, 1), /* MSDC1_CMD */
+ PIN_FIELD16(105, 105, 0xe30, 0x10, 12, 1), /* MSDC1_CLK */
+ PIN_FIELD16(106, 106, 0xe20, 0x10, 12, 1), /* MSDC1_DAT0 */
+ PIN_FIELD16(107, 107, 0xe30, 0x10, 0, 1), /* MSDC1_DAT1 */
+ PIN_FIELD16(108, 108, 0xe30, 0x10, 4, 1), /* MSDC1_DAT2 */
+ PIN_FIELD16(109, 109, 0xe30, 0x10, 8, 1), /* MSDC1_DAT3 */
+
+ /* MSDC0 */
+ PIN_FIELD16(110, 110, 0xe10, 0x10, 12, 1), /* MSDC0_DAT7 */
+ PIN_FIELD16(111, 111, 0xe10, 0x10, 8, 1), /* MSDC0_DAT6 */
+ PIN_FIELD16(112, 112, 0xe10, 0x10, 4, 1), /* MSDC0_DAT5 */
+ PIN_FIELD16(113, 113, 0xe10, 0x10, 0, 1), /* MSDC0_DAT4 */
+ PIN_FIELD16(114, 114, 0xe20, 0x10, 8, 1), /* MSDC0_RSTB */
+ PIN_FIELD16(115, 115, 0xe20, 0x10, 0, 1), /* MSDC0_CMD */
+ PIN_FIELD16(116, 116, 0xe20, 0x10, 4, 1), /* MSDC0_CLK */
+ PIN_FIELD16(117, 117, 0xe00, 0x10, 12, 1), /* MSDC0_DAT3 */
+ PIN_FIELD16(118, 118, 0xe00, 0x10, 8, 1), /* MSDC0_DAT2 */
+ PIN_FIELD16(119, 119, 0xe00, 0x10, 4, 1), /* MSDC0_DAT1 */
+ PIN_FIELD16(120, 120, 0xe00, 0x10, 0, 1), /* MSDC0_DAT0 */
+};
- MTK_PIN_DRV_GRP(114, 0xd70, 4, 2),
+static const struct mtk_pin_field_calc mt8516_pin_r1_range[] = {
+ /* EINT */
+ PIN_FIELD16(14, 14, 0xe50, 0x10, 13, 1), /* EINT14 */
+ PIN_FIELD16(15, 15, 0xe60, 0x10, 1, 1), /* EINT15 */
+ PIN_FIELD16(16, 16, 0xe60, 0x10, 5, 1), /* EINT16 */
+ PIN_FIELD16(17, 17, 0xe60, 0x10, 9, 1), /* EINT17 */
+ PIN_FIELD16(21, 21, 0xe60, 0x10, 13, 1), /* EINT21 */
+ PIN_FIELD16(22, 22, 0xe70, 0x10, 1, 1), /* EINT22 */
+ PIN_FIELD16(23, 23, 0xe70, 0x10, 5, 1), /* EINT23 */
+
+ /* KPROW */
+ PIN_FIELD16(40, 40, 0xe80, 0x10, 1, 1), /* KPROW0 */
+ PIN_FIELD16(41, 41, 0xe80, 0x10, 5, 1), /* KPROW1 */
+ PIN_FIELD16(42, 42, 0xe90, 0x10, 1, 1), /* KPCOL0 */
+ PIN_FIELD16(43, 43, 0xe90, 0x10, 5, 1), /* KPCOL1 */
+
+ /* MSDC2 */
+ PIN_FIELD16(68, 68, 0xe50, 0x10, 9, 1), /* MSDC2_CMD */
+ PIN_FIELD16(69, 69, 0xe50, 0x10, 5, 1), /* MSDC2_CLK */
+ PIN_FIELD16(70, 70, 0xe40, 0x10, 5, 1), /* MSDC2_DAT0 */
+ PIN_FIELD16(71, 71, 0xe40, 0x10, 9, 1), /* MSDC2_DAT1 */
+ PIN_FIELD16(72, 72, 0xe40, 0x10, 13, 1), /* MSDC2_DAT2 */
+ PIN_FIELD16(73, 73, 0xe50, 0x10, 1, 1), /* MSDC2_DAT3 */
+
+ /* MSDC1 */
+ PIN_FIELD16(104, 104, 0xe40, 0x10, 1, 1), /* MSDC1_CMD */
+ PIN_FIELD16(105, 105, 0xe30, 0x10, 13, 1), /* MSDC1_CLK */
+ PIN_FIELD16(106, 106, 0xe20, 0x10, 13, 1), /* MSDC1_DAT0 */
+ PIN_FIELD16(107, 107, 0xe30, 0x10, 1, 1), /* MSDC1_DAT1 */
+ PIN_FIELD16(108, 108, 0xe30, 0x10, 5, 1), /* MSDC1_DAT2 */
+ PIN_FIELD16(109, 109, 0xe30, 0x10, 9, 1), /* MSDC1_DAT3 */
+
+ /* MSDC0 */
+ PIN_FIELD16(110, 110, 0xe10, 0x10, 13, 1), /* MSDC0_DAT7 */
+ PIN_FIELD16(111, 111, 0xe10, 0x10, 9, 1), /* MSDC0_DAT6 */
+ PIN_FIELD16(112, 112, 0xe10, 0x10, 5, 1), /* MSDC0_DAT5 */
+ PIN_FIELD16(113, 113, 0xe10, 0x10, 1, 1), /* MSDC0_DAT4 */
+ PIN_FIELD16(114, 114, 0xe20, 0x10, 9, 1), /* MSDC0_RSTB */
+ PIN_FIELD16(115, 115, 0xe20, 0x10, 1, 1), /* MSDC0_CMD */
+ PIN_FIELD16(116, 116, 0xe20, 0x10, 5, 1), /* MSDC0_CLK */
+ PIN_FIELD16(117, 117, 0xe00, 0x10, 13, 1), /* MSDC0_DAT3 */
+ PIN_FIELD16(118, 118, 0xe00, 0x10, 9, 1), /* MSDC0_DAT2 */
+ PIN_FIELD16(119, 119, 0xe00, 0x10, 5, 1), /* MSDC0_DAT1 */
+ PIN_FIELD16(120, 120, 0xe00, 0x10, 1, 1), /* MSDC0_DAT0 */
+};
- MTK_PIN_DRV_GRP(115, 0xd60, 12, 2),
+static const struct mtk_pin_field_calc mt8516_pin_drv_range[] = {
+ PINS_FIELD16(0, 4, 0xd00, 0x10, 0, 2),
+ PINS_FIELD16(5, 10, 0xd00, 0x10, 4, 2),
+ PINS_FIELD16(11, 13, 0xd00, 0x10, 8, 2),
+ PINS_FIELD16(14, 17, 0xd00, 0x10, 12, 2),
+ PINS_FIELD16(18, 20, 0xd10, 0x10, 0, 2),
+ PINS_FIELD16(21, 23, 0xd00, 0x10, 12, 2),
+ PINS_FIELD16(24, 25, 0xd00, 0x10, 8, 2),
+ PINS_FIELD16(26, 30, 0xd10, 0x10, 4, 2),
+ PINS_FIELD16(31, 33, 0xd10, 0x10, 8, 2),
+ PINS_FIELD16(34, 35, 0xd10, 0x10, 12, 2),
+ PINS_FIELD16(36, 39, 0xd20, 0x10, 0, 2),
+ PIN_FIELD16(40, 40, 0xd20, 0x10, 4, 2),
+ PINS_FIELD16(41, 43, 0xd20, 0x10, 8, 2),
+ PINS_FIELD16(44, 47, 0xd20, 0x10, 12, 2),
+ PINS_FIELD16(48, 51, 0xd30, 0x10, 12, 2),
+
+ PIN_FIELD16(54, 54, 0xd30, 0x10, 8, 2),
+ PINS_FIELD16(55, 57, 0xd30, 0x10, 0, 2),
+
+ PINS_FIELD16(62, 67, 0xd40, 0x10, 8, 2),
+ PIN_FIELD16(68, 68, 0xd40, 0x10, 12, 2),
+ PIN_FIELD16(69, 69, 0xd50, 0x10, 0, 2),
+ PINS_FIELD16(70, 73, 0xd50, 0x10, 4, 2),
+
+ PINS_FIELD16(100, 103, 0xd50, 0x10, 8, 2),
+ PIN_FIELD16(104, 104, 0xd50, 0x10, 12, 2),
+ PIN_FIELD16(105, 105, 0xd60, 0x10, 0, 2),
+ PINS_FIELD16(106, 109, 0xd60, 0x10, 4, 2),
+ PINS_FIELD16(110, 113, 0xd70, 0x10, 0, 2),
+ PIN_FIELD16(114, 114, 0xd70, 0x10, 4, 2),
+ PIN_FIELD16(115, 115, 0xd60, 0x10, 12, 2),
+ PIN_FIELD16(116, 116, 0xd60, 0x10, 8, 2),
+ PINS_FIELD16(117, 120, 0xd70, 0x10, 0, 2),
+};
- MTK_PIN_DRV_GRP(116, 0xd60, 8, 2),
+static const struct mtk_pin_field_calc mt8516_pin_sr_range[] = {
+ PINS_FIELD16(0, 4, 0xd00, 0x10, 3, 1),
+ PINS_FIELD16(5, 10, 0xd00, 0x10, 7, 1),
+ PINS_FIELD16(11, 13, 0xd00, 0x10, 11, 1),
+ PINS_FIELD16(14, 17, 0xd00, 0x10, 15, 1),
+ PINS_FIELD16(18, 20, 0xd10, 0x10, 3, 1),
+ PINS_FIELD16(21, 23, 0xd00, 0x10, 15, 1),
+ PINS_FIELD16(24, 25, 0xd00, 0x10, 11, 1),
+ PINS_FIELD16(26, 30, 0xd10, 0x10, 7, 1),
+ PINS_FIELD16(31, 33, 0xd10, 0x10, 11, 1),
+ PINS_FIELD16(34, 35, 0xd10, 0x10, 15, 1),
+ PINS_FIELD16(36, 39, 0xd20, 0x10, 3, 1),
+ PIN_FIELD16(40, 40, 0xd20, 0x10, 7, 1),
+ PINS_FIELD16(41, 43, 0xd20, 0x10, 11, 1),
+ PINS_FIELD16(44, 47, 0xd20, 0x10, 15, 1),
+ PINS_FIELD16(48, 51, 0xd30, 0x10, 15, 1),
+
+ PIN_FIELD16(54, 54, 0xd30, 0x10, 11, 1),
+ PINS_FIELD16(55, 57, 0xd30, 0x10, 3, 1),
+
+ PINS_FIELD16(62, 67, 0xd40, 0x10, 11, 1),
+ PIN_FIELD16(68, 68, 0xd40, 0x10, 15, 1),
+ PIN_FIELD16(69, 69, 0xd50, 0x10, 3, 1),
+ PINS_FIELD16(70, 73, 0xd50, 0x10, 7, 1),
+
+ PINS_FIELD16(100, 103, 0xd50, 0x10, 11, 1),
+ PIN_FIELD16(104, 104, 0xd50, 0x10, 15, 1),
+ PIN_FIELD16(105, 105, 0xd60, 0x10, 3, 1),
+ PINS_FIELD16(106, 109, 0xd60, 0x10, 7, 1),
+ PINS_FIELD16(110, 113, 0xd70, 0x10, 3, 1),
+ PIN_FIELD16(114, 114, 0xd70, 0x10, 7, 1),
+ PIN_FIELD16(115, 115, 0xd60, 0x10, 15, 1),
+ PIN_FIELD16(116, 116, 0xd60, 0x10, 11, 1),
+ PINS_FIELD16(117, 120, 0xd70, 0x10, 3, 1),
+};
- MTK_PIN_DRV_GRP(117, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(118, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(119, 0xd70, 0, 2),
- MTK_PIN_DRV_GRP(120, 0xd70, 0, 2),
+static const struct mtk_pin_reg_calc mt8516_reg_cals[PINCTRL_PIN_REG_MAX] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt8516_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt8516_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt8516_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt8516_pin_do_range),
+ [PINCTRL_PIN_REG_SR] = MTK_RANGE(mt8516_pin_sr_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt8516_pin_smt_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt8516_pin_drv_range),
+ [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt8516_pin_pupd_range),
+ [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt8516_pin_r0_range),
+ [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt8516_pin_r1_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt8516_pin_ies_range),
+ [PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt8516_pin_pullen_range),
+ [PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt8516_pin_pullsel_range),
};
-static const struct mtk_pin_spec_pupd_set_samereg mt8516_spec_pupd[] = {
- MTK_PIN_PUPD_SPEC_SR(14, 0xe50, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(15, 0xe60, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(16, 0xe60, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(17, 0xe60, 10, 9, 8),
-
- MTK_PIN_PUPD_SPEC_SR(21, 0xe60, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(22, 0xe70, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(23, 0xe70, 6, 5, 4),
-
- MTK_PIN_PUPD_SPEC_SR(40, 0xe80, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(41, 0xe80, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(42, 0xe90, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(43, 0xe90, 6, 5, 4),
-
- MTK_PIN_PUPD_SPEC_SR(68, 0xe50, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(69, 0xe50, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(70, 0xe40, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(71, 0xe40, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(72, 0xe40, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(73, 0xe50, 2, 1, 0),
-
- MTK_PIN_PUPD_SPEC_SR(104, 0xe40, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(105, 0xe30, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(106, 0xe20, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(107, 0xe30, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(108, 0xe30, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(109, 0xe30, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(110, 0xe10, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(111, 0xe10, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(112, 0xe10, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(113, 0xe10, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(114, 0xe20, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(115, 0xe20, 2, 1, 0),
- MTK_PIN_PUPD_SPEC_SR(116, 0xe20, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(117, 0xe00, 14, 13, 12),
- MTK_PIN_PUPD_SPEC_SR(118, 0xe00, 10, 9, 8),
- MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 6, 5, 4),
- MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 2, 1, 0),
+static const struct mtk_eint_hw mt8516_eint_hw = {
+ .port_mask = 7,
+ .ports = 6,
+ .ap_num = 169,
+ .db_cnt = 64,
+ .db_time = debounce_time_mt6795,
};
-static const struct mtk_pin_ies_smt_set mt8516_ies_set[] = {
- MTK_PIN_IES_SMT_SPEC(0, 6, 0x900, 2),
- MTK_PIN_IES_SMT_SPEC(7, 10, 0x900, 3),
- MTK_PIN_IES_SMT_SPEC(11, 13, 0x900, 12),
- MTK_PIN_IES_SMT_SPEC(14, 17, 0x900, 13),
- MTK_PIN_IES_SMT_SPEC(18, 20, 0x910, 10),
- MTK_PIN_IES_SMT_SPEC(21, 23, 0x900, 13),
- MTK_PIN_IES_SMT_SPEC(24, 25, 0x900, 12),
- MTK_PIN_IES_SMT_SPEC(26, 30, 0x900, 0),
- MTK_PIN_IES_SMT_SPEC(31, 33, 0x900, 1),
- MTK_PIN_IES_SMT_SPEC(34, 39, 0x900, 2),
- MTK_PIN_IES_SMT_SPEC(40, 40, 0x910, 11),
- MTK_PIN_IES_SMT_SPEC(41, 43, 0x900, 10),
- MTK_PIN_IES_SMT_SPEC(44, 47, 0x900, 11),
- MTK_PIN_IES_SMT_SPEC(48, 51, 0x900, 14),
- MTK_PIN_IES_SMT_SPEC(52, 53, 0x910, 0),
- MTK_PIN_IES_SMT_SPEC(54, 54, 0x910, 2),
- MTK_PIN_IES_SMT_SPEC(55, 57, 0x910, 4),
- MTK_PIN_IES_SMT_SPEC(58, 59, 0x900, 15),
- MTK_PIN_IES_SMT_SPEC(60, 61, 0x910, 1),
- MTK_PIN_IES_SMT_SPEC(62, 65, 0x910, 5),
- MTK_PIN_IES_SMT_SPEC(66, 67, 0x910, 6),
- MTK_PIN_IES_SMT_SPEC(68, 68, 0x930, 2),
- MTK_PIN_IES_SMT_SPEC(69, 69, 0x930, 1),
- MTK_PIN_IES_SMT_SPEC(70, 70, 0x930, 6),
- MTK_PIN_IES_SMT_SPEC(71, 71, 0x930, 5),
- MTK_PIN_IES_SMT_SPEC(72, 72, 0x930, 4),
- MTK_PIN_IES_SMT_SPEC(73, 73, 0x930, 3),
- MTK_PIN_IES_SMT_SPEC(100, 103, 0x910, 7),
- MTK_PIN_IES_SMT_SPEC(104, 104, 0x920, 12),
- MTK_PIN_IES_SMT_SPEC(105, 105, 0x920, 11),
- MTK_PIN_IES_SMT_SPEC(106, 106, 0x930, 0),
- MTK_PIN_IES_SMT_SPEC(107, 107, 0x920, 15),
- MTK_PIN_IES_SMT_SPEC(108, 108, 0x920, 14),
- MTK_PIN_IES_SMT_SPEC(109, 109, 0x920, 13),
- MTK_PIN_IES_SMT_SPEC(110, 110, 0x920, 9),
- MTK_PIN_IES_SMT_SPEC(111, 111, 0x920, 8),
- MTK_PIN_IES_SMT_SPEC(112, 112, 0x920, 7),
- MTK_PIN_IES_SMT_SPEC(113, 113, 0x920, 6),
- MTK_PIN_IES_SMT_SPEC(114, 114, 0x920, 10),
- MTK_PIN_IES_SMT_SPEC(115, 115, 0x920, 1),
- MTK_PIN_IES_SMT_SPEC(116, 116, 0x920, 0),
- MTK_PIN_IES_SMT_SPEC(117, 117, 0x920, 5),
- MTK_PIN_IES_SMT_SPEC(118, 118, 0x920, 4),
- MTK_PIN_IES_SMT_SPEC(119, 119, 0x920, 3),
- MTK_PIN_IES_SMT_SPEC(120, 120, 0x920, 2),
- MTK_PIN_IES_SMT_SPEC(121, 124, 0x910, 9),
+static const unsigned int mt8516_pull_type[] = {
+ MTK_PULL_PULLSEL_TYPE,/*0*/ MTK_PULL_PULLSEL_TYPE,/*1*/
+ MTK_PULL_PULLSEL_TYPE,/*2*/ MTK_PULL_PULLSEL_TYPE,/*3*/
+ MTK_PULL_PULLSEL_TYPE,/*4*/ MTK_PULL_PULLSEL_TYPE,/*5*/
+ MTK_PULL_PULLSEL_TYPE,/*6*/ MTK_PULL_PULLSEL_TYPE,/*7*/
+ MTK_PULL_PULLSEL_TYPE,/*8*/ MTK_PULL_PULLSEL_TYPE,/*9*/
+ MTK_PULL_PULLSEL_TYPE,/*10*/ MTK_PULL_PULLSEL_TYPE,/*11*/
+ MTK_PULL_PULLSEL_TYPE,/*12*/ MTK_PULL_PULLSEL_TYPE,/*13*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*14*/ MTK_PULL_PUPD_R1R0_TYPE,/*15*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*16*/ MTK_PULL_PUPD_R1R0_TYPE,/*17*/
+ MTK_PULL_PULLSEL_TYPE,/*18*/ MTK_PULL_PULLSEL_TYPE,/*19*/
+ MTK_PULL_PULLSEL_TYPE,/*20*/ MTK_PULL_PUPD_R1R0_TYPE,/*21*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*22*/ MTK_PULL_PUPD_R1R0_TYPE,/*23*/
+ MTK_PULL_PULLSEL_TYPE,/*24*/ MTK_PULL_PULLSEL_TYPE,/*25*/
+ MTK_PULL_PULLSEL_TYPE,/*26*/ MTK_PULL_PULLSEL_TYPE,/*27*/
+ MTK_PULL_PULLSEL_TYPE,/*28*/ MTK_PULL_PULLSEL_TYPE,/*29*/
+ MTK_PULL_PULLSEL_TYPE,/*30*/ MTK_PULL_PULLSEL_TYPE,/*31*/
+ MTK_PULL_PULLSEL_TYPE,/*32*/ MTK_PULL_PULLSEL_TYPE,/*33*/
+ MTK_PULL_PULLSEL_TYPE,/*34*/ MTK_PULL_PULLSEL_TYPE,/*35*/
+ MTK_PULL_PULLSEL_TYPE,/*36*/ MTK_PULL_PULLSEL_TYPE,/*37*/
+ MTK_PULL_PULLSEL_TYPE,/*38*/ MTK_PULL_PULLSEL_TYPE,/*39*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*40*/ MTK_PULL_PUPD_R1R0_TYPE,/*41*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*42*/ MTK_PULL_PUPD_R1R0_TYPE,/*43*/
+ MTK_PULL_PULLSEL_TYPE,/*44*/ MTK_PULL_PULLSEL_TYPE,/*45*/
+ MTK_PULL_PULLSEL_TYPE,/*46*/ MTK_PULL_PULLSEL_TYPE,/*47*/
+ MTK_PULL_PULLSEL_TYPE,/*48*/ MTK_PULL_PULLSEL_TYPE,/*49*/
+ MTK_PULL_PULLSEL_TYPE,/*50*/ MTK_PULL_PULLSEL_TYPE,/*51*/
+ MTK_PULL_PULLSEL_TYPE,/*52*/ MTK_PULL_PULLSEL_TYPE,/*53*/
+ MTK_PULL_PULLSEL_TYPE,/*54*/ MTK_PULL_PULLSEL_TYPE,/*55*/
+ MTK_PULL_PULLSEL_TYPE,/*56*/ MTK_PULL_PULLSEL_TYPE,/*57*/
+ MTK_PULL_PULLSEL_TYPE,/*58*/ MTK_PULL_PULLSEL_TYPE,/*59*/
+ MTK_PULL_PULLSEL_TYPE,/*60*/ MTK_PULL_PULLSEL_TYPE,/*61*/
+ MTK_PULL_PULLSEL_TYPE,/*62*/ MTK_PULL_PULLSEL_TYPE,/*63*/
+ MTK_PULL_PULLSEL_TYPE,/*64*/ MTK_PULL_PULLSEL_TYPE,/*65*/
+ MTK_PULL_PULLSEL_TYPE,/*66*/ MTK_PULL_PULLSEL_TYPE,/*67*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*68*/ MTK_PULL_PUPD_R1R0_TYPE,/*69*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*70*/ MTK_PULL_PUPD_R1R0_TYPE,/*71*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*72*/ MTK_PULL_PUPD_R1R0_TYPE,/*73*/
+ MTK_PULL_PULLSEL_TYPE,/*74*/ MTK_PULL_PULLSEL_TYPE,/*75*/
+ MTK_PULL_PULLSEL_TYPE,/*76*/ MTK_PULL_PULLSEL_TYPE,/*77*/
+ MTK_PULL_PULLSEL_TYPE,/*78*/ MTK_PULL_PULLSEL_TYPE,/*79*/
+ MTK_PULL_PULLSEL_TYPE,/*80*/ MTK_PULL_PULLSEL_TYPE,/*81*/
+ MTK_PULL_PULLSEL_TYPE,/*82*/ MTK_PULL_PULLSEL_TYPE,/*83*/
+ MTK_PULL_PULLSEL_TYPE,/*84*/ MTK_PULL_PULLSEL_TYPE,/*85*/
+ MTK_PULL_PULLSEL_TYPE,/*86*/ MTK_PULL_PULLSEL_TYPE,/*87*/
+ MTK_PULL_PULLSEL_TYPE,/*88*/ MTK_PULL_PULLSEL_TYPE,/*89*/
+ MTK_PULL_PULLSEL_TYPE,/*90*/ MTK_PULL_PULLSEL_TYPE,/*91*/
+ MTK_PULL_PULLSEL_TYPE,/*92*/ MTK_PULL_PULLSEL_TYPE,/*93*/
+ MTK_PULL_PULLSEL_TYPE,/*94*/ MTK_PULL_PULLSEL_TYPE,/*95*/
+ MTK_PULL_PULLSEL_TYPE,/*96*/ MTK_PULL_PULLSEL_TYPE,/*97*/
+ MTK_PULL_PULLSEL_TYPE,/*98*/ MTK_PULL_PULLSEL_TYPE,/*99*/
+ MTK_PULL_PULLSEL_TYPE,/*100*/ MTK_PULL_PULLSEL_TYPE,/*101*/
+ MTK_PULL_PULLSEL_TYPE,/*102*/ MTK_PULL_PULLSEL_TYPE,/*103*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*104*/ MTK_PULL_PUPD_R1R0_TYPE,/*105*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*106*/ MTK_PULL_PUPD_R1R0_TYPE,/*107*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*108*/ MTK_PULL_PUPD_R1R0_TYPE,/*109*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*110*/ MTK_PULL_PUPD_R1R0_TYPE,/*111*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*112*/ MTK_PULL_PUPD_R1R0_TYPE,/*113*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*114*/ MTK_PULL_PUPD_R1R0_TYPE,/*115*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*116*/ MTK_PULL_PUPD_R1R0_TYPE,/*117*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*118*/ MTK_PULL_PUPD_R1R0_TYPE,/*119*/
+ MTK_PULL_PUPD_R1R0_TYPE,/*120*/ MTK_PULL_PULLSEL_TYPE,/*121*/
+ MTK_PULL_PULLSEL_TYPE,/*122*/ MTK_PULL_PULLSEL_TYPE,/*123*/
+ MTK_PULL_PULLSEL_TYPE,/*124*/
};
-static const struct mtk_pin_ies_smt_set mt8516_smt_set[] = {
- MTK_PIN_IES_SMT_SPEC(0, 6, 0xA00, 2),
- MTK_PIN_IES_SMT_SPEC(7, 10, 0xA00, 3),
- MTK_PIN_IES_SMT_SPEC(11, 13, 0xA00, 12),
- MTK_PIN_IES_SMT_SPEC(14, 17, 0xA00, 13),
- MTK_PIN_IES_SMT_SPEC(18, 20, 0xA10, 10),
- MTK_PIN_IES_SMT_SPEC(21, 23, 0xA00, 13),
- MTK_PIN_IES_SMT_SPEC(24, 25, 0xA00, 12),
- MTK_PIN_IES_SMT_SPEC(26, 30, 0xA00, 0),
- MTK_PIN_IES_SMT_SPEC(31, 33, 0xA00, 1),
- MTK_PIN_IES_SMT_SPEC(34, 39, 0xA00, 2),
- MTK_PIN_IES_SMT_SPEC(40, 40, 0xA10, 11),
- MTK_PIN_IES_SMT_SPEC(41, 43, 0xA00, 10),
- MTK_PIN_IES_SMT_SPEC(44, 47, 0xA00, 11),
- MTK_PIN_IES_SMT_SPEC(48, 51, 0xA00, 14),
- MTK_PIN_IES_SMT_SPEC(52, 53, 0xA10, 0),
- MTK_PIN_IES_SMT_SPEC(54, 54, 0xA10, 2),
- MTK_PIN_IES_SMT_SPEC(55, 57, 0xA10, 4),
- MTK_PIN_IES_SMT_SPEC(58, 59, 0xA00, 15),
- MTK_PIN_IES_SMT_SPEC(60, 61, 0xA10, 1),
- MTK_PIN_IES_SMT_SPEC(62, 65, 0xA10, 5),
- MTK_PIN_IES_SMT_SPEC(66, 67, 0xA10, 6),
- MTK_PIN_IES_SMT_SPEC(68, 68, 0xA30, 2),
- MTK_PIN_IES_SMT_SPEC(69, 69, 0xA30, 1),
- MTK_PIN_IES_SMT_SPEC(70, 70, 0xA30, 3),
- MTK_PIN_IES_SMT_SPEC(71, 71, 0xA30, 4),
- MTK_PIN_IES_SMT_SPEC(72, 72, 0xA30, 5),
- MTK_PIN_IES_SMT_SPEC(73, 73, 0xA30, 6),
-
- MTK_PIN_IES_SMT_SPEC(100, 103, 0xA10, 7),
- MTK_PIN_IES_SMT_SPEC(104, 104, 0xA20, 12),
- MTK_PIN_IES_SMT_SPEC(105, 105, 0xA20, 11),
- MTK_PIN_IES_SMT_SPEC(106, 106, 0xA30, 13),
- MTK_PIN_IES_SMT_SPEC(107, 107, 0xA20, 14),
- MTK_PIN_IES_SMT_SPEC(108, 108, 0xA20, 15),
- MTK_PIN_IES_SMT_SPEC(109, 109, 0xA30, 0),
- MTK_PIN_IES_SMT_SPEC(110, 110, 0xA20, 9),
- MTK_PIN_IES_SMT_SPEC(111, 111, 0xA20, 8),
- MTK_PIN_IES_SMT_SPEC(112, 112, 0xA20, 7),
- MTK_PIN_IES_SMT_SPEC(113, 113, 0xA20, 6),
- MTK_PIN_IES_SMT_SPEC(114, 114, 0xA20, 10),
- MTK_PIN_IES_SMT_SPEC(115, 115, 0xA20, 1),
- MTK_PIN_IES_SMT_SPEC(116, 116, 0xA20, 0),
- MTK_PIN_IES_SMT_SPEC(117, 117, 0xA20, 5),
- MTK_PIN_IES_SMT_SPEC(118, 118, 0xA20, 4),
- MTK_PIN_IES_SMT_SPEC(119, 119, 0xA20, 3),
- MTK_PIN_IES_SMT_SPEC(120, 120, 0xA20, 2),
- MTK_PIN_IES_SMT_SPEC(121, 124, 0xA10, 9),
+static const struct mtk_pin_soc mt8167_pinctrl_data = {
+ .reg_cal = mt8516_reg_cals,
+ .pins = mtk_pins_mt8167,
+ .npins = ARRAY_SIZE(mtk_pins_mt8167),
+ .ngrps = ARRAY_SIZE(mtk_pins_mt8167),
+ .nfuncs = 8,
+ .eint_hw = &mt8516_eint_hw,
+ .gpio_m = 0,
+ .ies_present = true,
+ .base_names = mtk_default_register_base_names,
+ .nbase_names = ARRAY_SIZE(mtk_default_register_base_names),
+ .pull_type = mt8516_pull_type,
+ .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
+ .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
+ .bias_set = mtk_pinconf_bias_set_rev1,
+ .bias_get = mtk_pinconf_bias_get_rev1,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
+ .drive_set = mtk_pinconf_drive_set_rev1,
+ .drive_get = mtk_pinconf_drive_get_rev1,
+ .adv_pull_get = mtk_pinconf_adv_pull_get,
+ .adv_pull_set = mtk_pinconf_adv_pull_set,
};
-static const struct mtk_pinctrl_devdata mt8516_pinctrl_data = {
+static const struct mtk_pin_soc mt8516_pinctrl_data = {
+ .reg_cal = mt8516_reg_cals,
.pins = mtk_pins_mt8516,
.npins = ARRAY_SIZE(mtk_pins_mt8516),
- .grp_desc = mt8516_drv_grp,
- .n_grp_cls = ARRAY_SIZE(mt8516_drv_grp),
- .pin_drv_grp = mt8516_pin_drv,
- .n_pin_drv_grps = ARRAY_SIZE(mt8516_pin_drv),
- .spec_ies = mt8516_ies_set,
- .n_spec_ies = ARRAY_SIZE(mt8516_ies_set),
- .spec_pupd = mt8516_spec_pupd,
- .n_spec_pupd = ARRAY_SIZE(mt8516_spec_pupd),
- .spec_smt = mt8516_smt_set,
- .n_spec_smt = ARRAY_SIZE(mt8516_smt_set),
- .spec_pull_set = mtk_pctrl_spec_pull_set_samereg,
- .spec_ies_smt_set = mtk_pconf_spec_set_ies_smt_range,
- .dir_offset = 0x0000,
- .pullen_offset = 0x0500,
- .pullsel_offset = 0x0600,
- .dout_offset = 0x0100,
- .din_offset = 0x0200,
- .pinmux_offset = 0x0300,
- .type1_start = 125,
- .type1_end = 125,
- .port_shf = 4,
- .port_mask = 0xf,
- .port_align = 4,
- .mode_mask = 0xf,
- .mode_per_reg = 5,
- .mode_shf = 4,
- .eint_hw = {
- .port_mask = 7,
- .ports = 6,
- .ap_num = 169,
- .db_cnt = 64,
- .db_time = debounce_time_mt6795,
- },
+ .ngrps = ARRAY_SIZE(mtk_pins_mt8516),
+ .nfuncs = 8,
+ .eint_hw = &mt8516_eint_hw,
+ .gpio_m = 0,
+ .ies_present = true,
+ .base_names = mtk_default_register_base_names,
+ .nbase_names = ARRAY_SIZE(mtk_default_register_base_names),
+ .pull_type = mt8516_pull_type,
+ .bias_disable_set = mtk_pinconf_bias_disable_set_rev1,
+ .bias_disable_get = mtk_pinconf_bias_disable_get_rev1,
+ .bias_set = mtk_pinconf_bias_set_rev1,
+ .bias_get = mtk_pinconf_bias_get_rev1,
+ .bias_set_combo = mtk_pinconf_bias_set_combo,
+ .bias_get_combo = mtk_pinconf_bias_get_combo,
+ .drive_set = mtk_pinconf_drive_set_rev1,
+ .drive_get = mtk_pinconf_drive_get_rev1,
+ .adv_pull_get = mtk_pinconf_adv_pull_get,
+ .adv_pull_set = mtk_pinconf_adv_pull_set,
};
-static const struct of_device_id mt8516_pctrl_match[] = {
+static const struct of_device_id mt8516_pinctrl_of_match[] = {
+ { .compatible = "mediatek,mt8167-pinctrl", .data = &mt8167_pinctrl_data },
{ .compatible = "mediatek,mt8516-pinctrl", .data = &mt8516_pinctrl_data },
{}
};
+MODULE_DEVICE_TABLE(of, mt8516_pinctrl_of_match);
-MODULE_DEVICE_TABLE(of, mt8516_pctrl_match);
-
-static struct platform_driver mtk_pinctrl_driver = {
- .probe = mtk_pctrl_common_probe,
+static struct platform_driver mt8516_pinctrl_driver = {
.driver = {
.name = "mediatek-mt8516-pinctrl",
- .of_match_table = mt8516_pctrl_match,
- .pm = pm_sleep_ptr(&mtk_eint_pm_ops),
+ .of_match_table = mt8516_pinctrl_of_match,
+ .pm = pm_sleep_ptr(&mtk_paris_pinctrl_pm_ops),
},
+ .probe = mtk_paris_pinctrl_probe,
};
-static int __init mtk_pinctrl_init(void)
+static int __init mt8516_pinctrl_init(void)
{
- return platform_driver_register(&mtk_pinctrl_driver);
+ return platform_driver_register(&mt8516_pinctrl_driver);
}
-arch_initcall(mtk_pinctrl_init);
+arch_initcall(mt8516_pinctrl_init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek MT8516/MT8167 Pinctrl Driver");
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h
index 225c41fc9b75..d0c603838644 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h
@@ -1,18 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2020 MediaTek Inc.
- */
#ifndef __PINCTRL_MTK_MT8167_H
#define __PINCTRL_MTK_MT8167_H
-#include <linux/pinctrl/pinctrl.h>
-#include "pinctrl-mtk-common.h"
+#include "pinctrl-paris.h"
-static const struct mtk_desc_pin mtk_pins_mt8167[] = {
+static const struct mtk_pin_desc mtk_pins_mt8167[] = {
MTK_PIN(
- PINCTRL_PIN(0, "EINT0"),
- NULL, "mt8167",
+ 0, "EINT0",
MTK_EINT_FUNCTION(0, 0),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO0"),
MTK_FUNCTION(1, "PWM_B"),
MTK_FUNCTION(2, "DPI_CK"),
@@ -22,9 +18,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[6]")
),
MTK_PIN(
- PINCTRL_PIN(1, "EINT1"),
- NULL, "mt8167",
+ 1, "EINT1",
MTK_EINT_FUNCTION(0, 1),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO1"),
MTK_FUNCTION(1, "PWM_C"),
MTK_FUNCTION(2, "DPI_D12"),
@@ -35,9 +31,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[7]")
),
MTK_PIN(
- PINCTRL_PIN(2, "EINT2"),
- NULL, "mt8167",
+ 2, "EINT2",
MTK_EINT_FUNCTION(0, 2),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO2"),
MTK_FUNCTION(1, "CLKM0"),
MTK_FUNCTION(2, "DPI_D13"),
@@ -48,9 +44,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[8]")
),
MTK_PIN(
- PINCTRL_PIN(3, "EINT3"),
- NULL, "mt8167",
+ 3, "EINT3",
MTK_EINT_FUNCTION(0, 3),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO3"),
MTK_FUNCTION(1, "CLKM1"),
MTK_FUNCTION(2, "DPI_D14"),
@@ -61,9 +57,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[9]")
),
MTK_PIN(
- PINCTRL_PIN(4, "EINT4"),
- NULL, "mt8167",
+ 4, "EINT4",
MTK_EINT_FUNCTION(0, 4),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO4"),
MTK_FUNCTION(1, "CLKM2"),
MTK_FUNCTION(2, "DPI_D15"),
@@ -74,9 +70,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[10]")
),
MTK_PIN(
- PINCTRL_PIN(5, "EINT5"),
- NULL, "mt8167",
+ 5, "EINT5",
MTK_EINT_FUNCTION(0, 5),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO5"),
MTK_FUNCTION(1, "UCTS2"),
MTK_FUNCTION(2, "DPI_D16"),
@@ -87,9 +83,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[11]")
),
MTK_PIN(
- PINCTRL_PIN(6, "EINT6"),
- NULL, "mt8167",
+ 6, "EINT6",
MTK_EINT_FUNCTION(0, 6),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO6"),
MTK_FUNCTION(1, "URTS2"),
MTK_FUNCTION(2, "DPI_D17"),
@@ -100,9 +96,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[12]")
),
MTK_PIN(
- PINCTRL_PIN(7, "EINT7"),
- NULL, "mt8167",
+ 7, "EINT7",
MTK_EINT_FUNCTION(0, 7),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO7"),
MTK_FUNCTION(1, "SQIRST"),
MTK_FUNCTION(2, "DPI_D6"),
@@ -113,9 +109,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[13]")
),
MTK_PIN(
- PINCTRL_PIN(8, "EINT8"),
- NULL, "mt8167",
+ 8, "EINT8",
MTK_EINT_FUNCTION(0, 8),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO8"),
MTK_FUNCTION(1, "SQICK"),
MTK_FUNCTION(2, "CLKM3"),
@@ -126,9 +122,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[14]")
),
MTK_PIN(
- PINCTRL_PIN(9, "EINT9"),
- NULL, "mt8167",
+ 9, "EINT9",
MTK_EINT_FUNCTION(0, 9),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO9"),
MTK_FUNCTION(1, "CLKM4"),
MTK_FUNCTION(2, "SDA2_0"),
@@ -139,9 +135,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[15]")
),
MTK_PIN(
- PINCTRL_PIN(10, "EINT10"),
- NULL, "mt8167",
+ 10, "EINT10",
MTK_EINT_FUNCTION(0, 10),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO10"),
MTK_FUNCTION(1, "CLKM5"),
MTK_FUNCTION(2, "SCL2_0"),
@@ -152,9 +148,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[16]")
),
MTK_PIN(
- PINCTRL_PIN(11, "EINT11"),
- NULL, "mt8167",
+ 11, "EINT11",
MTK_EINT_FUNCTION(0, 11),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO11"),
MTK_FUNCTION(1, "CLKM4"),
MTK_FUNCTION(2, "PWM_C"),
@@ -165,9 +161,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[17]")
),
MTK_PIN(
- PINCTRL_PIN(12, "EINT12"),
- NULL, "mt8167",
+ 12, "EINT12",
MTK_EINT_FUNCTION(0, 12),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO12"),
MTK_FUNCTION(1, "CLKM5"),
MTK_FUNCTION(2, "PWM_A"),
@@ -178,9 +174,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[18]")
),
MTK_PIN(
- PINCTRL_PIN(13, "EINT13"),
- NULL, "mt8167",
+ 13, "EINT13",
MTK_EINT_FUNCTION(0, 13),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO13"),
MTK_FUNCTION(3, "TSF_IN"),
MTK_FUNCTION(4, "ANT_SEL5"),
@@ -189,9 +185,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[19]")
),
MTK_PIN(
- PINCTRL_PIN(14, "EINT14"),
- NULL, "mt8167",
+ 14, "EINT14",
MTK_EINT_FUNCTION(0, 14),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO14"),
MTK_FUNCTION(2, "I2S_8CH_DO1"),
MTK_FUNCTION(3, "TDM_RX_MCK"),
@@ -201,9 +197,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[8]")
),
MTK_PIN(
- PINCTRL_PIN(15, "EINT15"),
- NULL, "mt8167",
+ 15, "EINT15",
MTK_EINT_FUNCTION(0, 15),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO15"),
MTK_FUNCTION(2, "I2S_8CH_LRCK"),
MTK_FUNCTION(3, "TDM_RX_BCK"),
@@ -213,9 +209,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[9]")
),
MTK_PIN(
- PINCTRL_PIN(16, "EINT16"),
- NULL, "mt8167",
+ 16, "EINT16",
MTK_EINT_FUNCTION(0, 16),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO16"),
MTK_FUNCTION(2, "I2S_8CH_BCK"),
MTK_FUNCTION(3, "TDM_RX_LRCK"),
@@ -225,9 +221,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[10]")
),
MTK_PIN(
- PINCTRL_PIN(17, "EINT17"),
- NULL, "mt8167",
+ 17, "EINT17",
MTK_EINT_FUNCTION(0, 17),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO17"),
MTK_FUNCTION(2, "I2S_8CH_MCK"),
MTK_FUNCTION(3, "TDM_RX_DI"),
@@ -237,9 +233,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[11]")
),
MTK_PIN(
- PINCTRL_PIN(18, "EINT18"),
- NULL, "mt8167",
+ 18, "EINT18",
MTK_EINT_FUNCTION(0, 18),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO18"),
MTK_FUNCTION(2, "USB_DRVVBUS"),
MTK_FUNCTION(3, "I2S3_LRCK"),
@@ -249,9 +245,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[20]")
),
MTK_PIN(
- PINCTRL_PIN(19, "EINT19"),
- NULL, "mt8167",
+ 19, "EINT19",
MTK_EINT_FUNCTION(0, 19),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO19"),
MTK_FUNCTION(1, "UCTS1"),
MTK_FUNCTION(2, "IDDIG"),
@@ -262,9 +258,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[21]")
),
MTK_PIN(
- PINCTRL_PIN(20, "EINT20"),
- NULL, "mt8167",
+ 20, "EINT20",
MTK_EINT_FUNCTION(0, 20),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO20"),
MTK_FUNCTION(1, "URTS1"),
MTK_FUNCTION(3, "I2S3_DO"),
@@ -274,9 +270,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[22]")
),
MTK_PIN(
- PINCTRL_PIN(21, "EINT21"),
- NULL, "mt8167",
+ 21, "EINT21",
MTK_EINT_FUNCTION(0, 21),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO21"),
MTK_FUNCTION(1, "NRNB"),
MTK_FUNCTION(2, "ANT_SEL0"),
@@ -284,9 +280,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[31]")
),
MTK_PIN(
- PINCTRL_PIN(22, "EINT22"),
- NULL, "mt8167",
+ 22, "EINT22",
MTK_EINT_FUNCTION(0, 22),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO22"),
MTK_FUNCTION(2, "I2S_8CH_DO2"),
MTK_FUNCTION(3, "TSF_IN"),
@@ -296,9 +292,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[12]")
),
MTK_PIN(
- PINCTRL_PIN(23, "EINT23"),
- NULL, "mt8167",
+ 23, "EINT23",
MTK_EINT_FUNCTION(0, 23),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO23"),
MTK_FUNCTION(2, "I2S_8CH_DO3"),
MTK_FUNCTION(3, "CLKM0"),
@@ -308,9 +304,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[13]")
),
MTK_PIN(
- PINCTRL_PIN(24, "EINT24"),
- NULL, "mt8167",
+ 24, "EINT24",
MTK_EINT_FUNCTION(0, 24),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO24"),
MTK_FUNCTION(1, "DPI_D20"),
MTK_FUNCTION(2, "DPI_DE"),
@@ -321,9 +317,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[0]")
),
MTK_PIN(
- PINCTRL_PIN(25, "EINT25"),
- NULL, "mt8167",
+ 25, "EINT25",
MTK_EINT_FUNCTION(0, 25),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO25"),
MTK_FUNCTION(1, "DPI_D19"),
MTK_FUNCTION(2, "DPI_VSYNC"),
@@ -334,25 +330,25 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[1]")
),
MTK_PIN(
- PINCTRL_PIN(26, "PWRAP_SPI0_MI"),
- NULL, "mt8167",
+ 26, "PWRAP_SPI0_MI",
MTK_EINT_FUNCTION(0, 26),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO26"),
MTK_FUNCTION(1, "PWRAP_SPI0_MO"),
MTK_FUNCTION(2, "PWRAP_SPI0_MI")
),
MTK_PIN(
- PINCTRL_PIN(27, "PWRAP_SPI0_MO"),
- NULL, "mt8167",
+ 27, "PWRAP_SPI0_MO",
MTK_EINT_FUNCTION(0, 27),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO27"),
MTK_FUNCTION(1, "PWRAP_SPI0_MI"),
MTK_FUNCTION(2, "PWRAP_SPI0_MO")
),
MTK_PIN(
- PINCTRL_PIN(28, "PWRAP_INT"),
- NULL, "mt8167",
+ 28, "PWRAP_INT",
MTK_EINT_FUNCTION(0, 28),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO28"),
MTK_FUNCTION(1, "I2S0_MCK"),
MTK_FUNCTION(4, "I2S_8CH_MCK"),
@@ -360,44 +356,44 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(6, "I2S3_MCK")
),
MTK_PIN(
- PINCTRL_PIN(29, "PWRAP_SPI0_CK"),
- NULL, "mt8167",
+ 29, "PWRAP_SPI0_CK",
MTK_EINT_FUNCTION(0, 29),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO29"),
MTK_FUNCTION(1, "PWRAP_SPI0_CK")
),
MTK_PIN(
- PINCTRL_PIN(30, "PWRAP_SPI0_CSN"),
- NULL, "mt8167",
+ 30, "PWRAP_SPI0_CSN",
MTK_EINT_FUNCTION(0, 30),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO30"),
MTK_FUNCTION(1, "PWRAP_SPI0_CSN")
),
MTK_PIN(
- PINCTRL_PIN(31, "RTC32K_CK"),
- NULL, "mt8167",
+ 31, "RTC32K_CK",
MTK_EINT_FUNCTION(0, 31),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO31"),
MTK_FUNCTION(1, "RTC32K_CK")
),
MTK_PIN(
- PINCTRL_PIN(32, "WATCHDOG"),
- NULL, "mt8167",
+ 32, "WATCHDOG",
MTK_EINT_FUNCTION(0, 32),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO32"),
MTK_FUNCTION(1, "WATCHDOG")
),
MTK_PIN(
- PINCTRL_PIN(33, "SRCLKENA"),
- NULL, "mt8167",
+ 33, "SRCLKENA",
MTK_EINT_FUNCTION(0, 33),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO33"),
MTK_FUNCTION(1, "SRCLKENA0")
),
MTK_PIN(
- PINCTRL_PIN(34, "URXD2"),
- NULL, "mt8167",
+ 34, "URXD2",
MTK_EINT_FUNCTION(0, 34),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO34"),
MTK_FUNCTION(1, "URXD2"),
MTK_FUNCTION(2, "DPI_D5"),
@@ -407,9 +403,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[0]")
),
MTK_PIN(
- PINCTRL_PIN(35, "UTXD2"),
- NULL, "mt8167",
+ 35, "UTXD2",
MTK_EINT_FUNCTION(0, 35),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO35"),
MTK_FUNCTION(1, "UTXD2"),
MTK_FUNCTION(2, "DPI_HSYNC"),
@@ -420,9 +416,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[1]")
),
MTK_PIN(
- PINCTRL_PIN(36, "MRG_CLK"),
- NULL, "mt8167",
+ 36, "MRG_CLK",
MTK_EINT_FUNCTION(0, 36),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO36"),
MTK_FUNCTION(1, "MRG_CLK"),
MTK_FUNCTION(2, "DPI_D4"),
@@ -433,9 +429,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[2]")
),
MTK_PIN(
- PINCTRL_PIN(37, "MRG_SYNC"),
- NULL, "mt8167",
+ 37, "MRG_SYNC",
MTK_EINT_FUNCTION(0, 37),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO37"),
MTK_FUNCTION(1, "MRG_SYNC"),
MTK_FUNCTION(2, "DPI_D3"),
@@ -446,9 +442,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[3]")
),
MTK_PIN(
- PINCTRL_PIN(38, "MRG_DI"),
- NULL, "mt8167",
+ 38, "MRG_DI",
MTK_EINT_FUNCTION(0, 38),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO38"),
MTK_FUNCTION(1, "MRG_DI"),
MTK_FUNCTION(2, "DPI_D1"),
@@ -459,9 +455,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[4]")
),
MTK_PIN(
- PINCTRL_PIN(39, "MRG_DO"),
- NULL, "mt8167",
+ 39, "MRG_DO",
MTK_EINT_FUNCTION(0, 39),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO39"),
MTK_FUNCTION(1, "MRG_DO"),
MTK_FUNCTION(2, "DPI_D2"),
@@ -472,18 +468,18 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[5]")
),
MTK_PIN(
- PINCTRL_PIN(40, "KPROW0"),
- NULL, "mt8167",
+ 40, "KPROW0",
MTK_EINT_FUNCTION(0, 40),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO40"),
MTK_FUNCTION(1, "KPROW0"),
MTK_FUNCTION(4, "IMG_TEST_CK"),
MTK_FUNCTION(7, "DBG_MON_B[4]")
),
MTK_PIN(
- PINCTRL_PIN(41, "KPROW1"),
- NULL, "mt8167",
+ 41, "KPROW1",
MTK_EINT_FUNCTION(0, 41),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO41"),
MTK_FUNCTION(1, "KPROW1"),
MTK_FUNCTION(2, "IDDIG"),
@@ -492,17 +488,17 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[5]")
),
MTK_PIN(
- PINCTRL_PIN(42, "KPCOL0"),
- NULL, "mt8167",
+ 42, "KPCOL0",
MTK_EINT_FUNCTION(0, 42),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO42"),
MTK_FUNCTION(1, "KPCOL0"),
MTK_FUNCTION(7, "DBG_MON_B[6]")
),
MTK_PIN(
- PINCTRL_PIN(43, "KPCOL1"),
- NULL, "mt8167",
+ 43, "KPCOL1",
MTK_EINT_FUNCTION(0, 43),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO43"),
MTK_FUNCTION(1, "KPCOL1"),
MTK_FUNCTION(2, "USB_DRVVBUS"),
@@ -513,9 +509,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[7]")
),
MTK_PIN(
- PINCTRL_PIN(44, "JTMS"),
- NULL, "mt8167",
+ 44, "JTMS",
MTK_EINT_FUNCTION(0, 44),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO44"),
MTK_FUNCTION(1, "JTMS"),
MTK_FUNCTION(2, "CONN_MCU_TMS"),
@@ -525,9 +521,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(6, "UDI_TMS_XI")
),
MTK_PIN(
- PINCTRL_PIN(45, "JTCK"),
- NULL, "mt8167",
+ 45, "JTCK",
MTK_EINT_FUNCTION(0, 45),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO45"),
MTK_FUNCTION(1, "JTCK"),
MTK_FUNCTION(2, "CONN_MCU_TCK"),
@@ -537,9 +533,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(6, "UDI_TCK_XI")
),
MTK_PIN(
- PINCTRL_PIN(46, "JTDI"),
- NULL, "mt8167",
+ 46, "JTDI",
MTK_EINT_FUNCTION(0, 46),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO46"),
MTK_FUNCTION(1, "JTDI"),
MTK_FUNCTION(2, "CONN_MCU_TDI"),
@@ -548,9 +544,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(6, "UDI_TDI_XI")
),
MTK_PIN(
- PINCTRL_PIN(47, "JTDO"),
- NULL, "mt8167",
+ 47, "JTDO",
MTK_EINT_FUNCTION(0, 47),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO47"),
MTK_FUNCTION(1, "JTDO"),
MTK_FUNCTION(2, "CONN_MCU_TDO"),
@@ -559,9 +555,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(6, "UDI_TDO")
),
MTK_PIN(
- PINCTRL_PIN(48, "SPI_CS"),
- NULL, "mt8167",
+ 48, "SPI_CS",
MTK_EINT_FUNCTION(0, 48),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO48"),
MTK_FUNCTION(1, "SPI_CSB"),
MTK_FUNCTION(3, "I2S0_DI"),
@@ -569,9 +565,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[23]")
),
MTK_PIN(
- PINCTRL_PIN(49, "SPI_CK"),
- NULL, "mt8167",
+ 49, "SPI_CK",
MTK_EINT_FUNCTION(0, 49),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO49"),
MTK_FUNCTION(1, "SPI_CLK"),
MTK_FUNCTION(3, "I2S0_LRCK"),
@@ -579,9 +575,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[24]")
),
MTK_PIN(
- PINCTRL_PIN(50, "SPI_MI"),
- NULL, "mt8167",
+ 50, "SPI_MI",
MTK_EINT_FUNCTION(0, 50),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO50"),
MTK_FUNCTION(1, "SPI_MI"),
MTK_FUNCTION(2, "SPI_MO"),
@@ -590,9 +586,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[25]")
),
MTK_PIN(
- PINCTRL_PIN(51, "SPI_MO"),
- NULL, "mt8167",
+ 51, "SPI_MO",
MTK_EINT_FUNCTION(0, 51),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO51"),
MTK_FUNCTION(1, "SPI_MO"),
MTK_FUNCTION(2, "SPI_MI"),
@@ -601,32 +597,32 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[26]")
),
MTK_PIN(
- PINCTRL_PIN(52, "SDA1"),
- NULL, "mt8167",
+ 52, "SDA1",
MTK_EINT_FUNCTION(0, 52),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO52"),
MTK_FUNCTION(1, "SDA1_0")
),
MTK_PIN(
- PINCTRL_PIN(53, "SCL1"),
- NULL, "mt8167",
+ 53, "SCL1",
MTK_EINT_FUNCTION(0, 53),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO53"),
MTK_FUNCTION(1, "SCL1_0")
),
MTK_PIN(
- PINCTRL_PIN(54, "DISP_PWM"),
- NULL, "mt8167",
+ 54, "DISP_PWM",
MTK_EINT_FUNCTION(0, 54),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO54"),
MTK_FUNCTION(1, "DISP_PWM"),
MTK_FUNCTION(2, "PWM_B"),
MTK_FUNCTION(7, "DBG_MON_B[2]")
),
MTK_PIN(
- PINCTRL_PIN(55, "I2S_DATA_IN"),
- NULL, "mt8167",
+ 55, "I2S_DATA_IN",
MTK_EINT_FUNCTION(0, 55),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO55"),
MTK_FUNCTION(1, "I2S0_DI"),
MTK_FUNCTION(2, "UCTS0"),
@@ -637,9 +633,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[28]")
),
MTK_PIN(
- PINCTRL_PIN(56, "I2S_LRCK"),
- NULL, "mt8167",
+ 56, "I2S_LRCK",
MTK_EINT_FUNCTION(0, 56),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO56"),
MTK_FUNCTION(1, "I2S0_LRCK"),
MTK_FUNCTION(3, "I2S3_LRCK"),
@@ -649,9 +645,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[29]")
),
MTK_PIN(
- PINCTRL_PIN(57, "I2S_BCK"),
- NULL, "mt8167",
+ 57, "I2S_BCK",
MTK_EINT_FUNCTION(0, 57),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO57"),
MTK_FUNCTION(1, "I2S0_BCK"),
MTK_FUNCTION(2, "URTS0"),
@@ -662,91 +658,91 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_A[30]")
),
MTK_PIN(
- PINCTRL_PIN(58, "SDA0"),
- NULL, "mt8167",
+ 58, "SDA0",
MTK_EINT_FUNCTION(0, 58),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO58"),
MTK_FUNCTION(1, "SDA0_0")
),
MTK_PIN(
- PINCTRL_PIN(59, "SCL0"),
- NULL, "mt8167",
+ 59, "SCL0",
MTK_EINT_FUNCTION(0, 59),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO59"),
MTK_FUNCTION(1, "SCL0_0")
),
MTK_PIN(
- PINCTRL_PIN(60, "SDA2"),
- NULL, "mt8167",
+ 60, "SDA2",
MTK_EINT_FUNCTION(0, 60),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO60"),
MTK_FUNCTION(1, "SDA2_0"),
MTK_FUNCTION(2, "PWM_B")
),
MTK_PIN(
- PINCTRL_PIN(61, "SCL2"),
- NULL, "mt8167",
+ 61, "SCL2",
MTK_EINT_FUNCTION(0, 61),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO61"),
MTK_FUNCTION(1, "SCL2_0"),
MTK_FUNCTION(2, "PWM_C")
),
MTK_PIN(
- PINCTRL_PIN(62, "URXD0"),
- NULL, "mt8167",
+ 62, "URXD0",
MTK_EINT_FUNCTION(0, 62),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO62"),
MTK_FUNCTION(1, "URXD0"),
MTK_FUNCTION(2, "UTXD0")
),
MTK_PIN(
- PINCTRL_PIN(63, "UTXD0"),
- NULL, "mt8167",
+ 63, "UTXD0",
MTK_EINT_FUNCTION(0, 63),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO63"),
MTK_FUNCTION(1, "UTXD0"),
MTK_FUNCTION(2, "URXD0")
),
MTK_PIN(
- PINCTRL_PIN(64, "URXD1"),
- NULL, "mt8167",
+ 64, "URXD1",
MTK_EINT_FUNCTION(0, 64),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO64"),
MTK_FUNCTION(1, "URXD1"),
MTK_FUNCTION(2, "UTXD1"),
MTK_FUNCTION(7, "DBG_MON_A[27]")
),
MTK_PIN(
- PINCTRL_PIN(65, "UTXD1"),
- NULL, "mt8167",
+ 65, "UTXD1",
MTK_EINT_FUNCTION(0, 65),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO65"),
MTK_FUNCTION(1, "UTXD1"),
MTK_FUNCTION(2, "URXD1"),
MTK_FUNCTION(7, "DBG_MON_A[31]")
),
MTK_PIN(
- PINCTRL_PIN(66, "LCM_RST"),
- NULL, "mt8167",
+ 66, "LCM_RST",
MTK_EINT_FUNCTION(0, 66),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO66"),
MTK_FUNCTION(1, "LCM_RST"),
MTK_FUNCTION(3, "I2S0_MCK"),
MTK_FUNCTION(7, "DBG_MON_B[3]")
),
MTK_PIN(
- PINCTRL_PIN(67, "DSI_TE"),
- NULL, "mt8167",
+ 67, "DSI_TE",
MTK_EINT_FUNCTION(0, 67),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO67"),
MTK_FUNCTION(1, "DSI_TE"),
MTK_FUNCTION(3, "I2S_8CH_MCK"),
MTK_FUNCTION(7, "DBG_MON_B[14]")
),
MTK_PIN(
- PINCTRL_PIN(68, "MSDC2_CMD"),
- NULL, "mt8167",
+ 68, "MSDC2_CMD",
MTK_EINT_FUNCTION(0, 68),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO68"),
MTK_FUNCTION(1, "MSDC2_CMD"),
MTK_FUNCTION(2, "I2S_8CH_DO4"),
@@ -756,9 +752,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[15]")
),
MTK_PIN(
- PINCTRL_PIN(69, "MSDC2_CLK"),
- NULL, "mt8167",
+ 69, "MSDC2_CLK",
MTK_EINT_FUNCTION(0, 69),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO69"),
MTK_FUNCTION(1, "MSDC2_CLK"),
MTK_FUNCTION(2, "I2S_8CH_DO3"),
@@ -769,9 +765,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[16]")
),
MTK_PIN(
- PINCTRL_PIN(70, "MSDC2_DAT0"),
- NULL, "mt8167",
+ 70, "MSDC2_DAT0",
MTK_EINT_FUNCTION(0, 70),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO70"),
MTK_FUNCTION(1, "MSDC2_DAT0"),
MTK_FUNCTION(2, "I2S_8CH_DO2"),
@@ -781,9 +777,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[17]")
),
MTK_PIN(
- PINCTRL_PIN(71, "MSDC2_DAT1"),
- NULL, "mt8167",
+ 71, "MSDC2_DAT1",
MTK_EINT_FUNCTION(0, 71),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO71"),
MTK_FUNCTION(1, "MSDC2_DAT1"),
MTK_FUNCTION(2, "I2S_8CH_DO1"),
@@ -794,9 +790,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[18]")
),
MTK_PIN(
- PINCTRL_PIN(72, "MSDC2_DAT2"),
- NULL, "mt8167",
+ 72, "MSDC2_DAT2",
MTK_EINT_FUNCTION(0, 72),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO72"),
MTK_FUNCTION(1, "MSDC2_DAT2"),
MTK_FUNCTION(2, "I2S_8CH_LRCK"),
@@ -807,9 +803,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[19]")
),
MTK_PIN(
- PINCTRL_PIN(73, "MSDC2_DAT3"),
- NULL, "mt8167",
+ 73, "MSDC2_DAT3",
MTK_EINT_FUNCTION(0, 73),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO73"),
MTK_FUNCTION(1, "MSDC2_DAT3"),
MTK_FUNCTION(2, "I2S_8CH_BCK"),
@@ -820,203 +816,203 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[20]")
),
MTK_PIN(
- PINCTRL_PIN(74, "TDN3"),
- NULL, "mt8167",
+ 74, "TDN3",
MTK_EINT_FUNCTION(0, 74),
- MTK_FUNCTION(0, "GPI74"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO74"),
MTK_FUNCTION(1, "TDN3")
),
MTK_PIN(
- PINCTRL_PIN(75, "TDP3"),
- NULL, "mt8167",
+ 75, "TDP3",
MTK_EINT_FUNCTION(0, 75),
- MTK_FUNCTION(0, "GPI75"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO75"),
MTK_FUNCTION(1, "TDP3")
),
MTK_PIN(
- PINCTRL_PIN(76, "TDN2"),
- NULL, "mt8167",
+ 76, "TDN2",
MTK_EINT_FUNCTION(0, 76),
- MTK_FUNCTION(0, "GPI76"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO76"),
MTK_FUNCTION(1, "TDN2")
),
MTK_PIN(
- PINCTRL_PIN(77, "TDP2"),
- NULL, "mt8167",
+ 77, "TDP2",
MTK_EINT_FUNCTION(0, 77),
- MTK_FUNCTION(0, "GPI77"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO77"),
MTK_FUNCTION(1, "TDP2")
),
MTK_PIN(
- PINCTRL_PIN(78, "TCN"),
- NULL, "mt8167",
+ 78, "TCN",
MTK_EINT_FUNCTION(0, 78),
- MTK_FUNCTION(0, "GPI78"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO78"),
MTK_FUNCTION(1, "TCN")
),
MTK_PIN(
- PINCTRL_PIN(79, "TCP"),
- NULL, "mt8167",
+ 79, "TCP",
MTK_EINT_FUNCTION(0, 79),
- MTK_FUNCTION(0, "GPI79"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO79"),
MTK_FUNCTION(1, "TCP")
),
MTK_PIN(
- PINCTRL_PIN(80, "TDN1"),
- NULL, "mt8167",
+ 80, "TDN1",
MTK_EINT_FUNCTION(0, 80),
- MTK_FUNCTION(0, "GPI80"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO80"),
MTK_FUNCTION(1, "TDN1")
),
MTK_PIN(
- PINCTRL_PIN(81, "TDP1"),
- NULL, "mt8167",
+ 81, "TDP1",
MTK_EINT_FUNCTION(0, 81),
- MTK_FUNCTION(0, "GPI81"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO81"),
MTK_FUNCTION(1, "TDP1")
),
MTK_PIN(
- PINCTRL_PIN(82, "TDN0"),
- NULL, "mt8167",
+ 82, "TDN0",
MTK_EINT_FUNCTION(0, 82),
- MTK_FUNCTION(0, "GPI82"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO82"),
MTK_FUNCTION(1, "TDN0")
),
MTK_PIN(
- PINCTRL_PIN(83, "TDP0"),
- NULL, "mt8167",
+ 83, "TDP0",
MTK_EINT_FUNCTION(0, 83),
- MTK_FUNCTION(0, "GPI83"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO83"),
MTK_FUNCTION(1, "TDP0")
),
MTK_PIN(
- PINCTRL_PIN(84, "RDN0"),
- NULL, "mt8167",
+ 84, "RDN0",
MTK_EINT_FUNCTION(0, 84),
- MTK_FUNCTION(0, "GPI84"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO84"),
MTK_FUNCTION(1, "RDN0")
),
MTK_PIN(
- PINCTRL_PIN(85, "RDP0"),
- NULL, "mt8167",
+ 85, "RDP0",
MTK_EINT_FUNCTION(0, 85),
- MTK_FUNCTION(0, "GPI85"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO85"),
MTK_FUNCTION(1, "RDP0")
),
MTK_PIN(
- PINCTRL_PIN(86, "RDN1"),
- NULL, "mt8167",
+ 86, "RDN1",
MTK_EINT_FUNCTION(0, 86),
- MTK_FUNCTION(0, "GPI86"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO86"),
MTK_FUNCTION(1, "RDN1")
),
MTK_PIN(
- PINCTRL_PIN(87, "RDP1"),
- NULL, "mt8167",
+ 87, "RDP1",
MTK_EINT_FUNCTION(0, 87),
- MTK_FUNCTION(0, "GPI87"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO87"),
MTK_FUNCTION(1, "RDP1")
),
MTK_PIN(
- PINCTRL_PIN(88, "RCN"),
- NULL, "mt8167",
+ 88, "RCN",
MTK_EINT_FUNCTION(0, 88),
- MTK_FUNCTION(0, "GPI88"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO88"),
MTK_FUNCTION(1, "RCN")
),
MTK_PIN(
- PINCTRL_PIN(89, "RCP"),
- NULL, "mt8167",
+ 89, "RCP",
MTK_EINT_FUNCTION(0, 89),
- MTK_FUNCTION(0, "GPI89"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO89"),
MTK_FUNCTION(1, "RCP")
),
MTK_PIN(
- PINCTRL_PIN(90, "RDN2"),
- NULL, "mt8167",
+ 90, "RDN2",
MTK_EINT_FUNCTION(0, 90),
- MTK_FUNCTION(0, "GPI90"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO90"),
MTK_FUNCTION(1, "RDN2"),
MTK_FUNCTION(2, "CMDAT8")
),
MTK_PIN(
- PINCTRL_PIN(91, "RDP2"),
- NULL, "mt8167",
+ 91, "RDP2",
MTK_EINT_FUNCTION(0, 91),
- MTK_FUNCTION(0, "GPI91"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO91"),
MTK_FUNCTION(1, "RDP2"),
MTK_FUNCTION(2, "CMDAT9")
),
MTK_PIN(
- PINCTRL_PIN(92, "RDN3"),
- NULL, "mt8167",
+ 92, "RDN3",
MTK_EINT_FUNCTION(0, 92),
- MTK_FUNCTION(0, "GPI92"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO92"),
MTK_FUNCTION(1, "RDN3"),
MTK_FUNCTION(2, "CMDAT4")
),
MTK_PIN(
- PINCTRL_PIN(93, "RDP3"),
- NULL, "mt8167",
+ 93, "RDP3",
MTK_EINT_FUNCTION(0, 93),
- MTK_FUNCTION(0, "GPI93"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO93"),
MTK_FUNCTION(1, "RDP3"),
MTK_FUNCTION(2, "CMDAT5")
),
MTK_PIN(
- PINCTRL_PIN(94, "RCN_A"),
- NULL, "mt8167",
+ 94, "RCN_A",
MTK_EINT_FUNCTION(0, 94),
- MTK_FUNCTION(0, "GPI94"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO94"),
MTK_FUNCTION(1, "RCN_A"),
MTK_FUNCTION(2, "CMDAT6")
),
MTK_PIN(
- PINCTRL_PIN(95, "RCP_A"),
- NULL, "mt8167",
+ 95, "RCP_A",
MTK_EINT_FUNCTION(0, 95),
- MTK_FUNCTION(0, "GPI95"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO95"),
MTK_FUNCTION(1, "RCP_A"),
MTK_FUNCTION(2, "CMDAT7")
),
MTK_PIN(
- PINCTRL_PIN(96, "RDN1_A"),
- NULL, "mt8167",
+ 96, "RDN1_A",
MTK_EINT_FUNCTION(0, 96),
- MTK_FUNCTION(0, "GPI96"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO96"),
MTK_FUNCTION(1, "RDN1_A"),
MTK_FUNCTION(2, "CMDAT2"),
MTK_FUNCTION(3, "CMCSD2")
),
MTK_PIN(
- PINCTRL_PIN(97, "RDP1_A"),
- NULL, "mt8167",
+ 97, "RDP1_A",
MTK_EINT_FUNCTION(0, 97),
- MTK_FUNCTION(0, "GPI97"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO97"),
MTK_FUNCTION(1, "RDP1_A"),
MTK_FUNCTION(2, "CMDAT3"),
MTK_FUNCTION(3, "CMCSD3")
),
MTK_PIN(
- PINCTRL_PIN(98, "RDN0_A"),
- NULL, "mt8167",
+ 98, "RDN0_A",
MTK_EINT_FUNCTION(0, 98),
- MTK_FUNCTION(0, "GPI98"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO98"),
MTK_FUNCTION(1, "RDN0_A"),
MTK_FUNCTION(2, "CMHSYNC")
),
MTK_PIN(
- PINCTRL_PIN(99, "RDP0_A"),
- NULL, "mt8167",
+ 99, "RDP0_A",
MTK_EINT_FUNCTION(0, 99),
- MTK_FUNCTION(0, "GPI99"),
+ DRV_GRP0, // N/A
+ MTK_FUNCTION(0, "GPIO99"),
MTK_FUNCTION(1, "RDP0_A"),
MTK_FUNCTION(2, "CMVSYNC")
),
MTK_PIN(
- PINCTRL_PIN(100, "CMDAT0"),
- NULL, "mt8167",
+ 100, "CMDAT0",
MTK_EINT_FUNCTION(0, 100),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO100"),
MTK_FUNCTION(1, "CMDAT0"),
MTK_FUNCTION(2, "CMCSD0"),
@@ -1025,9 +1021,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[21]")
),
MTK_PIN(
- PINCTRL_PIN(101, "CMDAT1"),
- NULL, "mt8167",
+ 101, "CMDAT1",
MTK_EINT_FUNCTION(0, 101),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO101"),
MTK_FUNCTION(1, "CMDAT1"),
MTK_FUNCTION(2, "CMCSD1"),
@@ -1037,9 +1033,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[22]")
),
MTK_PIN(
- PINCTRL_PIN(102, "CMMCLK"),
- NULL, "mt8167",
+ 102, "CMMCLK",
MTK_EINT_FUNCTION(0, 102),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO102"),
MTK_FUNCTION(1, "CMMCLK"),
MTK_FUNCTION(3, "ANT_SEL4"),
@@ -1047,29 +1043,29 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[23]")
),
MTK_PIN(
- PINCTRL_PIN(103, "CMPCLK"),
- NULL, "mt8167",
+ 103, "CMPCLK",
MTK_EINT_FUNCTION(0, 103),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO103"),
MTK_FUNCTION(1, "CMPCLK"),
MTK_FUNCTION(2, "CMCSK"),
MTK_FUNCTION(3, "ANT_SEL5"),
- MTK_FUNCTION(5, " TDM_RX_DI"),
+ MTK_FUNCTION(5, "TDM_RX_DI"),
MTK_FUNCTION(7, "DBG_MON_B[24]")
),
MTK_PIN(
- PINCTRL_PIN(104, "MSDC1_CMD"),
- NULL, "mt8167",
+ 104, "MSDC1_CMD",
MTK_EINT_FUNCTION(0, 104),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO104"),
MTK_FUNCTION(1, "MSDC1_CMD"),
MTK_FUNCTION(4, "SQICS"),
MTK_FUNCTION(7, "DBG_MON_B[25]")
),
MTK_PIN(
- PINCTRL_PIN(105, "MSDC1_CLK"),
- NULL, "mt8167",
+ 105, "MSDC1_CLK",
MTK_EINT_FUNCTION(0, 105),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO105"),
MTK_FUNCTION(1, "MSDC1_CLK"),
MTK_FUNCTION(2, "UDI_NTRST_XI"),
@@ -1079,9 +1075,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[26]")
),
MTK_PIN(
- PINCTRL_PIN(106, "MSDC1_DAT0"),
- NULL, "mt8167",
+ 106, "MSDC1_DAT0",
MTK_EINT_FUNCTION(0, 106),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO106"),
MTK_FUNCTION(1, "MSDC1_DAT0"),
MTK_FUNCTION(2, "UDI_TMS_XI"),
@@ -1091,9 +1087,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[27]")
),
MTK_PIN(
- PINCTRL_PIN(107, "MSDC1_DAT1"),
- NULL, "mt8167",
+ 107, "MSDC1_DAT1",
MTK_EINT_FUNCTION(0, 107),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO107"),
MTK_FUNCTION(1, "MSDC1_DAT1"),
MTK_FUNCTION(2, "UDI_TCK_XI"),
@@ -1103,9 +1099,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[28]")
),
MTK_PIN(
- PINCTRL_PIN(108, "MSDC1_DAT2"),
- NULL, "mt8167",
+ 108, "MSDC1_DAT2",
MTK_EINT_FUNCTION(0, 108),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO108"),
MTK_FUNCTION(1, "MSDC1_DAT2"),
MTK_FUNCTION(2, "UDI_TDI_XI"),
@@ -1115,9 +1111,9 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[29]")
),
MTK_PIN(
- PINCTRL_PIN(109, "MSDC1_DAT3"),
- NULL, "mt8167",
+ 109, "MSDC1_DAT3",
MTK_EINT_FUNCTION(0, 109),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO109"),
MTK_FUNCTION(1, "MSDC1_DAT3"),
MTK_FUNCTION(2, "UDI_TDO"),
@@ -1127,119 +1123,119 @@ static const struct mtk_desc_pin mtk_pins_mt8167[] = {
MTK_FUNCTION(7, "DBG_MON_B[30]")
),
MTK_PIN(
- PINCTRL_PIN(110, "MSDC0_DAT7"),
- NULL, "mt8167",
+ 110, "MSDC0_DAT7",
MTK_EINT_FUNCTION(0, 110),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO110"),
MTK_FUNCTION(1, "MSDC0_DAT7"),
MTK_FUNCTION(4, "NLD7")
),
MTK_PIN(
- PINCTRL_PIN(111, "MSDC0_DAT6"),
- NULL, "mt8167",
+ 111, "MSDC0_DAT6",
MTK_EINT_FUNCTION(0, 111),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO111"),
MTK_FUNCTION(1, "MSDC0_DAT6"),
MTK_FUNCTION(4, "NLD6")
),
MTK_PIN(
- PINCTRL_PIN(112, "MSDC0_DAT5"),
- NULL, "mt8167",
+ 112, "MSDC0_DAT5",
MTK_EINT_FUNCTION(0, 112),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO112"),
MTK_FUNCTION(1, "MSDC0_DAT5"),
MTK_FUNCTION(4, "NLD4")
),
MTK_PIN(
- PINCTRL_PIN(113, "MSDC0_DAT4"),
- NULL, "mt8167",
+ 113, "MSDC0_DAT4",
MTK_EINT_FUNCTION(0, 113),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO113"),
MTK_FUNCTION(1, "MSDC0_DAT4"),
MTK_FUNCTION(4, "NLD3")
),
MTK_PIN(
- PINCTRL_PIN(114, "MSDC0_RSTB"),
- NULL, "mt8167",
+ 114, "MSDC0_RSTB",
MTK_EINT_FUNCTION(0, 114),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO114"),
MTK_FUNCTION(1, "MSDC0_RSTB"),
MTK_FUNCTION(4, "NLD0")
),
MTK_PIN(
- PINCTRL_PIN(115, "MSDC0_CMD"),
- NULL, "mt8167",
+ 115, "MSDC0_CMD",
MTK_EINT_FUNCTION(0, 115),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO115"),
MTK_FUNCTION(1, "MSDC0_CMD"),
MTK_FUNCTION(4, "NALE")
),
MTK_PIN(
- PINCTRL_PIN(116, "MSDC0_CLK"),
- NULL, "mt8167",
+ 116, "MSDC0_CLK",
MTK_EINT_FUNCTION(0, 116),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO116"),
MTK_FUNCTION(1, "MSDC0_CLK"),
MTK_FUNCTION(4, "NWEB")
),
MTK_PIN(
- PINCTRL_PIN(117, "MSDC0_DAT3"),
- NULL, "mt8167",
+ 117, "MSDC0_DAT3",
MTK_EINT_FUNCTION(0, 117),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO117"),
MTK_FUNCTION(1, "MSDC0_DAT3"),
MTK_FUNCTION(4, "NLD1")
),
MTK_PIN(
- PINCTRL_PIN(118, "MSDC0_DAT2"),
- NULL, "mt8167",
+ 118, "MSDC0_DAT2",
MTK_EINT_FUNCTION(0, 118),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO118"),
MTK_FUNCTION(1, "MSDC0_DAT2"),
MTK_FUNCTION(4, "NLD5")
),
MTK_PIN(
- PINCTRL_PIN(119, "MSDC0_DAT1"),
- NULL, "mt8167",
+ 119, "MSDC0_DAT1",
MTK_EINT_FUNCTION(0, 119),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO119"),
MTK_FUNCTION(1, "MSDC0_DAT1"),
MTK_FUNCTION(4, "NLD8")
),
MTK_PIN(
- PINCTRL_PIN(120, "MSDC0_DAT0"),
- NULL, "mt8167",
+ 120, "MSDC0_DAT0",
MTK_EINT_FUNCTION(0, 120),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO120"),
MTK_FUNCTION(1, "MSDC0_DAT0"),
MTK_FUNCTION(4, "WATCHDOG"),
MTK_FUNCTION(5, "NLD2")
),
MTK_PIN(
- PINCTRL_PIN(121, "CEC"),
- NULL, "mt8167",
+ 121, "CEC",
MTK_EINT_FUNCTION(0, 121),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO121"),
MTK_FUNCTION(1, "CEC")
),
MTK_PIN(
- PINCTRL_PIN(122, "HTPLG"),
- NULL, "mt8167",
+ 122, "HTPLG",
MTK_EINT_FUNCTION(0, 122),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO122"),
MTK_FUNCTION(1, "HTPLG")
),
MTK_PIN(
- PINCTRL_PIN(123, "HDMISCK"),
- NULL, "mt8167",
+ 123, "HDMISCK",
MTK_EINT_FUNCTION(0, 123),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO123"),
MTK_FUNCTION(1, "HDMISCK")
),
MTK_PIN(
- PINCTRL_PIN(124, "HDMISD"),
- NULL, "mt8167",
+ 124, "HDMISD",
MTK_EINT_FUNCTION(0, 124),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO124"),
MTK_FUNCTION(1, "HDMISD")
),
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h
index f7a4c6e4a026..fc4f8401b3c6 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h
@@ -1,18 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2019 MediaTek Inc.
- */
#ifndef __PINCTRL_MTK_MT8516_H
#define __PINCTRL_MTK_MT8516_H
-#include <linux/pinctrl/pinctrl.h>
-#include "pinctrl-mtk-common.h"
+#include "pinctrl-paris.h"
-static const struct mtk_desc_pin mtk_pins_mt8516[] = {
+static const struct mtk_pin_desc mtk_pins_mt8516[] = {
MTK_PIN(
- PINCTRL_PIN(0, "EINT0"),
- NULL, "mt8516",
+ 0, "EINT0",
MTK_EINT_FUNCTION(0, 0),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO0"),
MTK_FUNCTION(1, "PWM_B"),
MTK_FUNCTION(3, "I2S2_BCK"),
@@ -21,9 +17,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[6]")
),
MTK_PIN(
- PINCTRL_PIN(1, "EINT1"),
- NULL, "mt8516",
+ 1, "EINT1",
MTK_EINT_FUNCTION(0, 1),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO1"),
MTK_FUNCTION(1, "PWM_C"),
MTK_FUNCTION(3, "I2S2_DI"),
@@ -33,9 +29,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[7]")
),
MTK_PIN(
- PINCTRL_PIN(2, "EINT2"),
- NULL, "mt8516",
+ 2, "EINT2",
MTK_EINT_FUNCTION(0, 2),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO2"),
MTK_FUNCTION(1, "CLKM0"),
MTK_FUNCTION(3, "I2S2_LRCK"),
@@ -45,9 +41,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[8]")
),
MTK_PIN(
- PINCTRL_PIN(3, "EINT3"),
- NULL, "mt8516",
+ 3, "EINT3",
MTK_EINT_FUNCTION(0, 3),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO3"),
MTK_FUNCTION(1, "CLKM1"),
MTK_FUNCTION(3, "SPI_MI"),
@@ -57,9 +53,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[9]")
),
MTK_PIN(
- PINCTRL_PIN(4, "EINT4"),
- NULL, "mt8516",
+ 4, "EINT4",
MTK_EINT_FUNCTION(0, 4),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO4"),
MTK_FUNCTION(1, "CLKM2"),
MTK_FUNCTION(3, "SPI_MO"),
@@ -69,9 +65,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[10]")
),
MTK_PIN(
- PINCTRL_PIN(5, "EINT5"),
- NULL, "mt8516",
+ 5, "EINT5",
MTK_EINT_FUNCTION(0, 5),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO5"),
MTK_FUNCTION(1, "UCTS2"),
MTK_FUNCTION(3, "SPI_CSB"),
@@ -81,9 +77,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[11]")
),
MTK_PIN(
- PINCTRL_PIN(6, "EINT6"),
- NULL, "mt8516",
+ 6, "EINT6",
MTK_EINT_FUNCTION(0, 6),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO6"),
MTK_FUNCTION(1, "URTS2"),
MTK_FUNCTION(3, "SPI_CLK"),
@@ -92,9 +88,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[12]")
),
MTK_PIN(
- PINCTRL_PIN(7, "EINT7"),
- NULL, "mt8516",
+ 7, "EINT7",
MTK_EINT_FUNCTION(0, 7),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO7"),
MTK_FUNCTION(1, "SQIRST"),
MTK_FUNCTION(3, "SDA1_0"),
@@ -104,9 +100,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[13]")
),
MTK_PIN(
- PINCTRL_PIN(8, "EINT8"),
- NULL, "mt8516",
+ 8, "EINT8",
MTK_EINT_FUNCTION(0, 8),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO8"),
MTK_FUNCTION(1, "SQICK"),
MTK_FUNCTION(2, "CLKM3"),
@@ -116,9 +112,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[14]")
),
MTK_PIN(
- PINCTRL_PIN(9, "EINT9"),
- NULL, "mt8516",
+ 9, "EINT9",
MTK_EINT_FUNCTION(0, 9),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO9"),
MTK_FUNCTION(1, "CLKM4"),
MTK_FUNCTION(2, "SDA2_0"),
@@ -128,9 +124,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[15]")
),
MTK_PIN(
- PINCTRL_PIN(10, "EINT10"),
- NULL, "mt8516",
+ 10, "EINT10",
MTK_EINT_FUNCTION(0, 10),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO10"),
MTK_FUNCTION(1, "CLKM5"),
MTK_FUNCTION(2, "SCL2_0"),
@@ -140,9 +136,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[16]")
),
MTK_PIN(
- PINCTRL_PIN(11, "EINT11"),
- NULL, "mt8516",
+ 11, "EINT11",
MTK_EINT_FUNCTION(0, 11),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO11"),
MTK_FUNCTION(1, "CLKM4"),
MTK_FUNCTION(2, "PWM_C"),
@@ -152,9 +148,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[17]")
),
MTK_PIN(
- PINCTRL_PIN(12, "EINT12"),
- NULL, "mt8516",
+ 12, "EINT12",
MTK_EINT_FUNCTION(0, 12),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO12"),
MTK_FUNCTION(1, "CLKM5"),
MTK_FUNCTION(2, "PWM_A"),
@@ -164,9 +160,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[18]")
),
MTK_PIN(
- PINCTRL_PIN(13, "EINT13"),
- NULL, "mt8516",
+ 13, "EINT13",
MTK_EINT_FUNCTION(0, 13),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO13"),
MTK_FUNCTION(3, "TSF_IN"),
MTK_FUNCTION(4, "ANT_SEL5"),
@@ -174,9 +170,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[19]")
),
MTK_PIN(
- PINCTRL_PIN(14, "EINT14"),
- NULL, "mt8516",
+ 14, "EINT14",
MTK_EINT_FUNCTION(0, 14),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO14"),
MTK_FUNCTION(2, "I2S_8CH_DO1"),
MTK_FUNCTION(3, "TDM_RX_MCK"),
@@ -186,9 +182,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[8]")
),
MTK_PIN(
- PINCTRL_PIN(15, "EINT15"),
- NULL, "mt8516",
+ 15, "EINT15",
MTK_EINT_FUNCTION(0, 15),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO15"),
MTK_FUNCTION(2, "I2S_8CH_LRCK"),
MTK_FUNCTION(3, "TDM_RX_BCK"),
@@ -198,9 +194,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[9]")
),
MTK_PIN(
- PINCTRL_PIN(16, "EINT16"),
- NULL, "mt8516",
+ 16, "EINT16",
MTK_EINT_FUNCTION(0, 16),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO16"),
MTK_FUNCTION(2, "I2S_8CH_BCK"),
MTK_FUNCTION(3, "TDM_RX_LRCK"),
@@ -210,9 +206,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[10]")
),
MTK_PIN(
- PINCTRL_PIN(17, "EINT17"),
- NULL, "mt8516",
+ 17, "EINT17",
MTK_EINT_FUNCTION(0, 17),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO17"),
MTK_FUNCTION(2, "I2S_8CH_MCK"),
MTK_FUNCTION(3, "TDM_RX_DI"),
@@ -222,9 +218,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[11]")
),
MTK_PIN(
- PINCTRL_PIN(18, "EINT18"),
- NULL, "mt8516",
+ 18, "EINT18",
MTK_EINT_FUNCTION(0, 18),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO18"),
MTK_FUNCTION(2, "USB_DRVVBUS"),
MTK_FUNCTION(3, "I2S3_LRCK"),
@@ -234,9 +230,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[20]")
),
MTK_PIN(
- PINCTRL_PIN(19, "EINT19"),
- NULL, "mt8516",
+ 19, "EINT19",
MTK_EINT_FUNCTION(0, 19),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO19"),
MTK_FUNCTION(1, "UCTS1"),
MTK_FUNCTION(2, "IDDIG"),
@@ -247,9 +243,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[21]")
),
MTK_PIN(
- PINCTRL_PIN(20, "EINT20"),
- NULL, "mt8516",
+ 20, "EINT20",
MTK_EINT_FUNCTION(0, 20),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO20"),
MTK_FUNCTION(1, "URTS1"),
MTK_FUNCTION(3, "I2S3_DO"),
@@ -259,9 +255,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[22]")
),
MTK_PIN(
- PINCTRL_PIN(21, "EINT21"),
- NULL, "mt8516",
+ 21, "EINT21",
MTK_EINT_FUNCTION(0, 21),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO21"),
MTK_FUNCTION(1, "NRNB"),
MTK_FUNCTION(2, "ANT_SEL0"),
@@ -269,9 +265,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[31]")
),
MTK_PIN(
- PINCTRL_PIN(22, "EINT22"),
- NULL, "mt8516",
+ 22, "EINT22",
MTK_EINT_FUNCTION(0, 22),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO22"),
MTK_FUNCTION(2, "I2S_8CH_DO2"),
MTK_FUNCTION(3, "TSF_IN"),
@@ -281,9 +277,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[12]")
),
MTK_PIN(
- PINCTRL_PIN(23, "EINT23"),
- NULL, "mt8516",
+ 23, "EINT23",
MTK_EINT_FUNCTION(0, 23),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO23"),
MTK_FUNCTION(2, "I2S_8CH_DO3"),
MTK_FUNCTION(3, "CLKM0"),
@@ -293,9 +289,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[13]")
),
MTK_PIN(
- PINCTRL_PIN(24, "EINT24"),
- NULL, "mt8516",
+ 24, "EINT24",
MTK_EINT_FUNCTION(0, 24),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO24"),
MTK_FUNCTION(3, "ANT_SEL1"),
MTK_FUNCTION(4, "UCTS2"),
@@ -304,9 +300,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[0]")
),
MTK_PIN(
- PINCTRL_PIN(25, "EINT25"),
- NULL, "mt8516",
+ 25, "EINT25",
MTK_EINT_FUNCTION(0, 25),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO25"),
MTK_FUNCTION(3, "ANT_SEL0"),
MTK_FUNCTION(4, "URTS2"),
@@ -315,25 +311,25 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[1]")
),
MTK_PIN(
- PINCTRL_PIN(26, "PWRAP_SPI0_MI"),
- NULL, "mt8516",
+ 26, "PWRAP_SPI0_MI",
MTK_EINT_FUNCTION(0, 26),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO26"),
MTK_FUNCTION(1, "PWRAP_SPI0_MO"),
MTK_FUNCTION(2, "PWRAP_SPI0_MI")
),
MTK_PIN(
- PINCTRL_PIN(27, "PWRAP_SPI0_MO"),
- NULL, "mt8516",
+ 27, "PWRAP_SPI0_MO",
MTK_EINT_FUNCTION(0, 27),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO27"),
MTK_FUNCTION(1, "PWRAP_SPI0_MI"),
MTK_FUNCTION(2, "PWRAP_SPI0_MO")
),
MTK_PIN(
- PINCTRL_PIN(28, "PWRAP_INT"),
- NULL, "mt8516",
+ 28, "PWRAP_INT",
MTK_EINT_FUNCTION(0, 28),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO28"),
MTK_FUNCTION(1, "I2S0_MCK"),
MTK_FUNCTION(4, "I2S_8CH_MCK"),
@@ -341,44 +337,44 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(6, "I2S3_MCK")
),
MTK_PIN(
- PINCTRL_PIN(29, "PWRAP_SPI0_CK"),
- NULL, "mt8516",
+ 29, "PWRAP_SPI0_CK",
MTK_EINT_FUNCTION(0, 29),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO29"),
MTK_FUNCTION(1, "PWRAP_SPI0_CK")
),
MTK_PIN(
- PINCTRL_PIN(30, "PWRAP_SPI0_CSN"),
- NULL, "mt8516",
+ 30, "PWRAP_SPI0_CSN",
MTK_EINT_FUNCTION(0, 30),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO30"),
MTK_FUNCTION(1, "PWRAP_SPI0_CSN")
),
MTK_PIN(
- PINCTRL_PIN(31, "RTC32K_CK"),
- NULL, "mt8516",
+ 31, "RTC32K_CK",
MTK_EINT_FUNCTION(0, 31),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO31"),
MTK_FUNCTION(1, "RTC32K_CK")
),
MTK_PIN(
- PINCTRL_PIN(32, "WATCHDOG"),
- NULL, "mt8516",
+ 32, "WATCHDOG",
MTK_EINT_FUNCTION(0, 32),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO32"),
MTK_FUNCTION(1, "WATCHDOG")
),
MTK_PIN(
- PINCTRL_PIN(33, "SRCLKENA"),
- NULL, "mt8516",
+ 33, "SRCLKENA",
MTK_EINT_FUNCTION(0, 33),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO33"),
MTK_FUNCTION(1, "SRCLKENA0")
),
MTK_PIN(
- PINCTRL_PIN(34, "URXD2"),
- NULL, "mt8516",
+ 34, "URXD2",
MTK_EINT_FUNCTION(0, 34),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO34"),
MTK_FUNCTION(1, "URXD2"),
MTK_FUNCTION(3, "UTXD2"),
@@ -387,9 +383,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[0]")
),
MTK_PIN(
- PINCTRL_PIN(35, "UTXD2"),
- NULL, "mt8516",
+ 35, "UTXD2",
MTK_EINT_FUNCTION(0, 35),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO35"),
MTK_FUNCTION(1, "UTXD2"),
MTK_FUNCTION(3, "URXD2"),
@@ -398,9 +394,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[1]")
),
MTK_PIN(
- PINCTRL_PIN(36, "MRG_CLK"),
- NULL, "mt8516",
+ 36, "MRG_CLK",
MTK_EINT_FUNCTION(0, 36),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO36"),
MTK_FUNCTION(1, "MRG_CLK"),
MTK_FUNCTION(3, "I2S0_BCK"),
@@ -410,9 +406,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[2]")
),
MTK_PIN(
- PINCTRL_PIN(37, "MRG_SYNC"),
- NULL, "mt8516",
+ 37, "MRG_SYNC",
MTK_EINT_FUNCTION(0, 37),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO37"),
MTK_FUNCTION(1, "MRG_SYNC"),
MTK_FUNCTION(3, "I2S0_LRCK"),
@@ -422,9 +418,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[3]")
),
MTK_PIN(
- PINCTRL_PIN(38, "MRG_DI"),
- NULL, "mt8516",
+ 38, "MRG_DI",
MTK_EINT_FUNCTION(0, 38),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO38"),
MTK_FUNCTION(1, "MRG_DI"),
MTK_FUNCTION(3, "I2S0_DI"),
@@ -434,9 +430,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[4]")
),
MTK_PIN(
- PINCTRL_PIN(39, "MRG_DO"),
- NULL, "mt8516",
+ 39, "MRG_DO",
MTK_EINT_FUNCTION(0, 39),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO39"),
MTK_FUNCTION(1, "MRG_DO"),
MTK_FUNCTION(3, "I2S0_MCK"),
@@ -446,17 +442,17 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[5]")
),
MTK_PIN(
- PINCTRL_PIN(40, "KPROW0"),
- NULL, "mt8516",
+ 40, "KPROW0",
MTK_EINT_FUNCTION(0, 40),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO40"),
MTK_FUNCTION(1, "KPROW0"),
MTK_FUNCTION(7, "DBG_MON_B[4]")
),
MTK_PIN(
- PINCTRL_PIN(41, "KPROW1"),
- NULL, "mt8516",
+ 41, "KPROW1",
MTK_EINT_FUNCTION(0, 41),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO41"),
MTK_FUNCTION(1, "KPROW1"),
MTK_FUNCTION(2, "IDDIG"),
@@ -464,17 +460,17 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[5]")
),
MTK_PIN(
- PINCTRL_PIN(42, "KPCOL0"),
- NULL, "mt8516",
+ 42, "KPCOL0",
MTK_EINT_FUNCTION(0, 42),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO42"),
MTK_FUNCTION(1, "KPCOL0"),
MTK_FUNCTION(7, "DBG_MON_B[6]")
),
MTK_PIN(
- PINCTRL_PIN(43, "KPCOL1"),
- NULL, "mt8516",
+ 43, "KPCOL1",
MTK_EINT_FUNCTION(0, 43),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO43"),
MTK_FUNCTION(1, "KPCOL1"),
MTK_FUNCTION(2, "USB_DRVVBUS"),
@@ -483,43 +479,43 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[7]")
),
MTK_PIN(
- PINCTRL_PIN(44, "JTMS"),
- NULL, "mt8516",
+ 44, "JTMS",
MTK_EINT_FUNCTION(0, 44),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO44"),
MTK_FUNCTION(1, "JTMS"),
MTK_FUNCTION(2, "CONN_MCU_TMS"),
MTK_FUNCTION(3, "CONN_MCU_AICE_JMSC")
),
MTK_PIN(
- PINCTRL_PIN(45, "JTCK"),
- NULL, "mt8516",
+ 45, "JTCK",
MTK_EINT_FUNCTION(0, 45),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO45"),
MTK_FUNCTION(1, "JTCK"),
MTK_FUNCTION(2, "CONN_MCU_TCK"),
MTK_FUNCTION(3, "CONN_MCU_AICE_JCKC")
),
MTK_PIN(
- PINCTRL_PIN(46, "JTDI"),
- NULL, "mt8516",
+ 46, "JTDI",
MTK_EINT_FUNCTION(0, 46),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO46"),
MTK_FUNCTION(1, "JTDI"),
MTK_FUNCTION(2, "CONN_MCU_TDI")
),
MTK_PIN(
- PINCTRL_PIN(47, "JTDO"),
- NULL, "mt8516",
+ 47, "JTDO",
MTK_EINT_FUNCTION(0, 47),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO47"),
MTK_FUNCTION(1, "JTDO"),
MTK_FUNCTION(2, "CONN_MCU_TDO")
),
MTK_PIN(
- PINCTRL_PIN(48, "SPI_CS"),
- NULL, "mt8516",
+ 48, "SPI_CS",
MTK_EINT_FUNCTION(0, 48),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO48"),
MTK_FUNCTION(1, "SPI_CSB"),
MTK_FUNCTION(3, "I2S0_DI"),
@@ -527,9 +523,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[23]")
),
MTK_PIN(
- PINCTRL_PIN(49, "SPI_CK"),
- NULL, "mt8516",
+ 49, "SPI_CK",
MTK_EINT_FUNCTION(0, 49),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO49"),
MTK_FUNCTION(1, "SPI_CLK"),
MTK_FUNCTION(3, "I2S0_LRCK"),
@@ -537,9 +533,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[24]")
),
MTK_PIN(
- PINCTRL_PIN(50, "SPI_MI"),
- NULL, "mt8516",
+ 50, "SPI_MI",
MTK_EINT_FUNCTION(0, 50),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO50"),
MTK_FUNCTION(1, "SPI_MI"),
MTK_FUNCTION(2, "SPI_MO"),
@@ -548,9 +544,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[25]")
),
MTK_PIN(
- PINCTRL_PIN(51, "SPI_MO"),
- NULL, "mt8516",
+ 51, "SPI_MO",
MTK_EINT_FUNCTION(0, 51),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO51"),
MTK_FUNCTION(1, "SPI_MO"),
MTK_FUNCTION(2, "SPI_MI"),
@@ -559,31 +555,31 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[26]")
),
MTK_PIN(
- PINCTRL_PIN(52, "SDA1"),
- NULL, "mt8516",
+ 52, "SDA1",
MTK_EINT_FUNCTION(0, 52),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO52"),
MTK_FUNCTION(1, "SDA1_0")
),
MTK_PIN(
- PINCTRL_PIN(53, "SCL1"),
- NULL, "mt8516",
+ 53, "SCL1",
MTK_EINT_FUNCTION(0, 53),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO53"),
MTK_FUNCTION(1, "SCL1_0")
),
MTK_PIN(
- PINCTRL_PIN(54, "GPIO54"),
- NULL, "mt8516",
+ 54, "GPIO54",
MTK_EINT_FUNCTION(0, 54),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO54"),
MTK_FUNCTION(2, "PWM_B"),
MTK_FUNCTION(7, "DBG_MON_B[2]")
),
MTK_PIN(
- PINCTRL_PIN(55, "I2S_DATA_IN"),
- NULL, "mt8516",
+ 55, "I2S_DATA_IN",
MTK_EINT_FUNCTION(0, 55),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO55"),
MTK_FUNCTION(1, "I2S0_DI"),
MTK_FUNCTION(2, "UCTS0"),
@@ -594,9 +590,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[28]")
),
MTK_PIN(
- PINCTRL_PIN(56, "I2S_LRCK"),
- NULL, "mt8516",
+ 56, "I2S_LRCK",
MTK_EINT_FUNCTION(0, 56),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO56"),
MTK_FUNCTION(1, "I2S0_LRCK"),
MTK_FUNCTION(3, "I2S3_LRCK"),
@@ -606,9 +602,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[29]")
),
MTK_PIN(
- PINCTRL_PIN(57, "I2S_BCK"),
- NULL, "mt8516",
+ 57, "I2S_BCK",
MTK_EINT_FUNCTION(0, 57),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO57"),
MTK_FUNCTION(1, "I2S0_BCK"),
MTK_FUNCTION(2, "URTS0"),
@@ -619,90 +615,90 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_A[30]")
),
MTK_PIN(
- PINCTRL_PIN(58, "SDA0"),
- NULL, "mt8516",
+ 58, "SDA0",
MTK_EINT_FUNCTION(0, 58),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO58"),
MTK_FUNCTION(1, "SDA0_0")
),
MTK_PIN(
- PINCTRL_PIN(59, "SCL0"),
- NULL, "mt8516",
+ 59, "SCL0",
MTK_EINT_FUNCTION(0, 59),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO59"),
MTK_FUNCTION(1, "SCL0_0")
),
MTK_PIN(
- PINCTRL_PIN(60, "SDA2"),
- NULL, "mt8516",
+ 60, "SDA2",
MTK_EINT_FUNCTION(0, 60),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO60"),
MTK_FUNCTION(1, "SDA2_0"),
MTK_FUNCTION(2, "PWM_B")
),
MTK_PIN(
- PINCTRL_PIN(61, "SCL2"),
- NULL, "mt8516",
+ 61, "SCL2",
MTK_EINT_FUNCTION(0, 61),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO61"),
MTK_FUNCTION(1, "SCL2_0"),
MTK_FUNCTION(2, "PWM_C")
),
MTK_PIN(
- PINCTRL_PIN(62, "URXD0"),
- NULL, "mt8516",
+ 62, "URXD0",
MTK_EINT_FUNCTION(0, 62),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO62"),
MTK_FUNCTION(1, "URXD0"),
MTK_FUNCTION(2, "UTXD0")
),
MTK_PIN(
- PINCTRL_PIN(63, "UTXD0"),
- NULL, "mt8516",
+ 63, "UTXD0",
MTK_EINT_FUNCTION(0, 63),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO63"),
MTK_FUNCTION(1, "UTXD0"),
MTK_FUNCTION(2, "URXD0")
),
MTK_PIN(
- PINCTRL_PIN(64, "URXD1"),
- NULL, "mt8516",
+ 64, "URXD1",
MTK_EINT_FUNCTION(0, 64),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO64"),
MTK_FUNCTION(1, "URXD1"),
MTK_FUNCTION(2, "UTXD1"),
MTK_FUNCTION(7, "DBG_MON_A[27]")
),
MTK_PIN(
- PINCTRL_PIN(65, "UTXD1"),
- NULL, "mt8516",
+ 65, "UTXD1",
MTK_EINT_FUNCTION(0, 65),
+ DRV_GRP0,
MTK_FUNCTION(0, "GPIO65"),
MTK_FUNCTION(1, "UTXD1"),
MTK_FUNCTION(2, "URXD1"),
MTK_FUNCTION(7, "DBG_MON_A[31]")
),
MTK_PIN(
- PINCTRL_PIN(66, "LCM_RST"),
- NULL, "mt8516",
+ 66, "LCM_RST",
MTK_EINT_FUNCTION(0, 66),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO66"),
MTK_FUNCTION(1, "LCM_RST"),
MTK_FUNCTION(3, "I2S0_MCK"),
MTK_FUNCTION(7, "DBG_MON_B[3]")
),
MTK_PIN(
- PINCTRL_PIN(67, "GPIO67"),
- NULL, "mt8516",
+ 67, "GPIO67",
MTK_EINT_FUNCTION(0, 67),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO67"),
MTK_FUNCTION(3, "I2S_8CH_MCK"),
MTK_FUNCTION(7, "DBG_MON_B[14]")
),
MTK_PIN(
- PINCTRL_PIN(68, "MSDC2_CMD"),
- NULL, "mt8516",
+ 68, "MSDC2_CMD",
MTK_EINT_FUNCTION(0, 68),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO68"),
MTK_FUNCTION(1, "MSDC2_CMD"),
MTK_FUNCTION(2, "I2S_8CH_DO4"),
@@ -712,9 +708,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[15]")
),
MTK_PIN(
- PINCTRL_PIN(69, "MSDC2_CLK"),
- NULL, "mt8516",
+ 69, "MSDC2_CLK",
MTK_EINT_FUNCTION(0, 69),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO69"),
MTK_FUNCTION(1, "MSDC2_CLK"),
MTK_FUNCTION(2, "I2S_8CH_DO3"),
@@ -724,9 +720,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[16]")
),
MTK_PIN(
- PINCTRL_PIN(70, "MSDC2_DAT0"),
- NULL, "mt8516",
+ 70, "MSDC2_DAT0",
MTK_EINT_FUNCTION(0, 70),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO70"),
MTK_FUNCTION(1, "MSDC2_DAT0"),
MTK_FUNCTION(2, "I2S_8CH_DO2"),
@@ -735,9 +731,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[17]")
),
MTK_PIN(
- PINCTRL_PIN(71, "MSDC2_DAT1"),
- NULL, "mt8516",
+ 71, "MSDC2_DAT1",
MTK_EINT_FUNCTION(0, 71),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO71"),
MTK_FUNCTION(1, "MSDC2_DAT1"),
MTK_FUNCTION(2, "I2S_8CH_DO1"),
@@ -748,9 +744,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[18]")
),
MTK_PIN(
- PINCTRL_PIN(72, "MSDC2_DAT2"),
- NULL, "mt8516",
+ 72, "MSDC2_DAT2",
MTK_EINT_FUNCTION(0, 72),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO72"),
MTK_FUNCTION(1, "MSDC2_DAT2"),
MTK_FUNCTION(2, "I2S_8CH_LRCK"),
@@ -760,9 +756,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[19]")
),
MTK_PIN(
- PINCTRL_PIN(73, "MSDC2_DAT3"),
- NULL, "mt8516",
+ 73, "MSDC2_DAT3",
MTK_EINT_FUNCTION(0, 73),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO73"),
MTK_FUNCTION(1, "MSDC2_DAT3"),
MTK_FUNCTION(2, "I2S_8CH_BCK"),
@@ -773,203 +769,203 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[20]")
),
MTK_PIN(
- PINCTRL_PIN(74, "TDN3"),
- NULL, "mt8516",
+ 74, "TDN3",
MTK_EINT_FUNCTION(0, 74),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO74"),
MTK_FUNCTION(1, "TDN3")
),
MTK_PIN(
- PINCTRL_PIN(75, "TDP3"),
- NULL, "mt8516",
+ 75, "TDP3",
MTK_EINT_FUNCTION(0, 75),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO75"),
MTK_FUNCTION(1, "TDP3")
),
MTK_PIN(
- PINCTRL_PIN(76, "TDN2"),
- NULL, "mt8516",
+ 76, "TDN2",
MTK_EINT_FUNCTION(0, 76),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO76"),
MTK_FUNCTION(1, "TDN2")
),
MTK_PIN(
- PINCTRL_PIN(77, "TDP2"),
- NULL, "mt8516",
+ 77, "TDP2",
MTK_EINT_FUNCTION(0, 77),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO77"),
MTK_FUNCTION(1, "TDP2")
),
MTK_PIN(
- PINCTRL_PIN(78, "TCN"),
- NULL, "mt8516",
+ 78, "TCN",
MTK_EINT_FUNCTION(0, 78),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO78"),
MTK_FUNCTION(1, "TCN")
),
MTK_PIN(
- PINCTRL_PIN(79, "TCP"),
- NULL, "mt8516",
+ 79, "TCP",
MTK_EINT_FUNCTION(0, 79),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO79"),
MTK_FUNCTION(1, "TCP")
),
MTK_PIN(
- PINCTRL_PIN(80, "TDN1"),
- NULL, "mt8516",
+ 80, "TDN1",
MTK_EINT_FUNCTION(0, 80),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO80"),
MTK_FUNCTION(1, "TDN1")
),
MTK_PIN(
- PINCTRL_PIN(81, "TDP1"),
- NULL, "mt8516",
+ 81, "TDP1",
MTK_EINT_FUNCTION(0, 81),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO81"),
MTK_FUNCTION(1, "TDP1")
),
MTK_PIN(
- PINCTRL_PIN(82, "TDN0"),
- NULL, "mt8516",
+ 82, "TDN0",
MTK_EINT_FUNCTION(0, 82),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO82"),
MTK_FUNCTION(1, "TDN0")
),
MTK_PIN(
- PINCTRL_PIN(83, "TDP0"),
- NULL, "mt8516",
+ 83, "TDP0",
MTK_EINT_FUNCTION(0, 83),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO83"),
MTK_FUNCTION(1, "TDP0")
),
MTK_PIN(
- PINCTRL_PIN(84, "RDN0"),
- NULL, "mt8516",
+ 84, "RDN0",
MTK_EINT_FUNCTION(0, 84),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO84"),
MTK_FUNCTION(1, "RDN0")
),
MTK_PIN(
- PINCTRL_PIN(85, "RDP0"),
- NULL, "mt8516",
+ 85, "RDP0",
MTK_EINT_FUNCTION(0, 85),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO85"),
MTK_FUNCTION(1, "RDP0")
),
MTK_PIN(
- PINCTRL_PIN(86, "RDN1"),
- NULL, "mt8516",
+ 86, "RDN1",
MTK_EINT_FUNCTION(0, 86),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO86"),
MTK_FUNCTION(1, "RDN1")
),
MTK_PIN(
- PINCTRL_PIN(87, "RDP1"),
- NULL, "mt8516",
+ 87, "RDP1",
MTK_EINT_FUNCTION(0, 87),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO87"),
MTK_FUNCTION(1, "RDP1")
),
MTK_PIN(
- PINCTRL_PIN(88, "RCN"),
- NULL, "mt8516",
+ 88, "RCN",
MTK_EINT_FUNCTION(0, 88),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO88"),
MTK_FUNCTION(1, "RCN")
),
MTK_PIN(
- PINCTRL_PIN(89, "RCP"),
- NULL, "mt8516",
+ 89, "RCP",
MTK_EINT_FUNCTION(0, 89),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO89"),
MTK_FUNCTION(1, "RCP")
),
MTK_PIN(
- PINCTRL_PIN(90, "RDN2"),
- NULL, "mt8516",
+ 90, "RDN2",
MTK_EINT_FUNCTION(0, 90),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO90"),
MTK_FUNCTION(1, "RDN2"),
MTK_FUNCTION(2, "CMDAT8")
),
MTK_PIN(
- PINCTRL_PIN(91, "RDP2"),
- NULL, "mt8516",
+ 91, "RDP2",
MTK_EINT_FUNCTION(0, 91),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO91"),
MTK_FUNCTION(1, "RDP2"),
MTK_FUNCTION(2, "CMDAT9")
),
MTK_PIN(
- PINCTRL_PIN(92, "RDN3"),
- NULL, "mt8516",
+ 92, "RDN3",
MTK_EINT_FUNCTION(0, 92),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO92"),
MTK_FUNCTION(1, "RDN3"),
MTK_FUNCTION(2, "CMDAT4")
),
MTK_PIN(
- PINCTRL_PIN(93, "RDP3"),
- NULL, "mt8516",
+ 93, "RDP3",
MTK_EINT_FUNCTION(0, 93),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO93"),
MTK_FUNCTION(1, "RDP3"),
MTK_FUNCTION(2, "CMDAT5")
),
MTK_PIN(
- PINCTRL_PIN(94, "RCN_A"),
- NULL, "mt8516",
+ 94, "RCN_A",
MTK_EINT_FUNCTION(0, 94),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO94"),
MTK_FUNCTION(1, "RCN_A"),
MTK_FUNCTION(2, "CMDAT6")
),
MTK_PIN(
- PINCTRL_PIN(95, "RCP_A"),
- NULL, "mt8516",
+ 95, "RCP_A",
MTK_EINT_FUNCTION(0, 95),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO95"),
MTK_FUNCTION(1, "RCP_A"),
MTK_FUNCTION(2, "CMDAT7")
),
MTK_PIN(
- PINCTRL_PIN(96, "RDN1_A"),
- NULL, "mt8516",
+ 96, "RDN1_A",
MTK_EINT_FUNCTION(0, 96),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO96"),
MTK_FUNCTION(1, "RDN1_A"),
MTK_FUNCTION(2, "CMDAT2"),
MTK_FUNCTION(3, "CMCSD2")
),
MTK_PIN(
- PINCTRL_PIN(97, "RDP1_A"),
- NULL, "mt8516",
+ 97, "RDP1_A",
MTK_EINT_FUNCTION(0, 97),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO97"),
MTK_FUNCTION(1, "RDP1_A"),
MTK_FUNCTION(2, "CMDAT3"),
MTK_FUNCTION(3, "CMCSD3")
),
MTK_PIN(
- PINCTRL_PIN(98, "RDN0_A"),
- NULL, "mt8516",
+ 98, "RDN0_A",
MTK_EINT_FUNCTION(0, 98),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO98"),
MTK_FUNCTION(1, "RDN0_A"),
MTK_FUNCTION(2, "CMHSYNC")
),
MTK_PIN(
- PINCTRL_PIN(99, "RDP0_A"),
- NULL, "mt8516",
+ 99, "RDP0_A",
MTK_EINT_FUNCTION(0, 99),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO99"),
MTK_FUNCTION(1, "RDP0_A"),
MTK_FUNCTION(2, "CMVSYNC")
),
MTK_PIN(
- PINCTRL_PIN(100, "CMDAT0"),
- NULL, "mt8516",
+ 100, "CMDAT0",
MTK_EINT_FUNCTION(0, 100),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO100"),
MTK_FUNCTION(1, "CMDAT0"),
MTK_FUNCTION(2, "CMCSD0"),
@@ -978,9 +974,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[21]")
),
MTK_PIN(
- PINCTRL_PIN(101, "CMDAT1"),
- NULL, "mt8516",
+ 101, "CMDAT1",
MTK_EINT_FUNCTION(0, 101),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO101"),
MTK_FUNCTION(1, "CMDAT1"),
MTK_FUNCTION(2, "CMCSD1"),
@@ -990,9 +986,9 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[22]")
),
MTK_PIN(
- PINCTRL_PIN(102, "CMMCLK"),
- NULL, "mt8516",
+ 102, "CMMCLK",
MTK_EINT_FUNCTION(0, 102),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO102"),
MTK_FUNCTION(1, "CMMCLK"),
MTK_FUNCTION(3, "ANT_SEL4"),
@@ -1000,181 +996,181 @@ static const struct mtk_desc_pin mtk_pins_mt8516[] = {
MTK_FUNCTION(7, "DBG_MON_B[23]")
),
MTK_PIN(
- PINCTRL_PIN(103, "CMPCLK"),
- NULL, "mt8516",
+ 103, "CMPCLK",
MTK_EINT_FUNCTION(0, 103),
+ DRV_GRP2,
MTK_FUNCTION(0, "GPIO103"),
MTK_FUNCTION(1, "CMPCLK"),
MTK_FUNCTION(2, "CMCSK"),
MTK_FUNCTION(3, "ANT_SEL5"),
- MTK_FUNCTION(5, " TDM_RX_DI"),
+ MTK_FUNCTION(5, "TDM_RX_DI"),
MTK_FUNCTION(7, "DBG_MON_B[24]")
),
MTK_PIN(
- PINCTRL_PIN(104, "MSDC1_CMD"),
- NULL, "mt8516",
+ 104, "MSDC1_CMD",
MTK_EINT_FUNCTION(0, 104),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO104"),
MTK_FUNCTION(1, "MSDC1_CMD"),
MTK_FUNCTION(4, "SQICS"),
MTK_FUNCTION(7, "DBG_MON_B[25]")
),
MTK_PIN(
- PINCTRL_PIN(105, "MSDC1_CLK"),
- NULL, "mt8516",
+ 105, "MSDC1_CLK",
MTK_EINT_FUNCTION(0, 105),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO105"),
MTK_FUNCTION(1, "MSDC1_CLK"),
MTK_FUNCTION(4, "SQISO"),
MTK_FUNCTION(7, "DBG_MON_B[26]")
),
MTK_PIN(
- PINCTRL_PIN(106, "MSDC1_DAT0"),
- NULL, "mt8516",
+ 106, "MSDC1_DAT0",
MTK_EINT_FUNCTION(0, 106),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO106"),
MTK_FUNCTION(1, "MSDC1_DAT0"),
MTK_FUNCTION(4, "SQISI"),
MTK_FUNCTION(7, "DBG_MON_B[27]")
),
MTK_PIN(
- PINCTRL_PIN(107, "MSDC1_DAT1"),
- NULL, "mt8516",
+ 107, "MSDC1_DAT1",
MTK_EINT_FUNCTION(0, 107),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO107"),
MTK_FUNCTION(1, "MSDC1_DAT1"),
MTK_FUNCTION(4, "SQIWP"),
MTK_FUNCTION(7, "DBG_MON_B[28]")
),
MTK_PIN(
- PINCTRL_PIN(108, "MSDC1_DAT2"),
- NULL, "mt8516",
+ 108, "MSDC1_DAT2",
MTK_EINT_FUNCTION(0, 108),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO108"),
MTK_FUNCTION(1, "MSDC1_DAT2"),
MTK_FUNCTION(4, "SQIRST"),
MTK_FUNCTION(7, "DBG_MON_B[29]")
),
MTK_PIN(
- PINCTRL_PIN(109, "MSDC1_DAT3"),
- NULL, "mt8516",
+ 109, "MSDC1_DAT3",
MTK_EINT_FUNCTION(0, 109),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO109"),
MTK_FUNCTION(1, "MSDC1_DAT3"),
- MTK_FUNCTION(4, "SQICK"), /* WIP */
+ MTK_FUNCTION(4, "SQICK"),
MTK_FUNCTION(7, "DBG_MON_B[30]")
),
MTK_PIN(
- PINCTRL_PIN(110, "MSDC0_DAT7"),
- NULL, "mt8516",
+ 110, "MSDC0_DAT7",
MTK_EINT_FUNCTION(0, 110),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO110"),
MTK_FUNCTION(1, "MSDC0_DAT7"),
MTK_FUNCTION(4, "NLD7")
),
MTK_PIN(
- PINCTRL_PIN(111, "MSDC0_DAT6"),
- NULL, "mt8516",
+ 111, "MSDC0_DAT6",
MTK_EINT_FUNCTION(0, 111),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO111"),
MTK_FUNCTION(1, "MSDC0_DAT6"),
MTK_FUNCTION(4, "NLD6")
),
MTK_PIN(
- PINCTRL_PIN(112, "MSDC0_DAT5"),
- NULL, "mt8516",
+ 112, "MSDC0_DAT5",
MTK_EINT_FUNCTION(0, 112),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO112"),
MTK_FUNCTION(1, "MSDC0_DAT5"),
MTK_FUNCTION(4, "NLD4")
),
MTK_PIN(
- PINCTRL_PIN(113, "MSDC0_DAT4"),
- NULL, "mt8516",
+ 113, "MSDC0_DAT4",
MTK_EINT_FUNCTION(0, 113),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO113"),
MTK_FUNCTION(1, "MSDC0_DAT4"),
MTK_FUNCTION(4, "NLD3")
),
MTK_PIN(
- PINCTRL_PIN(114, "MSDC0_RSTB"),
- NULL, "mt8516",
+ 114, "MSDC0_RSTB",
MTK_EINT_FUNCTION(0, 114),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO114"),
MTK_FUNCTION(1, "MSDC0_RSTB"),
MTK_FUNCTION(4, "NLD0")
),
MTK_PIN(
- PINCTRL_PIN(115, "MSDC0_CMD"),
- NULL, "mt8516",
+ 115, "MSDC0_CMD",
MTK_EINT_FUNCTION(0, 115),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO115"),
MTK_FUNCTION(1, "MSDC0_CMD"),
MTK_FUNCTION(4, "NALE")
),
MTK_PIN(
- PINCTRL_PIN(116, "MSDC0_CLK"),
- NULL, "mt8516",
+ 116, "MSDC0_CLK",
MTK_EINT_FUNCTION(0, 116),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO116"),
MTK_FUNCTION(1, "MSDC0_CLK"),
MTK_FUNCTION(4, "NWEB")
),
MTK_PIN(
- PINCTRL_PIN(117, "MSDC0_DAT3"),
- NULL, "mt8516",
+ 117, "MSDC0_DAT3",
MTK_EINT_FUNCTION(0, 117),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO117"),
MTK_FUNCTION(1, "MSDC0_DAT3"),
MTK_FUNCTION(4, "NLD1")
),
MTK_PIN(
- PINCTRL_PIN(118, "MSDC0_DAT2"),
- NULL, "mt8516",
+ 118, "MSDC0_DAT2",
MTK_EINT_FUNCTION(0, 118),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO118"),
MTK_FUNCTION(1, "MSDC0_DAT2"),
MTK_FUNCTION(4, "NLD5")
),
MTK_PIN(
- PINCTRL_PIN(119, "MSDC0_DAT1"),
- NULL, "mt8516",
+ 119, "MSDC0_DAT1",
MTK_EINT_FUNCTION(0, 119),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO119"),
MTK_FUNCTION(1, "MSDC0_DAT1"),
MTK_FUNCTION(4, "NLD8")
),
MTK_PIN(
- PINCTRL_PIN(120, "MSDC0_DAT0"),
- NULL, "mt8516",
+ 120, "MSDC0_DAT0",
MTK_EINT_FUNCTION(0, 120),
+ DRV_GRP4,
MTK_FUNCTION(0, "GPIO120"),
MTK_FUNCTION(1, "MSDC0_DAT0"),
MTK_FUNCTION(4, "WATCHDOG"),
MTK_FUNCTION(5, "NLD2")
),
MTK_PIN(
- PINCTRL_PIN(121, "GPIO121"),
- NULL, "mt8516",
+ 121, "GPIO121",
MTK_EINT_FUNCTION(0, 121),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO121")
),
MTK_PIN(
- PINCTRL_PIN(122, "GPIO122"),
- NULL, "mt8516",
+ 122, "GPIO122",
MTK_EINT_FUNCTION(0, 122),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO122")
),
MTK_PIN(
- PINCTRL_PIN(123, "GPIO123"),
- NULL, "mt8516",
+ 123, "GPIO123",
MTK_EINT_FUNCTION(0, 123),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO123")
),
MTK_PIN(
- PINCTRL_PIN(124, "GPIO124"),
- NULL, "mt8516",
+ 124, "GPIO124",
MTK_EINT_FUNCTION(0, 124),
+ DRV_GRP0, // N/A
MTK_FUNCTION(0, "GPIO124")
),
};
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 1/3] dt-bindings: pinctrl: mt8516/mt8167: Move compatibles from mt66xx to mt6795
From: Luca Leonardo Scorcia @ 2026-06-25 10:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260625104742.113803-1-l.scorcia@gmail.com>
Pinctrl settings for MediaTek mt8516-mt8167 SoCs use two reg base
addresses, one for GPIO and the other for EINT, as it is common in the
"Paris" pinctrl platform that is described in the MediaTek mt6795 docs.
Move the binding compatible for these two SoCs from mt66xx to the mt6796
one as a prerequisite for migrating the pinctrl driver to the
pinctrl-paris platform.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
.../devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml | 2 --
.../devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml | 5 ++++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
index 1468c6f87cfa..0cff2a352b1f 100644
--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt65xx-pinctrl.yaml
@@ -22,9 +22,7 @@ properties:
- mediatek,mt7623-pinctrl
- mediatek,mt8127-pinctrl
- mediatek,mt8135-pinctrl
- - mediatek,mt8167-pinctrl
- mediatek,mt8173-pinctrl
- - mediatek,mt8516-pinctrl
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
index 9a937f414cc9..c703de72e1d5 100644
--- a/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/mediatek,mt6795-pinctrl.yaml
@@ -15,7 +15,10 @@ description:
properties:
compatible:
- const: mediatek,mt6795-pinctrl
+ enum:
+ - mediatek,mt6795-pinctrl
+ - mediatek,mt8167-pinctrl
+ - mediatek,mt8516-pinctrl
gpio-controller: true
--
2.43.0
^ permalink raw reply related
* [RFC PATCH 0/3] pinctrl: mediatek: mt8516-mt8167: Convert to Paris driver
From: Luca Leonardo Scorcia @ 2026-06-25 10:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Luca Leonardo Scorcia, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
The pinctrl registers of the mt8516 and mt8167 SoCs follow the layout of
the Paris platform, but their pinctrl driver is currently modeled on
the mt65xx legacy driver. As suggested in [1], it is possible to migrate
them to the Paris driver.
In the process it is also possible to completely drop one of the two
drivers as their register layout is identical, they only differ in some
pin functions (mt8167 is basically mt8516 with added display blocks).
The Paris driver allows specifying two base registers, gpio and eint;
this way it's no longer necessary to have a syscfg node in the device
tree, referenced as a phandle in the pinctrl node. This also fixes the
following long standing dtbs_check errors:
mt8167-pumpkin.dtb: syscfg-pctl@10005000 (syscon): compatible: ['syscon']
is too short
mt8516-pumpkin.dtb: syscfg-pctl@10005000 (syscon): compatible: ['syscon']
is too short
The new driver has been checked against the SoC data sheet and adds the
capability to control pin driving strength and R1R0 pullup-pulldown
resistors.
This series is sent as a RFC since the changes could theoretically impact
existing devices. I am pretty sure that no device ever used upstream
drivers though, not even the Pumpkin board that's present in Linux
sources since this board lacks the associated mt6392 PMIC driver that
is required for regulator management. If for compatibility reasons it is
deemed better to keep both drivers in the kernel I would welcome any
suggestion on how to name the new driver, and how to adjust the two
bindings for coexistence.
These changes have been tested on the Xiaomi Mi Smart Clock X04G and on
the Lenovo Smart Clock 2 CD-24502F.
[1] https://lore.kernel.org/linux-mediatek/296b000c-5970-4668-bd42-b99ca78d598f@collabora.com/
Luca Leonardo Scorcia (3):
dt-bindings: pinctrl: mt8516/mt8167: Move compatibles from mt66xx to
mt6795
pinctrl: mediatek: mt8516/mt8167: Migrate driver to pinctrl-paris
platform
arm64: dts: mt8516/mt8167: Update pinctrl nodes for the new paris
driver
.../pinctrl/mediatek,mt65xx-pinctrl.yaml | 2 -
.../pinctrl/mediatek,mt6795-pinctrl.yaml | 5 +-
arch/arm64/boot/dts/mediatek/mt8167.dtsi | 15 +-
arch/arm64/boot/dts/mediatek/mt8516.dtsi | 12 +-
drivers/pinctrl/mediatek/Kconfig | 11 +-
drivers/pinctrl/mediatek/Makefile | 1 -
drivers/pinctrl/mediatek/pinctrl-mt8167.c | 345 --------
drivers/pinctrl/mediatek/pinctrl-mt8516.c | 770 +++++++++++-------
drivers/pinctrl/mediatek/pinctrl-mtk-mt8167.h | 562 +++++++------
drivers/pinctrl/mediatek/pinctrl-mtk-mt8516.h | 512 ++++++------
10 files changed, 1018 insertions(+), 1217 deletions(-)
delete mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8167.c
base-commit: 4e5dfb7c84012007c3c7061126491bbc92d71bf1
--
2.43.0
^ permalink raw reply
* [PATCH v19 7/7] arm64: dts: qcom: lemans: add interrupts to CTCU device
From: Jie Gan @ 2026-06-25 10:45 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
Alexander Shishkin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Tingwei Zhang, Jie Gan, Bjorn Andersson,
Konrad Dybcio, Yuanfang Zhang, Mao Jinlong
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
devicetree, Konrad Dybcio
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com>
Add interrupts to enable byte-cntr function for TMC ETR devices.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/lemans.dtsi | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 353a6e6fd3ac..2b4debc39db0 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -3150,6 +3150,9 @@ ctcu@4001000 {
clocks = <&aoss_qmp>;
clock-names = "apb";
+ interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>;
+
in-ports {
#address-cells = <1>;
#size-cells = <0>;
--
2.34.1
^ permalink raw reply related
* [PATCH v19 6/7] coresight: ctcu: enable byte-cntr for TMC ETR devices
From: Jie Gan @ 2026-06-25 10:45 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Leo Yan,
Alexander Shishkin, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Tingwei Zhang, Jie Gan, Bjorn Andersson,
Konrad Dybcio, Yuanfang Zhang, Mao Jinlong
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
devicetree
In-Reply-To: <20260625-enable-byte-cntr-for-ctcu-v19-0-8fbbf22e8381@oss.qualcomm.com>
The byte-cntr function provided by the CTCU device is used to transfer data
from the ETR buffer to the userspace. An interrupt is triggered if the data
size exceeds the threshold set in the BYTECNTRVAL register. The interrupt
handler counts the number of triggered interruptions and the read function
will read the data from the synced ETR buffer.
Switching the sysfs_buf when current buffer is full or the timeout is
triggered and resets rrp and rwp registers after switched the buffer.
The synced buffer will become available for reading after the switch.
Byte-cntr workflow:
start -> ctcu_enable(ctcu_byte_cntr_start) -> tmc_enable_etr_sink ->
tmc_read_prepare_etr(jump to tmc_read_prepare_byte_cntr) ->
tmc_etr_get_sysfs_trace(jump to tmc_byte_cntr_get_data) ->
tmc_disable_etr_sink -> ctcu_disable(ctcu_byte_cntr_stop) ->
tmc_read_unprepare_etr(jump to tmc_read_unprepare_byte_cntr) -> finish
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
---
.../ABI/testing/sysfs-bus-coresight-devices-ctcu | 9 +
drivers/hwtracing/coresight/Makefile | 2 +-
.../hwtracing/coresight/coresight-ctcu-byte-cntr.c | 327 +++++++++++++++++++++
drivers/hwtracing/coresight/coresight-ctcu-core.c | 127 +++++++-
drivers/hwtracing/coresight/coresight-ctcu.h | 81 ++++-
drivers/hwtracing/coresight/coresight-tmc-core.c | 3 +-
drivers/hwtracing/coresight/coresight-tmc-etr.c | 115 +++++++-
drivers/hwtracing/coresight/coresight-tmc.h | 9 +
8 files changed, 647 insertions(+), 26 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu
new file mode 100644
index 000000000000..beef0be21969
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-ctcu
@@ -0,0 +1,9 @@
+What: /sys/bus/coresight/devices/<ctcu-name>/irq_enabled[0:1]
+Date: June 2026
+KernelVersion: 7.3
+Contact: Tingwei Zhang <tingwei.zhang@oss.qualcomm.com>; Jinlong Mao <jinlong.mao@oss.qualcomm.com>; Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+ (RW) Configure the flag to enable interrupt to count data during CTCU enablement.
+ An interrupt is generated when the data size exceeds the value set in the IRQ register.
+ 0 : disable
+ 1 : enable
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index ab16d06783a5..821a1b06b20c 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -55,5 +55,5 @@ coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
obj-$(CONFIG_CORESIGHT_CTCU) += coresight-ctcu.o
-coresight-ctcu-y := coresight-ctcu-core.o
+coresight-ctcu-y := coresight-ctcu-core.o coresight-ctcu-byte-cntr.o
obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
new file mode 100644
index 000000000000..5ab97a71f02f
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/coresight.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/uaccess.h>
+
+#include "coresight-ctcu.h"
+#include "coresight-priv.h"
+#include "coresight-tmc.h"
+
+static irqreturn_t byte_cntr_handler(int irq, void *data)
+{
+ struct ctcu_byte_cntr *byte_cntr_data = data;
+
+ atomic_inc(&byte_cntr_data->irq_cnt);
+ wake_up(&byte_cntr_data->wq);
+
+ return IRQ_HANDLED;
+}
+
+static void ctcu_cfg_byte_cntr_reg(struct ctcu_drvdata *drvdata, u32 val,
+ u32 offset)
+{
+ /* A one value for IRQCTRL register represents 8 bytes */
+ ctcu_program_register(drvdata, val / 8, offset);
+}
+
+static struct ctcu_byte_cntr *ctcu_get_byte_cntr(struct coresight_device *ctcu,
+ struct coresight_device *etr)
+{
+ struct ctcu_drvdata *drvdata = dev_get_drvdata(ctcu->dev.parent);
+ int port;
+
+ port = coresight_get_in_port(etr, ctcu);
+ if (port < 0 || port > 1)
+ return NULL;
+
+ return &drvdata->byte_cntr_data[port];
+}
+
+static bool ctcu_byte_cntr_switch_buffer(struct tmc_drvdata *etr_drvdata,
+ struct ctcu_byte_cntr *byte_cntr_data)
+{
+ struct etr_buf_node *nd, *next, *curr_node = NULL, *picked_node = NULL;
+ struct etr_buf *curr_buf = etr_drvdata->sysfs_buf;
+ bool found_free_buf = false;
+ unsigned long flags;
+
+ if (WARN_ON(!etr_drvdata || !byte_cntr_data))
+ return false;
+
+ /* Stop the ETR before initiating the switch */
+ if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_DISABLED)
+ tmc_etr_enable_disable_hw(etr_drvdata, false);
+
+ /*
+ * Serialise the sysfs_buf/etr_buf swap against the ETR sink
+ * enable/disable paths which also touch these fields under the
+ * spinlock. tmc_etr_enable_disable_hw() takes the same lock, so it
+ * must be called outside this critical section.
+ */
+ raw_spin_lock_irqsave(&etr_drvdata->spinlock, flags);
+ list_for_each_entry_safe(nd, next, &etr_drvdata->etr_buf_list, link) {
+ /* curr_buf is free for next round */
+ if (nd->sysfs_buf == curr_buf) {
+ nd->is_free = true;
+ curr_node = nd;
+ } else if (!found_free_buf && nd->is_free) {
+ picked_node = nd;
+ found_free_buf = true;
+ }
+ }
+
+ if (found_free_buf) {
+ curr_node->pos = 0;
+ curr_node->reading = true;
+ byte_cntr_data->buf_node = curr_node;
+ etr_drvdata->sysfs_buf = picked_node->sysfs_buf;
+ etr_drvdata->etr_buf = picked_node->sysfs_buf;
+ picked_node->is_free = false;
+ /* Reset irq_cnt for next etr_buf */
+ atomic_set(&byte_cntr_data->irq_cnt, 0);
+ }
+ raw_spin_unlock_irqrestore(&etr_drvdata->spinlock, flags);
+
+ /* Restart the ETR once a free buffer is available */
+ if (found_free_buf &&
+ coresight_get_mode(etr_drvdata->csdev) != CS_MODE_DISABLED)
+ tmc_etr_enable_disable_hw(etr_drvdata, true);
+
+ return found_free_buf;
+}
+
+/*
+ * ctcu_byte_cntr_get_data() - reads data from the deactivated and filled buffer.
+ * The byte-cntr reading work reads data from the deactivated and filled buffer.
+ * The read operation waits for a buffer to become available, either filled or
+ * upon timeout, and then reads trace data from the synced buffer.
+ */
+static ssize_t tmc_byte_cntr_get_data(struct tmc_drvdata *etr_drvdata, loff_t pos,
+ size_t len, char **bufpp)
+{
+ struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
+ struct device *dev = &etr_drvdata->csdev->dev;
+ struct ctcu_byte_cntr *byte_cntr_data;
+ struct etr_buf *sysfs_buf;
+ atomic_t *irq_cnt;
+ ssize_t actual;
+ int ret;
+
+ byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
+ if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
+ return -EINVAL;
+
+ irq_cnt = &byte_cntr_data->irq_cnt;
+
+wait_buffer:
+ if (!byte_cntr_data->buf_node) {
+ ret = wait_event_interruptible_timeout(byte_cntr_data->wq,
+ (atomic_read(irq_cnt) >= MAX_IRQ_CNT - 1) ||
+ !byte_cntr_data->enable,
+ BYTE_CNTR_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ /*
+ * The current etr_buf is almost full or timeout is triggered,
+ * so switch the buffer and mark the switched buffer as reading.
+ */
+ if (byte_cntr_data->enable) {
+ if (!ctcu_byte_cntr_switch_buffer(etr_drvdata, byte_cntr_data)) {
+ dev_err(dev, "Switch buffer failed for the byte-cntr\n");
+ return -ENOMEM;
+ }
+ } else {
+ /* Exit byte-cntr reading */
+ return 0;
+ }
+ }
+
+ /* Check the status of current etr_buf */
+ if (atomic_read(irq_cnt) >= MAX_IRQ_CNT)
+ dev_warn(dev, "Data overwrite happened\n");
+
+ pos = byte_cntr_data->buf_node->pos;
+ sysfs_buf = byte_cntr_data->buf_node->sysfs_buf;
+ actual = tmc_etr_read_sysfs_buf(sysfs_buf, pos, len, bufpp);
+ if (actual <= 0) {
+ /* Reset buf_node upon reading is finished or failed */
+ byte_cntr_data->buf_node->reading = false;
+ byte_cntr_data->buf_node = NULL;
+
+ /*
+ * Nothing in the buffer, waiting for the next buffer
+ * to be filled.
+ */
+ if (actual == 0)
+ goto wait_buffer;
+ }
+
+ return actual;
+}
+
+static int tmc_read_prepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
+{
+ struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
+ struct ctcu_byte_cntr *byte_cntr_data;
+ unsigned long flags;
+ int ret = 0;
+
+ /* byte-cntr is operating with SYSFS mode being enabled only */
+ if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_SYSFS)
+ return -EINVAL;
+
+ byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
+ if (!byte_cntr_data || !byte_cntr_data->irq_enabled)
+ return -EINVAL;
+
+ raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
+ if (byte_cntr_data->reading) {
+ raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
+ return -EBUSY;
+ }
+
+ /* byte_cntr_data->enable may race with ctcu_platform_remove() */
+ if (!byte_cntr_data->enable) {
+ raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
+ return -ENODEV;
+ }
+
+ byte_cntr_data->reading = true;
+ raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
+ /* Setup an available etr_buf_list for byte-cntr */
+ ret = tmc_create_etr_buf_list(etr_drvdata, 2);
+ if (ret) {
+ byte_cntr_data->reading = false;
+ return ret;
+ }
+
+ scoped_guard(raw_spinlock_irqsave, &byte_cntr_data->spin_lock) {
+ atomic_set(&byte_cntr_data->irq_cnt, 0);
+ /*
+ * Configure the byte-cntr register to enable IRQ. The
+ * configured size is 5% of the buffer_size.
+ */
+ ctcu_cfg_byte_cntr_reg(byte_cntr_data->ctcu_drvdata,
+ etr_drvdata->size / MAX_IRQ_CNT,
+ byte_cntr_data->irq_ctrl_offset);
+ byte_cntr_data->buf_node = NULL;
+ }
+ /* enable_irq_wake() may sleep on slow-bus irqchips, call it unlocked */
+ enable_irq_wake(byte_cntr_data->irq);
+
+ return 0;
+}
+
+static int tmc_read_unprepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
+{
+ struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
+ struct ctcu_byte_cntr *byte_cntr_data;
+
+ /*
+ * Do the unprepare operation only when the byte_cntr_data->reading
+ * is truly set
+ */
+ byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
+ if (!byte_cntr_data || !byte_cntr_data->irq_enabled ||
+ !byte_cntr_data->reading)
+ return -EINVAL;
+
+ tmc_clean_etr_buf_list(etr_drvdata);
+ scoped_guard(raw_spinlock_irqsave, &byte_cntr_data->spin_lock) {
+ /* Configure the byte-cntr register to disable IRQ */
+ ctcu_cfg_byte_cntr_reg(byte_cntr_data->ctcu_drvdata, 0,
+ byte_cntr_data->irq_ctrl_offset);
+ byte_cntr_data->buf_node = NULL;
+ byte_cntr_data->reading = false;
+ }
+ /*
+ * The threshold IRQ is already disabled by the register write above,
+ * so no wake event can arrive here. disable_irq_wake() may sleep on
+ * slow-bus irqchips, so call it outside the spin_lock.
+ */
+ disable_irq_wake(byte_cntr_data->irq);
+ wake_up(&byte_cntr_data->wq);
+
+ return 0;
+}
+
+const struct tmc_sysfs_ops byte_cntr_sysfs_ops = {
+ .read_prepare = tmc_read_prepare_byte_cntr,
+ .read_unprepare = tmc_read_unprepare_byte_cntr,
+ .get_trace_data = tmc_byte_cntr_get_data,
+};
+
+/* Start the byte-cntr function when the path is enabled. */
+void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path)
+{
+ struct coresight_device *sink = coresight_get_sink(path);
+ struct ctcu_byte_cntr *byte_cntr_data;
+
+ byte_cntr_data = ctcu_get_byte_cntr(csdev, sink);
+ if (!byte_cntr_data)
+ return;
+
+ /* Don't start byte-cntr function when irq_enabled is not set. */
+ if (!byte_cntr_data->irq_enabled || byte_cntr_data->enable)
+ return;
+
+ guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
+ byte_cntr_data->enable = true;
+}
+
+/* Stop the byte-cntr function when the path is disabled. */
+void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path)
+{
+ struct coresight_device *sink = coresight_get_sink(path);
+ struct ctcu_byte_cntr *byte_cntr_data;
+
+ if (coresight_get_mode(sink) == CS_MODE_SYSFS)
+ return;
+
+ byte_cntr_data = ctcu_get_byte_cntr(csdev, sink);
+ if (!byte_cntr_data)
+ return;
+
+ guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
+ byte_cntr_data->enable = false;
+}
+
+void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int etr_num)
+{
+ struct ctcu_byte_cntr *byte_cntr_data;
+ struct device_node *nd = dev->of_node;
+ int irq_num, ret, i, irq_registered = 0;
+
+ for (i = 0; i < etr_num; i++) {
+ byte_cntr_data = &drvdata->byte_cntr_data[i];
+ irq_num = of_irq_get(nd, i);
+ if (irq_num < 0) {
+ dev_err(dev, "Failed to get IRQ from DT for port%d\n", i);
+ continue;
+ }
+
+ ret = devm_request_irq(dev, irq_num, byte_cntr_handler,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
+ dev_name(dev), byte_cntr_data);
+ if (ret) {
+ dev_err(dev, "Failed to register IRQ for port%d\n", i);
+ continue;
+ }
+
+ byte_cntr_data->irq = irq_num;
+ byte_cntr_data->ctcu_drvdata = drvdata;
+ init_waitqueue_head(&byte_cntr_data->wq);
+ raw_spin_lock_init(&byte_cntr_data->spin_lock);
+ irq_registered++;
+ }
+
+ if (irq_registered)
+ tmc_etr_set_byte_cntr_sysfs_ops(&byte_cntr_sysfs_ops);
+}
diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
index e8720026c9e3..2da1a6f3d29f 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
+++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2024-2026 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk.h>
@@ -18,6 +19,7 @@
#include "coresight-ctcu.h"
#include "coresight-priv.h"
+#include "coresight-tmc.h"
#define ctcu_writel(drvdata, val, offset) __raw_writel((val), drvdata->base + offset)
#define ctcu_readl(drvdata, offset) __raw_readl(drvdata->base + offset)
@@ -43,17 +45,21 @@
#define CTCU_ATID_REG_BIT(traceid) (traceid % 32)
#define CTCU_ATID_REG_SIZE 0x10
+#define CTCU_ETR0_IRQCTRL 0x6c
+#define CTCU_ETR1_IRQCTRL 0x70
#define CTCU_ETR0_ATID0 0xf8
#define CTCU_ETR1_ATID0 0x108
static const struct ctcu_etr_config sa8775p_etr_cfgs[] = {
{
- .atid_offset = CTCU_ETR0_ATID0,
- .port_num = 0,
+ .atid_offset = CTCU_ETR0_ATID0,
+ .irq_ctrl_offset = CTCU_ETR0_IRQCTRL,
+ .port_num = 0,
},
{
- .atid_offset = CTCU_ETR1_ATID0,
- .port_num = 1,
+ .atid_offset = CTCU_ETR1_ATID0,
+ .irq_ctrl_offset = CTCU_ETR1_IRQCTRL,
+ .port_num = 1,
},
};
@@ -62,6 +68,85 @@ static const struct ctcu_config sa8775p_cfgs = {
.num_etr_config = ARRAY_SIZE(sa8775p_etr_cfgs),
};
+void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset)
+{
+ CS_UNLOCK(drvdata->base);
+ ctcu_writel(drvdata, val, offset);
+ CS_LOCK(drvdata->base);
+}
+
+static ssize_t irq_enabled_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ctcu_byte_cntr_irq_attribute *irq_attr =
+ container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr);
+ struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ u8 port = irq_attr->port;
+
+ if (!drvdata->byte_cntr_data[port].irq_ctrl_offset)
+ return -EINVAL;
+
+ return sysfs_emit(buf, "%u\n",
+ (unsigned int)drvdata->byte_cntr_data[port].irq_enabled);
+}
+
+static ssize_t irq_enabled_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct ctcu_byte_cntr_irq_attribute *irq_attr =
+ container_of(attr, struct ctcu_byte_cntr_irq_attribute, attr);
+ struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ u8 port = irq_attr->port;
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(raw_spinlock_irqsave)(&drvdata->byte_cntr_data[port].spin_lock);
+ if (drvdata->byte_cntr_data[port].reading)
+ return -EBUSY;
+ else if (drvdata->byte_cntr_data[port].irq_ctrl_offset)
+ drvdata->byte_cntr_data[port].irq_enabled = !!val;
+
+ return size;
+}
+
+static umode_t irq_enabled_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device_attribute *dev_attr =
+ container_of(attr, struct device_attribute, attr);
+ struct ctcu_byte_cntr_irq_attribute *irq_attr =
+ container_of(dev_attr, struct ctcu_byte_cntr_irq_attribute, attr);
+ struct device *dev = kobj_to_dev(kobj);
+ struct ctcu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ u8 port = irq_attr->port;
+
+ if (drvdata && drvdata->byte_cntr_data[port].irq_ctrl_offset)
+ return attr->mode;
+
+ return 0;
+}
+
+static struct attribute *ctcu_attrs[] = {
+ ctcu_byte_cntr_irq_rw(0),
+ ctcu_byte_cntr_irq_rw(1),
+ NULL,
+};
+
+static struct attribute_group ctcu_attr_grp = {
+ .attrs = ctcu_attrs,
+ .is_visible = irq_enabled_is_visible,
+};
+
+static const struct attribute_group *ctcu_attr_grps[] = {
+ &ctcu_attr_grp,
+ NULL,
+};
+
static void ctcu_program_atid_register(struct ctcu_drvdata *drvdata, u32 reg_offset,
u8 bit, bool enable)
{
@@ -140,11 +225,15 @@ static int ctcu_set_etr_traceid(struct coresight_device *csdev, struct coresight
static int ctcu_enable(struct coresight_device *csdev, enum cs_mode mode,
struct coresight_path *path)
{
+ ctcu_byte_cntr_start(csdev, path);
+
return ctcu_set_etr_traceid(csdev, path, true);
}
static int ctcu_disable(struct coresight_device *csdev, struct coresight_path *path)
{
+ ctcu_byte_cntr_stop(csdev, path);
+
return ctcu_set_etr_traceid(csdev, path, false);
}
@@ -195,7 +284,10 @@ static int ctcu_probe(struct platform_device *pdev)
for (i = 0; i < cfgs->num_etr_config; i++) {
etr_cfg = &cfgs->etr_cfgs[i];
drvdata->atid_offset[i] = etr_cfg->atid_offset;
+ drvdata->byte_cntr_data[i].irq_ctrl_offset =
+ etr_cfg->irq_ctrl_offset;
}
+ ctcu_byte_cntr_init(dev, drvdata, cfgs->num_etr_config);
}
}
@@ -209,6 +301,7 @@ static int ctcu_probe(struct platform_device *pdev)
desc.dev = dev;
desc.ops = &ctcu_ops;
desc.access = CSDEV_ACCESS_IOMEM(base);
+ desc.groups = ctcu_attr_grps;
raw_spin_lock_init(&drvdata->spin_lock);
drvdata->csdev = coresight_register(&desc);
@@ -244,10 +337,34 @@ static int ctcu_platform_probe(struct platform_device *pdev)
static void ctcu_platform_remove(struct platform_device *pdev)
{
struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
+ struct ctcu_byte_cntr *byte_cntr_data;
+ unsigned long flags;
+ int i;
if (WARN_ON(!drvdata))
return;
+ /*
+ * Signal all active byte-cntr readers to exit, then wait for them to
+ * finish before resetting the ops pointer and freeing driver data.
+ * Without this, a reader blocked in wait_event_interruptible_timeout()
+ * would access the freed ctcu_drvdata wait-queue head (use-after-free).
+ */
+ for (i = 0; i < ETR_MAX_NUM; i++) {
+ byte_cntr_data = &drvdata->byte_cntr_data[i];
+ raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
+ /* Set enable=false for all ports to signal teardown to racing readers */
+ byte_cntr_data->enable = false;
+ if (!byte_cntr_data->reading) {
+ raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
+ continue;
+ }
+ raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
+ wake_up_all(&byte_cntr_data->wq);
+ wait_event(byte_cntr_data->wq, !byte_cntr_data->reading);
+ }
+
+ tmc_etr_reset_byte_cntr_sysfs_ops();
ctcu_remove(pdev);
pm_runtime_disable(&pdev->dev);
}
diff --git a/drivers/hwtracing/coresight/coresight-ctcu.h b/drivers/hwtracing/coresight/coresight-ctcu.h
index e9594c38dd91..a2ae0a0d91d0 100644
--- a/drivers/hwtracing/coresight/coresight-ctcu.h
+++ b/drivers/hwtracing/coresight/coresight-ctcu.h
@@ -1,23 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2024-2026 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _CORESIGHT_CTCU_H
#define _CORESIGHT_CTCU_H
+
+#include <linux/time.h>
#include "coresight-trace-id.h"
/* Maximum number of supported ETR devices for a single CTCU. */
#define ETR_MAX_NUM 2
+#define BYTE_CNTR_TIMEOUT (3 * HZ)
+#define MAX_IRQ_CNT 20
+
/**
* struct ctcu_etr_config
* @atid_offset: offset to the ATID0 Register.
- * @port_num: in-port number of CTCU device that connected to ETR.
+ * @port_num: in-port number of the CTCU device that connected to ETR.
+ * @irq_ctrl_offset: offset to the BYTECNTRVAL register.
*/
struct ctcu_etr_config {
const u32 atid_offset;
const u32 port_num;
+ const u32 irq_ctrl_offset;
};
struct ctcu_config {
@@ -25,15 +33,68 @@ struct ctcu_config {
int num_etr_config;
};
-struct ctcu_drvdata {
- void __iomem *base;
- struct clk *apb_clk;
- struct device *dev;
- struct coresight_device *csdev;
+/**
+ * struct ctcu_byte_cntr
+ * @enable: indicates that byte_cntr function is enabled or not.
+ * @irq_enabled: indicates that the interruption is enabled.
+ * @reading: indicates that byte_cntr is reading.
+ * @irq: allocated number of the IRQ.
+ * @irq_cnt: IRQ count number of the triggered interruptions.
+ * @wq: waitqueue for reading data from ETR buffer.
+ * @spin_lock: spinlock of the byte_cntr_data.
+ * @irq_ctrl_offset: offset to the BYTECNTVAL Register.
+ * @ctcu_drvdata: drvdata of the CTCU device.
+ * @buf_node: etr_buf_node for reading.
+ */
+struct ctcu_byte_cntr {
+ bool enable;
+ bool irq_enabled;
+ bool reading;
+ int irq;
+ atomic_t irq_cnt;
+ wait_queue_head_t wq;
raw_spinlock_t spin_lock;
- u32 atid_offset[ETR_MAX_NUM];
- /* refcnt for each traceid of each sink */
- u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
+ u32 irq_ctrl_offset;
+ struct ctcu_drvdata *ctcu_drvdata;
+ struct etr_buf_node *buf_node;
};
+struct ctcu_drvdata {
+ void __iomem *base;
+ struct clk *apb_clk;
+ struct device *dev;
+ struct coresight_device *csdev;
+ struct ctcu_byte_cntr byte_cntr_data[ETR_MAX_NUM];
+ raw_spinlock_t spin_lock;
+ u32 atid_offset[ETR_MAX_NUM];
+ /* refcnt for each traceid of each sink */
+ u8 traceid_refcnt[ETR_MAX_NUM][CORESIGHT_TRACE_ID_RES_TOP];
+};
+
+/**
+ * struct ctcu_byte_cntr_irq_attribute
+ * @attr: The device attribute.
+ * @port: port number.
+ */
+struct ctcu_byte_cntr_irq_attribute {
+ struct device_attribute attr;
+ u8 port;
+};
+
+#define ctcu_byte_cntr_irq_rw(port) \
+ (&((struct ctcu_byte_cntr_irq_attribute[]) { \
+ { \
+ __ATTR(irq_enabled##port, 0644, irq_enabled_show, \
+ irq_enabled_store), \
+ port, \
+ } \
+ })[0].attr.attr)
+
+void ctcu_program_register(struct ctcu_drvdata *drvdata, u32 val, u32 offset);
+
+/* Byte-cntr functions */
+void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path);
+void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path);
+void ctcu_byte_cntr_init(struct device *dev, struct ctcu_drvdata *drvdata, int port_num);
+
#endif
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 4b40b692be4d..6ad09995ba87 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -293,7 +293,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
return -EFAULT;
}
- *ppos += actual;
+ if (!tmc_etr_update_buf_node_pos(drvdata, actual))
+ *ppos += actual;
dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
return actual;
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 2b26ce6455a7..e78f8891f11e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -1168,6 +1168,9 @@ static int tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
return rc;
}
+/* Assumes a single CTCU instance per system, as on all current Qualcomm SoCs. */
+static const struct tmc_sysfs_ops *byte_cntr_sysfs_ops;
+
/*
* Return the available trace data in the buffer (starts at etr_buf->offset,
* limited by etr_buf->len) from @pos, with a maximum limit of @len,
@@ -1178,23 +1181,39 @@ static int tmc_etr_enable_hw(struct tmc_drvdata *drvdata,
* We are protected here by drvdata->reading != 0, which ensures the
* sysfs_buf stays alive.
*/
-ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
- loff_t pos, size_t len, char **bufpp)
+ssize_t tmc_etr_read_sysfs_buf(struct etr_buf *sysfs_buf, loff_t pos,
+ size_t len, char **bufpp)
{
s64 offset;
ssize_t actual = len;
- struct etr_buf *etr_buf = drvdata->sysfs_buf;
- if (pos + actual > etr_buf->len)
- actual = etr_buf->len - pos;
+ if (pos + actual > sysfs_buf->len)
+ actual = sysfs_buf->len - pos;
if (actual <= 0)
return actual;
/* Compute the offset from which we read the data */
- offset = etr_buf->offset + pos;
- if (offset >= etr_buf->size)
- offset -= etr_buf->size;
- return tmc_etr_buf_get_data(etr_buf, offset, actual, bufpp);
+ offset = sysfs_buf->offset + pos;
+ if (offset >= sysfs_buf->size)
+ offset -= sysfs_buf->size;
+ return tmc_etr_buf_get_data(sysfs_buf, offset, actual, bufpp);
+}
+EXPORT_SYMBOL_GPL(tmc_etr_read_sysfs_buf);
+
+ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
+ loff_t pos, size_t len, char **bufpp)
+{
+ ssize_t ret;
+ const struct tmc_sysfs_ops *byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
+
+ if (byte_cntr_ops) {
+ ret = byte_cntr_ops->get_trace_data(drvdata, pos, len, bufpp);
+ /* Return the filled buffer */
+ if (ret > 0 || ret == -ENOMEM)
+ return ret;
+ }
+
+ return tmc_etr_read_sysfs_buf(drvdata->sysfs_buf, pos, len, bufpp);
}
static struct etr_buf *
@@ -1248,6 +1267,39 @@ static void __tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
}
+static void tmc_etr_reset_sysfs_buf(struct tmc_drvdata *drvdata)
+{
+ u32 sts;
+
+ CS_UNLOCK(drvdata->base);
+ tmc_write_rrp(drvdata, drvdata->sysfs_buf->hwaddr);
+ tmc_write_rwp(drvdata, drvdata->sysfs_buf->hwaddr);
+ sts = readl_relaxed(drvdata->base + TMC_STS) & ~TMC_STS_FULL;
+ writel_relaxed(sts, drvdata->base + TMC_STS);
+ CS_LOCK(drvdata->base);
+}
+
+/**
+ * tmc_etr_enable_disable_hw - enable/disable the ETR hw.
+ * @drvdata: drvdata of the TMC device.
+ * @enable: indicates enable/disable.
+ */
+void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&drvdata->spinlock, flags);
+ if (enable) {
+ tmc_etr_reset_sysfs_buf(drvdata);
+ __tmc_etr_enable_hw(drvdata);
+ } else {
+ __tmc_etr_disable_hw(drvdata);
+ }
+
+ raw_spin_unlock_irqrestore(&drvdata->spinlock, flags);
+}
+EXPORT_SYMBOL_GPL(tmc_etr_enable_disable_hw);
+
void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
{
__tmc_etr_disable_hw(drvdata);
@@ -2068,15 +2120,54 @@ int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes)
}
EXPORT_SYMBOL_GPL(tmc_create_etr_buf_list);
+void tmc_etr_set_byte_cntr_sysfs_ops(const struct tmc_sysfs_ops *sysfs_ops)
+{
+ WRITE_ONCE(byte_cntr_sysfs_ops, sysfs_ops);
+}
+EXPORT_SYMBOL_GPL(tmc_etr_set_byte_cntr_sysfs_ops);
+
+void tmc_etr_reset_byte_cntr_sysfs_ops(void)
+{
+ WRITE_ONCE(byte_cntr_sysfs_ops, NULL);
+}
+EXPORT_SYMBOL_GPL(tmc_etr_reset_byte_cntr_sysfs_ops);
+
+bool tmc_etr_update_buf_node_pos(struct tmc_drvdata *drvdata, ssize_t size)
+{
+ struct etr_buf_node *nd, *next;
+
+ if (drvdata->config_type != TMC_CONFIG_TYPE_ETR)
+ return false;
+
+ list_for_each_entry_safe(nd, next, &drvdata->etr_buf_list, link) {
+ if (nd && nd->reading) {
+ nd->pos += size;
+ return true;
+ }
+ }
+
+ return false;
+}
+
int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
{
int ret = 0;
unsigned long flags;
+ const struct tmc_sysfs_ops *byte_cntr_ops;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
return -EINVAL;
+ byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
+ if (byte_cntr_ops) {
+ ret = byte_cntr_ops->read_prepare(drvdata);
+ if (!ret || ret == -EBUSY)
+ return ret;
+
+ ret = 0;
+ }
+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
if (drvdata->reading) {
ret = -EBUSY;
@@ -2108,11 +2199,17 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
{
unsigned long flags;
struct etr_buf *sysfs_buf = NULL;
+ const struct tmc_sysfs_ops *byte_cntr_ops;
/* config types are set a boot time and never change */
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
return -EINVAL;
+ byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
+ if (byte_cntr_ops)
+ if (!byte_cntr_ops->read_unprepare(drvdata))
+ return 0;
+
raw_spin_lock_irqsave(&drvdata->spinlock, flags);
/* RE-enable the TMC if need be */
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index fbb015079872..a15e2f93f16a 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -211,12 +211,15 @@ struct tmc_resrv_buf {
/**
* @sysfs_buf: Allocated sysfs_buf.
* @is_free: Indicates whether the buffer is free to choose.
+ * @reading: Indicates byte_cntr is reading the buffer attached to
+ * the node.
* @pos: Offset to the start of the buffer.
* @link: list_head of the node.
*/
struct etr_buf_node {
struct etr_buf *sysfs_buf;
bool is_free;
+ bool reading;
loff_t pos;
struct list_head link;
};
@@ -480,5 +483,11 @@ struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
extern const struct attribute_group coresight_etr_group;
void tmc_clean_etr_buf_list(struct tmc_drvdata *drvdata);
int tmc_create_etr_buf_list(struct tmc_drvdata *drvdata, int num_nodes);
+void tmc_etr_set_byte_cntr_sysfs_ops(const struct tmc_sysfs_ops *sysfs_ops);
+void tmc_etr_reset_byte_cntr_sysfs_ops(void);
+void tmc_etr_enable_disable_hw(struct tmc_drvdata *drvdata, bool enable);
+bool tmc_etr_update_buf_node_pos(struct tmc_drvdata *drvdata, ssize_t size);
+ssize_t tmc_etr_read_sysfs_buf(struct etr_buf *sysfs_buf, loff_t pos,
+ size_t len, char **bufpp);
#endif
--
2.34.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox