gpio-viperboard.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Nano River Technologies viperboard GPIO lib driver
  4. *
  5. * (C) 2012 by Lemonage GmbH
  6. * Author: Lars Poeschel <poeschel@lemonage.de>
  7. * All rights reserved.
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/errno.h>
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <linux/types.h>
  14. #include <linux/mutex.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/usb.h>
  17. #include <linux/gpio/driver.h>
  18. #include <linux/mfd/viperboard.h>
  19. #define VPRBRD_GPIOA_CLK_1MHZ 0
  20. #define VPRBRD_GPIOA_CLK_100KHZ 1
  21. #define VPRBRD_GPIOA_CLK_10KHZ 2
  22. #define VPRBRD_GPIOA_CLK_1KHZ 3
  23. #define VPRBRD_GPIOA_CLK_100HZ 4
  24. #define VPRBRD_GPIOA_CLK_10HZ 5
  25. #define VPRBRD_GPIOA_FREQ_DEFAULT 1000
  26. #define VPRBRD_GPIOA_CMD_CONT 0x00
  27. #define VPRBRD_GPIOA_CMD_PULSE 0x01
  28. #define VPRBRD_GPIOA_CMD_PWM 0x02
  29. #define VPRBRD_GPIOA_CMD_SETOUT 0x03
  30. #define VPRBRD_GPIOA_CMD_SETIN 0x04
  31. #define VPRBRD_GPIOA_CMD_SETINT 0x05
  32. #define VPRBRD_GPIOA_CMD_GETIN 0x06
  33. #define VPRBRD_GPIOB_CMD_SETDIR 0x00
  34. #define VPRBRD_GPIOB_CMD_SETVAL 0x01
  35. struct vprbrd_gpioa_msg {
  36. u8 cmd;
  37. u8 clk;
  38. u8 offset;
  39. u8 t1;
  40. u8 t2;
  41. u8 invert;
  42. u8 pwmlevel;
  43. u8 outval;
  44. u8 risefall;
  45. u8 answer;
  46. u8 __fill;
  47. } __packed;
  48. struct vprbrd_gpiob_msg {
  49. u8 cmd;
  50. u16 val;
  51. u16 mask;
  52. } __packed;
  53. struct vprbrd_gpio {
  54. struct gpio_chip gpioa; /* gpio a related things */
  55. u32 gpioa_out;
  56. u32 gpioa_val;
  57. struct gpio_chip gpiob; /* gpio b related things */
  58. u32 gpiob_out;
  59. u32 gpiob_val;
  60. struct vprbrd *vb;
  61. };
  62. /* gpioa sampling clock module parameter */
  63. static unsigned char gpioa_clk;
  64. static unsigned int gpioa_freq = VPRBRD_GPIOA_FREQ_DEFAULT;
  65. module_param(gpioa_freq, uint, 0);
  66. MODULE_PARM_DESC(gpioa_freq,
  67. "gpio-a sampling freq in Hz (default is 1000Hz) valid values: 10, 100, 1000, 10000, 100000, 1000000");
  68. /* ----- begin of gipo a chip -------------------------------------------- */
  69. static int vprbrd_gpioa_get(struct gpio_chip *chip,
  70. unsigned int offset)
  71. {
  72. int ret, answer, error = 0;
  73. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  74. struct vprbrd *vb = gpio->vb;
  75. struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
  76. /* if io is set to output, just return the saved value */
  77. if (gpio->gpioa_out & (1 << offset))
  78. return !!(gpio->gpioa_val & (1 << offset));
  79. mutex_lock(&vb->lock);
  80. gamsg->cmd = VPRBRD_GPIOA_CMD_GETIN;
  81. gamsg->clk = 0x00;
  82. gamsg->offset = offset;
  83. gamsg->t1 = 0x00;
  84. gamsg->t2 = 0x00;
  85. gamsg->invert = 0x00;
  86. gamsg->pwmlevel = 0x00;
  87. gamsg->outval = 0x00;
  88. gamsg->risefall = 0x00;
  89. gamsg->answer = 0x00;
  90. gamsg->__fill = 0x00;
  91. ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
  92. VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
  93. 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
  94. VPRBRD_USB_TIMEOUT_MS);
  95. if (ret != sizeof(struct vprbrd_gpioa_msg))
  96. error = -EREMOTEIO;
  97. ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
  98. VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_IN, 0x0000,
  99. 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
  100. VPRBRD_USB_TIMEOUT_MS);
  101. answer = gamsg->answer & 0x01;
  102. mutex_unlock(&vb->lock);
  103. if (ret != sizeof(struct vprbrd_gpioa_msg))
  104. error = -EREMOTEIO;
  105. if (error)
  106. return error;
  107. return answer;
  108. }
  109. static void vprbrd_gpioa_set(struct gpio_chip *chip,
  110. unsigned int offset, int value)
  111. {
  112. int ret;
  113. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  114. struct vprbrd *vb = gpio->vb;
  115. struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
  116. if (gpio->gpioa_out & (1 << offset)) {
  117. if (value)
  118. gpio->gpioa_val |= (1 << offset);
  119. else
  120. gpio->gpioa_val &= ~(1 << offset);
  121. mutex_lock(&vb->lock);
  122. gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
  123. gamsg->clk = 0x00;
  124. gamsg->offset = offset;
  125. gamsg->t1 = 0x00;
  126. gamsg->t2 = 0x00;
  127. gamsg->invert = 0x00;
  128. gamsg->pwmlevel = 0x00;
  129. gamsg->outval = value;
  130. gamsg->risefall = 0x00;
  131. gamsg->answer = 0x00;
  132. gamsg->__fill = 0x00;
  133. ret = usb_control_msg(vb->usb_dev,
  134. usb_sndctrlpipe(vb->usb_dev, 0),
  135. VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT,
  136. 0x0000, 0x0000, gamsg,
  137. sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS);
  138. mutex_unlock(&vb->lock);
  139. if (ret != sizeof(struct vprbrd_gpioa_msg))
  140. dev_err(chip->parent, "usb error setting pin value\n");
  141. }
  142. }
  143. static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
  144. unsigned int offset)
  145. {
  146. int ret;
  147. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  148. struct vprbrd *vb = gpio->vb;
  149. struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
  150. gpio->gpioa_out &= ~(1 << offset);
  151. mutex_lock(&vb->lock);
  152. gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN;
  153. gamsg->clk = gpioa_clk;
  154. gamsg->offset = offset;
  155. gamsg->t1 = 0x00;
  156. gamsg->t2 = 0x00;
  157. gamsg->invert = 0x00;
  158. gamsg->pwmlevel = 0x00;
  159. gamsg->outval = 0x00;
  160. gamsg->risefall = 0x00;
  161. gamsg->answer = 0x00;
  162. gamsg->__fill = 0x00;
  163. ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
  164. VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
  165. 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
  166. VPRBRD_USB_TIMEOUT_MS);
  167. mutex_unlock(&vb->lock);
  168. if (ret != sizeof(struct vprbrd_gpioa_msg))
  169. return -EREMOTEIO;
  170. return 0;
  171. }
  172. static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
  173. unsigned int offset, int value)
  174. {
  175. int ret;
  176. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  177. struct vprbrd *vb = gpio->vb;
  178. struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
  179. gpio->gpioa_out |= (1 << offset);
  180. if (value)
  181. gpio->gpioa_val |= (1 << offset);
  182. else
  183. gpio->gpioa_val &= ~(1 << offset);
  184. mutex_lock(&vb->lock);
  185. gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
  186. gamsg->clk = 0x00;
  187. gamsg->offset = offset;
  188. gamsg->t1 = 0x00;
  189. gamsg->t2 = 0x00;
  190. gamsg->invert = 0x00;
  191. gamsg->pwmlevel = 0x00;
  192. gamsg->outval = value;
  193. gamsg->risefall = 0x00;
  194. gamsg->answer = 0x00;
  195. gamsg->__fill = 0x00;
  196. ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
  197. VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
  198. 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
  199. VPRBRD_USB_TIMEOUT_MS);
  200. mutex_unlock(&vb->lock);
  201. if (ret != sizeof(struct vprbrd_gpioa_msg))
  202. return -EREMOTEIO;
  203. return 0;
  204. }
  205. /* ----- end of gpio a chip ---------------------------------------------- */
  206. /* ----- begin of gipo b chip -------------------------------------------- */
  207. static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
  208. unsigned int dir)
  209. {
  210. struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
  211. int ret;
  212. gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR;
  213. gbmsg->val = cpu_to_be16(dir << offset);
  214. gbmsg->mask = cpu_to_be16(0x0001 << offset);
  215. ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
  216. VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000,
  217. 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
  218. VPRBRD_USB_TIMEOUT_MS);
  219. if (ret != sizeof(struct vprbrd_gpiob_msg))
  220. return -EREMOTEIO;
  221. return 0;
  222. }
  223. static int vprbrd_gpiob_get(struct gpio_chip *chip,
  224. unsigned int offset)
  225. {
  226. int ret;
  227. u16 val;
  228. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  229. struct vprbrd *vb = gpio->vb;
  230. struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
  231. /* if io is set to output, just return the saved value */
  232. if (gpio->gpiob_out & (1 << offset))
  233. return gpio->gpiob_val & (1 << offset);
  234. mutex_lock(&vb->lock);
  235. ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
  236. VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000,
  237. 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
  238. VPRBRD_USB_TIMEOUT_MS);
  239. val = gbmsg->val;
  240. mutex_unlock(&vb->lock);
  241. if (ret != sizeof(struct vprbrd_gpiob_msg))
  242. return ret;
  243. /* cache the read values */
  244. gpio->gpiob_val = be16_to_cpu(val);
  245. return (gpio->gpiob_val >> offset) & 0x1;
  246. }
  247. static void vprbrd_gpiob_set(struct gpio_chip *chip,
  248. unsigned int offset, int value)
  249. {
  250. int ret;
  251. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  252. struct vprbrd *vb = gpio->vb;
  253. struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
  254. if (gpio->gpiob_out & (1 << offset)) {
  255. if (value)
  256. gpio->gpiob_val |= (1 << offset);
  257. else
  258. gpio->gpiob_val &= ~(1 << offset);
  259. mutex_lock(&vb->lock);
  260. gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL;
  261. gbmsg->val = cpu_to_be16(value << offset);
  262. gbmsg->mask = cpu_to_be16(0x0001 << offset);
  263. ret = usb_control_msg(vb->usb_dev,
  264. usb_sndctrlpipe(vb->usb_dev, 0),
  265. VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT,
  266. 0x0000, 0x0000, gbmsg,
  267. sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS);
  268. mutex_unlock(&vb->lock);
  269. if (ret != sizeof(struct vprbrd_gpiob_msg))
  270. dev_err(chip->parent, "usb error setting pin value\n");
  271. }
  272. }
  273. static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
  274. unsigned int offset)
  275. {
  276. int ret;
  277. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  278. struct vprbrd *vb = gpio->vb;
  279. gpio->gpiob_out &= ~(1 << offset);
  280. mutex_lock(&vb->lock);
  281. ret = vprbrd_gpiob_setdir(vb, offset, 0);
  282. mutex_unlock(&vb->lock);
  283. if (ret)
  284. dev_err(chip->parent, "usb error setting pin to input\n");
  285. return ret;
  286. }
  287. static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
  288. unsigned int offset, int value)
  289. {
  290. int ret;
  291. struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
  292. struct vprbrd *vb = gpio->vb;
  293. gpio->gpiob_out |= (1 << offset);
  294. mutex_lock(&vb->lock);
  295. ret = vprbrd_gpiob_setdir(vb, offset, 1);
  296. if (ret)
  297. dev_err(chip->parent, "usb error setting pin to output\n");
  298. mutex_unlock(&vb->lock);
  299. vprbrd_gpiob_set(chip, offset, value);
  300. return ret;
  301. }
  302. /* ----- end of gpio b chip ---------------------------------------------- */
  303. static int vprbrd_gpio_probe(struct platform_device *pdev)
  304. {
  305. struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
  306. struct vprbrd_gpio *vb_gpio;
  307. int ret;
  308. vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL);
  309. if (vb_gpio == NULL)
  310. return -ENOMEM;
  311. vb_gpio->vb = vb;
  312. /* registering gpio a */
  313. vb_gpio->gpioa.label = "viperboard gpio a";
  314. vb_gpio->gpioa.parent = &pdev->dev;
  315. vb_gpio->gpioa.owner = THIS_MODULE;
  316. vb_gpio->gpioa.base = -1;
  317. vb_gpio->gpioa.ngpio = 16;
  318. vb_gpio->gpioa.can_sleep = true;
  319. vb_gpio->gpioa.set = vprbrd_gpioa_set;
  320. vb_gpio->gpioa.get = vprbrd_gpioa_get;
  321. vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input;
  322. vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output;
  323. ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpioa, vb_gpio);
  324. if (ret < 0) {
  325. dev_err(vb_gpio->gpioa.parent, "could not add gpio a");
  326. return ret;
  327. }
  328. /* registering gpio b */
  329. vb_gpio->gpiob.label = "viperboard gpio b";
  330. vb_gpio->gpiob.parent = &pdev->dev;
  331. vb_gpio->gpiob.owner = THIS_MODULE;
  332. vb_gpio->gpiob.base = -1;
  333. vb_gpio->gpiob.ngpio = 16;
  334. vb_gpio->gpiob.can_sleep = true;
  335. vb_gpio->gpiob.set = vprbrd_gpiob_set;
  336. vb_gpio->gpiob.get = vprbrd_gpiob_get;
  337. vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input;
  338. vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output;
  339. ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpiob, vb_gpio);
  340. if (ret < 0) {
  341. dev_err(vb_gpio->gpiob.parent, "could not add gpio b");
  342. return ret;
  343. }
  344. platform_set_drvdata(pdev, vb_gpio);
  345. return ret;
  346. }
  347. static struct platform_driver vprbrd_gpio_driver = {
  348. .driver.name = "viperboard-gpio",
  349. .probe = vprbrd_gpio_probe,
  350. };
  351. static int __init vprbrd_gpio_init(void)
  352. {
  353. switch (gpioa_freq) {
  354. case 1000000:
  355. gpioa_clk = VPRBRD_GPIOA_CLK_1MHZ;
  356. break;
  357. case 100000:
  358. gpioa_clk = VPRBRD_GPIOA_CLK_100KHZ;
  359. break;
  360. case 10000:
  361. gpioa_clk = VPRBRD_GPIOA_CLK_10KHZ;
  362. break;
  363. case 1000:
  364. gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
  365. break;
  366. case 100:
  367. gpioa_clk = VPRBRD_GPIOA_CLK_100HZ;
  368. break;
  369. case 10:
  370. gpioa_clk = VPRBRD_GPIOA_CLK_10HZ;
  371. break;
  372. default:
  373. pr_warn("invalid gpioa_freq (%d)\n", gpioa_freq);
  374. gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
  375. }
  376. return platform_driver_register(&vprbrd_gpio_driver);
  377. }
  378. subsys_initcall(vprbrd_gpio_init);
  379. static void __exit vprbrd_gpio_exit(void)
  380. {
  381. platform_driver_unregister(&vprbrd_gpio_driver);
  382. }
  383. module_exit(vprbrd_gpio_exit);
  384. MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
  385. MODULE_DESCRIPTION("GPIO driver for Nano River Techs Viperboard");
  386. MODULE_LICENSE("GPL");
  387. MODULE_ALIAS("platform:viperboard-gpio");