firedtv-dvb.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * FireDTV driver (formerly known as FireSAT)
  3. *
  4. * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
  5. * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. */
  12. #include <linux/bitops.h>
  13. #include <linux/device.h>
  14. #include <linux/errno.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/mutex.h>
  18. #include <linux/types.h>
  19. #include <media/dmxdev.h>
  20. #include <media/dvb_demux.h>
  21. #include <media/dvbdev.h>
  22. #include <media/dvb_frontend.h>
  23. #include "firedtv.h"
  24. static int alloc_channel(struct firedtv *fdtv)
  25. {
  26. int i;
  27. for (i = 0; i < 16; i++)
  28. if (!__test_and_set_bit(i, &fdtv->channel_active))
  29. break;
  30. return i;
  31. }
  32. static void collect_channels(struct firedtv *fdtv, int *pidc, u16 pid[])
  33. {
  34. int i, n;
  35. for (i = 0, n = 0; i < 16; i++)
  36. if (test_bit(i, &fdtv->channel_active))
  37. pid[n++] = fdtv->channel_pid[i];
  38. *pidc = n;
  39. }
  40. static inline void dealloc_channel(struct firedtv *fdtv, int i)
  41. {
  42. __clear_bit(i, &fdtv->channel_active);
  43. }
  44. int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
  45. {
  46. struct firedtv *fdtv = dvbdmxfeed->demux->priv;
  47. int pidc, c, ret;
  48. u16 pids[16];
  49. switch (dvbdmxfeed->type) {
  50. case DMX_TYPE_TS:
  51. case DMX_TYPE_SEC:
  52. break;
  53. default:
  54. dev_err(fdtv->device, "can't start dmx feed: invalid type %u\n",
  55. dvbdmxfeed->type);
  56. return -EINVAL;
  57. }
  58. if (mutex_lock_interruptible(&fdtv->demux_mutex))
  59. return -EINTR;
  60. if (dvbdmxfeed->type == DMX_TYPE_TS) {
  61. switch (dvbdmxfeed->pes_type) {
  62. case DMX_PES_VIDEO:
  63. case DMX_PES_AUDIO:
  64. case DMX_PES_TELETEXT:
  65. case DMX_PES_PCR:
  66. case DMX_PES_OTHER:
  67. c = alloc_channel(fdtv);
  68. break;
  69. default:
  70. dev_err(fdtv->device,
  71. "can't start dmx feed: invalid pes type %u\n",
  72. dvbdmxfeed->pes_type);
  73. ret = -EINVAL;
  74. goto out;
  75. }
  76. } else {
  77. c = alloc_channel(fdtv);
  78. }
  79. if (c > 15) {
  80. dev_err(fdtv->device, "can't start dmx feed: busy\n");
  81. ret = -EBUSY;
  82. goto out;
  83. }
  84. dvbdmxfeed->priv = (typeof(dvbdmxfeed->priv))(unsigned long)c;
  85. fdtv->channel_pid[c] = dvbdmxfeed->pid;
  86. collect_channels(fdtv, &pidc, pids);
  87. if (dvbdmxfeed->pid == 8192) {
  88. ret = avc_tuner_get_ts(fdtv);
  89. if (ret) {
  90. dealloc_channel(fdtv, c);
  91. dev_err(fdtv->device, "can't get TS\n");
  92. goto out;
  93. }
  94. } else {
  95. ret = avc_tuner_set_pids(fdtv, pidc, pids);
  96. if (ret) {
  97. dealloc_channel(fdtv, c);
  98. dev_err(fdtv->device, "can't set PIDs\n");
  99. goto out;
  100. }
  101. }
  102. out:
  103. mutex_unlock(&fdtv->demux_mutex);
  104. return ret;
  105. }
  106. int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
  107. {
  108. struct dvb_demux *demux = dvbdmxfeed->demux;
  109. struct firedtv *fdtv = demux->priv;
  110. int pidc, c, ret;
  111. u16 pids[16];
  112. if (dvbdmxfeed->type == DMX_TYPE_TS &&
  113. !((dvbdmxfeed->ts_type & TS_PACKET) &&
  114. (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
  115. if (dvbdmxfeed->ts_type & TS_DECODER) {
  116. if (dvbdmxfeed->pes_type >= DMX_PES_OTHER ||
  117. !demux->pesfilter[dvbdmxfeed->pes_type])
  118. return -EINVAL;
  119. demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
  120. demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
  121. }
  122. if (!(dvbdmxfeed->ts_type & TS_DECODER &&
  123. dvbdmxfeed->pes_type < DMX_PES_OTHER))
  124. return 0;
  125. }
  126. if (mutex_lock_interruptible(&fdtv->demux_mutex))
  127. return -EINTR;
  128. c = (unsigned long)dvbdmxfeed->priv;
  129. dealloc_channel(fdtv, c);
  130. collect_channels(fdtv, &pidc, pids);
  131. ret = avc_tuner_set_pids(fdtv, pidc, pids);
  132. mutex_unlock(&fdtv->demux_mutex);
  133. return ret;
  134. }
  135. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  136. int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
  137. {
  138. int err;
  139. err = dvb_register_adapter(&fdtv->adapter, name,
  140. THIS_MODULE, fdtv->device, adapter_nr);
  141. if (err < 0)
  142. goto fail_log;
  143. /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
  144. fdtv->demux.dmx.capabilities = 0;
  145. fdtv->demux.priv = fdtv;
  146. fdtv->demux.filternum = 16;
  147. fdtv->demux.feednum = 16;
  148. fdtv->demux.start_feed = fdtv_start_feed;
  149. fdtv->demux.stop_feed = fdtv_stop_feed;
  150. fdtv->demux.write_to_decoder = NULL;
  151. err = dvb_dmx_init(&fdtv->demux);
  152. if (err)
  153. goto fail_unreg_adapter;
  154. fdtv->dmxdev.filternum = 16;
  155. fdtv->dmxdev.demux = &fdtv->demux.dmx;
  156. fdtv->dmxdev.capabilities = 0;
  157. err = dvb_dmxdev_init(&fdtv->dmxdev, &fdtv->adapter);
  158. if (err)
  159. goto fail_dmx_release;
  160. fdtv->frontend.source = DMX_FRONTEND_0;
  161. err = fdtv->demux.dmx.add_frontend(&fdtv->demux.dmx, &fdtv->frontend);
  162. if (err)
  163. goto fail_dmxdev_release;
  164. err = fdtv->demux.dmx.connect_frontend(&fdtv->demux.dmx,
  165. &fdtv->frontend);
  166. if (err)
  167. goto fail_rem_frontend;
  168. err = dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
  169. if (err)
  170. goto fail_disconnect_frontend;
  171. fdtv_frontend_init(fdtv, name);
  172. err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
  173. if (err)
  174. goto fail_net_release;
  175. err = fdtv_ca_register(fdtv);
  176. if (err)
  177. dev_info(fdtv->device,
  178. "Conditional Access Module not enabled\n");
  179. return 0;
  180. fail_net_release:
  181. dvb_net_release(&fdtv->dvbnet);
  182. fail_disconnect_frontend:
  183. fdtv->demux.dmx.close(&fdtv->demux.dmx);
  184. fail_rem_frontend:
  185. fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
  186. fail_dmxdev_release:
  187. dvb_dmxdev_release(&fdtv->dmxdev);
  188. fail_dmx_release:
  189. dvb_dmx_release(&fdtv->demux);
  190. fail_unreg_adapter:
  191. dvb_unregister_adapter(&fdtv->adapter);
  192. fail_log:
  193. dev_err(fdtv->device, "DVB initialization failed\n");
  194. return err;
  195. }
  196. void fdtv_dvb_unregister(struct firedtv *fdtv)
  197. {
  198. fdtv_ca_release(fdtv);
  199. dvb_unregister_frontend(&fdtv->fe);
  200. dvb_net_release(&fdtv->dvbnet);
  201. fdtv->demux.dmx.close(&fdtv->demux.dmx);
  202. fdtv->demux.dmx.remove_frontend(&fdtv->demux.dmx, &fdtv->frontend);
  203. dvb_dmxdev_release(&fdtv->dmxdev);
  204. dvb_dmx_release(&fdtv->demux);
  205. dvb_unregister_adapter(&fdtv->adapter);
  206. }