Skip to contentSkip to conversation

Add the Lantiq PEF2256 audio support

PATCH Superseded Herve Codina 4 participants 36 messages Mar 28, 2023 – Apr 13, 2023

Subsystems (4)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v5 cover Add the Lantiq PEF2256 audio support

Hi,

This series adds support for audio using the Lantiq PEF2256 framer.

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

The first part of this series (patches 1 to 3) adds the Lantiq PEF2256 driver core.
The second part (patch 4) adds the audio support using the Lantiq PEF2256 driver core.
The last patch adds myself as the PEF2256 maintainer.

The consumer/provider relation between the codec and the driver core allows to use the PEF2256 framer for other purpose than audio support.

Compared to the previous iteration
https://lore.kernel.org/linux-kernel/[email protected]/
This v5 series mainly:
- Fixes the binding

Best regards,
Herve Codina

Changes v4 -> v5
- Patch 1
Fix 'additionalProperties' and 'unevaluatedProperties' positions Fix sub-nodes names suffixes

Changes v3 -> v4
- Patch 1
Merge the codec sub-node description.
Move the 'allOf' property after the 'required' property. Rework the example to be more complete.

- Patches 2 and 5
Drop of_match_ptr()

- Patch 2
Add 'depends on OF' as pinconf_generic_dt_node_to_map_pin() needs OF support to be compiled (error raised by the kernel test robot).

- Patch 4
Remove patch (merged in patch 1)

Changes v2 -> v3
- Patch 1
Remove unneeded 'allOf' and quotes.
Add several 'additionalProperties: false'
Fix example (node name, interrupts and reg properties) Replace the lantiq,sysclk-rate-hz property by sclkr and sclkx clocks. Define 'lantiq,frame-format' property in top level.
Move to MFD

- Patch 2
Fix some #define.
Compact the register accessor helpers.
Rework pef2256_get_version().
Merge v1.2 and v2.x GCM setup functions into one pef2256_setup_gcm(). Update comments, avoid duplicates and change some conditionals. Remove the carrier spinlock and use atomic_t.
Make exported symbol consistent and use EXPORT_SYMBOL_GPL. Remove the no more needed pef2256_get_byphandle() and devm_pef2256_get_byphandle().
Replace the lantiq,sysclk-rate-hz property by sclkr and sclkx clocks. Move to MFD

- Patch 4
Remove, merged with patch 7

- Patch 4 (patch 5 in v2)
Update title and description.
Remove incorrect SPI reference.
Remove the 'lantiq,pef2256' phandle.
Fix commit log

- Patch 5 (patch 6 in v2)
Remove devm_pef2256_get_byphandle().
Fix commit log

- Patch 6 (patch 7 in v2)
Merge v2 patch 4. One entry only for PEF2256

Changes v1 -> v2
- Patch 2
Remove duplicate const qualifiers.
Add HAS_IOMEM as a dependency

- Patch 3
Fix a "Block quote ends without a blank line; unexpected unindent" syntax issue.

Herve Codina (5):
dt-bindings: mfd: Add the Lantiq PEF2256 E1/T1/J1 framer
mfd: Add support for the Lantiq PEF2256 framer
Documentation: sysfs: Document the Lantiq PEF2256 sysfs entry
ASoC: codecs: Add support for the Lantiq PEF2256 codec
MAINTAINERS: Add the Lantiq PEF2256 driver entry

 .../sysfs-bus-platform-devices-pef2256        |   12 +
 .../bindings/mfd/lantiq,pef2256.yaml          |  267 ++++
 MAINTAINERS                                   |    9 +
 drivers/mfd/Kconfig                           |   17 +
 drivers/mfd/Makefile                          |    1 +
 drivers/mfd/pef2256.c                         | 1355 +++++++++++++++++
 include/linux/mfd/pef2256.h                   |   28 +
 sound/soc/codecs/Kconfig                      |   14 +
 sound/soc/codecs/Makefile                     |    2 +
 sound/soc/codecs/pef2256-codec.c              |  390 +++++
 10 files changed, 2095 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256
 create mode 100644 Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h
 create mode 100644 sound/soc/codecs/pef2256-codec.c
Signature · 1 line
2.39.2
#1 lore raw

PATCH v5 1/5 dt-bindings: mfd: Add the Lantiq PEF2256 E1/T1/J1 framer

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

---
 .../bindings/mfd/lantiq,pef2256.yaml          | 267 ++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml
Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml new file +267 -0
new file mode 100644
index 000000000000..7bc29e93cbc6
@@ -0,0 +1,267 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/lantiq,pef2256.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Lantiq PEF2256
+
+maintainers:
+  - Herve Codina <[email protected]>
+
+description:
+  The Lantiq PEF2256, also known as Infineon PEF2256 or FALC56, is a framer and
+  line interface component designed to fulfill all required interfacing between
+  an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.
+
+properties:
+  compatible:
+    items:
+      - const: lantiq,pef2256
+      - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Master clock
+      - description: Receive System Clock
+      - description: Transmit System Clock
+
+  clock-names:
+    items:
+      - const: mclk
+      - const: sclkr
+      - const: sclkx
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    description:
+      GPIO used to reset the device.
+    maxItems: 1
+
+  pinctrl:
+    $ref: /schemas/pinctrl/pinctrl.yaml#
+    additionalProperties: false
+
+    patternProperties:
+      '-pins$':
+        type: object
+        $ref: /schemas/pinctrl/pincfg-node.yaml#
+        additionalProperties: false
+
+        properties:
+          pins:
+            enum: [ RPA, RPB, RPC, RPD, XPA, XPB, XPC, XPD ]
+
+          function:
+            enum: [ SYPR, RFM, RFMB, RSIGM, RSIG, DLR, FREEZE, RFSP, LOS,
+                    SYPX, XFMS, XSIG, TCLK, XMFB, XSIGM, DLX, XCLK, XLT,
+                    GPI, GPOH, GPOL ]
+
+        required:
+          - pins
+          - function
+
+  lantiq,line-interface:
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [e1, t1j1]
+    default: e1
+    description: |
+      The line interface type
+        - e1: E1 line
+        - t1j1: T1/J1 line
+
+  lantiq,frame-format:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      The line interface frame format.
+
+  lantiq,data-rate-bps:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [2048000, 4096000, 8192000, 16384000]
+    default: 2048000
+    description:
+      Data rate (bit per seconds) on the system highway.
+
+  lantiq,clock-falling-edge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Data is sent on falling edge of the clock (and received on the rising
+      edge). If 'clock-falling-edge' is not present, data is sent on the
+      rising edge (and received on the falling edge).
+
+  lantiq,channel-phase:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2, 3, 4, 5, 6, 7]
+    default: 0
+    description:
+      The pef2256 delivers a full frame (32 8bit time-slots in E1 and 24 8bit
+      time-slots 8 8bit signaling in E1/J1) every 125us. This lead to a data
+      rate of 2048000 bit/s. When lantiq,data-rate-bps is more than 2048000
+      bit/s, the data (all 32 8bit) present in the frame are interleave with
+      unused time-slots. The lantiq,channel-phase property allows to set the
+      correct alignment of the interleave mechanism.
+      For instance, suppose lantiq,data-rate-bps = 8192000 (ie 4*2048000), and
+      lantiq,channel-phase = 2, the interleave schema with unused time-slots
+      (nu) and used time-slots (XX) for TSi is
+        nu nu XX nu nu nu XX nu nu nu XX nu
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+      With lantiq,data-rate-bps = 8192000, and lantiq,channel-phase = 1, the
+      interleave schema is
+        nu XX nu nu nu XX nu nu nu XX nu nu
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+      With lantiq,data-rate-bps = 4096000 (ie 2*2048000), and
+      lantiq,channel-phase = 1, the interleave schema is
+        nu    XX    nu    XX    nu    XX
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+
+  lantiq,subordinate:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      If present, the pef2256 works in subordinate mode. In this mode it
+      synchronizes on line interface clock signals. Otherwise, it synchronizes
+      on internal clocks.
+
+patternProperties:
+  '^codec(-([0-9]|[1-2][0-9]|3[0-1]))?$':
+    type: object
+    $ref: /schemas/sound/dai-common.yaml
+    unevaluatedProperties: false
+    description:
+      Codec provided by the pef2256. This codec allows to use some of the PCM
+      system highway time-slots as audio channels to transport audio data over
+      the E1/T1/J1 lines.
+      The time-slots used by the codec must be set and so, the properties
+      'dai-tdm-slot-num', 'dai-tdm-slot-width', 'dai-tdm-slot-tx-mask' and
+      'dai-tdm-slot-rx-mask' must be present in the sound card node for
+      sub-nodes that involve the codec. The codec uses 8bit time-slots.
+      'dai-tdm-tdm-slot-with' must be set to 8.
+      The tx and rx masks define the pef2256 time-slots assigned to the codec.
+
+    properties:
+      compatible:
+        const: lantiq,pef2256-codec
+
+      '#sound-dai-cells':
+        const: 0
+
+    required:
+      - compatible
+      - '#sound-dai-cells'
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+allOf:
+  - if:
+      properties:
+        lantiq,line-interface:
+          contains:
+            const: e1
+    then:
+      properties:
+        lantiq,frame-format:
+          enum: [doubleframe, crc4-multiframe, auto-multiframe]
+          default: doubleframe
+          description: |
+            The E1 line interface frame format
+              - doubleframe: Doubleframe format
+              - crc4-multiframe: CRC4 multiframe format
+              - auto-multiframe: CRC4 multiframe format with interworking
+                                 capabilities (ITU-T G.706 Annex B)
+
+    else:
+      # T1/J1 line
+      properties:
+        lantiq,frame-format:
+          enum: [4frame, 12frame, 24frame, 72frame]
+          default: 12frame
+          description: |
+            The T1/J1 line interface frame format
+              - 4frame: 4-frame multiframe format (F4)
+              - 12frame: 12-frame multiframe format (F12, D3/4)
+              - 24frame: 24-frame multiframe format (ESF)
+              - 72frame: 72-frame multiframe format (F72, remote switch mode)
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    framer@2000000 {
+      compatible = "lantiq,pef2256", "simple-mfd";
+      reg = <0x2000000 0x100>;
+      interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+      interrupt-parent = <&intc>;
+      clocks = <&clk_mclk>, <&clk_sclkr>, <&clk_sclkx>;
+      clock-names = "mclk", "sclkr", "sclkx";
+      reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+      lantiq,data-rate-bps = <4096000>;
+
+      pinctrl {
+        pef2256_rpa_sypr: rpa-pins {
+          pins = "RPA";
+          function = "SYPR";
+        };
+        pef2256_xpa_sypx: xpa-pins {
+          pins = "XPA";
+          function = "SYPX";
+        };
+      };
+
+      pef2256_codec0: codec-0 {
+        compatible = "lantiq,pef2256-codec";
+        #sound-dai-cells = <0>;
+        sound-name-prefix = "PEF2256_0";
+      };
+
+      pef2256_codec1: codec-1 {
+        compatible = "lantiq,pef2256-codec";
+        #sound-dai-cells = <0>;
+        sound-name-prefix = "PEF2256_1";
+      };
+    };
+
+    sound {
+      compatible = "simple-audio-card";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      simple-audio-card,dai-link@0 { /* CPU DAI1 - pef2256 codec 1 */
+        reg = <0>;
+        cpu {
+          sound-dai = <&cpu_dai1>;
+        };
+        codec {
+          sound-dai = <&pef2256_codec0>;
+          dai-tdm-slot-num = <4>;
+          dai-tdm-slot-width = <8>;
+          /* TS 1, 2, 3, 4 */
+          dai-tdm-slot-tx-mask = <0 1 1 1 1>;
+          dai-tdm-slot-rx-mask = <0 1 1 1 1>;
+        };
+      };
+      simple-audio-card,dai-link@1 { /* CPU DAI2 - pef2256 codec 2 */
+        reg = <1>;
+        cpu {
+          sound-dai = <&cpu_dai2>;
+        };
+        codec {
+          sound-dai = <&pef2256_codec1>;
+          dai-tdm-slot-num = <4>;
+          dai-tdm-slot-width = <8>;
+          /* TS 5, 6, 7, 8 */
+          dai-tdm-slot-tx-mask = <0 0 0 0 0 1 1 1 1>;
+          dai-tdm-slot-rx-mask = <0 0 0 0 0 1 1 1 1>;
+        };
+      };
+    };
Signature · 1 line
2.39.2
Reviewed-by on v5 1/5
#2 lore raw

Re: [PATCH v5 1/5] dt-bindings: mfd: Add the Lantiq PEF2256 E1/T1/J1 framer

Quoted 8 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

---
 .../bindings/mfd/lantiq,pef2256.yaml          | 267 ++++++++++++++++++
 1 file changed, 267 insertions(+)

Best regards,
Krzysztof

#3 lore raw

PATCH v5 2/5 mfd: Add support for the Lantiq PEF2256 framer

In reply to Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

---
 drivers/mfd/Kconfig         |   17 +
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/pef2256.c       | 1355 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/pef2256.h |   28 +
 4 files changed, 1401 insertions(+)
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h
drivers/mfd/Kconfig +17 -0
index fcc141e067b9..74c3750d21e4 100644
@@ -1063,6 +1063,23 @@ config PCF50633_GPIO
 	  Say yes here if you want to include support GPIO for pins on
 	  the PCF50633 chip.
 
+config MFD_PEF2256
+	tristate "Lantiq PEF2256 (FALC56) framer"
+	depends on OF
+	select PINCTRL
+	select PINMUX
+	select GENERIC_PINCONF
+	help
+	  This option enables support for the Lantiq PEF2256 framer, also known
+	  as FALC56. This framer and its line interface component is designed
+	  to fulfill all required interfacing between analog E1/T1/J1 lines and
+	  the digital PCM system highway.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pef2256.
+
 config MFD_PM8XXX
 	tristate "Qualcomm PM8xxx PMIC chips driver"
 	depends on (ARM || HEXAGON || COMPILE_TEST)
drivers/mfd/Makefile +1 -0
index 2f6c89d1e277..b2bb6e6a141c 100644
@@ -195,6 +195,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-core.o
 
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
+obj-$(CONFIG_MFD_PEF2256)	+= pef2256.o
 obj-$(CONFIG_MFD_PM8XXX) 	+= qcom-pm8xxx.o ssbi.o
 obj-$(CONFIG_MFD_QCOM_RPM)	+= qcom_rpm.o
 obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
drivers/mfd/pef2256.c new file +1355 -0

1,355 lines not on this page · raw message

include/linux/mfd/pef2256.h new file +28 -0
new file mode 100644
index 000000000000..0c0afcefa3ef
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * PEF2256 management
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina <[email protected]>
+ */
+#ifndef __PEF2256_H__
+#define __PEF2256_H__
+
+#include <linux/types.h>
+
+struct pef2256;
+struct notifier_block;
+
+enum pef2256_event {
+	PEF2256_EVENT_CARRIER, /* Carrier state changed */
+};
+
+/* The nb.notifier_call function registered must not sleep */
+int pef2256_register_event_notifier(struct pef2256 *pef2256, struct notifier_block *nb);
+int pef2256_unregister_event_notifier(struct pef2256 *pef2256, struct notifier_block *nb);
+
+/* Retrieve carrier state. true: carrier on, false: carrier off */
+bool pef2256_get_carrier(struct pef2256 *pef2256);
+
+#endif /* __PEF2256_H__ */
Signature · 1 line
2.39.2
maintainer
#4 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

My suggestion to you:

* Split this up into components that fit functional subsystems
* Run checkpatch.pl
* Remove all of the debug prints
* Move all of the defines out to a header file
* Be more verbose in your documentation / comments
* Consider using simple-mfd to probe child devices.

Quoted 9 lines
---
 drivers/mfd/Kconfig         |   17 +
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/pef2256.c       | 1355 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/pef2256.h |   28 +
 4 files changed, 1401 insertions(+)
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h

--
Lee Jones [李琼斯]

#5 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 4 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 1 line

* Run checkpatch.pl

I did.

Quoted 1 line

* Remove all of the debug prints

I can do that in the next iteration if really needed.

Quoted 1 line

* Move all of the defines out to a header file

These defines are related to registers. As I don't want to share these registers, is it really necessary to use a header file for them ?

Quoted 1 line

* Be more verbose in your documentation / comments

I can improve the API documentation present in include/mfd/pef2256.h. Do you thing that is necessary ? Only a few devices will use this API.

Quoted 1 line

* Consider using simple-mfd to probe child devices.

I did.
The driver has (and needs to have) a compatible string.
Having this compatible string, sub-nodes are not automatically populated in the device tree. In order to have them populated and probed, the pef2256 probe function ends calling devm_of_platform_populate().

Best regards,
Hervé

Quoted 13 lines
Quoted 10 lines
---
 drivers/mfd/Kconfig         |   17 +
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/pef2256.c       | 1355 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/pef2256.h |   28 +
 4 files changed, 1401 insertions(+)
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h  

--
Lee Jones [李琼斯]

#6 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Quoted 8 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

... and other style issues:

CHECK: Please don't use multiple blank lines
CHECK: spaces preferred around that '+' (ctx:VxV)
CHECK: Alignment should match open parenthesis
CHECK: Macro argument reuse '_groups' - possible side-effects?
CHECK: usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst
CHECK: spaces preferred around that '/' (ctx:VxV)

Quoted 7 lines
Quoted 2 lines

* Remove all of the debug prints

I can do that in the next iteration if really needed.

Quoted 1 line

* Move all of the defines out to a header file

Quoted 8 lines

These defines are related to registers. As I don't want to share these registers, is it really necessary to use a header file for them ?

Quoted 1 line

* Be more verbose in your documentation / comments

I can improve the API documentation present in include/mfd/pef2256.h. Do you thing that is necessary ? Only a few devices will use this API.

Krzysztof

#7 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 3 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt. The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI. These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.
The switch to MFD was probably not the best thing to do.

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Quoted 6 lines
Quoted 6 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

I ran checkpatch.pl, not checkpatch.pl --strict.

The spaces related the #define can be seen on many other drivers.

#define FOO_REG_BAR 0x10
#define FOO_REG_BAR_BIT0 BIT(0)
#define FOO_REG_BAR_BIT4 BIT(4)

The first line is the register offset and the other lines (indented) are the bits description related to this register.

Quoted 10 lines

... and other style issues:

CHECK: Please don't use multiple blank lines
CHECK: spaces preferred around that '+' (ctx:VxV)
CHECK: Alignment should match open parenthesis
CHECK: Macro argument reuse '_groups' - possible side-effects?
CHECK: usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst
CHECK: spaces preferred around that '/' (ctx:VxV)

I will have a look and fix them in the next iteration.

Quoted 12 lines
Quoted 12 lines
Quoted 4 lines

* Remove all of the debug prints

I can do that in the next iteration if really needed.

Quoted 1 line

* Move all of the defines out to a header file

These defines are related to registers. As I don't want to share these registers, is it really necessary to use a header file for them ?

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

* Be more verbose in your documentation / comments

I can improve the API documentation present in include/mfd/pef2256.h. Do you thing that is necessary ? Only a few devices will use this API.

Krzysztof

Best regards,
Hervé

#8 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Quoted 18 lines
Quoted 8 lines
Quoted 8 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

I ran checkpatch.pl, not checkpatch.pl --strict.

Quoted 8 lines

The spaces related the #define can be seen on many other drivers.

#define FOO_REG_BAR 0x10
#define FOO_REG_BAR_BIT0 BIT(0)
#define FOO_REG_BAR_BIT4 BIT(4)

The first line is the register offset and the other lines (indented) are the bits description related to this register.

I don't think we have such convention in general and argument that some drivers do it in some subsystems is never a good argument. If they also misspell things or use Hungarian notation, shall we do the same?

Although maybe it is fine for Lee. I find it unreadable.

git grep '#define \+[A-Z]' | wc -l
73889
git grep '#define [A-Z]' | wc -l
3996054

In MFD there is only one driver doing this.

Most of other cases are net and gpu.

Best regards,
Krzysztof

#9 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 81 lines · On Fri, 31 Mar 2023 15:44:19 +0200 Krzysztof Kozlowski…
Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Quoted 8 lines

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Just to be clear on that point, I do not want to avoid any reviews and Lee's reviews are fully welcome.

I just misunderstood. I thought the issue was that the pef2256 MFD driver has an internal setup() and that the 'function' provided were not independent (they share the pef2256 API).
My first feeling was that it was expected a kind of 'empty' driver for the pef2256 MFD driver. The pef2256 driver cannot be empty. That's why I talk about misc.

Related to pinctrl, the probe() orders need to be controlled but that would not be an issue if I move the pinctrl part to pinctrl. I would like also to avoid exporting all registers. Only the pinctrl part needs to access registers and it needs to access a few of them.

Is there a way to restrict the registers available from a child ?

Best regards,
Hervé

Quoted 47 lines
Quoted 19 lines
Quoted 9 lines
Quoted 9 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

I ran checkpatch.pl, not checkpatch.pl --strict.

Quoted 8 lines

The spaces related the #define can be seen on many other drivers.

#define FOO_REG_BAR 0x10
#define FOO_REG_BAR_BIT0 BIT(0)
#define FOO_REG_BAR_BIT4 BIT(4)

The first line is the register offset and the other lines (indented) are the bits description related to this register.

I don't think we have such convention in general and argument that some drivers do it in some subsystems is never a good argument. If they also misspell things or use Hungarian notation, shall we do the same?

Although maybe it is fine for Lee. I find it unreadable.

git grep '#define \+[A-Z]' | wc -l
73889
git grep '#define [A-Z]' | wc -l
3996054

In MFD there is only one driver doing this.

Most of other cases are net and gpu.

Best regards,
Krzysztof

maintainer
#10 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 93 lines · Herve Codina
Quoted 81 lines · On Fri, 31 Mar 2023 15:44:19 +0200 Krzysztof Kozlowski…
Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Quoted 8 lines

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Quoted 8 lines

Just to be clear on that point, I do not want to avoid any reviews and Lee's reviews are fully welcome.

I just misunderstood. I thought the issue was that the pef2256 MFD driver has an internal setup() and that the 'function' provided were not independent (they share the pef2256 API).
My first feeling was that it was expected a kind of 'empty' driver for the pef2256 MFD driver. The pef2256 driver cannot be empty. That's why I talk about misc.

It can be empty. That's what simple-mfd is for. :)

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

--
Lee Jones [李琼斯]

#11 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Hi Lee,

Quoted 104 lines · On Mon, 3 Apr 2023 15:28:22 +0100 Lee Jones <[email protected]> wrote:
Quoted 93 lines · Herve Codina
Quoted 81 lines · On Fri, 31 Mar 2023 15:44:19 +0200 Krzysztof Kozlowski…
Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Quoted 8 lines

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Quoted 8 lines

Just to be clear on that point, I do not want to avoid any reviews and Lee's reviews are fully welcome.

I just misunderstood. I thought the issue was that the pef2256 MFD driver has an internal setup() and that the 'function' provided were not independent (they share the pef2256 API).
My first feeling was that it was expected a kind of 'empty' driver for the pef2256 MFD driver. The pef2256 driver cannot be empty. That's why I talk about misc.

Quoted 9 lines

It can be empty. That's what simple-mfd is for. :)

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

I am confused and I am not really sure to understand where to put my driver.

The core pef2256.c needs to:
1) setup the pef2256
2) add the children

To add the children it calls devm_of_platform_populate() to add the audio parts as several audio children can be available with the same compatible string.

I plan to move the pinctrl part to the pinctrl subsystem. With this done, the core pef2256.c will probably add the children using:
- a mfd_cell for the pinctrl part
- devm_of_platform_populate() for the audio children

The setup (E1 lines and TDM configuration) still needs to be done by the core pef2256.c. Moving this part only to Misc will break the hierarchy. The audio children depends on the core pef2256.c as this one do the setup. Having in the audio children and the part that do the setup in same hierarchy level is not correct. Audio children should be children of the part that do the setup.

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

Best regards,
Hervé

Signature · 3 lines
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
#12 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 30 lines · Herve Codina
Quoted 7 lines

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

I am confused and I am not really sure to understand where to put my driver.

The core pef2256.c needs to:
1) setup the pef2256
2) add the children

To add the children it calls devm_of_platform_populate() to add the audio parts as several audio children can be available with the same compatible string.

I plan to move the pinctrl part to the pinctrl subsystem. With this done, the core pef2256.c will probably add the children using:
- a mfd_cell for the pinctrl part
- devm_of_platform_populate() for the audio children

The setup (E1 lines and TDM configuration) still needs to be done by the core pef2256.c. Moving this part only to Misc will break the hierarchy. The audio children depends on the core pef2256.c as this one do the setup. Having in the audio children and the part that do the setup in same hierarchy level is not correct. Audio children should be children of the part that do the setup.

Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

Best regards,
Krzysztof

#13 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 38 lines · On Tue, 4 Apr 2023 09:23:36 +0200 Krzysztof Kozlowski…
Quoted 37 lines · Herve Codina
Quoted 7 lines

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

I am confused and I am not really sure to understand where to put my driver.

The core pef2256.c needs to:
1) setup the pef2256
2) add the children

To add the children it calls devm_of_platform_populate() to add the audio parts as several audio children can be available with the same compatible string.

I plan to move the pinctrl part to the pinctrl subsystem. With this done, the core pef2256.c will probably add the children using:
- a mfd_cell for the pinctrl part
- devm_of_platform_populate() for the audio children

The setup (E1 lines and TDM configuration) still needs to be done by the core pef2256.c. Moving this part only to Misc will break the hierarchy. The audio children depends on the core pef2256.c as this one do the setup. Having in the audio children and the part that do the setup in same hierarchy level is not correct. Audio children should be children of the part that do the setup.

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Quoted 4 lines
Quoted 1 line

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);

	pef2256_setup(pef2256);

	devm_of_platform_populate(pef2256->dev);
	
	return 0;

}

Quoted 4 lines

Best regards,
Krzysztof

Signature · 3 lines
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
#14 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 54 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);
Quoted 7 lines
	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Best regards,
Krzysztof

maintainer
#15 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 59 lines · Krzysztof Kozlowski
Quoted 57 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);
Quoted 7 lines
Quoted 4 lines
	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

--
Lee Jones [李琼斯]

#16 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);  
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

Best regards,
Hervé

#17 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Hi Lee,

Quoted 90 lines · On Wed, 5 Apr 2023 18:00:23 +0200 Herve Codina <[email protected]> wrote:

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);    
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Quoted 5 lines

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

I looked deeper for using mfd_add_devices() only and found an issue (related to my use-case).

mfd_add_devices() calls mfd_add_device() and in this function we have:
---- 8< ----

	if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
		for_each_child_of_node(parent->of_node, np) {
			if (of_device_is_compatible(np, cell->of_compatible)) {
				/* Ignore 'disabled' devices error free */
				if (!of_device_is_available(np)) {
					of_node_put(np);
					ret = 0;
					goto fail_alias;
				}

				ret = mfd_match_of_node_to_dev(pdev, np, cell);
				if (ret == -EAGAIN)
					continue;
				of_node_put(np);
				if (ret)
					goto fail_alias;

				break;
			}
		}

		if (!pdev->dev.of_node)
			pr_warn("%s: Failed to locate of_node [id: %d]\n",
				cell->name, platform_id);
	}

---- 8< ----

My issue is related to the loop.
The loop is aborted if the device is not available (typically 'Disabled' in the DT node).

My full pef2256 node can have several pef2256 audio subnodes with compatible set to "lantiq,pef2256-codec" and some of them can have 'status = "Disabled";' As soon as one device (with my expected compatible) is found 'Disabled', there is no way to look at other children.

Having 'continue' in case of device not available in the loop to look at the next child will change the behavior of mfd_add_device().
Do you think that looking at next child if we find a 'not available' child can be correct for mfd_add_device() ?
This probably will have impacts on other MFD drivers.

Best regards,
Hervé

maintainer
#18 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 142 lines · Herve Codina

Hi Lee,

Quoted 90 lines · On Wed, 5 Apr 2023 18:00:23 +0200 Herve Codina <[email protected]> wrote:

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Quoted 5 lines

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

I looked deeper for using mfd_add_devices() only and found an issue (related to my use-case).

mfd_add_devices() calls mfd_add_device() and in this function we have:
---- 8< ----

	if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
		for_each_child_of_node(parent->of_node, np) {
			if (of_device_is_compatible(np, cell->of_compatible)) {
				/* Ignore 'disabled' devices error free */
				if (!of_device_is_available(np)) {
					of_node_put(np);
					ret = 0;
					goto fail_alias;
				}

				ret = mfd_match_of_node_to_dev(pdev, np, cell);
				if (ret == -EAGAIN)
					continue;
				of_node_put(np);
				if (ret)
					goto fail_alias;

				break;
			}
		}

		if (!pdev->dev.of_node)
			pr_warn("%s: Failed to locate of_node [id: %d]\n",
				cell->name, platform_id);
	}

---- 8< ----

My issue is related to the loop.
The loop is aborted if the device is not available (typically 'Disabled' in the DT node).

My full pef2256 node can have several pef2256 audio subnodes with compatible set to "lantiq,pef2256-codec" and some of them can have 'status = "Disabled";' As soon as one device (with my expected compatible) is found 'Disabled', there is no way to look at other children.

Quoted 5 lines

Having 'continue' in case of device not available in the loop to look at the next child will change the behavior of mfd_add_device().
Do you think that looking at next child if we find a 'not available' child can be correct for mfd_add_device() ?
This probably will have impacts on other MFD drivers.

Looks like a bug. Encountering one disabled cell should not prevent the others from registering IMHO.

--
Lee Jones [李琼斯]

#19 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

Quoted 144 lines · On Wed, 12 Apr 2023 10:59:18 +0100 Lee Jones <[email protected]> wrote:
Quoted 142 lines · Herve Codina

Hi Lee,

Quoted 90 lines · On Wed, 5 Apr 2023 18:00:23 +0200 Herve Codina <[email protected]> wrote:

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);  
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Quoted 5 lines

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

I looked deeper for using mfd_add_devices() only and found an issue (related to my use-case).

mfd_add_devices() calls mfd_add_device() and in this function we have:
---- 8< ----

	if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
		for_each_child_of_node(parent->of_node, np) {
			if (of_device_is_compatible(np, cell->of_compatible)) {
				/* Ignore 'disabled' devices error free */
				if (!of_device_is_available(np)) {
					of_node_put(np);
					ret = 0;
					goto fail_alias;
				}

				ret = mfd_match_of_node_to_dev(pdev, np, cell);
				if (ret == -EAGAIN)
					continue;
				of_node_put(np);
				if (ret)
					goto fail_alias;

				break;
			}
		}

		if (!pdev->dev.of_node)
			pr_warn("%s: Failed to locate of_node [id: %d]\n",
				cell->name, platform_id);
	}

---- 8< ----

My issue is related to the loop.
The loop is aborted if the device is not available (typically 'Disabled' in the DT node).

My full pef2256 node can have several pef2256 audio subnodes with compatible set to "lantiq,pef2256-codec" and some of them can have 'status = "Disabled";' As soon as one device (with my expected compatible) is found 'Disabled', there is no way to look at other children.

Quoted 9 lines
Quoted 5 lines

Having 'continue' in case of device not available in the loop to look at the next child will change the behavior of mfd_add_device().
Do you think that looking at next child if we find a 'not available' child can be correct for mfd_add_device() ?
This probably will have impacts on other MFD drivers.

Looks like a bug. Encountering one disabled cell should not prevent the others from registering IMHO.

Thanks for your confirmation.
I will propose a fix in the next iteration of this series.

Regards,
Hervé

#20 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Lee Jones
Quoted 144 lines · On Wed, 12 Apr 2023 10:59:18 +0100 Lee Jones <[email protected]> wrote:
Quoted 142 lines · Herve Codina

Hi Lee,

Quoted 90 lines · On Wed, 5 Apr 2023 18:00:23 +0200 Herve Codina <[email protected]> wrote:

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);  
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Quoted 5 lines

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

I looked deeper for using mfd_add_devices() only and found an issue (related to my use-case).

mfd_add_devices() calls mfd_add_device() and in this function we have:
---- 8< ----

	if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
		for_each_child_of_node(parent->of_node, np) {
			if (of_device_is_compatible(np, cell->of_compatible)) {
				/* Ignore 'disabled' devices error free */
				if (!of_device_is_available(np)) {
					of_node_put(np);
					ret = 0;
					goto fail_alias;
				}

				ret = mfd_match_of_node_to_dev(pdev, np, cell);
				if (ret == -EAGAIN)
					continue;
				of_node_put(np);
				if (ret)
					goto fail_alias;

				break;
			}
		}

		if (!pdev->dev.of_node)
			pr_warn("%s: Failed to locate of_node [id: %d]\n",
				cell->name, platform_id);
	}

---- 8< ----

My issue is related to the loop.
The loop is aborted if the device is not available (typically 'Disabled' in the DT node).

My full pef2256 node can have several pef2256 audio subnodes with compatible set to "lantiq,pef2256-codec" and some of them can have 'status = "Disabled";' As soon as one device (with my expected compatible) is found 'Disabled', there is no way to look at other children.

Quoted 9 lines
Quoted 5 lines

Having 'continue' in case of device not available in the loop to look at the next child will change the behavior of mfd_add_device().
Do you think that looking at next child if we find a 'not available' child can be correct for mfd_add_device() ?
This probably will have impacts on other MFD drivers.

Looks like a bug. Encountering one disabled cell should not prevent the others from registering IMHO.

Thanks for your confirmation.
I will propose a fix in the next iteration of this series.

Regards,
Hervé

#21 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Herve Codina

Hi Lee,

Quoted 90 lines · On Wed, 5 Apr 2023 18:00:23 +0200 Herve Codina <[email protected]> wrote:

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);    
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Quoted 5 lines

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

I looked deeper for using mfd_add_devices() only and found an issue (related to my use-case).

mfd_add_devices() calls mfd_add_device() and in this function we have:
---- 8< ----

	if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
		for_each_child_of_node(parent->of_node, np) {
			if (of_device_is_compatible(np, cell->of_compatible)) {
				/* Ignore 'disabled' devices error free */
				if (!of_device_is_available(np)) {
					of_node_put(np);
					ret = 0;
					goto fail_alias;
				}

				ret = mfd_match_of_node_to_dev(pdev, np, cell);
				if (ret == -EAGAIN)
					continue;
				of_node_put(np);
				if (ret)
					goto fail_alias;

				break;
			}
		}

		if (!pdev->dev.of_node)
			pr_warn("%s: Failed to locate of_node [id: %d]\n",
				cell->name, platform_id);
	}

---- 8< ----

My issue is related to the loop.
The loop is aborted if the device is not available (typically 'Disabled' in the DT node).

My full pef2256 node can have several pef2256 audio subnodes with compatible set to "lantiq,pef2256-codec" and some of them can have 'status = "Disabled";' As soon as one device (with my expected compatible) is found 'Disabled', there is no way to look at other children.

Having 'continue' in case of device not available in the loop to look at the next child will change the behavior of mfd_add_device().
Do you think that looking at next child if we find a 'not available' child can be correct for mfd_add_device() ?
This probably will have impacts on other MFD drivers.

Best regards,
Hervé

#22 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Lee Jones

Hi Lee,

Quoted 66 lines · On Wed, 5 Apr 2023 14:54:50 +0100 Lee Jones <[email protected]> wrote:
Quoted 64 lines · Krzysztof Kozlowski
Quoted 61 lines · Herve Codina
Quoted 11 lines
Quoted 8 lines

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);  
Quoted 8 lines
Quoted 2 lines

Wait, now you use MFD framework, so the driver is suitable for MFD. Before there was nothing like that in your code.

Agree, the above is suitable for MFD, since it does all the things I said your last one did not. You *can* also use of_platform_populate() here, since you are *also* requesting and initialising shared resources. You cannot do *both* however.

Thanks for having confirmed that this driver can be a MFD driver.

Related to of_platform_populate() / mfd_add_devices(), I wanted to use both because:
- the pinctrl part does not have (and does not need to have) a specific node with a specific compatible property. In order to instantiate the related driver mfd_add_devices() is the only way I know.
- the audio component nodes have a compatible string and several components (ie several nodes) can be present. of_platform_populate() call seems the simple way to instantiate them.

Is there a way to use mfd_add_devices() in this case without the need to count the audio component nodes in order to allocate as much mfd_cell as nodes having a matching compatible property ? Is there an other API to do it ?

Best regards,
Hervé

#23 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Krzysztof Kozlowski
Quoted 38 lines · On Tue, 4 Apr 2023 09:23:36 +0200 Krzysztof Kozlowski…
Quoted 37 lines · Herve Codina
Quoted 7 lines

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

I am confused and I am not really sure to understand where to put my driver.

The core pef2256.c needs to:
1) setup the pef2256
2) add the children

To add the children it calls devm_of_platform_populate() to add the audio parts as several audio children can be available with the same compatible string.

I plan to move the pinctrl part to the pinctrl subsystem. With this done, the core pef2256.c will probably add the children using:
- a mfd_cell for the pinctrl part
- devm_of_platform_populate() for the audio children

The setup (E1 lines and TDM configuration) still needs to be done by the core pef2256.c. Moving this part only to Misc will break the hierarchy. The audio children depends on the core pef2256.c as this one do the setup. Having in the audio children and the part that do the setup in same hierarchy level is not correct. Audio children should be children of the part that do the setup.

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Quoted 4 lines
Quoted 1 line

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

You do not use MFD here, so why do you want to keep it in MFD? If you disagree, please tell me where is the MFD code in your patch?

I don't want to absolutely use MFD.
I just want to put my driver somewhere and I don't know the right location between MFD and Misc.

Basically, the driver needs to do (little simplified and error path removed):

  static const struct mfd_cell pef2256_devs[] = {
  	{ .name = "lantiq-pef2256-pinctrl", },
  };

static int pef2256_probe(struct platform_device *pdev)

  {
	struct pef2256 *pef2256;
	void __iomem *iomem;
	int ret;
	int irq;

	pef2256 = devm_kzalloc(&pdev->dev, sizeof(*pef2256), GFP_KERNEL);
	if (!pef2256)
		return -ENOMEM;

	pef2256->dev = &pdev->dev;

	iomem = devm_platform_ioremap_resource(pdev, 0);

	pef2256->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
						&pef2256_regmap_config);

	pef2256->mclk = devm_clk_get_enabled(&pdev->dev, "mclk");
	pef2256->sclkr = devm_clk_get_enabled(&pdev->dev, "sclkr");
	pef2256->sclkx = devm_clk_get_enabled(&pdev->dev, "sclkx");

	pef2256->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
	if (pef2256->reset_gpio) {
		gpiod_set_value_cansleep(pef2256->reset_gpio, 1);
		udelay(10);
		gpiod_set_value_cansleep(pef2256->reset_gpio, 0);
		udelay(10);
	}

	pef2556_of_parse(pef2256, np);

	irq = platform_get_irq(pdev, 0);
	ret = devm_request_irq(pef2256->dev, irq, pef2256_irq_handler, 0, "pef2256", pef2256);

	platform_set_drvdata(pdev, pef2256);

	mfd_add_devices(pef2256->dev, PLATFORM_DEVID_NONE, pef2256_devs,
	      		ARRAY_SIZE(pef2256_devs), NULL, 0, NULL);

	pef2256_setup(pef2256);

	devm_of_platform_populate(pef2256->dev);
	
	return 0;

}

Quoted 4 lines

Best regards,
Krzysztof

Signature · 3 lines
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
#24 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Lee Jones

Hi Lee,

Quoted 104 lines · On Mon, 3 Apr 2023 15:28:22 +0100 Lee Jones <[email protected]> wrote:
Quoted 93 lines · Herve Codina
Quoted 81 lines · On Fri, 31 Mar 2023 15:44:19 +0200 Krzysztof Kozlowski…
Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Quoted 8 lines

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Quoted 8 lines

Just to be clear on that point, I do not want to avoid any reviews and Lee's reviews are fully welcome.

I just misunderstood. I thought the issue was that the pef2256 MFD driver has an internal setup() and that the 'function' provided were not independent (they share the pef2256 API).
My first feeling was that it was expected a kind of 'empty' driver for the pef2256 MFD driver. The pef2256 driver cannot be empty. That's why I talk about misc.

Quoted 9 lines

It can be empty. That's what simple-mfd is for. :)

I suggest that none of this (besides the child registration, which is achieved by a simple OF API call in this case) has anything to do with MFD. We are not requesting and initialising shared resources and we are not using the MFD API to register children. The pin control functionality clearly needs moving to Pinctrl and the rest, if you cannot find a suitable home for it *may be* suitable for Misc.

I am confused and I am not really sure to understand where to put my driver.

The core pef2256.c needs to:
1) setup the pef2256
2) add the children

To add the children it calls devm_of_platform_populate() to add the audio parts as several audio children can be available with the same compatible string.

I plan to move the pinctrl part to the pinctrl subsystem. With this done, the core pef2256.c will probably add the children using:
- a mfd_cell for the pinctrl part
- devm_of_platform_populate() for the audio children

The setup (E1 lines and TDM configuration) still needs to be done by the core pef2256.c. Moving this part only to Misc will break the hierarchy. The audio children depends on the core pef2256.c as this one do the setup. Having in the audio children and the part that do the setup in same hierarchy level is not correct. Audio children should be children of the part that do the setup.

So, the structure I have in mind:
- pef2256.c (MFD)
implement and do the setup at probe()
Add the children at probe():
- pef2256-pinctrl (pinctrl) added using mfd_add_devices()
- pef2256-codec (ASoC codec) added using devm_of_platform_populate()

Lee, with this in mind, can the core pef2256.c be a MFD driver ?

Best regards,
Hervé

Signature · 3 lines
Hervé Codina, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
#25 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Krzysztof Kozlowski
Quoted 81 lines · On Fri, 31 Mar 2023 15:44:19 +0200 Krzysztof Kozlowski…
Quoted 43 lines · Herve Codina

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 1 line
Quoted 6 lines
Quoted 2 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt.

Just like all PMICs...

Quoted 2 lines

The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI.

Just like in all other cases...

Quoted 2 lines

These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

Just like in all other cases, so I really do not see here anything special.

Quoted 3 lines

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

Why? So far everything is exactly the same.

Quoted 4 lines

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.

Your DT bindings and nodes are not related to driver design. It does not matter for Devicetree if you put it to misc or MFD.

It does not matter for driver whether you call it in Devicetree foo or bar.

Quoted 1 line

The switch to MFD was probably not the best thing to do.

Quoted 8 lines

Maybe, but your existing arguments are not really related...

Quoted 3 lines

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Why? What would it solve? You want to stuff pinctrl driver to misc, to avoid Lee's review? No. Pinctrl goes to pinctrl. Not to misc. Not to MFD.

Just to be clear on that point, I do not want to avoid any reviews and Lee's reviews are fully welcome.

I just misunderstood. I thought the issue was that the pef2256 MFD driver has an internal setup() and that the 'function' provided were not independent (they share the pef2256 API).
My first feeling was that it was expected a kind of 'empty' driver for the pef2256 MFD driver. The pef2256 driver cannot be empty. That's why I talk about misc.

Related to pinctrl, the probe() orders need to be controlled but that would not be an issue if I move the pinctrl part to pinctrl. I would like also to avoid exporting all registers. Only the pinctrl part needs to access registers and it needs to access a few of them.

Is there a way to restrict the registers available from a child ?

Best regards,
Hervé

Quoted 47 lines
Quoted 19 lines
Quoted 9 lines
Quoted 9 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

I ran checkpatch.pl, not checkpatch.pl --strict.

Quoted 8 lines

The spaces related the #define can be seen on many other drivers.

#define FOO_REG_BAR 0x10
#define FOO_REG_BAR_BIT0 BIT(0)
#define FOO_REG_BAR_BIT4 BIT(4)

The first line is the register offset and the other lines (indented) are the bits description related to this register.

I don't think we have such convention in general and argument that some drivers do it in some subsystems is never a good argument. If they also misspell things or use Hungarian notation, shall we do the same?

Although maybe it is fine for Lee. I find it unreadable.

git grep '#define \+[A-Z]' | wc -l
73889
git grep '#define [A-Z]' | wc -l
3996054

In MFD there is only one driver doing this.

Most of other cases are net and gpu.

Best regards,
Krzysztof

#26 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Krzysztof Kozlowski

Hi Krzysztof, Lee

Quoted 28 lines · On Fri, 31 Mar 2023 11:13:30 +0200 Krzysztof Kozlowski…
Quoted 18 lines · Herve Codina

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Quoted 5 lines

The amount of defines and huge functions like pef2256_setup_e1() contradict it.

Even the pef2256_setup_e1() really does not follow Linux coding style - you know the size requirement, right?

I know that pef2256_setup_e1() is quite big and I will look at a way to split it in a consistent way.

Quoted 3 lines

pef2256_get_groups_count, struct pinmux_ops and others - this is pinctrl, not MFD! They cannot be in MFD driver.

Maybe the issue is that MFD was not a good choice.
The "function" provided are not independent of each other.
The "main" driver (pef2256.c) needs to do the setup and handle the interrupt. The "function" provided are some glues in order to be used in some sub-systems such as audio. Indeed, ASoC needs a codec DAI to be connected to a CPU DAI. These "functions" need to be started (ie probe()) after the pef2256 setup was done. So a start (probe()) order relationship is needed.

If a MFD driver needs independent children to handle independent functions, the pef2256 does not fit well as a MFD driver.

I switched from misc to MFD just to handle child DT nodes instead of having phandles. Using child DT nodes instead of phandles is really a good thing and need to be kept.
The switch to MFD was probably not the best thing to do.

What do you think if I switched back the pef2256 "main" driver (pef2256.c) to misc ?

Quoted 6 lines
Quoted 6 lines

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 7 lines
Quoted 3 lines
Quoted 1 line

* Run checkpatch.pl

I did.

There are tons of weird indentation,e.g.:
+#define PEF2256_2X_PC_XPC_XLT (0x8 << 0)
^^^^ there is only one space after #define

I ran checkpatch.pl, not checkpatch.pl --strict.

The spaces related the #define can be seen on many other drivers.

#define FOO_REG_BAR 0x10
#define FOO_REG_BAR_BIT0 BIT(0)
#define FOO_REG_BAR_BIT4 BIT(4)

The first line is the register offset and the other lines (indented) are the bits description related to this register.

Quoted 10 lines

... and other style issues:

CHECK: Please don't use multiple blank lines
CHECK: spaces preferred around that '+' (ctx:VxV)
CHECK: Alignment should match open parenthesis
CHECK: Macro argument reuse '_groups' - possible side-effects?
CHECK: usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst
CHECK: spaces preferred around that '/' (ctx:VxV)

I will have a look and fix them in the next iteration.

Quoted 12 lines
Quoted 12 lines
Quoted 4 lines

* Remove all of the debug prints

I can do that in the next iteration if really needed.

Quoted 1 line

* Move all of the defines out to a header file

These defines are related to registers. As I don't want to share these registers, is it really necessary to use a header file for them ?

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

* Be more verbose in your documentation / comments

I can improve the API documentation present in include/mfd/pef2256.h. Do you thing that is necessary ? Only a few devices will use this API.

Krzysztof

Best regards,
Hervé

#27 lore raw

Re: [PATCH v5 2/5] mfd: Add support for the Lantiq PEF2256 framer

In reply to Lee Jones

Hi Lee,

Quoted 9 lines · On Thu, 30 Mar 2023 17:05:10 +0100 Lee Jones <[email protected]> wrote:
Quoted 3 lines · Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

My goodness!

It's been a long time since I've seen anything quite like this.

Yes, old things but working on recent kernel.

Quoted 4 lines

My suggestion to you:

* Split this up into components that fit functional subsystems

It is done. The audio part is present in ASoC subsystem (path 5 in this series). pinctrl function is implemented in this driver and, as I don't want to share registers, I would prefer to keep this function inside this driver.

Also, I sent a RFC related to HDLC and PHY. In this RFC, the pef2256 is considered as a PHY and handled in the PHY subsystem.
https://lore.kernel.org/linux-kernel/[email protected]/

Quoted 1 line

* Run checkpatch.pl

I did.

Quoted 1 line

* Remove all of the debug prints

I can do that in the next iteration if really needed.

Quoted 1 line

* Move all of the defines out to a header file

These defines are related to registers. As I don't want to share these registers, is it really necessary to use a header file for them ?

Quoted 1 line

* Be more verbose in your documentation / comments

I can improve the API documentation present in include/mfd/pef2256.h. Do you thing that is necessary ? Only a few devices will use this API.

Quoted 1 line

* Consider using simple-mfd to probe child devices.

I did.
The driver has (and needs to have) a compatible string.
Having this compatible string, sub-nodes are not automatically populated in the device tree. In order to have them populated and probed, the pef2256 probe function ends calling devm_of_platform_populate().

Best regards,
Hervé

Quoted 13 lines
Quoted 10 lines
---
 drivers/mfd/Kconfig         |   17 +
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/pef2256.c       | 1355 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/pef2256.h |   28 +
 4 files changed, 1401 insertions(+)
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h  

--
Lee Jones [李琼斯]

#28 lore raw

PATCH v5 3/5 Documentation: sysfs: Document the Lantiq PEF2256 sysfs entry

In reply to Herve Codina

Document the "subordinate" sysfs attribute exposed by the PEF2256 driver.

---
 .../ABI/testing/sysfs-bus-platform-devices-pef2256   | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256
Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256 new file +12 -0
new file mode 100644
index 000000000000..95ba1ae55daf
@@ -0,0 +1,12 @@
+What:		/sys/bus/platform/devices/*.pef2256/subordinate
+KernelVersion:	6.4
+Contact:	Herve Codina <[email protected]>
+Description:
+		(RW) Controls whether the PEF2256 works as subordinate or main
+		device mode.
+
+		- 0: main device mode
+		- 1: subordinate mode
+
+		In subordinate device mode it synchronizes on line interface
+		clock signals. Otherwise, it synchronizes on internal clocks.
Signature · 1 line
2.39.2
#29 lore raw

PATCH v5 4/5 ASoC: codecs: Add support for the Lantiq PEF2256 codec

In reply to Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

The codec support allows to use some of the PCM system highway time-slots as audio channels to transport audio data over the E1/T1/J1 lines. It provides also line carrier detection events reported through the ALSA jack detection feature.

---
 sound/soc/codecs/Kconfig         |  14 ++
 sound/soc/codecs/Makefile        |   2 +
 sound/soc/codecs/pef2256-codec.c | 390 +++++++++++++++++++++++++++++++
 3 files changed, 406 insertions(+)
 create mode 100644 sound/soc/codecs/pef2256-codec.c
sound/soc/codecs/Kconfig +14 -0
index 0be061953e9a..4f78da914fc7 100644
@@ -168,6 +168,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_PCM512x_I2C
 	imply SND_SOC_PCM512x_SPI
 	imply SND_SOC_PEB2466
+	imply SND_SOC_PEF2256
 	imply SND_SOC_RK3328
 	imply SND_SOC_RK817
 	imply SND_SOC_RT274
@@ -1252,6 +1253,19 @@ config SND_SOC_PEB2466
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-soc-peb2466.
 
+config SND_SOC_PEF2256
+	tristate "Lantiq PEF2256 codec"
+	depends on MFD_PEF2256
+	help
+	  Enable support for the Lantiq PEF2256 (FALC56) codec.
+	  The PEF2256 is a framer and line interface between analog E1/T1/J1
+	  line and a digital PCM bus.
+	  This codec allows to use some of the time slots available on the
+	  PEF2256 PCM bus to transport some audio data.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-soc-pef2256.
+
 config SND_SOC_RK3328
 	tristate "Rockchip RK3328 audio CODEC"
 	select REGMAP_MMIO
sound/soc/codecs/Makefile +2 -0
index 20b388b77f1f..11bd66d46f7b 100644
@@ -188,6 +188,7 @@ snd-soc-pcm512x-objs := pcm512x.o
 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 snd-soc-peb2466-objs := peb2466.o
+snd-soc-pef2256-objs := pef2256-codec.o
 snd-soc-rk3328-objs := rk3328_codec.o
 snd-soc-rk817-objs := rk817_codec.o
 snd-soc-rl6231-objs := rl6231.o
@@ -551,6 +552,7 @@ obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 obj-$(CONFIG_SND_SOC_PEB2466)	+= snd-soc-peb2466.o
+obj-$(CONFIG_SND_SOC_PEF2256)	+= snd-soc-pef2256.o
 obj-$(CONFIG_SND_SOC_RK3328)	+= snd-soc-rk3328.o
 obj-$(CONFIG_SND_SOC_RK817)	+= snd-soc-rk817.o
 obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
sound/soc/codecs/pef2256-codec.c new file +390 -0

390 lines not on this page · raw message

Signature · 1 line
2.39.2
#30 lore raw

PATCH v5 5/5 MAINTAINERS: Add the Lantiq PEF2256 driver entry

In reply to Herve Codina

After contributing the driver, add myself as the maintainer for the Lantiq PEF2256 driver.

---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)
MAINTAINERS +9 -0
index fcb69242cd19..a17c85648f6f 100644
@@ -11651,6 +11651,15 @@ S:	Maintained
 F:	arch/mips/lantiq
 F:	drivers/soc/lantiq
 
+LANTIQ PEF2256 DRIVER
+M:	Herve Codina <[email protected]>
+S:	Maintained
+F:	Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256
+F:	Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml
+F:	drivers/mfd/pef2256.c
+F:	include/linux/mfd/pef2256.h
+F:	sound/soc/codecs/pef2256-codec.c
+
 LASI 53c700 driver for PARISC
 M:	"James E.J. Bottomley" <[email protected]>
 L:	[email protected]
Signature · 1 line
2.39.2
#31 lore raw

PATCH v5 1/5 dt-bindings: mfd: Add the Lantiq PEF2256 E1/T1/J1 framer

In reply to Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

---
 .../bindings/mfd/lantiq,pef2256.yaml          | 267 ++++++++++++++++++
 1 file changed, 267 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml
Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml new file +267 -0
new file mode 100644
index 000000000000..7bc29e93cbc6
@@ -0,0 +1,267 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/lantiq,pef2256.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Lantiq PEF2256
+
+maintainers:
+  - Herve Codina <[email protected]>
+
+description:
+  The Lantiq PEF2256, also known as Infineon PEF2256 or FALC56, is a framer and
+  line interface component designed to fulfill all required interfacing between
+  an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.
+
+properties:
+  compatible:
+    items:
+      - const: lantiq,pef2256
+      - const: simple-mfd
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Master clock
+      - description: Receive System Clock
+      - description: Transmit System Clock
+
+  clock-names:
+    items:
+      - const: mclk
+      - const: sclkr
+      - const: sclkx
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    description:
+      GPIO used to reset the device.
+    maxItems: 1
+
+  pinctrl:
+    $ref: /schemas/pinctrl/pinctrl.yaml#
+    additionalProperties: false
+
+    patternProperties:
+      '-pins$':
+        type: object
+        $ref: /schemas/pinctrl/pincfg-node.yaml#
+        additionalProperties: false
+
+        properties:
+          pins:
+            enum: [ RPA, RPB, RPC, RPD, XPA, XPB, XPC, XPD ]
+
+          function:
+            enum: [ SYPR, RFM, RFMB, RSIGM, RSIG, DLR, FREEZE, RFSP, LOS,
+                    SYPX, XFMS, XSIG, TCLK, XMFB, XSIGM, DLX, XCLK, XLT,
+                    GPI, GPOH, GPOL ]
+
+        required:
+          - pins
+          - function
+
+  lantiq,line-interface:
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [e1, t1j1]
+    default: e1
+    description: |
+      The line interface type
+        - e1: E1 line
+        - t1j1: T1/J1 line
+
+  lantiq,frame-format:
+    $ref: /schemas/types.yaml#/definitions/string
+    description:
+      The line interface frame format.
+
+  lantiq,data-rate-bps:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [2048000, 4096000, 8192000, 16384000]
+    default: 2048000
+    description:
+      Data rate (bit per seconds) on the system highway.
+
+  lantiq,clock-falling-edge:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      Data is sent on falling edge of the clock (and received on the rising
+      edge). If 'clock-falling-edge' is not present, data is sent on the
+      rising edge (and received on the falling edge).
+
+  lantiq,channel-phase:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2, 3, 4, 5, 6, 7]
+    default: 0
+    description:
+      The pef2256 delivers a full frame (32 8bit time-slots in E1 and 24 8bit
+      time-slots 8 8bit signaling in E1/J1) every 125us. This lead to a data
+      rate of 2048000 bit/s. When lantiq,data-rate-bps is more than 2048000
+      bit/s, the data (all 32 8bit) present in the frame are interleave with
+      unused time-slots. The lantiq,channel-phase property allows to set the
+      correct alignment of the interleave mechanism.
+      For instance, suppose lantiq,data-rate-bps = 8192000 (ie 4*2048000), and
+      lantiq,channel-phase = 2, the interleave schema with unused time-slots
+      (nu) and used time-slots (XX) for TSi is
+        nu nu XX nu nu nu XX nu nu nu XX nu
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+      With lantiq,data-rate-bps = 8192000, and lantiq,channel-phase = 1, the
+      interleave schema is
+        nu XX nu nu nu XX nu nu nu XX nu nu
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+      With lantiq,data-rate-bps = 4096000 (ie 2*2048000), and
+      lantiq,channel-phase = 1, the interleave schema is
+        nu    XX    nu    XX    nu    XX
+        <-- TSi --> <- TSi+1 -> <- TSi+2 ->
+
+  lantiq,subordinate:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      If present, the pef2256 works in subordinate mode. In this mode it
+      synchronizes on line interface clock signals. Otherwise, it synchronizes
+      on internal clocks.
+
+patternProperties:
+  '^codec(-([0-9]|[1-2][0-9]|3[0-1]))?$':
+    type: object
+    $ref: /schemas/sound/dai-common.yaml
+    unevaluatedProperties: false
+    description:
+      Codec provided by the pef2256. This codec allows to use some of the PCM
+      system highway time-slots as audio channels to transport audio data over
+      the E1/T1/J1 lines.
+      The time-slots used by the codec must be set and so, the properties
+      'dai-tdm-slot-num', 'dai-tdm-slot-width', 'dai-tdm-slot-tx-mask' and
+      'dai-tdm-slot-rx-mask' must be present in the sound card node for
+      sub-nodes that involve the codec. The codec uses 8bit time-slots.
+      'dai-tdm-tdm-slot-with' must be set to 8.
+      The tx and rx masks define the pef2256 time-slots assigned to the codec.
+
+    properties:
+      compatible:
+        const: lantiq,pef2256-codec
+
+      '#sound-dai-cells':
+        const: 0
+
+    required:
+      - compatible
+      - '#sound-dai-cells'
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+allOf:
+  - if:
+      properties:
+        lantiq,line-interface:
+          contains:
+            const: e1
+    then:
+      properties:
+        lantiq,frame-format:
+          enum: [doubleframe, crc4-multiframe, auto-multiframe]
+          default: doubleframe
+          description: |
+            The E1 line interface frame format
+              - doubleframe: Doubleframe format
+              - crc4-multiframe: CRC4 multiframe format
+              - auto-multiframe: CRC4 multiframe format with interworking
+                                 capabilities (ITU-T G.706 Annex B)
+
+    else:
+      # T1/J1 line
+      properties:
+        lantiq,frame-format:
+          enum: [4frame, 12frame, 24frame, 72frame]
+          default: 12frame
+          description: |
+            The T1/J1 line interface frame format
+              - 4frame: 4-frame multiframe format (F4)
+              - 12frame: 12-frame multiframe format (F12, D3/4)
+              - 24frame: 24-frame multiframe format (ESF)
+              - 72frame: 72-frame multiframe format (F72, remote switch mode)
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    framer@2000000 {
+      compatible = "lantiq,pef2256", "simple-mfd";
+      reg = <0x2000000 0x100>;
+      interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+      interrupt-parent = <&intc>;
+      clocks = <&clk_mclk>, <&clk_sclkr>, <&clk_sclkx>;
+      clock-names = "mclk", "sclkr", "sclkx";
+      reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
+      lantiq,data-rate-bps = <4096000>;
+
+      pinctrl {
+        pef2256_rpa_sypr: rpa-pins {
+          pins = "RPA";
+          function = "SYPR";
+        };
+        pef2256_xpa_sypx: xpa-pins {
+          pins = "XPA";
+          function = "SYPX";
+        };
+      };
+
+      pef2256_codec0: codec-0 {
+        compatible = "lantiq,pef2256-codec";
+        #sound-dai-cells = <0>;
+        sound-name-prefix = "PEF2256_0";
+      };
+
+      pef2256_codec1: codec-1 {
+        compatible = "lantiq,pef2256-codec";
+        #sound-dai-cells = <0>;
+        sound-name-prefix = "PEF2256_1";
+      };
+    };
+
+    sound {
+      compatible = "simple-audio-card";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      simple-audio-card,dai-link@0 { /* CPU DAI1 - pef2256 codec 1 */
+        reg = <0>;
+        cpu {
+          sound-dai = <&cpu_dai1>;
+        };
+        codec {
+          sound-dai = <&pef2256_codec0>;
+          dai-tdm-slot-num = <4>;
+          dai-tdm-slot-width = <8>;
+          /* TS 1, 2, 3, 4 */
+          dai-tdm-slot-tx-mask = <0 1 1 1 1>;
+          dai-tdm-slot-rx-mask = <0 1 1 1 1>;
+        };
+      };
+      simple-audio-card,dai-link@1 { /* CPU DAI2 - pef2256 codec 2 */
+        reg = <1>;
+        cpu {
+          sound-dai = <&cpu_dai2>;
+        };
+        codec {
+          sound-dai = <&pef2256_codec1>;
+          dai-tdm-slot-num = <4>;
+          dai-tdm-slot-width = <8>;
+          /* TS 5, 6, 7, 8 */
+          dai-tdm-slot-tx-mask = <0 0 0 0 0 1 1 1 1>;
+          dai-tdm-slot-rx-mask = <0 0 0 0 0 1 1 1 1>;
+        };
+      };
+    };
Signature · 1 line
2.39.2
#32 lore raw

PATCH v5 2/5 mfd: Add support for the Lantiq PEF2256 framer

In reply to Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

---
 drivers/mfd/Kconfig         |   17 +
 drivers/mfd/Makefile        |    1 +
 drivers/mfd/pef2256.c       | 1355 +++++++++++++++++++++++++++++++++++
 include/linux/mfd/pef2256.h |   28 +
 4 files changed, 1401 insertions(+)
 create mode 100644 drivers/mfd/pef2256.c
 create mode 100644 include/linux/mfd/pef2256.h
drivers/mfd/Kconfig +17 -0
index fcc141e067b9..74c3750d21e4 100644
@@ -1063,6 +1063,23 @@ config PCF50633_GPIO
 	  Say yes here if you want to include support GPIO for pins on
 	  the PCF50633 chip.
 
+config MFD_PEF2256
+	tristate "Lantiq PEF2256 (FALC56) framer"
+	depends on OF
+	select PINCTRL
+	select PINMUX
+	select GENERIC_PINCONF
+	help
+	  This option enables support for the Lantiq PEF2256 framer, also known
+	  as FALC56. This framer and its line interface component is designed
+	  to fulfill all required interfacing between analog E1/T1/J1 lines and
+	  the digital PCM system highway.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pef2256.
+
 config MFD_PM8XXX
 	tristate "Qualcomm PM8xxx PMIC chips driver"
 	depends on (ARM || HEXAGON || COMPILE_TEST)
drivers/mfd/Makefile +1 -0
index 2f6c89d1e277..b2bb6e6a141c 100644
@@ -195,6 +195,7 @@ obj-$(CONFIG_MFD_SI476X_CORE)	+= si476x-core.o
 
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
+obj-$(CONFIG_MFD_PEF2256)	+= pef2256.o
 obj-$(CONFIG_MFD_PM8XXX) 	+= qcom-pm8xxx.o ssbi.o
 obj-$(CONFIG_MFD_QCOM_RPM)	+= qcom_rpm.o
 obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
drivers/mfd/pef2256.c new file +1355 -0

1,355 lines not on this page · raw message

include/linux/mfd/pef2256.h new file +28 -0
new file mode 100644
index 000000000000..0c0afcefa3ef
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * PEF2256 management
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina <[email protected]>
+ */
+#ifndef __PEF2256_H__
+#define __PEF2256_H__
+
+#include <linux/types.h>
+
+struct pef2256;
+struct notifier_block;
+
+enum pef2256_event {
+	PEF2256_EVENT_CARRIER, /* Carrier state changed */
+};
+
+/* The nb.notifier_call function registered must not sleep */
+int pef2256_register_event_notifier(struct pef2256 *pef2256, struct notifier_block *nb);
+int pef2256_unregister_event_notifier(struct pef2256 *pef2256, struct notifier_block *nb);
+
+/* Retrieve carrier state. true: carrier on, false: carrier off */
+bool pef2256_get_carrier(struct pef2256 *pef2256);
+
+#endif /* __PEF2256_H__ */
Signature · 1 line
2.39.2
#33 lore raw

PATCH v5 3/5 Documentation: sysfs: Document the Lantiq PEF2256 sysfs entry

In reply to Herve Codina

Document the "subordinate" sysfs attribute exposed by the PEF2256 driver.

---
 .../ABI/testing/sysfs-bus-platform-devices-pef2256   | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256
Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256 new file +12 -0
new file mode 100644
index 000000000000..95ba1ae55daf
@@ -0,0 +1,12 @@
+What:		/sys/bus/platform/devices/*.pef2256/subordinate
+KernelVersion:	6.4
+Contact:	Herve Codina <[email protected]>
+Description:
+		(RW) Controls whether the PEF2256 works as subordinate or main
+		device mode.
+
+		- 0: main device mode
+		- 1: subordinate mode
+
+		In subordinate device mode it synchronizes on line interface
+		clock signals. Otherwise, it synchronizes on internal clocks.
Signature · 1 line
2.39.2
#34 lore raw

PATCH v5 4/5 ASoC: codecs: Add support for the Lantiq PEF2256 codec

In reply to Herve Codina

The Lantiq PEF2256 is a framer and line interface component designed to fulfill all required interfacing between an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.

The codec support allows to use some of the PCM system highway time-slots as audio channels to transport audio data over the E1/T1/J1 lines. It provides also line carrier detection events reported through the ALSA jack detection feature.

---
 sound/soc/codecs/Kconfig         |  14 ++
 sound/soc/codecs/Makefile        |   2 +
 sound/soc/codecs/pef2256-codec.c | 390 +++++++++++++++++++++++++++++++
 3 files changed, 406 insertions(+)
 create mode 100644 sound/soc/codecs/pef2256-codec.c
sound/soc/codecs/Kconfig +14 -0
index 0be061953e9a..4f78da914fc7 100644
@@ -168,6 +168,7 @@ config SND_SOC_ALL_CODECS
 	imply SND_SOC_PCM512x_I2C
 	imply SND_SOC_PCM512x_SPI
 	imply SND_SOC_PEB2466
+	imply SND_SOC_PEF2256
 	imply SND_SOC_RK3328
 	imply SND_SOC_RK817
 	imply SND_SOC_RT274
@@ -1252,6 +1253,19 @@ config SND_SOC_PEB2466
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-soc-peb2466.
 
+config SND_SOC_PEF2256
+	tristate "Lantiq PEF2256 codec"
+	depends on MFD_PEF2256
+	help
+	  Enable support for the Lantiq PEF2256 (FALC56) codec.
+	  The PEF2256 is a framer and line interface between analog E1/T1/J1
+	  line and a digital PCM bus.
+	  This codec allows to use some of the time slots available on the
+	  PEF2256 PCM bus to transport some audio data.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-soc-pef2256.
+
 config SND_SOC_RK3328
 	tristate "Rockchip RK3328 audio CODEC"
 	select REGMAP_MMIO
sound/soc/codecs/Makefile +2 -0
index 20b388b77f1f..11bd66d46f7b 100644
@@ -188,6 +188,7 @@ snd-soc-pcm512x-objs := pcm512x.o
 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
 snd-soc-pcm512x-spi-objs := pcm512x-spi.o
 snd-soc-peb2466-objs := peb2466.o
+snd-soc-pef2256-objs := pef2256-codec.o
 snd-soc-rk3328-objs := rk3328_codec.o
 snd-soc-rk817-objs := rk817_codec.o
 snd-soc-rl6231-objs := rl6231.o
@@ -551,6 +552,7 @@ obj-$(CONFIG_SND_SOC_PCM512x)	+= snd-soc-pcm512x.o
 obj-$(CONFIG_SND_SOC_PCM512x_I2C)	+= snd-soc-pcm512x-i2c.o
 obj-$(CONFIG_SND_SOC_PCM512x_SPI)	+= snd-soc-pcm512x-spi.o
 obj-$(CONFIG_SND_SOC_PEB2466)	+= snd-soc-peb2466.o
+obj-$(CONFIG_SND_SOC_PEF2256)	+= snd-soc-pef2256.o
 obj-$(CONFIG_SND_SOC_RK3328)	+= snd-soc-rk3328.o
 obj-$(CONFIG_SND_SOC_RK817)	+= snd-soc-rk817.o
 obj-$(CONFIG_SND_SOC_RL6231)	+= snd-soc-rl6231.o
sound/soc/codecs/pef2256-codec.c new file +390 -0

390 lines not on this page · raw message

Signature · 1 line
2.39.2
#35 lore raw

PATCH v5 5/5 MAINTAINERS: Add the Lantiq PEF2256 driver entry

In reply to Herve Codina

After contributing the driver, add myself as the maintainer for the Lantiq PEF2256 driver.

---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)
MAINTAINERS +9 -0
index fcb69242cd19..a17c85648f6f 100644
@@ -11651,6 +11651,15 @@ S:	Maintained
 F:	arch/mips/lantiq
 F:	drivers/soc/lantiq
 
+LANTIQ PEF2256 DRIVER
+M:	Herve Codina <[email protected]>
+S:	Maintained
+F:	Documentation/ABI/testing/sysfs-bus-platform-devices-pef2256
+F:	Documentation/devicetree/bindings/mfd/lantiq,pef2256.yaml
+F:	drivers/mfd/pef2256.c
+F:	include/linux/mfd/pef2256.h
+F:	sound/soc/codecs/pef2256-codec.c
+
 LASI 53c700 driver for PARISC
 M:	"James E.J. Bottomley" <[email protected]>
 L:	[email protected]
Signature · 1 line
2.39.2