diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-11-14 21:24:09 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2020-11-14 21:24:09 +0000 |
commit | 3acb5a2ea3dd56dba76639f38b234278b957c00e (patch) | |
tree | 93f9546ed4da9ce6dc289c192c0c315db37b4548 /sys/dev/fdt | |
parent | b50c864779379df2635546e8f45c3297a3301a0b (diff) |
Add support for the VF610 I2C controller to imxiic(4). It uses its
own clock divisor table and its registers are each a byte apart.
The status register is write 1 to clear instead of write 0 to clear,
and the enable bit is also inverted.
ok kettenis@
Diffstat (limited to 'sys/dev/fdt')
-rw-r--r-- | sys/dev/fdt/imxiic.c | 38 | ||||
-rw-r--r-- | sys/dev/fdt/imxiicvar.h | 20 |
2 files changed, 53 insertions, 5 deletions
diff --git a/sys/dev/fdt/imxiic.c b/sys/dev/fdt/imxiic.c index 24aac90c3d5..26399704b84 100644 --- a/sys/dev/fdt/imxiic.c +++ b/sys/dev/fdt/imxiic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imxiic.c,v 1.14 2020/11/14 21:21:26 patrick Exp $ */ +/* $OpenBSD: imxiic.c,v 1.15 2020/11/14 21:24:08 patrick Exp $ */ /* * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se> * @@ -48,12 +48,16 @@ #define I2C_I2SR_IAL (1 << 4) #define I2C_I2SR_IBB (1 << 5) +#define I2C_TYPE_IMX21 0 +#define I2C_TYPE_VF610 1 + struct imxiic_softc { struct device sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; bus_size_t sc_ios; int sc_reg_shift; + int sc_type; int sc_node; int sc_bitrate; uint32_t sc_clkrate; @@ -115,7 +119,8 @@ imxiic_match(struct device *parent, void *match, void *aux) { struct fdt_attach_args *faa = aux; - return OF_is_compatible(faa->fa_node, "fsl,imx21-i2c"); + return (OF_is_compatible(faa->fa_node, "fsl,imx21-i2c") || + OF_is_compatible(faa->fa_node, "fsl,vf610-i2c")); } void @@ -137,6 +142,14 @@ imxiic_attach(struct device *parent, struct device *self, void *aux) sc->sc_reg_shift = 2; sc->sc_clk_div = imxiic_imx21_clk_div; sc->sc_clk_ndiv = nitems(imxiic_imx21_clk_div); + sc->sc_type = I2C_TYPE_IMX21; + + if (OF_is_compatible(faa->fa_node, "fsl,vf610-i2c")) { + sc->sc_reg_shift = 0; + sc->sc_clk_div = imxiic_vf610_clk_div; + sc->sc_clk_ndiv = nitems(imxiic_vf610_clk_div); + sc->sc_type = I2C_TYPE_VF610; + } printf("\n"); @@ -173,8 +186,18 @@ imxiic_attach(struct device *parent, struct device *self, void *aux) void imxiic_enable(struct imxiic_softc *sc, int on) { - HWRITE1(sc, I2C_I2SR, 0); + /* + * VF610: write 1 to clear bits + * iMX21: write 0 to clear bits + */ + if (sc->sc_type == I2C_TYPE_VF610) + HWRITE1(sc, I2C_I2SR, I2C_I2SR_IAL | I2C_I2SR_IIF); + else + HWRITE1(sc, I2C_I2SR, 0); + /* VF610 inverts enable bit meaning */ + if (sc->sc_type == I2C_TYPE_VF610) + on = !on; if (on) HWRITE1(sc, I2C_I2CR, I2C_I2CR_IEN); else @@ -184,7 +207,14 @@ imxiic_enable(struct imxiic_softc *sc, int on) void imxiic_clear_iodone(struct imxiic_softc *sc) { - HCLR1(sc, I2C_I2SR, I2C_I2SR_IIF); + /* + * VF610: write bit to clear bit + * iMX21: clear bit, keep rest + */ + if (sc->sc_type == I2C_TYPE_VF610) + HWRITE1(sc, I2C_I2SR, I2C_I2SR_IIF); + else + HCLR1(sc, I2C_I2SR, I2C_I2SR_IIF); } void diff --git a/sys/dev/fdt/imxiicvar.h b/sys/dev/fdt/imxiicvar.h index 98f7fc1bf60..77786ea271a 100644 --- a/sys/dev/fdt/imxiicvar.h +++ b/sys/dev/fdt/imxiicvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: imxiicvar.h,v 1.3 2020/11/13 20:50:06 patrick Exp $ */ +/* $OpenBSD: imxiicvar.h,v 1.4 2020/11/14 21:24:08 patrick Exp $ */ /* * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se> * @@ -46,4 +46,22 @@ static struct imxiic_clk_pair imxiic_imx21_clk_div[50] = { { 3072, 0x1E }, { 3840, 0x1F } }; +static struct imxiic_clk_pair imxiic_vf610_clk_div[60] = { + { 20, 0x00 }, { 22, 0x01 }, { 24, 0x02 }, { 26, 0x03 }, + { 28, 0x04 }, { 30, 0x05 }, { 32, 0x09 }, { 34, 0x06 }, + { 36, 0x0A }, { 40, 0x07 }, { 44, 0x0C }, { 48, 0x0D }, + { 52, 0x43 }, { 56, 0x0E }, { 60, 0x45 }, { 64, 0x12 }, + { 68, 0x0F }, { 72, 0x13 }, { 80, 0x14 }, { 88, 0x15 }, + { 96, 0x19 }, { 104, 0x16 }, { 112, 0x1A }, { 128, 0x17 }, + { 136, 0x4F }, { 144, 0x1C }, { 160, 0x1D }, { 176, 0x55 }, + { 192, 0x1E }, { 208, 0x56 }, { 224, 0x22 }, { 228, 0x24 }, + { 240, 0x1F }, { 256, 0x23 }, { 288, 0x5C }, { 320, 0x25 }, + { 384, 0x26 }, { 448, 0x2A }, { 480, 0x27 }, { 512, 0x2B }, + { 576, 0x2C }, { 640, 0x2D }, { 768, 0x31 }, { 896, 0x32 }, + { 960, 0x2F }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 }, + { 1536, 0x36 }, { 1792, 0x3A }, { 1920, 0x37 }, { 2048, 0x3B }, + { 2304, 0x3C }, { 2560, 0x3D }, { 3072, 0x3E }, { 3584, 0x7A }, + { 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E }, +}; + #endif |