dtv5100.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*
  2. * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
  3. *
  4. * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
  5. * http://royale.zerezo.com/dtv5100/
  6. *
  7. * Inspired by gl861.c and au6610.c drivers
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #include "dtv5100.h"
  24. #include "qt1010.h"
  25. /* debug */
  26. static int dvb_usb_dtv5100_debug;
  27. module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
  28. MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
  29. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  30. static int dtv5100_read_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 *value)
  31. {
  32. return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
  33. DTV5100_I2C_READ, USB_TYPE_VENDOR|USB_DIR_IN,
  34. 0, (addr << 8) + reg, value, 1,
  35. DTV5100_USB_TIMEOUT);
  36. }
  37. static int dtv5100_write_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 value)
  38. {
  39. return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
  40. DTV5100_I2C_WRITE, USB_TYPE_VENDOR|USB_DIR_OUT,
  41. value, (addr << 8) + reg, NULL, 0,
  42. DTV5100_USB_TIMEOUT);
  43. }
  44. /* I2C */
  45. static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
  46. int num)
  47. {
  48. struct dvb_usb_device *d = i2c_get_adapdata(adap);
  49. int i;
  50. if (num > 2)
  51. return -EINVAL;
  52. if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
  53. return -EAGAIN;
  54. for (i = 0; i < num; i++) {
  55. if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
  56. /* write/read request, 2 messages
  57. * msg = {
  58. * { reg },
  59. * { val },
  60. * }
  61. */
  62. if (dtv5100_read_reg(d, msg[i].addr, msg[i].buf[0], msg[i+1].buf) < 0)
  63. break;
  64. i++;
  65. } else {
  66. /* write request, 1 message
  67. * msg = {
  68. * { reg, val },
  69. * }
  70. */
  71. if (dtv5100_write_reg(d, msg[i].addr, msg[i].buf[0], msg[i].buf[1]) < 0)
  72. break;
  73. }
  74. }
  75. mutex_unlock(&d->i2c_mutex);
  76. return i;
  77. }
  78. static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
  79. {
  80. return I2C_FUNC_I2C;
  81. }
  82. static struct i2c_algorithm dtv5100_i2c_algo = {
  83. .master_xfer = dtv5100_i2c_xfer,
  84. .functionality = dtv5100_i2c_func,
  85. };
  86. /* Callbacks for DVB USB */
  87. static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
  88. {
  89. adap->fe = dtv5100_fe_attach();
  90. return 0;
  91. }
  92. static struct qt1010_config dtv5100_qt1010_config = {
  93. .i2c_address = 0xc4
  94. };
  95. static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
  96. {
  97. return dvb_attach(qt1010_attach,
  98. adap->fe, &adap->dev->i2c_adap,
  99. &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
  100. }
  101. /* DVB USB Driver stuff */
  102. static struct dvb_usb_device_properties dtv5100_properties;
  103. static int dtv5100_probe(struct usb_interface *intf,
  104. const struct usb_device_id *id)
  105. {
  106. int i, ret;
  107. struct usb_device *udev = interface_to_usbdev(intf);
  108. ret = dvb_usb_device_init(intf, &dtv5100_properties,
  109. THIS_MODULE, NULL, adapter_nr);
  110. if (ret)
  111. return ret;
  112. /* initialize frontend & non qt1010 part? */
  113. for (i = 0; dtv5100_init[i].request; i++)
  114. {
  115. ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
  116. dtv5100_init[i].request,
  117. USB_TYPE_VENDOR|USB_DIR_OUT,
  118. dtv5100_init[i].value,
  119. dtv5100_init[i].index, NULL, 0,
  120. DTV5100_USB_TIMEOUT);
  121. if (ret)
  122. return ret;
  123. }
  124. return 0;
  125. }
  126. static struct usb_device_id dtv5100_table [] = {
  127. { USB_DEVICE(0x06be, 0xa232) },
  128. { } /* Terminating entry */
  129. };
  130. MODULE_DEVICE_TABLE(usb, dtv5100_table);
  131. static struct dvb_usb_device_properties dtv5100_properties = {
  132. .caps = DVB_USB_IS_AN_I2C_ADAPTER,
  133. .usb_ctrl = DEVICE_SPECIFIC,
  134. .size_of_priv = 0,
  135. .num_adapters = 1,
  136. .adapter = {{
  137. .frontend_attach = dtv5100_frontend_attach,
  138. .tuner_attach = dtv5100_tuner_attach,
  139. .stream = {
  140. .type = USB_BULK,
  141. .count = 8,
  142. .endpoint = 0x82,
  143. .u = {
  144. .bulk = {
  145. .buffersize = 4096,
  146. }
  147. }
  148. },
  149. } },
  150. .i2c_algo = &dtv5100_i2c_algo,
  151. .num_device_descs = 1,
  152. .devices = {
  153. {
  154. .name = "AME DTV-5100 USB2.0 DVB-T",
  155. .cold_ids = { NULL },
  156. .warm_ids = { &dtv5100_table[0], NULL },
  157. },
  158. }
  159. };
  160. static struct usb_driver dtv5100_driver = {
  161. .name = "dvb_usb_dtv5100",
  162. .probe = dtv5100_probe,
  163. .disconnect = dvb_usb_device_exit,
  164. .id_table = dtv5100_table,
  165. };
  166. /* module stuff */
  167. static int __init dtv5100_module_init(void)
  168. {
  169. int ret;
  170. ret = usb_register(&dtv5100_driver);
  171. if (ret)
  172. err("usb_register failed. Error number %d", ret);
  173. return ret;
  174. }
  175. static void __exit dtv5100_module_exit(void)
  176. {
  177. /* deregister this driver from the USB subsystem */
  178. usb_deregister(&dtv5100_driver);
  179. }
  180. module_init(dtv5100_module_init);
  181. module_exit(dtv5100_module_exit);
  182. MODULE_AUTHOR(DRIVER_AUTHOR);
  183. MODULE_DESCRIPTION(DRIVER_DESC);
  184. MODULE_LICENSE("GPL");