PageRenderTime 50ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/staging/go7007/s2250-loader.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 191 lines | 143 code | 31 blank | 17 comment | 19 complexity | 9096df421ffcc9b642459723698b5c30 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. * Copyright (C) 2008 Sensoray Company Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License (Version 2) as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software Foundation,
  15. * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/init.h>
  19. #include <linux/slab.h>
  20. #include <linux/usb.h>
  21. #include <dvb-usb.h>
  22. #define S2250_LOADER_FIRMWARE "s2250_loader.fw"
  23. #define S2250_FIRMWARE "s2250.fw"
  24. typedef struct device_extension_s {
  25. struct kref kref;
  26. int minor;
  27. struct usb_device *usbdev;
  28. } device_extension_t, *pdevice_extension_t;
  29. #define USB_s2250loader_MAJOR 240
  30. #define USB_s2250loader_MINOR_BASE 0
  31. #define MAX_DEVICES 256
  32. static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
  33. static DEFINE_MUTEX(s2250_dev_table_mutex);
  34. #define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
  35. static void s2250loader_delete(struct kref *kref)
  36. {
  37. pdevice_extension_t s = to_s2250loader_dev_common(kref);
  38. s2250_dev_table[s->minor] = NULL;
  39. kfree(s);
  40. }
  41. static int s2250loader_probe(struct usb_interface *interface,
  42. const struct usb_device_id *id)
  43. {
  44. struct usb_device *usbdev;
  45. int minor, ret;
  46. pdevice_extension_t s = NULL;
  47. const struct firmware *fw;
  48. usbdev = usb_get_dev(interface_to_usbdev(interface));
  49. if (!usbdev) {
  50. printk(KERN_ERR "Enter s2250loader_probe failed\n");
  51. return -1;
  52. }
  53. printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n");
  54. printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n",
  55. usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
  56. usbdev->devnum);
  57. if (usbdev->descriptor.bNumConfigurations != 1) {
  58. printk(KERN_ERR "can't handle multiple config\n");
  59. return -1;
  60. }
  61. mutex_lock(&s2250_dev_table_mutex);
  62. for (minor = 0; minor < MAX_DEVICES; minor++) {
  63. if (s2250_dev_table[minor] == NULL)
  64. break;
  65. }
  66. if (minor < 0 || minor >= MAX_DEVICES) {
  67. printk(KERN_ERR "Invalid minor: %d\n", minor);
  68. goto failed;
  69. }
  70. /* Allocate dev data structure */
  71. s = kmalloc(sizeof(device_extension_t), GFP_KERNEL);
  72. if (s == NULL) {
  73. printk(KERN_ERR "Out of memory\n");
  74. goto failed;
  75. }
  76. s2250_dev_table[minor] = s;
  77. printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n",
  78. usbdev->devnum, usbdev->bus->busnum, minor);
  79. memset(s, 0, sizeof(device_extension_t));
  80. s->usbdev = usbdev;
  81. printk(KERN_INFO "loading 2250 loader\n");
  82. kref_init(&(s->kref));
  83. mutex_unlock(&s2250_dev_table_mutex);
  84. if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
  85. printk(KERN_ERR
  86. "s2250: unable to load firmware from file \"%s\"\n",
  87. S2250_LOADER_FIRMWARE);
  88. goto failed2;
  89. }
  90. ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
  91. release_firmware(fw);
  92. if (0 != ret) {
  93. printk(KERN_ERR "loader download failed\n");
  94. goto failed2;
  95. }
  96. if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) {
  97. printk(KERN_ERR
  98. "s2250: unable to load firmware from file \"%s\"\n",
  99. S2250_FIRMWARE);
  100. goto failed2;
  101. }
  102. ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
  103. release_firmware(fw);
  104. if (0 != ret) {
  105. printk(KERN_ERR "firmware_s2250 download failed\n");
  106. goto failed2;
  107. }
  108. usb_set_intfdata(interface, s);
  109. return 0;
  110. failed:
  111. mutex_unlock(&s2250_dev_table_mutex);
  112. failed2:
  113. if (s)
  114. kref_put(&(s->kref), s2250loader_delete);
  115. printk(KERN_ERR "probe failed\n");
  116. return -1;
  117. }
  118. static void s2250loader_disconnect(struct usb_interface *interface)
  119. {
  120. pdevice_extension_t s;
  121. printk(KERN_INFO "s2250: disconnect\n");
  122. s = usb_get_intfdata(interface);
  123. usb_set_intfdata(interface, NULL);
  124. kref_put(&(s->kref), s2250loader_delete);
  125. }
  126. static const struct usb_device_id s2250loader_ids[] = {
  127. {USB_DEVICE(0x1943, 0xa250)},
  128. {} /* Terminating entry */
  129. };
  130. MODULE_DEVICE_TABLE(usb, s2250loader_ids);
  131. static struct usb_driver s2250loader_driver = {
  132. .name = "s2250-loader",
  133. .probe = s2250loader_probe,
  134. .disconnect = s2250loader_disconnect,
  135. .id_table = s2250loader_ids,
  136. };
  137. static int __init s2250loader_init(void)
  138. {
  139. int r;
  140. unsigned i = 0;
  141. for (i = 0; i < MAX_DEVICES; i++)
  142. s2250_dev_table[i] = NULL;
  143. r = usb_register(&s2250loader_driver);
  144. if (r) {
  145. printk(KERN_ERR "usb_register failed. Error number %d\n", r);
  146. return -1;
  147. }
  148. printk(KERN_INFO "s2250loader_init: driver registered\n");
  149. return 0;
  150. }
  151. module_init(s2250loader_init);
  152. static void __exit s2250loader_cleanup(void)
  153. {
  154. printk(KERN_INFO "s2250loader_cleanup\n");
  155. usb_deregister(&s2250loader_driver);
  156. }
  157. module_exit(s2250loader_cleanup);
  158. MODULE_AUTHOR("");
  159. MODULE_DESCRIPTION("firmware loader for Sensoray 2250/2251");
  160. MODULE_LICENSE("GPL v2");