V4L/DVB (13586): DiB0700: Add parameter to change the buffer size

Add parameter to change the buffer size. This buffer size is specified
in number of Ts packet. This parameter is stored inside the state.

For firmware higher than 1.21, the xfer buffer size can be changed
inside the dib0700 usb bridge the firware version is stored inside the
state

Signed-off-by: Patrick Boettcher <pboettcher@kernellabs.com>
Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Olivier Grenie 2009-12-07 08:22:53 -03:00 committed by Mauro Carvalho Chehab
parent 9542f502cf
commit acc5c9ee39
2 changed files with 109 additions and 18 deletions

View file

@ -20,20 +20,22 @@ extern int dvb_usb_dib0700_debug;
#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
#define REQUEST_I2C_READ 0x2
#define REQUEST_I2C_WRITE 0x3
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
#define REQUEST_JUMPRAM 0x8
#define REQUEST_SET_CLOCK 0xB
#define REQUEST_SET_GPIO 0xC
#define REQUEST_ENABLE_VIDEO 0xF
#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
/* higher than 1.21 */
#define REQUEST_I2C_READ 0x2
#define REQUEST_I2C_WRITE 0x3
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
#define REQUEST_JUMPRAM 0x8
#define REQUEST_SET_CLOCK 0xB
#define REQUEST_SET_GPIO 0xC
#define REQUEST_ENABLE_VIDEO 0xF
// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
#define REQUEST_SET_RC 0x11
#define REQUEST_NEW_I2C_READ 0x12
#define REQUEST_NEW_I2C_WRITE 0x13
#define REQUEST_GET_VERSION 0x15
#define REQUEST_SET_RC 0x11
#define REQUEST_NEW_I2C_READ 0x12
#define REQUEST_NEW_I2C_WRITE 0x13
#define REQUEST_GET_VERSION 0x15
struct dib0700_state {
u8 channel_state;
@ -44,6 +46,8 @@ struct dib0700_state {
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
u8 disable_streaming_master_mode;
u32 fw_version;
u32 nb_packet_buffer_size;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,

View file

@ -17,6 +17,14 @@ int dvb_usb_dib0700_ir_proto = 1;
module_param(dvb_usb_dib0700_ir_proto, int, 0644);
MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6).");
static int nb_packet_buffer_size = 21;
module_param(nb_packet_buffer_size, int, 0644);
MODULE_PARM_DESC(nb_packet_buffer_size,
"Set the dib0700 driver data buffer size. This parameter "
"corresponds to the number of TS packets. The actual size of "
"the data buffer corresponds to this parameter "
"multiplied by 188 (default: 21)");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@ -28,10 +36,14 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
*hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
*romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
*ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
*fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
if (hwversion != NULL)
*hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
if (romversion != NULL)
*romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7];
if (ramversion != NULL)
*ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
if (fwtype != NULL)
*fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
return ret;
}
@ -97,6 +109,27 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
return dib0700_ctrl_wr(d,buf,3);
}
static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
{
struct dib0700_state *st = d->priv;
u8 b[3];
int ret;
if (st->fw_version >= 0x10201) {
b[0] = REQUEST_SET_USB_XFER_LEN;
b[1] = (nb_ts_packets >> 8)&0xff;
b[2] = nb_ts_packets & 0xff;
deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
ret = dib0700_ctrl_wr(d, b, 3);
} else {
deb_info("this firmware does not allow to change the USB xfer len\n");
ret = -EIO;
}
return ret;
}
/*
* I2C master xfer function (supported in 1.20 firmware)
*/
@ -328,7 +361,9 @@ static int dib0700_jumpram(struct usb_device *udev, u32 address)
int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
{
struct hexline hx;
int pos = 0, ret, act_len;
int pos = 0, ret, act_len, i, adap_num;
u8 b[16];
u32 fw_version;
u8 buf[260];
@ -364,6 +399,34 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
} else
ret = -EIO;
/* the number of ts packet has to be at least 1 */
if (nb_packet_buffer_size < 1)
nb_packet_buffer_size = 1;
/* get the fimware version */
usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
/* set the buffer size - DVB-USB is allocating URB buffers
* only after the firwmare download was successful */
for (i = 0; i < dib0700_device_count; i++) {
for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
adap_num++) {
if (fw_version >= 0x10201)
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
else {
/* for fw version older than 1.20.1,
* the buffersize has to be n times 512 */
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
}
}
}
return ret;
}
@ -371,6 +434,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct dib0700_state *st = adap->dev->priv;
u8 b[4];
int ret;
if ((onoff != 0) && (st->fw_version >= 0x10201)) {
/* for firmware later than 1.20.1,
* the USB xfer length can be set */
ret = dib0700_set_usb_xfer_len(adap->dev,
st->nb_packet_buffer_size);
if (ret < 0) {
deb_info("can not set the USB xfer len\n");
return ret;
}
}
b[0] = REQUEST_ENABLE_VIDEO;
b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
@ -415,9 +490,21 @@ static int dib0700_probe(struct usb_interface *intf,
for (i = 0; i < dib0700_device_count; i++)
if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
&dev, adapter_nr) == 0)
{
&dev, adapter_nr) == 0) {
struct dib0700_state *st = dev->priv;
u32 hwversion, romversion, fw_version, fwtype;
dib0700_get_version(dev, &hwversion, &romversion,
&fw_version, &fwtype);
deb_info("Firmware version: %x, %d, 0x%x, %d\n",
hwversion, romversion, fw_version, fwtype);
st->fw_version = fw_version;
st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
dib0700_rc_setup(dev);
return 0;
}