gp8psk.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /* DVB USB compliant Linux driver for the
  2. * - GENPIX 8pks/qpsk USB2.0 DVB-S module
  3. *
  4. * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
  5. *
  6. * Thanks to GENPIX for the sample code used to implement this module.
  7. *
  8. * This module is based off the vp7045 and vp702x modules
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the Free
  12. * Software Foundation, version 2.
  13. *
  14. * see Documentation/dvb/README.dvb-usb for more information
  15. */
  16. #include "gp8psk.h"
  17. /* debug */
  18. static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
  19. int dvb_usb_gp8psk_debug;
  20. module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
  21. MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
  22. int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
  23. {
  24. int ret = 0,try = 0;
  25. if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
  26. return ret;
  27. while (ret >= 0 && ret != blen && try < 3) {
  28. ret = usb_control_msg(d->udev,
  29. usb_rcvctrlpipe(d->udev,0),
  30. req,
  31. USB_TYPE_VENDOR | USB_DIR_IN,
  32. value,index,b,blen,
  33. 2000);
  34. deb_info("reading number %d (ret: %d)\n",try,ret);
  35. try++;
  36. }
  37. if (ret < 0 || ret != blen) {
  38. warn("usb in operation failed.");
  39. ret = -EIO;
  40. } else
  41. ret = 0;
  42. deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
  43. debug_dump(b,blen,deb_xfer);
  44. mutex_unlock(&d->usb_mutex);
  45. return ret;
  46. }
  47. int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
  48. u16 index, u8 *b, int blen)
  49. {
  50. int ret;
  51. deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
  52. debug_dump(b,blen,deb_xfer);
  53. if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
  54. return ret;
  55. if (usb_control_msg(d->udev,
  56. usb_sndctrlpipe(d->udev,0),
  57. req,
  58. USB_TYPE_VENDOR | USB_DIR_OUT,
  59. value,index,b,blen,
  60. 2000) != blen) {
  61. warn("usb out operation failed.");
  62. ret = -EIO;
  63. } else
  64. ret = 0;
  65. mutex_unlock(&d->usb_mutex);
  66. return ret;
  67. }
  68. static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
  69. {
  70. int ret;
  71. const struct firmware *fw = NULL;
  72. u8 *ptr, *buf;
  73. if ((ret = request_firmware(&fw, bcm4500_firmware,
  74. &d->udev->dev)) != 0) {
  75. err("did not find the bcm4500 firmware file. (%s) "
  76. "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
  77. bcm4500_firmware,ret);
  78. return ret;
  79. }
  80. ret = -EINVAL;
  81. if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
  82. goto out_rel_fw;
  83. info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
  84. ptr = fw->data;
  85. buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
  86. while (ptr[0] != 0xff) {
  87. u16 buflen = ptr[0] + 4;
  88. if (ptr + buflen >= fw->data + fw->size) {
  89. err("failed to load bcm4500 firmware.");
  90. goto out_free;
  91. }
  92. memcpy(buf, ptr, buflen);
  93. if (dvb_usb_generic_write(d, buf, buflen)) {
  94. err("failed to load bcm4500 firmware.");
  95. goto out_free;
  96. }
  97. ptr += buflen;
  98. }
  99. ret = 0;
  100. out_free:
  101. kfree(buf);
  102. out_rel_fw:
  103. release_firmware(fw);
  104. return ret;
  105. }
  106. static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
  107. {
  108. u8 status, buf;
  109. if (onoff) {
  110. gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
  111. if (! (status & 0x01)) /* started */
  112. if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
  113. return -EINVAL;
  114. if (! (status & 0x02)) /* BCM4500 firmware loaded */
  115. if(gp8psk_load_bcm4500fw(d))
  116. return EINVAL;
  117. if (! (status & 0x04)) /* LNB Power */
  118. if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
  119. &buf, 1))
  120. return EINVAL;
  121. /* Set DVB mode */
  122. if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
  123. return -EINVAL;
  124. gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
  125. } else {
  126. /* Turn off LNB power */
  127. if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
  128. return EINVAL;
  129. /* Turn off 8psk power */
  130. if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
  131. return -EINVAL;
  132. }
  133. return 0;
  134. }
  135. static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
  136. {
  137. return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
  138. }
  139. static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
  140. {
  141. adap->fe = gp8psk_fe_attach(adap->dev);
  142. return 0;
  143. }
  144. static struct dvb_usb_device_properties gp8psk_properties;
  145. static int gp8psk_usb_probe(struct usb_interface *intf,
  146. const struct usb_device_id *id)
  147. {
  148. return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
  149. }
  150. static struct usb_device_id gp8psk_usb_table [] = {
  151. { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
  152. { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
  153. { 0 },
  154. };
  155. MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
  156. static struct dvb_usb_device_properties gp8psk_properties = {
  157. .usb_ctrl = CYPRESS_FX2,
  158. .firmware = "dvb-usb-gp8psk-01.fw",
  159. .num_adapters = 1,
  160. .adapter = {
  161. {
  162. .streaming_ctrl = gp8psk_streaming_ctrl,
  163. .frontend_attach = gp8psk_frontend_attach,
  164. /* parameter for the MPEG2-data transfer */
  165. .stream = {
  166. .type = USB_BULK,
  167. .count = 7,
  168. .endpoint = 0x82,
  169. .u = {
  170. .bulk = {
  171. .buffersize = 8192,
  172. }
  173. }
  174. },
  175. }
  176. },
  177. .power_ctrl = gp8psk_power_ctrl,
  178. .generic_bulk_ctrl_endpoint = 0x01,
  179. .num_device_descs = 1,
  180. .devices = {
  181. { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
  182. .cold_ids = { &gp8psk_usb_table[0], NULL },
  183. .warm_ids = { &gp8psk_usb_table[1], NULL },
  184. },
  185. { NULL },
  186. }
  187. };
  188. /* usb specific object needed to register this driver with the usb subsystem */
  189. static struct usb_driver gp8psk_usb_driver = {
  190. .name = "dvb_usb_gp8psk",
  191. .probe = gp8psk_usb_probe,
  192. .disconnect = dvb_usb_device_exit,
  193. .id_table = gp8psk_usb_table,
  194. };
  195. /* module stuff */
  196. static int __init gp8psk_usb_module_init(void)
  197. {
  198. int result;
  199. if ((result = usb_register(&gp8psk_usb_driver))) {
  200. err("usb_register failed. (%d)",result);
  201. return result;
  202. }
  203. return 0;
  204. }
  205. static void __exit gp8psk_usb_module_exit(void)
  206. {
  207. /* deregister this driver from the USB subsystem */
  208. usb_deregister(&gp8psk_usb_driver);
  209. }
  210. module_init(gp8psk_usb_module_init);
  211. module_exit(gp8psk_usb_module_exit);
  212. MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
  213. MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
  214. MODULE_VERSION("1.0");
  215. MODULE_LICENSE("GPL");