[PATCH] I2C: EXYNOS: High speed mode clock setting for HSI2C

2013-04-19 Thread Yuvaraj Kumar C D
This patch configure the High speed mode timing register using the
clock speed mentioned in the dts file.Also it configure the MASTER_ID
for High speed i2c transfer.
For i2c high speed transaction, tarnsaction initially starts with the
fast mode i,e 400Kbits/sec and then switches to high speed mode.For this
purpose it requires to set up timing value for fast mode and high speed
mode.

Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com
---
 drivers/i2c/busses/i2c-exynos5.c |   85 ++
 1 file changed, 58 insertions(+), 27 deletions(-)

diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
index 968c34f..ef7155f 100644
--- a/drivers/i2c/busses/i2c-exynos5.c
+++ b/drivers/i2c/busses/i2c-exynos5.c
@@ -139,12 +139,14 @@
 #define HSI2C_SLV_ADDR_SLV(x)  ((x  0x3ff)  0)
 #define HSI2C_SLV_ADDR_MAS(x)  ((x  0x3ff)  10)
 #define HSI2C_MASTER_ID(x) ((x  0xff)  24)
+#define MASTER_ID(x)   ((x  0x7) + 0x08)
 
 /* Controller operating frequency, timing values for operation
  * are calculated against this frequency
  */
 #define HSI2C_HS_TX_CLOCK  100
-#define HSI2C_FS_TX_CLOCK  100
+/*HSI2C supports upto 400 kb/s in FAST Mode and 3.4 Mb/s in High Speed Mode*/
+#define HSI2C_FS_TX_CLOCK   40
 #define HSI2C_HIGH_SPD 1
 #define HSI2C_FAST_SPD 0
 
@@ -173,7 +175,8 @@ struct exynos5_i2c {
int gpios[2];
 
/* Controller operating frequency */
-   unsigned intclock;
+   unsigned intfs_clock;
+   unsigned inths_clock;
unsigned intclk_cycle;
unsigned intclk_div;
 
@@ -182,6 +185,7 @@ struct exynos5_i2c {
 * 2. Fast speed upto 1Mbps
 */
int speed_mode;
+   int current_mode;
 };
 
 static const struct of_device_id exynos5_i2c_match[] = {
@@ -222,10 +226,11 @@ static void exynos5_i2c_clr_pend_irq(struct exynos5_i2c 
*i2c)
  */
 static int exynos5_i2c_clock_info(struct exynos5_i2c *i2c)
 {
-   unsigned int op_clk = i2c-clock;
unsigned int clkin = clk_get_rate(i2c-clk);
-   unsigned int i, utemp0 = 0, utemp1 = 0;
+   unsigned int div, utemp0 = 0, utemp1 = 0;
unsigned int t_ftl_cycle;
+   unsigned int op_clk = (i2c-current_mode == HSI2C_HIGH_SPD) ?
+   i2c-hs_clock : i2c-fs_clock;
 
/* FPCLK / FI2C =
 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
@@ -236,8 +241,8 @@ static int exynos5_i2c_clock_info(struct exynos5_i2c *i2c)
utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle;
 
/* CLK_DIV max is 256 */
-   for (i = 0; i  256; i++) {
-   utemp1 = utemp0 / (i + 1);
+   for (div = 0; div  256; div++) {
+   utemp1 = utemp0 / (div + 1);
 
/* SCL_L and SCL_H each has max value of 255
 * Hence, For the clk_cycle to the have right value
@@ -245,7 +250,7 @@ static int exynos5_i2c_clock_info(struct exynos5_i2c *i2c)
 */
if ((utemp1  512)  (utemp1  4)) {
i2c-clk_cycle = utemp1 - 2;
-   i2c-clk_div = i;
+   i2c-clk_div = div;
return 0;
}
}
@@ -297,7 +302,7 @@ static void exynos5_i2c_set_timing(struct exynos5_i2c *i2c)
n_clkdiv, t_sr_release);
dev_dbg(i2c-dev, tDATA_HD: %X\n, t_data_hd);
 
-   if (i2c-speed_mode == HSI2C_HIGH_SPD) {
+   if (i2c-current_mode == HSI2C_HIGH_SPD) {
writel(i2c_timing_s1, i2c-regs + HSI2C_TIMING_HS1);
writel(i2c_timing_s2, i2c-regs + HSI2C_TIMING_HS2);
writel(i2c_timing_s3, i2c-regs + HSI2C_TIMING_HS3);
@@ -309,25 +314,52 @@ static void exynos5_i2c_set_timing(struct exynos5_i2c 
*i2c)
writel(i2c_timing_sla, i2c-regs + HSI2C_TIMING_SLA);
 }
 
+static int exynos5_hsi2c_clock_setup(struct exynos5_i2c *i2c)
+{
+
+   if (exynos5_i2c_clock_info(i2c)) {
+   dev_err(i2c-dev, HSI2C FS Clock set up failed\n);
+   return -EINVAL;
+   }
+   exynos5_i2c_set_timing(i2c);
+/*If controller supports High Speed configure the High speed timing value*/
+   if (i2c-speed_mode == HSI2C_HIGH_SPD) {
+   i2c-current_mode = HSI2C_HIGH_SPD;
+   if (exynos5_i2c_clock_info(i2c)) {
+   dev_err(i2c-dev, HSI2C HS Clock set up failed\n);
+   return -EINVAL;
+   }
+   exynos5_i2c_set_timing(i2c);
+   }
+   return 0;
+}
+
 /* exynos5_i2c_init: configures the controller for I2C functionality
  * Programs I2C controller for Master mode operation
  *
  * Note: Currently, supports AUTO mode of operation.
  */
-static void exynos5_i2c_init(struct exynos5_i2c *i2c)

Re: [PATCH] I2C: EXYNOS: High speed mode clock setting for HSI2C

2013-04-19 Thread Wolfram Sang
On Fri, Apr 19, 2013 at 05:26:23PM +0530, Yuvaraj Kumar C D wrote:
 This patch configure the High speed mode timing register using the
 clock speed mentioned in the dts file.Also it configure the MASTER_ID
 for High speed i2c transfer.
 For i2c high speed transaction, tarnsaction initially starts with the
 fast mode i,e 400Kbits/sec and then switches to high speed mode.For this
 purpose it requires to set up timing value for fast mode and high speed
 mode.
 
 Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com

Since the exynos5 driver needs to be resent anyhow, I assume this will
be included in the next version? Please note that I had comments
regarding the bindings of the bus speed. We have a generic binding for
that already.

Thanks,

   Wolfram

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