2 * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices
3 * based on reference design made by DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
7 * see dvb-dibusb-core.c for more copyright details.
9 * This file contains functions for downloading the firmware to the device.
11 #include "dvb-dibusb.h"
13 #include <linux/firmware.h>
14 #include <linux/usb.h>
17 * load a firmware packet to the device
19 static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
21 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
22 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
25 int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
27 const struct firmware *fw = NULL;
32 if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
33 err("did not find a valid firmware file. (%s) "
34 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
35 dibdev->dev_cl->firmware);
39 p = kmalloc(fw->size,GFP_KERNEL);
43 * you cannot use the fw->data as buffer for
44 * usb_control_msg, a new buffer has to be
47 memcpy(p,fw->data,fw->size);
51 if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1)
52 err("could not stop the USB controller CPU.");
53 for(i = 0; p[i+3] == 0 && i < fw->size; ) {
55 addr = *((u16 *) &b[1]);
57 ret = dibusb_writemem(udev,addr,&b[4],b[0]);
60 err("error while transferring firmware "
61 "(transferred size: %d, block size: %d)",
73 if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
74 err("could not restart the USB controller CPU.");