Module Name: src Committed By: marty Date: Thu Dec 24 21:30:05 UTC 2015
Modified Files: src/sys/arch/arm/samsung: exynos_i2c.c Log Message: XU4 I2C snapshot This is a complete, but untested, driver; except that it needs to be able to configure gpios and, afaict, we don't yet have an fdtbus_gpio_* function that will do that. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/samsung/exynos_i2c.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/samsung/exynos_i2c.c diff -u src/sys/arch/arm/samsung/exynos_i2c.c:1.7 src/sys/arch/arm/samsung/exynos_i2c.c:1.8 --- src/sys/arch/arm/samsung/exynos_i2c.c:1.7 Tue Dec 22 22:32:54 2015 +++ src/sys/arch/arm/samsung/exynos_i2c.c Thu Dec 24 21:30:05 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_i2c.c,v 1.7 2015/12/22 22:32:54 jmcneill Exp $ */ +/* $NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $ */ /* * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ #include "opt_arm_debug.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.7 2015/12/22 22:32:54 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -61,8 +61,8 @@ struct exynos_i2c_softc { void * sc_ih; u_int sc_port; - struct fdtbus_gpio_pin sc_sda; - struct fdtbus_gpio_pin sc_slc; + struct fdtbus_gpio_pin *sc_sda; + struct fdtbus_gpio_pin *sc_scl; bool sc_sda_is_output; struct i2c_controller sc_ic; kmutex_t sc_lock; @@ -92,6 +92,14 @@ static void exynos_i2c_attach(device_t, CFATTACH_DECL_NEW(exynos_i2c, sizeof(struct exynos_i2c_softc), exynos_i2c_match, exynos_i2c_attach, NULL, NULL); +#define I2C_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) +#define I2C_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) + +#define IICON 0 +#define IRQPEND (1<<4) + static int exynos_i2c_match(device_t self, cfdata_t cf, void *aux) { @@ -114,6 +122,12 @@ exynos_i2c_attach(device_t parent, devic bus_size_t size; int error; + char result[64]; + int i2c_handle; + int len; + int handle; + int func /*, pud, drv */; + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { aprint_error(": couldn't get registers\n"); return; @@ -132,7 +146,7 @@ exynos_i2c_attach(device_t parent, devic sc->sc_port = i2c_port++; mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); cv_init(&sc->sc_cv, device_xname(self)); - aprint_normal(" @ 0x%08x", (uint)addr); + aprint_normal(" @ 0x%08x\n", (uint)addr); if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { aprint_error_dev(self, "failed to decode interrupt\n"); @@ -148,6 +162,50 @@ exynos_i2c_attach(device_t parent, devic } aprint_normal_dev(self, "interrupting on %s\n", intrstr); + len = OF_getprop(phandle, "pinctrl-0", (char *)&handle, + sizeof(handle)); + if (len != sizeof(int)) { + aprint_error_dev(self, "couldn't get pinctrl-0.\n"); + return; + } + + i2c_handle = fdtbus_get_phandle_from_native(be32toh(handle)); + len = OF_getprop(i2c_handle, "samsung,pins", result, sizeof(result)); + if (len <= 0) { + aprint_error_dev(self, "couldn't get pins.\n"); + return; + } + + len = OF_getprop(i2c_handle, "samsung,pin-function", + &handle, sizeof(handle)); + if (len <= 0) { + aprint_error_dev(self, "couldn't get pin-function.\n"); + return; + } else + func = be32toh(handle); + + sc->sc_sda = fdtbus_gpio_acquire(phandle, &result[0], func); + sc->sc_scl = fdtbus_gpio_acquire(phandle, &result[7], func); + + /* MJF: Need fdtbus_gpio_configure */ +#if 0 + len = OF_getprop(i2c_handle, "samsung,pin-pud", &handle, + sizeof(&handle)); + if (len <= 0) { + aprint_error_dev(self, "couldn't get pin-pud.\n"); + return; + } else + pud = be32toh(handle); + + len = OF_getprop(i2c_handle, "samsung,pin-drv", &handle, + sizeof(&handle)); + if (len <= 0) { + aprint_error_dev(self, "couldn't get pin-drv.\n"); + return; + } else + drv = be32toh(handle); + +#endif if (!exynos_i2c_attach_i2cbus(sc, &sc->sc_ic)) return; @@ -168,8 +226,6 @@ exynos_i2c_attach_i2cbus(struct exynos_i i2c_cntr->ic_read_byte = exynos_i2c_read_byte; i2c_cntr->ic_write_byte = exynos_i2c_write_byte; - /*MJF: FIX ME needs gpio pins */ -// exynos_gpio_pinset_acquire(pinset); return 1; } @@ -182,28 +238,28 @@ static void exynos_i2c_bb_set_bits(void *cookie, uint32_t bits) { struct exynos_i2c_softc *i2c_sc = cookie; - int sda, slc; + int sda, scl; sda = (bits & EXYNOS_I2C_BB_SDA) ? true : false; - slc = (bits & EXYNOS_I2C_BB_SCL) ? true : false; + scl = (bits & EXYNOS_I2C_BB_SCL) ? true : false; if (i2c_sc->sc_sda_is_output) - fdtbus_gpio_write(&i2c_sc->sc_sda, sda); - fdtbus_gpio_write(&i2c_sc->sc_slc, slc); + fdtbus_gpio_write(i2c_sc->sc_sda, sda); + fdtbus_gpio_write(i2c_sc->sc_scl, scl); } static uint32_t exynos_i2c_bb_read_bits(void *cookie) { struct exynos_i2c_softc *i2c_sc = cookie; - int sda, slc; + int sda, scl; sda = 0; if (!i2c_sc->sc_sda_is_output) - sda = fdtbus_gpio_read(&i2c_sc->sc_sda); - slc = fdtbus_gpio_read(&i2c_sc->sc_slc); + sda = fdtbus_gpio_read(i2c_sc->sc_sda); + scl = fdtbus_gpio_read(i2c_sc->sc_scl); - return (sda ? EXYNOS_I2C_BB_SDA : 0) | (slc ? EXYNOS_I2C_BB_SCL : 0); + return (sda ? EXYNOS_I2C_BB_SDA : 0) | (scl ? EXYNOS_I2C_BB_SCL : 0); } static void @@ -218,7 +274,7 @@ exynos_i2c_bb_set_dir(void *cookie, uint flags = GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE; /* MJF: This is wrong but fdtbus has no ctrl operation */ - fdtbus_gpio_write(&i2c_sc->sc_sda, flags); + fdtbus_gpio_write(i2c_sc->sc_sda, flags); } static const struct i2c_bitbang_ops exynos_i2c_bbops = { @@ -238,10 +294,11 @@ exynos_i2c_intr(void *priv) { struct exynos_i2c_softc * const sc = priv; -// const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG); -// if (istatus == 0) -// return 0; -// I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus); + uint32_t istatus = I2C_READ(sc, IICON); + if (!(istatus & IRQPEND)) + return 0; + istatus &= ~IRQPEND; + I2C_WRITE(sc, IICON, istatus); mutex_enter(&sc->sc_lock); cv_broadcast(&sc->sc_cv);