# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/simple-card.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Simple Audio Card Driver

maintainers:
  - Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

definitions:

  frame-master:
    description: Indicates dai-link frame master.
    $ref: /schemas/types.yaml#/definitions/phandle

  bitclock-master:
    description: Indicates dai-link bit clock master
    $ref: /schemas/types.yaml#/definitions/phandle

  frame-inversion:
    description: dai-link uses frame clock inversion
    $ref: /schemas/types.yaml#/definitions/flag

  bitclock-inversion:
    description: dai-link uses bit clock inversion
    $ref: /schemas/types.yaml#/definitions/flag

  dai-tdm-slot-num:
    description: see tdm-slot.txt.
    $ref: /schemas/types.yaml#/definitions/uint32

  dai-tdm-slot-width:
    description: see tdm-slot.txt.
    $ref: /schemas/types.yaml#/definitions/uint32

  system-clock-frequency:
    description: |
      If a clock is specified and a multiplication factor is given with
      mclk-fs, the clock will be set to the calculated mclk frequency
      when the stream starts.
    $ref: /schemas/types.yaml#/definitions/uint32

  system-clock-direction-out:
    description: |
      specifies clock direction as 'out' on initialization.
      It is useful for some aCPUs with fixed clocks.
    $ref: /schemas/types.yaml#/definitions/flag

  system-clock-fixed:
    description: |
      Specifies that the clock frequency should not be modified.
      Implied when system-clock-frequency is specified, but can be used when
      a clock is mapped to the device whose frequency cannot or should not be
      changed. When mclk-fs is also specified, this restricts the device to a
      single fixed sampling rate.
    $ref: /schemas/types.yaml#/definitions/flag

  mclk-fs:
    description: |
      Multiplication factor between stream rate and codec mclk.
      When defined, mclk-fs property defined in dai-link sub nodes are ignored.
    $ref: /schemas/types.yaml#/definitions/uint32

  aux-devs:
    description: |
      List of phandles pointing to auxiliary devices, such
      as amplifiers, to be added to the sound card.
    $ref: /schemas/types.yaml#/definitions/phandle-array

  convert-rate:
    description: CPU to Codec rate convert.
    $ref: /schemas/types.yaml#/definitions/uint32

  convert-channels:
    description: CPU to Codec rate channels.
    $ref: /schemas/types.yaml#/definitions/uint32

  prefix:
    description: device name prefix
    $ref: /schemas/types.yaml#/definitions/string

  label:
    maxItems: 1

  routing:
    description: |
      A list of the connections between audio components.
      Each entry is a pair of strings, the first being the
      connection's sink, the second being the connection's source.
    $ref: /schemas/types.yaml#/definitions/non-unique-string-array

  widgets:
    description: User specified audio sound widgets.
    $ref: /schemas/types.yaml#/definitions/non-unique-string-array

  pin-switches:
    description: the widget names for which pin switches must be created.
    $ref: /schemas/types.yaml#/definitions/string-array

  format:
    description: audio format.
    items:
      enum:
        - i2s
        - right_j
        - left_j
        - dsp_a
        - dsp_b
        - ac97
        - pdm
        - msb
        - lsb

  dai:
    type: object
    properties:
      sound-dai:
        maxItems: 1

      # common properties
      mclk-fs:
        $ref: "#/definitions/mclk-fs"
      prefix:
        $ref: "#/definitions/prefix"
      frame-inversion:
        $ref: "#/definitions/frame-inversion"
      bitclock-inversion:
        $ref: "#/definitions/bitclock-inversion"
      frame-master:
        $ref: /schemas/types.yaml#/definitions/flag
      bitclock-master:
        $ref: /schemas/types.yaml#/definitions/flag

      dai-tdm-slot-num:
        $ref: "#/definitions/dai-tdm-slot-num"
      dai-tdm-slot-width:
        $ref: "#/definitions/dai-tdm-slot-width"
      clocks:
        maxItems: 1
      system-clock-frequency:
        $ref: "#/definitions/system-clock-frequency"
      system-clock-direction-out:
        $ref: "#/definitions/system-clock-direction-out"
      system-clock-fixed:
        $ref: "#/definitions/system-clock-fixed"
    required:
      - sound-dai

  additional-devs:
    type: object
    description:
      Additional devices used by the simple audio card.
    patternProperties:
      '^iio-aux(-.+)?$':
        type: object
        $ref: audio-iio-aux.yaml#

properties:
  compatible:
    contains:
      enum:
        - simple-audio-card
        - simple-scu-audio-card

  "#address-cells":
    const: 1
  "#size-cells":
    const: 0

  label:
    $ref: "#/definitions/label"

  simple-audio-card,name:
    description: User specified audio sound card name.
    $ref: /schemas/types.yaml#/definitions/string

  simple-audio-card,widgets:
    $ref: "#/definitions/widgets"
  simple-audio-card,routing:
    $ref: "#/definitions/routing"

  # common properties
  simple-audio-card,frame-master:
    $ref: "#/definitions/frame-master"
  simple-audio-card,bitclock-master:
    $ref: "#/definitions/bitclock-master"
  simple-audio-card,frame-inversion:
    $ref: "#/definitions/frame-inversion"
  simple-audio-card,bitclock-inversion:
    $ref: "#/definitions/bitclock-inversion"
  simple-audio-card,format:
    $ref: "#/definitions/format"
  simple-audio-card,mclk-fs:
    $ref: "#/definitions/mclk-fs"
  simple-audio-card,aux-devs:
    $ref: "#/definitions/aux-devs"
  simple-audio-card,additional-devs:
    $ref: "#/definitions/additional-devs"
  simple-audio-card,convert-rate:
    $ref: "#/definitions/convert-rate"
  simple-audio-card,convert-channels:
    $ref: "#/definitions/convert-channels"
  simple-audio-card,prefix:
    $ref: "#/definitions/prefix"
  simple-audio-card,pin-switches:
    $ref: "#/definitions/pin-switches"
  simple-audio-card,hp-det-gpio:
    maxItems: 1
  simple-audio-card,mic-det-gpio:
    maxItems: 1

patternProperties:
  "^simple-audio-card,cpu(@[0-9a-f]+)?$":
    $ref: "#/definitions/dai"
  "^simple-audio-card,codec(@[0-9a-f]+)?$":
    $ref: "#/definitions/dai"
  "^simple-audio-card,plat(@[0-9a-f]+)?$":
    $ref: "#/definitions/dai"

  "^simple-audio-card,dai-link(@[0-9a-f]+)?$":
    description: |
      Container for dai-link level properties and the CPU and CODEC sub-nodes.
      This container may be omitted when the card has only one DAI link.
    type: object
    properties:
      reg:
        maxItems: 1

      "#address-cells":
        const: 1
      "#size-cells":
        const: 0
      # common properties
      frame-master:
        $ref: "#/definitions/frame-master"
      bitclock-master:
        $ref: "#/definitions/bitclock-master"
      frame-inversion:
        $ref: "#/definitions/frame-inversion"
      bitclock-inversion:
        $ref: "#/definitions/bitclock-inversion"
      format:
        $ref: "#/definitions/format"
      mclk-fs:
        $ref: "#/definitions/mclk-fs"
      aux-devs:
        $ref: "#/definitions/aux-devs"
      convert-rate:
        $ref: "#/definitions/convert-rate"
      convert-channels:
        $ref: "#/definitions/convert-channels"
      prefix:
        $ref: "#/definitions/prefix"
      pin-switches:
        $ref: "#/definitions/pin-switches"
      hp-det-gpio:
        maxItems: 1
      mic-det-gpio:
        maxItems: 1

    patternProperties:
      "^cpu(-[0-9]+)?$":
        $ref: "#/definitions/dai"
      "^codec(-[0-9]+)?$":
        $ref: "#/definitions/dai"
    additionalProperties: false

required:
  - compatible

additionalProperties: false

examples:
# --------------------
# single DAI link
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "VF610-Tower-Sound-Card";
        simple-audio-card,format = "left_j";
        simple-audio-card,bitclock-master = <&dailink0_master>;
        simple-audio-card,frame-master = <&dailink0_master>;
        simple-audio-card,widgets =
                "Microphone", "Microphone Jack",
                "Headphone", "Headphone Jack",
                "Speaker", "External Speaker";
        simple-audio-card,routing =
                "MIC_IN", "Microphone Jack",
                "Headphone Jack", "HP_OUT",
                "External Speaker", "LINE_OUT";

        simple-audio-card,cpu {
            sound-dai = <&sh_fsi2 0>;
        };

        dailink0_master: simple-audio-card,codec {
            sound-dai = <&ak4648>;
            clocks = <&osc>;
        };
    };

# --------------------
# Multi DAI links
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";
        simple-audio-card,name = "Cubox Audio";

        #address-cells = <1>;
        #size-cells = <0>;

        simple-audio-card,dai-link@0 {		/* I2S - HDMI */
            reg = <0>;
            format = "i2s";
            cpu {
                sound-dai = <&audio0>;
            };
            codec {
                sound-dai = <&tda998x0>;
            };
        };

        simple-audio-card,dai-link@1 {		/* S/PDIF - HDMI */
            reg = <1>;
            cpu {
                sound-dai = <&audio1>;
            };
            codec {
                sound-dai = <&tda998x1>;
            };
        };

        simple-audio-card,dai-link@2 {		/* S/PDIF - S/PDIF */
            reg = <2>;
            cpu {
                sound-dai = <&audio2>;
            };
            codec {
                sound-dai = <&spdif_codec>;
            };
        };
    };

# --------------------
# route audio from IMX6 SSI2 through TLV320DAC3100 codec
# through TPA6130A2 amplifier to headphones:
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";

        simple-audio-card,widgets =
            "Headphone", "Headphone Jack";
        simple-audio-card,routing =
            "Headphone Jack", "HPLEFT",
            "Headphone Jack", "HPRIGHT",
            "LEFTIN", "HPL",
            "RIGHTIN", "HPR";
        simple-audio-card,aux-devs = <&amp>;
        simple-audio-card,cpu {
            sound-dai = <&ssi2>;
        };
        simple-audio-card,codec {
            sound-dai = <&codec>;
            clocks = <&clocks>;
        };
    };

# --------------------
# route audio to/from a codec through an amplifier
# designed with a potentiometer driven by IIO:
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";

        simple-audio-card,aux-devs = <&amp_in>, <&amp_out>;
        simple-audio-card,routing =
            "CODEC LEFTIN", "AMP_IN LEFT OUT",
            "CODEC RIGHTIN", "AMP_IN RIGHT OUT",
            "AMP_OUT LEFT IN", "CODEC LEFTOUT",
            "AMP_OUT RIGHT IN", "CODEC RIGHTOUT";

        simple-audio-card,additional-devs {
            amp_out: iio-aux-out {
                compatible = "audio-iio-aux";
                io-channels = <&pot_out 0>, <&pot_out 1>;
                io-channel-names = "LEFT", "RIGHT";
                snd-control-invert-range = <1 1>;
                sound-name-prefix = "AMP_OUT";
            };

            amp_in: iio_aux-in {
                compatible = "audio-iio-aux";
                io-channels = <&pot_in 0>, <&pot_in 1>;
                io-channel-names = "LEFT", "RIGHT";
                sound-name-prefix = "AMP_IN";
            };
        };

        simple-audio-card,cpu {
            sound-dai = <&cpu>;
        };

        simple-audio-card,codec {
            sound-dai = <&codec>;
            clocks = <&clocks>;
        };
    };

# --------------------
# Sampling Rate Conversion
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";

        simple-audio-card,name = "rsnd-ak4643";
        simple-audio-card,format = "left_j";
        simple-audio-card,bitclock-master = <&sndcodec>;
        simple-audio-card,frame-master = <&sndcodec>;

        simple-audio-card,convert-rate = <48000>;

        simple-audio-card,prefix = "ak4642";
        simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
                                    "DAI0 Capture", "ak4642 Capture";

        sndcpu: simple-audio-card,cpu {
            sound-dai = <&rcar_sound>;
        };

        sndcodec: simple-audio-card,codec {
            sound-dai = <&ak4643>;
            system-clock-frequency = <11289600>;
        };
    };

# --------------------
# 2 CPU 1 Codec (Mixing)
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";
        #address-cells = <1>;
        #size-cells = <0>;

        simple-audio-card,name = "rsnd-ak4643";
        simple-audio-card,format = "left_j";
        simple-audio-card,bitclock-master = <&dpcmcpu>;
        simple-audio-card,frame-master = <&dpcmcpu>;

        simple-audio-card,convert-rate = <48000>;
        simple-audio-card,convert-channels = <2>;

        simple-audio-card,routing = "ak4642 Playback", "DAI0 Playback",
                                    "ak4642 Playback", "DAI1 Playback";

        dpcmcpu: simple-audio-card,cpu@0 {
            reg = <0>;
            sound-dai = <&rcar_sound 0>;
        };

        simple-audio-card,cpu@1 {
            reg = <1>;
            sound-dai = <&rcar_sound 1>;
        };

        simple-audio-card,codec {
            prefix = "ak4642";
            sound-dai = <&ak4643>;
            clocks = <&audio_clock>;
        };
    };

# --------------------
# Multi DAI links with DPCM:
#
# CPU0 ------ ak4613
# CPU1 ------ PCM3168A-p  /* DPCM 1ch/2ch */
# CPU2 --/                /* DPCM 3ch/4ch */
# CPU3 --/                /* DPCM 5ch/6ch */
# CPU4 --/                /* DPCM 7ch/8ch */
# CPU5 ------ PCM3168A-c
# --------------------
  - |
    sound {
        compatible = "simple-audio-card";
        #address-cells = <1>;
        #size-cells = <0>;

        simple-audio-card,routing =
            "pcm3168a Playback", "DAI1 Playback",
            "pcm3168a Playback", "DAI2 Playback",
            "pcm3168a Playback", "DAI3 Playback",
            "pcm3168a Playback", "DAI4 Playback";

        simple-audio-card,dai-link@0 {
            reg = <0>;
            format = "left_j";
            bitclock-master = <&sndcpu0>;
            frame-master = <&sndcpu0>;

            sndcpu0: cpu {
                sound-dai = <&rcar_sound 0>;
            };
            codec {
                sound-dai = <&ak4613>;
            };
        };

        simple-audio-card,dai-link@1 {
            reg = <1>;
            format = "i2s";
            bitclock-master = <&sndcpu1>;
            frame-master = <&sndcpu1>;

            convert-channels = <8>; /* TDM Split */

            sndcpu1: cpu-0 {
                sound-dai = <&rcar_sound 1>;
            };
            cpu-1 {
                sound-dai = <&rcar_sound 2>;
            };
            cpu-2 {
                sound-dai = <&rcar_sound 3>;
            };
            cpu-3 {
                sound-dai = <&rcar_sound 4>;
            };
            codec {
                mclk-fs = <512>;
                prefix = "pcm3168a";
                dai-tdm-slot-num = <8>;
                sound-dai = <&pcm3168a 0>;
            };
        };

        simple-audio-card,dai-link@2 {
            reg = <2>;
            format = "i2s";
            bitclock-master = <&sndcpu2>;
            frame-master = <&sndcpu2>;

            sndcpu2: cpu {
                sound-dai = <&rcar_sound 5>;
            };
            codec {
                mclk-fs = <512>;
                prefix = "pcm3168a";
                sound-dai = <&pcm3168a 1>;
            };
        };
    };