aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2015-06-09 03:14:39 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-06-17 06:40:38 -0400
commit3ded3743a026e0762fa74467eafc66ecc1c484cc (patch)
treeb7dd4178119f4aeafb48021c9157e9357c30673c /drivers/i2c
parentf30dc5208ca270ff783fa895b74bdd76dcb4ba3e (diff)
i2c: sh_mobile: add errata workaround
This used to be in platform init code. We want it to do in the driver now. This is basically a code move and a new compatible added. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Simon Horman <horms+renesas@verge.net.au> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 007818b3e174..7193bcfdd940 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -150,6 +150,7 @@ struct sh_mobile_i2c_data {
150 150
151struct sh_mobile_dt_config { 151struct sh_mobile_dt_config {
152 int clks_per_count; 152 int clks_per_count;
153 void (*setup)(struct sh_mobile_i2c_data *pd);
153}; 154};
154 155
155#define IIC_FLAG_HAS_ICIC67 (1 << 0) 156#define IIC_FLAG_HAS_ICIC67 (1 << 0)
@@ -164,6 +165,7 @@ struct sh_mobile_dt_config {
164#define ICIC 0x0c 165#define ICIC 0x0c
165#define ICCL 0x10 166#define ICCL 0x10
166#define ICCH 0x14 167#define ICCH 0x14
168#define ICSTART 0x70
167 169
168/* Register bits */ 170/* Register bits */
169#define ICCR_ICE 0x80 171#define ICCR_ICE 0x80
@@ -190,6 +192,8 @@ struct sh_mobile_dt_config {
190#define ICIC_WAITE 0x02 192#define ICIC_WAITE 0x02
191#define ICIC_DTEE 0x01 193#define ICIC_DTEE 0x01
192 194
195#define ICSTART_ICSTART 0x10
196
193static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) 197static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
194{ 198{
195 if (offs == ICIC) 199 if (offs == ICIC)
@@ -782,6 +786,33 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = {
782 .master_xfer = sh_mobile_i2c_xfer, 786 .master_xfer = sh_mobile_i2c_xfer,
783}; 787};
784 788
789/*
790 * r8a7740 chip has lasting errata on I2C I/O pad reset.
791 * this is work-around for it.
792 */
793static void sh_mobile_i2c_r8a7740_workaround(struct sh_mobile_i2c_data *pd)
794{
795 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
796 iic_rd(pd, ICCR); /* dummy read */
797
798 iic_set_clr(pd, ICSTART, ICSTART_ICSTART, 0);
799 iic_rd(pd, ICSTART); /* dummy read */
800
801 udelay(10);
802
803 iic_wr(pd, ICCR, ICCR_SCP);
804 iic_wr(pd, ICSTART, 0);
805
806 udelay(10);
807
808 iic_wr(pd, ICCR, ICCR_TRS);
809 udelay(10);
810 iic_wr(pd, ICCR, 0);
811 udelay(10);
812 iic_wr(pd, ICCR, ICCR_TRS);
813 udelay(10);
814}
815
785static const struct sh_mobile_dt_config default_dt_config = { 816static const struct sh_mobile_dt_config default_dt_config = {
786 .clks_per_count = 1, 817 .clks_per_count = 1,
787}; 818};
@@ -790,9 +821,15 @@ static const struct sh_mobile_dt_config fast_clock_dt_config = {
790 .clks_per_count = 2, 821 .clks_per_count = 2,
791}; 822};
792 823
824static const struct sh_mobile_dt_config r8a7740_dt_config = {
825 .clks_per_count = 1,
826 .setup = sh_mobile_i2c_r8a7740_workaround,
827};
828
793static const struct of_device_id sh_mobile_i2c_dt_ids[] = { 829static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
794 { .compatible = "renesas,rmobile-iic", .data = &default_dt_config }, 830 { .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
795 { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, 831 { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config },
832 { .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config },
796 { .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config }, 833 { .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config },
797 { .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config }, 834 { .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config },
798 { .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config }, 835 { .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config },
@@ -885,6 +922,9 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
885 922
886 config = match->data; 923 config = match->data;
887 pd->clks_per_count = config->clks_per_count; 924 pd->clks_per_count = config->clks_per_count;
925
926 if (config->setup)
927 config->setup(pd);
888 } 928 }
889 } else { 929 } else {
890 if (pdata && pdata->bus_speed) 930 if (pdata && pdata->bus_speed)