* [PATCH 1/3] dt-bindings: i2c: at91: document optional bus recovery properties
2019-12-05 14:03 [PATCH 0/3] SAMA5D2 i2c bus recovery testing Kamel Bouhara
@ 2019-12-05 14:03 ` Kamel Bouhara
2019-12-05 14:03 ` [PATCH 2/3] i2c: at91: implement i2c bus recovery Kamel Bouhara
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Kamel Bouhara @ 2019-12-05 14:03 UTC (permalink / raw)
To: Codrin.Ciubotariu
Cc: Kamel Bouhara, Alexandre Belloni, Ludovic Desroches,
linux-arm-kernel
The at91 I2C controller can support bus recovery by re-assigning SCL
and SDA to gpios. Add the optional pinctrl and gpio properties to do
so.
Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
---
Documentation/devicetree/bindings/i2c/i2c-at91.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt
index b7cec17c3daf..8ea2ce5d8610 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-at91.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt
@@ -19,8 +19,13 @@ Optional properties:
capable I2C controllers.
- i2c-sda-hold-time-ns: TWD hold time, only available for "atmel,sama5d4-i2c"
and "atmel,sama5d2-i2c".
+- scl-gpios: specify the gpio related to SCL pin
+- sda-gpios: specify the gpio related to SDA pin
+- pinctrl: add extra pinctrl to configure i2c pins to gpio function for i2c
+ bus recovery, call it "gpio" state
- Child nodes conforming to i2c bus binding
+
Examples :
i2c0: i2c@fff84000 {
@@ -55,6 +60,11 @@ i2c0: i2c@f8034600 {
clocks = <&flx0>;
atmel,fifo-size = <16>;
i2c-sda-hold-time-ns = <336>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_i2c0>;
+ pinctrl-1 = <&pinctrl_i2c0_gpio>;
+ sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA 31 GPIO_ACTIVE_HIGH>;
wm8731: wm8731@1a {
compatible = "wm8731";
--
2.24.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] i2c: at91: implement i2c bus recovery
2019-12-05 14:03 [PATCH 0/3] SAMA5D2 i2c bus recovery testing Kamel Bouhara
2019-12-05 14:03 ` [PATCH 1/3] dt-bindings: i2c: at91: document optional bus recovery properties Kamel Bouhara
@ 2019-12-05 14:03 ` Kamel Bouhara
2019-12-05 14:03 ` [PATCH 3/3] ARM: at91/dt: sama5d2: add i2c gpio pinctrl Kamel Bouhara
2019-12-16 10:10 ` [PATCH 0/3] SAMA5D2 i2c bus recovery testing Ludovic Desroches
3 siblings, 0 replies; 6+ messages in thread
From: Kamel Bouhara @ 2019-12-05 14:03 UTC (permalink / raw)
To: Codrin.Ciubotariu
Cc: Kamel Bouhara, Alexandre Belloni, Ludovic Desroches,
linux-arm-kernel
Implement i2c bus recovery when slaves devices might hold SDA low.
In this case re-assign SCL/SDA to gpios and issue 9 dummy clock pulses
until the slave release SDA.
Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
---
drivers/i2c/busses/i2c-at91-master.c | 64 ++++++++++++++++++++++++++++
drivers/i2c/busses/i2c-at91.h | 8 ++++
2 files changed, 72 insertions(+)
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index a3fcc35ffd3b..e279129e6a76 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -18,11 +18,13 @@
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dma-atmel.h>
#include <linux/pm_runtime.h>
@@ -554,6 +556,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
if (time_left == 0) {
dev->transfer_status |= at91_twi_read(dev, AT91_TWI_SR);
dev_err(dev->dev, "controller timed out\n");
+ i2c_recover_bus(&dev->adapter);
at91_init_twi_bus(dev);
ret = -ETIMEDOUT;
goto error;
@@ -768,6 +771,63 @@ static int at91_twi_configure_dma(struct at91_twi_dev *dev, u32 phy_addr)
return ret;
}
+static void at91_prepare_twi_recovery(struct i2c_adapter *adap)
+{
+ struct at91_twi_dev *dev = i2c_get_adapdata(adap);
+
+ pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio);
+}
+
+static void at91_unprepare_twi_recovery(struct i2c_adapter *adap)
+{
+ struct at91_twi_dev *dev = i2c_get_adapdata(adap);
+
+ pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
+}
+
+static int at91_init_twi_recovery_info(struct platform_device *pdev,
+ struct at91_twi_dev *dev)
+{
+ struct i2c_bus_recovery_info *rinfo = &dev->rinfo;
+
+ dev->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!dev->pinctrl || IS_ERR(dev->pinctrl)) {
+ dev_info(dev->dev, "can't get pinctrl, bus recovery not supported\n");
+ return PTR_ERR(dev->pinctrl);
+ }
+
+ dev->pinctrl_pins_default = pinctrl_lookup_state(dev->pinctrl,
+ PINCTRL_STATE_DEFAULT);
+ dev->pinctrl_pins_gpio = pinctrl_lookup_state(dev->pinctrl,
+ "gpio");
+ rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
+ if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ rinfo->scl_gpiod = devm_gpiod_get(&pdev->dev, "scl",
+ GPIOD_OUT_HIGH_OPEN_DRAIN);
+ if (PTR_ERR(rinfo->scl_gpiod) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+
+ if (IS_ERR(rinfo->sda_gpiod) ||
+ IS_ERR(rinfo->scl_gpiod) ||
+ IS_ERR(dev->pinctrl_pins_default) ||
+ IS_ERR(dev->pinctrl_pins_gpio)) {
+ dev_info(&pdev->dev, "recovery information incomplete\n");
+ return -EINVAL;
+ }
+
+ dev_info(&pdev->dev, "using scl%s for recovery\n",
+ rinfo->sda_gpiod ? ",sda" : "");
+
+ rinfo->prepare_recovery = at91_prepare_twi_recovery;
+ rinfo->unprepare_recovery = at91_unprepare_twi_recovery;
+ rinfo->recover_bus = i2c_generic_scl_recovery;
+ dev->adapter.bus_recovery_info = rinfo;
+
+ return 0;
+}
+
int at91_twi_probe_master(struct platform_device *pdev,
u32 phy_addr, struct at91_twi_dev *dev)
{
@@ -795,6 +855,10 @@ int at91_twi_probe_master(struct platform_device *pdev,
at91_calc_twi_clock(dev);
+ rc = at91_init_twi_recovery_info(pdev, dev);
+ if (rc == -EPROBE_DEFER)
+ return rc;
+
dev->adapter.algo = &at91_twi_algorithm;
dev->adapter.quirks = &at91_twi_quirks;
diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
index 499b506f6128..b89dab55e776 100644
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h
@@ -141,6 +141,10 @@ struct at91_twi_dev {
u32 fifo_size;
struct at91_twi_dma dma;
bool slave_detected;
+ struct i2c_bus_recovery_info rinfo;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pinctrl_pins_default;
+ struct pinctrl_state *pinctrl_pins_gpio;
#ifdef CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL
unsigned smr;
struct i2c_client *slave;
@@ -158,6 +162,10 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev);
int at91_twi_probe_master(struct platform_device *pdev, u32 phy_addr,
struct at91_twi_dev *dev);
+void at91_twi_prepare_recovery(struct i2c_adapter *adap);
+void at91_twi_unprepare_recovery(struct i2c_adapter *adap);
+void at91_twi_init_recovery_info(struct at91_twi_dev *dev);
+
#ifdef CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL
void at91_init_twi_bus_slave(struct at91_twi_dev *dev);
int at91_twi_probe_slave(struct platform_device *pdev, u32 phy_addr,
--
2.24.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] ARM: at91/dt: sama5d2: add i2c gpio pinctrl
2019-12-05 14:03 [PATCH 0/3] SAMA5D2 i2c bus recovery testing Kamel Bouhara
2019-12-05 14:03 ` [PATCH 1/3] dt-bindings: i2c: at91: document optional bus recovery properties Kamel Bouhara
2019-12-05 14:03 ` [PATCH 2/3] i2c: at91: implement i2c bus recovery Kamel Bouhara
@ 2019-12-05 14:03 ` Kamel Bouhara
2019-12-16 10:10 ` [PATCH 0/3] SAMA5D2 i2c bus recovery testing Ludovic Desroches
3 siblings, 0 replies; 6+ messages in thread
From: Kamel Bouhara @ 2019-12-05 14:03 UTC (permalink / raw)
To: Codrin.Ciubotariu
Cc: Kamel Bouhara, Alexandre Belloni, Ludovic Desroches,
linux-arm-kernel
Add the i2c gpio pinctrls to support the i2c bus recovery
Signed-off-by: Kamel Bouhara <kamel.bouhara@bootlin.com>
---
arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 33 +++++++++++++++++++--
arch/arm/boot/dts/at91-sama5d2_xplained.dts | 33 +++++++++++++++++++--
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
index ba7f3e646c26..b3cd651ecda0 100644
--- a/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts
@@ -180,8 +180,11 @@
i2c0: i2c@f8028000 {
dmas = <0>, <0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c0_default>;
+ pinctrl-1 = <&pinctrl_i2c0_gpio>;
+ sda-gpios = <&pioA PIN_PD21 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PD22 GPIO_ACTIVE_HIGH>;
status = "okay";
};
@@ -198,8 +201,11 @@
#address-cells = <1>;
#size-cells = <0>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_flx0_default>;
+ pinctrl-1 = <&pinctrl_flx0_gpio>;
+ sda-gpios = <&pioA PIN_PB28 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PB29 GPIO_ACTIVE_HIGH>;
atmel,fifo-size = <16>;
status = "okay";
};
@@ -226,8 +232,11 @@
i2c1: i2c@fc028000 {
dmas = <0>, <0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1_default>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ sda-gpios = <&pioA PIN_PC6 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PC7 GPIO_ACTIVE_HIGH>;
status = "okay";
at24@50 {
@@ -244,18 +253,36 @@
bias-disable;
};
+ pinctrl_flx0_gpio: flx0_gpio {
+ pinmux = <PIN_PB28__GPIO>,
+ <PIN_PB29__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_i2c0_default: i2c0_default {
pinmux = <PIN_PD21__TWD0>,
<PIN_PD22__TWCK0>;
bias-disable;
};
+ pinctrl_i2c0_gpio: i2c0_gpio {
+ pinmux = <PIN_PD21__GPIO>,
+ <PIN_PD22__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_i2c1_default: i2c1_default {
pinmux = <PIN_PC6__TWD1>,
<PIN_PC7__TWCK1>;
bias-disable;
};
+ pinctrl_i2c1_gpio: i2c1_gpio {
+ pinmux = <PIN_PC6__GPIO>,
+ <PIN_PC7__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_key_gpio_default: key_gpio_default {
pinmux = <PIN_PA10__GPIO>;
bias-pull-up;
diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
index 808e399fd39a..c22e2aad87fa 100644
--- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts
+++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts
@@ -129,8 +129,11 @@
i2c0: i2c@f8028000 {
dmas = <0>, <0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c0_default>;
+ pinctrl-1 = <&pinctrl_i2c0_gpio>;
+ sda-gpios = <&pioA PIN_PD21 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PD22 GPIO_ACTIVE_HIGH>;
i2c-sda-hold-time-ns = <350>;
status = "okay";
@@ -331,8 +334,11 @@
#address-cells = <1>;
#size-cells = <0>;
clocks = <&pmc PMC_TYPE_PERIPHERAL 23>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_flx4_default>;
+ pinctrl-1 = <&pinctrl_flx4_gpio>;
+ sda-gpios = <&pioA PIN_PD12 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PD13 GPIO_ACTIVE_HIGH>;
atmel,fifo-size = <16>;
status = "okay";
};
@@ -340,8 +346,11 @@
i2c1: i2c@fc028000 {
dmas = <0>, <0>;
- pinctrl-names = "default";
+ pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c1_default>;
+ pinctrl-1 = <&pinctrl_i2c1_gpio>;
+ sda-gpios = <&pioA PIN_PD4 GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&pioA PIN_PD5 GPIO_ACTIVE_HIGH>;
status = "okay";
at24@54 {
@@ -435,18 +444,36 @@
bias-disable;
};
+ pinctrl_flx4_gpio: flx4_gpio {
+ pinmux = <PIN_PD12__GPIO>,
+ <PIN_PD13__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_i2c0_default: i2c0_default {
pinmux = <PIN_PD21__TWD0>,
<PIN_PD22__TWCK0>;
bias-disable;
};
+ pinctrl_i2c0_gpio: i2c0_gpio {
+ pinmux = <PIN_PD21__GPIO>,
+ <PIN_PD22__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_i2c1_default: i2c1_default {
pinmux = <PIN_PD4__TWD1>,
<PIN_PD5__TWCK1>;
bias-disable;
};
+ pinctrl_i2c1_gpio: i2c1_gpio {
+ pinmux = <PIN_PD4__GPIO>,
+ <PIN_PD5__GPIO>;
+ bias-pull-up;
+ };
+
pinctrl_i2s0_default: i2s0_default {
pinmux = <PIN_PC1__I2SC0_CK>,
<PIN_PC2__I2SC0_MCK>,
--
2.24.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 0/3] SAMA5D2 i2c bus recovery testing
2019-12-05 14:03 [PATCH 0/3] SAMA5D2 i2c bus recovery testing Kamel Bouhara
` (2 preceding siblings ...)
2019-12-05 14:03 ` [PATCH 3/3] ARM: at91/dt: sama5d2: add i2c gpio pinctrl Kamel Bouhara
@ 2019-12-16 10:10 ` Ludovic Desroches
2019-12-16 10:26 ` Kamel Bouhara
3 siblings, 1 reply; 6+ messages in thread
From: Ludovic Desroches @ 2019-12-16 10:10 UTC (permalink / raw)
To: Kamel Bouhara; +Cc: linux-arm-kernel, Codrin.Ciubotariu, Alexandre Belloni
Hi Kamel,
On Thu, Dec 05, 2019 at 03:03:02PM +0100, Kamel Bouhara wrote:
>
> Here are the sama5d2 patches, as there is not pinmux defined in the
> dtsi. I choosed to only apply it to derivated board as the i2c
> configuration is specific for each.
>
> Of course, it could be great if could test it on the ptc board as well.
>
The i2c mailing list is missing, can you resend it please.
By the way, it fails to apply against next and 5.5-rc1. On which version is it
based? I assume a cherry-pick should work but git am fails.
Regards
Ludovic
> Best Regards,
> Kamel
>
> Kamel Bouhara (3):
> dt-bindings: i2c: at91: document optional bus recovery properties
> i2c: at91: implement i2c bus recovery
> ARM: at91/dt: sama5d2: add i2c gpio pinctrl
>
> .../devicetree/bindings/i2c/i2c-at91.txt | 10 +++
> arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 33 +++++++++-
> arch/arm/boot/dts/at91-sama5d2_xplained.dts | 33 +++++++++-
> drivers/i2c/busses/i2c-at91-master.c | 64 +++++++++++++++++++
> drivers/i2c/busses/i2c-at91.h | 8 +++
> 5 files changed, 142 insertions(+), 6 deletions(-)
>
> --
> 2.24.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 0/3] SAMA5D2 i2c bus recovery testing
2019-12-16 10:10 ` [PATCH 0/3] SAMA5D2 i2c bus recovery testing Ludovic Desroches
@ 2019-12-16 10:26 ` Kamel Bouhara
0 siblings, 0 replies; 6+ messages in thread
From: Kamel Bouhara @ 2019-12-16 10:26 UTC (permalink / raw)
To: Codrin.Ciubotariu, Nicolas Ferre, Alexandre Belloni,
linux-arm-kernel
On Mon, Dec 16, 2019 at 11:10:44AM +0100, Ludovic Desroches wrote:
> Hi Kamel,
>
Hi Ludovic,
> On Thu, Dec 05, 2019 at 03:03:02PM +0100, Kamel Bouhara wrote:
> >
> > Here are the sama5d2 patches, as there is not pinmux defined in the
> > dtsi. I choosed to only apply it to derivated board as the i2c
> > configuration is specific for each.
> >
> > Of course, it could be great if could test it on the ptc board as well.
> >
>
> The i2c mailing list is missing, can you resend it please.
>
Actually it was not intended to be sent to any mailing list, it is a
mail for Codrin so he can achieve some tests.
> By the way, it fails to apply against next and 5.5-rc1. On which version is it
> based? I assume a cherry-pick should work but git am fails.
>
It's based on 5.4, Im not sure it will apply on next but it should on
5.5, anyway it is a WIP here.
Best Regards,
Kamel
> Regards
>
> Ludovic
>
> > Best Regards,
> > Kamel
> >
> > Kamel Bouhara (3):
> > dt-bindings: i2c: at91: document optional bus recovery properties
> > i2c: at91: implement i2c bus recovery
> > ARM: at91/dt: sama5d2: add i2c gpio pinctrl
> >
> > .../devicetree/bindings/i2c/i2c-at91.txt | 10 +++
> > arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts | 33 +++++++++-
> > arch/arm/boot/dts/at91-sama5d2_xplained.dts | 33 +++++++++-
> > drivers/i2c/busses/i2c-at91-master.c | 64 +++++++++++++++++++
> > drivers/i2c/busses/i2c-at91.h | 8 +++
> > 5 files changed, 142 insertions(+), 6 deletions(-)
> >
> > --
> > 2.24.0
> >
--
Kamel Bouhara, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 6+ messages in thread