a800.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
  2. * USB2.0 (A800) DVB-T receiver.
  3. *
  4. * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@posteo.de)
  5. *
  6. * Thanks to
  7. * - AVerMedia who kindly provided information and
  8. * - Glen Harris who suffered from my mistakes during development.
  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/media/dvb-drivers/dvb-usb.rst for more information
  15. */
  16. #include "dibusb.h"
  17. static int debug;
  18. module_param(debug, int, 0644);
  19. MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
  20. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  21. #define deb_rc(args...) dprintk(debug,0x01,args)
  22. static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
  23. {
  24. /* do nothing for the AVerMedia */
  25. return 0;
  26. }
  27. /* assure to put cold to 0 for iManufacturer == 1 */
  28. static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
  29. struct dvb_usb_device_description **desc, int *cold)
  30. {
  31. *cold = udev->descriptor.iManufacturer != 1;
  32. return 0;
  33. }
  34. static int a800_rc_query(struct dvb_usb_device *d)
  35. {
  36. int ret = 0;
  37. u8 *key = kmalloc(5, GFP_KERNEL);
  38. if (!key)
  39. return -ENOMEM;
  40. if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
  41. 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
  42. 2000) != 5) {
  43. ret = -ENODEV;
  44. goto out;
  45. }
  46. /* Note that extended nec and nec32 are dropped */
  47. if (key[0] == 1)
  48. rc_keydown(d->rc_dev, RC_PROTO_NEC,
  49. RC_SCANCODE_NEC(key[1], key[3]), 0);
  50. else if (key[0] == 2)
  51. rc_repeat(d->rc_dev);
  52. out:
  53. kfree(key);
  54. return ret;
  55. }
  56. /* USB Driver stuff */
  57. static struct dvb_usb_device_properties a800_properties;
  58. static int a800_probe(struct usb_interface *intf,
  59. const struct usb_device_id *id)
  60. {
  61. return dvb_usb_device_init(intf, &a800_properties,
  62. THIS_MODULE, NULL, adapter_nr);
  63. }
  64. /* do not change the order of the ID table */
  65. static struct usb_device_id a800_table [] = {
  66. /* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
  67. /* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
  68. { } /* Terminating entry */
  69. };
  70. MODULE_DEVICE_TABLE (usb, a800_table);
  71. static struct dvb_usb_device_properties a800_properties = {
  72. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  73. .usb_ctrl = CYPRESS_FX2,
  74. .firmware = "dvb-usb-avertv-a800-02.fw",
  75. .num_adapters = 1,
  76. .adapter = {
  77. {
  78. .num_frontends = 1,
  79. .fe = {{
  80. .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
  81. .pid_filter_count = 32,
  82. .streaming_ctrl = dibusb2_0_streaming_ctrl,
  83. .pid_filter = dibusb_pid_filter,
  84. .pid_filter_ctrl = dibusb_pid_filter_ctrl,
  85. .frontend_attach = dibusb_dib3000mc_frontend_attach,
  86. .tuner_attach = dibusb_dib3000mc_tuner_attach,
  87. /* parameter for the MPEG2-data transfer */
  88. .stream = {
  89. .type = USB_BULK,
  90. .count = 7,
  91. .endpoint = 0x06,
  92. .u = {
  93. .bulk = {
  94. .buffersize = 4096,
  95. }
  96. }
  97. },
  98. }},
  99. .size_of_priv = sizeof(struct dibusb_state),
  100. },
  101. },
  102. .power_ctrl = a800_power_ctrl,
  103. .identify_state = a800_identify_state,
  104. .rc.core = {
  105. .rc_interval = DEFAULT_RC_INTERVAL,
  106. .rc_codes = RC_MAP_AVERMEDIA_M135A,
  107. .module_name = KBUILD_MODNAME,
  108. .rc_query = a800_rc_query,
  109. .allowed_protos = RC_PROTO_BIT_NEC,
  110. },
  111. .i2c_algo = &dibusb_i2c_algo,
  112. .generic_bulk_ctrl_endpoint = 0x01,
  113. .num_device_descs = 1,
  114. .devices = {
  115. { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
  116. { &a800_table[0], NULL },
  117. { &a800_table[1], NULL },
  118. },
  119. }
  120. };
  121. static struct usb_driver a800_driver = {
  122. .name = "dvb_usb_a800",
  123. .probe = a800_probe,
  124. .disconnect = dvb_usb_device_exit,
  125. .id_table = a800_table,
  126. };
  127. module_usb_driver(a800_driver);
  128. MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
  129. MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
  130. MODULE_VERSION("1.0");
  131. MODULE_LICENSE("GPL");