0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011
0012 #include <linux/kernel.h>
0013 #include <linux/init.h>
0014 #include <linux/slab.h>
0015 #include <linux/types.h>
0016 #include <linux/errno.h>
0017
0018 #include <linux/device.h>
0019 #include <linux/firmware.h>
0020
0021 #include <linux/usb.h>
0022
0023 #include <net/bluetooth/bluetooth.h>
0024
0025 #define VERSION "1.2"
0026
0027 static const struct usb_device_id bcm203x_table[] = {
0028
0029 { USB_DEVICE(0x0a5c, 0x2033) },
0030
0031 { }
0032 };
0033
0034 MODULE_DEVICE_TABLE(usb, bcm203x_table);
0035
0036 #define BCM203X_ERROR 0
0037 #define BCM203X_RESET 1
0038 #define BCM203X_LOAD_MINIDRV 2
0039 #define BCM203X_SELECT_MEMORY 3
0040 #define BCM203X_CHECK_MEMORY 4
0041 #define BCM203X_LOAD_FIRMWARE 5
0042 #define BCM203X_CHECK_FIRMWARE 6
0043
0044 #define BCM203X_IN_EP 0x81
0045 #define BCM203X_OUT_EP 0x02
0046
0047 struct bcm203x_data {
0048 struct usb_device *udev;
0049
0050 unsigned long state;
0051
0052 struct work_struct work;
0053 atomic_t shutdown;
0054
0055 struct urb *urb;
0056 unsigned char *buffer;
0057
0058 unsigned char *fw_data;
0059 unsigned int fw_size;
0060 unsigned int fw_sent;
0061 };
0062
0063 static void bcm203x_complete(struct urb *urb)
0064 {
0065 struct bcm203x_data *data = urb->context;
0066 struct usb_device *udev = urb->dev;
0067 int len;
0068
0069 BT_DBG("udev %p urb %p", udev, urb);
0070
0071 if (urb->status) {
0072 BT_ERR("URB failed with status %d", urb->status);
0073 data->state = BCM203X_ERROR;
0074 return;
0075 }
0076
0077 switch (data->state) {
0078 case BCM203X_LOAD_MINIDRV:
0079 memcpy(data->buffer, "#", 1);
0080
0081 usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
0082 data->buffer, 1, bcm203x_complete, data);
0083
0084 data->state = BCM203X_SELECT_MEMORY;
0085
0086
0087 schedule_work(&data->work);
0088 break;
0089
0090 case BCM203X_SELECT_MEMORY:
0091 usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
0092 data->buffer, 32, bcm203x_complete, data, 1);
0093
0094 data->state = BCM203X_CHECK_MEMORY;
0095
0096 if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
0097 BT_ERR("Can't submit URB");
0098 break;
0099
0100 case BCM203X_CHECK_MEMORY:
0101 if (data->buffer[0] != '#') {
0102 BT_ERR("Memory select failed");
0103 data->state = BCM203X_ERROR;
0104 break;
0105 }
0106
0107 data->state = BCM203X_LOAD_FIRMWARE;
0108 fallthrough;
0109 case BCM203X_LOAD_FIRMWARE:
0110 if (data->fw_sent == data->fw_size) {
0111 usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, BCM203X_IN_EP),
0112 data->buffer, 32, bcm203x_complete, data, 1);
0113
0114 data->state = BCM203X_CHECK_FIRMWARE;
0115 } else {
0116 len = min_t(uint, data->fw_size - data->fw_sent, 4096);
0117
0118 usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
0119 data->fw_data + data->fw_sent, len, bcm203x_complete, data);
0120
0121 data->fw_sent += len;
0122 }
0123
0124 if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
0125 BT_ERR("Can't submit URB");
0126 break;
0127
0128 case BCM203X_CHECK_FIRMWARE:
0129 if (data->buffer[0] != '.') {
0130 BT_ERR("Firmware loading failed");
0131 data->state = BCM203X_ERROR;
0132 break;
0133 }
0134
0135 data->state = BCM203X_RESET;
0136 break;
0137 }
0138 }
0139
0140 static void bcm203x_work(struct work_struct *work)
0141 {
0142 struct bcm203x_data *data =
0143 container_of(work, struct bcm203x_data, work);
0144
0145 if (atomic_read(&data->shutdown))
0146 return;
0147
0148 if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
0149 BT_ERR("Can't submit URB");
0150 }
0151
0152 static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id *id)
0153 {
0154 const struct firmware *firmware;
0155 struct usb_device *udev = interface_to_usbdev(intf);
0156 struct bcm203x_data *data;
0157 int size;
0158
0159 BT_DBG("intf %p id %p", intf, id);
0160
0161 if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
0162 return -ENODEV;
0163
0164 data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
0165 if (!data)
0166 return -ENOMEM;
0167
0168 data->udev = udev;
0169 data->state = BCM203X_LOAD_MINIDRV;
0170
0171 data->urb = usb_alloc_urb(0, GFP_KERNEL);
0172 if (!data->urb)
0173 return -ENOMEM;
0174
0175 if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
0176 BT_ERR("Mini driver request failed");
0177 usb_free_urb(data->urb);
0178 return -EIO;
0179 }
0180
0181 BT_DBG("minidrv data %p size %zu", firmware->data, firmware->size);
0182
0183 size = max_t(uint, firmware->size, 4096);
0184
0185 data->buffer = kmalloc(size, GFP_KERNEL);
0186 if (!data->buffer) {
0187 BT_ERR("Can't allocate memory for mini driver");
0188 release_firmware(firmware);
0189 usb_free_urb(data->urb);
0190 return -ENOMEM;
0191 }
0192
0193 memcpy(data->buffer, firmware->data, firmware->size);
0194
0195 usb_fill_bulk_urb(data->urb, udev, usb_sndbulkpipe(udev, BCM203X_OUT_EP),
0196 data->buffer, firmware->size, bcm203x_complete, data);
0197
0198 release_firmware(firmware);
0199
0200 if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) {
0201 BT_ERR("Firmware request failed");
0202 usb_free_urb(data->urb);
0203 kfree(data->buffer);
0204 return -EIO;
0205 }
0206
0207 BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
0208
0209 data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
0210 if (!data->fw_data) {
0211 BT_ERR("Can't allocate memory for firmware image");
0212 release_firmware(firmware);
0213 usb_free_urb(data->urb);
0214 kfree(data->buffer);
0215 return -ENOMEM;
0216 }
0217
0218 data->fw_size = firmware->size;
0219 data->fw_sent = 0;
0220
0221 release_firmware(firmware);
0222
0223 INIT_WORK(&data->work, bcm203x_work);
0224
0225 usb_set_intfdata(intf, data);
0226
0227
0228 schedule_work(&data->work);
0229
0230 return 0;
0231 }
0232
0233 static void bcm203x_disconnect(struct usb_interface *intf)
0234 {
0235 struct bcm203x_data *data = usb_get_intfdata(intf);
0236
0237 BT_DBG("intf %p", intf);
0238
0239 atomic_inc(&data->shutdown);
0240 cancel_work_sync(&data->work);
0241
0242 usb_kill_urb(data->urb);
0243
0244 usb_set_intfdata(intf, NULL);
0245
0246 usb_free_urb(data->urb);
0247 kfree(data->fw_data);
0248 kfree(data->buffer);
0249 }
0250
0251 static struct usb_driver bcm203x_driver = {
0252 .name = "bcm203x",
0253 .probe = bcm203x_probe,
0254 .disconnect = bcm203x_disconnect,
0255 .id_table = bcm203x_table,
0256 .disable_hub_initiated_lpm = 1,
0257 };
0258
0259 module_usb_driver(bcm203x_driver);
0260
0261 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
0262 MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);
0263 MODULE_VERSION(VERSION);
0264 MODULE_LICENSE("GPL");
0265 MODULE_FIRMWARE("BCM2033-MD.hex");
0266 MODULE_FIRMWARE("BCM2033-FW.bin");