aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorNguyen Viet Dung <nv-dung@jinso.co.jp>2013-09-02 20:09:25 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-09-04 06:49:16 -0400
commitb720423a2627f045133bec39a31fe2bc0dab86f3 (patch)
tree8b75444c4c435016fd24646a7ac64b9c452522c0 /drivers/i2c/busses
parent617da00cb11b75a17a271147e616296f754f591b (diff)
i2c: rcar: add rcar-H2 support
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> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-rcar.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
index e59c3f618542..d2fe11da5e82 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -101,6 +101,11 @@ enum {
101#define ID_ARBLOST (1 << 3) 101#define ID_ARBLOST (1 << 3)
102#define ID_NACK (1 << 4) 102#define ID_NACK (1 << 4)
103 103
104enum rcar_i2c_type {
105 I2C_RCAR_H1,
106 I2C_RCAR_H2,
107};
108
104struct rcar_i2c_priv { 109struct rcar_i2c_priv {
105 void __iomem *io; 110 void __iomem *io;
106 struct i2c_adapter adap; 111 struct i2c_adapter adap;
@@ -113,6 +118,7 @@ struct rcar_i2c_priv {
113 int irq; 118 int irq;
114 u32 icccr; 119 u32 icccr;
115 u32 flags; 120 u32 flags;
121 enum rcar_i2c_type devtype;
116}; 122};
117 123
118#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent) 124#define rcar_i2c_priv_to_dev(p) ((p)->adap.dev.parent)
@@ -224,12 +230,25 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
224 u32 scgd, cdf; 230 u32 scgd, cdf;
225 u32 round, ick; 231 u32 round, ick;
226 u32 scl; 232 u32 scl;
233 u32 cdf_width;
227 234
228 if (!clkp) { 235 if (!clkp) {
229 dev_err(dev, "there is no peripheral_clk\n"); 236 dev_err(dev, "there is no peripheral_clk\n");
230 return -EIO; 237 return -EIO;
231 } 238 }
232 239
240 switch (priv->devtype) {
241 case I2C_RCAR_H1:
242 cdf_width = 2;
243 break;
244 case I2C_RCAR_H2:
245 cdf_width = 3;
246 break;
247 default:
248 dev_err(dev, "device type error\n");
249 return -EIO;
250 }
251
233 /* 252 /*
234 * calculate SCL clock 253 * calculate SCL clock
235 * see 254 * see
@@ -245,7 +264,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
245 * clkp : peripheral_clk 264 * clkp : peripheral_clk
246 * F[] : integer up-valuation 265 * F[] : integer up-valuation
247 */ 266 */
248 for (cdf = 0; cdf < 4; cdf++) { 267 for (cdf = 0; cdf < (1 << cdf_width); cdf++) {
249 ick = clk_get_rate(clkp) / (1 + cdf); 268 ick = clk_get_rate(clkp) / (1 + cdf);
250 if (ick < 20000000) 269 if (ick < 20000000)
251 goto ick_find; 270 goto ick_find;
@@ -287,7 +306,7 @@ scgd_find:
287 /* 306 /*
288 * keep icccr value 307 * keep icccr value
289 */ 308 */
290 priv->icccr = (scgd << 2 | cdf); 309 priv->icccr = (scgd << (cdf_width) | cdf);
291 310
292 return 0; 311 return 0;
293} 312}
@@ -632,6 +651,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
632 bus_speed = 100000; /* default 100 kHz */ 651 bus_speed = 100000; /* default 100 kHz */
633 if (pdata && pdata->bus_speed) 652 if (pdata && pdata->bus_speed)
634 bus_speed = pdata->bus_speed; 653 bus_speed = pdata->bus_speed;
654
655 priv->devtype = platform_get_device_id(pdev)->driver_data;
656
635 ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); 657 ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
636 if (ret < 0) 658 if (ret < 0)
637 return ret; 659 return ret;
@@ -686,6 +708,14 @@ static int rcar_i2c_remove(struct platform_device *pdev)
686 return 0; 708 return 0;
687} 709}
688 710
711static struct platform_device_id rcar_i2c_id_table[] = {
712 { "i2c-rcar", I2C_RCAR_H1 },
713 { "i2c-rcar_h1", I2C_RCAR_H1 },
714 { "i2c-rcar_h2", I2C_RCAR_H2 },
715 {},
716};
717MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table);
718
689static struct platform_driver rcar_i2c_driver = { 719static struct platform_driver rcar_i2c_driver = {
690 .driver = { 720 .driver = {
691 .name = "i2c-rcar", 721 .name = "i2c-rcar",
@@ -693,6 +723,7 @@ static struct platform_driver rcar_i2c_driver = {
693 }, 723 },
694 .probe = rcar_i2c_probe, 724 .probe = rcar_i2c_probe,
695 .remove = rcar_i2c_remove, 725 .remove = rcar_i2c_remove,
726 .id_table = rcar_i2c_id_table,
696}; 727};
697 728
698module_platform_driver(rcar_i2c_driver); 729module_platform_driver(rcar_i2c_driver);