* [PATCH 06/22] ARM: dts: imx7-colibri: add GPIO wakeup key
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Stefan Agner, Sascha Hauer, linux-kernel, Philippe Schenker,
NXP Linux Team, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Stefan Agner <stefan.agner@toradex.com>
Add wakeup GPIO key which is able to wake the system from sleep
modes (e.g. Suspend-to-Memory).
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 14 ++++++++++++++
arch/arm/boot/dts/imx7-colibri.dtsi | 7 ++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
index 3f2746169181..d4dbc4fc1adf 100644
--- a/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi
@@ -52,6 +52,20 @@
clock-frequency = <16000000>;
};
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+
+ power {
+ label = "Wake-Up";
+ gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_WAKEUP>;
+ debounce-interval = <10>;
+ gpio-key,wakeup;
+ };
+ };
+
panel: panel {
compatible = "edt,et057090dhu";
backlight = <&bl>;
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 2480623c92ff..16d1a1ed1aff 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -741,12 +741,17 @@
pinctrl_gpio_lpsr: gpio1-grp {
fsl,pins = <
- MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x59
MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x59
MX7D_PAD_LPSR_GPIO1_IO03__GPIO1_IO3 0x59
>;
};
+ pinctrl_gpiokeys: gpiokeysgrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x19
+ >;
+ };
+
pinctrl_i2c1: i2c1-grp {
fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO05__I2C1_SDA 0x4000007f
--
2.22.0
^ permalink raw reply related
* [PATCH 05/22] ARM: dts: add recovery for I2C for iMX7
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Sascha Hauer, linux-kernel, Oleksandr Suvorov, Philippe Schenker,
NXP Linux Team, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
- add recovery mode for applicable i2c buses for
Colibri iMX7 module.
Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri.dtsi | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index a8d992f3e897..2480623c92ff 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -140,8 +140,12 @@
&i2c1 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1 &pinctrl_i2c1_int>;
+ pinctrl-1 = <&pinctrl_i2c1_recovery &pinctrl_i2c1_int>;
+ scl-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+
status = "okay";
codec: sgtl5000@a {
@@ -242,8 +246,11 @@
&i2c4 {
clock-frequency = <100000>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c4>;
+ pinctrl-1 = <&pinctrl_i2c4_recovery>;
+ scl-gpios = <&gpio7 8 GPIO_ACTIVE_HIGH>;
+ sda-gpios = <&gpio7 9 GPIO_ACTIVE_HIGH>;
};
&lcdif {
@@ -540,6 +547,13 @@
>;
};
+ pinctrl_i2c4_recovery: i2c4-recoverygrp {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_TD2__GPIO7_IO8 0x4000007f
+ MX7D_PAD_ENET1_RGMII_TD3__GPIO7_IO9 0x4000007f
+ >;
+ };
+
pinctrl_lcdif_dat: lcdif-dat-grp {
fsl,pins = <
MX7D_PAD_LCD_DATA00__LCD_DATA0 0x79
@@ -740,6 +754,13 @@
>;
};
+ pinctrl_i2c1_recovery: i2c1-recoverygrp {
+ fsl,pins = <
+ MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x4000007f
+ MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x4000007f
+ >;
+ };
+
pinctrl_cd_usdhc1: usdhc1-cd-grp {
fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO00__GPIO1_IO0 0x59 /* CD */
--
2.22.0
^ permalink raw reply related
* [PATCH 04/22] ARM: dts: imx7-colibri: Add sleep mode to ethernet
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Sascha Hauer, linux-kernel, Philippe Schenker, NXP Linux Team,
Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Philippe Schenker <philippe.schenker@toradex.com>
Add sleep pinmux to the fec so it can properly sleep.
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri.dtsi | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 52046085ce6f..a8d992f3e897 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -101,8 +101,9 @@
};
&fec1 {
- pinctrl-names = "default";
+ pinctrl-names = "default", "sleep";
pinctrl-0 = <&pinctrl_enet1>;
+ pinctrl-1 = <&pinctrl_enet1_sleep>;
clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
@@ -463,6 +464,22 @@
>;
};
+ pinctrl_enet1_sleep: enet1sleepgrp {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RX_CTL__GPIO7_IO4 0x0
+ MX7D_PAD_ENET1_RGMII_RD0__GPIO7_IO0 0x0
+ MX7D_PAD_ENET1_RGMII_RD1__GPIO7_IO1 0x0
+ MX7D_PAD_ENET1_RGMII_RXC__GPIO7_IO5 0x0
+
+ MX7D_PAD_ENET1_RGMII_TX_CTL__GPIO7_IO10 0x0
+ MX7D_PAD_ENET1_RGMII_TD0__GPIO7_IO6 0x0
+ MX7D_PAD_ENET1_RGMII_TD1__GPIO7_IO7 0x0
+ MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x0
+ MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x0
+ MX7D_PAD_SD2_WP__GPIO5_IO10 0x0
+ >;
+ };
+
pinctrl_ecspi3_cs: ecspi3-cs-grp {
fsl,pins = <
MX7D_PAD_I2C2_SDA__GPIO4_IO11 0x14
--
2.22.0
^ permalink raw reply related
* [PATCH 03/22] ARM: dts: imx7-colibri: prepare module device tree for FlexCAN
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Sascha Hauer, linux-kernel, Philippe Schenker, NXP Linux Team,
Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Philippe Schenker <philippe.schenker@toradex.com>
Prepare FlexCAN use on SODIMM 55/63 178/188. Those SODIMM pins are
compatible for CAN bus use with several modules from the Colibri
family.
Add Better drivestrength and also add flexcan2.
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri.dtsi | 35 ++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index f7c9ce5bed47..52046085ce6f 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -117,6 +117,18 @@
fsl,magic-packet;
};
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "disabled";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "disabled";
+};
+
&gpmi {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpmi_nand>;
@@ -330,12 +342,11 @@
&iomuxc {
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4>;
+ pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
+ &pinctrl_gpio7>;
pinctrl_gpio1: gpio1-grp {
fsl,pins = <
- MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x74 /* SODIMM 55 */
- MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x74 /* SODIMM 63 */
MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16 0x14 /* SODIMM 77 */
MX7D_PAD_EPDC_DATA09__GPIO2_IO9 0x14 /* SODIMM 89 */
MX7D_PAD_EPDC_DATA08__GPIO2_IO8 0x74 /* SODIMM 91 */
@@ -416,6 +427,13 @@
>;
};
+ pinctrl_gpio7: gpio7-grp { /* Alternatively CAN1 */
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x14 /* SODIMM 55 */
+ MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x14 /* SODIMM 63 */
+ >;
+ };
+
pinctrl_i2c1_int: i2c1-int-grp { /* PMIC / TOUCH */
fsl,pins = <
MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x79
@@ -459,10 +477,17 @@
>;
};
+ pinctrl_flexcan1: flexcan1-grp {
+ fsl,pins = <
+ MX7D_PAD_ENET1_RGMII_RD3__FLEXCAN1_TX 0x79 /* SODIMM 55 */
+ MX7D_PAD_ENET1_RGMII_RD2__FLEXCAN1_RX 0x79 /* SODIMM 63 */
+ >;
+ };
+
pinctrl_flexcan2: flexcan2-grp {
fsl,pins = <
- MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x59
- MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x59
+ MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX 0x79 /* SODIMM 188 */
+ MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX 0x79 /* SODIMM 178 */
>;
};
--
2.22.0
^ permalink raw reply related
* [PATCH 02/22] ARM: dts: imx7-colibri: disable HS400
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Stefan Agner, Sascha Hauer, linux-kernel, Philippe Schenker,
NXP Linux Team, Pengutronix Kernel Team, Fabio Estevam,
linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Stefan Agner <stefan.agner@toradex.com>
Force HS200 by masking bit 63 of the SDHCI capability register.
The i.MX ESDHC driver uses SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400. With
that the stack checks bit 63 to descide whether HS400 is available.
Using sdhci-caps-mask allows to mask bit 63. The stack then selects
HS200 as operating mode.
This prevents rare communication errors with minimal effect on
performance:
sdhci-esdhc-imx 30b60000.usdhc: warning! HS400 strobe DLL
status REF not lock!
Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index f1c1971f2160..f7c9ce5bed47 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -325,6 +325,7 @@
vmmc-supply = <®_module_3v3>;
vqmmc-supply = <®_DCDC3>;
non-removable;
+ sdhci-caps-mask = <0x80000000 0x0>;
};
&iomuxc {
--
2.22.0
^ permalink raw reply related
* [PATCH 01/22] ARM: dts: imx7-colibri: make sure module supplies are always on
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Sascha Hauer, linux-kernel, Philippe Schenker, NXP Linux Team,
Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
In-Reply-To: <20190730144649.19022-1-dev@pschenker.ch>
From: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Prevent regulators from being switched off.
Signed-off-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com>
---
arch/arm/boot/dts/imx7-colibri.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 895fbde4d433..f1c1971f2160 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -54,6 +54,7 @@
regulator-name = "+V3.3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
reg_module_3v3_avdd: regulator-module-3v3-avdd {
@@ -61,6 +62,7 @@
regulator-name = "+V3.3_AVDD_AUDIO";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
+ regulator-always-on;
};
sound {
--
2.22.0
^ permalink raw reply related
* [PATCH 00/22] This patchset holds some common changes that were never upstreamed.
From: Philippe Schenker @ 2019-07-30 14:46 UTC (permalink / raw)
To: marcel.ziswiler, max.krummenacher, stefan, devicetree,
Rob Herring, Shawn Guo, Mark Rutland
Cc: Sascha Hauer, linux-kernel, Philippe Schenker, NXP Linux Team,
Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel
From: Philippe Schenker <philippe.schenker@toradex.com>
With latest downstream kernel upgrade, I took the aproach to select
mainline devicetrees and atomically add missing stuff for downstream.
These patches I send here are separated out with changes that also
have a benfit for mainline.
Philippe
Marcel Ziswiler (1):
ARM: dts: imx7-colibri: make sure module supplies are always on
Max Krummenacher (2):
ARM: dts: imx6ull-colibri: reduce v_batt current in power off
ARM: dts: imx6ull: improve can templates
Oleksandr Suvorov (1):
ARM: dts: add recovery for I2C for iMX7
Philippe Schenker (15):
ARM: dts: imx7-colibri: prepare module device tree for FlexCAN
ARM: dts: imx7-colibri: Add sleep mode to ethernet
ARM: dts: imx7-colibri: Add touch controllers
ARM: dts: imx6qdl-colibri: add phy to fec
ARM: dts: imx6qdl-colibri: Add missing pin declaration in iomuxc
ARM: dts: imx6: Add sleep state to can interfaces
ARM: dts: imx6: Add touchscreens used on Toradex eval boards
ARM: dts: colibri-imx6: Add missing pinmuxing to Toradex eval board
ARM: dts: apalis-imx6: Add some example I2C devices
ARM: dts: apalis-imx6: Add some optional I2C devices
ARM: dts: imx6ull-colibri: Add sleep mode to fec
ARM: dts: imx6ull-colibri: Add watchdog
ARM: dts: imx6ull-colibri: Add general wakeup key used on Colibri
ARM: dts: imx6/7-colibri: switch dr_mode to otg
ARM: dts: imx6ull-colibri: Add touchscreens used with Eval Board
Stefan Agner (3):
ARM: dts: imx7-colibri: disable HS400
ARM: dts: imx7-colibri: add GPIO wakeup key
ARM: dts: imx7-colibri: fix 1.8V/UHS support
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 52 ++++++++
arch/arm/boot/dts/imx6q-apalis-eval.dts | 122 ++++++++++++++++++
arch/arm/boot/dts/imx6q-apalis-ixora-v1.1.dts | 19 +++
arch/arm/boot/dts/imx6q-apalis-ixora.dts | 19 +++
arch/arm/boot/dts/imx6qdl-apalis.dtsi | 27 +++-
arch/arm/boot/dts/imx6qdl-colibri.dtsi | 27 +++-
.../arm/boot/dts/imx6ull-colibri-eval-v3.dtsi | 63 +++++++++
.../arm/boot/dts/imx6ull-colibri-nonwifi.dtsi | 2 +-
arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi | 2 +-
arch/arm/boot/dts/imx6ull-colibri.dtsi | 52 +++++++-
arch/arm/boot/dts/imx7-colibri-eval-v3.dtsi | 51 ++++++++
arch/arm/boot/dts/imx7-colibri.dtsi | 114 ++++++++++++++--
12 files changed, 524 insertions(+), 26 deletions(-)
--
2.22.0
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier
From: Mark Brown @ 2019-07-30 14:33 UTC (permalink / raw)
To: Thomas Preston
Cc: Marco Felsch, Charles Keepax, Mark Rutland, devicetree,
alsa-devel, Rob Duncan, Kuninori Morimoto, Kirill Marinushkin,
linux-kernel, Takashi Iwai, Liam Girdwood, Annaliese McDermond,
Paul Cercueil, Vinod Koul, Rob Herring, Srinivas Kandagatla,
Nate Case, Cheng-Yi Chiang, Patrick Glaser, Jerome Brunet
In-Reply-To: <16a99e45-fd5a-2878-acf9-63518f9ca527@codethink.co.uk>
[-- Attachment #1: Type: text/plain, Size: 971 bytes --]
On Tue, Jul 30, 2019 at 03:12:21PM +0100, Thomas Preston wrote:
> On 30/07/2019 14:12, Marco Felsch wrote:
> >>> +- compatible : "st,tda7802"
> >>> +- reg : the I2C address of the device
> >>> +- enable-supply : a regulator spec for the PLLen pin
> > Shouldn't that be a pin called 'pllen-gpios'? IMHO I would not use a
> > regulator for that.
> Hi Marco,
> We have multiple amplifiers hooked up in a chain, and all the PLLens
> are connected to one GPIO. So we need to use a regulator so that
> i2c-TDA7802:00 doesn't turn off the PLLen which i2c-TDA7802:01 still
> requires.
> This is why we use a regulator. Is there GPIO support for this?
If it's a GPIO not a regulator then it should be a GPIO not a regulator
in the device tree. The device tree describes the hardware. There was
some work on helping share GPIOs in the GPIO framework to accomodate
GPIOs for regulator enables, you should be able to do something similar
to what the regulator framework does.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Mark Brown @ 2019-07-30 14:20 UTC (permalink / raw)
To: Thomas Preston
Cc: Charles Keepax, Mark Rutland, devicetree, alsa-devel,
Marco Felsch, Kuninori Morimoto, Kirill Marinushkin,
Cheng-Yi Chiang, linux-kernel, Takashi Iwai, Rob Herring,
Liam Girdwood, Paul Cercueil, Vinod Koul, Srinivas Kandagatla,
Annaliese McDermond, Jerome Brunet
In-Reply-To: <e7a879d3-36c2-2df8-97c0-3c4bbd2e7ea2@codethink.co.uk>
[-- Attachment #1: Type: text/plain, Size: 568 bytes --]
On Tue, Jul 30, 2019 at 03:04:19PM +0100, Thomas Preston wrote:
> On 30/07/2019 13:41, Charles Keepax wrote:
> > This could probably be removed using regmap_multi_reg_write.
> The problem is that I want to retain the state of the other bits in those
> registers. Maybe I should make a copy of the backed up state, set the bits
> I want to off-device, then either:
> 1. Write the changes with regmap_multi_reg_write
> 2. Write all six regs again (if my device doesn't support the multi_reg)
Or make this a regmap function, there's nothing device specific about
it.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Mark Brown @ 2019-07-30 14:19 UTC (permalink / raw)
To: Thomas Preston
Cc: Mark Rutland, devicetree, alsa-devel, Charles Keepax,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
Marco Felsch, Takashi Iwai, Annaliese McDermond, Liam Girdwood,
Paul Cercueil, Vinod Koul, Rob Herring, Srinivas Kandagatla,
linux-kernel, Jerome Brunet
In-Reply-To: <20190730120937.16271-4-thomas.preston@codethink.co.uk>
[-- Attachment #1.1: Type: text/plain, Size: 1411 bytes --]
On Tue, Jul 30, 2019 at 01:09:37PM +0100, Thomas Preston wrote:
> + struct dentry *debugfs;
> + struct mutex diagnostic_mutex;
> +};
It is unclear what this mutex usefully protects, it only gets taken when
writing to the debugfs file to trigger this diagnostic mode but doesn't
do anything to control interactions with any other code path in the
driver.
> +static int run_turn_on_diagnostic(struct tda7802_priv *tda7802, u8 *status)
> +{
> + struct device *dev = &tda7802->i2c->dev;
> + int err_status, err;
> + unsigned int val;
> + u8 state[NUM_IB];
> + /* We must wait 20ms for device to settle, otherwise diagnostics will
> + * not start and regmap poll will timeout.
> + */
> + msleep(DIAGNOSTIC_SETTLE_MS);
The comment and define might go out of sync...
> + err = regmap_bulk_read(tda7802->regmap, TDA7802_DB1, status, 4);
> + if (err < 0) {
> + dev_err(dev, "Could not read channel status, %d\n", err);
> + goto diagnostic_restore;
> + }
...but here we use a magic number for the array size :(
> +static int tda7802_diagnostic_show(struct seq_file *f, void *p)
> +{
> + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
We neither use nor free buf?
> +static int tda7802_probe(struct snd_soc_component *component)
> +{
> + struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
> + struct device *dev = &tda7802->i2c->dev;
> + int err;
Why is this done at the component level?
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Charles Keepax @ 2019-07-30 14:18 UTC (permalink / raw)
To: Thomas Preston
Cc: Mark Rutland, devicetree, alsa-devel, Kuninori Morimoto,
Kirill Marinushkin, Liam Girdwood, Mark Brown, Takashi Iwai,
Marco Felsch, Annaliese McDermond, linux-kernel, Paul Cercueil,
Vinod Koul, Rob Herring, Srinivas Kandagatla, Jerome Brunet,
Cheng-Yi Chiang
In-Reply-To: <e7a879d3-36c2-2df8-97c0-3c4bbd2e7ea2@codethink.co.uk>
On Tue, Jul 30, 2019 at 03:04:19PM +0100, Thomas Preston wrote:
> On 30/07/2019 13:41, Charles Keepax wrote:
> >> +static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
> >> + size_t update_count)
> >> +{
> >> + int i, err;
> >> +
> >> + for (i = 0; i < update_count; i++) {
> >> + err = regmap_update_bits(map, update[i].reg, update[i].mask,
> >> + update[i].val);
> >> + if (err < 0)
> >> + return err;
> >> + }
> >> +
> >> + return i;
> >> +}
> >
> > This could probably be removed using regmap_multi_reg_write.
> >
>
> The problem is that I want to retain the state of the other bits in those
> registers. Maybe I should make a copy of the backed up state, set the bits
> I want to off-device, then either:
>
> 1. Write the changes with regmap_multi_reg_write
> 2. Write all six regs again (if my device doesn't support the multi_reg)
>
Nah sorry my bad you are probably better off they way you are.
Thanks,
Charles
^ permalink raw reply
* [PATCH] ARM: dts: socfpga: add missing reset-names for dma
From: Dinh Nguyen @ 2019-07-30 14:15 UTC (permalink / raw)
To: robh+dt, mark.rutland; +Cc: dinguyen, linux-arm-kernel, devicetree
The dma dts node was missing the reset-names = "dma". The reset driver
needs this line to get the reset property.
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
arch/arm/boot/dts/socfpga.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index ec1966480f2f..ba47dc15a5d0 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -85,6 +85,7 @@
clocks = <&l4_main_clk>;
clock-names = "apb_pclk";
resets = <&rst DMA_RESET>;
+ reset-names = "dma";
};
};
--
2.20.0
^ permalink raw reply related
* Re: [alsa-devel] [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier
From: Thomas Preston @ 2019-07-30 14:12 UTC (permalink / raw)
To: Marco Felsch, Charles Keepax
Cc: Mark Rutland, devicetree, alsa-devel, Rob Duncan,
Kuninori Morimoto, Kirill Marinushkin, linux-kernel, Mark Brown,
Takashi Iwai, Liam Girdwood, Annaliese McDermond, Paul Cercueil,
Vinod Koul, Rob Herring, Srinivas Kandagatla, Nate Case,
Cheng-Yi Chiang, Patrick Glaser, Jerome Brunet
In-Reply-To: <20190730131209.rdv2kdlrpfeouh66@pengutronix.de>
On 30/07/2019 14:12, Marco Felsch wrote:
> Hi Charles,
>
> sorry for jumping in..
>
> On 19-07-30 13:27, Charles Keepax wrote:
>> On Tue, Jul 30, 2019 at 01:09:35PM +0100, Thomas Preston wrote:
>>> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
>>> Cc: Patrick Glaser <pglaser@tesla.com>
>>> Cc: Rob Duncan <rduncan@tesla.com>
>>> Cc: Nate Case <ncase@tesla.com>
>>> ---
>>> .../devicetree/bindings/sound/tda7802.txt | 26 +++++++++++++++++++
>>> 1 file changed, 26 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/sound/tda7802.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/sound/tda7802.txt b/Documentation/devicetree/bindings/sound/tda7802.txt
>>> new file mode 100644
>>> index 000000000000..f80aaf4f1ba0
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/sound/tda7802.txt
>>> @@ -0,0 +1,26 @@
>>> +ST TDA7802 audio processor
>>> +
>>> +This device supports I2C only.
>>> +
>>> +Required properties:
>>> +
>>> +- compatible : "st,tda7802"
>>> +- reg : the I2C address of the device
>>> +- enable-supply : a regulator spec for the PLLen pin
>
> Shouldn't that be a pin called 'pllen-gpios'? IMHO I would not use a
> regulator for that.
>
> Regards,
> Marco
>
Hi Marco,
We have multiple amplifiers hooked up in a chain, and all the PLLens
are connected to one GPIO. So we need to use a regulator so that
i2c-TDA7802:00 doesn't turn off the PLLen which i2c-TDA7802:01 still
requires.
This is why we use a regulator. Is there GPIO support for this?
Thanks,
Thomas
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier
From: Thomas Preston @ 2019-07-30 14:10 UTC (permalink / raw)
To: Charles Keepax
Cc: Mark Rutland, devicetree, alsa-devel, Marco Felsch,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
linux-kernel, Nate Case, Takashi Iwai, Rob Herring, Liam Girdwood,
Paul Cercueil, Vinod Koul, Mark Brown, Srinivas Kandagatla,
Annaliese McDermond, Rob Duncan, Patrick Glaser, Jerome Brunet
In-Reply-To: <20190730122748.GF54126@ediswmail.ad.cirrus.com>
On 30/07/2019 13:27, Charles Keepax wrote:
> On Tue, Jul 30, 2019 at 01:09:35PM +0100, Thomas Preston wrote:
>> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
>> Cc: Patrick Glaser <pglaser@tesla.com>
>> Cc: Rob Duncan <rduncan@tesla.com>
>> Cc: Nate Case <ncase@tesla.com>
>> ---
>> .../devicetree/bindings/sound/tda7802.txt | 26 +++++++++++++++++++
>> 1 file changed, 26 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/sound/tda7802.txt
>>
>> diff --git a/Documentation/devicetree/bindings/sound/tda7802.txt b/Documentation/devicetree/bindings/sound/tda7802.txt
>> new file mode 100644
>> index 000000000000..f80aaf4f1ba0
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/tda7802.txt
>> @@ -0,0 +1,26 @@
>> +ST TDA7802 audio processor
>> +
>> +This device supports I2C only.
>> +
>> +Required properties:
>> +
>> +- compatible : "st,tda7802"
>> +- reg : the I2C address of the device
>> +- enable-supply : a regulator spec for the PLLen pin
>> +
>> +Optional properties:
>> +
>> +- st,gain-ch13 : gain for channels 1 and 3 (range: 1-4)
>> +- st,gain-ch24 : gain for channels 2 and 3 (range: 1-4)
>
> I wouldn't have expected the gains to be available as a device
> tree setting.
>
Ah, I forgot to update the docs from v1. Thanks
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Thomas Preston @ 2019-07-30 14:04 UTC (permalink / raw)
To: Charles Keepax
Cc: Mark Rutland, devicetree, alsa-devel, Marco Felsch,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
linux-kernel, Takashi Iwai, Rob Herring, Liam Girdwood,
Paul Cercueil, Vinod Koul, Mark Brown, Srinivas Kandagatla,
Annaliese McDermond, Jerome Brunet
In-Reply-To: <20190730124158.GH54126@ediswmail.ad.cirrus.com>
Hi,
Thanks for getting back to me so quickly.
On 30/07/2019 13:41, Charles Keepax wrote:
> On Tue, Jul 30, 2019 at 01:09:37PM +0100, Thomas Preston wrote:
>> Add a debugfs device node which initiates the turn-on diagnostic routine
>> feature of the TDA7802 amplifier. The four status registers (one per
>> channel) are returned.
>>
>> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
>> ---
>> Changes since v1:
>> - Rename speaker-test to (turn-on) diagnostics
>> - Move turn-on diagnostic to debugfs as there is no standard ALSA
>> interface for this kind of routine.
>>
>> sound/soc/codecs/tda7802.c | 186 ++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 185 insertions(+), 1 deletion(-)
>>
>> +static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
>> + size_t update_count)
>> +{
>> + int i, err;
>> +
>> + for (i = 0; i < update_count; i++) {
>> + err = regmap_update_bits(map, update[i].reg, update[i].mask,
>> + update[i].val);
>> + if (err < 0)
>> + return err;
>> + }
>> +
>> + return i;
>> +}
>
> This could probably be removed using regmap_multi_reg_write.
>
The problem is that I want to retain the state of the other bits in those
registers. Maybe I should make a copy of the backed up state, set the bits
I want to off-device, then either:
1. Write the changes with regmap_multi_reg_write
2. Write all six regs again (if my device doesn't support the multi_reg)
>> +static int tda7802_probe(struct snd_soc_component *component)
>> +{
>> + struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
>> + struct device *dev = &tda7802->i2c->dev;
>> + int err;
>> +
>> + tda7802->debugfs = debugfs_create_dir(dev_name(dev), NULL);
>> + if (IS_ERR_OR_NULL(tda7802->debugfs)) {
>> + dev_info(dev,
>> + "Failed to create debugfs node, err %ld\n",
>> + PTR_ERR(tda7802->debugfs));
>> + return 0;
>> + }
>> +
>> + mutex_init(&tda7802->diagnostic_mutex);
>> + err = debugfs_create_file("diagnostic", 0444, tda7802->debugfs, tda7802,
>> + &tda7802_diagnostic_fops);
>> + if (err < 0) {
>> + dev_err(dev,
>> + "debugfs: Failed to create diagnostic node, err %d\n",
>> + err);
>> + goto cleanup_diagnostic;
>> + }
>
> You shouldn't be failing the driver probe if debugfs fails, it
> should be purely optional.
>
Got it, thanks.
^ permalink raw reply
* Re: [PATCH net-next v4 2/4] enetc: Add mdio bus driver for the PCIe MDIO endpoint
From: Andrew Lunn @ 2019-07-30 13:22 UTC (permalink / raw)
To: Claudiu Manoil
Cc: David S . Miller, Rob Herring, Li Yang, alexandru.marginean,
netdev, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <1564479919-18835-3-git-send-email-claudiu.manoil@nxp.com>
On Tue, Jul 30, 2019 at 12:45:17PM +0300, Claudiu Manoil wrote:
> ENETC ports can manage the MDIO bus via local register
> interface. However there's also a centralized way
> to manage the MDIO bus, via the MDIO PCIe endpoint
> device integrated by the same root complex that also
> integrates the ENETC ports (eth controllers).
>
> Depending on board design and use case, centralized
> access to MDIO may be better than using local ENETC
> port registers. For instance, on the LS1028A QDS board
> where MDIO muxing is required. Also, the LS1028A on-chip
> switch doesn't have a local MDIO register interface.
>
> The current patch registers the above PCIe endpoint as a
> separate MDIO bus and provides a driver for it by re-using
> the code used for local MDIO access. It also allows the
> ENETC port PHYs to be managed by this driver if the local
> "mdio" node is missing from the ENETC port node.
>
> Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier
From: Marco Felsch @ 2019-07-30 13:12 UTC (permalink / raw)
To: Charles Keepax
Cc: Thomas Preston, Liam Girdwood, Mark Brown, Rob Herring,
Mark Rutland, Jaroslav Kysela, Takashi Iwai, Jerome Brunet,
Srinivas Kandagatla, Paul Cercueil, Kirill Marinushkin,
Cheng-Yi Chiang, Kuninori Morimoto, Vinod Koul,
Annaliese McDermond, alsa-devel, devicetree, linux-kernel,
Patrick Glaser, Rob Duncan, Nate
In-Reply-To: <20190730122748.GF54126@ediswmail.ad.cirrus.com>
Hi Charles,
sorry for jumping in..
On 19-07-30 13:27, Charles Keepax wrote:
> On Tue, Jul 30, 2019 at 01:09:35PM +0100, Thomas Preston wrote:
> > Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
> > Cc: Patrick Glaser <pglaser@tesla.com>
> > Cc: Rob Duncan <rduncan@tesla.com>
> > Cc: Nate Case <ncase@tesla.com>
> > ---
> > .../devicetree/bindings/sound/tda7802.txt | 26 +++++++++++++++++++
> > 1 file changed, 26 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/tda7802.txt
> >
> > diff --git a/Documentation/devicetree/bindings/sound/tda7802.txt b/Documentation/devicetree/bindings/sound/tda7802.txt
> > new file mode 100644
> > index 000000000000..f80aaf4f1ba0
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/tda7802.txt
> > @@ -0,0 +1,26 @@
> > +ST TDA7802 audio processor
> > +
> > +This device supports I2C only.
> > +
> > +Required properties:
> > +
> > +- compatible : "st,tda7802"
> > +- reg : the I2C address of the device
> > +- enable-supply : a regulator spec for the PLLen pin
Shouldn't that be a pin called 'pllen-gpios'? IMHO I would not use a
regulator for that.
Regards,
Marco
> > +
> > +Optional properties:
> > +
> > +- st,gain-ch13 : gain for channels 1 and 3 (range: 1-4)
> > +- st,gain-ch24 : gain for channels 2 and 3 (range: 1-4)
>
> I wouldn't have expected the gains to be available as a device
> tree setting.
>
> > +- st,diagnostic-mode-ch13 : diagnotic mode for channels 1 and 3
> > + values: "Speaker" (default), "Booster"
> > +- st,diagnostic-mode-ch24 : diagnotic mode for channels 2 and 4
> > + values: "Speaker" (default), "Booster"
> > +
> > +Example:
> > +
> > +amp: tda7802@6c {
> > + compatible = "st,tda7802";
> > + reg = <0x6c>;
> > + enable-supply = <&_enable_reg>;
> > +};
> > --
> > 2.21.0
> >
>
> Thanks,
> Charles
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH 1/2] soc: qcom: Extend AOSS QMP driver to support resources that are used to wake up the SoC.
From: Amit Kucheria @ 2019-07-30 12:43 UTC (permalink / raw)
To: Thara Gopinath
Cc: linux-arm-msm, Andy Gross, Rob Herring, Mark Rutland,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML
In-Reply-To: <1564418001-24940-2-git-send-email-thara.gopinath@linaro.org>
On Mon, Jul 29, 2019 at 10:03 PM Thara Gopinath
<thara.gopinath@linaro.org> wrote:
>
> The AOSS QMP driver is extended to communicate with the additional
> resources. These resources are then registered as cooling devices
> with the thermal framework.
>
> Signed-off-by: Thara Gopinath <thara.gopinath@linaro.org>
> ---
> drivers/soc/qcom/qcom_aoss.c | 129 +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 129 insertions(+)
>
> diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c
> index 5f88519..010877e 100644
> --- a/drivers/soc/qcom/qcom_aoss.c
> +++ b/drivers/soc/qcom/qcom_aoss.c
> @@ -10,6 +10,8 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/pm_domain.h>
> +#include <linux/thermal.h>
> +#include <linux/slab.h>
>
> #define QMP_DESC_MAGIC 0x0
> #define QMP_DESC_VERSION 0x4
> @@ -40,6 +42,16 @@
> /* 64 bytes is enough to store the requests and provides padding to 4 bytes */
> #define QMP_MSG_LEN 64
>
> +#define QMP_NUM_COOLING_RESOURCES 2
> +
> +static bool qmp_cdev_init_state = 1;
> +
> +struct qmp_cooling_device {
> + struct thermal_cooling_device *cdev;
> + struct qmp *qmp;
> + bool state;
> +};
> +
> /**
> * struct qmp - driver state for QMP implementation
> * @msgram: iomem referencing the message RAM used for communication
> @@ -69,6 +81,7 @@ struct qmp {
>
> struct clk_hw qdss_clk;
> struct genpd_onecell_data pd_data;
> + struct qmp_cooling_device *cooling_devs;
> };
>
> struct qmp_pd {
> @@ -385,6 +398,117 @@ static void qmp_pd_remove(struct qmp *qmp)
> pm_genpd_remove(data->domains[i]);
> }
>
> +static int qmp_cdev_get_max_state(struct thermal_cooling_device *cdev,
> + unsigned long *state)
> +{
> + *state = qmp_cdev_init_state;
> + return 0;
> +}
> +
> +static int qmp_cdev_get_cur_state(struct thermal_cooling_device *cdev,
> + unsigned long *state)
> +{
> + struct qmp_cooling_device *qmp_cdev = cdev->devdata;
> +
> + *state = qmp_cdev->state;
> + return 0;
> +}
> +
> +static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
> + unsigned long state)
> +{
> + struct qmp_cooling_device *qmp_cdev = cdev->devdata;
> + char buf[QMP_MSG_LEN] = {};
> + bool cdev_state;
> + int ret;
> +
> + /* Normalize state */
> + cdev_state = !!state;
> +
> + if (qmp_cdev->state == state)
> + return 0;
> +
> + snprintf(buf, sizeof(buf),
> + "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
> + qmp_cdev->name,
This won't compile, there is no member "name" in qmp_cooling_device.
> + cdev_state ? "off" : "on");
> +
> + ret = qmp_send(qmp_cdev->qmp, buf, sizeof(buf));
> +
> + if (!ret)
> + qmp_cdev->state = cdev_state;
> +
> + return ret;
> +}
> +
> +static struct thermal_cooling_device_ops qmp_cooling_device_ops = {
> + .get_max_state = qmp_cdev_get_max_state,
> + .get_cur_state = qmp_cdev_get_cur_state,
> + .set_cur_state = qmp_cdev_set_cur_state,
> +};
> +
> +static int qmp_cooling_device_add(struct qmp *qmp,
> + struct qmp_cooling_device *qmp_cdev,
> + struct device_node *node)
> +{
> + char *cdev_name = (char *)node->name;
> +
> + qmp_cdev->qmp = qmp;
> + qmp_cdev->state = qmp_cdev_init_state;
> + qmp_cdev->cdev = devm_thermal_of_cooling_device_register
> + (qmp->dev, node,
> + cdev_name,
> + qmp_cdev, &qmp_cooling_device_ops);
> +
> + if (IS_ERR(qmp_cdev->cdev))
> + dev_err(qmp->dev, "unable to register %s cooling device\n",
> + cdev_name);
> +
> + return PTR_ERR_OR_ZERO(qmp_cdev->cdev);
> +}
> +
> +static int qmp_cooling_devices_register(struct qmp *qmp)
> +{
> + struct device_node *np, *child;
> + int count = QMP_NUM_COOLING_RESOURCES;
> + int ret;
> +
> + np = qmp->dev->of_node;
> +
> + qmp->cooling_devs = devm_kcalloc(qmp->dev, count,
> + sizeof(*qmp->cooling_devs),
> + GFP_KERNEL);
> +
> + if (!qmp->cooling_devs)
> + return -ENOMEM;
> +
> + for_each_available_child_of_node(np, child) {
> + if (!of_find_property(child, "#cooling-cells", NULL))
> + continue;
> + ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++],
> + child);
> + if (ret)
> + goto uroll_cooling_devices;
unroll?
> + }
> +
> + return 0;
> +
> +uroll_cooling_devices:
> + while (--count >= 0)
> + thermal_cooling_device_unregister
> + (qmp->cooling_devs[count].cdev);
> +
> + return ret;
> +}
> +
> +static void qmp_cooling_devices_remove(struct qmp *qmp)
> +{
> + int i;
> +
> + for (i = 0; i < QMP_NUM_COOLING_RESOURCES; i++)
> + thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev);
> +}
> +
> static int qmp_probe(struct platform_device *pdev)
> {
> struct resource *res;
> @@ -433,6 +557,10 @@ static int qmp_probe(struct platform_device *pdev)
> if (ret)
> goto err_remove_qdss_clk;
>
> + ret = qmp_cooling_devices_register(qmp);
> + if (ret)
> + dev_err(&pdev->dev, "failed to register aoss cooling devices\n");
> +
> platform_set_drvdata(pdev, qmp);
>
> return 0;
> @@ -453,6 +581,7 @@ static int qmp_remove(struct platform_device *pdev)
>
> qmp_qdss_clk_remove(qmp);
> qmp_pd_remove(qmp);
> + qmp_cooling_devices_remove(qmp);
>
> qmp_close(qmp);
> mbox_free_channel(qmp->mbox_chan);
> --
> 2.1.4
>
^ permalink raw reply
* Re: [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Charles Keepax @ 2019-07-30 12:41 UTC (permalink / raw)
To: Thomas Preston
Cc: Mark Rutland, devicetree, alsa-devel, Marco Felsch,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
linux-kernel, Takashi Iwai, Rob Herring, Liam Girdwood,
Paul Cercueil, Vinod Koul, Mark Brown, Srinivas Kandagatla,
Annaliese McDermond, Jerome Brunet
In-Reply-To: <20190730120937.16271-4-thomas.preston@codethink.co.uk>
On Tue, Jul 30, 2019 at 01:09:37PM +0100, Thomas Preston wrote:
> Add a debugfs device node which initiates the turn-on diagnostic routine
> feature of the TDA7802 amplifier. The four status registers (one per
> channel) are returned.
>
> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
> ---
> Changes since v1:
> - Rename speaker-test to (turn-on) diagnostics
> - Move turn-on diagnostic to debugfs as there is no standard ALSA
> interface for this kind of routine.
>
> sound/soc/codecs/tda7802.c | 186 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 185 insertions(+), 1 deletion(-)
>
> +static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
> + size_t update_count)
> +{
> + int i, err;
> +
> + for (i = 0; i < update_count; i++) {
> + err = regmap_update_bits(map, update[i].reg, update[i].mask,
> + update[i].val);
> + if (err < 0)
> + return err;
> + }
> +
> + return i;
> +}
This could probably be removed using regmap_multi_reg_write.
> +static int tda7802_probe(struct snd_soc_component *component)
> +{
> + struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
> + struct device *dev = &tda7802->i2c->dev;
> + int err;
> +
> + tda7802->debugfs = debugfs_create_dir(dev_name(dev), NULL);
> + if (IS_ERR_OR_NULL(tda7802->debugfs)) {
> + dev_info(dev,
> + "Failed to create debugfs node, err %ld\n",
> + PTR_ERR(tda7802->debugfs));
> + return 0;
> + }
> +
> + mutex_init(&tda7802->diagnostic_mutex);
> + err = debugfs_create_file("diagnostic", 0444, tda7802->debugfs, tda7802,
> + &tda7802_diagnostic_fops);
> + if (err < 0) {
> + dev_err(dev,
> + "debugfs: Failed to create diagnostic node, err %d\n",
> + err);
> + goto cleanup_diagnostic;
> + }
You shouldn't be failing the driver probe if debugfs fails, it
should be purely optional.
Thanks,
Charles
^ permalink raw reply
* Re: [PATCH v2 2/3] ASoC: Add codec driver for ST TDA7802
From: Charles Keepax @ 2019-07-30 12:38 UTC (permalink / raw)
To: Thomas Preston
Cc: Mark Rutland, devicetree, alsa-devel, Marco Felsch,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
linux-kernel, Nate Case, Takashi Iwai, Rob Herring, Liam Girdwood,
Paul Cercueil, Vinod Koul, Mark Brown, Srinivas Kandagatla,
Annaliese McDermond, Rob Duncan, Patrick Glaser, Jerome Brunet
In-Reply-To: <20190730120937.16271-3-thomas.preston@codethink.co.uk>
On Tue, Jul 30, 2019 at 01:09:36PM +0100, Thomas Preston wrote:
> Add an I2C based codec driver for ST TDA7802 amplifier. The amplifier
> supports 4 audio channels but can support up to 16 with multiple
> devices.
>
> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
> Cc: Patrick Glaser <pglaser@tesla.com>
> Cc: Rob Duncan <rduncan@tesla.com>
> Cc: Nate Case <ncase@tesla.com>
> ---
> Changes since v1:
> - Use ALSA kcontrol interface to expose device controls to userland
> - Gain
> - Channel diagnostic mode
> - Impedance efficiency optimiser. I decided against setting this
> as a DT property since it seems like something that can be
> changed on the fly.
> - Add regmap default values
> - Channel unmute by default is added in a downstream patch.
> - I'm not sure if I should keep this since they're all zero,
> although there are other drivers will all-zero reg_defaults.
> - I believe the "//" style is used for SPDX headers in normal C source files.
> https://lwn.net/Articles/739183/
> - Drop the "enable" sysfs device attribute.
> - Don't set TDM format using magic numbers.
> - Set sample rate using hw_params.
> - Remove unecessary defines.
> - Use DAPM to handle AMP_ON.
> - Cosmetic fixups
>
> sound/soc/codecs/Kconfig | 6 +
> sound/soc/codecs/Makefile | 2 +
> sound/soc/codecs/tda7802.c | 509 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 517 insertions(+)
> create mode 100644 sound/soc/codecs/tda7802.c
>
> +++ b/sound/soc/codecs/tda7802.c
> @@ -0,0 +1,509 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * tda7802.c -- codec driver for ST TDA7802
> + *
> + * Copyright (C) 2016-2019 Tesla Motors, Inc.
> + */
Better to make the whole comment // see something like
sound/soc/codecs/cs47l35.c for an example.
> +static int tda7802_set_bias_level(struct snd_soc_component *component,
> + enum snd_soc_bias_level level)
> +{
> + const struct tda7802_priv *tda7802 =
> + snd_soc_component_get_drvdata(component);
> + struct snd_soc_dapm_context *dapm_context =
> + snd_soc_component_get_dapm(component);
> + const enum snd_soc_bias_level oldlevel =
> + snd_soc_dapm_get_bias_level(dapm_context);
> + int err = 0;
> +
> + dev_dbg(component->dev, "%s level %d\n", __func__, level);
> +
> + switch (level) {
> + case SND_SOC_BIAS_ON:
> + break;
> + case SND_SOC_BIAS_PREPARE:
> + break;
> + case SND_SOC_BIAS_STANDBY:
> + err = regulator_enable(tda7802->enable_reg);
> + if (err < 0) {
> + dev_err(component->dev, "Could not enable.\n");
> + return err;
> + }
> + dev_dbg(component->dev, "Regulator enabled\n");
> + msleep(ENABLE_DELAY_MS);
> +
> + if (oldlevel == SND_SOC_BIAS_OFF) {
> + dev_dbg(component->dev, "Syncing regcache\n");
> + err = regcache_sync(component->regmap);
> + if (err < 0)
> + dev_err(component->dev,
> + "Could not sync regcache, %d\n", err);
If your doing a regcache_sync I would probably have expected to
see calls to regcache_cache_only.
If the device needs syncing that implies the hardware registers
have lost state, so there is little point in writing to them
if they are unavailable/about to loose their state.
> + }
> + break;
> + case SND_SOC_BIAS_OFF:
> + regcache_mark_dirty(component->regmap);
> + err = regulator_disable(tda7802->enable_reg);
> + if (err < 0)
> + dev_err(component->dev, "Could not disable.\n");
> + break;
> + }
> +
> + return err;
> +}
Thanks,
Charles
^ permalink raw reply
* Re: [PATCH 2/4] counter: new TI eQEP driver
From: Uwe Kleine-König @ 2019-07-30 12:35 UTC (permalink / raw)
To: David Lechner
Cc: linux-iio, linux-omap, devicetree, Rob Herring, Mark Rutland,
Benoît Cousson, Tony Lindgren, William Breathitt Gray,
Thierry Reding, linux-kernel, linux-pwm
In-Reply-To: <20190722154538.5314-3-david@lechnology.com>
On Mon, Jul 22, 2019 at 10:45:36AM -0500, David Lechner wrote:
> This adds a new counter driver for the Texas Instruments Enhanced
> Quadrature Encoder Pulse (eQEP) module.
>
> Only very basic functionality is currently implemented - only enough to
> be able to read the position. The actual device has many more features
> which can be added to the driver on an as-needed basis.
>
> Signed-off-by: David Lechner <david@lechnology.com>
> ---
> MAINTAINERS | 6 +
> drivers/counter/Kconfig | 12 ++
> drivers/counter/Makefile | 1 +
> drivers/counter/ti-eqep.c | 381 ++++++++++++++++++++++++++++++++++++++
> drivers/pwm/Kconfig | 2 +-
It's not obvious why the change to drivers/pwm/Kconfig is needed. Can
you please motivate that in the change log?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier
From: Charles Keepax @ 2019-07-30 12:27 UTC (permalink / raw)
To: Thomas Preston
Cc: Mark Rutland, devicetree, alsa-devel, Marco Felsch,
Kuninori Morimoto, Kirill Marinushkin, Cheng-Yi Chiang,
linux-kernel, Nate Case, Takashi Iwai, Rob Herring, Liam Girdwood,
Paul Cercueil, Vinod Koul, Mark Brown, Srinivas Kandagatla,
Annaliese McDermond, Rob Duncan, Patrick Glaser, Jerome Brunet
In-Reply-To: <20190730120937.16271-2-thomas.preston@codethink.co.uk>
On Tue, Jul 30, 2019 at 01:09:35PM +0100, Thomas Preston wrote:
> Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
> Cc: Patrick Glaser <pglaser@tesla.com>
> Cc: Rob Duncan <rduncan@tesla.com>
> Cc: Nate Case <ncase@tesla.com>
> ---
> .../devicetree/bindings/sound/tda7802.txt | 26 +++++++++++++++++++
> 1 file changed, 26 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/tda7802.txt
>
> diff --git a/Documentation/devicetree/bindings/sound/tda7802.txt b/Documentation/devicetree/bindings/sound/tda7802.txt
> new file mode 100644
> index 000000000000..f80aaf4f1ba0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/tda7802.txt
> @@ -0,0 +1,26 @@
> +ST TDA7802 audio processor
> +
> +This device supports I2C only.
> +
> +Required properties:
> +
> +- compatible : "st,tda7802"
> +- reg : the I2C address of the device
> +- enable-supply : a regulator spec for the PLLen pin
> +
> +Optional properties:
> +
> +- st,gain-ch13 : gain for channels 1 and 3 (range: 1-4)
> +- st,gain-ch24 : gain for channels 2 and 3 (range: 1-4)
I wouldn't have expected the gains to be available as a device
tree setting.
> +- st,diagnostic-mode-ch13 : diagnotic mode for channels 1 and 3
> + values: "Speaker" (default), "Booster"
> +- st,diagnostic-mode-ch24 : diagnotic mode for channels 2 and 4
> + values: "Speaker" (default), "Booster"
> +
> +Example:
> +
> +amp: tda7802@6c {
> + compatible = "st,tda7802";
> + reg = <0x6c>;
> + enable-supply = <&_enable_reg>;
> +};
> --
> 2.21.0
>
Thanks,
Charles
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2 7/7] ASoC: dt-bindings: Introduce compatible strings for 7ULP and 8MQ
From: Daniel Baluta @ 2019-07-30 12:10 UTC (permalink / raw)
To: Mark Brown
Cc: Nicolin Chen, Daniel Baluta, Devicetree List, Linux-ALSA,
Pengutronix Kernel Team, Timur Tabi, Rob Herring, S.j. Wang,
Angus Ainslie (Purism), Takashi Iwai, Linux Kernel Mailing List,
dl-linux-imx, Viorel Suman, Fabio Estevam, Mihai Serban,
Lucas Stach
In-Reply-To: <20190730120455.GA4264@sirena.org.uk>
On Tue, Jul 30, 2019 at 3:05 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Tue, Jul 30, 2019 at 03:02:30PM +0300, Daniel Baluta wrote:
>
> > I removed the 'or' on purpose because I don't want to move it
> > around each time we add a new compatible.
>
> > Anyhow, I can put it back if this is the convention.
>
> You could convert to the YAML binding format and sidestep the problem a
> different way!
Someone needs to do that in the end, so will try to change to yaml
with the next version
of the patch series.
^ permalink raw reply
* [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
From: Thomas Preston @ 2019-07-30 12:09 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Charles Keepax, Jerome Brunet,
Srinivas Kandagatla, Marco Felsch, Paul Cercueil,
Kirill Marinushkin, Cheng-Yi Chiang, Kuninori Morimoto,
Vinod Koul, Annaliese McDermond, Thomas Preston, alsa-devel,
devicetree, linux-kernel
In-Reply-To: <20190730120937.16271-1-thomas.preston@codethink.co.uk>
Add a debugfs device node which initiates the turn-on diagnostic routine
feature of the TDA7802 amplifier. The four status registers (one per
channel) are returned.
Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
Changes since v1:
- Rename speaker-test to (turn-on) diagnostics
- Move turn-on diagnostic to debugfs as there is no standard ALSA
interface for this kind of routine.
sound/soc/codecs/tda7802.c | 186 ++++++++++++++++++++++++++++++++++++-
1 file changed, 185 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/tda7802.c b/sound/soc/codecs/tda7802.c
index 0f82a88bc1a4..74436212241d 100644
--- a/sound/soc/codecs/tda7802.c
+++ b/sound/soc/codecs/tda7802.c
@@ -5,6 +5,7 @@
* Copyright (C) 2016-2019 Tesla Motors, Inc.
*/
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
@@ -26,6 +27,7 @@
#define TDA7802_IB5 0x05
#define TDA7802_DB0 0x10
+#define TDA7802_DB1 0x11
#define TDA7802_DB5 0x15
#define IB2_DIGITAL_MUTE_DISABLED (1 << 2)
@@ -47,6 +49,17 @@
#define IB3_FORMAT_TDM16_DEV3 (6 << IB3_FORMAT_SHIFT)
#define IB3_FORMAT_TDM16_DEV4 (7 << IB3_FORMAT_SHIFT)
+#define IB4_DIAG_MODE_ENABLE (1 << 0)
+
+#define IB5_AMPLIFIER_ON (1 << 0)
+
+#define DB0_STARTUP_DIAG_STATUS (1 << 6)
+
+#define DIAGNOSTIC_POLL_PERIOD_US 5000
+#define DIAGNOSTIC_TIMEOUT_US 5000000
+#define DIAGNOSTIC_SETTLE_MS 20
+#define NUM_IB 6
+
enum tda7802_type {
tda7802_base,
};
@@ -55,6 +68,12 @@ struct tda7802_priv {
struct i2c_client *i2c;
struct regmap *regmap;
struct regulator *enable_reg;
+ struct dentry *debugfs;
+ struct mutex diagnostic_mutex;
+};
+
+struct reg_update {
+ unsigned int reg, mask, val;
};
static const struct reg_default tda7802_reg[] = {
@@ -113,6 +132,19 @@ static const struct regmap_config tda7802_regmap_config = {
.cache_type = REGCACHE_RBTREE,
};
+/* The following bits need to be updated before diagnostics mode is set. */
+static const struct reg_update diagnostic_state[NUM_IB] = {
+ { TDA7802_IB0, 0, 0 },
+ { TDA7802_IB1, 0, 0 },
+ { TDA7802_IB2,
+ IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+ IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+ },
+ { TDA7802_IB3, 0, 0 },
+ { TDA7802_IB4, IB4_DIAG_MODE_ENABLE, 0 },
+ { TDA7802_IB5, IB5_AMPLIFIER_ON, 0 },
+};
+
static int tda7802_digital_mute(struct snd_soc_dai *dai, int mute)
{
const u8 mute_disabled = mute ? 0 : IB2_DIGITAL_MUTE_DISABLED;
@@ -414,7 +446,6 @@ static const struct snd_kcontrol_new tda7802_snd_controls[] = {
SOC_SINGLE("AC diag enable", TDA7802_IB4, 3, 1, 0),
SOC_ENUM("Diag mode channels 1 & 3", diag_mode_ch13),
SOC_ENUM("Diag mode channels 2 & 4", diag_mode_ch24),
- SOC_SINGLE("Diag mode enable", TDA7802_IB4, 0, 1, 0),
SOC_ENUM("Clipping detect channels 1 & 3", clip_detect_ch13),
SOC_ENUM("Clipping detect channels 2 & 4", clip_detect_ch24),
@@ -432,7 +463,160 @@ static const struct snd_soc_dapm_route tda7802_dapm_routes[] = {
{ "SPK", NULL, "DAC" },
};
+static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
+ size_t update_count)
+{
+ int i, err;
+
+ for (i = 0; i < update_count; i++) {
+ err = regmap_update_bits(map, update[i].reg, update[i].mask,
+ update[i].val);
+ if (err < 0)
+ return err;
+ }
+
+ return i;
+}
+
+static int run_turn_on_diagnostic(struct tda7802_priv *tda7802, u8 *status)
+{
+ struct device *dev = &tda7802->i2c->dev;
+ int err_status, err;
+ unsigned int val;
+ u8 state[NUM_IB];
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ /* Save state and prepare for diagnostic */
+ err = regmap_bulk_read(tda7802->regmap, TDA7802_IB0, state,
+ ARRAY_SIZE(state));
+ if (err < 0) {
+ dev_err(dev, "Could not save device state, %d\n", err);
+ return err;
+ }
+
+ err = tda7802_bulk_update(tda7802->regmap, diagnostic_state,
+ ARRAY_SIZE(diagnostic_state));
+ if (err < 0) {
+ dev_err(dev, "Could not prepare for diagnostics, %d\n", err);
+ goto diagnostic_restore;
+ }
+
+ /* We must wait 20ms for device to settle, otherwise diagnostics will
+ * not start and regmap poll will timeout.
+ */
+ msleep(DIAGNOSTIC_SETTLE_MS);
+
+ /* Turn on diagnostic */
+ err = regmap_update_bits(tda7802->regmap, TDA7802_IB4,
+ IB4_DIAG_MODE_ENABLE, IB4_DIAG_MODE_ENABLE);
+ if (err < 0) {
+ dev_err(dev, "Could not enable diagnostic mode, %d\n", err);
+ goto diagnostic_restore;
+ }
+
+ /* Wait until DB0_STARTUP_DIAG_STATUS is set, then read status */
+ err_status = regmap_read_poll_timeout(tda7802->regmap, TDA7802_DB0, val,
+ val & DB0_STARTUP_DIAG_STATUS,
+ DIAGNOSTIC_POLL_PERIOD_US,
+ DIAGNOSTIC_TIMEOUT_US);
+ if (err_status < 0) {
+ dev_err(dev, "Diagnostic did not complete, err %d, reg %x",
+ err_status, val);
+ goto diagnostic_restore;
+ }
+
+ err = regmap_bulk_read(tda7802->regmap, TDA7802_DB1, status, 4);
+ if (err < 0) {
+ dev_err(dev, "Could not read channel status, %d\n", err);
+ goto diagnostic_restore;
+ }
+
+diagnostic_restore:
+ err = regmap_bulk_write(tda7802->regmap, TDA7802_IB0, state,
+ ARRAY_SIZE(state));
+ if (err < 0)
+ dev_err(dev, "Could not restore state, %d\n", err);
+
+ if (err_status < 0)
+ return err_status;
+ else
+ return err;
+}
+
+static int tda7802_diagnostic_show(struct seq_file *f, void *p)
+{
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ struct tda7802_priv *tda7802 = f->private;
+ u8 status[4] = { 0 };
+ int i, err;
+
+ mutex_lock(&tda7802->diagnostic_mutex);
+ err = run_turn_on_diagnostic(tda7802, status);
+ mutex_unlock(&tda7802->diagnostic_mutex);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < ARRAY_SIZE(status); i++)
+ seq_printf(f, "%02x: %02x\n", TDA7802_DB1+i, status[i]);
+
+ return 0;
+}
+
+static int tda7802_diagnostic_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, tda7802_diagnostic_show, inode->i_private);
+}
+
+static const struct file_operations tda7802_diagnostic_fops = {
+ .open = tda7802_diagnostic_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int tda7802_probe(struct snd_soc_component *component)
+{
+ struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+ struct device *dev = &tda7802->i2c->dev;
+ int err;
+
+ tda7802->debugfs = debugfs_create_dir(dev_name(dev), NULL);
+ if (IS_ERR_OR_NULL(tda7802->debugfs)) {
+ dev_info(dev,
+ "Failed to create debugfs node, err %ld\n",
+ PTR_ERR(tda7802->debugfs));
+ return 0;
+ }
+
+ mutex_init(&tda7802->diagnostic_mutex);
+ err = debugfs_create_file("diagnostic", 0444, tda7802->debugfs, tda7802,
+ &tda7802_diagnostic_fops);
+ if (err < 0) {
+ dev_err(dev,
+ "debugfs: Failed to create diagnostic node, err %d\n",
+ err);
+ goto cleanup_diagnostic;
+ }
+
+ return 0;
+
+cleanup_diagnostic:
+ mutex_destroy(&tda7802->diagnostic_mutex);
+ return err;
+}
+
+static void tda7802_remove(struct snd_soc_component *component)
+{
+ struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+
+ debugfs_remove_recursive(tda7802->debugfs);
+ mutex_destroy(&tda7802->diagnostic_mutex);
+}
+
static const struct snd_soc_component_driver tda7802_component_driver = {
+ .probe = tda7802_probe,
+ .remove = tda7802_remove,
.set_bias_level = tda7802_set_bias_level,
.idle_bias_on = 1,
.suspend_bias_off = 1,
--
2.21.0
^ permalink raw reply related
* [PATCH v2 2/3] ASoC: Add codec driver for ST TDA7802
From: Thomas Preston @ 2019-07-30 12:09 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Charles Keepax, Jerome Brunet,
Srinivas Kandagatla, Marco Felsch, Paul Cercueil,
Kirill Marinushkin, Cheng-Yi Chiang, Kuninori Morimoto,
Vinod Koul, Annaliese McDermond, Thomas Preston, alsa-devel,
devicetree, linux-kernel
Cc: Patrick Glaser, Rob Duncan, Nate Case
In-Reply-To: <20190730120937.16271-1-thomas.preston@codethink.co.uk>
Add an I2C based codec driver for ST TDA7802 amplifier. The amplifier
supports 4 audio channels but can support up to 16 with multiple
devices.
Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
Cc: Patrick Glaser <pglaser@tesla.com>
Cc: Rob Duncan <rduncan@tesla.com>
Cc: Nate Case <ncase@tesla.com>
---
Changes since v1:
- Use ALSA kcontrol interface to expose device controls to userland
- Gain
- Channel diagnostic mode
- Impedance efficiency optimiser. I decided against setting this
as a DT property since it seems like something that can be
changed on the fly.
- Add regmap default values
- Channel unmute by default is added in a downstream patch.
- I'm not sure if I should keep this since they're all zero,
although there are other drivers will all-zero reg_defaults.
- I believe the "//" style is used for SPDX headers in normal C source files.
https://lwn.net/Articles/739183/
- Drop the "enable" sysfs device attribute.
- Don't set TDM format using magic numbers.
- Set sample rate using hw_params.
- Remove unecessary defines.
- Use DAPM to handle AMP_ON.
- Cosmetic fixups
sound/soc/codecs/Kconfig | 6 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/tda7802.c | 509 +++++++++++++++++++++++++++++++++++++
3 files changed, 517 insertions(+)
create mode 100644 sound/soc/codecs/tda7802.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9f89a5346299..7e3117eab735 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -182,6 +182,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TAS5720 if I2C
select SND_SOC_TAS6424 if I2C
select SND_SOC_TDA7419 if I2C
+ select SND_SOC_TDA7802 if I2C
select SND_SOC_TFA9879 if I2C
select SND_SOC_TLV320AIC23_I2C if I2C
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
@@ -1121,6 +1122,11 @@ config SND_SOC_TDA7419
depends on I2C
select REGMAP_I2C
+config SND_SOC_TDA7802
+ tristate "ST TDA7802 audio processor"
+ depends on I2C
+ select REGMAP_I2C
+
config SND_SOC_TFA9879
tristate "NXP Semiconductors TFA9879 amplifier"
depends on I2C
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5b4bb8cf4325..31dec8930e98 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -194,6 +194,7 @@ snd-soc-tas571x-objs := tas571x.o
snd-soc-tas5720-objs := tas5720.o
snd-soc-tas6424-objs := tas6424.o
snd-soc-tda7419-objs := tda7419.o
+snd-soc-tda7802-objs := tda7802.o
snd-soc-tfa9879-objs := tfa9879.o
snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
@@ -474,6 +475,7 @@ obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o
obj-$(CONFIG_SND_SOC_TDA7419) += snd-soc-tda7419.o
+obj-$(CONFIG_SND_SOC_TDA7802) += snd-soc-tda7802.o
obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
diff --git a/sound/soc/codecs/tda7802.c b/sound/soc/codecs/tda7802.c
new file mode 100644
index 000000000000..0f82a88bc1a4
--- /dev/null
+++ b/sound/soc/codecs/tda7802.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * tda7802.c -- codec driver for ST TDA7802
+ *
+ * Copyright (C) 2016-2019 Tesla Motors, Inc.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/string.h>
+#include <sound/control.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#define ENABLE_DELAY_MS 10
+
+#define TDA7802_IB0 0x00
+#define TDA7802_IB1 0x01
+#define TDA7802_IB2 0x02
+#define TDA7802_IB3 0x03
+#define TDA7802_IB4 0x04
+#define TDA7802_IB5 0x05
+
+#define TDA7802_DB0 0x10
+#define TDA7802_DB5 0x15
+
+#define IB2_DIGITAL_MUTE_DISABLED (1 << 2)
+
+#define IB3_SAMPLE_RATE_SHIFT 6
+#define IB3_SAMPLE_RATE_MASK (3 << IB3_SAMPLE_RATE_SHIFT)
+#define IB3_SAMPLE_RATE_44_KHZ (0 << IB3_SAMPLE_RATE_SHIFT)
+#define IB3_SAMPLE_RATE_48_KHZ (1 << IB3_SAMPLE_RATE_SHIFT)
+#define IB3_SAMPLE_RATE_96_KHZ (2 << IB3_SAMPLE_RATE_SHIFT)
+#define IB3_SAMPLE_RATE_192_KHZ (3 << IB3_SAMPLE_RATE_SHIFT)
+#define IB3_FORMAT_SHIFT 3
+#define IB3_FORMAT_MASK (7 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_I2S (0 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM4 (1 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM8_DEV1 (2 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM8_DEV2 (3 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM16_DEV1 (4 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM16_DEV2 (5 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM16_DEV3 (6 << IB3_FORMAT_SHIFT)
+#define IB3_FORMAT_TDM16_DEV4 (7 << IB3_FORMAT_SHIFT)
+
+enum tda7802_type {
+ tda7802_base,
+};
+
+struct tda7802_priv {
+ struct i2c_client *i2c;
+ struct regmap *regmap;
+ struct regulator *enable_reg;
+};
+
+static const struct reg_default tda7802_reg[] = {
+ { TDA7802_IB0, 0x0 },
+ { TDA7802_IB1, 0x0 },
+ { TDA7802_IB2, 0x0 },
+ { TDA7802_IB3, 0x0 },
+ { TDA7802_IB4, 0x0 },
+ { TDA7802_IB5, 0x0 },
+};
+
+static bool tda7802_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TDA7802_IB0 ... TDA7802_IB5:
+ case TDA7802_DB0 ... TDA7802_DB5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool tda7802_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TDA7802_DB0 ... TDA7802_DB5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool tda7802_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case TDA7802_IB0 ... TDA7802_IB5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static const struct regmap_config tda7802_regmap_config = {
+ .val_bits = 8,
+ .reg_bits = 8,
+ .max_register = TDA7802_DB5,
+ .use_single_read = 1,
+ .use_single_write = 1,
+
+ .readable_reg = tda7802_readable_reg,
+ .volatile_reg = tda7802_volatile_reg,
+ .writeable_reg = tda7802_writeable_reg,
+
+ .reg_defaults = tda7802_reg,
+ .num_reg_defaults = ARRAY_SIZE(tda7802_reg),
+ .cache_type = REGCACHE_RBTREE,
+};
+
+static int tda7802_digital_mute(struct snd_soc_dai *dai, int mute)
+{
+ const u8 mute_disabled = mute ? 0 : IB2_DIGITAL_MUTE_DISABLED;
+ struct device *dev = dai->dev;
+ int err;
+
+ dev_dbg(dev, "%s mute=%d\n", __func__, mute);
+
+ err = snd_soc_component_update_bits(dai->component, TDA7802_IB2,
+ IB2_DIGITAL_MUTE_DISABLED, mute_disabled);
+ if (err < 0)
+ dev_err(dev, "Cannot mute amp %d\n", err);
+
+ return err;
+}
+
+static int tda7802_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots, int slot_width)
+{
+ struct device *dev = dai->dev;
+ u8 tdm_format;
+ int ret;
+
+ dev_dbg(dai->dev, "%s tx %x, rx %x, slots %d, slot_width %d\n",
+ __func__, tx_mask, rx_mask, slots, slot_width);
+
+ switch (slots) {
+ case 4:
+ tdm_format = IB3_FORMAT_TDM4;
+ break;
+ case 8:
+ switch (tx_mask) {
+ case 0x000f:
+ tdm_format = IB3_FORMAT_TDM8_DEV1;
+ break;
+ case 0x00f0:
+ tdm_format = IB3_FORMAT_TDM8_DEV2;
+ break;
+ default:
+ dev_err(dev,
+ "Failed to set tdm fmt, slots %d, tx_mask %x\n",
+ slots, tx_mask);
+ return -ENOTSUPP;
+ }
+ break;
+ case 16:
+ switch (tx_mask) {
+ case 0x000f:
+ tdm_format = IB3_FORMAT_TDM16_DEV1;
+ break;
+ case 0x00f0:
+ tdm_format = IB3_FORMAT_TDM16_DEV2;
+ break;
+ case 0x0f00:
+ tdm_format = IB3_FORMAT_TDM16_DEV3;
+ break;
+ case 0xf000:
+ tdm_format = IB3_FORMAT_TDM16_DEV4;
+ break;
+ default:
+ dev_err(dev,
+ "Failed to set tdm fmt, slots %d, tx_mask %x\n",
+ slots, tx_mask);
+ return -ENOTSUPP;
+ }
+ break;
+ default:
+ dev_err(dev, "Failed to set %d slots, supported: 4, 8, 16\n",
+ slots);
+ return -ENOTSUPP;
+ }
+
+ ret = snd_soc_component_update_bits(dai->component, TDA7802_IB3,
+ IB3_FORMAT_MASK, tdm_format);
+ if (ret < 0) {
+ dev_err(dev, "Failed to write IB3 config %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int tda7802_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ int err;
+ u8 val;
+
+ dev_dbg(dai->dev, "%s rate %d\n", __func__, params_rate(params));
+
+ switch (params_rate(params)) {
+ case 44100:
+ val = IB3_SAMPLE_RATE_44_KHZ;
+ break;
+ case 48000:
+ val = IB3_SAMPLE_RATE_48_KHZ;
+ break;
+ case 96000:
+ val = IB3_SAMPLE_RATE_96_KHZ;
+ break;
+ case 192000:
+ val = IB3_SAMPLE_RATE_192_KHZ;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = snd_soc_component_update_bits(dai->component, TDA7802_IB3,
+ IB3_SAMPLE_RATE_MASK, val);
+ if (err < 0)
+ dev_err(dai->dev, "Could not set hw_params, %d\n", err);
+
+ return err;
+}
+
+static const struct snd_soc_dai_ops tda7802_dai_ops = {
+ .digital_mute = tda7802_digital_mute,
+ .hw_params = tda7802_hw_params,
+ .set_tdm_slot = tda7802_set_tdm_slot,
+};
+
+static struct snd_soc_dai_driver tda7802_dai_driver = {
+ .name = "tda7802",
+ .playback = {
+ .stream_name = "Playback",
+ .channels_min = 4,
+ .channels_max = 4,
+ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ },
+ .ops = &tda7802_dai_ops,
+};
+
+static int tda7802_set_bias_level(struct snd_soc_component *component,
+ enum snd_soc_bias_level level)
+{
+ const struct tda7802_priv *tda7802 =
+ snd_soc_component_get_drvdata(component);
+ struct snd_soc_dapm_context *dapm_context =
+ snd_soc_component_get_dapm(component);
+ const enum snd_soc_bias_level oldlevel =
+ snd_soc_dapm_get_bias_level(dapm_context);
+ int err = 0;
+
+ dev_dbg(component->dev, "%s level %d\n", __func__, level);
+
+ switch (level) {
+ case SND_SOC_BIAS_ON:
+ break;
+ case SND_SOC_BIAS_PREPARE:
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ err = regulator_enable(tda7802->enable_reg);
+ if (err < 0) {
+ dev_err(component->dev, "Could not enable.\n");
+ return err;
+ }
+ dev_dbg(component->dev, "Regulator enabled\n");
+ msleep(ENABLE_DELAY_MS);
+
+ if (oldlevel == SND_SOC_BIAS_OFF) {
+ dev_dbg(component->dev, "Syncing regcache\n");
+ err = regcache_sync(component->regmap);
+ if (err < 0)
+ dev_err(component->dev,
+ "Could not sync regcache, %d\n", err);
+ }
+ break;
+ case SND_SOC_BIAS_OFF:
+ regcache_mark_dirty(component->regmap);
+ err = regulator_disable(tda7802->enable_reg);
+ if (err < 0)
+ dev_err(component->dev, "Could not disable.\n");
+ break;
+ }
+
+ return err;
+}
+
+static const char * const amp_mode_str[] = {
+ "High Efficiency",
+ "Standard Class AB",
+};
+
+static SOC_ENUM_SINGLE_DECL(ch1_amp_mode, TDA7802_IB0, 0, amp_mode_str);
+static SOC_ENUM_SINGLE_DECL(ch2_amp_mode, TDA7802_IB0, 1, amp_mode_str);
+static SOC_ENUM_SINGLE_DECL(ch3_amp_mode, TDA7802_IB0, 2, amp_mode_str);
+static SOC_ENUM_SINGLE_DECL(ch4_amp_mode, TDA7802_IB0, 3, amp_mode_str);
+
+static const char * const zopt_str[] = {
+ "2ohm",
+ "4ohm",
+};
+
+static SOC_ENUM_SINGLE_DECL(zopt_ch24, TDA7802_IB1, 7, zopt_str);
+static SOC_ENUM_SINGLE_DECL(zopt_ch13, TDA7802_IB2, 0, zopt_str);
+
+static const char * const diag_timing_str[] = {
+ "default",
+ "x2",
+ "x4",
+ "x8",
+};
+
+static SOC_ENUM_SINGLE_DECL(diag_timing, TDA7802_IB1, 5, diag_timing_str);
+
+static const char * const mute_time_str[] = {
+ "1.45ms",
+ "5.8ms",
+ "11.6ms",
+ "23.2ms",
+ "46.4ms",
+ "92.8ms",
+ "185.6ms",
+ "371.2ms",
+};
+
+static SOC_ENUM_SINGLE_DECL(mute_time, TDA7802_IB2, 5, mute_time_str);
+
+static const char * const automute_threshold_str[] = {
+ "5.3V",
+ "7.3V",
+};
+
+static SOC_ENUM_SINGLE_DECL(automute_threshold, TDA7802_IB2, 1,
+ automute_threshold_str);
+
+static const char * const ac_diag_threshold_str[] = {
+ "High",
+ "Low",
+};
+
+static SOC_ENUM_SINGLE_DECL(ac_diag_threshold, TDA7802_IB3, 4,
+ ac_diag_threshold_str);
+
+static const char * const ch_diag_mode_str[] = {
+ "Speaker",
+ "Boosted",
+};
+
+static SOC_ENUM_SINGLE_DECL(diag_mode_ch13, TDA7802_IB4, 2, ch_diag_mode_str);
+static SOC_ENUM_SINGLE_DECL(diag_mode_ch24, TDA7802_IB4, 1, ch_diag_mode_str);
+
+static const char * const temp_warn_str[] = {
+ "TW1",
+ "TW2",
+ "TW3",
+ "TW4",
+ "None",
+};
+
+static SOC_ENUM_SINGLE_DECL(temp_warn, TDA7802_IB5, 5, temp_warn_str);
+
+static const char * const clip_detect_str[] = {
+ "2%",
+ "5%",
+ "10%",
+ "None",
+};
+
+static SOC_ENUM_SINGLE_DECL(clip_detect_ch13, TDA7802_IB5, 3, clip_detect_str);
+static SOC_ENUM_SINGLE_DECL(clip_detect_ch24, TDA7802_IB5, 1, clip_detect_str);
+
+static const struct snd_kcontrol_new tda7802_snd_controls[] = {
+ SOC_SINGLE("Channel 4 Tristate", TDA7802_IB0, 7, 1, 0),
+ SOC_SINGLE("Channel 3 Tristate", TDA7802_IB0, 6, 1, 0),
+ SOC_SINGLE("Channel 2 Tristate", TDA7802_IB0, 5, 1, 0),
+ SOC_SINGLE("Channel 1 Tristate", TDA7802_IB0, 4, 1, 0),
+ SOC_ENUM("Channel 4 Amplifier Mode", ch4_amp_mode),
+ SOC_ENUM("Channel 3 Amplifier Mode", ch3_amp_mode),
+ SOC_ENUM("Channel 2 Amplifier Mode", ch2_amp_mode),
+ SOC_ENUM("Channel 1 Amplifier Mode", ch1_amp_mode),
+
+ /* Impedance (Z) efficiency optimiser */
+ SOC_ENUM("Z efficiency opt channels 2 & 4", zopt_ch24),
+ SOC_ENUM("Z efficiency opt channels 1 & 3", zopt_ch13),
+
+ SOC_ENUM("Long diag config timing", diag_timing),
+ SOC_SINGLE_RANGE("Gain channels 1 & 3", TDA7802_IB1, 3, 0, 3, 0),
+ SOC_SINGLE_RANGE("Gain channels 2 & 4", TDA7802_IB1, 1, 0, 3, 0),
+ SOC_SINGLE("Digital gain boost +6db", TDA7802_IB1, 0, 1, 0),
+
+ /* Mute settings */
+ SOC_ENUM("Mute time", mute_time),
+ SOC_SINGLE("Unmute channels 1 & 3", TDA7802_IB2, 4, 1, 0),
+ SOC_SINGLE("Unmute channels 2 & 4", TDA7802_IB2, 3, 1, 0),
+ SOC_ENUM("Automute threshold", automute_threshold),
+
+ SOC_SINGLE("High pass filter enable", TDA7802_IB3, 0, 1, 0),
+
+ /* Interactive diagnostics */
+ SOC_SINGLE("Noise gating func enable", TDA7802_IB4, 7, 1, 1),
+ SOC_SINGLE("CDdiag: short fault", TDA7802_IB4, 6, 1, 1),
+ SOC_SINGLE("CDdiag: offset", TDA7802_IB4, 5, 1, 1),
+ SOC_ENUM("CDdiag: temperature warning", temp_warn),
+ SOC_ENUM("AC diag current threshold", ac_diag_threshold),
+ SOC_SINGLE("AC diag enable", TDA7802_IB4, 3, 1, 0),
+ SOC_ENUM("Diag mode channels 1 & 3", diag_mode_ch13),
+ SOC_ENUM("Diag mode channels 2 & 4", diag_mode_ch24),
+ SOC_SINGLE("Diag mode enable", TDA7802_IB4, 0, 1, 0),
+
+ SOC_ENUM("Clipping detect channels 1 & 3", clip_detect_ch13),
+ SOC_ENUM("Clipping detect channels 2 & 4", clip_detect_ch24),
+};
+
+static const struct snd_soc_dapm_widget tda7802_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN("AIFIN", NULL, 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC("DAC", NULL, TDA7802_IB5, 0, 0),
+ SND_SOC_DAPM_OUTPUT("SPK"),
+};
+
+static const struct snd_soc_dapm_route tda7802_dapm_routes[] = {
+ { "AIFIN", NULL, "Playback" },
+ { "DAC", NULL, "AIFIN" },
+ { "SPK", NULL, "DAC" },
+};
+
+static const struct snd_soc_component_driver tda7802_component_driver = {
+ .set_bias_level = tda7802_set_bias_level,
+ .idle_bias_on = 1,
+ .suspend_bias_off = 1,
+ .controls = tda7802_snd_controls,
+ .num_controls = ARRAY_SIZE(tda7802_snd_controls),
+ .dapm_widgets = tda7802_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(tda7802_dapm_widgets),
+ .dapm_routes = tda7802_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(tda7802_dapm_routes),
+};
+
+static int tda7802_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &i2c->dev;
+ struct tda7802_priv *tda7802;
+ int err;
+
+ dev_dbg(dev, "%s addr=0x%02hx, id %p\n", __func__, i2c->addr, id);
+
+ tda7802 = devm_kmalloc(dev, sizeof(*tda7802), GFP_KERNEL);
+ if (!tda7802)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, tda7802);
+ tda7802->i2c = i2c;
+
+ tda7802->enable_reg = devm_regulator_get(dev, "enable");
+ if (IS_ERR(tda7802->enable_reg)) {
+ dev_err(dev, "Failed to get enable regulator\n");
+ return PTR_ERR(tda7802->enable_reg);
+ }
+
+ tda7802->regmap = devm_regmap_init_i2c(tda7802->i2c,
+ &tda7802_regmap_config);
+ if (IS_ERR(tda7802->regmap))
+ return PTR_ERR(tda7802->regmap);
+
+ err = devm_snd_soc_register_component(dev, &tda7802_component_driver,
+ &tda7802_dai_driver, 1);
+ if (err < 0)
+ dev_err(dev, "Failed to register codec: %d\n", err);
+ return err;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tda7802_of_match[] = {
+ { .compatible = "st,tda7802" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tda7802_of_match);
+#endif
+
+static const struct i2c_device_id tda7802_i2c_id[] = {
+ { "tda7802", tda7802_base },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, tda7802_i2c_id);
+
+static struct i2c_driver tda7802_i2c_driver = {
+ .driver = {
+ .name = "tda7802-codec",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(tda7802_of_match),
+ },
+ .probe = tda7802_i2c_probe,
+ .id_table = tda7802_i2c_id,
+};
+module_i2c_driver(tda7802_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC ST TDA7802 driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rob Duncan <rduncan@tesla.com>");
+MODULE_AUTHOR("Thomas Preston <thomas.preston@codethink.co.uk>");
--
2.21.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox