PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/media/dvb/mantis/mantis_uart.c

https://bitbucket.org/abioy/linux
C | 186 lines | 123 code | 37 blank | 26 comment | 6 complexity | df1124bec69595e146251450e62c1e7a MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. Mantis PCI bridge driver
  3. Copyright (C) Manu Abraham (abraham.manu@gmail.com)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/signal.h>
  19. #include <linux/sched.h>
  20. #include <linux/interrupt.h>
  21. #include "dmxdev.h"
  22. #include "dvbdev.h"
  23. #include "dvb_demux.h"
  24. #include "dvb_frontend.h"
  25. #include "dvb_net.h"
  26. #include "mantis_common.h"
  27. #include "mantis_reg.h"
  28. #include "mantis_uart.h"
  29. struct mantis_uart_params {
  30. enum mantis_baud baud_rate;
  31. enum mantis_parity parity;
  32. };
  33. static struct {
  34. char string[7];
  35. } rates[5] = {
  36. { "9600" },
  37. { "19200" },
  38. { "38400" },
  39. { "57600" },
  40. { "115200" }
  41. };
  42. static struct {
  43. char string[5];
  44. } parity[3] = {
  45. { "NONE" },
  46. { "ODD" },
  47. { "EVEN" }
  48. };
  49. #define UART_MAX_BUF 16
  50. int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
  51. {
  52. struct mantis_hwconfig *config = mantis->hwconfig;
  53. u32 stat = 0, i;
  54. /* get data */
  55. for (i = 0; i < (config->bytes + 1); i++) {
  56. stat = mmread(MANTIS_UART_STAT);
  57. if (stat & MANTIS_UART_RXFIFO_FULL) {
  58. dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
  59. }
  60. data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
  61. dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
  62. if (data[i] & (1 << 7)) {
  63. dprintk(MANTIS_ERROR, 1, "UART framing error");
  64. return -EINVAL;
  65. }
  66. if (data[i] & (1 << 6)) {
  67. dprintk(MANTIS_ERROR, 1, "UART parity error");
  68. return -EINVAL;
  69. }
  70. }
  71. return 0;
  72. }
  73. static void mantis_uart_work(struct work_struct *work)
  74. {
  75. struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
  76. struct mantis_hwconfig *config = mantis->hwconfig;
  77. u8 buf[16];
  78. int i;
  79. mantis_uart_read(mantis, buf);
  80. for (i = 0; i < (config->bytes + 1); i++)
  81. dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
  82. dprintk(MANTIS_DEBUG, 0, "\n");
  83. }
  84. static int mantis_uart_setup(struct mantis_pci *mantis,
  85. struct mantis_uart_params *params)
  86. {
  87. u32 reg;
  88. mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
  89. reg = mmread(MANTIS_UART_BAUD);
  90. switch (params->baud_rate) {
  91. case MANTIS_BAUD_9600:
  92. reg |= 0xd8;
  93. break;
  94. case MANTIS_BAUD_19200:
  95. reg |= 0x6c;
  96. break;
  97. case MANTIS_BAUD_38400:
  98. reg |= 0x36;
  99. break;
  100. case MANTIS_BAUD_57600:
  101. reg |= 0x23;
  102. break;
  103. case MANTIS_BAUD_115200:
  104. reg |= 0x11;
  105. break;
  106. default:
  107. return -EINVAL;
  108. }
  109. mmwrite(reg, MANTIS_UART_BAUD);
  110. return 0;
  111. }
  112. int mantis_uart_init(struct mantis_pci *mantis)
  113. {
  114. struct mantis_hwconfig *config = mantis->hwconfig;
  115. struct mantis_uart_params params;
  116. /* default parity: */
  117. params.baud_rate = config->baud_rate;
  118. params.parity = config->parity;
  119. dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
  120. rates[params.baud_rate].string,
  121. parity[params.parity].string);
  122. init_waitqueue_head(&mantis->uart_wq);
  123. spin_lock_init(&mantis->uart_lock);
  124. INIT_WORK(&mantis->uart_work, mantis_uart_work);
  125. /* disable interrupt */
  126. mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
  127. mantis_uart_setup(mantis, &params);
  128. /* default 1 byte */
  129. mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
  130. /* flush buffer */
  131. mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
  132. /* enable interrupt */
  133. mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
  134. mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
  135. schedule_work(&mantis->uart_work);
  136. dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized");
  137. return 0;
  138. }
  139. EXPORT_SYMBOL_GPL(mantis_uart_init);
  140. void mantis_uart_exit(struct mantis_pci *mantis)
  141. {
  142. /* disable interrupt */
  143. mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
  144. }
  145. EXPORT_SYMBOL_GPL(mantis_uart_exit);