diseqc.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <linux/dvb/frontend.h>
  2. #include <sys/ioctl.h>
  3. #include <time.h>
  4. #include "scan.h"
  5. #include "diseqc.h"
  6. struct diseqc_cmd switch_cmds[] = {
  7. { { { 0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00 }, 4 }, 0 },
  8. { { { 0xe0, 0x10, 0x38, 0xf2, 0x00, 0x00 }, 4 }, 0 },
  9. { { { 0xe0, 0x10, 0x38, 0xf1, 0x00, 0x00 }, 4 }, 0 },
  10. { { { 0xe0, 0x10, 0x38, 0xf3, 0x00, 0x00 }, 4 }, 0 },
  11. { { { 0xe0, 0x10, 0x38, 0xf4, 0x00, 0x00 }, 4 }, 0 },
  12. { { { 0xe0, 0x10, 0x38, 0xf6, 0x00, 0x00 }, 4 }, 0 },
  13. { { { 0xe0, 0x10, 0x38, 0xf5, 0x00, 0x00 }, 4 }, 0 },
  14. { { { 0xe0, 0x10, 0x38, 0xf7, 0x00, 0x00 }, 4 }, 0 },
  15. { { { 0xe0, 0x10, 0x38, 0xf8, 0x00, 0x00 }, 4 }, 0 },
  16. { { { 0xe0, 0x10, 0x38, 0xfa, 0x00, 0x00 }, 4 }, 0 },
  17. { { { 0xe0, 0x10, 0x38, 0xf9, 0x00, 0x00 }, 4 }, 0 },
  18. { { { 0xe0, 0x10, 0x38, 0xfb, 0x00, 0x00 }, 4 }, 0 },
  19. { { { 0xe0, 0x10, 0x38, 0xfc, 0x00, 0x00 }, 4 }, 0 },
  20. { { { 0xe0, 0x10, 0x38, 0xfe, 0x00, 0x00 }, 4 }, 0 },
  21. { { { 0xe0, 0x10, 0x38, 0xfd, 0x00, 0x00 }, 4 }, 0 },
  22. { { { 0xe0, 0x10, 0x38, 0xff, 0x00, 0x00 }, 4 }, 0 }
  23. };
  24. /*--------------------------------------------------------------------------*/
  25. static inline
  26. void msleep(uint32_t msec)
  27. {
  28. struct timespec req = { msec / 1000, 1000000 * (msec % 1000) };
  29. while (nanosleep(&req, &req))
  30. ;
  31. }
  32. int diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd,
  33. fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
  34. {
  35. int err;
  36. if ((err = ioctl(fd, FE_SET_TONE, SEC_TONE_OFF)))
  37. return err;
  38. if ((err = ioctl(fd, FE_SET_VOLTAGE, v)))
  39. return err;
  40. msleep(15);
  41. while (*cmd) {
  42. debug("DiSEqC: %02x %02x %02x %02x %02x %02x\n",
  43. (*cmd)->cmd.msg[0], (*cmd)->cmd.msg[1],
  44. (*cmd)->cmd.msg[2], (*cmd)->cmd.msg[3],
  45. (*cmd)->cmd.msg[4], (*cmd)->cmd.msg[5]);
  46. if ((err = ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &(*cmd)->cmd)))
  47. return err;
  48. msleep((*cmd)->wait);
  49. cmd++;
  50. }
  51. //debug(" %s ", v == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
  52. // v == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "???");
  53. //debug(" %s ", b == SEC_MINI_A ? "SEC_MINI_A" :
  54. // b == SEC_MINI_B ? "SEC_MINI_B" : "???");
  55. //debug(" %s\n", t == SEC_TONE_ON ? "SEC_TONE_ON" :
  56. // t == SEC_TONE_OFF ? "SEC_TONE_OFF" : "???");
  57. msleep(15);
  58. if ((err = ioctl(fd, FE_DISEQC_SEND_BURST, b)))
  59. return err;
  60. msleep(15);
  61. return ioctl(fd, FE_SET_TONE, t);
  62. }
  63. int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int hiband)
  64. {
  65. struct diseqc_cmd *cmd[2] = { NULL, NULL };
  66. int i = 4 * switch_pos + 2 * hiband + (voltage_18 ? 1 : 0);
  67. verbose("DiSEqC: switch pos %i, %sV, %sband (index %d)\n",
  68. switch_pos, voltage_18 ? "18" : "13", hiband ? "hi" : "lo", i);
  69. if (i < 0 || i >= (int) (sizeof(switch_cmds)/sizeof(struct diseqc_cmd)))
  70. return -EINVAL;
  71. cmd[0] = &switch_cmds[i];
  72. return diseqc_send_msg (frontend_fd,
  73. i % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13,
  74. cmd,
  75. (i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF,
  76. (i/4) % 2 ? SEC_MINI_B : SEC_MINI_A);
  77. }