Patchwork [v2,1/1,resend] i2c: rcar: modify I2C driver

login
register
mail settings
Submitter Nguyen Viet Dung
Date Aug. 5, 2013, 7:19 a.m.
Message ID <1375687174-577-2-git-send-email-nv-dung@jinso.co.jp>
Download mbox | patch
Permalink /patch/264580/
State Changes Requested
Headers show

Comments

Nguyen Viet Dung - Aug. 5, 2013, 7:19 a.m.
This patch modify I2C driver of rcar-H1 to usable on both rcar-H1 and rcar-H2.

Signed-off-by: Nguyen Viet Dung <nv-dung@jinso.co.jp>
---
 drivers/i2c/busses/i2c-rcar.c |   17 +++++++++++++++--
 include/linux/i2c/i2c-rcar.h  |    4 ++++
 2 files changed, 19 insertions(+), 2 deletions(-)
Wolfram Sang - Aug. 7, 2013, 3:12 p.m.
On Mon, Aug 05, 2013 at 04:19:34PM +0900, Nguyen Viet Dung wrote:
> This patch modify I2C driver of rcar-H1 to usable on both rcar-H1 and rcar-H2.
> 
> Signed-off-by: Nguyen Viet Dung <nv-dung@jinso.co.jp>

Isn't it possible to distinguish between H1 and H2 somewhere in
hardware? Then we could skip the 'flags' variable in pdata.

Thanks,

   Wolfram
Nguyen Viet Dung - Aug. 8, 2013, 1:13 a.m.
Difference between H2 and H1 in hardware is only CDF bit of ICCCR register.
So, by using the flag variable in pdata, it is possible to distinguish 
H2 and H1.

If this method is not a common method, please tell me about common method.

Thanks,
Dung
On 08/08/2013 12:12 AM, Wolfram Sang wrote:
> On Mon, Aug 05, 2013 at 04:19:34PM +0900, Nguyen Viet Dung wrote:
>> This patch modify I2C driver of rcar-H1 to usable on both rcar-H1 and rcar-H2.
>>
>> Signed-off-by: Nguyen Viet Dung <nv-dung@jinso.co.jp>
> Isn't it possible to distinguish between H1 and H2 somewhere in
> hardware? Then we could skip the 'flags' variable in pdata.
>
> Thanks,
>
>     Wolfram

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfram Sang - Aug. 8, 2013, 8:12 a.m.
On Thu, Aug 08, 2013 at 10:13:16AM +0900, Nguyen Viet Dung wrote:

> Difference between H2 and H1 in hardware is only CDF bit of ICCCR register.

No IP version register? Sigh...

> If this method is not a common method, please tell me about common method.

Use a new platform_device_id and populate the driver_data with the info
needed to distinguish between the revisions. Check i2c-imx.c for an
example.

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nguyen Viet Dung - Aug. 8, 2013, 11:39 a.m.
Hi Wolffam

Thank for your advice.
I have understand what you have guided.

Time of 08/10~08/18 day is summer holiday in Japan.
Affter summer holiday, I am going modify the patch, and send again.

At that time,please check it for me.
Thanks,
Dung

On 08/08/2013 05:12 PM, Wolfram Sang wrote:
> On Thu, Aug 08, 2013 at 10:13:16AM +0900, Nguyen Viet Dung wrote:
>
>> Difference between H2 and H1 in hardware is only CDF bit of ICCCR register.
> No IP version register? Sigh...
>
>> If this method is not a common method, please tell me about common method.
> Use a new platform_device_id and populate the driver_data with the info
> needed to distinguish between the revisions. Check i2c-imx.c for an
> example.
>
>
>

--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index 4ba4a95..85987c1 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -221,15 +221,28 @@  static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
 				    struct device *dev)
 {
 	struct clk *clkp = clk_get(NULL, "peripheral_clk");
+	struct i2c_rcar_platform_data *pdata = dev->platform_data;
 	u32 scgd, cdf;
 	u32 round, ick;
 	u32 scl;
+	u32 cdf_width;
+	u32 flags = pdata ? pdata->flags : 0;
 
 	if (!clkp) {
 		dev_err(dev, "there is no peripheral_clk\n");
 		return -EIO;
 	}
 
+	switch (flags & I2C_RCAR_FLAGS_ICCCR_MASK) {
+	default:
+	case I2C_RCAR_FLAGS_ICCCR_IS_2BIT:
+		cdf_width = 2;
+		break;
+	case I2C_RCAR_FLAGS_ICCCR_IS_3BIT:
+		cdf_width = 3;
+		break;
+	}
+
 	/*
 	 * calculate SCL clock
 	 * see
@@ -245,7 +258,7 @@  static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
 	 * clkp : peripheral_clk
 	 * F[]  : integer up-valuation
 	 */
-	for (cdf = 0; cdf < 4; cdf++) {
+	for (cdf = 0; cdf < (1 << cdf_width); cdf++) {
 		ick = clk_get_rate(clkp) / (1 + cdf);
 		if (ick < 20000000)
 			goto ick_find;
@@ -287,7 +300,7 @@  scgd_find:
 	/*
 	 * keep icccr value
 	 */
-	priv->icccr = (scgd << 2 | cdf);
+	priv->icccr = (scgd << (cdf_width) | cdf);
 
 	return 0;
 }
diff --git a/include/linux/i2c/i2c-rcar.h b/include/linux/i2c/i2c-rcar.h
index 496f5c2..572a6e5 100644
--- a/include/linux/i2c/i2c-rcar.h
+++ b/include/linux/i2c/i2c-rcar.h
@@ -5,6 +5,10 @@ 
 
 struct i2c_rcar_platform_data {
 	u32 bus_speed;
+	u32 flags;
+#define I2C_RCAR_FLAGS_ICCCR_MASK	(0xF << 0)
+#define I2C_RCAR_FLAGS_ICCCR_IS_2BIT	(0 << 0) /* default */
+#define I2C_RCAR_FLAGS_ICCCR_IS_3BIT	(1 << 0)
 };
 
 #endif /* __I2C_R_CAR_H__ */