Module Name: src
Committed By: marty
Date: Wed Dec 30 04:30:27 UTC 2015
Modified Files:
src/sys/arch/arm/samsung: exynos_combiner.c exynos_gpio.c exynos_i2c.c
exynos_pinctrl.c exynos_var.h
Log Message:
XU4 i2c, gpio & pinctrl changes
modify exynos_gpio.c to support the new pinctrl model.
set up the new pinctrl model in exynos_pinctrl.c
Flesh out exynos_i2c.c and set it up to use the new pinctrl model. NOTE:
exynos_i2c.c is still incomplete. I need to figure out what to set the
prescaler and scaler to.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/samsung/exynos_combiner.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/samsung/exynos_gpio.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/samsung/exynos_i2c.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/samsung/exynos_pinctrl.c
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/samsung/exynos_var.h
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_combiner.c
diff -u src/sys/arch/arm/samsung/exynos_combiner.c:1.3 src/sys/arch/arm/samsung/exynos_combiner.c:1.4
--- src/sys/arch/arm/samsung/exynos_combiner.c:1.3 Thu Dec 24 21:20:17 2015
+++ src/sys/arch/arm/samsung/exynos_combiner.c Wed Dec 30 04:30:27 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_combiner.c,v 1.3 2015/12/24 21:20:17 marty Exp $ */
+/* $NetBSD: exynos_combiner.c,v 1.4 2015/12/30 04:30:27 marty Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.3 2015/12/24 21:20:17 marty Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.4 2015/12/30 04:30:27 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -197,7 +197,7 @@ exynos_combiner_intrstr(device_t dev, in
kmem_free(interrupts, len);
- snprintf(buf, buflen, "LIC irq %d", irq);
+ snprintf(buf, buflen, "combiner irq %d", irq);
return true;
}
Index: src/sys/arch/arm/samsung/exynos_gpio.c
diff -u src/sys/arch/arm/samsung/exynos_gpio.c:1.21 src/sys/arch/arm/samsung/exynos_gpio.c:1.22
--- src/sys/arch/arm/samsung/exynos_gpio.c:1.21 Sun Dec 27 12:42:14 2015
+++ src/sys/arch/arm/samsung/exynos_gpio.c Wed Dec 30 04:30:27 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_gpio.c,v 1.21 2015/12/27 12:42:14 jmcneill Exp $ */
+/* $NetBSD: exynos_gpio.c,v 1.22 2015/12/30 04:30:27 marty Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.21 2015/12/27 12:42:14 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.22 2015/12/30 04:30:27 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -53,16 +53,6 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.
#include <dev/fdt/fdtvar.h>
-struct exynos_gpio_pin_cfg {
- uint32_t cfg;
- uint32_t pud;
- uint32_t drv;
- uint32_t conpwd;
- uint32_t pudpwd;
-};
-
-struct exynos_gpio_softc;
-
struct exynos_gpio_bank {
const char bank_name[6];
device_t bank_dev;
@@ -80,12 +70,6 @@ struct exynos_gpio_bank {
struct exynos_gpio_bank * bank_next;
};
-struct exynos_gpio_softc {
- device_t sc_dev;
- bus_space_tag_t sc_bst;
- bus_space_handle_t sc_bsh;
-};
-
struct exynos_gpio_pin {
struct exynos_gpio_softc *pin_sc;
int pin_no;
@@ -144,7 +128,7 @@ static struct exynos_gpio_bank exynos5_b
GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2),
GPIO_GRP(5, MUXD, 0x0100, gph0, 4),
- GPIO_GRP(5, MUXE, 0x0000, gpz0, 7),
+ GPIO_GRP(5, MUXE, 0x0000, gpz, 7),
};
@@ -159,7 +143,6 @@ static void exynos_gpio_fdt_release(devi
static int exynos_gpio_fdt_read(device_t, void *, bool);
static void exynos_gpio_fdt_write(device_t, void *, int, bool);
-static struct exynos_gpio_bank *exynos_gpio_bank_lookup(const char *);
static int exynos_gpio_cfprint(void *, const char *);
struct fdtbus_gpio_controller_func exynos_gpio_funcs = {
@@ -279,7 +262,27 @@ exynos_gpio_pin_ctl(void *cookie, int pi
exynos_gpio_update_cfg_regs(bank, &ncfg);
}
-void
+void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *bank,
+ struct exynos_gpio_pin_cfg *cfg)
+{
+ cfg->cfg = GPIO_READ(bank, EXYNOS_GPIO_CON);
+ cfg->pud = GPIO_READ(bank, EXYNOS_GPIO_PUD);
+ cfg->drv = GPIO_READ(bank, EXYNOS_GPIO_DRV);
+ cfg->conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD);
+ cfg->pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD);
+}
+
+void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *bank,
+ const struct exynos_gpio_pin_cfg *cfg)
+{
+ GPIO_WRITE(bank, EXYNOS_GPIO_CON, cfg->cfg);
+ GPIO_WRITE(bank, EXYNOS_GPIO_PUD, cfg->pud);
+ GPIO_WRITE(bank, EXYNOS_GPIO_DRV, cfg->drv);
+ GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, cfg->conpwd);
+ GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, cfg->pudpwd);
+}
+
+struct exynos_gpio_softc *
exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent,
const struct fdt_attach_args *faa, int node)
{
@@ -294,13 +297,14 @@ exynos_gpio_bank_config(struct exynos_pi
if (bank == NULL) {
aprint_error_dev(parent->sc_dev, "no bank found for %s\n",
result);
- return;
+ return NULL;
}
sc->sc_dev = parent->sc_dev;
sc->sc_bst = &armv7_generic_bs_tag;
sc->sc_bsh = parent->sc_bsh;
-
+ sc->sc_bank = bank;
+
gc_tag = &bank->bank_gc;
gc_tag->gp_cookie = bank;
gc_tag->gp_pin_read = exynos_gpio_pin_read;
@@ -327,14 +331,23 @@ exynos_gpio_bank_config(struct exynos_pi
fdtbus_register_gpio_controller(bank->bank_dev, node,
&exynos_gpio_funcs);
+ return sc;
}
-static struct exynos_gpio_bank *
+/*
+ * This function is a bit funky. Given a string that may look like
+ * 'gpAN' or 'gpAN-P' it is meant to find a match to the part before
+ * the '-', or the four character string if the dash is not present.
+ */
+struct exynos_gpio_bank *
exynos_gpio_bank_lookup(const char *name)
{
+ struct exynos_gpio_bank *bank;
+
for (u_int n = 0; n < __arraycount(exynos5_banks); n++) {
- struct exynos_gpio_bank *bank = &exynos_gpio_banks[n];
- if (strncmp(bank->bank_name, name, strlen(name)) == 0) {
+ bank = &exynos_gpio_banks[n];
+ if (!strncmp(bank->bank_name, name,
+ strlen(bank->bank_name))) {
return bank;
}
}
Index: src/sys/arch/arm/samsung/exynos_i2c.c
diff -u src/sys/arch/arm/samsung/exynos_i2c.c:1.8 src/sys/arch/arm/samsung/exynos_i2c.c:1.9
--- src/sys/arch/arm/samsung/exynos_i2c.c:1.8 Thu Dec 24 21:30:05 2015
+++ src/sys/arch/arm/samsung/exynos_i2c.c Wed Dec 30 04:30:27 2015
@@ -1,12 +1,9 @@
-/* $NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $ */
+/* $NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $ */
/*
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2015 Jared D. McNeill <[email protected]>
* All rights reserved.
*
- * This code is derived from software contributed to The NetBSD Foundation
- * by Reinoud Zandijk.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -34,16 +31,18 @@
#include "opt_arm_debug.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
+#include <sys/kernel.h>
#include <sys/kmem.h>
#include <arm/samsung/exynos_reg.h>
+#include <arm/samsung/exynos_var.h>
#include <arm/samsung/exynos_intr.h>
#include <sys/gpio.h>
@@ -59,19 +58,18 @@ struct exynos_i2c_softc {
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
void * sc_ih;
- u_int sc_port;
+ struct clk * sc_clk;
- struct fdtbus_gpio_pin *sc_sda;
- struct fdtbus_gpio_pin *sc_scl;
+ struct fdtbus_pinctrl_pin *sc_sda;
+ struct fdtbus_pinctrl_pin *sc_scl;
bool sc_sda_is_output;
+
struct i2c_controller sc_ic;
kmutex_t sc_lock;
kcondvar_t sc_cv;
device_t sc_i2cdev;
};
-static u_int i2c_port;
-
static int exynos_i2c_intr(void *);
static int exynos_i2c_acquire_bus(void *, int);
@@ -83,22 +81,46 @@ static int exynos_i2c_initiate_xfer(void
static int exynos_i2c_read_byte(void *, uint8_t *, int);
static int exynos_i2c_write_byte(void *, uint8_t , int);
-static bool exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *,
- struct i2c_controller *);
+static int exynos_i2c_wait(struct exynos_i2c_softc *, int);
+
static int exynos_i2c_match(device_t, cfdata_t, void *);
static void exynos_i2c_attach(device_t, device_t, void *);
+static i2c_tag_t exynos_i2c_get_tag(device_t);
+
+struct fdtbus_i2c_controller_func exynos_i2c_funcs = {
+ .get_tag = exynos_i2c_get_tag
+};
+
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))
+ bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
#define I2C_READ(sc, reg) \
- bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+ bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (reg))
-#define IICON 0
-#define IRQPEND (1<<4)
+#define IICCON 0x00
+#define IICSTAT 0x04
+#define IICADD 0x08
+#define IICDS 0x0C
+
+#define ACKENABLE (1<<7)
+#define TXPRESCALE (1<<6)
+#define INTENABLE (1<<5)
+#define IRQPEND (1<<4)
+#define PRESCALE (0x0f)
+
+#define MODESELECT (3<<6)
+#define BUSYSTART (1<<5)
+#define BUSENABLE (1<<4)
+#define ARBITRATION (1<<3)
+#define SLAVESTATUS (1<<2)
+#define ZEROSTATUS (1<<1)
+#define LASTBIT (1<<0)
+
+#define READBIT (1<<7)
static int
exynos_i2c_match(device_t self, cfdata_t cf, void *aux)
@@ -126,7 +148,7 @@ exynos_i2c_attach(device_t parent, devic
int i2c_handle;
int len;
int handle;
- int func /*, pud, drv */;
+ int func, pud, drv;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get registers\n");
@@ -143,7 +165,6 @@ exynos_i2c_attach(device_t parent, devic
return;
}
- 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\n", (uint)addr);
@@ -184,11 +205,18 @@ exynos_i2c_attach(device_t parent, devic
} else
func = be32toh(handle);
- sc->sc_sda = fdtbus_gpio_acquire(phandle, &result[0], func);
- sc->sc_scl = fdtbus_gpio_acquire(phandle, &result[7], func);
+ sc->sc_sda = fdtbus_pinctrl_acquire(phandle, &result[0]);
+ if (sc->sc_sda == NULL) {
+ printf("could not acquire sda gpio %s\n", &result[0]);
+ return;
+ }
+
+ sc->sc_scl = fdtbus_pinctrl_acquire(phandle, &result[7]);
+ if (sc->sc_scl == NULL) {
+ printf("could not acquire scl gpio %s\n", &result[7]);
+ return;
+ }
- /* MJF: Need fdtbus_gpio_configure */
-#if 0
len = OF_getprop(i2c_handle, "samsung,pin-pud", &handle,
sizeof(&handle));
if (len <= 0) {
@@ -205,100 +233,47 @@ exynos_i2c_attach(device_t parent, devic
} else
drv = be32toh(handle);
-#endif
- if (!exynos_i2c_attach_i2cbus(sc, &sc->sc_ic))
- return;
+ struct exynos_gpio_pin_cfg cfg;
+ cfg.cfg = func;
+ cfg.pud = pud;
+ cfg.drv = drv;
+ cfg.conpwd = 0;
+ cfg.pudpwd = 0;
+
+ fdtbus_pinctrl_set_cfg(sc->sc_scl, &cfg);
+ fdtbus_pinctrl_set_cfg(sc->sc_sda, &cfg);
+
+ sc->sc_ic.ic_cookie = sc;
+ sc->sc_ic.ic_acquire_bus = exynos_i2c_acquire_bus;
+ sc->sc_ic.ic_release_bus = exynos_i2c_release_bus;
+ sc->sc_ic.ic_send_start = exynos_i2c_send_start;
+ sc->sc_ic.ic_send_stop = exynos_i2c_send_stop;
+ sc->sc_ic.ic_initiate_xfer = exynos_i2c_initiate_xfer;
+ sc->sc_ic.ic_read_byte = exynos_i2c_read_byte;
+ sc->sc_ic.ic_write_byte = exynos_i2c_write_byte;
sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
}
-static bool
-exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *i2c_sc,
- struct i2c_controller *i2c_cntr)
-{
- i2c_cntr->ic_cookie = i2c_sc;
- i2c_cntr->ic_acquire_bus = exynos_i2c_acquire_bus;
- i2c_cntr->ic_release_bus = exynos_i2c_release_bus;
- i2c_cntr->ic_send_start = exynos_i2c_send_start;
- i2c_cntr->ic_send_stop = exynos_i2c_send_stop;
- i2c_cntr->ic_initiate_xfer = exynos_i2c_initiate_xfer;
- i2c_cntr->ic_read_byte = exynos_i2c_read_byte;
- i2c_cntr->ic_write_byte = exynos_i2c_write_byte;
-
- return 1;
-}
-
-#define EXYNOS_I2C_BB_SDA __BIT(1)
-#define EXYNOS_I2C_BB_SCL __BIT(2)
-#define EXYNOS_I2C_BB_SDA_OUT __BIT(3)
-#define EXYNOS_I2C_BB_SDA_IN 0
-
-static void
-exynos_i2c_bb_set_bits(void *cookie, uint32_t bits)
-{
- struct exynos_i2c_softc *i2c_sc = cookie;
- int sda, scl;
-
- sda = (bits & EXYNOS_I2C_BB_SDA) ? 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_scl, scl);
-}
-
-static uint32_t
-exynos_i2c_bb_read_bits(void *cookie)
+static i2c_tag_t
+exynos_i2c_get_tag(device_t dev)
{
- struct exynos_i2c_softc *i2c_sc = cookie;
- int sda, scl;
-
- sda = 0;
- if (!i2c_sc->sc_sda_is_output)
- sda = fdtbus_gpio_read(i2c_sc->sc_sda);
- scl = fdtbus_gpio_read(i2c_sc->sc_scl);
+ struct exynos_i2c_softc * const sc = device_private(dev);
- return (sda ? EXYNOS_I2C_BB_SDA : 0) | (scl ? EXYNOS_I2C_BB_SCL : 0);
+ return &sc->sc_ic;
}
-static void
-exynos_i2c_bb_set_dir(void *cookie, uint32_t bits)
-{
- struct exynos_i2c_softc *i2c_sc = cookie;
- int flags;
-
- flags = GPIO_PIN_INPUT | GPIO_PIN_TRISTATE;
- i2c_sc->sc_sda_is_output = ((bits & EXYNOS_I2C_BB_SDA_OUT) != 0);
- if (i2c_sc->sc_sda_is_output)
- 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);
-}
-
-static const struct i2c_bitbang_ops exynos_i2c_bbops = {
- exynos_i2c_bb_set_bits,
- exynos_i2c_bb_set_dir,
- exynos_i2c_bb_read_bits,
- {
- EXYNOS_I2C_BB_SDA,
- EXYNOS_I2C_BB_SCL,
- EXYNOS_I2C_BB_SDA_OUT,
- EXYNOS_I2C_BB_SDA_IN,
- }
-};
-
static int
exynos_i2c_intr(void *priv)
{
struct exynos_i2c_softc * const sc = priv;
- uint32_t istatus = I2C_READ(sc, IICON);
+ uint8_t istatus = I2C_READ(sc, IICCON);
if (!(istatus & IRQPEND))
return 0;
istatus &= ~IRQPEND;
- I2C_WRITE(sc, IICON, istatus);
+ I2C_WRITE(sc, IICCON, istatus);
mutex_enter(&sc->sc_lock);
cv_broadcast(&sc->sc_cv);
@@ -312,9 +287,6 @@ exynos_i2c_acquire_bus(void *cookie, int
{
struct exynos_i2c_softc *i2c_sc = cookie;
- /* XXX what to do in polling case? could another cpu help */
- if (flags & I2C_F_POLL)
- return 0;
mutex_enter(&i2c_sc->sc_lock);
return 0;
}
@@ -324,41 +296,94 @@ exynos_i2c_release_bus(void *cookie, int
{
struct exynos_i2c_softc *i2c_sc = cookie;
- /* XXX what to do in polling case? could another cpu help */
- if (flags & I2C_F_POLL)
- return;
mutex_exit(&i2c_sc->sc_lock);
}
static int
+exynos_i2c_wait(struct exynos_i2c_softc *sc, int flags)
+{
+ int error, retry;
+ uint8_t stat = 0;
+
+ retry = (flags & I2C_F_POLL) ? 100000 : 100;
+
+ while (--retry > 0) {
+ if ((flags & I2C_F_POLL) == 0) {
+ error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
+ max(mstohz(10), 1));
+ if (error) {
+ return error;
+ }
+ }
+ stat = I2C_READ(sc, IICSTAT);
+ if (!(stat & BUSYSTART)) {
+ break;
+ }
+ if (flags & I2C_F_POLL) {
+ delay(10);
+ }
+ }
+ if (retry == 0) {
+ stat = I2C_READ(sc, IICSTAT);
+ device_printf(sc->sc_dev, "timed out, status = %#x\n", stat);
+ return ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+
+static int
exynos_i2c_send_start(void *cookie, int flags)
{
- return i2c_bitbang_send_start(cookie, flags, &exynos_i2c_bbops);
+ struct exynos_i2c_softc *sc = cookie;
+ I2C_WRITE(sc, IICSTAT, 0xF0);
+ return 0;
}
static int
exynos_i2c_send_stop(void *cookie, int flags)
{
- return i2c_bitbang_send_stop(cookie, flags, &exynos_i2c_bbops);
+ struct exynos_i2c_softc *sc = cookie;
+ I2C_WRITE(sc, IICSTAT, 0xD0);
+ return 0;
}
static int
exynos_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
{
- return i2c_bitbang_initiate_xfer(cookie, addr, flags,
- &exynos_i2c_bbops);
+ struct exynos_i2c_softc *sc = cookie;
+ uint8_t byte = addr & 0x7f;
+ if (flags & I2C_F_READ)
+ byte |= READBIT;
+ else
+ byte &= ~READBIT;
+ I2C_WRITE(sc, IICADD, addr);
+ exynos_i2c_send_start(cookie, flags);
+ exynos_i2c_write_byte(cookie, byte, flags);
+ return exynos_i2c_wait(cookie, flags);
}
static int
exynos_i2c_read_byte(void *cookie, uint8_t *bytep, int flags)
{
- return i2c_bitbang_read_byte(cookie, bytep, flags,
- &exynos_i2c_bbops);
+ struct exynos_i2c_softc *sc = cookie;
+ int error = exynos_i2c_wait(sc, flags);
+ if (error)
+ return error;
+ *bytep = I2C_READ(sc, IICDS) & 0xff;
+ if (flags & I2C_F_STOP)
+ exynos_i2c_send_stop(cookie, flags);
+ return 0;
}
static int
exynos_i2c_write_byte(void *cookie, uint8_t byte, int flags)
{
- return i2c_bitbang_write_byte(cookie, byte, flags,
- &exynos_i2c_bbops);
+ struct exynos_i2c_softc *sc = cookie;
+ int error = exynos_i2c_wait(sc, flags);
+ if (error)
+ return error;
+ I2C_WRITE(sc, IICDS, byte);
+ return 0;
}
Index: src/sys/arch/arm/samsung/exynos_pinctrl.c
diff -u src/sys/arch/arm/samsung/exynos_pinctrl.c:1.7 src/sys/arch/arm/samsung/exynos_pinctrl.c:1.8
--- src/sys/arch/arm/samsung/exynos_pinctrl.c:1.7 Sun Dec 27 12:21:37 2015
+++ src/sys/arch/arm/samsung/exynos_pinctrl.c Wed Dec 30 04:30:27 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_pinctrl.c,v 1.7 2015/12/27 12:21:37 jmcneill Exp $ */
+/* $NetBSD: exynos_pinctrl.c,v 1.8 2015/12/30 04:30:27 marty Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
#include "gpio.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.7 2015/12/27 12:21:37 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.8 2015/12/30 04:30:27 marty Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -56,6 +56,18 @@ __KERNEL_RCSID(1, "$NetBSD: exynos_pinct
static int exynos_pinctrl_match(device_t, cfdata_t, void *);
static void exynos_pinctrl_attach(device_t, device_t, void *);
+static void *exynos_pinctrl_acquire(device_t, const char *);
+static void exynos_pinctrl_release(device_t, void *);
+static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *, void *);
+static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *, void *);
+
+static struct fdtbus_pinctrl_controller_func exynos_pinctrl_controller_func = {
+ .acquire = exynos_pinctrl_acquire,
+ .release = exynos_pinctrl_release,
+ .get = exynos_pinctrl_get_cfg,
+ .set = exynos_pinctrl_set_cfg,
+};
+
CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc),
exynos_pinctrl_match, exynos_pinctrl_attach, NULL, NULL);
@@ -74,6 +86,7 @@ exynos_pinctrl_attach(device_t parent, d
struct exynos_pinctrl_softc * const sc
= kmem_zalloc(sizeof(*sc), KM_SLEEP);
struct fdt_attach_args * const faa = aux;
+ struct exynos_gpio_softc *child_sc;
bus_addr_t addr;
bus_size_t size;
int error;
@@ -101,6 +114,41 @@ exynos_pinctrl_attach(device_t parent, d
child = OF_peer(child)) {
if (of_getprop_bool(child, "gpio-controller") == false)
continue;
- exynos_gpio_bank_config(sc, faa, child);
+ child_sc = exynos_gpio_bank_config(sc, faa, child);
+ fdtbus_register_pinctrl_controller(child_sc->sc_dev, child,
+ &exynos_pinctrl_controller_func);
}
}
+
+
+static void *exynos_pinctrl_acquire(device_t self, const char *name)
+{
+ return exynos_gpio_bank_lookup(name);
+}
+
+static void exynos_pinctrl_release(device_t self, void *cookie)
+{
+}
+
+static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *pin,
+ void *cookie)
+{
+ struct exynos_gpio_bank *bank = pin->pp_priv;
+ struct exynos_gpio_pin_cfg *cfg = cookie;
+ struct exynos_gpio_pin_cfg **cfgp = &cfg;
+ struct exynos_gpio_pin_cfg *newcfg = kmem_zalloc(sizeof(*newcfg),
+ KM_SLEEP);
+ if (newcfg == NULL)
+ return;
+ exynos_gpio_pin_ctl_read(bank, newcfg);
+ *cfgp = newcfg;
+ return;
+}
+
+static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *pin,
+ void *cookie)
+{
+ struct exynos_gpio_bank *bank = pin->pp_priv;
+ struct exynos_gpio_pin_cfg *cfg = cookie;
+ exynos_gpio_pin_ctl_write(bank, cfg);
+}
Index: src/sys/arch/arm/samsung/exynos_var.h
diff -u src/sys/arch/arm/samsung/exynos_var.h:1.22 src/sys/arch/arm/samsung/exynos_var.h:1.23
--- src/sys/arch/arm/samsung/exynos_var.h:1.22 Thu Dec 24 01:10:51 2015
+++ src/sys/arch/arm/samsung/exynos_var.h Wed Dec 30 04:30:27 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: exynos_var.h,v 1.22 2015/12/24 01:10:51 marty Exp $ */
+/* $NetBSD: exynos_var.h,v 1.23 2015/12/30 04:30:27 marty Exp $ */
/*-
* Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -104,6 +104,21 @@ struct exynos_gpio_pindata {
int pd_pin;
};
+struct exynos_gpio_pin_cfg {
+ uint32_t cfg;
+ uint32_t pud;
+ uint32_t drv;
+ uint32_t conpwd;
+ uint32_t pudpwd;
+};
+
+struct exynos_gpio_softc {
+ device_t sc_dev;
+ bus_space_tag_t sc_bst;
+ bus_space_handle_t sc_bsh;
+ struct exynos_gpio_bank *sc_bank;
+ int sc_phandle;
+};
#define EXYNOS_MAX_IIC_BUSSES 9
struct i2c_controller;
@@ -127,8 +142,10 @@ extern void exynos_bootstrap(vaddr_t, va
extern void exynos_dma_bootstrap(psize_t memsize);
struct exynos_pinctrl_softc;
+struct exynos_gpio_softc;
struct fdt_attach_args;
-extern void exynos_gpio_bank_config(struct exynos_pinctrl_softc *,
+
+extern struct exynos_gpio_softc * exynos_gpio_bank_config(struct exynos_pinctrl_softc *,
const struct fdt_attach_args *, int);
extern void exynos_wdt_reset(void);
@@ -146,13 +163,17 @@ extern void exynos_usb_soc_powerup(void)
extern void exyo_device_register(device_t self, void *aux);
extern void exyo_device_register_post_config(device_t self, void *aux);
+extern struct exynos_gpio_bank *exynos_gpio_bank_lookup(const char *name);
extern bool exynos_gpio_pinset_available(const struct exynos_gpio_pinset *);
extern void exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *);
extern void exynos_gpio_pinset_release(const struct exynos_gpio_pinset *);
extern void exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *,
int pinnr, struct exynos_gpio_pindata *);
extern bool exynos_gpio_pin_reserve(const char *, struct exynos_gpio_pindata *);
-
+extern void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *,
+ struct exynos_gpio_pin_cfg *);
+extern void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *,
+ const struct exynos_gpio_pin_cfg *);
static inline void
exynos_gpio_pindata_write(const struct exynos_gpio_pindata *pd, int value)
{