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);

Reply via email to