Unverified Commit 038e0da7 authored by Mark Brown's avatar Mark Brown
Browse files

mfd: Immutable branch between MFD, Pinctrl and soundwire due for the v6.6 merge window

Merge tag 'ib-mfd-pinctrl-soundwire-v6.6' of https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into tmp

Immutable branch between MFD, Pinctrl and soundwire due for the v6.6 merge window
parents 2ccdd1b1 d5282a53
Loading
Loading
Loading
Loading
+313 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/cirrus,cs42l43.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Cirrus Logic CS42L43 Audio CODEC

maintainers:
  - patches@opensource.cirrus.com

description: |
  The CS42L43 is an audio CODEC with integrated MIPI SoundWire interface
  (Version 1.2.1 compliant), I2C, SPI, and I2S/TDM interfaces designed
  for portable applications. It provides a high dynamic range, stereo
  DAC for headphone output, two integrated Class D amplifiers for
  loudspeakers, and two ADCs for wired headset microphone input or
  stereo line input. PDM inputs are provided for digital microphones.

allOf:
  - $ref: dai-common.yaml#

properties:
  compatible:
    enum:
      - cirrus,cs42l43

  reg:
    maxItems: 1

  vdd-p-supply:
    description:
      Power supply for the high voltage interface.

  vdd-a-supply:
    description:
      Power supply for internal analog circuits.

  vdd-d-supply:
    description:
      Power supply for internal digital circuits. Can be internally supplied.

  vdd-io-supply:
    description:
      Power supply for external interface and internal digital logic.

  vdd-cp-supply:
    description:
      Power supply for the amplifier 3 and 4 charge pump.

  vdd-amp-supply:
    description:
      Power supply for amplifier 1 and 2.

  reset-gpios:
    maxItems: 1

  interrupt-controller: true

  "#interrupt-cells":
    const: 2

  interrupts:
    maxItems: 1

  "#sound-dai-cells":
    const: 1

  clocks:
    items:
      - description: Synchronous audio clock provided on mclk_in.

  clock-names:
    const: mclk

  cirrus,bias-low:
    type: boolean
    description:
      Select a 1.8V headset micbias rather than 2.8V.

  cirrus,bias-sense-microamp:
    description:
      Current at which the headset micbias sense clamp will engage, 0 to
      disable.
    enum: [ 0, 14, 23, 41, 50, 60, 68, 86, 95 ]
    default: 0

  cirrus,bias-ramp-ms:
    description:
      Time in milliseconds the hardware allows for the headset micbias to
      ramp up.
    enum: [ 10, 40, 90, 170 ]
    default: 170

  cirrus,detect-us:
    description:
      Time in microseconds the type detection will run for. Long values will
      cause more audible effects, but give more accurate detection.
    enum: [ 20, 100, 1000, 10000, 50000, 75000, 100000, 200000 ]
    default: 10000

  cirrus,button-automute:
    type: boolean
    description:
      Enable the hardware automuting of decimator 1 when a headset button is
      pressed.

  cirrus,buttons-ohms:
    description:
      Impedance in Ohms for each headset button, these should be listed in
      ascending order.
    minItems: 1
    maxItems: 6

  cirrus,tip-debounce-ms:
    description:
      Software debounce on tip sense triggering in milliseconds.
    default: 0

  cirrus,tip-invert:
    type: boolean
    description:
      Indicates tip detect polarity, inverted implies open-circuit whilst the
      jack is inserted.

  cirrus,tip-disable-pullup:
    type: boolean
    description:
      Indicates if the internal pullup on the tip detect should be disabled.

  cirrus,tip-fall-db-ms:
    description:
      Time in milliseconds a falling edge on the tip detect should be hardware
      debounced for. Note the falling edge is considered after the invert.
    enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
    default: 500

  cirrus,tip-rise-db-ms:
    description:
      Time in milliseconds a rising edge on the tip detect should be hardware
      debounced for. Note the rising edge is considered after the invert.
    enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
    default: 500

  cirrus,use-ring-sense:
    type: boolean
    description:
      Indicates if the ring sense should be used.

  cirrus,ring-invert:
    type: boolean
    description:
      Indicates ring detect polarity, inverted implies open-circuit whilst the
      jack is inserted.

  cirrus,ring-disable-pullup:
    type: boolean
    description:
      Indicates if the internal pullup on the ring detect should be disabled.

  cirrus,ring-fall-db-ms:
    description:
      Time in milliseconds a falling edge on the ring detect should be hardware
      debounced for. Note the falling edge is considered after the invert.
    enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
    default: 500

  cirrus,ring-rise-db-ms:
    description:
      Time in milliseconds a rising edge on the ring detect should be hardware
      debounced for. Note the rising edge is considered after the invert.
    enum: [ 0, 125, 250, 500, 750, 1000, 1250, 1500 ]
    default: 500

  pinctrl:
    type: object
    $ref: /schemas/pinctrl/pinctrl.yaml#
    additionalProperties: false

    properties:
      gpio-controller: true

      "#gpio-cells":
        const: 2

      gpio-ranges:
        items:
          - description: A phandle to the CODEC pinctrl node
            minimum: 0
          - const: 0
          - const: 0
          - const: 3

    patternProperties:
      "-state$":
        oneOf:
          - $ref: "#/$defs/cirrus-cs42l43-state"
          - patternProperties:
              "-pins$":
                $ref: "#/$defs/cirrus-cs42l43-state"
            additionalProperties: false

  spi:
    type: object
    $ref: /schemas/spi/spi-controller.yaml#
    unevaluatedProperties: false

$defs:
  cirrus-cs42l43-state:
    type: object

    allOf:
      - $ref: /schemas/pinctrl/pincfg-node.yaml#
      - $ref: /schemas/pinctrl/pinmux-node.yaml#

    oneOf:
      - required: [ groups ]
      - required: [ pins ]

    additionalProperties: false

    properties:
      groups:
        enum: [ gpio1, gpio2, gpio3, asp, pdmout2, pdmout1, i2c, spi ]

      pins:
        enum: [ gpio1, gpio2, gpio3,
                asp_dout, asp_fsync, asp_bclk,
                pdmout2_clk, pdmout2_data, pdmout1_clk, pdmout1_data,
                i2c_sda, i2c_scl,
                spi_miso, spi_sck, spi_ssb ]

      function:
        enum: [ gpio, spdif, irq, mic-shutter, spk-shutter ]

      drive-strength:
        description: Set drive strength in mA
        enum: [ 1, 2, 4, 8, 9, 10, 12, 16 ]

      input-debounce:
        description: Set input debounce in uS
        enum: [ 0, 85 ]

required:
  - compatible
  - reg
  - vdd-p-supply
  - vdd-a-supply
  - vdd-io-supply
  - vdd-cp-supply

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>

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

        cs42l43: codec@1a {
            compatible = "cirrus,cs42l43";
            reg = <0x1a>;

            vdd-p-supply = <&vdd5v0>;
            vdd-a-supply = <&vdd1v8>;
            vdd-io-supply = <&vdd1v8>;
            vdd-cp-supply = <&vdd1v8>;
            vdd-amp-supply = <&vdd5v0>;

            reset-gpios = <&gpio 0>;

            interrupt-controller;
            #interrupt-cells = <2>;
            interrupt-parent = <&gpio>;
            interrupts = <56 IRQ_TYPE_LEVEL_LOW>;

            #sound-dai-cells = <1>;

            clocks = <&clks 0>;
            clock-names = "mclk";

            cs42l43_pins: pinctrl {
                gpio-controller;
                #gpio-cells = <2>;
                gpio-ranges = <&cs42l43_pins 0 0 3>;

                pinctrl-names = "default";
                pinctrl-0 = <&pinsettings>;

                pinsettings: default-state {
                    shutter-pins {
                        groups = "gpio3";
                        function = "mic-shutter";
                    };
                };
            };

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

                cs-gpios = <&cs42l43_pins 1 0>;

                sensor@0 {
                    compatible = "bosch,bme680";
                    reg = <0>;
                    spi-max-frequency = <1400000>;
                };
            };
        };
    };
+3 −0
Original line number Diff line number Diff line
@@ -4886,7 +4886,10 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
L:	patches@opensource.cirrus.com
S:	Maintained
F:	Documentation/devicetree/bindings/sound/cirrus,cs*
F:	drivers/mfd/cs42l43*
F:	drivers/pinctrl/cirrus/pinctrl-cs42l43*
F:	include/dt-bindings/sound/cs*
F:	include/linux/mfd/cs42l43*
F:	include/sound/cs*
F:	sound/pci/hda/cs*
F:	sound/pci/hda/hda_cs_dsp_ctl.*
+23 −0
Original line number Diff line number Diff line
@@ -237,6 +237,29 @@ config MFD_CROS_EC_DEV
	  To compile this driver as a module, choose M here: the module will be
	  called cros-ec-dev.

config MFD_CS42L43
	tristate
	select MFD_CORE
	select REGMAP

config MFD_CS42L43_I2C
	tristate "Cirrus Logic CS42L43 (I2C)"
	depends on I2C
	select REGMAP_I2C
	select MFD_CS42L43
	help
	  Select this to support the Cirrus Logic CS42L43 PC CODEC with
	  headphone and class D speaker drivers over I2C.

config MFD_CS42L43_SDW
	tristate "Cirrus Logic CS42L43 (SoundWire)"
	depends on SOUNDWIRE
	select REGMAP_SOUNDWIRE
	select MFD_CS42L43
	help
	  Select this to support the Cirrus Logic CS42L43 PC CODEC with
	  headphone and class D speaker drivers over SoundWire.

config MFD_MADERA
	tristate "Cirrus Logic Madera codecs"
	select MFD_CORE
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,9 @@ obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o
obj-$(CONFIG_MFD_BCM590XX)	+= bcm590xx.o
obj-$(CONFIG_MFD_BD9571MWV)	+= bd9571mwv.o
obj-$(CONFIG_MFD_CROS_EC_DEV)	+= cros_ec_dev.o
obj-$(CONFIG_MFD_CS42L43)	+= cs42l43.o
obj-$(CONFIG_MFD_CS42L43_I2C)	+= cs42l43-i2c.o
obj-$(CONFIG_MFD_CS42L43_SDW)	+= cs42l43-sdw.o
obj-$(CONFIG_MFD_ENE_KB3930)	+= ene-kb3930.o
obj-$(CONFIG_MFD_EXYNOS_LPASS)	+= exynos-lpass.o
obj-$(CONFIG_MFD_GATEWORKS_GSC)	+= gateworks-gsc.o
+98 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * CS42L43 I2C driver
 *
 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and
 *                         Cirrus Logic International Semiconductor Ltd.
 */

#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/mfd/cs42l43-regs.h>
#include <linux/module.h>

#include "cs42l43.h"

static const struct regmap_config cs42l43_i2c_regmap = {
	.reg_bits		= 32,
	.reg_stride		= 4,
	.val_bits		= 32,
	.reg_format_endian	= REGMAP_ENDIAN_BIG,
	.val_format_endian	= REGMAP_ENDIAN_BIG,

	.max_register		= CS42L43_MCU_RAM_MAX,
	.readable_reg		= cs42l43_readable_register,
	.volatile_reg		= cs42l43_volatile_register,
	.precious_reg		= cs42l43_precious_register,

	.cache_type		= REGCACHE_MAPLE,
	.reg_defaults		= cs42l43_reg_default,
	.num_reg_defaults	= ARRAY_SIZE(cs42l43_reg_default),
};

static int cs42l43_i2c_probe(struct i2c_client *i2c)
{
	struct cs42l43 *cs42l43;
	int ret;

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

	cs42l43->dev = &i2c->dev;
	cs42l43->irq = i2c->irq;
	/* A device on an I2C is always attached by definition. */
	cs42l43->attached = true;

	cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
	if (IS_ERR(cs42l43->regmap)) {
		ret = PTR_ERR(cs42l43->regmap);
		dev_err(cs42l43->dev, "Failed to allocate regmap: %d\n", ret);
		return ret;
	}

	return cs42l43_dev_probe(cs42l43);
}

static void cs42l43_i2c_remove(struct i2c_client *i2c)
{
	struct cs42l43 *cs42l43 = dev_get_drvdata(&i2c->dev);

	cs42l43_dev_remove(cs42l43);
}

#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id cs42l43_of_match[] = {
	{ .compatible = "cirrus,cs42l43", },
	{}
};
MODULE_DEVICE_TABLE(of, cs42l43_of_match);
#endif

#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id cs42l43_acpi_match[] = {
	{ "CSC4243", 0 },
	{}
};
MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);
#endif

static struct i2c_driver cs42l43_i2c_driver = {
	.driver = {
		.name			= "cs42l43",
		.pm			= pm_ptr(&cs42l43_pm_ops),
		.of_match_table		= of_match_ptr(cs42l43_of_match),
		.acpi_match_table	= ACPI_PTR(cs42l43_acpi_match),
	},

	.probe		= cs42l43_i2c_probe,
	.remove		= cs42l43_i2c_remove,
};
module_i2c_driver(cs42l43_i2c_driver);

MODULE_IMPORT_NS(MFD_CS42L43);

MODULE_DESCRIPTION("CS42L43 I2C Driver");
MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");
MODULE_LICENSE("GPL");
Loading