cx23885-f300.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Driver for Silicon Labs C8051F300 microcontroller.
  3. *
  4. * It is used for LNB power control in TeVii S470,
  5. * TBS 6920 PCIe DVB-S2 cards.
  6. *
  7. * Microcontroller connected to cx23885 GPIO pins:
  8. * GPIO0 - data - P0.3 F300
  9. * GPIO1 - reset - P0.2 F300
  10. * GPIO2 - clk - P0.1 F300
  11. * GPIO3 - busy - P0.0 F300
  12. *
  13. * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation; either version 2 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. *
  24. * GNU General Public License for more details.
  25. */
  26. #include "cx23885.h"
  27. #include "cx23885-f300.h"
  28. #define F300_DATA GPIO_0
  29. #define F300_RESET GPIO_1
  30. #define F300_CLK GPIO_2
  31. #define F300_BUSY GPIO_3
  32. static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
  33. {
  34. cx23885_gpio_enable(dev, line, 1);
  35. if (lvl == 1)
  36. cx23885_gpio_set(dev, line);
  37. else
  38. cx23885_gpio_clear(dev, line);
  39. }
  40. static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
  41. {
  42. cx23885_gpio_enable(dev, line, 0);
  43. return cx23885_gpio_get(dev, line);
  44. }
  45. static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
  46. {
  47. u8 i;
  48. for (i = 0; i < 8; i++) {
  49. f300_set_line(dev, F300_CLK, 0);
  50. udelay(30);
  51. f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
  52. udelay(30);
  53. dta <<= 1;
  54. f300_set_line(dev, F300_CLK, 1);
  55. udelay(30);
  56. }
  57. }
  58. static u8 f300_get_byte(struct cx23885_dev *dev)
  59. {
  60. u8 i, dta = 0;
  61. for (i = 0; i < 8; i++) {
  62. f300_set_line(dev, F300_CLK, 0);
  63. udelay(30);
  64. dta <<= 1;
  65. f300_set_line(dev, F300_CLK, 1);
  66. udelay(30);
  67. dta |= f300_get_line(dev, F300_DATA);/* msb first */
  68. }
  69. return dta;
  70. }
  71. static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
  72. {
  73. struct cx23885_tsport *port = fe->dvb->priv;
  74. struct cx23885_dev *dev = port->dev;
  75. u8 i, temp, ret = 0;
  76. temp = buf[0];
  77. for (i = 0; i < buf[0]; i++)
  78. temp += buf[i + 1];
  79. temp = (~temp + 1);/* get check sum */
  80. buf[1 + buf[0]] = temp;
  81. f300_set_line(dev, F300_RESET, 1);
  82. f300_set_line(dev, F300_CLK, 1);
  83. udelay(30);
  84. f300_set_line(dev, F300_DATA, 1);
  85. msleep(1);
  86. /* question: */
  87. f300_set_line(dev, F300_RESET, 0);/* begin to send data */
  88. msleep(1);
  89. f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
  90. msleep(1);
  91. temp = buf[0];
  92. temp += 2;
  93. for (i = 0; i < temp; i++)
  94. f300_send_byte(dev, buf[i]);
  95. f300_set_line(dev, F300_RESET, 1);/* sent data over */
  96. f300_set_line(dev, F300_DATA, 1);
  97. /* answer: */
  98. temp = 0;
  99. for (i = 0; ((i < 8) & (temp == 0)); i++) {
  100. msleep(1);
  101. if (f300_get_line(dev, F300_BUSY) == 0)
  102. temp = 1;
  103. }
  104. if (i > 7) {
  105. printk(KERN_ERR "%s: timeout, the slave no response\n",
  106. __func__);
  107. ret = 1; /* timeout, the slave no response */
  108. } else { /* the slave not busy, prepare for getting data */
  109. f300_set_line(dev, F300_RESET, 0);/*ready...*/
  110. msleep(1);
  111. f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
  112. msleep(1);
  113. temp = f300_get_byte(dev);/*get the data length */
  114. if (temp > 14)
  115. temp = 14;
  116. for (i = 0; i < (temp + 1); i++)
  117. f300_get_byte(dev);/* get data to empty buffer */
  118. f300_set_line(dev, F300_RESET, 1);/* received data over */
  119. f300_set_line(dev, F300_DATA, 1);
  120. }
  121. return ret;
  122. }
  123. int f300_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
  124. {
  125. u8 buf[16];
  126. buf[0] = 0x05;
  127. buf[1] = 0x38;/* write port */
  128. buf[2] = 0x01;/* A port, lnb power */
  129. switch (voltage) {
  130. case SEC_VOLTAGE_13:
  131. buf[3] = 0x01;/* power on */
  132. buf[4] = 0x02;/* B port, H/V */
  133. buf[5] = 0x00;/*13V v*/
  134. break;
  135. case SEC_VOLTAGE_18:
  136. buf[3] = 0x01;
  137. buf[4] = 0x02;
  138. buf[5] = 0x01;/* 18V h*/
  139. break;
  140. case SEC_VOLTAGE_OFF:
  141. buf[3] = 0x00;/* power off */
  142. buf[4] = 0x00;
  143. buf[5] = 0x00;
  144. break;
  145. }
  146. return f300_xfer(fe, buf);
  147. }