提交 a4099ae7 编写于 作者: L Linus Torvalds

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (37 commits)
  V4L/DVB: v4l: radio: si470x: fix unneeded free_irq() call
  V4L/DVB: v4l: videobuf: prevent passing a NULL to dma_free_coherent()
  V4L/DVB: ir-core: Fix null dereferences in the protocols sysfs interface
  V4L/DVB: v4l: s5p-fimc: Fix 3-planar formats handling and pixel offset error on S5PV210 SoCs
  V4L/DVB: v4l: s5p-fimc: Fix return value on probe() failure
  V4L/DVB: uvcvideo: Restrict frame rates for Chicony CNF7129 webcam
  V4L/DVB: uvcvideo: Fix support for Medion Akoya All-in-one PC integrated webcam
  V4L/DVB: ivtvfb: prevent reading uninitialized stack memory
  V4L/DVB: cx25840: Fix typo in volume control initialization: 65335 vs. 65535
  V4L/DVB: v4l: mem2mem_testdev: add missing release for video_device
  V4L/DVB: v4l: mem2mem_testdev: fix errorenous comparison
  V4L/DVB: mt9v022.c: Fixed compilation warning
  V4L/DVB: mt9m111: added current colorspace at g_fmt
  V4L/DVB: mt9m111: cropcap and s_crop check if type is VIDEO_CAPTURE
  V4L/DVB: mx2_camera: fix a race causing NULL dereference
  V4L/DVB: tm6000: bugfix data handling
  V4L/DVB: gspca - sn9c20x: Bad transfer size of Bayer images
  V4L/DVB: videobuf-dma-sg: set correct size in last sg element
  V4L/DVB: cx231xx: Avoid an OOPS when card is unknown (card=0)
  V4L/DVB: dvb: fix smscore_getbuffer() logic
  ...
...@@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie) ...@@ -319,7 +319,7 @@ static void ir_timer_keyup(unsigned long cookie)
* a keyup event might follow immediately after the keydown. * a keyup event might follow immediately after the keydown.
*/ */
spin_lock_irqsave(&ir->keylock, flags); spin_lock_irqsave(&ir->keylock, flags);
if (time_is_after_eq_jiffies(ir->keyup_jiffies)) if (time_is_before_eq_jiffies(ir->keyup_jiffies))
ir_keyup(ir); ir_keyup(ir);
spin_unlock_irqrestore(&ir->keylock, flags); spin_unlock_irqrestore(&ir->keylock, flags);
} }
...@@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev, ...@@ -510,6 +510,13 @@ int __ir_input_register(struct input_dev *input_dev,
(ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ? (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_IR_RAW) ?
" in raw mode" : ""); " in raw mode" : "");
/*
* Default delay of 250ms is too short for some protocols, expecially
* since the timeout is currently set to 250ms. Increase it to 500ms,
* to avoid wrong repetition of the keycodes.
*/
input_dev->rep[REP_DELAY] = 500;
return 0; return 0;
out_event: out_event:
......
...@@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev) ...@@ -267,7 +267,7 @@ static int ir_lirc_register(struct input_dev *input_dev)
features |= LIRC_CAN_SET_SEND_CARRIER; features |= LIRC_CAN_SET_SEND_CARRIER;
if (ir_dev->props->s_tx_duty_cycle) if (ir_dev->props->s_tx_duty_cycle)
features |= LIRC_CAN_SET_REC_DUTY_CYCLE; features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
} }
if (ir_dev->props->s_rx_carrier_range) if (ir_dev->props->s_rx_carrier_range)
......
...@@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev) ...@@ -279,9 +279,11 @@ int ir_raw_event_register(struct input_dev *input_dev)
"rc%u", (unsigned int)ir->devno); "rc%u", (unsigned int)ir->devno);
if (IS_ERR(ir->raw->thread)) { if (IS_ERR(ir->raw->thread)) {
int ret = PTR_ERR(ir->raw->thread);
kfree(ir->raw); kfree(ir->raw);
ir->raw = NULL; ir->raw = NULL;
return PTR_ERR(ir->raw->thread); return ret;
} }
mutex_lock(&ir_raw_handler_lock); mutex_lock(&ir_raw_handler_lock);
......
...@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d, ...@@ -67,13 +67,14 @@ static ssize_t show_protocols(struct device *d,
char *tmp = buf; char *tmp = buf;
int i; int i;
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
enabled = ir_dev->rc_tab.ir_type; enabled = ir_dev->rc_tab.ir_type;
allowed = ir_dev->props->allowed_protos; allowed = ir_dev->props->allowed_protos;
} else { } else if (ir_dev->raw) {
enabled = ir_dev->raw->enabled_protocols; enabled = ir_dev->raw->enabled_protocols;
allowed = ir_raw_get_allowed_protocols(); allowed = ir_raw_get_allowed_protocols();
} } else
return sprintf(tmp, "[builtin]\n");
IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
(long long)allowed, (long long)allowed,
...@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d, ...@@ -121,10 +122,14 @@ static ssize_t store_protocols(struct device *d,
int rc, i, count = 0; int rc, i, count = 0;
unsigned long flags; unsigned long flags;
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
type = ir_dev->rc_tab.ir_type; type = ir_dev->rc_tab.ir_type;
else else if (ir_dev->raw)
type = ir_dev->raw->enabled_protocols; type = ir_dev->raw->enabled_protocols;
else {
IR_dprintk(1, "Protocol switching not supported\n");
return -EINVAL;
}
while ((tmp = strsep((char **) &data, " \n")) != NULL) { while ((tmp = strsep((char **) &data, " \n")) != NULL) {
if (!*tmp) if (!*tmp)
...@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d, ...@@ -185,7 +190,7 @@ static ssize_t store_protocols(struct device *d,
} }
} }
if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) { if (ir_dev->props && ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
spin_lock_irqsave(&ir_dev->rc_tab.lock, flags); spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
ir_dev->rc_tab.ir_type = type; ir_dev->rc_tab.ir_type = type;
spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags); spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
......
...@@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = { ...@@ -19,6 +19,7 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0416, KEY_PLAY }, { 0x800f0416, KEY_PLAY },
{ 0x800f0418, KEY_PAUSE }, { 0x800f0418, KEY_PAUSE },
{ 0x800f046e, KEY_PLAYPAUSE },
{ 0x800f0419, KEY_STOP }, { 0x800f0419, KEY_STOP },
{ 0x800f0417, KEY_RECORD }, { 0x800f0417, KEY_RECORD },
...@@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = { ...@@ -37,6 +38,8 @@ static struct ir_scancode rc6_mce[] = {
{ 0x800f0411, KEY_VOLUMEDOWN }, { 0x800f0411, KEY_VOLUMEDOWN },
{ 0x800f0412, KEY_CHANNELUP }, { 0x800f0412, KEY_CHANNELUP },
{ 0x800f0413, KEY_CHANNELDOWN }, { 0x800f0413, KEY_CHANNELDOWN },
{ 0x800f043a, KEY_BRIGHTNESSUP },
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
{ 0x800f0401, KEY_NUMERIC_1 }, { 0x800f0401, KEY_NUMERIC_1 },
{ 0x800f0402, KEY_NUMERIC_2 }, { 0x800f0402, KEY_NUMERIC_2 },
......
...@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = { ...@@ -120,6 +120,10 @@ static struct usb_device_id mceusb_dev_table[] = {
{ USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, { USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
/* Philips eHome Infrared Transceiver */ /* Philips eHome Infrared Transceiver */
{ USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
/* Philips/Spinel plus IR transceiver for ASUS */
{ USB_DEVICE(VENDOR_PHILIPS, 0x206c) },
/* Philips/Spinel plus IR transceiver for ASUS */
{ USB_DEVICE(VENDOR_PHILIPS, 0x2088) },
/* Realtek MCE IR Receiver */ /* Realtek MCE IR Receiver */
{ USB_DEVICE(VENDOR_REALTEK, 0x0161) }, { USB_DEVICE(VENDOR_REALTEK, 0x0161) },
/* SMK/Toshiba G83C0004D410 */ /* SMK/Toshiba G83C0004D410 */
......
...@@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf, ...@@ -673,9 +673,6 @@ static int dib0700_probe(struct usb_interface *intf,
else else
dev->props.rc.core.bulk_mode = false; dev->props.rc.core.bulk_mode = false;
/* Need a higher delay, to avoid wrong repeat */
dev->rc_input_dev->rep[REP_DELAY] = 500;
dib0700_rc_setup(dev); dib0700_rc_setup(dev);
return 0; return 0;
......
...@@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) ...@@ -940,6 +940,58 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
return adap->fe == NULL ? -ENODEV : 0; return adap->fe == NULL ? -ENODEV : 0;
} }
/* STK7770P */
static struct dib7000p_config dib7770p_dib7000p_config = {
.output_mpeg2_in_188_bytes = 1,
.agc_config_count = 1,
.agc = &dib7070_agc_config,
.bw = &dib7070_bw_config_12_mhz,
.tuner_is_baseband = 1,
.spur_protect = 1,
.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
.hostbus_diversity = 1,
.enable_current_mirror = 1,
.disable_sample_and_hold = 0,
};
static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
{
struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
else
dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
dib0700_ctrl_clock(adap->dev, 72, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
&dib7770p_dib7000p_config) != 0) {
err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
__func__);
return -ENODEV;
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&dib7770p_dib7000p_config);
return adap->fe == NULL ? -ENODEV : 0;
}
/* DIB807x generic */ /* DIB807x generic */
static struct dibx000_agc_config dib807x_agc_config[2] = { static struct dibx000_agc_config dib807x_agc_config[2] = {
{ {
...@@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = { ...@@ -1781,7 +1833,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) }, /* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) }, { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) }, { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
{ USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) }, { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) }, /* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
...@@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { ...@@ -2406,7 +2458,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.pid_filter_count = 32, .pid_filter_count = 32,
.pid_filter = stk70x0p_pid_filter, .pid_filter = stk70x0p_pid_filter,
.pid_filter_ctrl = stk70x0p_pid_filter_ctrl, .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
.frontend_attach = stk7070p_frontend_attach, .frontend_attach = stk7770p_frontend_attach,
.tuner_attach = dib7770p_tuner_attach, .tuner_attach = dib7770p_tuner_attach,
DIB0700_DEFAULT_STREAMING_CONFIG(0x02), DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
......
...@@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev, ...@@ -483,9 +483,7 @@ static int opera1_xilinx_load_firmware(struct usb_device *dev,
} }
} }
kfree(p); kfree(p);
if (fw) { release_firmware(fw);
release_firmware(fw);
}
return ret; return ret;
} }
......
...@@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad ...@@ -260,6 +260,9 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
dib7000p_write_word(state, 908, reg_908); dib7000p_write_word(state, 908, reg_908);
dib7000p_write_word(state, 909, reg_909); dib7000p_write_word(state, 909, reg_909);
} }
...@@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte ...@@ -778,7 +781,10 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
default: default:
case GUARD_INTERVAL_1_32: value *= 1; break; case GUARD_INTERVAL_1_32: value *= 1; break;
} }
state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO if (state->cfg.diversity_delay == 0)
state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
else
state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo
/* deactive the possibility of diversity reception if extended interleaver */ /* deactive the possibility of diversity reception if extended interleaver */
state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
......
...@@ -33,6 +33,11 @@ struct dib7000p_config { ...@@ -33,6 +33,11 @@ struct dib7000p_config {
int (*agc_control) (struct dvb_frontend *, u8 before); int (*agc_control) (struct dvb_frontend *, u8 before);
u8 output_mode; u8 output_mode;
u8 disable_sample_and_hold : 1;
u8 enable_current_mirror : 1;
u8 diversity_delay;
}; };
#define DEFAULT_DIB7000P_I2C_ADDRESS 18 #define DEFAULT_DIB7000P_I2C_ADDRESS 18
......
...@@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse); ...@@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
* *
* @return pointer to descriptor on success, NULL on error. * @return pointer to descriptor on success, NULL on error.
*/ */
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
{ {
struct smscore_buffer_t *cb = NULL; struct smscore_buffer_t *cb = NULL;
unsigned long flags; unsigned long flags;
DEFINE_WAIT(wait);
spin_lock_irqsave(&coredev->bufferslock, flags); spin_lock_irqsave(&coredev->bufferslock, flags);
if (!list_empty(&coredev->buffers)) {
/* This function must return a valid buffer, since the buffer list is cb = (struct smscore_buffer_t *) coredev->buffers.next;
* finite, we check that there is an available buffer, if not, we wait list_del(&cb->entry);
* until such buffer become available.
*/
prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
if (list_empty(&coredev->buffers)) {
spin_unlock_irqrestore(&coredev->bufferslock, flags);
schedule();
spin_lock_irqsave(&coredev->bufferslock, flags);
} }
spin_unlock_irqrestore(&coredev->bufferslock, flags);
return cb;
}
finish_wait(&coredev->buffer_mng_waitq, &wait); struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
{
cb = (struct smscore_buffer_t *) coredev->buffers.next; struct smscore_buffer_t *cb = NULL;
list_del(&cb->entry);
spin_unlock_irqrestore(&coredev->bufferslock, flags); wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
return cb; return cb;
} }
......
...@@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client, ...@@ -395,7 +395,7 @@ static int __devinit si470x_i2c_probe(struct i2c_client *client,
radio->registers[POWERCFG] = POWERCFG_ENABLE; radio->registers[POWERCFG] = POWERCFG_ENABLE;
if (si470x_set_register(radio, POWERCFG) < 0) { if (si470x_set_register(radio, POWERCFG) < 0) {
retval = -EIO; retval = -EIO;
goto err_all; goto err_video;
} }
msleep(110); msleep(110);
......
...@@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video ...@@ -11,4 +11,5 @@ EXTRA_CFLAGS += -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/common/tuners EXTRA_CFLAGS += -Idrivers/media/common/tuners
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <media/v4l2-chip-ident.h> #include <media/v4l2-chip-ident.h>
#include <media/cx25840.h> #include <media/cx25840.h>
#include "dvb-usb-ids.h"
#include "xc5000.h" #include "xc5000.h"
#include "cx231xx.h" #include "cx231xx.h"
...@@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = { ...@@ -175,6 +176,8 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_CNXT_RDE_250}, .driver_info = CX231XX_BOARD_CNXT_RDE_250},
{USB_DEVICE(0x0572, 0x58A1), {USB_DEVICE(0x0572, 0x58A1),
.driver_info = CX231XX_BOARD_CNXT_RDU_250}, .driver_info = CX231XX_BOARD_CNXT_RDU_250},
{USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000,0x4fff),
.driver_info = CX231XX_BOARD_UNKNOWN},
{}, {},
}; };
...@@ -226,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev) ...@@ -226,14 +229,16 @@ void cx231xx_pre_card_setup(struct cx231xx *dev)
dev->board.name, dev->model); dev->board.name, dev->model);
/* set the direction for GPIO pins */ /* set the direction for GPIO pins */
cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1); if (dev->board.tuner_gpio) {
cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1); cx231xx_set_gpio_direction(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1); cx231xx_set_gpio_value(dev, dev->board.tuner_gpio->bit, 1);
cx231xx_set_gpio_direction(dev, dev->board.tuner_sif_gpio, 1);
/* request some modules if any required */ /* request some modules if any required */
/* reset the Tuner */ /* reset the Tuner */
cx231xx_gpio_set(dev, dev->board.tuner_gpio); cx231xx_gpio_set(dev, dev->board.tuner_gpio);
}
/* set the mode to Analog mode initially */ /* set the mode to Analog mode initially */
cx231xx_set_mode(dev, CX231XX_ANALOG_MODE); cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
......
...@@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client, ...@@ -1996,7 +1996,7 @@ static int cx25840_probe(struct i2c_client *client,
state->volume = v4l2_ctrl_new_std(&state->hdl, state->volume = v4l2_ctrl_new_std(&state->hdl,
&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
0, 65335, 65535 / 100, default_volume); 0, 65535, 65535 / 100, default_volume);
state->mute = v4l2_ctrl_new_std(&state->hdl, state->mute = v4l2_ctrl_new_std(&state->hdl,
&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE, &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
0, 1, 1, 0); 0, 1, 1, 0);
......
...@@ -17,7 +17,7 @@ config VIDEO_CX88 ...@@ -17,7 +17,7 @@ config VIDEO_CX88
config VIDEO_CX88_ALSA config VIDEO_CX88_ALSA
tristate "Conexant 2388x DMA audio support" tristate "Conexant 2388x DMA audio support"
depends on VIDEO_CX88 && SND && EXPERIMENTAL depends on VIDEO_CX88 && SND
select SND_PCM select SND_PCM
---help--- ---help---
This is a video4linux driver for direct (DMA) audio on This is a video4linux driver for direct (DMA) audio on
......
...@@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev, ...@@ -223,6 +223,7 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
usb_rcvintpipe(dev, ep->bEndpointAddress), usb_rcvintpipe(dev, ep->bEndpointAddress),
buffer, buffer_len, buffer, buffer_len,
int_irq, (void *)gspca_dev, interval); int_irq, (void *)gspca_dev, interval);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
gspca_dev->int_urb = urb; gspca_dev->int_urb = urb;
ret = usb_submit_urb(urb, GFP_KERNEL); ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) { if (ret < 0) {
......
...@@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ...@@ -2357,8 +2357,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
(data[33] << 10); (data[33] << 10);
avg_lum >>= 9; avg_lum >>= 9;
atomic_set(&sd->avg_lum, avg_lum); atomic_set(&sd->avg_lum, avg_lum);
gspca_frame_add(gspca_dev, LAST_PACKET, gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
data, len);
return; return;
} }
if (gspca_dev->last_packet_type == LAST_PACKET) { if (gspca_dev->last_packet_type == LAST_PACKET) {
......
...@@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar ...@@ -466,6 +466,8 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
struct fb_vblank vblank; struct fb_vblank vblank;
u32 trace; u32 trace;
memset(&vblank, 0, sizeof(struct fb_vblank));
vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT | vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
FB_VBLANK_HAVE_VSYNC; FB_VBLANK_HAVE_VSYNC;
trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16; trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
......
...@@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx, ...@@ -239,7 +239,7 @@ static int device_process(struct m2mtest_ctx *ctx,
return -EFAULT; return -EFAULT;
} }
if (in_buf->vb.size < out_buf->vb.size) { if (in_buf->vb.size > out_buf->vb.size) {
v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
return -EINVAL; return -EINVAL;
} }
...@@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev) ...@@ -1014,6 +1014,7 @@ static int m2mtest_remove(struct platform_device *pdev)
v4l2_m2m_release(dev->m2m_dev); v4l2_m2m_release(dev->m2m_dev);
del_timer_sync(&dev->timer); del_timer_sync(&dev->timer);
video_unregister_device(dev->vfd); video_unregister_device(dev->vfd);
video_device_release(dev->vfd);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev); kfree(dev);
......
...@@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) ...@@ -447,6 +447,9 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n", dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
__func__, rect.left, rect.top, rect.width, rect.height); __func__, rect.left, rect.top, rect.width, rect.height);
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
ret = mt9m111_make_rect(client, &rect); ret = mt9m111_make_rect(client, &rect);
if (!ret) if (!ret)
mt9m111->rect = rect; mt9m111->rect = rect;
...@@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) ...@@ -466,12 +469,14 @@ static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
{ {
if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
a->bounds.left = MT9M111_MIN_DARK_COLS; a->bounds.left = MT9M111_MIN_DARK_COLS;
a->bounds.top = MT9M111_MIN_DARK_ROWS; a->bounds.top = MT9M111_MIN_DARK_ROWS;
a->bounds.width = MT9M111_MAX_WIDTH; a->bounds.width = MT9M111_MAX_WIDTH;
a->bounds.height = MT9M111_MAX_HEIGHT; a->bounds.height = MT9M111_MAX_HEIGHT;
a->defrect = a->bounds; a->defrect = a->bounds;
a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
a->pixelaspect.numerator = 1; a->pixelaspect.numerator = 1;
a->pixelaspect.denominator = 1; a->pixelaspect.denominator = 1;
...@@ -487,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd, ...@@ -487,6 +492,7 @@ static int mt9m111_g_fmt(struct v4l2_subdev *sd,
mf->width = mt9m111->rect.width; mf->width = mt9m111->rect.width;
mf->height = mt9m111->rect.height; mf->height = mt9m111->rect.height;
mf->code = mt9m111->fmt->code; mf->code = mt9m111->fmt->code;
mf->colorspace = mt9m111->fmt->colorspace;
mf->field = V4L2_FIELD_NONE; mf->field = V4L2_FIELD_NONE;
return 0; return 0;
......
...@@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, ...@@ -402,9 +402,6 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC) if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
return -EINVAL; return -EINVAL;
break; break;
case 0:
/* No format change, only geometry */
break;
default: default:
return -EINVAL; return -EINVAL;
} }
......
...@@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, ...@@ -378,6 +378,9 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
spin_lock_irqsave(&pcdev->lock, flags); spin_lock_irqsave(&pcdev->lock, flags);
if (*fb_active == NULL)
goto out;
vb = &(*fb_active)->vb; vb = &(*fb_active)->vb;
dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
vb, vb->baddr, vb->bsize); vb, vb->baddr, vb->bsize);
...@@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb, ...@@ -402,6 +405,7 @@ static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
*fb_active = buf; *fb_active = buf;
out:
spin_unlock_irqrestore(&pcdev->lock, flags); spin_unlock_irqrestore(&pcdev->lock, flags);
} }
......
...@@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, ...@@ -513,7 +513,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
if (ret >= 0) { if (ret >= 0) {
ret = pvr2_ctrl_range_check(cptr,*valptr); ret = pvr2_ctrl_range_check(cptr,*valptr);
} }
if (maskptr) *maskptr = ~0; *maskptr = ~0;
} else if (cptr->info->type == pvr2_ctl_bool) { } else if (cptr->info->type == pvr2_ctl_bool) {
ret = parse_token(ptr,len,valptr,boolNames, ret = parse_token(ptr,len,valptr,boolNames,
ARRAY_SIZE(boolNames)); ARRAY_SIZE(boolNames));
...@@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, ...@@ -522,7 +522,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
} else if (ret == 0) { } else if (ret == 0) {
*valptr = (*valptr & 1) ? !0 : 0; *valptr = (*valptr & 1) ? !0 : 0;
} }
if (maskptr) *maskptr = 1; *maskptr = 1;
} else if (cptr->info->type == pvr2_ctl_enum) { } else if (cptr->info->type == pvr2_ctl_enum) {
ret = parse_token( ret = parse_token(
ptr,len,valptr, ptr,len,valptr,
...@@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, ...@@ -531,7 +531,7 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
if (ret >= 0) { if (ret >= 0) {
ret = pvr2_ctrl_range_check(cptr,*valptr); ret = pvr2_ctrl_range_check(cptr,*valptr);
} }
if (maskptr) *maskptr = ~0; *maskptr = ~0;
} else if (cptr->info->type == pvr2_ctl_bitmask) { } else if (cptr->info->type == pvr2_ctl_bitmask) {
ret = parse_tlist( ret = parse_tlist(
ptr,len,maskptr,valptr, ptr,len,maskptr,valptr,
......
...@@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx) ...@@ -393,6 +393,37 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
dbg("ctx->out_order_1p= %d", ctx->out_order_1p); dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
} }
static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
{
struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
f->dma_offset.y_h = f->offs_h;
if (!variant->pix_hoff)
f->dma_offset.y_h *= (f->fmt->depth >> 3);
f->dma_offset.y_v = f->offs_v;
f->dma_offset.cb_h = f->offs_h;
f->dma_offset.cb_v = f->offs_v;
f->dma_offset.cr_h = f->offs_h;
f->dma_offset.cr_v = f->offs_v;
if (!variant->pix_hoff) {
if (f->fmt->planes_cnt == 3) {
f->dma_offset.cb_h >>= 1;
f->dma_offset.cr_h >>= 1;
}
if (f->fmt->color == S5P_FIMC_YCBCR420) {
f->dma_offset.cb_v >>= 1;
f->dma_offset.cr_v >>= 1;
}
}
dbg("in_offset: color= %d, y_h= %d, y_v= %d",
f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
}
/** /**
* fimc_prepare_config - check dimensions, operation and color mode * fimc_prepare_config - check dimensions, operation and color mode
* and pre-calculate offset and the scaling coefficients. * and pre-calculate offset and the scaling coefficients.
...@@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) ...@@ -406,7 +437,6 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
{ {
struct fimc_frame *s_frame, *d_frame; struct fimc_frame *s_frame, *d_frame;
struct fimc_vid_buffer *buf = NULL; struct fimc_vid_buffer *buf = NULL;
struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
int ret = 0; int ret = 0;
s_frame = &ctx->s_frame; s_frame = &ctx->s_frame;
...@@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) ...@@ -419,61 +449,16 @@ static int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
swap(d_frame->width, d_frame->height); swap(d_frame->width, d_frame->height);
} }
/* Prepare the output offset ratios for scaler. */ /* Prepare the DMA offset ratios for scaler. */
d_frame->dma_offset.y_h = d_frame->offs_h; fimc_prepare_dma_offset(ctx, &ctx->s_frame);
if (!variant->pix_hoff) fimc_prepare_dma_offset(ctx, &ctx->d_frame);
d_frame->dma_offset.y_h *= (d_frame->fmt->depth >> 3);
d_frame->dma_offset.y_v = d_frame->offs_v;
d_frame->dma_offset.cb_h = d_frame->offs_h;
d_frame->dma_offset.cb_v = d_frame->offs_v;
d_frame->dma_offset.cr_h = d_frame->offs_h;
d_frame->dma_offset.cr_v = d_frame->offs_v;
if (!variant->pix_hoff && d_frame->fmt->planes_cnt == 3) {
d_frame->dma_offset.cb_h >>= 1;
d_frame->dma_offset.cb_v >>= 1;
d_frame->dma_offset.cr_h >>= 1;
d_frame->dma_offset.cr_v >>= 1;
}
dbg("out offset: color= %d, y_h= %d, y_v= %d",
d_frame->fmt->color,
d_frame->dma_offset.y_h, d_frame->dma_offset.y_v);
/* Prepare the input offset ratios for scaler. */
s_frame->dma_offset.y_h = s_frame->offs_h;
if (!variant->pix_hoff)
s_frame->dma_offset.y_h *= (s_frame->fmt->depth >> 3);
s_frame->dma_offset.y_v = s_frame->offs_v;
s_frame->dma_offset.cb_h = s_frame->offs_h;
s_frame->dma_offset.cb_v = s_frame->offs_v;
s_frame->dma_offset.cr_h = s_frame->offs_h;
s_frame->dma_offset.cr_v = s_frame->offs_v;
if (!variant->pix_hoff && s_frame->fmt->planes_cnt == 3) {
s_frame->dma_offset.cb_h >>= 1;
s_frame->dma_offset.cb_v >>= 1;
s_frame->dma_offset.cr_h >>= 1;
s_frame->dma_offset.cr_v >>= 1;
}
dbg("in offset: color= %d, y_h= %d, y_v= %d",
s_frame->fmt->color, s_frame->dma_offset.y_h,
s_frame->dma_offset.y_v);
fimc_set_yuv_order(ctx);
/* Check against the scaler ratio. */
if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) || if (s_frame->height > (SCALER_MAX_VRATIO * d_frame->height) ||
s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) { s_frame->width > (SCALER_MAX_HRATIO * d_frame->width)) {
err("out of scaler range"); err("out of scaler range");
return -EINVAL; return -EINVAL;
} }
fimc_set_yuv_order(ctx);
} }
/* Input DMA mode is not allowed when the scaler is disabled. */ /* Input DMA mode is not allowed when the scaler is disabled. */
...@@ -822,7 +807,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) ...@@ -822,7 +807,8 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
} else { } else {
v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
"Wrong buffer/video queue type (%d)\n", f->type); "Wrong buffer/video queue type (%d)\n", f->type);
return -EINVAL; ret = -EINVAL;
goto s_fmt_out;
} }
pix = &f->fmt.pix; pix = &f->fmt.pix;
...@@ -1414,8 +1400,10 @@ static int fimc_probe(struct platform_device *pdev) ...@@ -1414,8 +1400,10 @@ static int fimc_probe(struct platform_device *pdev)
} }
fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev)); fimc->work_queue = create_workqueue(dev_name(&fimc->pdev->dev));
if (!fimc->work_queue) if (!fimc->work_queue) {
ret = -ENOMEM;
goto err_irq; goto err_irq;
}
ret = fimc_register_m2m_device(fimc); ret = fimc_register_m2m_device(fimc);
if (ret) if (ret)
...@@ -1492,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { ...@@ -1492,6 +1480,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = {
}; };
static struct samsung_fimc_variant fimc01_variant_s5pv210 = { static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
.pix_hoff = 1,
.has_inp_rot = 1, .has_inp_rot = 1,
.has_out_rot = 1, .has_out_rot = 1,
.min_inp_pixsize = 16, .min_inp_pixsize = 16,
...@@ -1506,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = { ...@@ -1506,6 +1495,7 @@ static struct samsung_fimc_variant fimc01_variant_s5pv210 = {
}; };
static struct samsung_fimc_variant fimc2_variant_s5pv210 = { static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
.pix_hoff = 1,
.min_inp_pixsize = 16, .min_inp_pixsize = 16,
.min_out_pixsize = 32, .min_out_pixsize = 32,
......
...@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = { ...@@ -4323,13 +4323,13 @@ struct saa7134_board saa7134_boards[] = {
}, },
[SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = { [SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM] = {
/* Beholder Intl. Ltd. 2008 */ /* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */ /* Dmitry Belimov <d.belimov@gmail.com> */
.name = "Beholder BeholdTV Columbus TVFM", .name = "Beholder BeholdTV Columbus TV/FM",
.audio_clock = 0x00187de7, .audio_clock = 0x00187de7,
.tuner_type = TUNER_ALPS_TSBE5_PAL, .tuner_type = TUNER_ALPS_TSBE5_PAL,
.radio_type = UNSET, .radio_type = TUNER_TEA5767,
.tuner_addr = ADDR_UNSET, .tuner_addr = 0xc2 >> 1,
.radio_addr = ADDR_UNSET, .radio_addr = 0xc0 >> 1,
.tda9887_conf = TDA9887_PRESENT, .tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x000A8004, .gpiomask = 0x000A8004,
.inputs = {{ .inputs = {{
......
...@@ -136,10 +136,11 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port, ...@@ -136,10 +136,11 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
int saa7164_buffer_dealloc(struct saa7164_tsport *port, int saa7164_buffer_dealloc(struct saa7164_tsport *port,
struct saa7164_buffer *buf) struct saa7164_buffer *buf)
{ {
struct saa7164_dev *dev = port->dev; struct saa7164_dev *dev;
if ((buf == 0) || (port == 0)) if (!buf || !port)
return SAA_ERR_BAD_PARAMETER; return SAA_ERR_BAD_PARAMETER;
dev = port->dev;
dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf); dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
......
...@@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev, ...@@ -486,6 +486,12 @@ static int uvc_parse_format(struct uvc_device *dev,
max(frame->dwFrameInterval[0], max(frame->dwFrameInterval[0],
frame->dwDefaultFrameInterval)); frame->dwDefaultFrameInterval));
if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
frame->bFrameIntervalType = 1;
frame->dwFrameInterval[0] =
frame->dwDefaultFrameInterval;
}
uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n", uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n",
frame->wWidth, frame->wHeight, frame->wWidth, frame->wHeight,
10000000/frame->dwDefaultFrameInterval, 10000000/frame->dwDefaultFrameInterval,
...@@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = { ...@@ -2026,6 +2032,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1, .bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 }, .bInterfaceProtocol = 0 },
/* Chicony CNF7129 (Asus EEE 100HE) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x04f2,
.idProduct = 0xb071,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE },
/* Alcor Micro AU3820 (Future Boy PC USB Webcam) */ /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO, | USB_DEVICE_ID_MATCH_INT_INFO,
...@@ -2091,6 +2106,15 @@ static struct usb_device_id uvc_ids[] = { ...@@ -2091,6 +2106,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceProtocol = 0, .bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_MINMAX .driver_info = UVC_QUIRK_PROBE_MINMAX
| UVC_QUIRK_PROBE_DEF }, | UVC_QUIRK_PROBE_DEF },
/* IMC Networks (Medion Akoya) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x13d3,
.idProduct = 0x5103,
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Syntek (HP Spartan) */ /* Syntek (HP Spartan) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO, | USB_DEVICE_ID_MATCH_INT_INFO,
......
...@@ -182,6 +182,7 @@ struct uvc_xu_control { ...@@ -182,6 +182,7 @@ struct uvc_xu_control {
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
#define UVC_QUIRK_PROBE_DEF 0x00000100 #define UVC_QUIRK_PROBE_DEF 0x00000100
#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200
/* Format flags */ /* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001 #define UVC_FMT_FLAG_COMPRESSED 0x00000001
......
...@@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q, ...@@ -393,8 +393,10 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
} }
/* read() method */ /* read() method */
dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); if (mem->vaddr) {
mem->vaddr = NULL; dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle);
mem->vaddr = NULL;
}
} }
EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); EXPORT_SYMBOL_GPL(videobuf_dma_contig_free);
......
...@@ -94,7 +94,7 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, ...@@ -94,7 +94,7 @@ static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt,
* must free the memory. * must free the memory.
*/ */
static struct scatterlist *videobuf_pages_to_sg(struct page **pages, static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
int nr_pages, int offset) int nr_pages, int offset, size_t size)
{ {
struct scatterlist *sglist; struct scatterlist *sglist;
int i; int i;
...@@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages, ...@@ -110,12 +110,14 @@ static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
/* DMA to highmem pages might not work */ /* DMA to highmem pages might not work */
goto highmem; goto highmem;
sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset); sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset);
size -= PAGE_SIZE - offset;
for (i = 1; i < nr_pages; i++) { for (i = 1; i < nr_pages; i++) {
if (NULL == pages[i]) if (NULL == pages[i])
goto nopage; goto nopage;
if (PageHighMem(pages[i])) if (PageHighMem(pages[i]))
goto highmem; goto highmem;
sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0); sg_set_page(&sglist[i], pages[i], min(PAGE_SIZE, size), 0);
size -= min(PAGE_SIZE, size);
} }
return sglist; return sglist;
...@@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, ...@@ -170,7 +172,8 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
first = (data & PAGE_MASK) >> PAGE_SHIFT; first = (data & PAGE_MASK) >> PAGE_SHIFT;
last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT;
dma->offset = data & ~PAGE_MASK; dma->offset = data & ~PAGE_MASK;
dma->size = size;
dma->nr_pages = last-first+1; dma->nr_pages = last-first+1;
dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL);
if (NULL == dma->pages) if (NULL == dma->pages)
...@@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma) ...@@ -252,7 +255,7 @@ int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
if (dma->pages) { if (dma->pages) {
dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages, dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
dma->offset); dma->offset, dma->size);
} }
if (dma->vaddr) { if (dma->vaddr) {
dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr, dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr,
......
config VIDEO_TM6000 config VIDEO_TM6000
tristate "TV Master TM5600/6000/6010 driver" tristate "TV Master TM5600/6000/6010 driver"
depends on VIDEO_DEV && I2C && INPUT && USB && EXPERIMENTAL depends on VIDEO_DEV && I2C && INPUT && IR_CORE && USB && EXPERIMENTAL
select VIDEO_TUNER select VIDEO_TUNER
select MEDIA_TUNER_XC2028 select MEDIA_TUNER_XC2028
select MEDIA_TUNER_XC5000 select MEDIA_TUNER_XC5000
......
...@@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable"); ...@@ -46,7 +46,7 @@ MODULE_PARM_DESC(enable_ir, "enable ir (default is enable");
} }
struct tm6000_ir_poll_result { struct tm6000_ir_poll_result {
u8 rc_data[4]; u16 rc_data;
}; };
struct tm6000_IR { struct tm6000_IR {
...@@ -60,9 +60,9 @@ struct tm6000_IR { ...@@ -60,9 +60,9 @@ struct tm6000_IR {
int polling; int polling;
struct delayed_work work; struct delayed_work work;
u8 wait:1; u8 wait:1;
u8 key:1;
struct urb *int_urb; struct urb *int_urb;
u8 *urb_data; u8 *urb_data;
u8 key:1;
int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
...@@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb) ...@@ -122,13 +122,14 @@ static void tm6000_ir_urb_received(struct urb *urb)
if (urb->status != 0) if (urb->status != 0)
printk(KERN_INFO "not ready\n"); printk(KERN_INFO "not ready\n");
else if (urb->actual_length > 0) else if (urb->actual_length > 0) {
memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
ir->key = 1; ir->key = 1;
}
rc = usb_submit_urb(urb, GFP_ATOMIC); rc = usb_submit_urb(urb, GFP_ATOMIC);
} }
...@@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir, ...@@ -140,30 +141,47 @@ static int default_polling_getkey(struct tm6000_IR *ir,
int rc; int rc;
u8 buf[2]; u8 buf[2];
if (ir->wait && !&dev->int_in) { if (ir->wait && !&dev->int_in)
poll_result->rc_data[0] = 0xff;
return 0; return 0;
}
if (&dev->int_in) { if (&dev->int_in) {
poll_result->rc_data[0] = ir->urb_data[0]; if (ir->ir.ir_type == IR_TYPE_RC5)
poll_result->rc_data[1] = ir->urb_data[1]; poll_result->rc_data = ir->urb_data[0];
else
poll_result->rc_data = ir->urb_data[0] | ir->urb_data[1] << 8;
} else { } else {
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
msleep(10); msleep(10);
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
msleep(10); msleep(10);
rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | if (ir->ir.ir_type == IR_TYPE_RC5) {
USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1); rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
REQ_02_GET_IR_CODE, 0, 0, buf, 1);
msleep(10); msleep(10);
dprintk("read data=%02x\n", buf[0]); dprintk("read data=%02x\n", buf[0]);
if (rc < 0) if (rc < 0)
return rc; return rc;
poll_result->rc_data[0] = buf[0]; poll_result->rc_data = buf[0];
} else {
rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
REQ_02_GET_IR_CODE, 0, 0, buf, 2);
msleep(10);
dprintk("read data=%04x\n", buf[0] | buf[1] << 8);
if (rc < 0)
return rc;
poll_result->rc_data = buf[0] | buf[1] << 8;
}
if ((poll_result->rc_data & 0x00ff) != 0xff)
ir->key = 1;
} }
return 0; return 0;
} }
...@@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir) ...@@ -180,12 +198,11 @@ static void tm6000_ir_handle_key(struct tm6000_IR *ir)
return; return;
} }
dprintk("ir->get_key result data=%02x %02x\n", dprintk("ir->get_key result data=%04x\n", poll_result.rc_data);
poll_result.rc_data[0], poll_result.rc_data[1]);
if (poll_result.rc_data[0] != 0xff && ir->key == 1) { if (ir->key) {
ir_input_keydown(ir->input->input_dev, &ir->ir, ir_input_keydown(ir->input->input_dev, &ir->ir,
poll_result.rc_data[0] | poll_result.rc_data[1] << 8); (u32)poll_result.rc_data);
ir_input_nokey(ir->input->input_dev, &ir->ir); ir_input_nokey(ir->input->input_dev, &ir->ir);
ir->key = 0; ir->key = 0;
......
...@@ -48,6 +48,7 @@ struct videobuf_dmabuf { ...@@ -48,6 +48,7 @@ struct videobuf_dmabuf {
/* for userland buffer */ /* for userland buffer */
int offset; int offset;
size_t size;
struct page **pages; struct page **pages;
/* for kernel buffers */ /* for kernel buffers */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册