Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1629742 > unrolled thread

[PATCH v2 00/18] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs

Started byRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
First post2017-04-24 18:20 +0200
Last post2017-04-28 09:50 +0200
Articles 20 on this page of 21 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 00/18] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
    [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
      Re: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on  Cirrus Logic Madera codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-25 11:50 +0200
      Re: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on  Cirrus Logic Madera codecs Rob Herring <robh@kernel.org> - 2017-04-28 20:20 +0200
    [PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
      Re: [PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic  Madera codecs Rob Herring <robh@kernel.org> - 2017-04-28 20:10 +0200
    [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
      Re: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus  Logic Madera codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-25 11:40 +0200
      Re: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus  Logic Madera codecs Rob Herring <robh@kernel.org> - 2017-04-28 20:20 +0200
    [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
      Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-25 16:20 +0200
        Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera  class codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-25 16:50 +0200
          Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-28 09:50 +0200
      Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-28 09:50 +0200
    [PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
      Re: [PATCH v2 07/18] regulator: arizona-micsupp: Add support for  Cirrus Logic Madera codecs Rob Herring <robh@kernel.org> - 2017-04-28 20:10 +0200
    [PATCH v2 08/18] regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
    [PATCH v2 02/18] mfd: madera: Add common support for Cirrus Logic Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-24 18:20 +0200
    Re: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic  Madera codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-25 11:50 +0200
      Re: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic  Madera codecs Richard Fitzgerald <rf@opensource.wolfsonmicro.com> - 2017-04-25 12:30 +0200
    Re: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic  Madera codecs Linus Walleij <linus.walleij@linaro.org> - 2017-04-28 09:50 +0200

Page 1 of 2  [1] 2  Next page →


#1629742 — [PATCH v2 00/18] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 00/18] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs
Message-ID<tzOIO-JE-23@gated-at.bofh.it>
The Cirrus Logic CS47L35, CS47L85, CS47L90/91 codecs are complex audio SoC
devices. In addition to the core audio capability they have onboard GPIO,
regulators, DSPs and interrupt controller and a large register map space
accessed over SPI or I2C. This family of codecs is based around common IP
blocks and they are managed by a set of common drivers referred to as "Madera".

Summary of main changes since V1:
- dt bindings moved to separate patches
- pdata struct descriptions fixed to be kerneldoc format
- now re-uses the arizona micsupp and ldo1 regulators
- various fixes and improvements to the pinctrl driver
- gpio driver can now interoperate with the pinctrl driver
- some changes to the way Kconfig options are selected

Richard Fitzgerald (18):
  mfd: madera: Add register definitions for Cirrus Logic Madera codecs
  mfd: madera: Add common support for Cirrus Logic Madera codecs
  dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs
  mfd: madera: Register map tables for Cirrus Logic CS47L35
  mfd: madera: Register map tables for Cirrus Logic CS47L85
  mfd: madera: Register map tables for Cirrus Logic CS47L90/91
  regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs
  regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs
  irqchip: Add driver for Cirrus Logic Madera codecs
  pinctrl: madera: Add driver for Cirrus Logic Madera codecs
  dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs
  gpio: madera: Support Cirrus Logic Madera class codecs
  dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs
  ASoC: madera: Add common support for Cirrus Logic Madera codecs
  dt-bindings: sound: Add bindings for Cirrus Logic Madera codecs
  ASoC: cs47l35: Add codec driver for Cirrus Logic CS47L35
  ASoC: cs47l85: Add codec driver for Cirrus Logic CS47L85
  ASoC: cs47l90: Add codec driver for Cirrus Logic CS47L90

 .../devicetree/bindings/gpio/gpio-madera.txt       |   27 +
 Documentation/devicetree/bindings/mfd/madera.txt   |   96 +
 .../bindings/pinctrl/cirrus,madera-pinctrl.txt     |  102 +
 .../bindings/regulator/arizona-regulator.txt       |    3 +-
 Documentation/devicetree/bindings/sound/madera.txt |   66 +
 MAINTAINERS                                        |   24 +
 drivers/gpio/Kconfig                               |    6 +
 drivers/gpio/Makefile                              |    1 +
 drivers/gpio/gpio-madera.c                         |  196 +
 drivers/irqchip/Kconfig                            |    3 +
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-madera.c                       |  349 +
 drivers/mfd/Kconfig                                |   50 +
 drivers/mfd/Makefile                               |   13 +
 drivers/mfd/cs47l35-tables.c                       | 1688 ++++
 drivers/mfd/cs47l85-tables.c                       | 3169 +++++++
 drivers/mfd/cs47l90-tables.c                       | 2830 +++++++
 drivers/mfd/madera-core.c                          |  635 ++
 drivers/mfd/madera-i2c.c                           |  131 +
 drivers/mfd/madera-spi.c                           |  132 +
 drivers/mfd/madera.h                               |   52 +
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/cirrus/Kconfig                     |   15 +
 drivers/pinctrl/cirrus/Makefile                    |   11 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c           |   46 +
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c           |   60 +
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c           |   58 +
 drivers/pinctrl/cirrus/pinctrl-madera.c            | 1106 +++
 drivers/pinctrl/cirrus/pinctrl-madera.h            |   40 +
 drivers/regulator/Kconfig                          |   15 +-
 drivers/regulator/arizona-ldo1.c                   |   82 +-
 drivers/regulator/arizona-micsupp.c                |   71 +-
 include/dt-bindings/sound/madera.h                 |   18 +
 include/linux/irqchip/irq-madera-pdata.h           |   19 +
 include/linux/irqchip/irq-madera.h                 |   96 +
 include/linux/mfd/madera/core.h                    |  180 +
 include/linux/mfd/madera/pdata.h                   |   61 +
 include/linux/mfd/madera/registers.h               | 8832 ++++++++++++++++++++
 include/sound/madera-pdata.h                       |   58 +
 sound/soc/codecs/Kconfig                           |   23 +
 sound/soc/codecs/Makefile                          |    8 +
 sound/soc/codecs/cs47l35.c                         | 1747 ++++
 sound/soc/codecs/cs47l85.c                         | 2706 ++++++
 sound/soc/codecs/cs47l90.c                         | 2645 ++++++
 sound/soc/codecs/madera.c                          | 4430 ++++++++++
 sound/soc/codecs/madera.h                          |  470 ++
 47 files changed, 32363 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-madera.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt
 create mode 100644 Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/sound/madera.txt
 create mode 100644 drivers/gpio/gpio-madera.c
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 drivers/mfd/cs47l35-tables.c
 create mode 100644 drivers/mfd/cs47l85-tables.c
 create mode 100644 drivers/mfd/cs47l90-tables.c
 create mode 100644 drivers/mfd/madera-core.c
 create mode 100644 drivers/mfd/madera-i2c.c
 create mode 100644 drivers/mfd/madera-spi.c
 create mode 100644 drivers/mfd/madera.h
 create mode 100644 drivers/pinctrl/cirrus/Kconfig
 create mode 100644 drivers/pinctrl/cirrus/Makefile
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l35.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l85.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l90.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.h
 create mode 100644 include/dt-bindings/sound/madera.h
 create mode 100644 include/linux/irqchip/irq-madera-pdata.h
 create mode 100644 include/linux/irqchip/irq-madera.h
 create mode 100644 include/linux/mfd/madera/core.h
 create mode 100644 include/linux/mfd/madera/pdata.h
 create mode 100644 include/linux/mfd/madera/registers.h
 create mode 100644 include/sound/madera-pdata.h
 create mode 100644 sound/soc/codecs/cs47l35.c
 create mode 100644 sound/soc/codecs/cs47l85.c
 create mode 100644 sound/soc/codecs/cs47l90.c
 create mode 100644 sound/soc/codecs/madera.c
 create mode 100644 sound/soc/codecs/madera.h

-- 
1.9.1

[toc] | [next] | [standalone]


#1629747 — [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs
Message-ID<tzOSu-O4-17@gated-at.bofh.it>
In reply to#1629742
The Cirrus Logic Madera codecs have a range of GPIO pins that can be
used as single-bit logic input or output. These are presented as a
standard GPIO binding.

The second cell in a GPIO binding is currently reserved for future use
as chip-specific flags.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes from V1:
- moved out of main gpio patch into a separate patch
- added gpio-line-names as an optional property

 .../devicetree/bindings/gpio/gpio-madera.txt       | 27 ++++++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/gpio-madera.txt

diff --git a/Documentation/devicetree/bindings/gpio/gpio-madera.txt b/Documentation/devicetree/bindings/gpio/gpio-madera.txt
new file mode 100644
index 0000000..6254f5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-madera.txt
@@ -0,0 +1,27 @@
+Cirrus Logic Madera class audio codecs gpio driver
+
+This is a subnode of the parent mfd node.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+Required properties:
+  - compatible : must be "cirrus,madera-gpio"
+  - gpio-controller : Indicates this device is a GPIO controller.
+  - #gpio-cells : Must be 2. The first cell is the pin number. The second cell
+    is reserved for future use and must be zero
+
+Optional properties:
+  - gpio-line-names : as described in bindings/gpio/gpio.txt
+
+Example:
+
+cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	gpio {
+		compatible = "cirrus,madera-gpio";
+		gpio-controller;
+		#gpio-cells = <2>;
+	}
+};
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1630349 — Re: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-25 11:50 +0200
SubjectRe: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs
Message-ID<tA5gC-2XU-21@gated-at.bofh.it>
In reply to#1629747
On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:

> The Cirrus Logic Madera codecs have a range of GPIO pins that can be
> used as single-bit logic input or output. These are presented as a
> standard GPIO binding.
>
> The second cell in a GPIO binding is currently reserved for future use
> as chip-specific flags.
>
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Changes from V1:
> - moved out of main gpio patch into a separate patch
> - added gpio-line-names as an optional property

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1633076 — Re: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs

FromRob Herring <robh@kernel.org>
Date2017-04-28 20:20 +0200
SubjectRe: [PATCH v2 13/18] dt-bindings: gpio: Add bindings for GPIO on Cirrus Logic Madera codecs
Message-ID<tBiEO-2Jd-13@gated-at.bofh.it>
In reply to#1629747
On Mon, Apr 24, 2017 at 05:08:39PM +0100, Richard Fitzgerald wrote:
> The Cirrus Logic Madera codecs have a range of GPIO pins that can be
> used as single-bit logic input or output. These are presented as a
> standard GPIO binding.
> 
> The second cell in a GPIO binding is currently reserved for future use
> as chip-specific flags.
> 
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Changes from V1:
> - moved out of main gpio patch into a separate patch
> - added gpio-line-names as an optional property
> 
>  .../devicetree/bindings/gpio/gpio-madera.txt       | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/gpio-madera.txt

Acked-by: Rob Herring <robh@kernel.org>

[toc] | [prev] | [next] | [standalone]


#1629749 — [PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs
Message-ID<tzOSu-O4-19@gated-at.bofh.it>
In reply to#1629742
Specification of the bindings for the parent MFD driver component
of the Cirrus Logic Madera codec drivers.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes since V1:
- split out from main MFD patch
- moved interrupt control binding descriptions into here
- added description of the regulator child nodes
- fixed the node name of the example
- removed the MICBIAS from the example, these have been removed from the code

 Documentation/devicetree/bindings/mfd/madera.txt | 96 ++++++++++++++++++++++++
 1 file changed, 96 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt

diff --git a/Documentation/devicetree/bindings/mfd/madera.txt b/Documentation/devicetree/bindings/mfd/madera.txt
new file mode 100644
index 0000000..af9b85f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/madera.txt
@@ -0,0 +1,96 @@
+Cirrus Logic Madera class audio codecs multi-function device
+
+These devices are audio SoCs with extensive digital capabilities and a range
+of analogue I/O.
+
+See also the child driver bindings in:
+bindings/gpio/gpio-madera.txt
+bindings/pinctrl/cirrus,madera-pinctrl.txt
+bindings/regulator/arizona-regulator.txt
+bindings/sound/madera.txt
+
+Required properties:
+
+  - compatible : One of the following chip-specific strings:
+        "cirrus,cs47l35"
+        "cirrus,cs47l85"
+        "cirrus,cs47l90"
+        "cirrus,cs47l91"
+        "cirrus,wm1840"
+
+  - reg : I2C slave address when connected using I2C, chip select number when
+    using SPI.
+
+  - DCVDD-supply : Power supply for the device as defined in
+    bindings/regulator/regulator.txt
+    Mandatory on CS47L35, CS47L90, CS47L91
+    Optional on CS47L85, WM1840
+
+  - AVDD-supply, DBVDD1-supply, DBVDD2-supply, CPVDD1-supply, CPVDD2-supply :
+    Power supplies for the device
+
+  - DBVDD3-supply, DBVDD4-supply : Power supplies for the device
+    (CS47L85, CS47L90, CS47L91, WM1840)
+
+  - SPKVDDL-supply, SPKVDDR-supply : Power supplies for the device
+    (CS47L85, WM1840)
+
+  - SPKVDD-supply : Power supply for the device
+    (CS47L35)
+
+  - interrupt-controller : Madera class devices contain interrupt controllers
+    and may provide interrupt services to other devices.
+
+  - #interrupt-cells: the number of cells to describe an IRQ, must be 2.
+    The first cell is the IRQ number.
+    The second cell is the flags, encoded as the trigger masks from
+    bindings/interrupt-controller/interrupts.txt
+
+  - interrupt-parent : The parent interrupt controller.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+    connected to.
+
+Optional properties:
+
+  - MICVDD-supply : Power supply, only need to be specified if
+    powered externally
+
+  - reset-gpios : One entry specifying the GPIO controlling /RESET.
+    As defined in bindings/gpio.txt.
+    Although optional, it is strongly recommended to use a hardware reset
+
+  - MICBIASx : Initial data for the MICBIAS regulators, as covered in
+    Documentation/devicetree/bindings/regulator/regulator.txt.
+    One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
+    (all codecs)
+
+    One for each output pin (MICBIAS1A, MIBCIAS1B, MICBIAS2A, ...)
+    (all except CS47L85, WM1840)
+
+    The following following additional property is supported for the generator
+    nodes:
+      - cirrus,ext-cap : Set to 1 if the MICBIAS has external decoupling
+        capacitors attached.
+
+Optional child nodes:
+    micvdd : Node containing initialization data for the micvdd regulator
+    See bindings/regulator/arizona-regulator.txt
+
+    ldo1 : Node containing initialization data for the LDO1 regulator
+    See bindings/regulator/arizona-regulator.txt
+    (cs47l85, wm1840)
+
+Example:
+
+cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+	reg = <0>;
+
+	reset-gpios = <&gpio 0>;
+
+	interrupt-controller;
+	#interrupt-cells = <2>;
+	interrupts = <&host_irq1>;
+	interrupt-parent = <&gic>;
+};
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1633066 — Re: [PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs

FromRob Herring <robh@kernel.org>
Date2017-04-28 20:10 +0200
SubjectRe: [PATCH v2 03/18] dt-bindings: mfd: Add bindings for Cirrus Logic Madera codecs
Message-ID<tBiv8-2EY-25@gated-at.bofh.it>
In reply to#1629749
On Mon, Apr 24, 2017 at 05:08:29PM +0100, Richard Fitzgerald wrote:
> Specification of the bindings for the parent MFD driver component
> of the Cirrus Logic Madera codec drivers.
> 
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Changes since V1:
> - split out from main MFD patch
> - moved interrupt control binding descriptions into here
> - added description of the regulator child nodes
> - fixed the node name of the example
> - removed the MICBIAS from the example, these have been removed from the code
> 
>  Documentation/devicetree/bindings/mfd/madera.txt | 96 ++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt

Acked-by: Rob Herring <robh@kernel.org>

[toc] | [prev] | [next] | [standalone]


#1629750 — [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs
Message-ID<tzOSv-O4-29@gated-at.bofh.it>
In reply to#1629742
This is the binding description of the pinctrl driver for Cirru Logic
Madera codecs. The binding uses the generic pinctrl binding so  the main
purpose here is to describe the device-specific names for groups and
functions.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes since V1:
- split out from main pinctrl patch into a separate patch
- fixed typo in pinctrl-names property description

 .../bindings/pinctrl/cirrus,madera-pinctrl.txt     | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
new file mode 100644
index 0000000..0de91b5
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
@@ -0,0 +1,102 @@
+Cirrus Logic Madera class audio codecs pinctrl driver
+
+The Cirrus Logic Madera codecs provide a number of GPIO functions for
+interfacing to external hardware and to provide logic outputs to other devices.
+Certain groups of GPIO pins also have an alternate function, normally as an
+audio interface.
+
+The set of available GPIOs, functions and alternate function groups differs
+between codecs so refer to the datasheet for the codec for further information
+on what is supported on that device.
+
+The root node for this driver must be a subnode of the parent MFD driver node.
+It contains one subnode that is a container for an arbitrary number of subnodes
+to configure each pin or function group.
+
+See also
+  the core bindings for the parent MFD driver:
+    Documentation/devicetree/bindings/mfd/madera.txt
+
+  the generic pinmix bindings:
+    Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+Required properties of parent mfd node:
+  - pinctrl-names : must be "default"
+  - pinctrl-0 : a phandle to the node containing the configuration subnodes
+
+Required properties of pinctrl subnode:
+  - compatible : must be "cirrus,madera-pinctrl"
+
+Required properties of configuration subnodes:
+  - groups : name of one pin group to configure. One of:
+	aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+	dmic4, dmic5, dmic6,
+	gpio1, gpio2, ..., gpio40
+    The gpioN groups select the single pin of this name for configuration
+
+Optional properties of configuration subnodes:
+  Any configuration option not explicitly listed in the dts will be left at
+  chip default setting.
+
+  - function : name of function to assign to this group. One of:
+	aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+	dmic3, dmic4, dmic5, dmic6,
+	io, dsp-gpio, irq1, irq2,
+	fll1-clk, fll1-lock, fll2-clk, fll2-lock, fll3-clk, fll3-lock,
+	fllao-clk, fllao-lock,
+	opclk, opclk-async, pwm1, pwm2, spdif,
+	asrc1-in1-lock, asrc1-in2-lock, asrc2-in1-lock, asrc2-in2-lock,
+	spkl-short-circuit, spkr-short-circuit, spk-shutdown,
+	spk-overheat-shutdown, spk-overheat-warn,
+	timer1-sts, timer2-sts, timer3-sts, timer4-sts, timer5-sts, timer6-sts,
+	timer7-sts, timer8-sts,
+	log1-fifo-ne, log2-fifo-ne, log3-fifo-ne, log4-fifo-ne, log5-fifo-ne,
+	log6-fifo-ne, log7-fifo-ne, log8-fifo-ne,
+
+  - bias-disable : disable pull-up and pull-down
+  - bias-bus-hold : enable buskeeper
+  - bias-pull-up : output is pulled-up
+  - bias-pull-down : output is pulled-down
+  - drive-push-pull : CMOS output
+  - drive-open-drain : open-drain output
+  - drive-strength : drive strength in mA. Valid values are 4 or 8
+  - input-schmitt-enable : enable schmitt-trigger mode
+  - input-schmitt-disable : disable schmitt-trigger mode
+  - input-debounce : A value of 0 disables debounce, a value !=0 enables
+	debounce
+  - output-low : set the pin to output mode with low level
+  - output-high : set the pin to output mode with high level
+
+Example:
+
+cs47l85@0 {
+	compatible = "cirrus,cs47l85";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&cs47l85_gpio_defaults>;
+
+	pinctrl {
+		compatible = "cirrus,madera-pinctrl";
+
+		cs47l85_gpio_defaults: defaults {
+			aif1 {
+				groups = "aif1";
+				function = "aif1";
+				bias-bus-hold;
+			};
+
+			aif2 {
+				groups = "aif2";
+				function = "aif2";
+				bias-bus-hold;
+			};
+
+			opclk {
+				groups = "gpio1";
+				function = "opclk";
+				bias-pull-up;
+				drive-strength = <8>;
+			};
+		};
+	};
+};
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1630335 — Re: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-25 11:40 +0200
SubjectRe: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs
Message-ID<tA56V-2RZ-1@gated-at.bofh.it>
In reply to#1629750
On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:

> This is the binding description of the pinctrl driver for Cirru Logic
> Madera codecs. The binding uses the generic pinctrl binding so  the main
> purpose here is to describe the device-specific names for groups and
> functions.
>
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Changes since V1:
> - split out from main pinctrl patch into a separate patch
> - fixed typo in pinctrl-names property description

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1633074 — Re: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs

FromRob Herring <robh@kernel.org>
Date2017-04-28 20:20 +0200
SubjectRe: [PATCH v2 11/18] dt-bindings: pinctrl: Add bindings for Cirrus Logic Madera codecs
Message-ID<tBiEO-2Jd-7@gated-at.bofh.it>
In reply to#1629750
On Mon, Apr 24, 2017 at 05:08:37PM +0100, Richard Fitzgerald wrote:
> This is the binding description of the pinctrl driver for Cirru Logic
> Madera codecs. The binding uses the generic pinctrl binding so  the main
> purpose here is to describe the device-specific names for groups and
> functions.
> 
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Changes since V1:
> - split out from main pinctrl patch into a separate patch
> - fixed typo in pinctrl-names property description
> 
>  .../bindings/pinctrl/cirrus,madera-pinctrl.txt     | 102 +++++++++++++++++++++
>  1 file changed, 102 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt

Acked-by: Rob Herring <robh@kernel.org>

[toc] | [prev] | [next] | [standalone]


#1629751 — [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
Message-ID<tzOSv-O4-25@gated-at.bofh.it>
In reply to#1629742
This adds support for the GPIOs on Cirrus Logic Madera class codecs.
Any pins not used for special functions (see the pinctrl driver) can be
used as general single-bit input or output lines. The number of available
GPIOs varies between codecs.

Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
---
Changes from V1:
- dt bindings moved to a separate patch
- dependent on pinctrl driver instead of parent MFD
- added get_direction function
- added .request / .free / .set_config to work with pinctrl driver
- register range with pinctrl driver

 MAINTAINERS                |   2 +
 drivers/gpio/Kconfig       |   6 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-madera.c | 196 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 205 insertions(+)
 create mode 100644 drivers/gpio/gpio-madera.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3e42a03..66c5263 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3304,10 +3304,12 @@ L:	patches@opensource.wolfsonmicro.com
 T:	git https://github.com/CirrusLogic/linux-drivers.git
 W:	https://github.com/CirrusLogic/linux-drivers/wiki
 S:	Supported
+F:	Documentation/devicetree/bindings/gpio/gpio-madera.txt
 F:	Documentation/devicetree/bindings/mfd/madera.txt
 F:	Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F:	include/linux/irqchip/irq-madera*
 F:	include/linux/mfd/madera/*
+F:	drivers/gpio/gpio-madera*
 F:	drivers/irqchip/irq-madera*
 F:	drivers/mfd/madera*
 F:	drivers/mfd/cs47l*
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 05e8fbf..9488abe 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -941,6 +941,12 @@ config GPIO_LP873X
 	  This driver can also be built as a module. If so, the module will be
           called gpio-lp873x.
 
+config GPIO_MADERA
+	bool "Cirrus Logic Madera class codecs"
+	depends on PINCTRL_MADERA
+	help
+	  Support for GPIOs on Cirrus Logic Madera class codecs.
+
 config GPIO_MAX77620
 	tristate "GPIO support for PMIC MAX77620 and MAX20024"
 	depends on MFD_MAX77620
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 095598e..d4b6c30 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_GPIO_LPC18XX)	+= gpio-lpc18xx.o
 obj-$(CONFIG_ARCH_LPC32XX)	+= gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LP873X)	+= gpio-lp873x.o
 obj-$(CONFIG_GPIO_LYNXPOINT)	+= gpio-lynxpoint.o
+obj-$(CONFIG_GPIO_MADERA)	+= gpio-madera.o
 obj-$(CONFIG_GPIO_MAX730X)	+= gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= gpio-max7300.o
 obj-$(CONFIG_GPIO_MAX7301)	+= gpio-max7301.o
diff --git a/drivers/gpio/gpio-madera.c b/drivers/gpio/gpio-madera.c
new file mode 100644
index 0000000..37ac706
--- /dev/null
+++ b/drivers/gpio/gpio-madera.c
@@ -0,0 +1,196 @@
+/*
+ * GPIO support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
+struct madera_gpio {
+	struct madera *madera;
+	struct gpio_chip gpio_chip;
+};
+
+static int madera_gpio_get_direction(struct gpio_chip *chip,
+				     unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(madera->regmap,
+			  MADERA_GPIO1_CTRL_2 + (2 * offset), &val);
+	if (ret < 0)
+		return ret;
+
+	return (val & MADERA_GP1_DIR_MASK) >> MADERA_GP1_DIR_SHIFT;
+}
+
+static int madera_gpio_direction_in(struct gpio_chip *chip, unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+
+	return regmap_update_bits(madera->regmap,
+				  MADERA_GPIO1_CTRL_2 + (2 * offset),
+				  MADERA_GP1_DIR_MASK, MADERA_GP1_DIR);
+}
+
+static int madera_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int val;
+	int ret;
+
+	ret = regmap_read(madera->regmap,
+			  MADERA_GPIO1_CTRL_1 + (2 * offset), &val);
+	if (ret < 0)
+		return ret;
+
+	return !!(val & MADERA_GP1_LVL_MASK);
+}
+
+static int madera_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned int offset, int value)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int regval;
+	int ret;
+
+	if (value)
+		regval = MADERA_GP1_LVL;
+	else
+		regval = 0;
+
+	ret = regmap_update_bits(madera->regmap,
+				 MADERA_GPIO1_CTRL_2 + (2 * offset),
+				 MADERA_GP1_DIR_MASK, 0);
+	if (ret < 0)
+		return ret;
+
+	return regmap_update_bits(madera->regmap,
+				  MADERA_GPIO1_CTRL_1 + (2 * offset),
+				  MADERA_GP1_LVL_MASK, regval);
+}
+
+static void madera_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			    int value)
+{
+	struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+	struct madera *madera = madera_gpio->madera;
+	unsigned int regval;
+	int ret;
+
+	if (value)
+		regval = MADERA_GP1_LVL;
+	else
+		regval = 0;
+
+	ret = regmap_update_bits(madera->regmap,
+				 MADERA_GPIO1_CTRL_1 + (2 * offset),
+				 MADERA_GP1_LVL_MASK, regval);
+	if (ret)
+		dev_warn(madera->dev, "Failed to write to 0x%x (%d)\n",
+			 MADERA_GPIO1_CTRL_1 + (2 * offset), ret);
+}
+
+static struct gpio_chip template_chip = {
+	.label			= "madera",
+	.owner			= THIS_MODULE,
+	.request		= gpiochip_generic_request,
+	.free			= gpiochip_generic_free,
+	.get_direction		= madera_gpio_get_direction,
+	.direction_input	= madera_gpio_direction_in,
+	.get			= madera_gpio_get,
+	.direction_output	= madera_gpio_direction_out,
+	.set			= madera_gpio_set,
+	.set_config		= gpiochip_generic_config,
+	.can_sleep		= true,
+};
+
+static int madera_gpio_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct madera_pdata *pdata = dev_get_platdata(madera->dev);
+	struct madera_gpio *madera_gpio;
+	int ret;
+
+	madera_gpio = devm_kzalloc(&pdev->dev, sizeof(*madera_gpio),
+				   GFP_KERNEL);
+	if (!madera_gpio)
+		return -ENOMEM;
+
+	madera_gpio->madera = madera;
+	madera_gpio->gpio_chip = template_chip;
+	madera_gpio->gpio_chip.parent = &pdev->dev;
+
+	if (IS_ENABLED(CONFIG_OF_GPIO))
+		madera_gpio->gpio_chip.of_node = pdev->dev.of_node;
+
+	switch (madera->type) {
+	case CS47L35:
+		madera_gpio->gpio_chip.ngpio = CS47L35_NUM_GPIOS;
+		break;
+	case CS47L85:
+	case WM1840:
+		madera_gpio->gpio_chip.ngpio = CS47L85_NUM_GPIOS;
+		break;
+	case CS47L90:
+	case CS47L91:
+		madera_gpio->gpio_chip.ngpio = CS47L90_NUM_GPIOS;
+		break;
+	default:
+		dev_err(&pdev->dev, "Unknown chip variant %d\n", madera->type);
+		return -EINVAL;
+	}
+
+	if (pdata && pdata->gpio_base)
+		madera_gpio->gpio_chip.base = pdata->gpio_base;
+	else
+		madera_gpio->gpio_chip.base = -1;
+
+	ret = devm_gpiochip_add_data(&pdev->dev, &madera_gpio->gpio_chip,
+				     madera_gpio);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+		return ret;
+	}
+
+	ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
+				     0, 0, madera_gpio->gpio_chip.ngpio);
+	if (ret) {
+		dev_warn(&pdev->dev, "Failed to add pin range (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct platform_driver madera_gpio_driver = {
+	.driver.name	= "madera-gpio",
+	.driver.owner	= THIS_MODULE,
+	.probe		= madera_gpio_probe,
+};
+
+module_platform_driver(madera_gpio_driver);
+
+MODULE_DESCRIPTION("GPIO interface for Madera codecs");
+MODULE_AUTHOR("Nariman Poushin <nariman@opensource.wolfsonmicro.com>");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:madera-gpio");
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1630549 — Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-25 16:20 +0200
SubjectRe: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
Message-ID<tA9tU-5Lr-23@gated-at.bofh.it>
In reply to#1629751
On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:

> This adds support for the GPIOs on Cirrus Logic Madera class codecs.
> Any pins not used for special functions (see the pinctrl driver) can be
> used as general single-bit input or output lines. The number of available
> GPIOs varies between codecs.
>
> Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> Changes from V1:
> - dt bindings moved to a separate patch
> - dependent on pinctrl driver instead of parent MFD
> - added get_direction function
> - added .request / .free / .set_config to work with pinctrl driver
> - register range with pinctrl driver

Nice, but...

> +       ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
> +                                    0, 0, madera_gpio->gpio_chip.ngpio);
> +       if (ret) {
> +               dev_warn(&pdev->dev, "Failed to add pin range (%d)\n", ret);
> +               return ret;
> +       }

This is all fine, but we have generic code for adding ranges from
the device tree, see
Documentation/devicetree/bindings/gpio/gpio.txt

With that this range should not even be needed.
Apart from that it looks pretty solid.

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1630570 — Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-25 16:50 +0200
SubjectRe: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
Message-ID<tA9WW-5VD-23@gated-at.bofh.it>
In reply to#1630549
On Tue, 2017-04-25 at 16:13 +0200, Linus Walleij wrote:
> On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
> <rf@opensource.wolfsonmicro.com> wrote:
> 
> > This adds support for the GPIOs on Cirrus Logic Madera class codecs.
> > Any pins not used for special functions (see the pinctrl driver) can be
> > used as general single-bit input or output lines. The number of available
> > GPIOs varies between codecs.
> >
> > Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
> > Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> > Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> > ---
> > Changes from V1:
> > - dt bindings moved to a separate patch
> > - dependent on pinctrl driver instead of parent MFD
> > - added get_direction function
> > - added .request / .free / .set_config to work with pinctrl driver
> > - register range with pinctrl driver
> 
> Nice, but...
> 
> > +       ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
> > +                                    0, 0, madera_gpio->gpio_chip.ngpio);
> > +       if (ret) {
> > +               dev_warn(&pdev->dev, "Failed to add pin range (%d)\n", ret);
> > +               return ret;
> > +       }
> 
> This is all fine, but we have generic code for adding ranges from
> the device tree, see
> Documentation/devicetree/bindings/gpio/gpio.txt
> 

The range of gpio pins is a fixed property of the chip, and so is the
combination of gpio+pinctrl drivers.

I think the general principle of the DT maintainers is that DT should be
used for things that the drivers don't already know and can't figure
out.

> With that this range should not even be needed.
> Apart from that it looks pretty solid.
> 
> Yours,
> Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1632593 — Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-28 09:50 +0200
SubjectRe: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
Message-ID<tB8P8-4n0-15@gated-at.bofh.it>
In reply to#1630570
On Tue, Apr 25, 2017 at 4:44 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:
> On Tue, 2017-04-25 at 16:13 +0200, Linus Walleij wrote:
>> On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
>> <rf@opensource.wolfsonmicro.com> wrote:
>>
>> > This adds support for the GPIOs on Cirrus Logic Madera class codecs.
>> > Any pins not used for special functions (see the pinctrl driver) can be
>> > used as general single-bit input or output lines. The number of available
>> > GPIOs varies between codecs.
>> >
>> > Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
>> > Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
>> > Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
>> > ---
>> > Changes from V1:
>> > - dt bindings moved to a separate patch
>> > - dependent on pinctrl driver instead of parent MFD
>> > - added get_direction function
>> > - added .request / .free / .set_config to work with pinctrl driver
>> > - register range with pinctrl driver
>>
>> Nice, but...
>>
>> > +       ret = gpiochip_add_pin_range(&madera_gpio->gpio_chip, "madera-pinctrl",
>> > +                                    0, 0, madera_gpio->gpio_chip.ngpio);
>> > +       if (ret) {
>> > +               dev_warn(&pdev->dev, "Failed to add pin range (%d)\n", ret);
>> > +               return ret;
>> > +       }
>>
>> This is all fine, but we have generic code for adding ranges from
>> the device tree, see
>> Documentation/devicetree/bindings/gpio/gpio.txt
>>
>
> The range of gpio pins is a fixed property of the chip, and so is the
> combination of gpio+pinctrl drivers.

Well so is the IRQ number, but we still put that in the device tree.

> I think the general principle of the DT maintainers is that DT should be
> used for things that the drivers don't already know and can't figure
> out.

It's a grayzone. People use ranges in the device tree for example when
there are several instances of the same GPIO block with different
ranges into a single pin controller and then it makes sense.

But in this case you have your separate chip with one instance so
it doesn't make sense, keep it like this.

Also it is necessary to proble from boardfiles as you explained in the
pinctrl patch.

Good job, it's a nice driver. Also the pinctrl driver is very nice.

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1632594 — Re: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-28 09:50 +0200
SubjectRe: [PATCH v2 12/18] gpio: madera: Support Cirrus Logic Madera class codecs
Message-ID<tB8P8-4n0-17@gated-at.bofh.it>
In reply to#1629751
On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:

> This adds support for the GPIOs on Cirrus Logic Madera class codecs.
> Any pins not used for special functions (see the pinctrl driver) can be
> used as general single-bit input or output lines. The number of available
> GPIOs varies between codecs.
>
> Signed-off-by: Nariman Poushin <nariman@opensource.wolfsonmicro.com>
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
> ---
> Changes from V1:
> - dt bindings moved to a separate patch
> - dependent on pinctrl driver instead of parent MFD
> - added get_direction function
> - added .request / .free / .set_config to work with pinctrl driver
> - register range with pinctrl driver

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1629752 — [PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs
Message-ID<tzOSv-O4-31@gated-at.bofh.it>
In reply to#1629742
This adds a new driver identity "madera-micsupp" and probe function
so that this driver can be used to control the micsupp regulator on
Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Replaces the madera-specific driver from V1 patchset

 .../bindings/regulator/arizona-regulator.txt       |  3 +-
 drivers/regulator/Kconfig                          |  7 ++-
 drivers/regulator/arizona-micsupp.c                | 71 +++++++++++++++++++++-
 3 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
index 443564d..91b00f9 100644
--- a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
@@ -5,7 +5,8 @@ of analogue I/O.
 
 This document lists regulator specific bindings, see the primary binding
 document:
-  ../mfd/arizona.txt
+  For Wolfson Arizona codecs: ../mfd/arizona.txt
+  For Cirrus Logic Madera codecs: ../mfd/madera.txt
 
 Optional properties:
   - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8647538..05e6aae 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -134,11 +134,12 @@ config REGULATOR_ARIZONA_LDO1
 	  devices.
 
 config REGULATOR_ARIZONA_MICSUPP
-	tristate "Wolfson Arizona class devices MICSUPP"
-	depends on MFD_ARIZONA
+	tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
+	depends on MFD_ARIZONA || MFD_MADERA
 	depends on SND_SOC
 	help
-	  Support for the MICSUPP regulators found on Wolfson Arizona class
+	  Support for the MICSUPP regulators found on Cirrus Logic Madera codecs
+	  and Wolfson Arizona codecs
 	  devices.
 
 config REGULATOR_AS3711
diff --git a/drivers/regulator/arizona-micsupp.c b/drivers/regulator/arizona-micsupp.c
index 120de94..36bf73c 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -30,6 +30,10 @@
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
 
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
 #include <linux/regulator/arizona-micsupp.h>
 
 struct arizona_micsupp {
@@ -205,6 +209,28 @@ static int arizona_micsupp_set_bypass(struct regulator_dev *rdev, bool ena)
 	.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_micsupp = {
+	.name = "MICVDD",
+	.supply_name = "CPVDD1",
+	.type = REGULATOR_VOLTAGE,
+	.n_voltages = 40,
+	.ops = &arizona_micsupp_ops,
+
+	.vsel_reg = MADERA_LDO2_CONTROL_1,
+	.vsel_mask = MADERA_LDO2_VSEL_MASK,
+	.enable_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.enable_mask = MADERA_CPMIC_ENA,
+	.bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
+	.bypass_mask = MADERA_CPMIC_BYPASS,
+
+	.linear_ranges = arizona_micsupp_ext_ranges,
+	.n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
+
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
 static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
 					struct regulator_config *config,
 					const struct regulator_desc *desc)
@@ -321,6 +347,24 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
 					   &arizona->pdata.micvdd);
 }
 
+static int madera_micsupp_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct arizona_micsupp *micsupp;
+
+	micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+	if (!micsupp)
+		return -ENOMEM;
+
+	micsupp->regmap = madera->regmap;
+	micsupp->dapm = &madera->dapm;
+	micsupp->dev = madera->dev;
+	micsupp->init_data = arizona_micsupp_ext_default;
+
+	return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
+					   &madera->pdata.micvdd);
+}
+
 static struct platform_driver arizona_micsupp_driver = {
 	.probe = arizona_micsupp_probe,
 	.driver		= {
@@ -328,10 +372,35 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
 	},
 };
 
-module_platform_driver(arizona_micsupp_driver);
+static struct platform_driver madera_micsupp_driver = {
+	.probe = madera_micsupp_probe,
+	.driver		= {
+		.name	= "madera-micsupp",
+	},
+};
+
+static struct platform_driver * const arizona_micsupp_drivers[] = {
+	&arizona_micsupp_driver,
+	&madera_micsupp_driver,
+};
+
+static int __init arizona_micsupp_init(void)
+{
+	return platform_register_drivers(arizona_micsupp_drivers,
+					 ARRAY_SIZE(arizona_micsupp_drivers));
+}
+module_init(arizona_micsupp_init);
+
+static void __exit arizona_micsupp_exit(void)
+{
+	platform_unregister_drivers(arizona_micsupp_drivers,
+				    ARRAY_SIZE(arizona_micsupp_drivers));
+}
+module_exit(arizona_micsupp_exit);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Arizona microphone supply driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:arizona-micsupp");
+MODULE_ALIAS("platform:madera-micsupp");
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1633069 — Re: [PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs

FromRob Herring <robh@kernel.org>
Date2017-04-28 20:10 +0200
SubjectRe: [PATCH v2 07/18] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs
Message-ID<tBiv8-2EY-31@gated-at.bofh.it>
In reply to#1629752
On Mon, Apr 24, 2017 at 05:08:33PM +0100, Richard Fitzgerald wrote:
> This adds a new driver identity "madera-micsupp" and probe function
> so that this driver can be used to control the micsupp regulator on
> Cirrus Logic Madera codecs.
> 
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> ---
> Replaces the madera-specific driver from V1 patchset
> 
>  .../bindings/regulator/arizona-regulator.txt       |  3 +-

Acked-by: Rob Herring <robh@kernel.org>

>  drivers/regulator/Kconfig                          |  7 ++-
>  drivers/regulator/arizona-micsupp.c                | 71 +++++++++++++++++++++-
>  3 files changed, 76 insertions(+), 5 deletions(-)

[toc] | [prev] | [next] | [standalone]


#1629753 — [PATCH v2 08/18] regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 08/18] regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs
Message-ID<tzOSv-O4-37@gated-at.bofh.it>
In reply to#1629742
This adds a new driver identity "madera-ldo1" and probe function
so that this driver can be used to control the LDO1 regulator on
some Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Replaces the madera-specific driver from V1 patchset

 drivers/regulator/Kconfig        |  8 ++--
 drivers/regulator/arizona-ldo1.c | 82 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 05e6aae..d12da22 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -126,12 +126,12 @@ config REGULATOR_AB8500
 	  signal AB8500 PMIC
 
 config REGULATOR_ARIZONA_LDO1
-	tristate "Wolfson Arizona class devices LDO1"
-	depends on MFD_ARIZONA
+	tristate "Cirrus Madera and Wolfson Arizona class devices LDO1"
+	depends on MFD_ARIZONA || MFD_MADERA
 	depends on SND_SOC
 	help
-	  Support for the LDO1 regulators found on Wolfson Arizona class
-	  devices.
+	  Support for the LDO1 regulators found on Cirrus Logic Madera codecs
+	  and Wolfson Arizona codecs.
 
 config REGULATOR_ARIZONA_MICSUPP
 	tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 96fddff..c64625e 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -31,6 +31,10 @@
 #include <linux/mfd/arizona/pdata.h>
 #include <linux/mfd/arizona/registers.h>
 
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/mfd/madera/registers.h>
+
 struct arizona_ldo1 {
 	struct regulator_dev *regulator;
 	struct regmap *regmap;
@@ -188,6 +192,31 @@ static int arizona_ldo1_hc_get_voltage_sel(struct regulator_dev *rdev)
 	.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_ldo1 = {
+	.name = "LDO1",
+	.supply_name = "LDOVDD",
+	.type = REGULATOR_VOLTAGE,
+	.ops = &arizona_ldo1_ops,
+
+	.vsel_reg = MADERA_LDO1_CONTROL_1,
+	.vsel_mask = MADERA_LDO1_VSEL_MASK,
+	.min_uV = 900000,
+	.uV_step = 25000,
+	.n_voltages = 13,
+	.enable_time = 3000,
+
+	.owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data madera_ldo1_default = {
+	.constraints = {
+		.min_uV = 1200000,
+		.max_uV = 1200000,
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = 1,
+};
+
 static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
 				     struct regulator_config *config,
 				     const struct regulator_desc *desc,
@@ -341,6 +370,32 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static int madera_ldo1_probe(struct platform_device *pdev)
+{
+	struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+	struct arizona_ldo1 *ldo1;
+	bool external_dcvdd;
+	int ret;
+
+	ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
+	if (!ldo1)
+		return -ENOMEM;
+
+	ldo1->regmap = madera->regmap;
+
+	ldo1->init_data = madera_ldo1_default;
+
+	ret = arizona_ldo1_common_init(pdev, ldo1, &arizona_ldo1,
+				       &madera->pdata.ldo1,
+				       &external_dcvdd);
+	if (ret)
+		return ret;
+
+	madera->internal_dcvdd = !external_dcvdd;
+
+	return 0;
+}
+
 static struct platform_driver arizona_ldo1_driver = {
 	.probe = arizona_ldo1_probe,
 	.driver		= {
@@ -348,10 +403,35 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
 	},
 };
 
-module_platform_driver(arizona_ldo1_driver);
+static struct platform_driver madera_ldo1_driver = {
+	.probe = madera_ldo1_probe,
+	.driver		= {
+		.name	= "madera-ldo1",
+	},
+};
+
+static struct platform_driver * const madera_ldo1_drivers[] = {
+	&arizona_ldo1_driver,
+	&madera_ldo1_driver,
+};
+
+static int __init arizona_ldo1_init(void)
+{
+	return platform_register_drivers(madera_ldo1_drivers,
+					 ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_init(arizona_ldo1_init);
+
+static void __exit madera_ldo1_exit(void)
+{
+	platform_unregister_drivers(madera_ldo1_drivers,
+				    ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_exit(madera_ldo1_exit);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Arizona LDO1 driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:arizona-ldo1");
+MODULE_ALIAS("platform:madera-ldo1");
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1629754 — [PATCH v2 02/18] mfd: madera: Add common support for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-24 18:20 +0200
Subject[PATCH v2 02/18] mfd: madera: Add common support for Cirrus Logic Madera codecs
Message-ID<tzOSv-O4-47@gated-at.bofh.it>
In reply to#1629742
This adds the generic core support for Cirrus Logic "Madera" class codecs.
These are complex audio codec SoCs with a variety of digital and analogue
I/O, onboard audio processing and DSPs, and other features.

These codecs are all based off a common set of hardware IP so can be
supported by a core of common code (with a few minor device-to-device
variations).


Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Nikesh Oswal <Nikesh.Oswal@wolfsonmicro.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
---
Changes since V1:
- Moved dt binding into separate patch
- Fixed some errors with Kconfig options and select MADERA_IRQ directly
  from MFD
- Added custom parent supply information, mainly for re-using the Arizona
  regulators (which don't have their own DT node)
- re-ordered the error test and debug print in madera_wait_for_boot()
- re-worked the initialization of the reset gpio configuration from probe
- renamed madera_of_get_type() to madera_get_type_from_of() to make its
  purpose clearer
- removed reading of MICBIAS configuration
- ordered includes alphabetically
- added a header comment that struct madera is internal
- fixed pdata comments to be kerneldoc format

 MAINTAINERS                      |   3 +
 drivers/mfd/Kconfig              |  29 ++
 drivers/mfd/Makefile             |   4 +
 drivers/mfd/madera-core.c        | 635 +++++++++++++++++++++++++++++++++++++++
 drivers/mfd/madera-i2c.c         | 131 ++++++++
 drivers/mfd/madera-spi.c         | 132 ++++++++
 drivers/mfd/madera.h             |  52 ++++
 include/linux/mfd/madera/core.h  | 180 +++++++++++
 include/linux/mfd/madera/pdata.h |  61 ++++
 9 files changed, 1227 insertions(+)
 create mode 100644 drivers/mfd/madera-core.c
 create mode 100644 drivers/mfd/madera-i2c.c
 create mode 100644 drivers/mfd/madera-spi.c
 create mode 100644 drivers/mfd/madera.h
 create mode 100644 include/linux/mfd/madera/core.h
 create mode 100644 include/linux/mfd/madera/pdata.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4e07159..4a01a2a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3304,7 +3304,10 @@ L:	patches@opensource.wolfsonmicro.com
 T:	git https://github.com/CirrusLogic/linux-drivers.git
 W:	https://github.com/CirrusLogic/linux-drivers/wiki
 S:	Supported
+F:	Documentation/devicetree/bindings/mfd/madera.txt
 F:	include/linux/mfd/madera/*
+F:	drivers/mfd/madera*
+F:	drivers/mfd/cs47l*
 
 CLEANCACHE API
 M:	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 3eb5c93..8128aaa 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -203,6 +203,35 @@ config MFD_CROS_EC_SPI
 	  response time cannot be guaranteed, we support ignoring
 	  'pre-amble' bytes before the response actually starts.
 
+config MFD_MADERA
+	bool
+
+config MFD_MADERA_I2C
+	bool "Cirrus Logic Madera codecs with I2C"
+	select REGMAP
+	select REGMAP_IRQ
+	select MFD_CORE
+	select REGMAP_I2C
+	select MFD_MADERA
+	select MADERA_IRQ
+	depends on I2C
+	help
+	  Support for the Cirrus Logic Madera platform audio SoC
+	  core functionality controlled via I2C.
+
+config MFD_MADERA_SPI
+	bool "Cirrus Logic Madera codecs with SPI"
+	select REGMAP
+	select REGMAP_IRQ
+	select MFD_CORE
+	select REGMAP_SPI
+	select MFD_MADERA
+	select MADERA_IRQ
+	depends on SPI_MASTER
+	help
+	  Support for the Cirrus Logic Madera platform audio SoC
+	  core functionality controlled via SPI.
+
 config MFD_ASIC3
 	bool "Compaq ASIC3"
 	depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c16bf1e..38b1514 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -72,6 +72,10 @@ obj-$(CONFIG_MFD_WM8350_I2C)	+= wm8350-i2c.o
 wm8994-objs			:= wm8994-core.o wm8994-irq.o wm8994-regmap.o
 obj-$(CONFIG_MFD_WM8994)	+= wm8994.o
 
+obj-$(CONFIG_MFD_MADERA)	+= madera-core.o
+obj-$(CONFIG_MFD_MADERA_I2C)	+= madera-i2c.o
+obj-$(CONFIG_MFD_MADERA_SPI)	+= madera-spi.o
+
 obj-$(CONFIG_TPS6105X)		+= tps6105x.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_TPS6507X)		+= tps6507x.o
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
new file mode 100644
index 0000000..bed018d
--- /dev/null
+++ b/drivers/mfd/madera-core.c
@@ -0,0 +1,635 @@
+/*
+ * Core MFD support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <linux/mfd/madera/core.h>
+#include <linux/mfd/madera/registers.h>
+
+#include "madera.h"
+
+#define CS47L35_SILICON_ID	0x6360
+#define CS47L85_SILICON_ID	0x6338
+#define CS47L90_SILICON_ID	0x6364
+
+#define MADERA_32KZ_MCLK2	1
+
+static const char * const madera_core_supplies[] = {
+	"AVDD",
+	"DBVDD1",
+};
+
+static const struct mfd_cell madera_ldo1_devs[] = {
+	{ .name = "madera-ldo1" },
+};
+
+static const char * const cs47l35_supplies[] = {
+	"MICVDD",
+	"DBVDD2",
+	"CPVDD1",
+	"CPVDD2",
+	"SPKVDD",
+};
+
+static const struct mfd_cell cs47l35_devs[] = {
+	{ .name = "madera-pinctrl", .of_compatible = "cirrus,madera-pinctrl" },
+	{ .name = "madera-irq", },
+	{ .name = "madera-micsupp", },
+	{ .name = "madera-gpio",    .of_compatible = "cirrus,madera-gpio" },
+	{ .name = "madera-extcon",  .of_compatible = "cirrus,madera-extcon" },
+	{
+		.name = "cs47l35-codec",
+		.of_compatible = "cirrus,cs47l35-codec",
+		.parent_supplies = cs47l35_supplies,
+		.num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
+	},
+};
+
+static const char * const cs47l85_supplies[] = {
+	"MICVDD",
+	"DBVDD2",
+	"DBVDD3",
+	"DBVDD4",
+	"CPVDD1",
+	"CPVDD2",
+	"SPKVDDL",
+	"SPKVDDR",
+};
+
+static const struct mfd_cell cs47l85_devs[] = {
+	{ .name = "madera-pinctrl", .of_compatible = "cirrus,madera-pinctrl" },
+	{ .name = "madera-irq", },
+	{ .name = "madera-micsupp" },
+	{ .name = "madera-gpio",    .of_compatible = "cirrus,madera-gpio" },
+	{ .name = "madera-extcon",  .of_compatible = "cirrus,madera-extcon" },
+	{
+		.name = "cs47l85-codec",
+		.of_compatible = "cirrus,cs47l85-codec",
+		.parent_supplies = cs47l85_supplies,
+		.num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
+	},
+};
+
+static const char * const cs47l90_supplies[] = {
+	"MICVDD",
+	"DBVDD2",
+	"DBVDD3",
+	"DBVDD4",
+	"CPVDD1",
+	"CPVDD2",
+};
+
+static const struct mfd_cell cs47l90_devs[] = {
+	{ .name = "madera-pinctrl", .of_compatible = "cirrus,madera-pinctrl" },
+	{ .name = "madera-irq", },
+	{ .name = "madera-micsupp", },
+	{ .name = "madera-gpio",    .of_compatible = "cirrus,madera-gpio" },
+	{ .name = "madera-extcon",  .of_compatible = "cirrus,madera-extcon" },
+	{
+		.name = "cs47l90-codec",
+		 .of_compatible = "cirrus,cs47l90-codec",
+		.parent_supplies = cs47l90_supplies,
+		.num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
+	},
+};
+
+const char *madera_name_from_type(enum madera_type type)
+{
+	switch (type) {
+	case CS47L35:
+		return "CS47L35";
+	case CS47L85:
+		return "CS47L85";
+	case CS47L90:
+		return "CS47L90";
+	case CS47L91:
+		return "CS47L91";
+	case WM1840:
+		return "WM1840";
+	default:
+		return "Unknown";
+	}
+}
+EXPORT_SYMBOL_GPL(madera_name_from_type);
+
+#define MADERA_BOOT_POLL_MAX_INTERVAL_US  5000
+#define MADERA_BOOT_POLL_TIMEOUT_US	 25000
+
+static int madera_wait_for_boot(struct madera *madera)
+{
+	unsigned int val;
+	int ret;
+
+	/*
+	 * We can't use an interrupt as we need to runtime resume to do so,
+	 * so we poll the status bit. This won't race with the interrupt
+	 * handler because it will be blocked on runtime resume.
+	 */
+	ret = regmap_read_poll_timeout(madera->regmap,
+				       MADERA_IRQ1_RAW_STATUS_1,
+				       val,
+				       (val & MADERA_BOOT_DONE_STS1),
+				       MADERA_BOOT_POLL_MAX_INTERVAL_US,
+				       MADERA_BOOT_POLL_TIMEOUT_US);
+
+	if (ret)
+		dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
+
+	/*
+	 * BOOT_DONE defaults to unmasked on boot so we must ack it.
+	 * Do this unconditionally to avoid interrupt storms
+	 */
+	regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
+		     MADERA_BOOT_DONE_EINT1);
+
+	pm_runtime_mark_last_busy(madera->dev);
+
+	return ret;
+}
+
+static int madera_soft_reset(struct madera *madera)
+{
+	int ret;
+
+	ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
+	if (ret != 0) {
+		dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
+		return ret;
+	}
+
+	/* Allow time for internal clocks to startup after reset */
+	usleep_range(1000, 2000);
+
+	return 0;
+}
+
+static void madera_enable_hard_reset(struct madera *madera)
+{
+	if (madera->reset_gpio)
+		gpiod_set_value_cansleep(madera->reset_gpio, 0);
+}
+
+static void madera_disable_hard_reset(struct madera *madera)
+{
+	if (madera->reset_gpio) {
+		gpiod_set_value_cansleep(madera->reset_gpio, 1);
+		usleep_range(1000, 2000);
+	}
+}
+
+#ifdef CONFIG_PM
+static int madera_runtime_resume(struct device *dev)
+{
+	struct madera *madera = dev_get_drvdata(dev);
+	int ret;
+
+	dev_dbg(dev, "Leaving sleep mode\n");
+
+	ret = regulator_enable(madera->dcvdd);
+	if (ret) {
+		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
+		return ret;
+	}
+
+	regcache_cache_only(madera->regmap, false);
+	regcache_cache_only(madera->regmap_32bit, false);
+
+	ret = madera_wait_for_boot(madera);
+	if (ret)
+		goto err;
+
+	ret = regcache_sync(madera->regmap);
+	if (ret) {
+		dev_err(dev, "Failed to restore 16-bit register cache\n");
+		goto err;
+	}
+
+	ret = regcache_sync(madera->regmap_32bit);
+	if (ret) {
+		dev_err(dev, "Failed to restore 32-bit register cache\n");
+		goto err;
+	}
+
+	return 0;
+
+err:
+	regcache_cache_only(madera->regmap_32bit, true);
+	regcache_cache_only(madera->regmap, true);
+	regulator_disable(madera->dcvdd);
+
+	return ret;
+}
+
+static int madera_runtime_suspend(struct device *dev)
+{
+	struct madera *madera = dev_get_drvdata(dev);
+
+	dev_dbg(madera->dev, "Entering sleep mode\n");
+
+	regcache_cache_only(madera->regmap, true);
+	regcache_mark_dirty(madera->regmap);
+	regcache_cache_only(madera->regmap_32bit, true);
+	regcache_mark_dirty(madera->regmap_32bit);
+
+	regulator_disable(madera->dcvdd);
+
+	return 0;
+}
+#endif
+
+const struct dev_pm_ops madera_pm_ops = {
+	SET_RUNTIME_PM_OPS(madera_runtime_suspend,
+			   madera_runtime_resume,
+			   NULL)
+};
+EXPORT_SYMBOL_GPL(madera_pm_ops);
+
+unsigned int madera_get_num_micbias(struct madera *madera)
+{
+
+	switch (madera->type) {
+	case CS47L35:
+		return 2;
+	case CS47L85:
+	case WM1840:
+		return 4;
+	case CS47L90:
+	case CS47L91:
+		return 2;
+	default:
+		dev_warn(madera->dev, "No micbias known for codec %s\n",
+			 madera_name_from_type(madera->type));
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(madera_get_num_micbias);
+
+unsigned int madera_get_num_childbias(struct madera *madera,
+				      unsigned int micbias)
+{
+	/*
+	 * micbias argument reserved for future codecs that don't
+	 * have the same number of children on each micbias
+	 */
+
+	switch (madera->type) {
+	case CS47L35:
+		return 2;
+	case CS47L85:
+	case WM1840:
+		return 0;
+	case CS47L90:
+	case CS47L91:
+		return 4;
+	default:
+		dev_warn(madera->dev, "No child micbias known for codec %s\n",
+			 madera_name_from_type(madera->type));
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(madera_get_num_childbias);
+
+#ifdef CONFIG_OF
+const struct of_device_id madera_of_match[] = {
+	{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
+	{ .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
+	{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
+	{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
+	{ .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
+	{},
+};
+EXPORT_SYMBOL_GPL(madera_of_match);
+
+unsigned long madera_get_type_from_of(struct device *dev)
+{
+	const struct of_device_id *id = of_match_device(madera_of_match, dev);
+
+	if (id)
+		return (unsigned long)id->data;
+	else
+		return 0;
+}
+EXPORT_SYMBOL_GPL(madera_get_type_from_of);
+#endif
+
+static int madera_get_reset_gpio(struct madera *madera)
+{
+	int ret;
+
+	/* We use 0 in pdata to indicate a GPIO has not been set */
+	if (dev_get_platdata(madera->dev) && (madera->pdata.reset > 0)) {
+		/* Start out with /RESET asserted */
+		ret = devm_gpio_request_one(madera->dev,
+					    madera->pdata.reset,
+					    GPIOF_DIR_OUT | GPIOF_INIT_LOW,
+					    "madera reset");
+		if (!ret)
+			madera->reset_gpio = gpio_to_desc(madera->pdata.reset);
+	} else {
+		madera->reset_gpio = devm_gpiod_get_optional(madera->dev,
+							     "reset",
+							     GPIOD_OUT_LOW);
+		if (IS_ERR(madera->reset_gpio))
+			ret = PTR_ERR(madera->reset_gpio);
+		else
+			ret = 0;
+	}
+
+	if (ret == -EPROBE_DEFER)
+		return ret;
+
+	if (ret) {
+		dev_err(madera->dev, "Failed to request /RESET: %d\n", ret);
+		return ret;
+	}
+
+	if (!madera->reset_gpio)
+		dev_warn(madera->dev,
+			 "Running without reset GPIO is not recommended\n");
+
+	return 0;
+}
+
+int madera_dev_init(struct madera *madera)
+{
+	struct device *dev = madera->dev;
+	const char *name;
+	unsigned int hwid;
+	int (*patch_fn)(struct madera *) = NULL;
+	const struct mfd_cell *mfd_devs;
+	int n_devs = 0;
+	int i, ret;
+
+	dev_set_drvdata(madera->dev, madera);
+	BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
+
+	if (dev_get_platdata(madera->dev)) {
+		memcpy(&madera->pdata, dev_get_platdata(madera->dev),
+		       sizeof(madera->pdata));
+	}
+
+	ret = madera_get_reset_gpio(madera);
+	if (ret)
+		return ret;
+
+	regcache_cache_only(madera->regmap, true);
+	regcache_cache_only(madera->regmap_32bit, true);
+
+	for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
+		madera->core_supplies[i].supply = madera_core_supplies[i];
+
+	madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
+
+	switch (madera->type) {
+	case CS47L35:
+	case CS47L90:
+	case CS47L91:
+		break;
+	case CS47L85:
+	case WM1840:
+		/* On these DCVDD could be supplied from the onboard LDO1 */
+		ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
+				      madera_ldo1_devs,
+				      ARRAY_SIZE(madera_ldo1_devs),
+				      NULL, 0, NULL);
+		if (ret) {
+			dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
+			return ret;
+		}
+		break;
+	default:
+		dev_err(madera->dev, "Unknown device type %d\n", madera->type);
+		return -ENODEV;
+	}
+
+	ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
+				      madera->core_supplies);
+	if (ret) {
+		dev_err(dev, "Failed to request core supplies: %d\n", ret);
+		goto err_devs;
+	}
+
+	/*
+	 * Don't use devres here because the only device we have to get
+	 * against is the MFD device and DCVDD will likely be supplied by
+	 * one of its children. Meaning that the regulator will be
+	 * destroyed by the time devres calls regulator put.
+	 */
+	madera->dcvdd = regulator_get_exclusive(madera->dev, "DCVDD");
+	if (IS_ERR(madera->dcvdd)) {
+		ret = PTR_ERR(madera->dcvdd);
+		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
+		goto err_devs;
+	}
+
+	ret = regulator_bulk_enable(madera->num_core_supplies,
+				    madera->core_supplies);
+	if (ret) {
+		dev_err(dev, "Failed to enable core supplies: %d\n", ret);
+		goto err_dcvdd;
+	}
+
+	ret = regulator_enable(madera->dcvdd);
+	if (ret) {
+		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
+		goto err_enable;
+	}
+
+	madera_disable_hard_reset(madera);
+
+	regcache_cache_only(madera->regmap, false);
+	regcache_cache_only(madera->regmap_32bit, false);
+
+	/*
+	 * Verify that this is a chip we know about before we
+	 * starting doing any writes to its registers
+	 */
+	ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
+	if (ret) {
+		dev_err(dev, "Failed to read ID register: %d\n", ret);
+		goto err_reset;
+	}
+
+	switch (hwid) {
+	case CS47L35_SILICON_ID:
+	case CS47L85_SILICON_ID:
+	case CS47L90_SILICON_ID:
+		break;
+	default:
+		dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
+		ret = -EINVAL;
+		goto err_reset;
+	}
+
+	/* If we don't have a reset GPIO use a soft reset */
+	if (!madera->reset_gpio) {
+		ret = madera_soft_reset(madera);
+		if (ret)
+			goto err_reset;
+	}
+
+	ret = madera_wait_for_boot(madera);
+	if (ret) {
+		dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
+		goto err_reset;
+	}
+
+	ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
+			  &madera->rev);
+	if (ret) {
+		dev_err(dev, "Failed to read revision register: %d\n", ret);
+		goto err_reset;
+	}
+	madera->rev &= MADERA_HW_REVISION_MASK;
+
+	name = madera_name_from_type(madera->type);
+
+	switch (hwid) {
+	case CS47L35_SILICON_ID:
+		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
+			switch (madera->type) {
+			case CS47L35:
+				patch_fn = cs47l35_patch;
+				mfd_devs = cs47l35_devs;
+				n_devs = ARRAY_SIZE(cs47l35_devs);
+				break;
+			default:
+				break;
+			}
+		}
+		break;
+	case CS47L85_SILICON_ID:
+		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
+			switch (madera->type) {
+			case CS47L85:
+			case WM1840:
+				patch_fn = cs47l85_patch;
+				mfd_devs = cs47l85_devs;
+				n_devs = ARRAY_SIZE(cs47l85_devs);
+				break;
+			default:
+				break;
+			}
+		}
+		break;
+	case CS47L90_SILICON_ID:
+		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
+			switch (madera->type) {
+			case CS47L90:
+			case CS47L91:
+				patch_fn = cs47l90_patch;
+				mfd_devs = cs47l90_devs;
+				n_devs = ARRAY_SIZE(cs47l90_devs);
+				break;
+			default:
+				break;
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (!n_devs) {
+		dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid, name);
+		ret = -ENODEV;
+		goto err_reset;
+	}
+
+	dev_info(dev, "%s silicon revision %d\n", name, madera->rev);
+
+	/* Apply hardware patch */
+	if (patch_fn) {
+		ret = patch_fn(madera);
+		if (ret) {
+			dev_err(madera->dev, "Failed to apply patch %d\n", ret);
+			goto err_reset;
+		}
+	}
+
+	/* Init 32k clock sourced from MCLK2 */
+	ret = regmap_update_bits(madera->regmap,
+			MADERA_CLOCK_32K_1,
+			MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
+			MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
+	if (ret) {
+		dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
+		goto err_reset;
+	}
+
+	pm_runtime_set_active(madera->dev);
+	pm_runtime_enable(madera->dev);
+	pm_runtime_set_autosuspend_delay(madera->dev, 100);
+	pm_runtime_use_autosuspend(madera->dev);
+
+	ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
+			      mfd_devs, n_devs,
+			      NULL, 0, NULL);
+	if (ret) {
+		dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
+		goto err_pm_runtime;
+	}
+
+	return 0;
+
+err_pm_runtime:
+	pm_runtime_disable(madera->dev);
+err_reset:
+	madera_enable_hard_reset(madera);
+	regulator_disable(madera->dcvdd);
+err_enable:
+	regulator_bulk_disable(madera->num_core_supplies,
+			       madera->core_supplies);
+err_dcvdd:
+	regulator_put(madera->dcvdd);
+err_devs:
+	mfd_remove_devices(dev);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(madera_dev_init);
+
+int madera_dev_exit(struct madera *madera)
+{
+	/* Prevent any IRQs being serviced while we clean up */
+	disable_irq(madera->irq);
+
+	/*
+	 * DCVDD could be supplied by a child node, we must disable it before
+	 * removing the children, and prevent PM runtime from turning it back on
+	 */
+	pm_runtime_disable(madera->dev);
+
+	regulator_disable(madera->dcvdd);
+	regulator_put(madera->dcvdd);
+
+	mfd_remove_devices(madera->dev);
+	madera_enable_hard_reset(madera);
+
+	regulator_bulk_disable(madera->num_core_supplies,
+			       madera->core_supplies);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(madera_dev_exit);
diff --git a/drivers/mfd/madera-i2c.c b/drivers/mfd/madera-i2c.c
new file mode 100644
index 0000000..20e4cd4
--- /dev/null
+++ b/drivers/mfd/madera-i2c.c
@@ -0,0 +1,131 @@
+/*
+ * I2C bus interface to Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+
+#include <linux/mfd/madera/core.h>
+
+#include "madera.h"
+
+static int madera_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct madera *madera;
+	const struct regmap_config *regmap_16bit_config = NULL;
+	const struct regmap_config *regmap_32bit_config = NULL;
+	unsigned long type;
+	int ret;
+
+	if (i2c->dev.of_node)
+		type = madera_get_type_from_of(&i2c->dev);
+	else
+		type = id->driver_data;
+
+	switch (type) {
+	case CS47L35:
+		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
+			regmap_16bit_config = &cs47l35_16bit_i2c_regmap;
+			regmap_32bit_config = &cs47l35_32bit_i2c_regmap;
+		}
+		break;
+	case CS47L85:
+	case WM1840:
+		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
+			regmap_16bit_config = &cs47l85_16bit_i2c_regmap;
+			regmap_32bit_config = &cs47l85_32bit_i2c_regmap;
+		}
+		break;
+	case CS47L90:
+	case CS47L91:
+		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
+			regmap_16bit_config = &cs47l90_16bit_i2c_regmap;
+			regmap_32bit_config = &cs47l90_32bit_i2c_regmap;
+		}
+		break;
+	default:
+		dev_err(&i2c->dev,
+			"Unknown Madera I2C device type %ld\n", type);
+		return -EINVAL;
+	}
+
+	if (!regmap_16bit_config) {
+		dev_err(&i2c->dev,
+			"Kernel does not include support for %s\n",
+			madera_name_from_type(type));
+		return -EINVAL;
+	}
+
+	madera = devm_kzalloc(&i2c->dev, sizeof(*madera), GFP_KERNEL);
+	if (!madera)
+		return -ENOMEM;
+
+	madera->regmap = devm_regmap_init_i2c(i2c, regmap_16bit_config);
+	if (IS_ERR(madera->regmap)) {
+		ret = PTR_ERR(madera->regmap);
+		dev_err(&i2c->dev,
+			"Failed to allocate 16-bit register map: %d\n",	ret);
+		return ret;
+	}
+
+	madera->regmap_32bit = devm_regmap_init_i2c(i2c, regmap_32bit_config);
+	if (IS_ERR(madera->regmap_32bit)) {
+		ret = PTR_ERR(madera->regmap_32bit);
+		dev_err(&i2c->dev,
+			"Failed to allocate 32-bit register map: %d\n", ret);
+		return ret;
+	}
+
+	madera->type = type;
+	madera->dev = &i2c->dev;
+	madera->irq = i2c->irq;
+
+	return madera_dev_init(madera);
+}
+
+static int madera_i2c_remove(struct i2c_client *i2c)
+{
+	struct madera *madera = dev_get_drvdata(&i2c->dev);
+
+	madera_dev_exit(madera);
+
+	return 0;
+}
+
+static const struct i2c_device_id madera_i2c_id[] = {
+	{ "cs47l35", CS47L35 },
+	{ "cs47l85", CS47L85 },
+	{ "cs47l90", CS47L90 },
+	{ "cs47l91", CS47L91 },
+	{ "wm1840", WM1840 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, madera_i2c_id);
+
+static struct i2c_driver madera_i2c_driver = {
+	.driver = {
+		.name	= "madera",
+		.pm	= &madera_pm_ops,
+		.of_match_table	= of_match_ptr(madera_of_match),
+	},
+	.probe		= madera_i2c_probe,
+	.remove		= madera_i2c_remove,
+	.id_table	= madera_i2c_id,
+};
+
+module_i2c_driver(madera_i2c_driver);
+
+MODULE_DESCRIPTION("Madera I2C bus interface");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/madera-spi.c b/drivers/mfd/madera-spi.c
new file mode 100644
index 0000000..375bb36
--- /dev/null
+++ b/drivers/mfd/madera-spi.c
@@ -0,0 +1,132 @@
+/*
+ * SPI bus interface to Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/madera/core.h>
+
+#include "madera.h"
+
+static int madera_spi_probe(struct spi_device *spi)
+{
+	const struct spi_device_id *id = spi_get_device_id(spi);
+	struct madera *madera;
+	const struct regmap_config *regmap_16bit_config = NULL;
+	const struct regmap_config *regmap_32bit_config = NULL;
+	unsigned long type;
+	int ret;
+
+	if (spi->dev.of_node)
+		type = madera_get_type_from_of(&spi->dev);
+	else
+		type = id->driver_data;
+
+	switch (type) {
+	case CS47L35:
+		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
+			regmap_16bit_config = &cs47l35_16bit_spi_regmap;
+			regmap_32bit_config = &cs47l35_32bit_spi_regmap;
+		}
+		break;
+	case CS47L85:
+	case WM1840:
+		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
+			regmap_16bit_config = &cs47l85_16bit_spi_regmap;
+			regmap_32bit_config = &cs47l85_32bit_spi_regmap;
+		}
+		break;
+	case CS47L90:
+	case CS47L91:
+		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
+			regmap_16bit_config = &cs47l90_16bit_spi_regmap;
+			regmap_32bit_config = &cs47l90_32bit_spi_regmap;
+		}
+		break;
+	default:
+		dev_err(&spi->dev,
+			"Unknown Madera SPI device type %ld\n", type);
+		return -EINVAL;
+	}
+
+	if (!regmap_16bit_config) {
+		dev_err(&spi->dev,
+			"Kernel does not include support for %s\n",
+			madera_name_from_type(type));
+		return -EINVAL;
+	}
+
+	madera = devm_kzalloc(&spi->dev, sizeof(*madera), GFP_KERNEL);
+	if (!madera)
+		return -ENOMEM;
+
+	madera->regmap = devm_regmap_init_spi(spi, regmap_16bit_config);
+	if (IS_ERR(madera->regmap)) {
+		ret = PTR_ERR(madera->regmap);
+		dev_err(&spi->dev,
+			"Failed to allocate 16-bit register map: %d\n",	ret);
+		return ret;
+	}
+
+	madera->regmap_32bit = devm_regmap_init_spi(spi, regmap_32bit_config);
+	if (IS_ERR(madera->regmap_32bit)) {
+		ret = PTR_ERR(madera->regmap_32bit);
+		dev_err(&spi->dev,
+			"Failed to allocate 32-bit register map: %d\n",	ret);
+		return ret;
+	}
+
+	madera->type = type;
+	madera->dev = &spi->dev;
+	madera->irq = spi->irq;
+
+	return madera_dev_init(madera);
+}
+
+static int madera_spi_remove(struct spi_device *spi)
+{
+	struct madera *madera = spi_get_drvdata(spi);
+
+	madera_dev_exit(madera);
+
+	return 0;
+}
+
+static const struct spi_device_id madera_spi_ids[] = {
+	{ "cs47l35", CS47L35 },
+	{ "cs47l85", CS47L85 },
+	{ "cs47l90", CS47L90 },
+	{ "cs47l91", CS47L91 },
+	{ "wm1840", WM1840 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, madera_spi_ids);
+
+static struct spi_driver madera_spi_driver = {
+	.driver = {
+		.name	= "madera",
+		.owner	= THIS_MODULE,
+		.pm	= &madera_pm_ops,
+		.of_match_table	= of_match_ptr(madera_of_match),
+	},
+	.probe		= madera_spi_probe,
+	.remove		= madera_spi_remove,
+	.id_table	= madera_spi_ids,
+};
+
+module_spi_driver(madera_spi_driver);
+
+MODULE_DESCRIPTION("Madera SPI bus interface");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/madera.h b/drivers/mfd/madera.h
new file mode 100644
index 0000000..6d1b5b8
--- /dev/null
+++ b/drivers/mfd/madera.h
@@ -0,0 +1,52 @@
+/*
+ * MFD internals for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_MFD_H
+#define MADERA_MFD_H
+
+#include <linux/of.h>
+#include <linux/pm.h>
+
+struct madera;
+
+extern const struct dev_pm_ops madera_pm_ops;
+extern const struct of_device_id madera_of_match[];
+
+int madera_dev_init(struct madera *madera);
+int madera_dev_exit(struct madera *madera);
+
+#ifdef CONFIG_OF
+unsigned long madera_get_type_from_of(struct device *dev);
+#else
+static inline unsigned long madera_get_type_from_of(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+extern const struct regmap_config cs47l35_16bit_spi_regmap;
+extern const struct regmap_config cs47l35_32bit_spi_regmap;
+extern const struct regmap_config cs47l35_16bit_i2c_regmap;
+extern const struct regmap_config cs47l35_32bit_i2c_regmap;
+int cs47l35_patch(struct madera *madera);
+
+extern const struct regmap_config cs47l85_16bit_spi_regmap;
+extern const struct regmap_config cs47l85_32bit_spi_regmap;
+extern const struct regmap_config cs47l85_16bit_i2c_regmap;
+extern const struct regmap_config cs47l85_32bit_i2c_regmap;
+int cs47l85_patch(struct madera *madera);
+
+extern const struct regmap_config cs47l90_16bit_spi_regmap;
+extern const struct regmap_config cs47l90_32bit_spi_regmap;
+extern const struct regmap_config cs47l90_16bit_i2c_regmap;
+extern const struct regmap_config cs47l90_32bit_i2c_regmap;
+int cs47l90_patch(struct madera *madera);
+
+#endif
diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
new file mode 100644
index 0000000..6609e3c
--- /dev/null
+++ b/include/linux/mfd/madera/core.h
@@ -0,0 +1,180 @@
+/*
+ * MFD internals for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_CORE_H
+#define MADERA_CORE_H
+
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/regmap.h>
+#include <linux/gpio/consumer.h>
+#include <linux/irqchip/irq-madera.h>
+#include <linux/mfd/madera/pdata.h>
+#include <linux/regulator/consumer.h>
+#include <sound/madera-pdata.h>
+
+enum madera_type {
+	CS47L35 = 1,
+	CS47L85 = 2,
+	CS47L90 = 3,
+	CS47L91 = 4,
+	WM1840 = 7,
+};
+
+#define MADERA_MAX_CORE_SUPPLIES	2
+#define MADERA_MAX_GPIOS		40
+
+#define CS47L35_NUM_GPIOS		16
+#define CS47L85_NUM_GPIOS		40
+#define CS47L90_NUM_GPIOS		38
+
+
+/* Notifier events */
+#define MADERA_NOTIFY_VOICE_TRIGGER	0x1
+#define MADERA_NOTIFY_HPDET		0x2
+#define MADERA_NOTIFY_MICDET		0x4
+
+/* GPIO Function Definitions */
+#define MADERA_GP_FN_ALTERNATE		0x00
+#define MADERA_GP_FN_GPIO		0x01
+#define MADERA_GP_FN_DSP_GPIO		0x02
+#define MADERA_GP_FN_IRQ1		0x03
+#define MADERA_GP_FN_IRQ2		0x04
+#define MADERA_GP_FN_FLL1_CLOCK		0x10
+#define MADERA_GP_FN_FLL2_CLOCK		0x11
+#define MADERA_GP_FN_FLL3_CLOCK		0x12
+#define MADERA_GP_FN_FLLAO_CLOCK	0x13
+#define MADERA_GP_FN_FLL1_LOCK		0x18
+#define MADERA_GP_FN_FLL2_LOCK		0x19
+#define MADERA_GP_FN_FLL3_LOCK		0x1A
+#define MADERA_GP_FN_FLLAO_LOCK		0x1B
+#define MADERA_GP_FN_OPCLK_OUT		0x40
+#define MADERA_GP_FN_OPCLK_ASYNC_OUT	0x41
+#define MADERA_GP_FN_PWM1		0x48
+#define MADERA_GP_FN_PWM2		0x49
+#define MADERA_GP_FN_SPDIF_OUT		0x4C
+#define MADERA_GP_FN_HEADPHONE_DET	0x50
+#define MADERA_GP_FN_MIC_DET		0x58
+#define MADERA_GP_FN_DRC1_SIGNAL_DETECT	0x80
+#define MADERA_GP_FN_DRC2_SIGNAL_DETECT	0x81
+#define MADERA_GP_FN_ASRC1_IN1_LOCK	0x88
+#define MADERA_GP_FN_ASRC1_IN2_LOCK	0x89
+#define MADERA_GP_FN_ASRC2_IN1_LOCK	0x8A
+#define MADERA_GP_FN_ASRC2_IN2_LOCK	0x8B
+#define MADERA_GP_FN_DSP_IRQ1		0xA0
+#define MADERA_GP_FN_DSP_IRQ2		0xA1
+#define MADERA_GP_FN_DSP_IRQ3		0xA2
+#define MADERA_GP_FN_DSP_IRQ4		0xA3
+#define MADERA_GP_FN_DSP_IRQ5		0xA4
+#define MADERA_GP_FN_DSP_IRQ6		0xA5
+#define MADERA_GP_FN_DSP_IRQ7		0xA6
+#define MADERA_GP_FN_DSP_IRQ8		0xA7
+#define MADERA_GP_FN_DSP_IRQ9		0xA8
+#define MADERA_GP_FN_DSP_IRQ10		0xA9
+#define MADERA_GP_FN_DSP_IRQ11		0xAA
+#define MADERA_GP_FN_DSP_IRQ12		0xAB
+#define MADERA_GP_FN_DSP_IRQ13		0xAC
+#define MADERA_GP_FN_DSP_IRQ14		0xAD
+#define MADERA_GP_FN_DSP_IRQ15		0xAE
+#define MADERA_GP_FN_DSP_IRQ16		0xAF
+#define MADERA_GP_FN_HPOUT1L_SC		0xB0
+#define MADERA_GP_FN_HPOUT1R_SC		0xB1
+#define MADERA_GP_FN_HPOUT2L_SC		0xB2
+#define MADERA_GP_FN_HPOUT2R_SC		0xB3
+#define MADERA_GP_FN_HPOUT3L_SC		0xB4
+#define MADERA_GP_FN_HPOUT4R_SC		0xB5
+#define MADERA_GP_FN_SPKOUTL_SC		0xB6
+#define MADERA_GP_FN_SPKOUTR_SC		0xB7
+#define MADERA_GP_FN_HPOUT1L_ENA	0xC0
+#define MADERA_GP_FN_HPOUT1R_ENA	0xC1
+#define MADERA_GP_FN_HPOUT2L_ENA	0xC2
+#define MADERA_GP_FN_HPOUT2R_ENA	0xC3
+#define MADERA_GP_FN_HPOUT3L_ENA	0xC4
+#define MADERA_GP_FN_HPOUT4R_ENA	0xC5
+#define MADERA_GP_FN_SPKOUTL_ENA	0xC6
+#define MADERA_GP_FN_SPKOUTR_ENA	0xC7
+#define MADERA_GP_FN_HPOUT1L_DIS	0xD0
+#define MADERA_GP_FN_HPOUT1R_DIS	0xD1
+#define MADERA_GP_FN_HPOUT2L_DIS	0xD2
+#define MADERA_GP_FN_HPOUT2R_DIS	0xD3
+#define MADERA_GP_FN_HPOUT3L_DIS	0xD4
+#define MADERA_GP_FN_HPOUT4R_DIS	0xD5
+#define MADERA_GP_FN_SPKOUTL_DIS	0xD6
+#define MADERA_GP_FN_SPKOUTR_DIS	0xD7
+#define MADERA_GP_FN_SPK_SHUTDOWN	0xE0
+#define MADERA_GP_FN_SPK_OVH_SHUTDOWN	0xE1
+#define MADERA_GP_FN_SPK_OVH_WARN	0xE2
+#define MADERA_GP_FN_TIMER1_STATUS	0x140
+#define MADERA_GP_FN_TIMER2_STATUS	0x141
+#define MADERA_GP_FN_TIMER3_STATUS	0x142
+#define MADERA_GP_FN_TIMER4_STATUS	0x143
+#define MADERA_GP_FN_TIMER5_STATUS	0x144
+#define MADERA_GP_FN_TIMER6_STATUS	0x145
+#define MADERA_GP_FN_TIMER7_STATUS	0x146
+#define MADERA_GP_FN_TIMER8_STATUS	0x147
+#define MADERA_GP_FN_EVENTLOG1_FIFO_STS	0x150
+#define MADERA_GP_FN_EVENTLOG2_FIFO_STS	0x151
+#define MADERA_GP_FN_EVENTLOG3_FIFO_STS	0x152
+#define MADERA_GP_FN_EVENTLOG4_FIFO_STS	0x153
+#define MADERA_GP_FN_EVENTLOG5_FIFO_STS	0x154
+#define MADERA_GP_FN_EVENTLOG6_FIFO_STS	0x155
+#define MADERA_GP_FN_EVENTLOG7_FIFO_STS	0x156
+#define MADERA_GP_FN_EVENTLOG8_FIFO_STS	0x157
+
+struct snd_soc_dapm_context;
+
+/*
+ * struct madera
+ *
+ * This should not be used by anything except child drivers of the Madera MFD
+ */
+struct madera {
+	struct regmap *regmap;
+	struct regmap *regmap_32bit;
+
+	struct device *dev;
+
+	enum madera_type type;
+	unsigned int rev;
+
+	struct gpio_desc *reset_gpio;
+
+	int num_core_supplies;
+	struct regulator_bulk_data core_supplies[MADERA_MAX_CORE_SUPPLIES];
+	struct regulator *dcvdd;
+	bool internal_dcvdd;
+
+	struct madera_pdata pdata;
+
+	struct device *irq_dev;
+	int irq;
+
+	unsigned int out_clamp[MADERA_MAX_OUTPUT];
+	unsigned int out_shorted[MADERA_MAX_OUTPUT];
+	unsigned int hp_ena;
+
+	struct snd_soc_dapm_context *dapm;
+
+	struct blocking_notifier_head notifier;
+};
+
+unsigned int madera_get_num_micbias(struct madera *madera);
+unsigned int madera_get_num_childbias(struct madera *madera,
+				      unsigned int micbias);
+
+const char *madera_name_from_type(enum madera_type type);
+
+static inline int madera_call_notifiers(struct madera *madera,
+					unsigned long event,
+					void *data)
+{
+	return blocking_notifier_call_chain(&madera->notifier, event, data);
+}
+#endif
diff --git a/include/linux/mfd/madera/pdata.h b/include/linux/mfd/madera/pdata.h
new file mode 100644
index 0000000..b3af47c
--- /dev/null
+++ b/include/linux/mfd/madera/pdata.h
@@ -0,0 +1,61 @@
+/*
+ * Platform data for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_PDATA_H
+#define MADERA_PDATA_H
+
+#include <linux/kernel.h>
+#include <linux/irqchip/irq-madera-pdata.h>
+#include <linux/regulator/arizona-ldo1.h>
+#include <linux/regulator/arizona-micsupp.h>
+#include <linux/regulator/machine.h>
+#include <sound/madera-pdata.h>
+
+#define MADERA_MAX_MICBIAS		4
+#define MADERA_MAX_CHILD_MICBIAS	4
+
+#define MADERA_MAX_GPSW			2
+
+struct pinctrl_map;
+
+/**
+ * struct madera_pdata - Configuration data for Madera devices
+ *
+ * @reset:	    GPIO controlling /RESET (0 = none)
+ * @ldo1:	    Substruct of pdata for the LDO1 regulator
+ * @micvdd:	    Substruct of pdata for the MICVDD regulator
+ * @irqchip:	    Substruct of pdata for the irqchip driver
+ * @gpio_base:	    Base GPIO number
+ * @gpio_configs:   Array of GPIO configurations (See Documentation/pinctrl.txt)
+ * @n_gpio_configs: Number of entries in gpio_configs
+ * @codec:	    Substructure of pdata for the ASoC codec driver
+ *		    See include/sound/madera-pdata.h
+ * @gpsw:	    General purpose switch mode setting (See the SW1_MODE field
+ *		    in the datasheet for the available values for your codec)
+ */
+struct madera_pdata {
+	int reset;
+
+	struct arizona_ldo1_pdata ldo1;
+	struct arizona_micsupp_pdata micvdd;
+
+	struct madera_irqchip_pdata irqchip;
+
+	int gpio_base;
+
+	const struct pinctrl_map *gpio_configs;
+	int n_gpio_configs;
+
+	struct madera_codec_pdata codec;
+
+	u32 gpsw[MADERA_MAX_GPSW];
+};
+
+#endif
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1630345 — Re: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic Madera codecs

FromLinus Walleij <linus.walleij@linaro.org>
Date2017-04-25 11:50 +0200
SubjectRe: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic Madera codecs
Message-ID<tA5gB-2XU-11@gated-at.bofh.it>
In reply to#1629742
On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
<rf@opensource.wolfsonmicro.com> wrote:

> These codecs have a variable number of I/O lines each of which
> is individually selectable to a wide range of possible functions.
>
> The functionality is slightly different from the traditional muxed
> GPIO since most of the functions can be mapped to any pin (and even
> the same function to multiple pins). Most pins have a dedicated
> "alternate" function that is only available on that pin. The
> alternate functions are usually a group of signals, though it is
> not always necessary to enable the full group, depending on the
> alternate function and how it is to be used. The mapping between
> alternate functions and GPIO pins varies between codecs depending
> on the number of alternate functions and available pins.
>
> Note on the Kconfig options:
> The formula "default y if..." is used for PINCTRL_MADERA so that its
> select options will be processed, allowing us to group selects for
> pinctrl into the pinctrl Kconfig where they logically belong instead
> of accumulating under the parent MFD Kconfig.
>
> Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
(...)

> Changes since V1:

This is starting to look good!

In fact, kind of finished. Except:

> +       if (pdata) {
> +               ret = pinctrl_register_mappings(pdata->gpio_configs,
> +                                               pdata->n_gpio_configs);
> +               if (ret) {
> +                       dev_err(priv->dev,
> +                               "Failed to register pdata mappings (%d)\n",
> +                               ret);
> +                       return ret;
> +               }
> +       }

What is this? It looks like boardfile support which we do not like to
encourage. Why are the mappings not exclusively set up from
device tree or similar?

Yours,
Linus Walleij

[toc] | [prev] | [next] | [standalone]


#1630378 — Re: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic Madera codecs

FromRichard Fitzgerald <rf@opensource.wolfsonmicro.com>
Date2017-04-25 12:30 +0200
SubjectRe: [PATCH v2 10/18] pinctrl: madera: Add driver for Cirrus Logic Madera codecs
Message-ID<tA5Tl-3rD-41@gated-at.bofh.it>
In reply to#1630345
On Tue, 2017-04-25 at 11:41 +0200, Linus Walleij wrote:
> On Mon, Apr 24, 2017 at 6:08 PM, Richard Fitzgerald
> <rf@opensource.wolfsonmicro.com> wrote:
> 
> > These codecs have a variable number of I/O lines each of which
> > is individually selectable to a wide range of possible functions.
> >
> > The functionality is slightly different from the traditional muxed
> > GPIO since most of the functions can be mapped to any pin (and even
> > the same function to multiple pins). Most pins have a dedicated
> > "alternate" function that is only available on that pin. The
> > alternate functions are usually a group of signals, though it is
> > not always necessary to enable the full group, depending on the
> > alternate function and how it is to be used. The mapping between
> > alternate functions and GPIO pins varies between codecs depending
> > on the number of alternate functions and available pins.
> >
> > Note on the Kconfig options:
> > The formula "default y if..." is used for PINCTRL_MADERA so that its
> > select options will be processed, allowing us to group selects for
> > pinctrl into the pinctrl Kconfig where they logically belong instead
> > of accumulating under the parent MFD Kconfig.
> >
> > Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
> (...)
> 
> > Changes since V1:
> 
> This is starting to look good!
> 
> In fact, kind of finished. Except:
> 
> > +       if (pdata) {
> > +               ret = pinctrl_register_mappings(pdata->gpio_configs,
> > +                                               pdata->n_gpio_configs);
> > +               if (ret) {
> > +                       dev_err(priv->dev,
> > +                               "Failed to register pdata mappings (%d)\n",
> > +                               ret);
> > +                       return ret;
> > +               }
> > +       }
> 
> What is this? It looks like boardfile support which we do not like to
> encourage. Why are the mappings not exclusively set up from
> device tree or similar?
> 

We want to work on systems that don't use DT for configuration, so we
offer pdata as a fallback across all the drivers. In that case the
configuration is defined as part of the parent pdata struct and this
applies it.

> Yours,
> Linus Walleij

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web