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>
This commit is contained in:
parent
f30dc5208c
commit
3ded3743a0
@ -150,6 +150,7 @@ struct sh_mobile_i2c_data {
|
|||||||
|
|
||||||
struct sh_mobile_dt_config {
|
struct sh_mobile_dt_config {
|
||||||
int clks_per_count;
|
int clks_per_count;
|
||||||
|
void (*setup)(struct sh_mobile_i2c_data *pd);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IIC_FLAG_HAS_ICIC67 (1 << 0)
|
#define IIC_FLAG_HAS_ICIC67 (1 << 0)
|
||||||
@ -164,6 +165,7 @@ struct sh_mobile_dt_config {
|
|||||||
#define ICIC 0x0c
|
#define ICIC 0x0c
|
||||||
#define ICCL 0x10
|
#define ICCL 0x10
|
||||||
#define ICCH 0x14
|
#define ICCH 0x14
|
||||||
|
#define ICSTART 0x70
|
||||||
|
|
||||||
/* Register bits */
|
/* Register bits */
|
||||||
#define ICCR_ICE 0x80
|
#define ICCR_ICE 0x80
|
||||||
@ -190,6 +192,8 @@ struct sh_mobile_dt_config {
|
|||||||
#define ICIC_WAITE 0x02
|
#define ICIC_WAITE 0x02
|
||||||
#define ICIC_DTEE 0x01
|
#define ICIC_DTEE 0x01
|
||||||
|
|
||||||
|
#define ICSTART_ICSTART 0x10
|
||||||
|
|
||||||
static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
|
static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
|
||||||
{
|
{
|
||||||
if (offs == ICIC)
|
if (offs == ICIC)
|
||||||
@ -782,6 +786,33 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = {
|
|||||||
.master_xfer = sh_mobile_i2c_xfer,
|
.master_xfer = sh_mobile_i2c_xfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* r8a7740 chip has lasting errata on I2C I/O pad reset.
|
||||||
|
* this is work-around for it.
|
||||||
|
*/
|
||||||
|
static void sh_mobile_i2c_r8a7740_workaround(struct sh_mobile_i2c_data *pd)
|
||||||
|
{
|
||||||
|
iic_set_clr(pd, ICCR, ICCR_ICE, 0);
|
||||||
|
iic_rd(pd, ICCR); /* dummy read */
|
||||||
|
|
||||||
|
iic_set_clr(pd, ICSTART, ICSTART_ICSTART, 0);
|
||||||
|
iic_rd(pd, ICSTART); /* dummy read */
|
||||||
|
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
iic_wr(pd, ICCR, ICCR_SCP);
|
||||||
|
iic_wr(pd, ICSTART, 0);
|
||||||
|
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
iic_wr(pd, ICCR, ICCR_TRS);
|
||||||
|
udelay(10);
|
||||||
|
iic_wr(pd, ICCR, 0);
|
||||||
|
udelay(10);
|
||||||
|
iic_wr(pd, ICCR, ICCR_TRS);
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct sh_mobile_dt_config default_dt_config = {
|
static const struct sh_mobile_dt_config default_dt_config = {
|
||||||
.clks_per_count = 1,
|
.clks_per_count = 1,
|
||||||
};
|
};
|
||||||
@ -790,9 +821,15 @@ static const struct sh_mobile_dt_config fast_clock_dt_config = {
|
|||||||
.clks_per_count = 2,
|
.clks_per_count = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sh_mobile_dt_config r8a7740_dt_config = {
|
||||||
|
.clks_per_count = 1,
|
||||||
|
.setup = sh_mobile_i2c_r8a7740_workaround,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
|
static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
|
||||||
{ .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
|
{ .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
|
||||||
{ .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config },
|
{ .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config },
|
||||||
|
{ .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config },
|
||||||
{ .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config },
|
{ .compatible = "renesas,iic-r8a7790", .data = &fast_clock_dt_config },
|
||||||
{ .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config },
|
{ .compatible = "renesas,iic-r8a7791", .data = &fast_clock_dt_config },
|
||||||
{ .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config },
|
{ .compatible = "renesas,iic-r8a7792", .data = &fast_clock_dt_config },
|
||||||
@ -885,6 +922,9 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
|
|||||||
|
|
||||||
config = match->data;
|
config = match->data;
|
||||||
pd->clks_per_count = config->clks_per_count;
|
pd->clks_per_count = config->clks_per_count;
|
||||||
|
|
||||||
|
if (config->setup)
|
||||||
|
config->setup(pd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (pdata && pdata->bus_speed)
|
if (pdata && pdata->bus_speed)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user