Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 283616
b: refs/heads/master
c: 6831f3a
h: refs/heads/master
v: v3
  • Loading branch information
Kuninori Morimoto authored and Paul Mundt committed Nov 11, 2011
1 parent 114e4c4 commit da477a5
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5ade0672f2a2142de216ca705692c9d3238ee650
refs/heads/master: 6831f3a9184a1c5400e4fa2f2d3172b6dfb2c805
106 changes: 106 additions & 0 deletions trunk/arch/arm/mach-shmobile/setup-r8a7740.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/serial_sci.h>
#include <linux/sh_timer.h>
Expand Down Expand Up @@ -233,10 +235,114 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
&cmt10_device,
};

/* I2C */
static struct resource i2c0_resources[] = {
[0] = {
.name = "IIC0",
.start = 0xfff20000,
.end = 0xfff20425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(201),
.end = gic_spi(204),
.flags = IORESOURCE_IRQ,
},
};

static struct resource i2c1_resources[] = {
[0] = {
.name = "IIC1",
.start = 0xe6c20000,
.end = 0xe6c20425 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = gic_spi(70),
.end = gic_spi(73),
.flags = IORESOURCE_IRQ,
},
};

static struct platform_device i2c0_device = {
.name = "i2c-sh_mobile",
.id = 0,
.resource = i2c0_resources,
.num_resources = ARRAY_SIZE(i2c0_resources),
};

static struct platform_device i2c1_device = {
.name = "i2c-sh_mobile",
.id = 1,
.resource = i2c1_resources,
.num_resources = ARRAY_SIZE(i2c1_resources),
};

static struct platform_device *r8a7740_late_devices[] __initdata = {
&i2c0_device,
&i2c1_device,
};

#define ICCR 0x0004
#define ICSTART 0x0070

#define i2c_read(reg, offset) ioread8(reg + offset)
#define i2c_write(reg, offset, data) iowrite8(data, reg + offset)

/*
* r8a7740 chip has lasting errata on I2C I/O pad reset.
* this is work-around for it.
*/
static void r8a7740_i2c_workaround(struct platform_device *pdev)
{
struct resource *res;
void __iomem *reg;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!res)) {
pr_err("r8a7740 i2c workaround fail (cannot find resource)\n");
return;
}

reg = ioremap(res->start, resource_size(res));
if (unlikely(!reg)) {
pr_err("r8a7740 i2c workaround fail (cannot map IO)\n");
return;
}

i2c_write(reg, ICCR, i2c_read(reg, ICCR) | 0x80);
i2c_read(reg, ICCR); /* dummy read */

i2c_write(reg, ICSTART, i2c_read(reg, ICSTART) | 0x10);
i2c_read(reg, ICSTART); /* dummy read */

mdelay(100);

i2c_write(reg, ICCR, 0x01);
i2c_read(reg, ICCR);
i2c_write(reg, ICSTART, 0x00);
i2c_read(reg, ICSTART);

i2c_write(reg, ICCR, 0x10);
mdelay(100);
i2c_write(reg, ICCR, 0x00);
mdelay(100);
i2c_write(reg, ICCR, 0x10);
mdelay(100);

iounmap(reg);
}

void __init r8a7740_add_standard_devices(void)
{
/* I2C work-around */
r8a7740_i2c_workaround(&i2c0_device);
r8a7740_i2c_workaround(&i2c1_device);

platform_add_devices(r8a7740_early_devices,
ARRAY_SIZE(r8a7740_early_devices));
platform_add_devices(r8a7740_late_devices,
ARRAY_SIZE(r8a7740_late_devices));
}

void __init r8a7740_add_early_devices(void)
Expand Down

0 comments on commit da477a5

Please sign in to comment.