cx23885-f300.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29. */
  30. #include "cx23885.h"
  31. #define F300_DATA GPIO_0
  32. #define F300_RESET GPIO_1
  33. #define F300_CLK GPIO_2
  34. #define F300_BUSY GPIO_3
  35. static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
  36. {
  37. cx23885_gpio_enable(dev, line, 1);
  38. if (lvl == 1)
  39. cx23885_gpio_set(dev, line);
  40. else
  41. cx23885_gpio_clear(dev, line);
  42. }
  43. static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
  44. {
  45. cx23885_gpio_enable(dev, line, 0);
  46. return cx23885_gpio_get(dev, line);
  47. }
  48. static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
  49. {
  50. u8 i;
  51. for (i = 0; i < 8; i++) {
  52. f300_set_line(dev, F300_CLK, 0);
  53. udelay(30);
  54. f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
  55. udelay(30);
  56. dta <<= 1;
  57. f300_set_line(dev, F300_CLK, 1);
  58. udelay(30);
  59. }
  60. }
  61. static u8 f300_get_byte(struct cx23885_dev *dev)
  62. {
  63. u8 i, dta = 0;
  64. for (i = 0; i < 8; i++) {
  65. f300_set_line(dev, F300_CLK, 0);
  66. udelay(30);
  67. dta <<= 1;
  68. f300_set_line(dev, F300_CLK, 1);
  69. udelay(30);
  70. dta |= f300_get_line(dev, F300_DATA);/* msb first */
  71. }
  72. return dta;
  73. }
  74. static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
  75. {
  76. struct cx23885_tsport *port = fe->dvb->priv;
  77. struct cx23885_dev *dev = port->dev;
  78. u8 i, temp, ret = 0;
  79. temp = buf[0];
  80. for (i = 0; i < buf[0]; i++)
  81. temp += buf[i + 1];
  82. temp = (~temp + 1);/* get check sum */
  83. buf[1 + buf[0]] = temp;
  84. f300_set_line(dev, F300_RESET, 1);
  85. f300_set_line(dev, F300_CLK, 1);
  86. udelay(30);
  87. f300_set_line(dev, F300_DATA, 1);
  88. msleep(1);
  89. /* question: */
  90. f300_set_line(dev, F300_RESET, 0);/* begin to send data */
  91. msleep(1);
  92. f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
  93. msleep(1);
  94. temp = buf[0];
  95. temp += 2;
  96. for (i = 0; i < temp; i++)
  97. f300_send_byte(dev, buf[i]);
  98. f300_set_line(dev, F300_RESET, 1);/* sent data over */
  99. f300_set_line(dev, F300_DATA, 1);
  100. /* answer: */
  101. temp = 0;
  102. for (i = 0; ((i < 8) & (temp == 0)); i++) {
  103. msleep(1);
  104. if (f300_get_line(dev, F300_BUSY) == 0)
  105. temp = 1;
  106. }
  107. if (i > 7) {
  108. printk(KERN_ERR "%s: timeout, the slave no response\n",
  109. __func__);
  110. ret = 1; /* timeout, the slave no response */
  111. } else { /* the slave not busy, prepare for getting data */
  112. f300_set_line(dev, F300_RESET, 0);/*ready...*/
  113. msleep(1);
  114. f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
  115. msleep(1);
  116. temp = f300_get_byte(dev);/*get the data length */
  117. if (temp > 14)
  118. temp = 14;
  119. for (i = 0; i < (temp + 1); i++)
  120. f300_get_byte(dev);/* get data to empty buffer */
  121. f300_set_line(dev, F300_RESET, 1);/* received data over */
  122. f300_set_line(dev, F300_DATA, 1);
  123. }
  124. return ret;
  125. }
  126. int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
  127. {
  128. u8 buf[16];
  129. buf[0] = 0x05;
  130. buf[1] = 0x38;/* write port */
  131. buf[2] = 0x01;/* A port, lnb power */
  132. switch (voltage) {
  133. case SEC_VOLTAGE_13:
  134. buf[3] = 0x01;/* power on */
  135. buf[4] = 0x02;/* B port, H/V */
  136. buf[5] = 0x00;/*13V v*/
  137. break;
  138. case SEC_VOLTAGE_18:
  139. buf[3] = 0x01;
  140. buf[4] = 0x02;
  141. buf[5] = 0x01;/* 18V h*/
  142. break;
  143. case SEC_VOLTAGE_OFF:
  144. buf[3] = 0x00;/* power off */
  145. buf[4] = 0x00;
  146. buf[5] = 0x00;
  147. break;
  148. }
  149. return f300_xfer(fe, buf);
  150. }