gpio-vr41xx.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /*
  2. * Driver for NEC VR4100 series General-purpose I/O Unit.
  3. *
  4. * Copyright (C) 2002 MontaVista Software Inc.
  5. * Author: Yoichi Yuasa <source@mvista.com>
  6. * Copyright (C) 2003-2009 Yoichi Yuasa <yuasa@linux-mips.org>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #include <linux/errno.h>
  23. #include <linux/fs.h>
  24. #include <linux/gpio.h>
  25. #include <linux/init.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/io.h>
  28. #include <linux/irq.h>
  29. #include <linux/kernel.h>
  30. #include <linux/module.h>
  31. #include <linux/platform_device.h>
  32. #include <linux/spinlock.h>
  33. #include <linux/types.h>
  34. #include <asm/vr41xx/giu.h>
  35. #include <asm/vr41xx/irq.h>
  36. #include <asm/vr41xx/vr41xx.h>
  37. MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
  38. MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver");
  39. MODULE_LICENSE("GPL");
  40. #define GIUIOSELL 0x00
  41. #define GIUIOSELH 0x02
  42. #define GIUPIODL 0x04
  43. #define GIUPIODH 0x06
  44. #define GIUINTSTATL 0x08
  45. #define GIUINTSTATH 0x0a
  46. #define GIUINTENL 0x0c
  47. #define GIUINTENH 0x0e
  48. #define GIUINTTYPL 0x10
  49. #define GIUINTTYPH 0x12
  50. #define GIUINTALSELL 0x14
  51. #define GIUINTALSELH 0x16
  52. #define GIUINTHTSELL 0x18
  53. #define GIUINTHTSELH 0x1a
  54. #define GIUPODATL 0x1c
  55. #define GIUPODATEN 0x1c
  56. #define GIUPODATH 0x1e
  57. #define PIOEN0 0x0100
  58. #define PIOEN1 0x0200
  59. #define GIUPODAT 0x1e
  60. #define GIUFEDGEINHL 0x20
  61. #define GIUFEDGEINHH 0x22
  62. #define GIUREDGEINHL 0x24
  63. #define GIUREDGEINHH 0x26
  64. #define GIUUSEUPDN 0x1e0
  65. #define GIUTERMUPDN 0x1e2
  66. #define GPIO_HAS_PULLUPDOWN_IO 0x0001
  67. #define GPIO_HAS_OUTPUT_ENABLE 0x0002
  68. #define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100
  69. enum {
  70. GPIO_INPUT,
  71. GPIO_OUTPUT,
  72. };
  73. static DEFINE_SPINLOCK(giu_lock);
  74. static unsigned long giu_flags;
  75. static void __iomem *giu_base;
  76. static struct gpio_chip vr41xx_gpio_chip;
  77. #define giu_read(offset) readw(giu_base + (offset))
  78. #define giu_write(offset, value) writew((value), giu_base + (offset))
  79. #define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE)
  80. #define GIUINT_HIGH_OFFSET 16
  81. #define GIUINT_HIGH_MAX 32
  82. static inline u16 giu_set(u16 offset, u16 set)
  83. {
  84. u16 data;
  85. data = giu_read(offset);
  86. data |= set;
  87. giu_write(offset, data);
  88. return data;
  89. }
  90. static inline u16 giu_clear(u16 offset, u16 clear)
  91. {
  92. u16 data;
  93. data = giu_read(offset);
  94. data &= ~clear;
  95. giu_write(offset, data);
  96. return data;
  97. }
  98. static void ack_giuint_low(struct irq_data *d)
  99. {
  100. giu_write(GIUINTSTATL, 1 << GPIO_PIN_OF_IRQ(d->irq));
  101. }
  102. static void mask_giuint_low(struct irq_data *d)
  103. {
  104. giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
  105. }
  106. static void mask_ack_giuint_low(struct irq_data *d)
  107. {
  108. unsigned int pin;
  109. pin = GPIO_PIN_OF_IRQ(d->irq);
  110. giu_clear(GIUINTENL, 1 << pin);
  111. giu_write(GIUINTSTATL, 1 << pin);
  112. }
  113. static void unmask_giuint_low(struct irq_data *d)
  114. {
  115. giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(d->irq));
  116. }
  117. static unsigned int startup_giuint(struct irq_data *data)
  118. {
  119. if (gpiochip_lock_as_irq(&vr41xx_gpio_chip, data->hwirq))
  120. dev_err(vr41xx_gpio_chip.dev,
  121. "unable to lock HW IRQ %lu for IRQ\n",
  122. data->hwirq);
  123. /* Satisfy the .enable semantics by unmasking the line */
  124. unmask_giuint_low(data);
  125. return 0;
  126. }
  127. static void shutdown_giuint(struct irq_data *data)
  128. {
  129. mask_giuint_low(data);
  130. gpiochip_unlock_as_irq(&vr41xx_gpio_chip, data->hwirq);
  131. }
  132. static struct irq_chip giuint_low_irq_chip = {
  133. .name = "GIUINTL",
  134. .irq_ack = ack_giuint_low,
  135. .irq_mask = mask_giuint_low,
  136. .irq_mask_ack = mask_ack_giuint_low,
  137. .irq_unmask = unmask_giuint_low,
  138. .irq_startup = startup_giuint,
  139. .irq_shutdown = shutdown_giuint,
  140. };
  141. static void ack_giuint_high(struct irq_data *d)
  142. {
  143. giu_write(GIUINTSTATH,
  144. 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
  145. }
  146. static void mask_giuint_high(struct irq_data *d)
  147. {
  148. giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
  149. }
  150. static void mask_ack_giuint_high(struct irq_data *d)
  151. {
  152. unsigned int pin;
  153. pin = GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET;
  154. giu_clear(GIUINTENH, 1 << pin);
  155. giu_write(GIUINTSTATH, 1 << pin);
  156. }
  157. static void unmask_giuint_high(struct irq_data *d)
  158. {
  159. giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(d->irq) - GIUINT_HIGH_OFFSET));
  160. }
  161. static struct irq_chip giuint_high_irq_chip = {
  162. .name = "GIUINTH",
  163. .irq_ack = ack_giuint_high,
  164. .irq_mask = mask_giuint_high,
  165. .irq_mask_ack = mask_ack_giuint_high,
  166. .irq_unmask = unmask_giuint_high,
  167. };
  168. static int giu_get_irq(unsigned int irq)
  169. {
  170. u16 pendl, pendh, maskl, maskh;
  171. int i;
  172. pendl = giu_read(GIUINTSTATL);
  173. pendh = giu_read(GIUINTSTATH);
  174. maskl = giu_read(GIUINTENL);
  175. maskh = giu_read(GIUINTENH);
  176. maskl &= pendl;
  177. maskh &= pendh;
  178. if (maskl) {
  179. for (i = 0; i < 16; i++) {
  180. if (maskl & (1 << i))
  181. return GIU_IRQ(i);
  182. }
  183. } else if (maskh) {
  184. for (i = 0; i < 16; i++) {
  185. if (maskh & (1 << i))
  186. return GIU_IRQ(i + GIUINT_HIGH_OFFSET);
  187. }
  188. }
  189. printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
  190. maskl, pendl, maskh, pendh);
  191. atomic_inc(&irq_err_count);
  192. return -EINVAL;
  193. }
  194. void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger,
  195. irq_signal_t signal)
  196. {
  197. u16 mask;
  198. if (pin < GIUINT_HIGH_OFFSET) {
  199. mask = 1 << pin;
  200. if (trigger != IRQ_TRIGGER_LEVEL) {
  201. giu_set(GIUINTTYPL, mask);
  202. if (signal == IRQ_SIGNAL_HOLD)
  203. giu_set(GIUINTHTSELL, mask);
  204. else
  205. giu_clear(GIUINTHTSELL, mask);
  206. if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
  207. switch (trigger) {
  208. case IRQ_TRIGGER_EDGE_FALLING:
  209. giu_set(GIUFEDGEINHL, mask);
  210. giu_clear(GIUREDGEINHL, mask);
  211. break;
  212. case IRQ_TRIGGER_EDGE_RISING:
  213. giu_clear(GIUFEDGEINHL, mask);
  214. giu_set(GIUREDGEINHL, mask);
  215. break;
  216. default:
  217. giu_set(GIUFEDGEINHL, mask);
  218. giu_set(GIUREDGEINHL, mask);
  219. break;
  220. }
  221. }
  222. irq_set_chip_and_handler(GIU_IRQ(pin),
  223. &giuint_low_irq_chip,
  224. handle_edge_irq);
  225. } else {
  226. giu_clear(GIUINTTYPL, mask);
  227. giu_clear(GIUINTHTSELL, mask);
  228. irq_set_chip_and_handler(GIU_IRQ(pin),
  229. &giuint_low_irq_chip,
  230. handle_level_irq);
  231. }
  232. giu_write(GIUINTSTATL, mask);
  233. } else if (pin < GIUINT_HIGH_MAX) {
  234. mask = 1 << (pin - GIUINT_HIGH_OFFSET);
  235. if (trigger != IRQ_TRIGGER_LEVEL) {
  236. giu_set(GIUINTTYPH, mask);
  237. if (signal == IRQ_SIGNAL_HOLD)
  238. giu_set(GIUINTHTSELH, mask);
  239. else
  240. giu_clear(GIUINTHTSELH, mask);
  241. if (giu_flags & GPIO_HAS_INTERRUPT_EDGE_SELECT) {
  242. switch (trigger) {
  243. case IRQ_TRIGGER_EDGE_FALLING:
  244. giu_set(GIUFEDGEINHH, mask);
  245. giu_clear(GIUREDGEINHH, mask);
  246. break;
  247. case IRQ_TRIGGER_EDGE_RISING:
  248. giu_clear(GIUFEDGEINHH, mask);
  249. giu_set(GIUREDGEINHH, mask);
  250. break;
  251. default:
  252. giu_set(GIUFEDGEINHH, mask);
  253. giu_set(GIUREDGEINHH, mask);
  254. break;
  255. }
  256. }
  257. irq_set_chip_and_handler(GIU_IRQ(pin),
  258. &giuint_high_irq_chip,
  259. handle_edge_irq);
  260. } else {
  261. giu_clear(GIUINTTYPH, mask);
  262. giu_clear(GIUINTHTSELH, mask);
  263. irq_set_chip_and_handler(GIU_IRQ(pin),
  264. &giuint_high_irq_chip,
  265. handle_level_irq);
  266. }
  267. giu_write(GIUINTSTATH, mask);
  268. }
  269. }
  270. EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
  271. void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
  272. {
  273. u16 mask;
  274. if (pin < GIUINT_HIGH_OFFSET) {
  275. mask = 1 << pin;
  276. if (level == IRQ_LEVEL_HIGH)
  277. giu_set(GIUINTALSELL, mask);
  278. else
  279. giu_clear(GIUINTALSELL, mask);
  280. giu_write(GIUINTSTATL, mask);
  281. } else if (pin < GIUINT_HIGH_MAX) {
  282. mask = 1 << (pin - GIUINT_HIGH_OFFSET);
  283. if (level == IRQ_LEVEL_HIGH)
  284. giu_set(GIUINTALSELH, mask);
  285. else
  286. giu_clear(GIUINTALSELH, mask);
  287. giu_write(GIUINTSTATH, mask);
  288. }
  289. }
  290. EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
  291. static int giu_set_direction(struct gpio_chip *chip, unsigned pin, int dir)
  292. {
  293. u16 offset, mask, reg;
  294. unsigned long flags;
  295. if (pin >= chip->ngpio)
  296. return -EINVAL;
  297. if (pin < 16) {
  298. offset = GIUIOSELL;
  299. mask = 1 << pin;
  300. } else if (pin < 32) {
  301. offset = GIUIOSELH;
  302. mask = 1 << (pin - 16);
  303. } else {
  304. if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
  305. offset = GIUPODATEN;
  306. mask = 1 << (pin - 32);
  307. } else {
  308. switch (pin) {
  309. case 48:
  310. offset = GIUPODATH;
  311. mask = PIOEN0;
  312. break;
  313. case 49:
  314. offset = GIUPODATH;
  315. mask = PIOEN1;
  316. break;
  317. default:
  318. return -EINVAL;
  319. }
  320. }
  321. }
  322. spin_lock_irqsave(&giu_lock, flags);
  323. reg = giu_read(offset);
  324. if (dir == GPIO_OUTPUT)
  325. reg |= mask;
  326. else
  327. reg &= ~mask;
  328. giu_write(offset, reg);
  329. spin_unlock_irqrestore(&giu_lock, flags);
  330. return 0;
  331. }
  332. int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
  333. {
  334. u16 reg, mask;
  335. unsigned long flags;
  336. if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO)
  337. return -EPERM;
  338. if (pin >= 15)
  339. return -EINVAL;
  340. mask = 1 << pin;
  341. spin_lock_irqsave(&giu_lock, flags);
  342. if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) {
  343. reg = giu_read(GIUTERMUPDN);
  344. if (pull == GPIO_PULL_UP)
  345. reg |= mask;
  346. else
  347. reg &= ~mask;
  348. giu_write(GIUTERMUPDN, reg);
  349. reg = giu_read(GIUUSEUPDN);
  350. reg |= mask;
  351. giu_write(GIUUSEUPDN, reg);
  352. } else {
  353. reg = giu_read(GIUUSEUPDN);
  354. reg &= ~mask;
  355. giu_write(GIUUSEUPDN, reg);
  356. }
  357. spin_unlock_irqrestore(&giu_lock, flags);
  358. return 0;
  359. }
  360. EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
  361. static int vr41xx_gpio_get(struct gpio_chip *chip, unsigned pin)
  362. {
  363. u16 reg, mask;
  364. if (pin >= chip->ngpio)
  365. return -EINVAL;
  366. if (pin < 16) {
  367. reg = giu_read(GIUPIODL);
  368. mask = 1 << pin;
  369. } else if (pin < 32) {
  370. reg = giu_read(GIUPIODH);
  371. mask = 1 << (pin - 16);
  372. } else if (pin < 48) {
  373. reg = giu_read(GIUPODATL);
  374. mask = 1 << (pin - 32);
  375. } else {
  376. reg = giu_read(GIUPODATH);
  377. mask = 1 << (pin - 48);
  378. }
  379. if (reg & mask)
  380. return 1;
  381. return 0;
  382. }
  383. static void vr41xx_gpio_set(struct gpio_chip *chip, unsigned pin,
  384. int value)
  385. {
  386. u16 offset, mask, reg;
  387. unsigned long flags;
  388. if (pin >= chip->ngpio)
  389. return;
  390. if (pin < 16) {
  391. offset = GIUPIODL;
  392. mask = 1 << pin;
  393. } else if (pin < 32) {
  394. offset = GIUPIODH;
  395. mask = 1 << (pin - 16);
  396. } else if (pin < 48) {
  397. offset = GIUPODATL;
  398. mask = 1 << (pin - 32);
  399. } else {
  400. offset = GIUPODATH;
  401. mask = 1 << (pin - 48);
  402. }
  403. spin_lock_irqsave(&giu_lock, flags);
  404. reg = giu_read(offset);
  405. if (value)
  406. reg |= mask;
  407. else
  408. reg &= ~mask;
  409. giu_write(offset, reg);
  410. spin_unlock_irqrestore(&giu_lock, flags);
  411. }
  412. static int vr41xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
  413. {
  414. return giu_set_direction(chip, offset, GPIO_INPUT);
  415. }
  416. static int vr41xx_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
  417. int value)
  418. {
  419. vr41xx_gpio_set(chip, offset, value);
  420. return giu_set_direction(chip, offset, GPIO_OUTPUT);
  421. }
  422. static int vr41xx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
  423. {
  424. if (offset >= chip->ngpio)
  425. return -EINVAL;
  426. return GIU_IRQ_BASE + offset;
  427. }
  428. static struct gpio_chip vr41xx_gpio_chip = {
  429. .label = "vr41xx",
  430. .owner = THIS_MODULE,
  431. .direction_input = vr41xx_gpio_direction_input,
  432. .get = vr41xx_gpio_get,
  433. .direction_output = vr41xx_gpio_direction_output,
  434. .set = vr41xx_gpio_set,
  435. .to_irq = vr41xx_gpio_to_irq,
  436. };
  437. static int giu_probe(struct platform_device *pdev)
  438. {
  439. struct resource *res;
  440. unsigned int trigger, i, pin;
  441. struct irq_chip *chip;
  442. int irq, ret;
  443. switch (pdev->id) {
  444. case GPIO_50PINS_PULLUPDOWN:
  445. giu_flags = GPIO_HAS_PULLUPDOWN_IO;
  446. vr41xx_gpio_chip.ngpio = 50;
  447. break;
  448. case GPIO_36PINS:
  449. vr41xx_gpio_chip.ngpio = 36;
  450. break;
  451. case GPIO_48PINS_EDGE_SELECT:
  452. giu_flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
  453. vr41xx_gpio_chip.ngpio = 48;
  454. break;
  455. default:
  456. dev_err(&pdev->dev, "GIU: unknown ID %d\n", pdev->id);
  457. return -ENODEV;
  458. }
  459. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  460. if (!res)
  461. return -EBUSY;
  462. giu_base = ioremap(res->start, resource_size(res));
  463. if (!giu_base)
  464. return -ENOMEM;
  465. vr41xx_gpio_chip.dev = &pdev->dev;
  466. ret = gpiochip_add(&vr41xx_gpio_chip);
  467. if (!ret) {
  468. iounmap(giu_base);
  469. return -ENODEV;
  470. }
  471. giu_write(GIUINTENL, 0);
  472. giu_write(GIUINTENH, 0);
  473. trigger = giu_read(GIUINTTYPH) << 16;
  474. trigger |= giu_read(GIUINTTYPL);
  475. for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
  476. pin = GPIO_PIN_OF_IRQ(i);
  477. if (pin < GIUINT_HIGH_OFFSET)
  478. chip = &giuint_low_irq_chip;
  479. else
  480. chip = &giuint_high_irq_chip;
  481. if (trigger & (1 << pin))
  482. irq_set_chip_and_handler(i, chip, handle_edge_irq);
  483. else
  484. irq_set_chip_and_handler(i, chip, handle_level_irq);
  485. }
  486. irq = platform_get_irq(pdev, 0);
  487. if (irq < 0 || irq >= nr_irqs)
  488. return -EBUSY;
  489. return cascade_irq(irq, giu_get_irq);
  490. }
  491. static int giu_remove(struct platform_device *pdev)
  492. {
  493. if (giu_base) {
  494. iounmap(giu_base);
  495. giu_base = NULL;
  496. }
  497. return 0;
  498. }
  499. static struct platform_driver giu_device_driver = {
  500. .probe = giu_probe,
  501. .remove = giu_remove,
  502. .driver = {
  503. .name = "GIU",
  504. },
  505. };
  506. module_platform_driver(giu_device_driver);