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.diff -r1.3 -r1.4 src/sys/arch/arm/samsung/exynos_combiner.c
(marty)
--- src/sys/arch/arm/samsung/exynos_combiner.c 2015/12/24 21:20:17 1.3
+++ src/sys/arch/arm/samsung/exynos_combiner.c 2015/12/30 04:30:27 1.4
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: exynos_combiner.c,v 1.3 2015/12/24 21:20:17 marty Exp $ */ | 1 | /* $NetBSD: exynos_combiner.c,v 1.4 2015/12/30 04:30:27 marty Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2015 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2015 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Marty Fouts | 8 | * by Marty Fouts | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -24,27 +24,27 @@ | @@ -24,27 +24,27 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include "opt_exynos.h" | 32 | #include "opt_exynos.h" | |
33 | #include "opt_arm_debug.h" | 33 | #include "opt_arm_debug.h" | |
34 | #include "gpio.h" | 34 | #include "gpio.h" | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.3 2015/12/24 21:20:17 marty Exp $"); | 37 | __KERNEL_RCSID(1, "$NetBSD: exynos_combiner.c,v 1.4 2015/12/30 04:30:27 marty Exp $"); | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/bus.h> | 40 | #include <sys/bus.h> | |
41 | #include <sys/device.h> | 41 | #include <sys/device.h> | |
42 | #include <sys/intr.h> | 42 | #include <sys/intr.h> | |
43 | #include <sys/systm.h> | 43 | #include <sys/systm.h> | |
44 | #include <sys/kmem.h> | 44 | #include <sys/kmem.h> | |
45 | 45 | |||
46 | #include <arm/cortex/gic_intr.h> | 46 | #include <arm/cortex/gic_intr.h> | |
47 | 47 | |||
48 | #include <arm/samsung/exynos_reg.h> | 48 | #include <arm/samsung/exynos_reg.h> | |
49 | #include <arm/samsung/exynos_intr.h> | 49 | #include <arm/samsung/exynos_intr.h> | |
50 | 50 | |||
@@ -187,17 +187,17 @@ exynos_combiner_intrstr(device_t dev, in | @@ -187,17 +187,17 @@ exynos_combiner_intrstr(device_t dev, in | |||
187 | return false; | 187 | return false; | |
188 | } | 188 | } | |
189 | 189 | |||
190 | /* 1st cell is the interrupt type; */ | 190 | /* 1st cell is the interrupt type; */ | |
191 | /* 2nd cell is the interrupt number */ | 191 | /* 2nd cell is the interrupt number */ | |
192 | /* 3rd cell is flags */ | 192 | /* 3rd cell is flags */ | |
193 | 193 | |||
194 | const u_int type = be32toh(interrupts[index * clen + 0]); | 194 | const u_int type = be32toh(interrupts[index * clen + 0]); | |
195 | const u_int intr = be32toh(interrupts[index * clen + 1]); | 195 | const u_int intr = be32toh(interrupts[index * clen + 1]); | |
196 | const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr); | 196 | const u_int irq = type == 0 ? IRQ_SPI(intr) : IRQ_PPI(intr); | |
197 | 197 | |||
198 | kmem_free(interrupts, len); | 198 | kmem_free(interrupts, len); | |
199 | 199 | |||
200 | snprintf(buf, buflen, "LIC irq %d", irq); | 200 | snprintf(buf, buflen, "combiner irq %d", irq); | |
201 | 201 | |||
202 | return true; | 202 | return true; | |
203 | } | 203 | } |
--- src/sys/arch/arm/samsung/exynos_gpio.c 2015/12/27 12:42:14 1.21
+++ src/sys/arch/arm/samsung/exynos_gpio.c 2015/12/30 04:30:27 1.22
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: exynos_gpio.c,v 1.21 2015/12/27 12:42:14 jmcneill Exp $ */ | 1 | /* $NetBSD: exynos_gpio.c,v 1.22 2015/12/30 04:30:27 marty Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Reinoud Zandijk | 8 | * by Reinoud Zandijk | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -24,78 +24,62 @@ | @@ -24,78 +24,62 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include "opt_exynos.h" | 32 | #include "opt_exynos.h" | |
33 | #include "opt_arm_debug.h" | 33 | #include "opt_arm_debug.h" | |
34 | #include "gpio.h" | 34 | #include "gpio.h" | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.21 2015/12/27 12:42:14 jmcneill Exp $"); | 37 | __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.22 2015/12/30 04:30:27 marty Exp $"); | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/bus.h> | 40 | #include <sys/bus.h> | |
41 | #include <sys/device.h> | 41 | #include <sys/device.h> | |
42 | #include <sys/intr.h> | 42 | #include <sys/intr.h> | |
43 | #include <sys/systm.h> | 43 | #include <sys/systm.h> | |
44 | #include <sys/kmem.h> | 44 | #include <sys/kmem.h> | |
45 | #include <sys/gpio.h> | 45 | #include <sys/gpio.h> | |
46 | 46 | |||
47 | #include <dev/gpio/gpiovar.h> | 47 | #include <dev/gpio/gpiovar.h> | |
48 | 48 | |||
49 | #include <arm/samsung/exynos_reg.h> | 49 | #include <arm/samsung/exynos_reg.h> | |
50 | #include <arm/samsung/exynos_var.h> | 50 | #include <arm/samsung/exynos_var.h> | |
51 | #include <arm/samsung/exynos_intr.h> | 51 | #include <arm/samsung/exynos_intr.h> | |
52 | #include <arm/samsung/exynos_pinctrl.h> | 52 | #include <arm/samsung/exynos_pinctrl.h> | |
53 | 53 | |||
54 | #include <dev/fdt/fdtvar.h> | 54 | #include <dev/fdt/fdtvar.h> | |
55 | 55 | |||
56 | struct exynos_gpio_pin_cfg { | |||
57 | uint32_t cfg; | |||
58 | uint32_t pud; | |||
59 | uint32_t drv; | |||
60 | uint32_t conpwd; | |||
61 | uint32_t pudpwd; | |||
62 | }; | |||
63 | ||||
64 | struct exynos_gpio_softc; | |||
65 | ||||
66 | struct exynos_gpio_bank { | 56 | struct exynos_gpio_bank { | |
67 | const char bank_name[6]; | 57 | const char bank_name[6]; | |
68 | device_t bank_dev; | 58 | device_t bank_dev; | |
69 | struct gpio_chipset_tag bank_gc; | 59 | struct gpio_chipset_tag bank_gc; | |
70 | struct exynos_gpio_softc *bank_sc; | 60 | struct exynos_gpio_softc *bank_sc; | |
71 | gpio_pin_t bank_pins[8]; | 61 | gpio_pin_t bank_pins[8]; | |
72 | 62 | |||
73 | const bus_addr_t bank_core_offset; | 63 | const bus_addr_t bank_core_offset; | |
74 | const uint8_t bank_bits; | 64 | const uint8_t bank_bits; | |
75 | 65 | |||
76 | uint8_t bank_pin_mask; | 66 | uint8_t bank_pin_mask; | |
77 | uint8_t bank_pin_inuse_mask; | 67 | uint8_t bank_pin_inuse_mask; | |
78 | bus_space_handle_t bank_bsh; | 68 | bus_space_handle_t bank_bsh; | |
79 | struct exynos_gpio_pin_cfg bank_cfg; | 69 | struct exynos_gpio_pin_cfg bank_cfg; | |
80 | struct exynos_gpio_bank * bank_next; | 70 | struct exynos_gpio_bank * bank_next; | |
81 | }; | 71 | }; | |
82 | 72 | |||
83 | struct exynos_gpio_softc { | |||
84 | device_t sc_dev; | |||
85 | bus_space_tag_t sc_bst; | |||
86 | bus_space_handle_t sc_bsh; | |||
87 | }; | |||
88 | ||||
89 | struct exynos_gpio_pin { | 73 | struct exynos_gpio_pin { | |
90 | struct exynos_gpio_softc *pin_sc; | 74 | struct exynos_gpio_softc *pin_sc; | |
91 | int pin_no; | 75 | int pin_no; | |
92 | u_int pin_flags; | 76 | u_int pin_flags; | |
93 | int pin_actlo; | 77 | int pin_actlo; | |
94 | const struct exynos_gpio_bank *pin_bank; | 78 | const struct exynos_gpio_bank *pin_bank; | |
95 | }; | 79 | }; | |
96 | 80 | |||
97 | 81 | |||
98 | //#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o)) | 82 | //#define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o)) | |
99 | #define GPIO_REG(v,s,o) ((o)) | 83 | #define GPIO_REG(v,s,o) ((o)) | |
100 | #define GPIO_GRP(v, s, o, n, b) \ | 84 | #define GPIO_GRP(v, s, o, n, b) \ | |
101 | { \ | 85 | { \ | |
@@ -134,42 +118,41 @@ static struct exynos_gpio_bank exynos5_b | @@ -134,42 +118,41 @@ static struct exynos_gpio_bank exynos5_b | |||
134 | GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2), | 118 | GPIO_GRP(5, MUXC, 0x00C0, gpg2, 2), | |
135 | GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4), | 119 | GPIO_GRP(5, MUXC, 0x00E0, gpj4, 4), | |
136 | 120 | |||
137 | GPIO_GRP(5, MUXD, 0x0000, gpa0, 8), | 121 | GPIO_GRP(5, MUXD, 0x0000, gpa0, 8), | |
138 | GPIO_GRP(5, MUXD, 0x0020, gpa1, 6), | 122 | GPIO_GRP(5, MUXD, 0x0020, gpa1, 6), | |
139 | GPIO_GRP(5, MUXD, 0x0040, gpa2, 8), | 123 | GPIO_GRP(5, MUXD, 0x0040, gpa2, 8), | |
140 | GPIO_GRP(5, MUXD, 0x0060, gpb0, 5), | 124 | GPIO_GRP(5, MUXD, 0x0060, gpb0, 5), | |
141 | GPIO_GRP(5, MUXD, 0x0080, gpb1, 5), | 125 | GPIO_GRP(5, MUXD, 0x0080, gpb1, 5), | |
142 | GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4), | 126 | GPIO_GRP(5, MUXD, 0x00A0, gpb2, 4), | |
143 | GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8), | 127 | GPIO_GRP(5, MUXD, 0x00C0, gpb3, 8), | |
144 | GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2), | 128 | GPIO_GRP(5, MUXD, 0x00E0, gpb4, 2), | |
145 | GPIO_GRP(5, MUXD, 0x0100, gph0, 4), | 129 | GPIO_GRP(5, MUXD, 0x0100, gph0, 4), | |
146 | 130 | |||
147 | GPIO_GRP(5, MUXE, 0x0000, gpz0, 7), | 131 | GPIO_GRP(5, MUXE, 0x0000, gpz, 7), | |
148 | 132 | |||
149 | }; | 133 | }; | |
150 | 134 | |||
151 | struct exynos_gpio_bank *exynos_gpio_banks = exynos5_banks; | 135 | struct exynos_gpio_bank *exynos_gpio_banks = exynos5_banks; | |
152 | 136 | |||
153 | static int exynos_gpio_pin_read(void *, int); | 137 | static int exynos_gpio_pin_read(void *, int); | |
154 | static void exynos_gpio_pin_write(void *, int, int); | 138 | static void exynos_gpio_pin_write(void *, int, int); | |
155 | static void exynos_gpio_pin_ctl(void *, int, int); | 139 | static void exynos_gpio_pin_ctl(void *, int, int); | |
156 | static void *exynos_gpio_fdt_acquire(device_t, const void *, | 140 | static void *exynos_gpio_fdt_acquire(device_t, const void *, | |
157 | size_t, int); | 141 | size_t, int); | |
158 | static void exynos_gpio_fdt_release(device_t, void *); | 142 | static void exynos_gpio_fdt_release(device_t, void *); | |
159 | 143 | |||
160 | static int exynos_gpio_fdt_read(device_t, void *, bool); | 144 | static int exynos_gpio_fdt_read(device_t, void *, bool); | |
161 | static void exynos_gpio_fdt_write(device_t, void *, int, bool); | 145 | static void exynos_gpio_fdt_write(device_t, void *, int, bool); | |
162 | static struct exynos_gpio_bank *exynos_gpio_bank_lookup(const char *); | |||
163 | static int exynos_gpio_cfprint(void *, const char *); | 146 | static int exynos_gpio_cfprint(void *, const char *); | |
164 | 147 | |||
165 | struct fdtbus_gpio_controller_func exynos_gpio_funcs = { | 148 | struct fdtbus_gpio_controller_func exynos_gpio_funcs = { | |
166 | .acquire = exynos_gpio_fdt_acquire, | 149 | .acquire = exynos_gpio_fdt_acquire, | |
167 | .release = exynos_gpio_fdt_release, | 150 | .release = exynos_gpio_fdt_release, | |
168 | .read = exynos_gpio_fdt_read, | 151 | .read = exynos_gpio_fdt_read, | |
169 | .write = exynos_gpio_fdt_write | 152 | .write = exynos_gpio_fdt_write | |
170 | }; | 153 | }; | |
171 | #define GPIO_WRITE(bank, reg, val) \ | 154 | #define GPIO_WRITE(bank, reg, val) \ | |
172 | bus_space_write_4((bank)->bank_sc->sc_bst, \ | 155 | bus_space_write_4((bank)->bank_sc->sc_bst, \ | |
173 | (bank)->bank_sc->sc_bsh, \ | 156 | (bank)->bank_sc->sc_bsh, \ | |
174 | (bank)->bank_core_offset + (reg), (val)) | 157 | (bank)->bank_core_offset + (reg), (val)) | |
175 | #define GPIO_READ(bank, reg) \ | 158 | #define GPIO_READ(bank, reg) \ | |
@@ -269,82 +252,112 @@ exynos_gpio_pin_ctl(void *cookie, int pi | @@ -269,82 +252,112 @@ exynos_gpio_pin_ctl(void *cookie, int pi | |||
269 | /* honour i/o */ | 252 | /* honour i/o */ | |
270 | if (flags & GPIO_PIN_INPUT) { | 253 | if (flags & GPIO_PIN_INPUT) { | |
271 | ncfg.cfg &= ~(0x0f << shift); | 254 | ncfg.cfg &= ~(0x0f << shift); | |
272 | ncfg.cfg |= EXYNOS_GPIO_FUNC_INPUT << shift; | 255 | ncfg.cfg |= EXYNOS_GPIO_FUNC_INPUT << shift; | |
273 | } else if (flags & GPIO_PIN_OUTPUT) { | 256 | } else if (flags & GPIO_PIN_OUTPUT) { | |
274 | ncfg.cfg &= ~(0x0f << shift); | 257 | ncfg.cfg &= ~(0x0f << shift); | |
275 | ncfg.cfg |= EXYNOS_GPIO_FUNC_OUTPUT << shift; | 258 | ncfg.cfg |= EXYNOS_GPIO_FUNC_OUTPUT << shift; | |
276 | } | 259 | } | |
277 | 260 | |||
278 | /* update any config registers that changed */ | 261 | /* update any config registers that changed */ | |
279 | exynos_gpio_update_cfg_regs(bank, &ncfg); | 262 | exynos_gpio_update_cfg_regs(bank, &ncfg); | |
280 | } | 263 | } | |
281 | 264 | |||
282 | void | 265 | void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *bank, | |
266 | struct exynos_gpio_pin_cfg *cfg) | |||
267 | { | |||
268 | cfg->cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); | |||
269 | cfg->pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); | |||
270 | cfg->drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); | |||
271 | cfg->conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); | |||
272 | cfg->pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); | |||
273 | } | |||
274 | ||||
275 | void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *bank, | |||
276 | const struct exynos_gpio_pin_cfg *cfg) | |||
277 | { | |||
278 | GPIO_WRITE(bank, EXYNOS_GPIO_CON, cfg->cfg); | |||
279 | GPIO_WRITE(bank, EXYNOS_GPIO_PUD, cfg->pud); | |||
280 | GPIO_WRITE(bank, EXYNOS_GPIO_DRV, cfg->drv); | |||
281 | GPIO_WRITE(bank, EXYNOS_GPIO_CONPWD, cfg->conpwd); | |||
282 | GPIO_WRITE(bank, EXYNOS_GPIO_PUDPWD, cfg->pudpwd); | |||
283 | } | |||
284 | ||||
285 | struct exynos_gpio_softc * | |||
283 | exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent, | 286 | exynos_gpio_bank_config(struct exynos_pinctrl_softc * parent, | |
284 | const struct fdt_attach_args *faa, int node) | 287 | const struct fdt_attach_args *faa, int node) | |
285 | { | 288 | { | |
286 | struct exynos_gpio_bank *bank = kmem_zalloc(sizeof(*bank), KM_SLEEP); | 289 | struct exynos_gpio_bank *bank = kmem_zalloc(sizeof(*bank), KM_SLEEP); | |
287 | struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); | 290 | struct exynos_gpio_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); | |
288 | struct gpiobus_attach_args gba; | 291 | struct gpiobus_attach_args gba; | |
289 | struct gpio_chipset_tag *gc_tag; | 292 | struct gpio_chipset_tag *gc_tag; | |
290 | char result[64]; | 293 | char result[64]; | |
291 | 294 | |||
292 | OF_getprop(node, "name", result, sizeof(result)); | 295 | OF_getprop(node, "name", result, sizeof(result)); | |
293 | bank = exynos_gpio_bank_lookup(result); | 296 | bank = exynos_gpio_bank_lookup(result); | |
294 | if (bank == NULL) { | 297 | if (bank == NULL) { | |
295 | aprint_error_dev(parent->sc_dev, "no bank found for %s\n", | 298 | aprint_error_dev(parent->sc_dev, "no bank found for %s\n", | |
296 | result); | 299 | result); | |
297 | return; | 300 | return NULL; | |
298 | } | 301 | } | |
299 | 302 | |||
300 | sc->sc_dev = parent->sc_dev; | 303 | sc->sc_dev = parent->sc_dev; | |
301 | sc->sc_bst = &armv7_generic_bs_tag; | 304 | sc->sc_bst = &armv7_generic_bs_tag; | |
302 | sc->sc_bsh = parent->sc_bsh; | 305 | sc->sc_bsh = parent->sc_bsh; | |
303 | 306 | sc->sc_bank = bank; | ||
307 | ||||
304 | gc_tag = &bank->bank_gc; | 308 | gc_tag = &bank->bank_gc; | |
305 | gc_tag->gp_cookie = bank; | 309 | gc_tag->gp_cookie = bank; | |
306 | gc_tag->gp_pin_read = exynos_gpio_pin_read; | 310 | gc_tag->gp_pin_read = exynos_gpio_pin_read; | |
307 | gc_tag->gp_pin_write = exynos_gpio_pin_write; | 311 | gc_tag->gp_pin_write = exynos_gpio_pin_write; | |
308 | gc_tag->gp_pin_ctl = exynos_gpio_pin_ctl; | 312 | gc_tag->gp_pin_ctl = exynos_gpio_pin_ctl; | |
309 | memset(&gba, 0, sizeof(gba)); | 313 | memset(&gba, 0, sizeof(gba)); | |
310 | gba.gba_gc = &bank->bank_gc; | 314 | gba.gba_gc = &bank->bank_gc; | |
311 | gba.gba_pins = bank->bank_pins; | 315 | gba.gba_pins = bank->bank_pins; | |
312 | gba.gba_npins = bank->bank_bits; | 316 | gba.gba_npins = bank->bank_bits; | |
313 | bank->bank_sc = sc; | 317 | bank->bank_sc = sc; | |
314 | bank->bank_dev = config_found_ia(parent->sc_dev, "gpiobus", &gba, | 318 | bank->bank_dev = config_found_ia(parent->sc_dev, "gpiobus", &gba, | |
315 | exynos_gpio_cfprint); | 319 | exynos_gpio_cfprint); | |
316 | 320 | |||
317 | bank->bank_pin_mask = __BIT(bank->bank_bits) - 1; | 321 | bank->bank_pin_mask = __BIT(bank->bank_bits) - 1; | |
318 | bank->bank_pin_inuse_mask = 0; | 322 | bank->bank_pin_inuse_mask = 0; | |
319 | 323 | |||
320 | 324 | |||
321 | /* read in our initial settings */ | 325 | /* read in our initial settings */ | |
322 | bank->bank_cfg.cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); | 326 | bank->bank_cfg.cfg = GPIO_READ(bank, EXYNOS_GPIO_CON); | |
323 | bank->bank_cfg.pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); | 327 | bank->bank_cfg.pud = GPIO_READ(bank, EXYNOS_GPIO_PUD); | |
324 | bank->bank_cfg.drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); | 328 | bank->bank_cfg.drv = GPIO_READ(bank, EXYNOS_GPIO_DRV); | |
325 | bank->bank_cfg.conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); | 329 | bank->bank_cfg.conpwd = GPIO_READ(bank, EXYNOS_GPIO_CONPWD); | |
326 | bank->bank_cfg.pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); | 330 | bank->bank_cfg.pudpwd = GPIO_READ(bank, EXYNOS_GPIO_PUDPWD); | |
327 | 331 | |||
328 | fdtbus_register_gpio_controller(bank->bank_dev, node, | 332 | fdtbus_register_gpio_controller(bank->bank_dev, node, | |
329 | &exynos_gpio_funcs); | 333 | &exynos_gpio_funcs); | |
334 | return sc; | |||
330 | } | 335 | } | |
331 | 336 | |||
332 | static struct exynos_gpio_bank * | 337 | /* | |
338 | * This function is a bit funky. Given a string that may look like | |||
339 | * 'gpAN' or 'gpAN-P' it is meant to find a match to the part before | |||
340 | * the '-', or the four character string if the dash is not present. | |||
341 | */ | |||
342 | struct exynos_gpio_bank * | |||
333 | exynos_gpio_bank_lookup(const char *name) | 343 | exynos_gpio_bank_lookup(const char *name) | |
334 | { | 344 | { | |
345 | struct exynos_gpio_bank *bank; | |||
346 | ||||
335 | for (u_int n = 0; n < __arraycount(exynos5_banks); n++) { | 347 | for (u_int n = 0; n < __arraycount(exynos5_banks); n++) { | |
336 | struct exynos_gpio_bank *bank = &exynos_gpio_banks[n]; | 348 | bank = &exynos_gpio_banks[n]; | |
337 | if (strncmp(bank->bank_name, name, strlen(name)) == 0) { | 349 | if (!strncmp(bank->bank_name, name, | |
350 | strlen(bank->bank_name))) { | |||
338 | return bank; | 351 | return bank; | |
339 | } | 352 | } | |
340 | } | 353 | } | |
341 | 354 | |||
342 | return NULL; | 355 | return NULL; | |
343 | } | 356 | } | |
344 | 357 | |||
345 | #if notyet | 358 | #if notyet | |
346 | static int | 359 | static int | |
347 | exynos_gpio_pin_lookup(const char *name) | 360 | exynos_gpio_pin_lookup(const char *name) | |
348 | { | 361 | { | |
349 | char *p; | 362 | char *p; | |
350 | 363 |
--- src/sys/arch/arm/samsung/exynos_i2c.c 2015/12/24 21:30:05 1.8
+++ src/sys/arch/arm/samsung/exynos_i2c.c 2015/12/30 04:30:27 1.9
@@ -1,22 +1,19 @@ | @@ -1,22 +1,19 @@ | |||
1 | /* $NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $ */ | 1 | /* $NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca> | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | |||
8 | * by Reinoud Zandijk. | |||
9 | * | |||
10 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 9 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
16 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
17 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
18 | * | 15 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | |
20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
@@ -24,91 +21,116 @@ | @@ -24,91 +21,116 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 26 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | * | 27 | * | |
31 | */ | 28 | */ | |
32 | 29 | |||
33 | #include "opt_exynos.h" | 30 | #include "opt_exynos.h" | |
34 | #include "opt_arm_debug.h" | 31 | #include "opt_arm_debug.h" | |
35 | 32 | |||
36 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.8 2015/12/24 21:30:05 marty Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: exynos_i2c.c,v 1.9 2015/12/30 04:30:27 marty Exp $"); | |
38 | 35 | |||
39 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
40 | #include <sys/bus.h> | 37 | #include <sys/bus.h> | |
41 | #include <sys/device.h> | 38 | #include <sys/device.h> | |
42 | #include <sys/intr.h> | 39 | #include <sys/intr.h> | |
43 | #include <sys/systm.h> | 40 | #include <sys/systm.h> | |
41 | #include <sys/kernel.h> | |||
44 | #include <sys/kmem.h> | 42 | #include <sys/kmem.h> | |
45 | 43 | |||
46 | #include <arm/samsung/exynos_reg.h> | 44 | #include <arm/samsung/exynos_reg.h> | |
45 | #include <arm/samsung/exynos_var.h> | |||
47 | #include <arm/samsung/exynos_intr.h> | 46 | #include <arm/samsung/exynos_intr.h> | |
48 | 47 | |||
49 | #include <sys/gpio.h> | 48 | #include <sys/gpio.h> | |
50 | #include <dev/gpio/gpiovar.h> | 49 | #include <dev/gpio/gpiovar.h> | |
51 | 50 | |||
52 | #include <dev/i2c/i2cvar.h> | 51 | #include <dev/i2c/i2cvar.h> | |
53 | #include <dev/i2c/i2c_bitbang.h> | 52 | #include <dev/i2c/i2c_bitbang.h> | |
54 | 53 | |||
55 | #include <dev/fdt/fdtvar.h> | 54 | #include <dev/fdt/fdtvar.h> | |
56 | 55 | |||
57 | struct exynos_i2c_softc { | 56 | struct exynos_i2c_softc { | |
58 | device_t sc_dev; | 57 | device_t sc_dev; | |
59 | bus_space_tag_t sc_bst; | 58 | bus_space_tag_t sc_bst; | |
60 | bus_space_handle_t sc_bsh; | 59 | bus_space_handle_t sc_bsh; | |
61 | void * sc_ih; | 60 | void * sc_ih; | |
62 | u_int sc_port; | 61 | struct clk * sc_clk; | |
63 | 62 | |||
64 | struct fdtbus_gpio_pin *sc_sda; | 63 | struct fdtbus_pinctrl_pin *sc_sda; | |
65 | struct fdtbus_gpio_pin *sc_scl; | 64 | struct fdtbus_pinctrl_pin *sc_scl; | |
66 | bool sc_sda_is_output; | 65 | bool sc_sda_is_output; | |
66 | ||||
67 | struct i2c_controller sc_ic; | 67 | struct i2c_controller sc_ic; | |
68 | kmutex_t sc_lock; | 68 | kmutex_t sc_lock; | |
69 | kcondvar_t sc_cv; | 69 | kcondvar_t sc_cv; | |
70 | device_t sc_i2cdev; | 70 | device_t sc_i2cdev; | |
71 | }; | 71 | }; | |
72 | 72 | |||
73 | static u_int i2c_port; | |||
74 | ||||
75 | static int exynos_i2c_intr(void *); | 73 | static int exynos_i2c_intr(void *); | |
76 | 74 | |||
77 | static int exynos_i2c_acquire_bus(void *, int); | 75 | static int exynos_i2c_acquire_bus(void *, int); | |
78 | static void exynos_i2c_release_bus(void *, int); | 76 | static void exynos_i2c_release_bus(void *, int); | |
79 | 77 | |||
80 | static int exynos_i2c_send_start(void *, int); | 78 | static int exynos_i2c_send_start(void *, int); | |
81 | static int exynos_i2c_send_stop(void *, int); | 79 | static int exynos_i2c_send_stop(void *, int); | |
82 | static int exynos_i2c_initiate_xfer(void *, i2c_addr_t, int); | 80 | static int exynos_i2c_initiate_xfer(void *, i2c_addr_t, int); | |
83 | static int exynos_i2c_read_byte(void *, uint8_t *, int); | 81 | static int exynos_i2c_read_byte(void *, uint8_t *, int); | |
84 | static int exynos_i2c_write_byte(void *, uint8_t , int); | 82 | static int exynos_i2c_write_byte(void *, uint8_t , int); | |
85 | 83 | |||
86 | static bool exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *, | 84 | static int exynos_i2c_wait(struct exynos_i2c_softc *, int); | |
87 | struct i2c_controller *); | 85 | ||
88 | 86 | |||
89 | static int exynos_i2c_match(device_t, cfdata_t, void *); | 87 | static int exynos_i2c_match(device_t, cfdata_t, void *); | |
90 | static void exynos_i2c_attach(device_t, device_t, void *); | 88 | static void exynos_i2c_attach(device_t, device_t, void *); | |
91 | 89 | |||
90 | static i2c_tag_t exynos_i2c_get_tag(device_t); | |||
91 | ||||
92 | struct fdtbus_i2c_controller_func exynos_i2c_funcs = { | |||
93 | .get_tag = exynos_i2c_get_tag | |||
94 | }; | |||
95 | ||||
92 | CFATTACH_DECL_NEW(exynos_i2c, sizeof(struct exynos_i2c_softc), | 96 | CFATTACH_DECL_NEW(exynos_i2c, sizeof(struct exynos_i2c_softc), | |
93 | exynos_i2c_match, exynos_i2c_attach, NULL, NULL); | 97 | exynos_i2c_match, exynos_i2c_attach, NULL, NULL); | |
94 | 98 | |||
95 | #define I2C_WRITE(sc, reg, val) \ | 99 | #define I2C_WRITE(sc, reg, val) \ | |
96 | bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) | 100 | bus_space_write_1((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) | |
97 | #define I2C_READ(sc, reg) \ | 101 | #define I2C_READ(sc, reg) \ | |
98 | bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) | 102 | bus_space_read_1((sc)->sc_bst, (sc)->sc_bsh, (reg)) | |
99 | 103 | |||
100 | #define IICON 0 | 104 | #define IICCON 0x00 | |
101 | #define IRQPEND (1<<4) | 105 | #define IICSTAT 0x04 | |
106 | #define IICADD 0x08 | |||
107 | #define IICDS 0x0C | |||
108 | ||||
109 | #define ACKENABLE (1<<7) | |||
110 | #define TXPRESCALE (1<<6) | |||
111 | #define INTENABLE (1<<5) | |||
112 | #define IRQPEND (1<<4) | |||
113 | #define PRESCALE (0x0f) | |||
114 | ||||
115 | #define MODESELECT (3<<6) | |||
116 | #define BUSYSTART (1<<5) | |||
117 | #define BUSENABLE (1<<4) | |||
118 | #define ARBITRATION (1<<3) | |||
119 | #define SLAVESTATUS (1<<2) | |||
120 | #define ZEROSTATUS (1<<1) | |||
121 | #define LASTBIT (1<<0) | |||
122 | ||||
123 | #define READBIT (1<<7) | |||
102 | 124 | |||
103 | static int | 125 | static int | |
104 | exynos_i2c_match(device_t self, cfdata_t cf, void *aux) | 126 | exynos_i2c_match(device_t self, cfdata_t cf, void *aux) | |
105 | { | 127 | { | |
106 | const char * const compatible[] = { "samsung,s3c2440-i2c", NULL }; | 128 | const char * const compatible[] = { "samsung,s3c2440-i2c", NULL }; | |
107 | struct fdt_attach_args * const faa = aux; | 129 | struct fdt_attach_args * const faa = aux; | |
108 | 130 | |||
109 | return of_match_compatible(faa->faa_phandle, compatible); | 131 | return of_match_compatible(faa->faa_phandle, compatible); | |
110 | } | 132 | } | |
111 | 133 | |||
112 | static void | 134 | static void | |
113 | exynos_i2c_attach(device_t parent, device_t self, void *aux) | 135 | exynos_i2c_attach(device_t parent, device_t self, void *aux) | |
114 | { | 136 | { | |
@@ -116,44 +138,43 @@ exynos_i2c_attach(device_t parent, devic | @@ -116,44 +138,43 @@ exynos_i2c_attach(device_t parent, devic | |||
116 | struct fdt_attach_args * const faa = aux; | 138 | struct fdt_attach_args * const faa = aux; | |
117 | const int phandle = faa->faa_phandle; | 139 | const int phandle = faa->faa_phandle; | |
118 | struct i2cbus_attach_args iba; | 140 | struct i2cbus_attach_args iba; | |
119 | 141 | |||
120 | char intrstr[128]; | 142 | char intrstr[128]; | |
121 | bus_addr_t addr; | 143 | bus_addr_t addr; | |
122 | bus_size_t size; | 144 | bus_size_t size; | |
123 | int error; | 145 | int error; | |
124 | 146 | |||
125 | char result[64]; | 147 | char result[64]; | |
126 | int i2c_handle; | 148 | int i2c_handle; | |
127 | int len; | 149 | int len; | |
128 | int handle; | 150 | int handle; | |
129 | int func /*, pud, drv */; | 151 | int func, pud, drv; | |
130 | 152 | |||
131 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | 153 | if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { | |
132 | aprint_error(": couldn't get registers\n"); | 154 | aprint_error(": couldn't get registers\n"); | |
133 | return; | 155 | return; | |
134 | } | 156 | } | |
135 | 157 | |||
136 | 158 | |||
137 | sc->sc_dev = self; | 159 | sc->sc_dev = self; | |
138 | sc->sc_bst = faa->faa_bst; | 160 | sc->sc_bst = faa->faa_bst; | |
139 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | 161 | error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh); | |
140 | if (error) { | 162 | if (error) { | |
141 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, | 163 | aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, | |
142 | error); | 164 | error); | |
143 | return; | 165 | return; | |
144 | } | 166 | } | |
145 | 167 | |||
146 | sc->sc_port = i2c_port++; | |||
147 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); | 168 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); | |
148 | cv_init(&sc->sc_cv, device_xname(self)); | 169 | cv_init(&sc->sc_cv, device_xname(self)); | |
149 | aprint_normal(" @ 0x%08x\n", (uint)addr); | 170 | aprint_normal(" @ 0x%08x\n", (uint)addr); | |
150 | 171 | |||
151 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | 172 | if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { | |
152 | aprint_error_dev(self, "failed to decode interrupt\n"); | 173 | aprint_error_dev(self, "failed to decode interrupt\n"); | |
153 | return; | 174 | return; | |
154 | } | 175 | } | |
155 | 176 | |||
156 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, | 177 | sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, | |
157 | FDT_INTR_MPSAFE, exynos_i2c_intr, sc); | 178 | FDT_INTR_MPSAFE, exynos_i2c_intr, sc); | |
158 | if (sc->sc_ih == NULL) { | 179 | if (sc->sc_ih == NULL) { | |
159 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | 180 | aprint_error_dev(self, "couldn't establish interrupt on %s\n", | |
@@ -174,191 +195,195 @@ exynos_i2c_attach(device_t parent, devic | @@ -174,191 +195,195 @@ exynos_i2c_attach(device_t parent, devic | |||
174 | if (len <= 0) { | 195 | if (len <= 0) { | |
175 | aprint_error_dev(self, "couldn't get pins.\n"); | 196 | aprint_error_dev(self, "couldn't get pins.\n"); | |
176 | return; | 197 | return; | |
177 | } | 198 | } | |
178 | 199 | |||
179 | len = OF_getprop(i2c_handle, "samsung,pin-function", | 200 | len = OF_getprop(i2c_handle, "samsung,pin-function", | |
180 | &handle, sizeof(handle)); | 201 | &handle, sizeof(handle)); | |
181 | if (len <= 0) { | 202 | if (len <= 0) { | |
182 | aprint_error_dev(self, "couldn't get pin-function.\n"); | 203 | aprint_error_dev(self, "couldn't get pin-function.\n"); | |
183 | return; | 204 | return; | |
184 | } else | 205 | } else | |
185 | func = be32toh(handle); | 206 | func = be32toh(handle); | |
186 | 207 | |||
187 | sc->sc_sda = fdtbus_gpio_acquire(phandle, &result[0], func); | 208 | sc->sc_sda = fdtbus_pinctrl_acquire(phandle, &result[0]); | |
188 | sc->sc_scl = fdtbus_gpio_acquire(phandle, &result[7], func); | 209 | if (sc->sc_sda == NULL) { | |
210 | printf("could not acquire sda gpio %s\n", &result[0]); | |||
211 | return; | |||
212 | } | |||
213 | ||||
214 | sc->sc_scl = fdtbus_pinctrl_acquire(phandle, &result[7]); | |||
215 | if (sc->sc_scl == NULL) { | |||
216 | printf("could not acquire scl gpio %s\n", &result[7]); | |||
217 | return; | |||
218 | } | |||
189 | 219 | |||
190 | /* MJF: Need fdtbus_gpio_configure */ | |||
191 | #if 0 | |||
192 | len = OF_getprop(i2c_handle, "samsung,pin-pud", &handle, | 220 | len = OF_getprop(i2c_handle, "samsung,pin-pud", &handle, | |
193 | sizeof(&handle)); | 221 | sizeof(&handle)); | |
194 | if (len <= 0) { | 222 | if (len <= 0) { | |
195 | aprint_error_dev(self, "couldn't get pin-pud.\n"); | 223 | aprint_error_dev(self, "couldn't get pin-pud.\n"); | |
196 | return; | 224 | return; | |
197 | } else | 225 | } else | |
198 | pud = be32toh(handle); | 226 | pud = be32toh(handle); | |
199 | 227 | |||
200 | len = OF_getprop(i2c_handle, "samsung,pin-drv", &handle, | 228 | len = OF_getprop(i2c_handle, "samsung,pin-drv", &handle, | |
201 | sizeof(&handle)); | 229 | sizeof(&handle)); | |
202 | if (len <= 0) { | 230 | if (len <= 0) { | |
203 | aprint_error_dev(self, "couldn't get pin-drv.\n"); | 231 | aprint_error_dev(self, "couldn't get pin-drv.\n"); | |
204 | return; | 232 | return; | |
205 | } else | 233 | } else | |
206 | drv = be32toh(handle); | 234 | drv = be32toh(handle); | |
207 | 235 | |||
208 | #endif | 236 | struct exynos_gpio_pin_cfg cfg; | |
209 | if (!exynos_i2c_attach_i2cbus(sc, &sc->sc_ic)) | 237 | cfg.cfg = func; | |
210 | return; | 238 | cfg.pud = pud; | |
239 | cfg.drv = drv; | |||
240 | cfg.conpwd = 0; | |||
241 | cfg.pudpwd = 0; | |||
242 | ||||
243 | fdtbus_pinctrl_set_cfg(sc->sc_scl, &cfg); | |||
244 | fdtbus_pinctrl_set_cfg(sc->sc_sda, &cfg); | |||
245 | ||||
246 | sc->sc_ic.ic_cookie = sc; | |||
247 | sc->sc_ic.ic_acquire_bus = exynos_i2c_acquire_bus; | |||
248 | sc->sc_ic.ic_release_bus = exynos_i2c_release_bus; | |||
249 | sc->sc_ic.ic_send_start = exynos_i2c_send_start; | |||
250 | sc->sc_ic.ic_send_stop = exynos_i2c_send_stop; | |||
251 | sc->sc_ic.ic_initiate_xfer = exynos_i2c_initiate_xfer; | |||
252 | sc->sc_ic.ic_read_byte = exynos_i2c_read_byte; | |||
253 | sc->sc_ic.ic_write_byte = exynos_i2c_write_byte; | |||
211 | 254 | |||
212 | sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print); | 255 | sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print); | |
213 | 256 | |||
214 | } | 257 | } | |
215 | 258 | |||
216 | static bool | 259 | static i2c_tag_t | |
217 | exynos_i2c_attach_i2cbus(struct exynos_i2c_softc *i2c_sc, | 260 | exynos_i2c_get_tag(device_t dev) | |
218 | struct i2c_controller *i2c_cntr) | |||
219 | { | |||
220 | i2c_cntr->ic_cookie = i2c_sc; | |||
221 | i2c_cntr->ic_acquire_bus = exynos_i2c_acquire_bus; | |||
222 | i2c_cntr->ic_release_bus = exynos_i2c_release_bus; | |||
223 | i2c_cntr->ic_send_start = exynos_i2c_send_start; | |||
224 | i2c_cntr->ic_send_stop = exynos_i2c_send_stop; | |||
225 | i2c_cntr->ic_initiate_xfer = exynos_i2c_initiate_xfer; | |||
226 | i2c_cntr->ic_read_byte = exynos_i2c_read_byte; | |||
227 | i2c_cntr->ic_write_byte = exynos_i2c_write_byte; | |||
228 | ||||
229 | return 1; | |||
230 | } | |||
231 | ||||
232 | #define EXYNOS_I2C_BB_SDA __BIT(1) | |||
233 | #define EXYNOS_I2C_BB_SCL __BIT(2) | |||
234 | #define EXYNOS_I2C_BB_SDA_OUT __BIT(3) | |||
235 | #define EXYNOS_I2C_BB_SDA_IN 0 | |||
236 | ||||
237 | static void | |||
238 | exynos_i2c_bb_set_bits(void *cookie, uint32_t bits) | |||
239 | { | |||
240 | struct exynos_i2c_softc *i2c_sc = cookie; | |||
241 | int sda, scl; | |||
242 | ||||
243 | sda = (bits & EXYNOS_I2C_BB_SDA) ? true : false; | |||
244 | scl = (bits & EXYNOS_I2C_BB_SCL) ? true : false; | |||
245 | ||||
246 | if (i2c_sc->sc_sda_is_output) | |||
247 | fdtbus_gpio_write(i2c_sc->sc_sda, sda); | |||
248 | fdtbus_gpio_write(i2c_sc->sc_scl, scl); | |||
249 | } | |||
250 | ||||
251 | static uint32_t | |||
252 | exynos_i2c_bb_read_bits(void *cookie) | |||
253 | { | 261 | { | |
254 | struct exynos_i2c_softc *i2c_sc = cookie; | 262 | struct exynos_i2c_softc * const sc = device_private(dev); | |
255 | int sda, scl; | |||
256 | ||||
257 | sda = 0; | |||
258 | if (!i2c_sc->sc_sda_is_output) | |||
259 | sda = fdtbus_gpio_read(i2c_sc->sc_sda); | |||
260 | scl = fdtbus_gpio_read(i2c_sc->sc_scl); | |||
261 | 263 | |||
262 | return (sda ? EXYNOS_I2C_BB_SDA : 0) | (scl ? EXYNOS_I2C_BB_SCL : 0); | 264 | return &sc->sc_ic; | |
263 | } | 265 | } | |
264 | 266 | |||
265 | static void | |||
266 | exynos_i2c_bb_set_dir(void *cookie, uint32_t bits) | |||
267 | { | |||
268 | struct exynos_i2c_softc *i2c_sc = cookie; | |||
269 | int flags; | |||
270 | ||||
271 | flags = GPIO_PIN_INPUT | GPIO_PIN_TRISTATE; | |||
272 | i2c_sc->sc_sda_is_output = ((bits & EXYNOS_I2C_BB_SDA_OUT) != 0); | |||
273 | if (i2c_sc->sc_sda_is_output) | |||
274 | flags = GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE; | |||
275 | ||||
276 | /* MJF: This is wrong but fdtbus has no ctrl operation */ | |||
277 | fdtbus_gpio_write(i2c_sc->sc_sda, flags); | |||
278 | } | |||
279 | ||||
280 | static const struct i2c_bitbang_ops exynos_i2c_bbops = { | |||
281 | exynos_i2c_bb_set_bits, | |||
282 | exynos_i2c_bb_set_dir, | |||
283 | exynos_i2c_bb_read_bits, | |||
284 | { | |||
285 | EXYNOS_I2C_BB_SDA, | |||
286 | EXYNOS_I2C_BB_SCL, | |||
287 | EXYNOS_I2C_BB_SDA_OUT, | |||
288 | EXYNOS_I2C_BB_SDA_IN, | |||
289 | } | |||
290 | }; | |||
291 | ||||
292 | static int | 267 | static int | |
293 | exynos_i2c_intr(void *priv) | 268 | exynos_i2c_intr(void *priv) | |
294 | { | 269 | { | |
295 | struct exynos_i2c_softc * const sc = priv; | 270 | struct exynos_i2c_softc * const sc = priv; | |
296 | 271 | |||
297 | uint32_t istatus = I2C_READ(sc, IICON); | 272 | uint8_t istatus = I2C_READ(sc, IICCON); | |
298 | if (!(istatus & IRQPEND)) | 273 | if (!(istatus & IRQPEND)) | |
299 | return 0; | 274 | return 0; | |
300 | istatus &= ~IRQPEND; | 275 | istatus &= ~IRQPEND; | |
301 | I2C_WRITE(sc, IICON, istatus); | 276 | I2C_WRITE(sc, IICCON, istatus); | |
302 | 277 | |||
303 | mutex_enter(&sc->sc_lock); | 278 | mutex_enter(&sc->sc_lock); | |
304 | cv_broadcast(&sc->sc_cv); | 279 | cv_broadcast(&sc->sc_cv); | |
305 | mutex_exit(&sc->sc_lock); | 280 | mutex_exit(&sc->sc_lock); | |
306 | 281 | |||
307 | return 1; | 282 | return 1; | |
308 | } | 283 | } | |
309 | 284 | |||
310 | static int | 285 | static int | |
311 | exynos_i2c_acquire_bus(void *cookie, int flags) | 286 | exynos_i2c_acquire_bus(void *cookie, int flags) | |
312 | { | 287 | { | |
313 | struct exynos_i2c_softc *i2c_sc = cookie; | 288 | struct exynos_i2c_softc *i2c_sc = cookie; | |
314 | 289 | |||
315 | /* XXX what to do in polling case? could another cpu help */ | |||
316 | if (flags & I2C_F_POLL) | |||
317 | return 0; | |||
318 | mutex_enter(&i2c_sc->sc_lock); | 290 | mutex_enter(&i2c_sc->sc_lock); | |
319 | return 0; | 291 | return 0; | |
320 | } | 292 | } | |
321 | 293 | |||
322 | static void | 294 | static void | |
323 | exynos_i2c_release_bus(void *cookie, int flags) | 295 | exynos_i2c_release_bus(void *cookie, int flags) | |
324 | { | 296 | { | |
325 | struct exynos_i2c_softc *i2c_sc = cookie; | 297 | struct exynos_i2c_softc *i2c_sc = cookie; | |
326 | 298 | |||
327 | /* XXX what to do in polling case? could another cpu help */ | |||
328 | if (flags & I2C_F_POLL) | |||
329 | return; | |||
330 | mutex_exit(&i2c_sc->sc_lock); | 299 | mutex_exit(&i2c_sc->sc_lock); | |
331 | } | 300 | } | |
332 | 301 | |||
333 | static int | 302 | static int | |
303 | exynos_i2c_wait(struct exynos_i2c_softc *sc, int flags) | |||
304 | { | |||
305 | int error, retry; | |||
306 | uint8_t stat = 0; | |||
307 | ||||
308 | retry = (flags & I2C_F_POLL) ? 100000 : 100; | |||
309 | ||||
310 | while (--retry > 0) { | |||
311 | if ((flags & I2C_F_POLL) == 0) { | |||
312 | error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock, | |||
313 | max(mstohz(10), 1)); | |||
314 | if (error) { | |||
315 | return error; | |||
316 | } | |||
317 | } | |||
318 | stat = I2C_READ(sc, IICSTAT); | |||
319 | if (!(stat & BUSYSTART)) { | |||
320 | break; | |||
321 | } | |||
322 | if (flags & I2C_F_POLL) { | |||
323 | delay(10); | |||
324 | } | |||
325 | } | |||
326 | if (retry == 0) { | |||
327 | stat = I2C_READ(sc, IICSTAT); | |||
328 | device_printf(sc->sc_dev, "timed out, status = %#x\n", stat); | |||
329 | return ETIMEDOUT; | |||
330 | } | |||
331 | ||||
332 | return 0; | |||
333 | } | |||
334 | ||||
335 | ||||
336 | static int | |||
334 | exynos_i2c_send_start(void *cookie, int flags) | 337 | exynos_i2c_send_start(void *cookie, int flags) | |
335 | { | 338 | { | |
336 | return i2c_bitbang_send_start(cookie, flags, &exynos_i2c_bbops); | 339 | struct exynos_i2c_softc *sc = cookie; | |
340 | I2C_WRITE(sc, IICSTAT, 0xF0); | |||
341 | return 0; | |||
337 | } | 342 | } | |
338 | 343 | |||
339 | static int | 344 | static int | |
340 | exynos_i2c_send_stop(void *cookie, int flags) | 345 | exynos_i2c_send_stop(void *cookie, int flags) | |
341 | { | 346 | { | |
342 | return i2c_bitbang_send_stop(cookie, flags, &exynos_i2c_bbops); | 347 | struct exynos_i2c_softc *sc = cookie; | |
348 | I2C_WRITE(sc, IICSTAT, 0xD0); | |||
349 | return 0; | |||
343 | } | 350 | } | |
344 | 351 | |||
345 | static int | 352 | static int | |
346 | exynos_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) | 353 | exynos_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) | |
347 | { | 354 | { | |
348 | return i2c_bitbang_initiate_xfer(cookie, addr, flags, | 355 | struct exynos_i2c_softc *sc = cookie; | |
349 | &exynos_i2c_bbops); | 356 | uint8_t byte = addr & 0x7f; | |
357 | if (flags & I2C_F_READ) | |||
358 | byte |= READBIT; | |||
359 | else | |||
360 | byte &= ~READBIT; | |||
361 | I2C_WRITE(sc, IICADD, addr); | |||
362 | exynos_i2c_send_start(cookie, flags); | |||
363 | exynos_i2c_write_byte(cookie, byte, flags); | |||
364 | return exynos_i2c_wait(cookie, flags); | |||
350 | } | 365 | } | |
351 | 366 | |||
352 | static int | 367 | static int | |
353 | exynos_i2c_read_byte(void *cookie, uint8_t *bytep, int flags) | 368 | exynos_i2c_read_byte(void *cookie, uint8_t *bytep, int flags) | |
354 | { | 369 | { | |
355 | return i2c_bitbang_read_byte(cookie, bytep, flags, | 370 | struct exynos_i2c_softc *sc = cookie; | |
356 | &exynos_i2c_bbops); | 371 | int error = exynos_i2c_wait(sc, flags); | |
372 | if (error) | |||
373 | return error; | |||
374 | *bytep = I2C_READ(sc, IICDS) & 0xff; | |||
375 | if (flags & I2C_F_STOP) | |||
376 | exynos_i2c_send_stop(cookie, flags); | |||
377 | return 0; | |||
357 | } | 378 | } | |
358 | 379 | |||
359 | static int | 380 | static int | |
360 | exynos_i2c_write_byte(void *cookie, uint8_t byte, int flags) | 381 | exynos_i2c_write_byte(void *cookie, uint8_t byte, int flags) | |
361 | { | 382 | { | |
362 | return i2c_bitbang_write_byte(cookie, byte, flags, | 383 | struct exynos_i2c_softc *sc = cookie; | |
363 | &exynos_i2c_bbops); | 384 | int error = exynos_i2c_wait(sc, flags); | |
385 | if (error) | |||
386 | return error; | |||
387 | I2C_WRITE(sc, IICDS, byte); | |||
388 | return 0; | |||
364 | } | 389 | } |
--- src/sys/arch/arm/samsung/exynos_pinctrl.c 2015/12/27 12:21:37 1.7
+++ src/sys/arch/arm/samsung/exynos_pinctrl.c 2015/12/30 04:30:27 1.8
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: exynos_pinctrl.c,v 1.7 2015/12/27 12:21:37 jmcneill Exp $ */ | 1 | /* $NetBSD: exynos_pinctrl.c,v 1.8 2015/12/30 04:30:27 marty Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2015 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2015 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Marty Fouts | 8 | * by Marty Fouts | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -24,66 +24,79 @@ | @@ -24,66 +24,79 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | #include "opt_exynos.h" | 32 | #include "opt_exynos.h" | |
33 | #include "opt_arm_debug.h" | 33 | #include "opt_arm_debug.h" | |
34 | #include "gpio.h" | 34 | #include "gpio.h" | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.7 2015/12/27 12:21:37 jmcneill Exp $"); | 37 | __KERNEL_RCSID(1, "$NetBSD: exynos_pinctrl.c,v 1.8 2015/12/30 04:30:27 marty Exp $"); | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/bus.h> | 40 | #include <sys/bus.h> | |
41 | #include <sys/device.h> | 41 | #include <sys/device.h> | |
42 | #include <sys/intr.h> | 42 | #include <sys/intr.h> | |
43 | #include <sys/systm.h> | 43 | #include <sys/systm.h> | |
44 | #include <sys/kmem.h> | 44 | #include <sys/kmem.h> | |
45 | #include <sys/gpio.h> | 45 | #include <sys/gpio.h> | |
46 | 46 | |||
47 | #include <dev/gpio/gpiovar.h> | 47 | #include <dev/gpio/gpiovar.h> | |
48 | 48 | |||
49 | #include <arm/samsung/exynos_reg.h> | 49 | #include <arm/samsung/exynos_reg.h> | |
50 | #include <arm/samsung/exynos_var.h> | 50 | #include <arm/samsung/exynos_var.h> | |
51 | #include <arm/samsung/exynos_intr.h> | 51 | #include <arm/samsung/exynos_intr.h> | |
52 | #include <arm/samsung/exynos_pinctrl.h> | 52 | #include <arm/samsung/exynos_pinctrl.h> | |
53 | 53 | |||
54 | #include <dev/fdt/fdtvar.h> | 54 | #include <dev/fdt/fdtvar.h> | |
55 | 55 | |||
56 | static int exynos_pinctrl_match(device_t, cfdata_t, void *); | 56 | static int exynos_pinctrl_match(device_t, cfdata_t, void *); | |
57 | static void exynos_pinctrl_attach(device_t, device_t, void *); | 57 | static void exynos_pinctrl_attach(device_t, device_t, void *); | |
58 | 58 | |||
59 | static void *exynos_pinctrl_acquire(device_t, const char *); | |||
60 | static void exynos_pinctrl_release(device_t, void *); | |||
61 | static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *, void *); | |||
62 | static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *, void *); | |||
63 | ||||
64 | static struct fdtbus_pinctrl_controller_func exynos_pinctrl_controller_func = { | |||
65 | .acquire = exynos_pinctrl_acquire, | |||
66 | .release = exynos_pinctrl_release, | |||
67 | .get = exynos_pinctrl_get_cfg, | |||
68 | .set = exynos_pinctrl_set_cfg, | |||
69 | }; | |||
70 | ||||
59 | CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc), | 71 | CFATTACH_DECL_NEW(exynos_pinctrl, sizeof(struct exynos_pinctrl_softc), | |
60 | exynos_pinctrl_match, exynos_pinctrl_attach, NULL, NULL); | 72 | exynos_pinctrl_match, exynos_pinctrl_attach, NULL, NULL); | |
61 | 73 | |||
62 | static int | 74 | static int | |
63 | exynos_pinctrl_match(device_t parent, cfdata_t cf, void *aux) | 75 | exynos_pinctrl_match(device_t parent, cfdata_t cf, void *aux) | |
64 | { | 76 | { | |
65 | const char * const compatible[] = { "samsung,exynos5420-pinctrl", | 77 | const char * const compatible[] = { "samsung,exynos5420-pinctrl", | |
66 | NULL }; | 78 | NULL }; | |
67 | struct fdt_attach_args * const faa = aux; | 79 | struct fdt_attach_args * const faa = aux; | |
68 | return of_match_compatible(faa->faa_phandle, compatible); | 80 | return of_match_compatible(faa->faa_phandle, compatible); | |
69 | } | 81 | } | |
70 | 82 | |||
71 | static void | 83 | static void | |
72 | exynos_pinctrl_attach(device_t parent, device_t self, void *aux) | 84 | exynos_pinctrl_attach(device_t parent, device_t self, void *aux) | |
73 | { | 85 | { | |
74 | struct exynos_pinctrl_softc * const sc | 86 | struct exynos_pinctrl_softc * const sc | |
75 | = kmem_zalloc(sizeof(*sc), KM_SLEEP); | 87 | = kmem_zalloc(sizeof(*sc), KM_SLEEP); | |
76 | struct fdt_attach_args * const faa = aux; | 88 | struct fdt_attach_args * const faa = aux; | |
89 | struct exynos_gpio_softc *child_sc; | |||
77 | bus_addr_t addr; | 90 | bus_addr_t addr; | |
78 | bus_size_t size; | 91 | bus_size_t size; | |
79 | int error; | 92 | int error; | |
80 | int child; | 93 | int child; | |
81 | 94 | |||
82 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | 95 | if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) { | |
83 | aprint_error(": couldn't get registers\n"); | 96 | aprint_error(": couldn't get registers\n"); | |
84 | return; | 97 | return; | |
85 | } | 98 | } | |
86 | 99 | |||
87 | aprint_normal(" pinctl @ 0x%08x ", (uint)addr); | 100 | aprint_normal(" pinctl @ 0x%08x ", (uint)addr); | |
88 | sc->sc_dev = self; | 101 | sc->sc_dev = self; | |
89 | sc->sc_bst = faa->faa_bst; | 102 | sc->sc_bst = faa->faa_bst; | |
@@ -91,16 +104,51 @@ exynos_pinctrl_attach(device_t parent, d | @@ -91,16 +104,51 @@ exynos_pinctrl_attach(device_t parent, d | |||
91 | if (error) { | 104 | if (error) { | |
92 | aprint_error(": couldn't map %#llx: %d", | 105 | aprint_error(": couldn't map %#llx: %d", | |
93 | (uint64_t)addr, error); | 106 | (uint64_t)addr, error); | |
94 | return; | 107 | return; | |
95 | } | 108 | } | |
96 | 109 | |||
97 | aprint_naive("\n"); | 110 | aprint_naive("\n"); | |
98 | aprint_normal("\n"); | 111 | aprint_normal("\n"); | |
99 | 112 | |||
100 | for (child = OF_child(faa->faa_phandle); child; | 113 | for (child = OF_child(faa->faa_phandle); child; | |
101 | child = OF_peer(child)) { | 114 | child = OF_peer(child)) { | |
102 | if (of_getprop_bool(child, "gpio-controller") == false) | 115 | if (of_getprop_bool(child, "gpio-controller") == false) | |
103 | continue; | 116 | continue; | |
104 | exynos_gpio_bank_config(sc, faa, child); | 117 | child_sc = exynos_gpio_bank_config(sc, faa, child); | |
118 | fdtbus_register_pinctrl_controller(child_sc->sc_dev, child, | |||
119 | &exynos_pinctrl_controller_func); | |||
105 | } | 120 | } | |
106 | } | 121 | } | |
122 | ||||
123 | ||||
124 | static void *exynos_pinctrl_acquire(device_t self, const char *name) | |||
125 | { | |||
126 | return exynos_gpio_bank_lookup(name); | |||
127 | } | |||
128 | ||||
129 | static void exynos_pinctrl_release(device_t self, void *cookie) | |||
130 | { | |||
131 | } | |||
132 | ||||
133 | static void exynos_pinctrl_get_cfg(struct fdtbus_pinctrl_pin *pin, | |||
134 | void *cookie) | |||
135 | { | |||
136 | struct exynos_gpio_bank *bank = pin->pp_priv; | |||
137 | struct exynos_gpio_pin_cfg *cfg = cookie; | |||
138 | struct exynos_gpio_pin_cfg **cfgp = &cfg; | |||
139 | struct exynos_gpio_pin_cfg *newcfg = kmem_zalloc(sizeof(*newcfg), | |||
140 | KM_SLEEP); | |||
141 | if (newcfg == NULL) | |||
142 | return; | |||
143 | exynos_gpio_pin_ctl_read(bank, newcfg); | |||
144 | *cfgp = newcfg; | |||
145 | return; | |||
146 | } | |||
147 | ||||
148 | static void exynos_pinctrl_set_cfg(struct fdtbus_pinctrl_pin *pin, | |||
149 | void *cookie) | |||
150 | { | |||
151 | struct exynos_gpio_bank *bank = pin->pp_priv; | |||
152 | struct exynos_gpio_pin_cfg *cfg = cookie; | |||
153 | exynos_gpio_pin_ctl_write(bank, cfg); | |||
154 | } |
--- src/sys/arch/arm/samsung/exynos_var.h 2015/12/24 01:10:51 1.22
+++ src/sys/arch/arm/samsung/exynos_var.h 2015/12/30 04:30:27 1.23
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: exynos_var.h,v 1.22 2015/12/24 01:10:51 marty Exp $ */ | 1 | /* $NetBSD: exynos_var.h,v 1.23 2015/12/30 04:30:27 marty Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas of 3am Software Foundry. | 8 | * by Matt Thomas of 3am Software Foundry. | |
9 | * | 9 | * | |
10 | * This code is derived from software contributed to The NetBSD Foundation | 10 | * This code is derived from software contributed to The NetBSD Foundation | |
11 | * by Reinoud Zandijk. | 11 | * by Reinoud Zandijk. | |
12 | * | 12 | * | |
13 | * Redistribution and use in source and binary forms, with or without | 13 | * Redistribution and use in source and binary forms, with or without | |
14 | * modification, are permitted provided that the following conditions | 14 | * modification, are permitted provided that the following conditions | |
@@ -94,75 +94,96 @@ struct exyo_attach_args { | @@ -94,75 +94,96 @@ struct exyo_attach_args { | |||
94 | }; | 94 | }; | |
95 | 95 | |||
96 | struct exynos_gpio_pinset { | 96 | struct exynos_gpio_pinset { | |
97 | char pinset_bank[10]; | 97 | char pinset_bank[10]; | |
98 | uint8_t pinset_func; | 98 | uint8_t pinset_func; | |
99 | uint8_t pinset_mask; | 99 | uint8_t pinset_mask; | |
100 | }; | 100 | }; | |
101 | 101 | |||
102 | struct exynos_gpio_pindata { | 102 | struct exynos_gpio_pindata { | |
103 | gpio_chipset_tag_t pd_gc; | 103 | gpio_chipset_tag_t pd_gc; | |
104 | int pd_pin; | 104 | int pd_pin; | |
105 | }; | 105 | }; | |
106 | 106 | |||
107 | struct exynos_gpio_pin_cfg { | |||
108 | uint32_t cfg; | |||
109 | uint32_t pud; | |||
110 | uint32_t drv; | |||
111 | uint32_t conpwd; | |||
112 | uint32_t pudpwd; | |||
113 | }; | |||
114 | ||||
115 | struct exynos_gpio_softc { | |||
116 | device_t sc_dev; | |||
117 | bus_space_tag_t sc_bst; | |||
118 | bus_space_handle_t sc_bsh; | |||
119 | struct exynos_gpio_bank *sc_bank; | |||
120 | int sc_phandle; | |||
121 | }; | |||
107 | 122 | |||
108 | #define EXYNOS_MAX_IIC_BUSSES 9 | 123 | #define EXYNOS_MAX_IIC_BUSSES 9 | |
109 | struct i2c_controller; | 124 | struct i2c_controller; | |
110 | extern struct i2c_controller *exynos_i2cbus[EXYNOS_MAX_IIC_BUSSES]; | 125 | extern struct i2c_controller *exynos_i2cbus[EXYNOS_MAX_IIC_BUSSES]; | |
111 | 126 | |||
112 | 127 | |||
113 | extern struct bus_space exynos_bs_tag; | 128 | extern struct bus_space exynos_bs_tag; | |
114 | extern struct bus_space exynos_a4x_bs_tag; | 129 | extern struct bus_space exynos_a4x_bs_tag; | |
115 | extern struct arm32_bus_dma_tag exynos_bus_dma_tag; | 130 | extern struct arm32_bus_dma_tag exynos_bus_dma_tag; | |
116 | extern struct arm32_bus_dma_tag exynos_coherent_bus_dma_tag; | 131 | extern struct arm32_bus_dma_tag exynos_coherent_bus_dma_tag; | |
117 | 132 | |||
118 | extern struct bus_space armv7_generic_bs_tag; | 133 | extern struct bus_space armv7_generic_bs_tag; | |
119 | extern struct bus_space armv7_generic_a4x_bs_tag; | 134 | extern struct bus_space armv7_generic_a4x_bs_tag; | |
120 | extern bus_space_handle_t exynos_core_bsh; | 135 | extern bus_space_handle_t exynos_core_bsh; | |
121 | extern bus_space_handle_t exynos_wdt_bsh; | 136 | extern bus_space_handle_t exynos_wdt_bsh; | |
122 | extern bus_space_handle_t exynos_pmu_bsh; | 137 | extern bus_space_handle_t exynos_pmu_bsh; | |
123 | extern bus_space_handle_t exynos_cmu_bsh; | 138 | extern bus_space_handle_t exynos_cmu_bsh; | |
124 | extern bus_space_handle_t exynos_sysreg_bsh; | 139 | extern bus_space_handle_t exynos_sysreg_bsh; | |
125 | 140 | |||
126 | extern void exynos_bootstrap(vaddr_t, vaddr_t); | 141 | extern void exynos_bootstrap(vaddr_t, vaddr_t); | |
127 | extern void exynos_dma_bootstrap(psize_t memsize); | 142 | extern void exynos_dma_bootstrap(psize_t memsize); | |
128 | 143 | |||
129 | struct exynos_pinctrl_softc; | 144 | struct exynos_pinctrl_softc; | |
145 | struct exynos_gpio_softc; | |||
130 | struct fdt_attach_args; | 146 | struct fdt_attach_args; | |
131 | extern void exynos_gpio_bank_config(struct exynos_pinctrl_softc *, | 147 | ||
148 | extern struct exynos_gpio_softc * exynos_gpio_bank_config(struct exynos_pinctrl_softc *, | |||
132 | const struct fdt_attach_args *, int); | 149 | const struct fdt_attach_args *, int); | |
133 | extern void exynos_wdt_reset(void); | 150 | extern void exynos_wdt_reset(void); | |
134 | 151 | |||
135 | extern void exynos_init_clkout_for_usb(void); // board specific | 152 | extern void exynos_init_clkout_for_usb(void); // board specific | |
136 | 153 | |||
137 | extern void exynos_clocks_bootstrap(void); | 154 | extern void exynos_clocks_bootstrap(void); | |
138 | extern void exynos_sysctl_cpufreq_init(void); | 155 | extern void exynos_sysctl_cpufreq_init(void); | |
139 | extern uint64_t exynos_get_cpufreq(void); | 156 | extern uint64_t exynos_get_cpufreq(void); | |
140 | 157 | |||
141 | extern void exynos_device_register(device_t self, void *aux); | 158 | extern void exynos_device_register(device_t self, void *aux); | |
142 | extern void exynos_device_register_post_config(device_t self, void *aux); | 159 | extern void exynos_device_register_post_config(device_t self, void *aux); | |
143 | extern void exynos_usb_phy_init(bus_space_handle_t usb2phy_bsh); | 160 | extern void exynos_usb_phy_init(bus_space_handle_t usb2phy_bsh); | |
144 | extern void exynos_usb_soc_powerup(void); | 161 | extern void exynos_usb_soc_powerup(void); | |
145 | 162 | |||
146 | extern void exyo_device_register(device_t self, void *aux); | 163 | extern void exyo_device_register(device_t self, void *aux); | |
147 | extern void exyo_device_register_post_config(device_t self, void *aux); | 164 | extern void exyo_device_register_post_config(device_t self, void *aux); | |
148 | 165 | |||
166 | extern struct exynos_gpio_bank *exynos_gpio_bank_lookup(const char *name); | |||
149 | extern bool exynos_gpio_pinset_available(const struct exynos_gpio_pinset *); | 167 | extern bool exynos_gpio_pinset_available(const struct exynos_gpio_pinset *); | |
150 | extern void exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *); | 168 | extern void exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *); | |
151 | extern void exynos_gpio_pinset_release(const struct exynos_gpio_pinset *); | 169 | extern void exynos_gpio_pinset_release(const struct exynos_gpio_pinset *); | |
152 | extern void exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *, | 170 | extern void exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *, | |
153 | int pinnr, struct exynos_gpio_pindata *); | 171 | int pinnr, struct exynos_gpio_pindata *); | |
154 | extern bool exynos_gpio_pin_reserve(const char *, struct exynos_gpio_pindata *); | 172 | extern bool exynos_gpio_pin_reserve(const char *, struct exynos_gpio_pindata *); | |
155 | 173 | extern void exynos_gpio_pin_ctl_read(const struct exynos_gpio_bank *, | ||
174 | struct exynos_gpio_pin_cfg *); | |||
175 | extern void exynos_gpio_pin_ctl_write(const struct exynos_gpio_bank *, | |||
176 | const struct exynos_gpio_pin_cfg *); | |||
156 | static inline void | 177 | static inline void | |
157 | exynos_gpio_pindata_write(const struct exynos_gpio_pindata *pd, int value) | 178 | exynos_gpio_pindata_write(const struct exynos_gpio_pindata *pd, int value) | |
158 | { | 179 | { | |
159 | gpiobus_pin_write(pd->pd_gc, pd->pd_pin, value); | 180 | gpiobus_pin_write(pd->pd_gc, pd->pd_pin, value); | |
160 | } | 181 | } | |
161 | 182 | |||
162 | static inline int | 183 | static inline int | |
163 | exynos_gpio_pindata_read(const struct exynos_gpio_pindata *pd) | 184 | exynos_gpio_pindata_read(const struct exynos_gpio_pindata *pd) | |
164 | { | 185 | { | |
165 | return gpiobus_pin_read(pd->pd_gc, pd->pd_pin); | 186 | return gpiobus_pin_read(pd->pd_gc, pd->pd_pin); | |
166 | } | 187 | } | |
167 | 188 | |||
168 | static inline void | 189 | static inline void |