diff options
Diffstat (limited to 'linux/drivers')
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/Kconfig | 8 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/Makefile | 3 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dw2102.c | 425 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-usb/dw2102.h | 9 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/z0194a.h | 97 | ||||
-rw-r--r-- | linux/drivers/media/video/cs5345.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-firmware.c | 54 | ||||
-rw-r--r-- | linux/drivers/media/video/sh_mobile_ceu_camera.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/videobuf-dma-contig.c | 8 |
10 files changed, 562 insertions, 46 deletions
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index a577c0f89..3c663c65e 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -246,6 +246,14 @@ config DVB_USB_AF9005_REMOTE Say Y here to support the default remote control decoding for the Afatech AF9005 based receiver. +config DVB_USB_DW2102 + tristate "DvbWorld 2102 DVB-S USB2.0 receiver" + depends on DVB_USB + select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_PLL if !DVB_FE_CUSTOMISE + help + Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver. + config DVB_USB_ANYSEE tristate "Anysee DVB-T/C USB2.0 support" depends on DVB_USB diff --git a/linux/drivers/media/dvb/dvb-usb/Makefile b/linux/drivers/media/dvb/dvb-usb/Makefile index 44c11e45e..e206f1ea0 100644 --- a/linux/drivers/media/dvb/dvb-usb/Makefile +++ b/linux/drivers/media/dvb/dvb-usb/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o dvb-usb-anysee-objs = anysee.o obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o +dvb-usb-dw2102-objs = dw2102.o +obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index e5238b31e..029b437ca 100644 --- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -204,5 +204,6 @@ #define USB_PID_ASUS_U3000 0x171f #define USB_PID_ASUS_U3100 0x173f #define USB_PID_YUAN_EC372S 0x1edc +#define USB_PID_DW2102 0x2102 #endif diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c new file mode 100644 index 000000000..a4d898b44 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/dw2102.c @@ -0,0 +1,425 @@ +/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card +* +* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* see Documentation/dvb/README.dvb-usb for more information +*/ +#include <linux/version.h> +#include "dw2102.h" +#include "stv0299.h" +#include "z0194a.h" + +#ifndef USB_PID_DW2102 +#define USB_PID_DW2102 0x2102 +#endif + +#define DW2102_READ_MSG 0 +#define DW2102_WRITE_MSG 1 + +#define REG_1F_SYMBOLRATE_BYTE0 0x1f +#define REG_20_SYMBOLRATE_BYTE1 0x20 +#define REG_21_SYMBOLRATE_BYTE2 0x21 + +#define DW2102_VOLTAGE_CTRL (0x1800) +#define DW2102_RC_QUERY (0x1a00) + +struct dw2102_state { + u32 last_key_pressed; +}; +struct dw2102_rc_keys { + u32 keycode; + u32 event; +}; + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, + u8 *data, u16 len, int flags) +{ + int ret; + u8 u8buf[len]; + + unsigned int pipe = (flags == DW2102_READ_MSG) ? + usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); + u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; + + if (flags == DW2102_WRITE_MSG) + memcpy(u8buf, data, len); + ret = usb_control_msg(dev, pipe, request, + request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); + + if (flags == DW2102_READ_MSG) + memcpy(data, u8buf, len); + return ret; +} + +/* I2C */ + +static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ +struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i = 0, ret = 0; + u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; + u8 request; + u16 value; + + if (!d) + return -ENODEV; + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + switch (num) { + case 2: + /* read stv0299 register */ + request = 0xb5; + value = msg[0].buf[0];/* register */ + for (i = 0; i < msg[1].len; i++) { + value = value + i; + ret = dw2102_op_rw(d->udev, 0xb5, + value, buf6, 2, DW2102_READ_MSG); + msg[1].buf[i] = buf6[0]; + + } + break; + case 1: + switch (msg[0].addr) { + case 0x68: + /* write to stv0299 register */ + buf6[0] = 0x2a; + buf6[1] = msg[0].buf[0]; + buf6[2] = msg[0].buf[1]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 3, DW2102_WRITE_MSG); + break; + case 0x60: + if (msg[0].flags == 0) { + /* write to tuner pll */ + buf6[0] = 0x2c; + buf6[1] = 5; + buf6[2] = 0xc0; + buf6[3] = msg[0].buf[0]; + buf6[4] = msg[0].buf[1]; + buf6[5] = msg[0].buf[2]; + buf6[6] = msg[0].buf[3]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 7, DW2102_WRITE_MSG); + } else { + /* write to tuner pll */ + ret = dw2102_op_rw(d->udev, 0xb5, + 0, buf6, 1, DW2102_READ_MSG); + msg[0].buf[0] = buf6[0]; + } + break; + case (DW2102_RC_QUERY): + ret = dw2102_op_rw(d->udev, 0xb8, + 0, buf6, 2, DW2102_READ_MSG); + msg[0].buf[0] = buf6[0]; + msg[0].buf[1] = buf6[1]; + break; + case (DW2102_VOLTAGE_CTRL): + buf6[0] = 0x30; + buf6[1] = msg[0].buf[0]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 2, DW2102_WRITE_MSG); + break; + } + + break; + } + + mutex_unlock(&d->i2c_mutex); + return num; +} + +static u32 dw2102_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm dw2102_i2c_algo = { + .master_xfer = dw2102_i2c_transfer, + .functionality = dw2102_i2c_func, +}; + +static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + static u8 command_13v[1] = {0x00}; + static u8 command_18v[1] = {0x01}; + struct i2c_msg msg[] = { + {.addr = DW2102_VOLTAGE_CTRL, .flags = 0, + .buf = command_13v, .len = 1}, + }; + + struct dvb_usb_adapter *udev_adap = + (struct dvb_usb_adapter *)(fe->dvb->priv); + if (voltage == SEC_VOLTAGE_18) + msg[0].buf = command_18v; + i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); + return 0; +} + +static int dw2102_frontend_attach(struct dvb_usb_adapter *d) +{ + d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, + &d->dev->i2c_adap); + if (d->fe != NULL) { + d->fe->ops.set_voltage = dw2102_set_voltage; + info("Attached stv0299!\n"); + return 0; + } + return -EIO; +} + +static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) +{ + dvb_attach(dvb_pll_attach, adap->fe, 0x60, + &adap->dev->i2c_adap, DVB_PLL_OPERA1); + return 0; +} + +static struct dvb_usb_rc_key dw2102_rc_keys[] = { + { 0xf8, 0x0a, KEY_Q }, /*power*/ + { 0xf8, 0x0c, KEY_M }, /*mute*/ + { 0xf8, 0x11, KEY_1 }, + { 0xf8, 0x12, KEY_2 }, + { 0xf8, 0x13, KEY_3 }, + { 0xf8, 0x14, KEY_4 }, + { 0xf8, 0x15, KEY_5 }, + { 0xf8, 0x16, KEY_6 }, + { 0xf8, 0x17, KEY_7 }, + { 0xf8, 0x18, KEY_8 }, + { 0xf8, 0x19, KEY_9 }, + { 0xf8, 0x10, KEY_0 }, + { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/ + { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/ + { 0xf8, 0x1a, KEY_O }, /*vol+*/ + { 0xf8, 0x0e, KEY_Z }, /*vol-*/ + { 0xf8, 0x04, KEY_R }, /*rec*/ + { 0xf8, 0x09, KEY_D }, /*fav*/ + { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/ + { 0xf8, 0x07, KEY_A }, /*fast*/ + { 0xf8, 0x0b, KEY_P }, /*pause*/ + { 0xf8, 0x02, KEY_ESC }, /*cancel*/ + { 0xf8, 0x03, KEY_G }, /*tab*/ + { 0xf8, 0x00, KEY_UP }, /*up*/ + { 0xf8, 0x1f, KEY_ENTER }, /*ok*/ + { 0xf8, 0x01, KEY_DOWN }, /*down*/ + { 0xf8, 0x05, KEY_C }, /*cap*/ + { 0xf8, 0x06, KEY_S }, /*stop*/ + { 0xf8, 0x40, KEY_F }, /*full*/ + { 0xf8, 0x1e, KEY_W }, /*tvmode*/ + { 0xf8, 0x1b, KEY_B }, /*recall*/ + +}; + + + +static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + struct dw2102_state *st = d->priv; + u8 key[2]; + struct i2c_msg msg[] = { + {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, + .len = 2}, + }; + int i; + + *state = REMOTE_NO_KEY_PRESSED; + if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { + for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) { + if (dw2102_rc_keys[i].data == msg[0].buf[0]) { + *state = REMOTE_KEY_PRESSED; + *event = dw2102_rc_keys[i].event; + st->last_key_pressed = + dw2102_rc_keys[i].event; + break; + } + st->last_key_pressed = 0; + } + } + /* info("key: %x %x\n",key[0],key[1]); */ + return 0; +} + +static struct usb_device_id dw2102_table[] = { + {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, + {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, + { } +}; + +MODULE_DEVICE_TABLE(usb, dw2102_table); + +static int dw2102_load_firmware(struct usb_device *dev, + const struct firmware *frmwr) +{ + u8 *b, *p; + int ret = 0, i; + u8 reset; + u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; + const struct firmware *fw; + const char *filename = "dvb-usb-dw2101.fw"; + switch (dev->descriptor.idProduct) { + case 0x2101: + ret = request_firmware(&fw, filename, &dev->dev); + if (ret != 0) { + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more details " + "on firmware-problems.", filename); + return ret; + } + break; + case USB_PID_DW2102: + fw = frmwr; + break; + } + info("start downloading DW2102 firmware"); + p = kmalloc(fw->size, GFP_KERNEL); + reset = 1; + /*stop the CPU*/ + dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); + dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); + + if (p != NULL) { + memcpy(p, fw->data, fw->size); + for (i = 0; i < fw->size; i += 0x40) { + b = (u8 *) p + i; + if (dw2102_op_rw + (dev, 0xa0, i, b , 0x40, + DW2102_WRITE_MSG) != 0x40 + ) { + err("error while transferring firmware"); + ret = -EINVAL; + break; + } + } + /* restart the CPU */ + reset = 0; + if (ret || dw2102_op_rw + (dev, 0xa0, 0x7f92, &reset, 1, + DW2102_WRITE_MSG) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + if (ret || dw2102_op_rw + (dev, 0xa0, 0xe600, &reset, 1, + DW2102_WRITE_MSG) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + /* init registers */ + switch (dev->descriptor.idProduct) { + case USB_PID_DW2102: + dw2102_op_rw + (dev, 0xbf, 0x0040, &reset, 0, + DW2102_WRITE_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); + break; + case 0x2101: + dw2102_op_rw + (dev, 0xbc, 0x0030, &reset16[0], 2, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); + break; + } + kfree(p); + } + return ret; +} + +static struct dvb_usb_device_properties dw2102_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-dw2102.fw", + .size_of_priv = sizeof(struct dw2102_state), + .no_reconnect = 1, + + .i2c_algo = &dw2102_i2c_algo, + .rc_key_map = dw2102_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + + .generic_bulk_ctrl_endpoint = 0x81, + /* parameter for the MPEG2-data transfer */ + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .adapter = { + { + .frontend_attach = dw2102_frontend_attach, + .streaming_ctrl = NULL, + .tuner_attach = dw2102_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } + }, + .num_device_descs = 2, + .devices = { + {"DVBWorld DVB-S 2102 USB2.0", + {&dw2102_table[0], NULL}, + {NULL}, + }, + {"DVBWorld DVB-S 2101 USB2.0", + {&dw2102_table[1], NULL}, + {NULL}, + }, + } +}; + +static int dw2102_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf, &dw2102_properties, + THIS_MODULE, NULL, adapter_nr); +} + +static struct usb_driver dw2102_driver = { + .name = "dw2102", + .probe = dw2102_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dw2102_table, +}; + +static int __init dw2102_module_init(void) +{ + int ret = usb_register(&dw2102_driver); + if (ret) + err("usb_register failed. Error number %d", ret); + + return ret; +} + +static void __exit dw2102_module_exit(void) +{ + usb_deregister(&dw2102_driver); +} + +module_init(dw2102_module_init); +module_exit(dw2102_module_exit); + +MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); +MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.h b/linux/drivers/media/dvb/dvb-usb/dw2102.h new file mode 100644 index 000000000..cb5873752 --- /dev/null +++ b/linux/drivers/media/dvb/dvb-usb/dw2102.h @@ -0,0 +1,9 @@ +#ifndef _DW2102_H_ +#define _DW2102_H_ + +#define DVB_USB_LOG_PREFIX "dw2102" +#include <dvb-usb.h> + +extern int dvb_usb_dw2102_debug; +#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) +#endif diff --git a/linux/drivers/media/dvb/frontends/z0194a.h b/linux/drivers/media/dvb/frontends/z0194a.h new file mode 100644 index 000000000..b5ca9e754 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/z0194a.h @@ -0,0 +1,97 @@ +/* z0194a.h Sharp z0194a tuner support +* +* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* see Documentation/dvb/README.dvb-usb for more information +*/ + +#ifndef Z0194A +#define Z0194A + +static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, + u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { + aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { + aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { + aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { + aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { + aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { + aclk = 0xb4; bclk = 0x51; } + + stv0299_writereg(fe, 0x13, aclk); + stv0299_writereg(fe, 0x14, bclk); + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg(fe, 0x21, (ratio) & 0xf0); + + return 0; +} + +static u8 sharp_z0194a__inittab[] = { + 0x01, 0x15, + 0x02, 0x00, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, /* AGC2 0x3d */ + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, /* lock detector threshold */ + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */ + 0x29, 0x1e, /* 1/2 threshold */ + 0x2a, 0x14, /* 2/3 threshold */ + 0x2b, 0x0f, /* 3/4 threshold */ + 0x2c, 0x09, /* 5/6 threshold */ + 0x2d, 0x05, /* 7/8 threshold */ + 0x2e, 0x01, + 0x31, 0x1f, /* test all FECs */ + 0x32, 0x19, /* viterbi and synchro search */ + 0x33, 0xfc, /* rs control */ + 0x34, 0x93, /* error control */ + 0x0f, 0x52, + 0xff, 0xff +}; + +static struct stv0299_config sharp_z0194a_config = { + .demod_address = 0x68, + .inittab = sharp_z0194a__inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = sharp_z0194a__set_symbol_rate, +}; + +#endif diff --git a/linux/drivers/media/video/cs5345.c b/linux/drivers/media/video/cs5345.c index e2f0b0278..e4c505d2f 100644 --- a/linux/drivers/media/video/cs5345.c +++ b/linux/drivers/media/video/cs5345.c @@ -117,7 +117,7 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg) if (cmd == VIDIOC_DBG_G_REGISTER) reg->val = cs5345_read(client, reg->reg & 0x1f); else - cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f); + cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff); break; } #endif diff --git a/linux/drivers/media/video/cx18/cx18-firmware.c b/linux/drivers/media/video/cx18/cx18-firmware.c index 2d630d9f7..78fadd2ad 100644 --- a/linux/drivers/media/video/cx18/cx18-firmware.c +++ b/linux/drivers/media/video/cx18/cx18-firmware.c @@ -86,10 +86,6 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C -/* Encoder/decoder firmware sizes */ -#define CX18_FW_CPU_SIZE (158332) -#define CX18_FW_APU_SIZE (141200) - #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ @@ -100,35 +96,22 @@ struct cx18_apu_rom_seghdr { u32 size; }; -static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size) +static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) { const struct firmware *fw = NULL; - int retries = 3; int i, j; + unsigned size; u32 __iomem *dst = (u32 __iomem *)mem; const u32 *src; -retry: - if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n", - fn, size); + if (request_firmware(&fw, fn, &cx->dev->dev)) { + CX18_ERR("Unable to open firmware %s\n", fn); CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } src = (const u32 *)fw->data; - if (fw->size != size) { - /* Due to race conditions in firmware loading (esp. with - udev <0.95) the wrong file was sometimes loaded. So we check - filesizes to see if at least the right-sized file was - loaded. If not, then we retry. */ - CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", - fn, size, fw->size); - release_firmware(fw); - retries--; - goto retry; - } for (i = 0; i < fw->size; i += 4096) { setup_page(i); for (j = i; j < fw->size && j < i + 4096; j += 4) { @@ -145,15 +128,16 @@ retry: } if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); + size = fw->size; release_firmware(fw); return size; } -static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size) +static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) { const struct firmware *fw = NULL; - int retries = 3; int i, j; + unsigned size; const u32 *src; struct cx18_apu_rom_seghdr seghdr; const u8 *vers; @@ -161,10 +145,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, u32 apu_version = 0; int sz; -retry: - if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("unable to open firmware %s (must be %ld bytes)\n", - fn, size); + if (request_firmware(&fw, fn, &cx->dev->dev)) { + CX18_ERR("unable to open firmware %s\n", fn); CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } @@ -173,19 +155,8 @@ retry: vers = fw->data + sizeof(seghdr); sz = fw->size; - if (fw->size != size) { - /* Due to race conditions in firmware loading (esp. with - udev <0.95) the wrong file was sometimes loaded. So we check - filesizes to see if at least the right-sized file was - loaded. If not, then we retry. */ - CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", - fn, size, fw->size); - release_firmware(fw); - retries--; - goto retry; - } apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; - while (offset + sizeof(seghdr) < size) { + while (offset + sizeof(seghdr) < fw->size) { /* TODO: byteswapping */ memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); offset += sizeof(seghdr); @@ -215,6 +186,7 @@ retry: if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", fn, apu_version, fw->size); + size = fw->size; release_firmware(fw); /* Clear bit0 for APU to start from 0 */ write_reg(read_reg(0xc72030) & ~1, 0xc72030); @@ -340,7 +312,7 @@ int cx18_firmware_init(struct cx18 *cx) /* Only if the processor is not running */ if (read_reg(CX18_PROC_SOFT_RESET) & 8) { int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", - cx->enc_mem, cx, CX18_FW_APU_SIZE); + cx->enc_mem, cx); write_enc(0xE51FF004, 0); write_enc(0xa00000, 4); /* todo: not hardcoded */ @@ -348,7 +320,7 @@ int cx18_firmware_init(struct cx18 *cx) cx18_msleep_timeout(500, 0); sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", - cx->enc_mem, cx, CX18_FW_CPU_SIZE); + cx->enc_mem, cx); if (sz > 0) { int retries = 0; diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index 012005e1a..f7ca3cb93 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -91,6 +91,7 @@ struct sh_mobile_ceu_dev { void __iomem *base; unsigned long video_limit; + /* lock used to protect videobuf */ spinlock_t lock; struct list_head capture; struct videobuf_buffer *active; diff --git a/linux/drivers/media/video/videobuf-dma-contig.c b/linux/drivers/media/video/videobuf-dma-contig.c index c71001da3..a3bf4c151 100644 --- a/linux/drivers/media/video/videobuf-dma-contig.c +++ b/linux/drivers/media/video/videobuf-dma-contig.c @@ -29,10 +29,10 @@ struct videobuf_dma_contig_memory { }; #define MAGIC_DC_MEM 0x0733ac61 -#define MAGIC_CHECK(is, should) \ - if (unlikely((is) != (should))) { \ - pr_err("magic mismatch: %x expected %x\n", is, should); \ - BUG(); \ +#define MAGIC_CHECK(is, should) \ + if (unlikely((is) != (should))) { \ + pr_err("magic mismatch: %x expected %x\n", (is), (should)); \ + BUG(); \ } static void |