stb6000.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. Driver for ST STB6000 DVBS Silicon tuner
  4. Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
  5. */
  6. #include <linux/slab.h>
  7. #include <linux/module.h>
  8. #include <linux/dvb/frontend.h>
  9. #include <asm/types.h>
  10. #include "stb6000.h"
  11. static int debug;
  12. #define dprintk(args...) \
  13. do { \
  14. if (debug) \
  15. printk(KERN_DEBUG "stb6000: " args); \
  16. } while (0)
  17. struct stb6000_priv {
  18. /* i2c details */
  19. int i2c_address;
  20. struct i2c_adapter *i2c;
  21. u32 frequency;
  22. };
  23. static void stb6000_release(struct dvb_frontend *fe)
  24. {
  25. kfree(fe->tuner_priv);
  26. fe->tuner_priv = NULL;
  27. }
  28. static int stb6000_sleep(struct dvb_frontend *fe)
  29. {
  30. struct stb6000_priv *priv = fe->tuner_priv;
  31. int ret;
  32. u8 buf[] = { 10, 0 };
  33. struct i2c_msg msg = {
  34. .addr = priv->i2c_address,
  35. .flags = 0,
  36. .buf = buf,
  37. .len = 2
  38. };
  39. dprintk("%s:\n", __func__);
  40. if (fe->ops.i2c_gate_ctrl)
  41. fe->ops.i2c_gate_ctrl(fe, 1);
  42. ret = i2c_transfer(priv->i2c, &msg, 1);
  43. if (ret != 1)
  44. dprintk("%s: i2c error\n", __func__);
  45. if (fe->ops.i2c_gate_ctrl)
  46. fe->ops.i2c_gate_ctrl(fe, 0);
  47. return (ret == 1) ? 0 : ret;
  48. }
  49. static int stb6000_set_params(struct dvb_frontend *fe)
  50. {
  51. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  52. struct stb6000_priv *priv = fe->tuner_priv;
  53. unsigned int n, m;
  54. int ret;
  55. u32 freq_mhz;
  56. int bandwidth;
  57. u8 buf[12];
  58. struct i2c_msg msg = {
  59. .addr = priv->i2c_address,
  60. .flags = 0,
  61. .buf = buf,
  62. .len = 12
  63. };
  64. dprintk("%s:\n", __func__);
  65. freq_mhz = p->frequency / 1000;
  66. bandwidth = p->symbol_rate / 1000000;
  67. if (bandwidth > 31)
  68. bandwidth = 31;
  69. if ((freq_mhz > 949) && (freq_mhz < 2151)) {
  70. buf[0] = 0x01;
  71. buf[1] = 0xac;
  72. if (freq_mhz < 1950)
  73. buf[1] = 0xaa;
  74. if (freq_mhz < 1800)
  75. buf[1] = 0xa8;
  76. if (freq_mhz < 1650)
  77. buf[1] = 0xa6;
  78. if (freq_mhz < 1530)
  79. buf[1] = 0xa5;
  80. if (freq_mhz < 1470)
  81. buf[1] = 0xa4;
  82. if (freq_mhz < 1370)
  83. buf[1] = 0xa2;
  84. if (freq_mhz < 1300)
  85. buf[1] = 0xa1;
  86. if (freq_mhz < 1200)
  87. buf[1] = 0xa0;
  88. if (freq_mhz < 1075)
  89. buf[1] = 0xbc;
  90. if (freq_mhz < 1000)
  91. buf[1] = 0xba;
  92. if (freq_mhz < 1075) {
  93. n = freq_mhz / 8; /* vco=lo*4 */
  94. m = 2;
  95. } else {
  96. n = freq_mhz / 16; /* vco=lo*2 */
  97. m = 1;
  98. }
  99. buf[2] = n >> 1;
  100. buf[3] = (unsigned char)(((n & 1) << 7) |
  101. (m * freq_mhz - n * 16) | 0x60);
  102. buf[4] = 0x04;
  103. buf[5] = 0x0e;
  104. buf[6] = (unsigned char)(bandwidth);
  105. buf[7] = 0xd8;
  106. buf[8] = 0xd0;
  107. buf[9] = 0x50;
  108. buf[10] = 0xeb;
  109. buf[11] = 0x4f;
  110. if (fe->ops.i2c_gate_ctrl)
  111. fe->ops.i2c_gate_ctrl(fe, 1);
  112. ret = i2c_transfer(priv->i2c, &msg, 1);
  113. if (ret != 1)
  114. dprintk("%s: i2c error\n", __func__);
  115. udelay(10);
  116. if (fe->ops.i2c_gate_ctrl)
  117. fe->ops.i2c_gate_ctrl(fe, 0);
  118. buf[0] = 0x07;
  119. buf[1] = 0xdf;
  120. buf[2] = 0xd0;
  121. buf[3] = 0x50;
  122. buf[4] = 0xfb;
  123. msg.len = 5;
  124. if (fe->ops.i2c_gate_ctrl)
  125. fe->ops.i2c_gate_ctrl(fe, 1);
  126. ret = i2c_transfer(priv->i2c, &msg, 1);
  127. if (ret != 1)
  128. dprintk("%s: i2c error\n", __func__);
  129. udelay(10);
  130. if (fe->ops.i2c_gate_ctrl)
  131. fe->ops.i2c_gate_ctrl(fe, 0);
  132. priv->frequency = freq_mhz * 1000;
  133. return (ret == 1) ? 0 : ret;
  134. }
  135. return -1;
  136. }
  137. static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
  138. {
  139. struct stb6000_priv *priv = fe->tuner_priv;
  140. *frequency = priv->frequency;
  141. return 0;
  142. }
  143. static const struct dvb_tuner_ops stb6000_tuner_ops = {
  144. .info = {
  145. .name = "ST STB6000",
  146. .frequency_min_hz = 950 * MHz,
  147. .frequency_max_hz = 2150 * MHz
  148. },
  149. .release = stb6000_release,
  150. .sleep = stb6000_sleep,
  151. .set_params = stb6000_set_params,
  152. .get_frequency = stb6000_get_frequency,
  153. };
  154. struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
  155. struct i2c_adapter *i2c)
  156. {
  157. struct stb6000_priv *priv = NULL;
  158. u8 b0[] = { 0 };
  159. u8 b1[] = { 0, 0 };
  160. struct i2c_msg msg[2] = {
  161. {
  162. .addr = addr,
  163. .flags = 0,
  164. .buf = b0,
  165. .len = 0
  166. }, {
  167. .addr = addr,
  168. .flags = I2C_M_RD,
  169. .buf = b1,
  170. .len = 2
  171. }
  172. };
  173. int ret;
  174. dprintk("%s:\n", __func__);
  175. if (fe->ops.i2c_gate_ctrl)
  176. fe->ops.i2c_gate_ctrl(fe, 1);
  177. /* is some i2c device here ? */
  178. ret = i2c_transfer(i2c, msg, 2);
  179. if (fe->ops.i2c_gate_ctrl)
  180. fe->ops.i2c_gate_ctrl(fe, 0);
  181. if (ret != 2)
  182. return NULL;
  183. priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
  184. if (priv == NULL)
  185. return NULL;
  186. priv->i2c_address = addr;
  187. priv->i2c = i2c;
  188. memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
  189. sizeof(struct dvb_tuner_ops));
  190. fe->tuner_priv = priv;
  191. return fe;
  192. }
  193. EXPORT_SYMBOL(stb6000_attach);
  194. module_param(debug, int, 0644);
  195. MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  196. MODULE_DESCRIPTION("DVB STB6000 driver");
  197. MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
  198. MODULE_LICENSE("GPL");