ark_mcu_serial.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Arkmicro mcu serial driver
  3. *
  4. * Licensed under GPLv2 or later.
  5. */
  6. #include <linux/module.h>
  7. #include <linux/ioport.h>
  8. #include <linux/init.h>
  9. #include <linux/console.h>
  10. #include <linux/sysrq.h>
  11. #include <linux/device.h>
  12. #include <linux/tty.h>
  13. #include <linux/tty_flip.h>
  14. #include <linux/serial_core.h>
  15. #include <linux/serial.h>
  16. #include <linux/amba/bus.h>
  17. #include <linux/amba/serial.h>
  18. #include <linux/clk.h>
  19. #include <linux/slab.h>
  20. #include <linux/dmaengine.h>
  21. #include <linux/dma-mapping.h>
  22. #include <linux/scatterlist.h>
  23. #include <linux/delay.h>
  24. #include <linux/types.h>
  25. #include <linux/of.h>
  26. #include <linux/of_device.h>
  27. #include <linux/pinctrl/consumer.h>
  28. #include <linux/sizes.h>
  29. #include <linux/io.h>
  30. #include <linux/acpi.h>
  31. #include <linux/module.h>
  32. #include <linux/init.h>
  33. #include <linux/device.h>
  34. #include <linux/spinlock.h>
  35. #include <linux/workqueue.h>
  36. #define RX_BUF_SIZE PAGE_SIZE
  37. struct mcu_serial_info {
  38. int rx_head;
  39. int rx_tail;
  40. int carback_ready;
  41. unsigned char *rx_buf;
  42. spinlock_t lock;
  43. struct work_struct rx_task;
  44. };
  45. extern int mcu_serial_send(const unsigned char *buf, int len);
  46. extern void mcu_serial_register_rev_handler(void (*handler)(unsigned char ch), struct work_struct *task);
  47. extern void mcu_serial_unregister_rev_handler(void);
  48. #ifdef CONFIG_ARK1668E_CARBACK
  49. extern void get_mcu_carback_data(unsigned char ch);
  50. #endif
  51. static struct mcu_serial_info *msinfo;
  52. #ifdef CONFIG_ARK1668E_CARBACK
  53. void ark_set_track_ready(void)
  54. {
  55. msinfo->carback_ready = 1;
  56. }
  57. EXPORT_SYMBOL(ark_set_track_ready);
  58. void ark_set_track_noready(void)
  59. {
  60. msinfo->carback_ready = 0;
  61. }
  62. EXPORT_SYMBOL(ark_set_track_noready);
  63. #endif
  64. static void mcu_serial_get_ch(unsigned char ch)
  65. {
  66. struct mcu_serial_info *info = msinfo;
  67. unsigned long flags;
  68. spin_lock_irqsave(&info->lock, flags);
  69. //printk(KERN_ALERT "++++++ mcu_serial_get_ch rev ch = %d\n",ch);
  70. info->rx_buf[info->rx_head] = ch;
  71. #ifdef CONFIG_ARK1668E_CARBACK
  72. if(info->carback_ready)
  73. get_mcu_carback_data(info->rx_buf[info->rx_head]);
  74. #endif
  75. info->rx_head = (info->rx_head + 1) & (RX_BUF_SIZE - 1);
  76. if (info->rx_head == info->rx_tail) {
  77. printk("rev buf is full, lost ch.\n");
  78. if (--info->rx_head < 0)
  79. info->rx_head = RX_BUF_SIZE - 1;
  80. }
  81. spin_unlock_irqrestore(&info->lock, flags);
  82. }
  83. static void mcu_serial_rx_task(struct work_struct *work)
  84. {
  85. struct mcu_serial_info *info =
  86. container_of(work, struct mcu_serial_info, rx_task);
  87. int count;
  88. unsigned long flags;
  89. spin_lock_irqsave(&info->lock, flags);
  90. count = info->rx_head - info->rx_tail;
  91. spin_unlock_irqrestore(&info->lock, flags);
  92. if (count < 0)
  93. count += RX_BUF_SIZE;
  94. printk("rx count=%d.\n", count);
  95. }
  96. static int ark_mcu_serial_probe(struct platform_device *pdev)
  97. {
  98. struct mcu_serial_info *info = devm_kzalloc(&pdev->dev, sizeof(struct mcu_serial_info),
  99. GFP_KERNEL);
  100. if (!info)
  101. return -ENOMEM;
  102. info->rx_buf = devm_kzalloc(&pdev->dev, RX_BUF_SIZE, GFP_KERNEL);
  103. if (!info->rx_buf)
  104. return -ENOMEM;
  105. msinfo = info;
  106. info->carback_ready = 0;
  107. spin_lock_init(&info->lock);
  108. INIT_WORK(&info->rx_task, mcu_serial_rx_task);
  109. mcu_serial_register_rev_handler(mcu_serial_get_ch, &info->rx_task);
  110. platform_set_drvdata(pdev, info);
  111. printk(KERN_ALERT "enable get mcu data\n");
  112. return 0;
  113. }
  114. static int ark_mcu_serial_remove(struct platform_device *pdev)
  115. {
  116. struct mcu_serial_info *info = platform_get_drvdata(pdev);
  117. cancel_work_sync(&info->rx_task);
  118. mcu_serial_unregister_rev_handler();
  119. return 0;
  120. }
  121. static const struct of_device_id ark_mcu_serial_of_match[] = {
  122. { .compatible = "arkmicro,ark-mcu-serial", },
  123. {},
  124. };
  125. static struct platform_driver ark_mcu_serial_platform_driver = {
  126. .probe = ark_mcu_serial_probe,
  127. .remove = ark_mcu_serial_remove,
  128. .driver = {
  129. .name = "ark-mcu-serial",
  130. .of_match_table = of_match_ptr(ark_mcu_serial_of_match),
  131. },
  132. };
  133. static int __init ark_mcu_serial_init(void)
  134. {
  135. return platform_driver_register(&ark_mcu_serial_platform_driver);
  136. }
  137. static void __exit ark_mcu_serial_exit(void)
  138. {
  139. platform_driver_unregister(&ark_mcu_serial_platform_driver);
  140. }
  141. /*
  142. * While this can be a module, if builtin it's most likely the console
  143. * So let's leave module_exit but move module_init to an earlier place
  144. */
  145. arch_initcall(ark_mcu_serial_init);
  146. module_exit(ark_mcu_serial_exit);
  147. MODULE_AUTHOR("Sim");
  148. MODULE_DESCRIPTION("Arkmicro mcu serial driver");
  149. MODULE_LICENSE("GPL v2");