aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/i2c/samsung-i2c.txt8
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c30
2 files changed, 36 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt b/Documentation/devicetree/bindings/i2c/samsung-i2c.txt
index 38832c712919..b6cb5a12c672 100644
--- a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/samsung-i2c.txt
@@ -6,14 +6,18 @@ Required properties:
6 - compatible: value should be either of the following. 6 - compatible: value should be either of the following.
7 (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c. 7 (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c.
8 (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. 8 (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c.
9 (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used
10 inside HDMIPHY block found on several samsung SoCs
9 - reg: physical base address of the controller and length of memory mapped 11 - reg: physical base address of the controller and length of memory mapped
10 region. 12 region.
11 - interrupts: interrupt number to the cpu. 13 - interrupts: interrupt number to the cpu.
12 - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges. 14 - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges.
13 - gpios: The order of the gpios should be the following: <SDA, SCL>.
14 The gpio specifier depends on the gpio controller.
15 15
16Optional properties: 16Optional properties:
17 - gpios: The order of the gpios should be the following: <SDA, SCL>.
18 The gpio specifier depends on the gpio controller. Required in all
19 cases except for "samsung,s3c2440-hdmiphy-i2c" whose input/output
20 lines are permanently wired to the respective client
17 - samsung,i2c-slave-addr: Slave address in multi-master enviroment. If not 21 - samsung,i2c-slave-addr: Slave address in multi-master enviroment. If not
18 specified, default value is 0. 22 specified, default value is 0.
19 - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not 23 - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 23736ffaaa2a..fa0b13490873 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -46,6 +46,8 @@
46 46
47/* Treat S3C2410 as baseline hardware, anything else is supported via quirks */ 47/* Treat S3C2410 as baseline hardware, anything else is supported via quirks */
48#define QUIRK_S3C2440 (1 << 0) 48#define QUIRK_S3C2440 (1 << 0)
49#define QUIRK_HDMIPHY (1 << 1)
50#define QUIRK_NO_GPIO (1 << 2)
49 51
50/* i2c controller state */ 52/* i2c controller state */
51enum s3c24xx_i2c_state { 53enum s3c24xx_i2c_state {
@@ -93,6 +95,9 @@ static struct platform_device_id s3c24xx_driver_ids[] = {
93 }, { 95 }, {
94 .name = "s3c2440-i2c", 96 .name = "s3c2440-i2c",
95 .driver_data = QUIRK_S3C2440, 97 .driver_data = QUIRK_S3C2440,
98 }, {
99 .name = "s3c2440-hdmiphy-i2c",
100 .driver_data = QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO,
96 }, { }, 101 }, { },
97}; 102};
98MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids); 103MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
@@ -101,6 +106,8 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
101static const struct of_device_id s3c24xx_i2c_match[] = { 106static const struct of_device_id s3c24xx_i2c_match[] = {
102 { .compatible = "samsung,s3c2410-i2c", .data = (void *)0 }, 107 { .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
103 { .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 }, 108 { .compatible = "samsung,s3c2440-i2c", .data = (void *)QUIRK_S3C2440 },
109 { .compatible = "samsung,s3c2440-hdmiphy-i2c",
110 .data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
104 {}, 111 {},
105}; 112};
106MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match); 113MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
@@ -483,6 +490,13 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
483 unsigned long iicstat; 490 unsigned long iicstat;
484 int timeout = 400; 491 int timeout = 400;
485 492
493 /* the timeout for HDMIPHY is reduced to 10 ms because
494 * the hangup is expected to happen, so waiting 400 ms
495 * causes only unnecessary system hangup
496 */
497 if (i2c->quirks & QUIRK_HDMIPHY)
498 timeout = 10;
499
486 while (timeout-- > 0) { 500 while (timeout-- > 0) {
487 iicstat = readl(i2c->regs + S3C2410_IICSTAT); 501 iicstat = readl(i2c->regs + S3C2410_IICSTAT);
488 502
@@ -492,6 +506,15 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
492 msleep(1); 506 msleep(1);
493 } 507 }
494 508
509 /* hang-up of bus dedicated for HDMIPHY occurred, resetting */
510 if (i2c->quirks & QUIRK_HDMIPHY) {
511 writel(0, i2c->regs + S3C2410_IICCON);
512 writel(0, i2c->regs + S3C2410_IICSTAT);
513 writel(0, i2c->regs + S3C2410_IICDS);
514
515 return 0;
516 }
517
495 return -ETIMEDOUT; 518 return -ETIMEDOUT;
496} 519}
497 520
@@ -773,6 +796,9 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
773{ 796{
774 int idx, gpio, ret; 797 int idx, gpio, ret;
775 798
799 if (i2c->quirks & QUIRK_NO_GPIO)
800 return 0;
801
776 for (idx = 0; idx < 2; idx++) { 802 for (idx = 0; idx < 2; idx++) {
777 gpio = of_get_gpio(i2c->dev->of_node, idx); 803 gpio = of_get_gpio(i2c->dev->of_node, idx);
778 if (!gpio_is_valid(gpio)) { 804 if (!gpio_is_valid(gpio)) {
@@ -797,6 +823,10 @@ free_gpio:
797static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) 823static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c)
798{ 824{
799 unsigned int idx; 825 unsigned int idx;
826
827 if (i2c->quirks & QUIRK_NO_GPIO)
828 return;
829
800 for (idx = 0; idx < 2; idx++) 830 for (idx = 0; idx < 2; idx++)
801 gpio_free(i2c->gpios[idx]); 831 gpio_free(i2c->gpios[idx]);
802} 832}