dibx000_common.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include <linux/i2c.h>
  2. #include "dibx000_common.h"
  3. static int debug;
  4. module_param(debug, int, 0644);
  5. MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  6. #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
  7. static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
  8. {
  9. u8 b[4] = {
  10. (reg >> 8) & 0xff, reg & 0xff,
  11. (val >> 8) & 0xff, val & 0xff,
  12. };
  13. struct i2c_msg msg = {
  14. .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
  15. };
  16. return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
  17. }
  18. static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
  19. enum dibx000_i2c_interface intf)
  20. {
  21. if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
  22. dprintk("selecting interface: %d", intf);
  23. mst->selected_interface = intf;
  24. return dibx000_write_word(mst, mst->base_reg + 4, intf);
  25. }
  26. return 0;
  27. }
  28. static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
  29. u8 addr, int onoff)
  30. {
  31. u16 val;
  32. if (onoff)
  33. val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
  34. else
  35. val = 1 << 7;
  36. if (mst->device_rev > DIB7000)
  37. val <<= 1;
  38. tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
  39. tx[1] = ((mst->base_reg + 1) & 0xff);
  40. tx[2] = val >> 8;
  41. tx[3] = val & 0xff;
  42. return 0;
  43. }
  44. static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
  45. {
  46. return I2C_FUNC_I2C;
  47. }
  48. static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
  49. struct i2c_msg msg[], int num)
  50. {
  51. struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
  52. struct i2c_msg m[2 + num];
  53. u8 tx_open[4], tx_close[4];
  54. memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
  55. dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
  56. dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
  57. m[0].addr = mst->i2c_addr;
  58. m[0].buf = tx_open;
  59. m[0].len = 4;
  60. memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
  61. dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
  62. m[num + 1].addr = mst->i2c_addr;
  63. m[num + 1].buf = tx_close;
  64. m[num + 1].len = 4;
  65. return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
  66. }
  67. static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
  68. .master_xfer = dibx000_i2c_gated_tuner_xfer,
  69. .functionality = dibx000_i2c_func,
  70. };
  71. struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
  72. enum dibx000_i2c_interface intf,
  73. int gating)
  74. {
  75. struct i2c_adapter *i2c = NULL;
  76. switch (intf) {
  77. case DIBX000_I2C_INTERFACE_TUNER:
  78. if (gating)
  79. i2c = &mst->gated_tuner_i2c_adap;
  80. break;
  81. default:
  82. printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
  83. break;
  84. }
  85. return i2c;
  86. }
  87. EXPORT_SYMBOL(dibx000_get_i2c_adapter);
  88. void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
  89. {
  90. /* initialize the i2c-master by closing the gate */
  91. u8 tx[4];
  92. struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
  93. dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
  94. i2c_transfer(mst->i2c_adap, &m, 1);
  95. mst->selected_interface = 0xff; // the first time force a select of the I2C
  96. dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
  97. }
  98. EXPORT_SYMBOL(dibx000_reset_i2c_master);
  99. static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
  100. struct i2c_algorithm *algo, const char *name,
  101. struct dibx000_i2c_master *mst)
  102. {
  103. strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
  104. i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
  105. i2c_adap->algo_data = NULL;
  106. i2c_set_adapdata(i2c_adap, mst);
  107. if (i2c_add_adapter(i2c_adap) < 0)
  108. return -ENODEV;
  109. return 0;
  110. }
  111. int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
  112. struct i2c_adapter *i2c_adap, u8 i2c_addr)
  113. {
  114. u8 tx[4];
  115. struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
  116. mst->device_rev = device_rev;
  117. mst->i2c_adap = i2c_adap;
  118. mst->i2c_addr = i2c_addr >> 1;
  119. if (device_rev == DIB7000P || device_rev == DIB8000)
  120. mst->base_reg = 1024;
  121. else
  122. mst->base_reg = 768;
  123. if (i2c_adapter_init
  124. (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
  125. "DiBX000 tuner I2C bus", mst) != 0)
  126. printk(KERN_ERR
  127. "DiBX000: could not initialize the tuner i2c_adapter\n");
  128. /* initialize the i2c-master by closing the gate */
  129. dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
  130. return i2c_transfer(i2c_adap, &m, 1) == 1;
  131. }
  132. EXPORT_SYMBOL(dibx000_init_i2c_master);
  133. void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
  134. {
  135. i2c_del_adapter(&mst->gated_tuner_i2c_adap);
  136. }
  137. EXPORT_SYMBOL(dibx000_exit_i2c_master);
  138. u32 systime()
  139. {
  140. struct timespec t;
  141. t = current_kernel_time();
  142. return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
  143. }
  144. EXPORT_SYMBOL(systime);
  145. MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
  146. MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
  147. MODULE_LICENSE("GPL");