All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karol Lewandowski <k.lewandowsk-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
To: Jean-Christophe PLAGNIOL-VILLARD
	<plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org
Subject: Re: [PATCH 1/4] i2c/gpio-i2c add: add DT support
Date: Tue, 07 Feb 2012 16:35:38 +0100	[thread overview]
Message-ID: <4F3144CA.6070003@samsung.com> (raw)
In-Reply-To: <20120207032533.GC15647-RQcB7r2h9QmfDR2tN2SG5Ni2O/JbrIOy@public.gmane.org>

On 07.02.2012 04:25, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 19:38 Mon 06 Feb     , Karol Lewandowski wrote:

>>> +	- udelay: half clock cycle time in us (may depend on each platform)
>>
>> Could we use "clock-frequency" as Grant have suggested during review
>> of previous patch to i2c-gpio?

> as exaplained no as for gpio the delay is platform dependent

Following sniplet from i2c-gpio suggests that in some cases both udelay 
and timeout can be calculated given presence of other parameters:

   static int __devinit i2c_gpio_probe(struct platform_device *pdev)
   ...
	if (pdata->udelay)
		bit_data->udelay = pdata->udelay;
	else if (pdata->scl_is_output_only)
		bit_data->udelay = 50;			/* 10 kHz */
	else
		bit_data->udelay = 5;			/* 100 kHz */

	if (pdata->timeout)
		bit_data->timeout = pdata->timeout;
	else
		bit_data->timeout = HZ / 10;		/* 100 ms */

However, I find it more troubling that driver manually grabs parameters 
that are specific to i2c-algo-bit (timeout, udelay).

Thus, I have feeling that it should be generically addressed there. What 
do you think?


>>
>>    https://lkml.org/lkml/2011/2/24/220
>>
>>> +	- timeout: timeout to get data
>>> +
>>> +
>>> +Example nodes:
>>> +
>>> +i2c-gpio@0 {
>>> +	compatible = "gpio-i2c";
>>> +	gpios =<&pioA 23 0 /* sda */
>>> +		&pioA 24 0 /* scl */
>>> +		>;
>>> +	gpio-i2c,sda_is_open_drain;
>>> +	gpio-i2c,scl_is_open_drain;
>>> +	udelay =<2>;		/* ~100 kHz */
>>> +	#address-cells =<1>;
>>> +	#size-cells =<0>;
>>> +
>>> +	rv3029c2@56 {
>>> +		compatible = "rv3029c2";
>>> +		reg =<0x56>;
>>> +	};
>>> +};
>>> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
>>> index a651779..6b5d794 100644
>>> --- a/drivers/i2c/busses/i2c-gpio.c
>>> +++ b/drivers/i2c/busses/i2c-gpio.c
>>> @@ -14,6 +14,8 @@
>>>   #include<linux/module.h>
>>>   #include<linux/slab.h>
>>>   #include<linux/platform_device.h>
>>> +#include<linux/of_gpio.h>
>>> +#include<linux/of_i2c.h>
>>>
>>>   #include<asm/gpio.h>
>>>
>>> @@ -78,16 +80,51 @@ static int i2c_gpio_getscl(void *data)
>>>   	return gpio_get_value(pdata->scl_pin);
>>>   }
>>>
>>> +static int of_i2c_gpio_probe(struct device_node *np,
>>> +			     struct i2c_gpio_platform_data *pdata)
>>> +{
>>> +	u32 reg;
>>> +
>>
>> if (of_gpio_count(np)<  2)
>> 	return -EINVAL;
> ok
>>
>>> +	pdata->sda_pin = of_get_gpio(np, 0);
>>> +	pdata->scl_pin = of_get_gpio(np, 1);
>>
>> if (pdata->sda_pin<  0 || pdata->scl_pin<  0)
>> 	return -EINVAL;
>
>>
>>> +
>>> +	if (of_property_read_u32(np, "udelay",&reg))
>>> +		pdata->udelay = reg;
>>> +
>>> +	if (of_property_read_u32(np, "timeout",&reg))
>>> +		pdata->timeout = reg;

One more thing missed in original review - of_property_read* rnegative 
value on error, so logic has to reversed here:

   if (of_property_read_u32(np, "timeout",&reg) == 0)

or

   if (!of_property_read_u32(np, "timeout",&reg))


As I have been testing your driver on real hardware I've also made 
changes (see below) which I have previously written about. If you would 
like to see these in git-am-able format please drop me a note.

diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 6b5d794..d22c2c7 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -80,29 +80,45 @@ static int i2c_gpio_getscl(void *data)
  	return gpio_get_value(pdata->scl_pin);
  }

+#ifdef CONFIG_OF
  static int of_i2c_gpio_probe(struct device_node *np,
  			     struct i2c_gpio_platform_data *pdata)
  {
  	u32 reg;

+	if (!np)
+		return -EINVAL;
+
+	if (of_gpio_count(np) < 2)
+		return -EINVAL;
+
  	pdata->sda_pin = of_get_gpio(np, 0);
  	pdata->scl_pin = of_get_gpio(np, 1);

-	if (of_property_read_u32(np, "udelay", &reg))
+	if (pdata->sda_pin < 0 || pdata->scl_pin < 0)
+		return -EINVAL;
+
+	if (!of_property_read_u32(np, "udelay", &reg))
  		pdata->udelay = reg;

-	if (of_property_read_u32(np, "timeout", &reg))
+	if (!of_property_read_u32(np, "timeout", &reg))
  		pdata->timeout = reg;

  	pdata->sda_is_open_drain =
-		!!of_get_property(np, "gpio-i2c,sda_is_open_drain", NULL);
+		!!of_get_property(np, "i2c-gpio,sda-open-drain", NULL);
  	pdata->scl_is_open_drain =
-		!!of_get_property(np, "gpio-i2c,scl_is_open_drain", NULL);
+		!!of_get_property(np, "i2c-gpio,scl-open-drain", NULL);
  	pdata->scl_is_output_only =
-		!!of_get_property(np, "gpio-i2c,scl_is_output_only", NULL);
+		!!of_get_property(np, "i2c-gpio,scl-output-only", NULL);

  	return 0;
  }
+#else
+static int of_i2c_gpio_probe(struct device_node *np,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -EINVAL
+#endif

  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
  {
@@ -116,15 +132,11 @@ static int __devinit i2c_gpio_probe(struct 
platform_device *pdev)
  	if (!pdata)
  		return -ENOMEM;

-	if (pdev->dev.of_node) {
-		of_i2c_gpio_probe(pdev->dev.of_node, pdata);
-	} else {
-		if (!pdev->dev.platform_data) {
-			ret = -ENXIO;
-			goto err_alloc_adap;
-		}
+	ret = -ENXIO;
+	if ((ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata)) < 0 && 
!pdev->dev.platform_data)
+		goto err_alloc_adap;
+	else if (pdev->dev.platform_data)
  		memcpy(pdata, pdev->dev.platform_data, len);
-	}

  	ret = -ENOMEM;
  	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
@@ -235,7 +247,7 @@ static int __devexit i2c_gpio_remove(struct 
platform_device *pdev)

  #if defined(CONFIG_OF)
  static const struct of_device_id gpio_i2c_dt_ids[] = {
-	{ .compatible = "gpio-i2c", },
+	{ .compatible = "i2c-gpio", },
  	{ /* sentinel */ }
  };


Regards,
-- 
Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

WARNING: multiple messages have this Message-ID (diff)
From: k.lewandowsk@samsung.com (Karol Lewandowski)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4] i2c/gpio-i2c add: add DT support
Date: Tue, 07 Feb 2012 16:35:38 +0100	[thread overview]
Message-ID: <4F3144CA.6070003@samsung.com> (raw)
In-Reply-To: <20120207032533.GC15647@game.jcrosoft.org>

On 07.02.2012 04:25, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 19:38 Mon 06 Feb     , Karol Lewandowski wrote:

>>> +	- udelay: half clock cycle time in us (may depend on each platform)
>>
>> Could we use "clock-frequency" as Grant have suggested during review
>> of previous patch to i2c-gpio?

> as exaplained no as for gpio the delay is platform dependent

Following sniplet from i2c-gpio suggests that in some cases both udelay 
and timeout can be calculated given presence of other parameters:

   static int __devinit i2c_gpio_probe(struct platform_device *pdev)
   ...
	if (pdata->udelay)
		bit_data->udelay = pdata->udelay;
	else if (pdata->scl_is_output_only)
		bit_data->udelay = 50;			/* 10 kHz */
	else
		bit_data->udelay = 5;			/* 100 kHz */

	if (pdata->timeout)
		bit_data->timeout = pdata->timeout;
	else
		bit_data->timeout = HZ / 10;		/* 100 ms */

However, I find it more troubling that driver manually grabs parameters 
that are specific to i2c-algo-bit (timeout, udelay).

Thus, I have feeling that it should be generically addressed there. What 
do you think?


>>
>>    https://lkml.org/lkml/2011/2/24/220
>>
>>> +	- timeout: timeout to get data
>>> +
>>> +
>>> +Example nodes:
>>> +
>>> +i2c-gpio at 0 {
>>> +	compatible = "gpio-i2c";
>>> +	gpios =<&pioA 23 0 /* sda */
>>> +		&pioA 24 0 /* scl */
>>> +		>;
>>> +	gpio-i2c,sda_is_open_drain;
>>> +	gpio-i2c,scl_is_open_drain;
>>> +	udelay =<2>;		/* ~100 kHz */
>>> +	#address-cells =<1>;
>>> +	#size-cells =<0>;
>>> +
>>> +	rv3029c2 at 56 {
>>> +		compatible = "rv3029c2";
>>> +		reg =<0x56>;
>>> +	};
>>> +};
>>> diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
>>> index a651779..6b5d794 100644
>>> --- a/drivers/i2c/busses/i2c-gpio.c
>>> +++ b/drivers/i2c/busses/i2c-gpio.c
>>> @@ -14,6 +14,8 @@
>>>   #include<linux/module.h>
>>>   #include<linux/slab.h>
>>>   #include<linux/platform_device.h>
>>> +#include<linux/of_gpio.h>
>>> +#include<linux/of_i2c.h>
>>>
>>>   #include<asm/gpio.h>
>>>
>>> @@ -78,16 +80,51 @@ static int i2c_gpio_getscl(void *data)
>>>   	return gpio_get_value(pdata->scl_pin);
>>>   }
>>>
>>> +static int of_i2c_gpio_probe(struct device_node *np,
>>> +			     struct i2c_gpio_platform_data *pdata)
>>> +{
>>> +	u32 reg;
>>> +
>>
>> if (of_gpio_count(np)<  2)
>> 	return -EINVAL;
> ok
>>
>>> +	pdata->sda_pin = of_get_gpio(np, 0);
>>> +	pdata->scl_pin = of_get_gpio(np, 1);
>>
>> if (pdata->sda_pin<  0 || pdata->scl_pin<  0)
>> 	return -EINVAL;
>
>>
>>> +
>>> +	if (of_property_read_u32(np, "udelay",&reg))
>>> +		pdata->udelay = reg;
>>> +
>>> +	if (of_property_read_u32(np, "timeout",&reg))
>>> +		pdata->timeout = reg;

One more thing missed in original review - of_property_read* rnegative 
value on error, so logic has to reversed here:

   if (of_property_read_u32(np, "timeout",&reg) == 0)

or

   if (!of_property_read_u32(np, "timeout",&reg))


As I have been testing your driver on real hardware I've also made 
changes (see below) which I have previously written about. If you would 
like to see these in git-am-able format please drop me a note.

diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 6b5d794..d22c2c7 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -80,29 +80,45 @@ static int i2c_gpio_getscl(void *data)
  	return gpio_get_value(pdata->scl_pin);
  }

+#ifdef CONFIG_OF
  static int of_i2c_gpio_probe(struct device_node *np,
  			     struct i2c_gpio_platform_data *pdata)
  {
  	u32 reg;

+	if (!np)
+		return -EINVAL;
+
+	if (of_gpio_count(np) < 2)
+		return -EINVAL;
+
  	pdata->sda_pin = of_get_gpio(np, 0);
  	pdata->scl_pin = of_get_gpio(np, 1);

-	if (of_property_read_u32(np, "udelay", &reg))
+	if (pdata->sda_pin < 0 || pdata->scl_pin < 0)
+		return -EINVAL;
+
+	if (!of_property_read_u32(np, "udelay", &reg))
  		pdata->udelay = reg;

-	if (of_property_read_u32(np, "timeout", &reg))
+	if (!of_property_read_u32(np, "timeout", &reg))
  		pdata->timeout = reg;

  	pdata->sda_is_open_drain =
-		!!of_get_property(np, "gpio-i2c,sda_is_open_drain", NULL);
+		!!of_get_property(np, "i2c-gpio,sda-open-drain", NULL);
  	pdata->scl_is_open_drain =
-		!!of_get_property(np, "gpio-i2c,scl_is_open_drain", NULL);
+		!!of_get_property(np, "i2c-gpio,scl-open-drain", NULL);
  	pdata->scl_is_output_only =
-		!!of_get_property(np, "gpio-i2c,scl_is_output_only", NULL);
+		!!of_get_property(np, "i2c-gpio,scl-output-only", NULL);

  	return 0;
  }
+#else
+static int of_i2c_gpio_probe(struct device_node *np,
+			     struct i2c_gpio_platform_data *pdata)
+{
+	return -EINVAL
+#endif

  static int __devinit i2c_gpio_probe(struct platform_device *pdev)
  {
@@ -116,15 +132,11 @@ static int __devinit i2c_gpio_probe(struct 
platform_device *pdev)
  	if (!pdata)
  		return -ENOMEM;

-	if (pdev->dev.of_node) {
-		of_i2c_gpio_probe(pdev->dev.of_node, pdata);
-	} else {
-		if (!pdev->dev.platform_data) {
-			ret = -ENXIO;
-			goto err_alloc_adap;
-		}
+	ret = -ENXIO;
+	if ((ret = of_i2c_gpio_probe(pdev->dev.of_node, pdata)) < 0 && 
!pdev->dev.platform_data)
+		goto err_alloc_adap;
+	else if (pdev->dev.platform_data)
  		memcpy(pdata, pdev->dev.platform_data, len);
-	}

  	ret = -ENOMEM;
  	adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
@@ -235,7 +247,7 @@ static int __devexit i2c_gpio_remove(struct 
platform_device *pdev)

  #if defined(CONFIG_OF)
  static const struct of_device_id gpio_i2c_dt_ids[] = {
-	{ .compatible = "gpio-i2c", },
+	{ .compatible = "i2c-gpio", },
  	{ /* sentinel */ }
  };


Regards,
-- 
Karol Lewandowski | Samsung Poland R&D Center | Linux/Platform

  parent reply	other threads:[~2012-02-07 15:35 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-05 10:38 [PATCH 1/4] i2c/gpio-i2c add: add DT support Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38 ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38 ` [PATCH 2/4] ARM: at91s: sam9g20 add i2c " Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38   ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38 ` [PATCH 3/4] ARM: at91: usb_a9g20 add DT i2c support Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38   ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38 ` [PATCH 4/4] ARM: at91: sam9g45 add i2c DT support Jean-Christophe PLAGNIOL-VILLARD
2012-02-05 10:38   ` Jean-Christophe PLAGNIOL-VILLARD
     [not found] ` <1328438337-21185-1-git-send-email-plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org>
2012-02-06 16:09   ` [PATCH 1/4] i2c/gpio-i2c add: add " Mark Brown
2012-02-06 16:09     ` Mark Brown
     [not found]     ` <20120206160907.GG10173-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2012-02-07  2:56       ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-07  2:56         ` Jean-Christophe PLAGNIOL-VILLARD
     [not found]         ` <20120207025624.GB15647-RQcB7r2h9QmfDR2tN2SG5Ni2O/JbrIOy@public.gmane.org>
2012-02-07 11:25           ` Mark Brown
2012-02-07 11:25             ` Mark Brown
2012-02-06 18:38   ` Karol Lewandowski
2012-02-06 18:38     ` Karol Lewandowski
     [not found]     ` <4F301E25.5060507-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-02-06 19:15       ` Jean Delvare
2012-02-06 19:15         ` Jean Delvare
2012-02-07  3:25       ` Jean-Christophe PLAGNIOL-VILLARD
2012-02-07  3:25         ` Jean-Christophe PLAGNIOL-VILLARD
     [not found]         ` <20120207032533.GC15647-RQcB7r2h9QmfDR2tN2SG5Ni2O/JbrIOy@public.gmane.org>
2012-02-07 15:35           ` Karol Lewandowski [this message]
2012-02-07 15:35             ` Karol Lewandowski
2012-02-13 23:14       ` Ben Dooks
2012-02-13 23:14         ` Ben Dooks

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F3144CA.6070003@samsung.com \
    --to=k.lewandowsk-sze3o3uu22jbdgjk7y7tuq@public.gmane.org \
    --cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
    --cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=plagnioj-sclMFOaUSTBWk0Htik3J/w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.