pxa2x0_gpio.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. /* $OpenBSD: pxa2x0_gpio.c,v 1.24 2014/07/12 18:44:41 tedu Exp $ */
  2. /* $NetBSD: pxa2x0_gpio.c,v 1.2 2003/07/15 00:24:55 lukem Exp $ */
  3. /*
  4. * Copyright 2003 Wasabi Systems, Inc.
  5. * All rights reserved.
  6. *
  7. * Written by Steve C. Woodford for Wasabi Systems, Inc.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. All advertising materials mentioning features or use of this software
  18. * must display the following acknowledgement:
  19. * This product includes software developed for the NetBSD Project by
  20. * Wasabi Systems, Inc.
  21. * 4. The name of Wasabi Systems, Inc. may not be used to endorse
  22. * or promote products derived from this software without specific prior
  23. * written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
  26. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  27. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  28. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
  29. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. * POSSIBILITY OF SUCH DAMAGE.
  36. */
  37. #include <sys/param.h>
  38. #include <sys/systm.h>
  39. #include <sys/device.h>
  40. #include <sys/malloc.h>
  41. #include <sys/evcount.h>
  42. #include <machine/intr.h>
  43. #include <machine/bus.h>
  44. #include <arm/cpufunc.h>
  45. #include <arm/xscale/pxa2x0reg.h>
  46. #include <arm/xscale/pxa2x0var.h>
  47. #include <arm/xscale/pxa2x0_gpio.h>
  48. struct gpio_irq_handler {
  49. struct gpio_irq_handler *gh_next;
  50. int (*gh_func)(void *);
  51. void *gh_arg;
  52. int gh_spl;
  53. u_int gh_gpio;
  54. int gh_level;
  55. int gh_irq;
  56. struct evcount gh_count;
  57. };
  58. struct pxagpio_softc {
  59. struct device sc_dev;
  60. bus_space_tag_t sc_bust;
  61. bus_space_handle_t sc_bush;
  62. void *sc_irqcookie[4];
  63. u_int32_t sc_mask[3];
  64. #ifdef PXAGPIO_HAS_GPION_INTRS
  65. struct gpio_irq_handler *sc_handlers[GPIO_NPINS];
  66. int sc_minipl;
  67. int sc_maxipl;
  68. #else
  69. struct gpio_irq_handler *sc_handlers[2];
  70. #endif
  71. int npins;
  72. int pxa27x_pins;
  73. };
  74. int pxagpio_match(struct device *, void *, void *);
  75. void pxagpio_attach(struct device *, struct device *, void *);
  76. #ifdef __NetBSD__
  77. CFATTACH_DECL(pxagpio, sizeof(struct pxagpio_softc),
  78. pxagpio_match, pxagpio_attach, NULL, NULL);
  79. #else
  80. struct cfattach pxagpio_ca = {
  81. sizeof (struct pxagpio_softc), pxagpio_match, pxagpio_attach
  82. };
  83. struct cfdriver pxagpio_cd = {
  84. NULL, "pxagpio", DV_DULL
  85. };
  86. #endif
  87. static struct pxagpio_softc *pxagpio_softc;
  88. static vaddr_t pxagpio_regs;
  89. #define GPIO_BOOTSTRAP_REG(reg) \
  90. (*((volatile u_int32_t *)(pxagpio_regs + (reg))))
  91. void pxa2x0_gpio_set_intr_level(u_int, int);
  92. int pxagpio_intr0(void *);
  93. int pxagpio_intr1(void *);
  94. #ifdef PXAGPIO_HAS_GPION_INTRS
  95. int pxagpio_dispatch(struct pxagpio_softc *, int);
  96. int pxagpio_intrN(void *);
  97. int pxagpio_intrlow(void *);
  98. void pxa2x0_gpio_intr_fixup(int minipl, int maxipl);
  99. #endif
  100. u_int32_t pxagpio_reg_read(struct pxagpio_softc *sc, int reg);
  101. void pxagpio_reg_write(struct pxagpio_softc *sc, int reg, u_int32_t val);
  102. u_int32_t
  103. pxagpio_reg_read(struct pxagpio_softc *sc, int reg)
  104. {
  105. if (__predict_true(sc != NULL))
  106. return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg));
  107. else
  108. if (pxagpio_regs)
  109. return (GPIO_BOOTSTRAP_REG(reg));
  110. panic("pxagpio_reg_read: not bootstrapped");
  111. }
  112. void
  113. pxagpio_reg_write(struct pxagpio_softc *sc, int reg, u_int32_t val)
  114. {
  115. if (__predict_true(sc != NULL))
  116. bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val);
  117. else
  118. if (pxagpio_regs)
  119. GPIO_BOOTSTRAP_REG(reg) = val;
  120. else
  121. panic("pxagpio_reg_write: not bootstrapped");
  122. return;
  123. }
  124. int
  125. pxagpio_match(struct device *parent, void *cf, void *aux)
  126. {
  127. struct pxaip_attach_args *pxa = aux;
  128. if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE)
  129. return (0);
  130. pxa->pxa_size = PXA2X0_GPIO_SIZE;
  131. return (1);
  132. }
  133. void
  134. pxagpio_attach(struct device *parent, struct device *self, void *aux)
  135. {
  136. struct pxagpio_softc *sc = (struct pxagpio_softc *)self;
  137. struct pxaip_attach_args *pxa = aux;
  138. sc->sc_bust = pxa->pxa_iot;
  139. printf(": GPIO Controller\n");
  140. if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) {
  141. sc->npins = GPIO_NPINS;
  142. sc->pxa27x_pins = 1;
  143. } else {
  144. sc->npins = GPIO_NPINS_25x;
  145. sc->pxa27x_pins = 0;
  146. }
  147. if (bus_space_map(sc->sc_bust, pxa->pxa_addr, pxa->pxa_size, 0,
  148. &sc->sc_bush)) {
  149. printf("%s: Can't map registers!\n", sc->sc_dev.dv_xname);
  150. return;
  151. }
  152. memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers));
  153. /*
  154. * Disable all GPIO interrupts
  155. */
  156. pxagpio_reg_write(sc, GPIO_GRER0, 0);
  157. pxagpio_reg_write(sc, GPIO_GRER1, 0);
  158. pxagpio_reg_write(sc, GPIO_GRER2, 0);
  159. pxagpio_reg_write(sc, GPIO_GRER3, 0);
  160. pxagpio_reg_write(sc, GPIO_GFER0, 0);
  161. pxagpio_reg_write(sc, GPIO_GFER1, 0);
  162. pxagpio_reg_write(sc, GPIO_GFER2, 0);
  163. pxagpio_reg_write(sc, GPIO_GFER3, 0);
  164. pxagpio_reg_write(sc, GPIO_GEDR0, ~0);
  165. pxagpio_reg_write(sc, GPIO_GEDR1, ~0);
  166. pxagpio_reg_write(sc, GPIO_GEDR2, ~0);
  167. pxagpio_reg_write(sc, GPIO_GEDR3, ~0);
  168. #ifdef PXAGPIO_HAS_GPION_INTRS
  169. sc->sc_minipl = IPL_NONE;
  170. sc->sc_maxipl = IPL_NONE;
  171. #endif
  172. sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL;
  173. pxagpio_softc = sc;
  174. }
  175. void
  176. pxa2x0_gpio_bootstrap(vaddr_t gpio_regs)
  177. {
  178. pxagpio_regs = gpio_regs;
  179. }
  180. void *
  181. pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *),
  182. void *arg, const char *name)
  183. {
  184. struct pxagpio_softc *sc = pxagpio_softc;
  185. struct gpio_irq_handler *gh;
  186. u_int32_t bit;
  187. #ifdef DEBUG
  188. #ifdef PXAGPIO_HAS_GPION_INTRS
  189. if (gpio >= sc->npins)
  190. panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
  191. #else
  192. if (gpio > 1)
  193. panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio);
  194. #endif
  195. #endif
  196. if (GPIO_FN_IS_OUT(pxa2x0_gpio_get_function(gpio)) != GPIO_IN)
  197. panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio);
  198. gh = (struct gpio_irq_handler *)malloc(sizeof(struct gpio_irq_handler),
  199. M_DEVBUF, M_NOWAIT);
  200. gh->gh_func = func;
  201. gh->gh_arg = arg;
  202. gh->gh_spl = spl;
  203. gh->gh_gpio = gpio;
  204. gh->gh_irq = gpio+32;
  205. gh->gh_level = level;
  206. evcount_attach(&gh->gh_count, name, &gh->gh_irq);
  207. gh->gh_next = sc->sc_handlers[gpio];
  208. sc->sc_handlers[gpio] = gh;
  209. if (gpio == 0) {
  210. KDASSERT(sc->sc_irqcookie[0] == NULL);
  211. sc->sc_irqcookie[0] = pxa2x0_intr_establish(PXA2X0_INT_GPIO0,
  212. spl, pxagpio_intr0, sc, NULL);
  213. KDASSERT(sc->sc_irqcookie[0]);
  214. } else if (gpio == 1) {
  215. KDASSERT(sc->sc_irqcookie[1] == NULL);
  216. sc->sc_irqcookie[1] = pxa2x0_intr_establish(PXA2X0_INT_GPIO1,
  217. spl, pxagpio_intr1, sc, NULL);
  218. KDASSERT(sc->sc_irqcookie[1]);
  219. } else {
  220. #ifdef PXAGPIO_HAS_GPION_INTRS
  221. int minipl, maxipl;
  222. if (sc->sc_maxipl == IPL_NONE || spl > sc->sc_maxipl) {
  223. maxipl = spl;
  224. } else {
  225. maxipl = sc->sc_maxipl;
  226. }
  227. if (sc->sc_minipl == IPL_NONE || spl < sc->sc_minipl) {
  228. minipl = spl;
  229. } else {
  230. minipl = sc->sc_minipl;
  231. }
  232. pxa2x0_gpio_intr_fixup(minipl, maxipl);
  233. #endif
  234. }
  235. bit = GPIO_BIT(gpio);
  236. sc->sc_mask[GPIO_BANK(gpio)] |= bit;
  237. pxa2x0_gpio_set_intr_level(gpio, gh->gh_level);
  238. return (gh);
  239. }
  240. void
  241. pxa2x0_gpio_intr_disestablish(void *cookie)
  242. {
  243. struct pxagpio_softc *sc = pxagpio_softc;
  244. struct gpio_irq_handler *gh = cookie;
  245. u_int32_t bit, reg;
  246. evcount_detach(&gh->gh_count);
  247. bit = GPIO_BIT(gh->gh_gpio);
  248. reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio));
  249. reg &= ~bit;
  250. pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio), reg);
  251. reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio));
  252. reg &= ~bit;
  253. pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio), reg);
  254. pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit);
  255. sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit;
  256. sc->sc_handlers[gh->gh_gpio] = NULL;
  257. if (gh->gh_gpio == 0) {
  258. pxa2x0_intr_disestablish(sc->sc_irqcookie[0]);
  259. sc->sc_irqcookie[0] = NULL;
  260. } else if (gh->gh_gpio == 1) {
  261. pxa2x0_intr_disestablish(sc->sc_irqcookie[1]);
  262. sc->sc_irqcookie[1] = NULL;
  263. } else {
  264. #ifdef PXAGPIO_HAS_GPION_INTRS
  265. int i, minipl, maxipl, ipl;
  266. minipl = IPL_HIGH;
  267. maxipl = IPL_NONE;
  268. for (i = 2; i < sc->npins; i++) {
  269. if (sc->sc_handlers[i] != NULL) {
  270. ipl = sc->sc_handlers[i]->gh_spl;
  271. if (minipl > ipl)
  272. minipl = ipl;
  273. if (maxipl < ipl)
  274. maxipl = ipl;
  275. }
  276. }
  277. pxa2x0_gpio_intr_fixup(minipl, maxipl);
  278. #endif /* PXAGPIO_HAS_GPION_INTRS */
  279. }
  280. free(gh, M_DEVBUF, 0);
  281. }
  282. #ifdef PXAGPIO_HAS_GPION_INTRS
  283. void
  284. pxa2x0_gpio_intr_fixup(int minipl, int maxipl)
  285. {
  286. struct pxagpio_softc *sc = pxagpio_softc;
  287. int save = disable_interrupts(I32_bit);
  288. if (maxipl == IPL_NONE && minipl == IPL_HIGH) {
  289. /* no remaining interrupts */
  290. if (sc->sc_irqcookie[2])
  291. pxa2x0_intr_disestablish(sc->sc_irqcookie[2]);
  292. sc->sc_irqcookie[2] = NULL;
  293. if (sc->sc_irqcookie[3])
  294. pxa2x0_intr_disestablish(sc->sc_irqcookie[3]);
  295. sc->sc_irqcookie[3] = NULL;
  296. sc->sc_minipl = IPL_NONE;
  297. sc->sc_maxipl = IPL_NONE;
  298. restore_interrupts(save);
  299. return;
  300. }
  301. if (sc->sc_maxipl == IPL_NONE || maxipl > sc->sc_maxipl) {
  302. if (sc->sc_irqcookie[2])
  303. pxa2x0_intr_disestablish(sc->sc_irqcookie[2]);
  304. sc->sc_maxipl = maxipl;
  305. sc->sc_irqcookie[2] =
  306. pxa2x0_intr_establish(PXA2X0_INT_GPION,
  307. maxipl, pxagpio_intrN, sc, NULL);
  308. if (sc->sc_irqcookie[2] == NULL) {
  309. printf("%s: failed to hook main "
  310. "GPIO interrupt\n",
  311. sc->sc_dev.dv_xname);
  312. /* XXX - panic? */
  313. }
  314. }
  315. if (sc->sc_minipl == IPL_NONE || minipl < sc->sc_minipl) {
  316. if (sc->sc_irqcookie[3])
  317. pxa2x0_intr_disestablish(sc->sc_irqcookie[3]);
  318. sc->sc_minipl = minipl;
  319. sc->sc_irqcookie[3] =
  320. pxa2x0_intr_establish(PXA2X0_INT_GPION,
  321. sc->sc_minipl, pxagpio_intrlow, sc, NULL);
  322. if (sc->sc_irqcookie[3] == NULL) {
  323. printf("%s: failed to hook main "
  324. "GPIO interrupt\n",
  325. sc->sc_dev.dv_xname);
  326. /* XXX - panic? */
  327. }
  328. }
  329. restore_interrupts(save);
  330. }
  331. #endif /* PXAGPIO_HAS_GPION_INTRS */
  332. const char *
  333. pxa2x0_gpio_intr_string(void *cookie)
  334. {
  335. static char irqstr[32];
  336. struct gpio_irq_handler *gh = cookie;
  337. if (gh == NULL)
  338. snprintf(irqstr, sizeof irqstr, "couldn't establish interrupt");
  339. else
  340. snprintf(irqstr, sizeof irqstr, "irq %d", gh->gh_irq);
  341. return(irqstr);
  342. }
  343. int
  344. pxagpio_intr0(void *arg)
  345. {
  346. struct pxagpio_softc *sc = arg;
  347. int ret;
  348. #ifdef DIAGNOSTIC
  349. if (sc->sc_handlers[0] == NULL) {
  350. printf("%s: stray GPIO#0 edge interrupt\n",
  351. sc->sc_dev.dv_xname);
  352. return (0);
  353. }
  354. #endif
  355. bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0),
  356. GPIO_BIT(0));
  357. ret = (sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg);
  358. if (ret != 0)
  359. sc->sc_handlers[0]->gh_count.ec_count++;
  360. return ret;
  361. }
  362. int
  363. pxagpio_intr1(void *arg)
  364. {
  365. struct pxagpio_softc *sc = arg;
  366. int ret;
  367. #ifdef DIAGNOSTIC
  368. if (sc->sc_handlers[1] == NULL) {
  369. printf("%s: stray GPIO#1 edge interrupt\n",
  370. sc->sc_dev.dv_xname);
  371. return (0);
  372. }
  373. #endif
  374. bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1),
  375. GPIO_BIT(1));
  376. ret = (sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg);
  377. if (ret != 0)
  378. sc->sc_handlers[1]->gh_count.ec_count++;
  379. return ret;
  380. }
  381. #ifdef PXAGPIO_HAS_GPION_INTRS
  382. int
  383. pxagpio_dispatch(struct pxagpio_softc *sc, int gpio_base)
  384. {
  385. struct gpio_irq_handler **ghp, *gh;
  386. int i, s, nhandled, handled, pins;
  387. u_int32_t gedr, mask;
  388. int bank;
  389. /* Fetch bitmap of pending interrupts on this GPIO bank */
  390. gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base));
  391. /* Don't handle GPIO 0/1 here */
  392. if (gpio_base == 0)
  393. gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1));
  394. /* Bail early if there are no pending interrupts in this bank */
  395. if (gedr == 0)
  396. return (0);
  397. /* Acknowledge pending interrupts. */
  398. pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr);
  399. bank = GPIO_BANK(gpio_base);
  400. /*
  401. * We're only interested in those for which we have a handler
  402. * registered
  403. */
  404. #ifdef DEBUG
  405. if ((gedr & sc->sc_mask[bank]) == 0) {
  406. printf("%s: stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n",
  407. sc->sc_dev.dv_xname, bank, gedr, sc->sc_mask[bank]);
  408. return (1); /* XXX: Pretend we dealt with it */
  409. }
  410. #endif
  411. gedr &= sc->sc_mask[bank];
  412. ghp = &sc->sc_handlers[gpio_base];
  413. if (sc->pxa27x_pins == 1)
  414. pins = (gpio_base < 96) ? 32 : 25;
  415. else
  416. pins = (gpio_base < 64) ? 32 : 17;
  417. handled = 0;
  418. for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) {
  419. if ((gedr & mask) == 0)
  420. continue;
  421. gedr &= ~mask;
  422. if ((gh = *ghp) == NULL) {
  423. printf("%s: unhandled GPIO interrupt. GPIO#%d\n",
  424. sc->sc_dev.dv_xname, gpio_base + i);
  425. continue;
  426. }
  427. s = _splraise(gh->gh_spl);
  428. do {
  429. nhandled = (gh->gh_func)(gh->gh_arg);
  430. if (nhandled != 0)
  431. gh->gh_count.ec_count++;
  432. handled |= nhandled;
  433. gh = gh->gh_next;
  434. } while (gh != NULL);
  435. splx(s);
  436. }
  437. return (handled);
  438. }
  439. int
  440. pxagpio_intrN(void *arg)
  441. {
  442. struct pxagpio_softc *sc = arg;
  443. int handled;
  444. handled = pxagpio_dispatch(sc, 0);
  445. handled |= pxagpio_dispatch(sc, 32);
  446. handled |= pxagpio_dispatch(sc, 64);
  447. handled |= pxagpio_dispatch(sc, 96);
  448. return (handled);
  449. }
  450. int
  451. pxagpio_intrlow(void *arg)
  452. {
  453. /* dummy */
  454. return 0;
  455. }
  456. #endif /* PXAGPIO_HAS_GPION_INTRS */
  457. u_int
  458. pxa2x0_gpio_get_function(u_int gpio)
  459. {
  460. struct pxagpio_softc *sc = pxagpio_softc;
  461. u_int32_t rv, io;
  462. if (__predict_true(sc != NULL))
  463. KDASSERT(gpio < sc->npins);
  464. rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio);
  465. rv = GPIO_FN(rv);
  466. io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio));
  467. if (io & GPIO_BIT(gpio))
  468. rv |= GPIO_OUT;
  469. io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio));
  470. if (io & GPIO_BIT(gpio))
  471. rv |= GPIO_SET;
  472. return (rv);
  473. }
  474. u_int
  475. pxa2x0_gpio_set_function(u_int gpio, u_int fn)
  476. {
  477. struct pxagpio_softc *sc = pxagpio_softc;
  478. u_int32_t rv, bit;
  479. u_int oldfn;
  480. if (__predict_true(sc != NULL))
  481. KDASSERT(gpio < sc->npins);
  482. oldfn = pxa2x0_gpio_get_function(gpio);
  483. if (GPIO_FN(fn) == GPIO_FN(oldfn) &&
  484. GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) {
  485. /*
  486. * The pin's function is not changing.
  487. * For Alternate Functions and GPIO input, we can just
  488. * return now.
  489. * For GPIO output pins, check the initial state is
  490. * the same.
  491. *
  492. * Return 'fn' instead of 'oldfn' so the caller can
  493. * reliably detect that we didn't change anything.
  494. * (The initial state might be different for non-
  495. * GPIO output pins).
  496. */
  497. if (!GPIO_IS_GPIO_OUT(fn) ||
  498. GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn))
  499. return (fn);
  500. }
  501. /*
  502. * See section 4.1.3.7 of the PXA2x0 Developer's Manual for
  503. * the correct procedure for changing GPIO pin functions.
  504. */
  505. bit = GPIO_BIT(gpio);
  506. /*
  507. * 1. Configure the correct set/clear state of the pin
  508. */
  509. if (GPIO_FN_IS_SET(fn))
  510. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
  511. else
  512. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
  513. /*
  514. * 2. Configure the pin as an input or output as appropriate
  515. */
  516. rv = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
  517. if (GPIO_FN_IS_OUT(fn))
  518. rv |= bit;
  519. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), rv);
  520. /*
  521. * 3. Configure the pin's function
  522. */
  523. bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio);
  524. fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio);
  525. rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit;
  526. pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn);
  527. return (oldfn);
  528. }
  529. /*
  530. * Quick function to read pin value
  531. */
  532. int
  533. pxa2x0_gpio_get_bit(u_int gpio)
  534. {
  535. struct pxagpio_softc *sc = pxagpio_softc;
  536. int bit;
  537. bit = GPIO_BIT(gpio);
  538. if (pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio)) & bit)
  539. return 1;
  540. else
  541. return 0;
  542. }
  543. /*
  544. * Quick function to set pin to 1
  545. */
  546. void
  547. pxa2x0_gpio_set_bit(u_int gpio)
  548. {
  549. struct pxagpio_softc *sc = pxagpio_softc;
  550. int bit;
  551. bit = GPIO_BIT(gpio);
  552. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit);
  553. }
  554. /*
  555. * Quick function to set pin to 0
  556. */
  557. void
  558. pxa2x0_gpio_clear_bit(u_int gpio)
  559. {
  560. struct pxagpio_softc *sc = pxagpio_softc;
  561. int bit;
  562. bit = GPIO_BIT(gpio);
  563. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit);
  564. }
  565. /*
  566. * Quick function to change pin direction
  567. */
  568. void
  569. pxa2x0_gpio_set_dir(u_int gpio, int dir)
  570. {
  571. struct pxagpio_softc *sc = pxagpio_softc;
  572. int bit;
  573. u_int32_t reg;
  574. bit = GPIO_BIT(gpio);
  575. reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit;
  576. if (GPIO_FN_IS_OUT(dir))
  577. reg |= bit;
  578. pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), reg);
  579. }
  580. /*
  581. * Quick function to clear interrupt status on a pin
  582. * GPIO pins may be toggle in an interrupt and we dont want
  583. * extra spurious interrupts to occur.
  584. * Suppose this causes a slight race if a key is pressed while
  585. * the interrupt handler is running. (yes this is for the keyboard driver)
  586. */
  587. void
  588. pxa2x0_gpio_clear_intr(u_int gpio)
  589. {
  590. struct pxagpio_softc *sc = pxagpio_softc;
  591. int bit;
  592. bit = GPIO_BIT(gpio);
  593. pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio), bit);
  594. }
  595. /*
  596. * Quick function to mask (disable) a GPIO interrupt
  597. */
  598. void
  599. pxa2x0_gpio_intr_mask(void *v)
  600. {
  601. struct gpio_irq_handler *gh = v;
  602. pxa2x0_gpio_set_intr_level(gh->gh_gpio, IPL_NONE);
  603. }
  604. /*
  605. * Quick function to unmask (enable) a GPIO interrupt
  606. */
  607. void
  608. pxa2x0_gpio_intr_unmask(void *v)
  609. {
  610. struct gpio_irq_handler *gh = v;
  611. pxa2x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level);
  612. }
  613. /*
  614. * Configure the edge sensitivity of interrupt pins
  615. */
  616. void
  617. pxa2x0_gpio_set_intr_level(u_int gpio, int level)
  618. {
  619. struct pxagpio_softc *sc = pxagpio_softc;
  620. u_int32_t bit;
  621. u_int32_t gfer;
  622. u_int32_t grer;
  623. int s;
  624. s = splhigh();
  625. bit = GPIO_BIT(gpio);
  626. gfer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio));
  627. grer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio));
  628. switch (level) {
  629. case IST_NONE:
  630. gfer &= ~bit;
  631. grer &= ~bit;
  632. break;
  633. case IST_EDGE_FALLING:
  634. gfer |= bit;
  635. grer &= ~bit;
  636. break;
  637. case IST_EDGE_RISING:
  638. gfer &= ~bit;
  639. grer |= bit;
  640. break;
  641. case IST_EDGE_BOTH:
  642. gfer |= bit;
  643. grer |= bit;
  644. break;
  645. default:
  646. panic("pxa2x0_gpio_set_intr_level: bad level: %d", level);
  647. break;
  648. }
  649. pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), gfer);
  650. pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), grer);
  651. splx(s);
  652. }