Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (25 commits) em28xx: remove backward compat macro added on a previous fix V4L/DVB (9748): em28xx: fix compile warning V4L/DVB (9743): em28xx: fix oops audio V4L/DVB (9742): em28xx-alsa: implement another locking schema V4L/DVB (9732): sms1xxx: use new firmware for Hauppauge WinTV MiniStick V4L/DVB (9691): gspca: Move the video device to a separate area. V4L/DVB (9690): gspca: Lock the subdrivers via module_get/put. V4L/DVB (9689): gspca: Memory leak when disconnect while streaming. V4L/DVB (9668): em28xx: fix a race condition with hald V4L/DVB (9664): af9015: don't reconnect device in USB-bus V4L/DVB (9647): em28xx: void having two concurrent control URB's V4L/DVB (9646): em28xx: avoid allocating/dealocating memory on every control urb V4L/DVB (9645): em28xx: Avoid memory leaks if registration fails V4L/DVB (9639): Make dib0700 remote control support work with firmware v1.20 V4L/DVB (9635): v4l: s2255drv fix firmware test on big-endian V4L/DVB (9634): Make sure the i2c gate is open before powering down tuner V4L/DVB (9632): make em28xx aux audio input work V4L/DVB (9631): Make s2api work for ATSC support V4L/DVB (9627): em28xx: Avoid i2c register error for boards without eeprom V4L/DVB (9608): Fix section mismatch warning for dm1105 during make ...
This commit is contained in:
Коммит
0d815142d1
|
@ -376,7 +376,7 @@ static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb)
|
|||
pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr);
|
||||
}
|
||||
|
||||
static void __devinit dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
|
||||
static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb)
|
||||
{
|
||||
outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK));
|
||||
outb(1, dm_io_mem(DM1105_CR));
|
||||
|
|
|
@ -585,6 +585,8 @@ restart:
|
|||
if (fe->ops.set_voltage)
|
||||
fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF);
|
||||
if (fe->ops.tuner_ops.sleep) {
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
fe->ops.tuner_ops.sleep(fe);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
@ -934,7 +936,8 @@ void dtv_property_dump(struct dtv_property *tvp)
|
|||
int is_legacy_delivery_system(fe_delivery_system_t s)
|
||||
{
|
||||
if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) ||
|
||||
(s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS))
|
||||
(s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) ||
|
||||
(s == SYS_ATSC))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -681,12 +681,6 @@ static int af9015_download_firmware(struct usb_device *udev,
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* firmware is running, reconnect device in the usb bus */
|
||||
req.cmd = RECONNECT_USB;
|
||||
ret = af9015_rw_udev(udev, &req);
|
||||
if (ret)
|
||||
err("reconnect failed: %d", ret);
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1208,6 +1202,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.download_firmware = af9015_download_firmware,
|
||||
.firmware = "dvb-usb-af9015.fw",
|
||||
.no_reconnect = 1,
|
||||
|
||||
.size_of_priv = sizeof(struct af9015_state), \
|
||||
|
||||
|
@ -1306,6 +1301,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
|
|||
.usb_ctrl = DEVICE_SPECIFIC,
|
||||
.download_firmware = af9015_download_firmware,
|
||||
.firmware = "dvb-usb-af9015.fw",
|
||||
.no_reconnect = 1,
|
||||
|
||||
.size_of_priv = sizeof(struct af9015_state), \
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ extern int dvb_usb_dib0700_debug;
|
|||
|
||||
#define REQUEST_I2C_READ 0x2
|
||||
#define REQUEST_I2C_WRITE 0x3
|
||||
#define REQUEST_POLL_RC 0x4
|
||||
#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
|
||||
#define REQUEST_JUMPRAM 0x8
|
||||
#define REQUEST_SET_CLOCK 0xB
|
||||
#define REQUEST_SET_GPIO 0xC
|
||||
|
@ -40,11 +40,14 @@ struct dib0700_state {
|
|||
u16 mt2060_if1[2];
|
||||
u8 rc_toggle;
|
||||
u8 rc_counter;
|
||||
u8 rc_func_version;
|
||||
u8 is_dib7000pc;
|
||||
u8 fw_use_new_i2c_api;
|
||||
u8 disable_streaming_master_mode;
|
||||
};
|
||||
|
||||
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
|
||||
u32 *romversion, u32 *ramversion, u32 *fwtype);
|
||||
extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
|
||||
extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
|
||||
extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
|
||||
|
|
|
@ -19,6 +19,22 @@ MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (defau
|
|||
|
||||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||
|
||||
|
||||
int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
|
||||
u32 *romversion, u32 *ramversion, u32 *fwtype)
|
||||
{
|
||||
u8 b[16];
|
||||
int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
|
||||
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];
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* expecting rx buffer: request data[0] data[1] ... data[2] */
|
||||
static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ static struct mt2060_config bristol_mt2060_config[2] = {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
|
||||
.band_caps = BAND_VHF | BAND_UHF,
|
||||
.setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
|
||||
|
@ -451,8 +452,13 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
|
|||
|
||||
/* Number of keypresses to ignore before start repeating */
|
||||
#define RC_REPEAT_DELAY 2
|
||||
#define RC_REPEAT_DELAY_V1_20 5
|
||||
|
||||
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
|
||||
|
||||
/* Used by firmware versions < 1.20 (deprecated) */
|
||||
static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
|
||||
int *state)
|
||||
{
|
||||
u8 key[4];
|
||||
int i;
|
||||
|
@ -529,6 +535,137 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is the structure of the RC response packet starting in firmware 1.20 */
|
||||
struct dib0700_rc_response {
|
||||
u8 report_id;
|
||||
u8 data_state;
|
||||
u8 system_msb;
|
||||
u8 system_lsb;
|
||||
u8 data;
|
||||
u8 not_data;
|
||||
};
|
||||
|
||||
/* This supports the new IR response format for firmware v1.20 */
|
||||
static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
|
||||
int *state)
|
||||
{
|
||||
struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
|
||||
struct dib0700_state *st = d->priv;
|
||||
struct dib0700_rc_response poll_reply;
|
||||
u8 buf[6];
|
||||
int i;
|
||||
int status;
|
||||
int actlen;
|
||||
int found = 0;
|
||||
|
||||
/* Set initial results in case we exit the function early */
|
||||
*event = 0;
|
||||
*state = REMOTE_NO_KEY_PRESSED;
|
||||
|
||||
/* Firmware v1.20 provides RC data via bulk endpoint 1 */
|
||||
status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf,
|
||||
sizeof(buf), &actlen, 50);
|
||||
if (status < 0) {
|
||||
/* No data available (meaning no key press) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (actlen != sizeof(buf)) {
|
||||
/* We didn't get back the 6 byte message we expected */
|
||||
err("Unexpected RC response size [%d]", actlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
poll_reply.report_id = buf[0];
|
||||
poll_reply.data_state = buf[1];
|
||||
poll_reply.system_msb = buf[2];
|
||||
poll_reply.system_lsb = buf[3];
|
||||
poll_reply.data = buf[4];
|
||||
poll_reply.not_data = buf[5];
|
||||
|
||||
/*
|
||||
info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n",
|
||||
poll_reply.report_id, poll_reply.data_state,
|
||||
poll_reply.system_msb, poll_reply.system_lsb,
|
||||
poll_reply.data, poll_reply.not_data);
|
||||
*/
|
||||
|
||||
if ((poll_reply.data + poll_reply.not_data) != 0xff) {
|
||||
/* Key failed integrity check */
|
||||
err("key failed integrity check: %02x %02x %02x %02x",
|
||||
poll_reply.system_msb, poll_reply.system_lsb,
|
||||
poll_reply.data, poll_reply.not_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the key in the map */
|
||||
for (i = 0; i < d->props.rc_key_map_size; i++) {
|
||||
if (keymap[i].custom == poll_reply.system_lsb &&
|
||||
keymap[i].data == poll_reply.data) {
|
||||
*event = keymap[i].event;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == 0) {
|
||||
err("Unknown remote controller key: %02x %02x %02x %02x",
|
||||
poll_reply.system_msb, poll_reply.system_lsb,
|
||||
poll_reply.data, poll_reply.not_data);
|
||||
d->last_event = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (poll_reply.data_state == 1) {
|
||||
/* New key hit */
|
||||
st->rc_counter = 0;
|
||||
*event = keymap[i].event;
|
||||
*state = REMOTE_KEY_PRESSED;
|
||||
d->last_event = keymap[i].event;
|
||||
} else if (poll_reply.data_state == 2) {
|
||||
/* Key repeated */
|
||||
st->rc_counter++;
|
||||
|
||||
/* prevents unwanted double hits */
|
||||
if (st->rc_counter > RC_REPEAT_DELAY_V1_20) {
|
||||
*event = d->last_event;
|
||||
*state = REMOTE_KEY_PRESSED;
|
||||
st->rc_counter = RC_REPEAT_DELAY_V1_20;
|
||||
}
|
||||
} else {
|
||||
err("Unknown data state [%d]", poll_reply.data_state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
{
|
||||
struct dib0700_state *st = d->priv;
|
||||
|
||||
/* Because some people may have improperly named firmware files,
|
||||
let's figure out whether to use the new firmware call or the legacy
|
||||
call based on the firmware version embedded in the file */
|
||||
if (st->rc_func_version == 0) {
|
||||
u32 hwver, romver, ramver, fwtype;
|
||||
int ret = dib0700_get_version(d, &hwver, &romver, &ramver,
|
||||
&fwtype);
|
||||
if (ret < 0) {
|
||||
err("Could not determine version info");
|
||||
return -1;
|
||||
}
|
||||
if (ramver < 0x10200)
|
||||
st->rc_func_version = 1;
|
||||
else
|
||||
st->rc_func_version = 2;
|
||||
}
|
||||
|
||||
if (st->rc_func_version == 2)
|
||||
return dib0700_rc_query_v1_20(d, event, state);
|
||||
else
|
||||
return dib0700_rc_query_legacy(d, event, state);
|
||||
}
|
||||
|
||||
static struct dvb_usb_rc_key dib0700_rc_keys[] = {
|
||||
/* Key codes for the tiny Pinnacle remote*/
|
||||
{ 0x07, 0x00, KEY_MUTE },
|
||||
|
|
|
@ -135,7 +135,7 @@ stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num])
|
|||
|
||||
static int usb_bulk_urb_init(struct usb_data_stream *stream)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
|
||||
stream->props.u.bulk.buffersize)) < 0)
|
||||
|
@ -143,9 +143,13 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream)
|
|||
|
||||
/* allocate the URBs */
|
||||
for (i = 0; i < stream->props.count; i++) {
|
||||
if ((stream->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
|
||||
stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!stream->urb_list[i]) {
|
||||
deb_mem("not enough memory for urb_alloc_urb!.\n");
|
||||
for (j = 0; j < i; j++)
|
||||
usb_free_urb(stream->urb_list[i]);
|
||||
return -ENOMEM;
|
||||
|
||||
}
|
||||
usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
|
||||
usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
|
||||
stream->buf_list[i],
|
||||
|
@ -170,9 +174,14 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream)
|
|||
for (i = 0; i < stream->props.count; i++) {
|
||||
struct urb *urb;
|
||||
int frame_offset = 0;
|
||||
if ((stream->urb_list[i] =
|
||||
usb_alloc_urb(stream->props.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
|
||||
|
||||
stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
|
||||
if (!stream->urb_list[i]) {
|
||||
deb_mem("not enough memory for urb_alloc_urb!\n");
|
||||
for (j = 0; j < i; j++)
|
||||
usb_free_urb(stream->urb_list[i]);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
urb = stream->urb_list[i];
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ static struct sms_board sms_boards[] = {
|
|||
[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
|
||||
.name = "Hauppauge WinTV MiniStick",
|
||||
.type = SMS_NOVA_B0,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -808,6 +808,12 @@ static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
|
|||
ISO_BUF_COUNT,
|
||||
&ttusb->iso_dma_handle);
|
||||
|
||||
if (!ttusb->iso_buffer) {
|
||||
dprintk("%s: pci_alloc_consistent - not enough memory\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(ttusb->iso_buffer, 0,
|
||||
ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
|
||||
|
||||
|
@ -1659,7 +1665,14 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
|
|||
|
||||
ttusb_setup_interfaces(ttusb);
|
||||
|
||||
ttusb_alloc_iso_urbs(ttusb);
|
||||
result = ttusb_alloc_iso_urbs(ttusb);
|
||||
if (result < 0) {
|
||||
dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
|
||||
mutex_unlock(&ttusb->semi2c);
|
||||
kfree(ttusb);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ttusb_init_controller(ttusb))
|
||||
printk("ttusb_init_controller: error\n");
|
||||
|
||||
|
|
|
@ -1157,6 +1157,12 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
|
|||
ISO_BUF_COUNT),
|
||||
&dec->iso_dma_handle);
|
||||
|
||||
if (!dec->iso_buffer) {
|
||||
dprintk("%s: pci_alloc_consistent - not enough memory\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(dec->iso_buffer, 0,
|
||||
ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
|
||||
|
||||
|
@ -1254,6 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec)
|
|||
dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE,
|
||||
GFP_ATOMIC, &dec->irq_dma_handle);
|
||||
if(!dec->irq_buffer) {
|
||||
usb_free_urb(dec->irq_urb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
|
||||
|
|
|
@ -62,7 +62,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
|
|||
|
||||
dprintk("Stopping isoc\n");
|
||||
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
|
||||
usb_kill_urb(dev->adev->urb[i]);
|
||||
usb_unlink_urb(dev->adev->urb[i]);
|
||||
usb_free_urb(dev->adev->urb[i]);
|
||||
dev->adev->urb[i] = NULL;
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
|||
struct em28xx *dev = urb->context;
|
||||
int i;
|
||||
unsigned int oldptr;
|
||||
unsigned long flags;
|
||||
int period_elapsed = 0;
|
||||
int status;
|
||||
unsigned char *cp;
|
||||
|
@ -96,9 +95,21 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
|||
if (!length)
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&dev->adev->slock, flags);
|
||||
|
||||
oldptr = dev->adev->hwptr_done_capture;
|
||||
if (oldptr + length >= runtime->buffer_size) {
|
||||
unsigned int cnt =
|
||||
runtime->buffer_size - oldptr;
|
||||
memcpy(runtime->dma_area + oldptr * stride, cp,
|
||||
cnt * stride);
|
||||
memcpy(runtime->dma_area, cp + cnt * stride,
|
||||
length * stride - cnt * stride);
|
||||
} else {
|
||||
memcpy(runtime->dma_area + oldptr * stride, cp,
|
||||
length * stride);
|
||||
}
|
||||
|
||||
snd_pcm_stream_lock(substream);
|
||||
|
||||
dev->adev->hwptr_done_capture += length;
|
||||
if (dev->adev->hwptr_done_capture >=
|
||||
runtime->buffer_size)
|
||||
|
@ -113,19 +124,7 @@ static void em28xx_audio_isocirq(struct urb *urb)
|
|||
period_elapsed = 1;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->adev->slock, flags);
|
||||
|
||||
if (oldptr + length >= runtime->buffer_size) {
|
||||
unsigned int cnt =
|
||||
runtime->buffer_size - oldptr;
|
||||
memcpy(runtime->dma_area + oldptr * stride, cp,
|
||||
cnt * stride);
|
||||
memcpy(runtime->dma_area, cp + cnt * stride,
|
||||
length * stride - cnt * stride);
|
||||
} else {
|
||||
memcpy(runtime->dma_area + oldptr * stride, cp,
|
||||
length * stride);
|
||||
}
|
||||
snd_pcm_stream_unlock(substream);
|
||||
}
|
||||
if (period_elapsed)
|
||||
snd_pcm_period_elapsed(substream);
|
||||
|
|
|
@ -69,19 +69,33 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
|
|||
int ret, byte;
|
||||
|
||||
if (dev->state & DEV_DISCONNECTED)
|
||||
return(-ENODEV);
|
||||
return -ENODEV;
|
||||
|
||||
if (len > URB_MAX_CTRL_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
|
||||
|
||||
mutex_lock(&dev->ctrl_urb_lock);
|
||||
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
0x0000, reg, buf, len, HZ);
|
||||
0x0000, reg, dev->urb_buf, len, HZ);
|
||||
if (ret < 0) {
|
||||
if (reg_debug)
|
||||
printk(" failed!\n");
|
||||
mutex_unlock(&dev->ctrl_urb_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (len)
|
||||
memcpy(buf, dev->urb_buf, len);
|
||||
|
||||
mutex_unlock(&dev->ctrl_urb_lock);
|
||||
|
||||
if (reg_debug) {
|
||||
printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
|
||||
printk("%02x values: ", ret);
|
||||
for (byte = 0; byte < len; byte++)
|
||||
printk(" %02x", (unsigned char)buf[byte]);
|
||||
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
|
@ -102,16 +116,20 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
|
|||
|
||||
em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
|
||||
|
||||
mutex_lock(&dev->ctrl_urb_lock);
|
||||
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
|
||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
0x0000, reg, &val, 1, HZ);
|
||||
0x0000, reg, dev->urb_buf, 1, HZ);
|
||||
val = dev->urb_buf[0];
|
||||
mutex_unlock(&dev->ctrl_urb_lock);
|
||||
|
||||
if (ret < 0) {
|
||||
printk(" failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (reg_debug)
|
||||
printk(ret < 0 ? " failed!\n" :
|
||||
"%02x\n", (unsigned char) val);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
printk("%02x\n", (unsigned char) val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -130,19 +148,13 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*usb_control_msg seems to expect a kmalloced buffer */
|
||||
unsigned char *bufs;
|
||||
|
||||
if (dev->state & DEV_DISCONNECTED)
|
||||
return -ENODEV;
|
||||
|
||||
if (len < 1)
|
||||
if ((len < 1) || (len > URB_MAX_CTRL_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
bufs = kmalloc(len, GFP_KERNEL);
|
||||
|
||||
em28xx_regdbg("req=%02x reg=%02x:", req, reg);
|
||||
|
||||
if (reg_debug) {
|
||||
int i;
|
||||
for (i = 0; i < len; ++i)
|
||||
|
@ -150,16 +162,16 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
|
|||
printk("\n");
|
||||
}
|
||||
|
||||
if (!bufs)
|
||||
return -ENOMEM;
|
||||
memcpy(bufs, buf, len);
|
||||
mutex_lock(&dev->ctrl_urb_lock);
|
||||
memcpy(dev->urb_buf, buf, len);
|
||||
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
|
||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||
0x0000, reg, bufs, len, HZ);
|
||||
0x0000, reg, dev->urb_buf, len, HZ);
|
||||
mutex_unlock(&dev->ctrl_urb_lock);
|
||||
|
||||
if (dev->wait_after_write)
|
||||
msleep(dev->wait_after_write);
|
||||
|
||||
kfree(bufs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -270,6 +282,8 @@ static int em28xx_set_audio_source(struct em28xx *dev)
|
|||
break;
|
||||
case EM28XX_AMUX_LINE_IN:
|
||||
input = EM28XX_AUDIO_SRC_LINE;
|
||||
video = disable;
|
||||
line = enable;
|
||||
break;
|
||||
case EM28XX_AMUX_AC97_VIDEO:
|
||||
input = EM28XX_AUDIO_SRC_LINE;
|
||||
|
|
|
@ -337,9 +337,9 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
|
|||
/* Check if board has eeprom */
|
||||
err = i2c_master_recv(&dev->i2c_client, &buf, 0);
|
||||
if (err < 0) {
|
||||
em28xx_errdev("%s: i2c_master_recv failed! err [%d]\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
em28xx_errdev("board has no eeprom\n");
|
||||
memset(eedata, 0, len);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
buf = 0;
|
||||
|
@ -609,14 +609,16 @@ int em28xx_i2c_register(struct em28xx *dev)
|
|||
dev->i2c_client.adapter = &dev->i2c_adap;
|
||||
|
||||
retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
|
||||
if (retval < 0) {
|
||||
if ((retval < 0) && (retval != -ENODEV)) {
|
||||
em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n",
|
||||
__func__, retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (i2c_scan)
|
||||
em28xx_do_i2c_scan(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
|
|||
MODULE_LICENSE("GPL");
|
||||
|
||||
static LIST_HEAD(em28xx_devlist);
|
||||
static DEFINE_MUTEX(em28xx_devlist_mutex);
|
||||
|
||||
static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
||||
static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
|
||||
|
@ -1519,7 +1520,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
|||
struct em28xx_fh *fh;
|
||||
enum v4l2_buf_type fh_type = 0;
|
||||
|
||||
lock_kernel();
|
||||
mutex_lock(&em28xx_devlist_mutex);
|
||||
list_for_each_entry(h, &em28xx_devlist, devlist) {
|
||||
if (h->vdev->minor == minor) {
|
||||
dev = h;
|
||||
|
@ -1535,10 +1536,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
|||
dev = h;
|
||||
}
|
||||
}
|
||||
if (NULL == dev) {
|
||||
unlock_kernel();
|
||||
mutex_unlock(&em28xx_devlist_mutex);
|
||||
if (NULL == dev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
em28xx_videodbg("open minor=%d type=%s users=%d\n",
|
||||
minor, v4l2_type_names[fh_type], dev->users);
|
||||
|
@ -1547,10 +1549,9 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
|||
fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
|
||||
if (!fh) {
|
||||
em28xx_errdev("em28xx-video.c: Out of memory?!\n");
|
||||
unlock_kernel();
|
||||
mutex_unlock(&dev->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mutex_lock(&dev->lock);
|
||||
fh->dev = dev;
|
||||
fh->radio = radio;
|
||||
fh->type = fh_type;
|
||||
|
@ -1584,7 +1585,6 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
|
|||
sizeof(struct em28xx_buffer), fh);
|
||||
|
||||
mutex_unlock(&dev->lock);
|
||||
unlock_kernel();
|
||||
|
||||
return errCode;
|
||||
}
|
||||
|
@ -1871,6 +1871,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
|
|||
{
|
||||
struct em28xx *dev = NULL;
|
||||
|
||||
mutex_lock(&em28xx_devlist_mutex);
|
||||
mutex_lock(&em28xx_extension_devlist_lock);
|
||||
list_add_tail(&ops->next, &em28xx_extension_devlist);
|
||||
list_for_each_entry(dev, &em28xx_devlist, devlist) {
|
||||
|
@ -1879,6 +1880,7 @@ int em28xx_register_extension(struct em28xx_ops *ops)
|
|||
}
|
||||
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
|
||||
mutex_unlock(&em28xx_extension_devlist_lock);
|
||||
mutex_unlock(&em28xx_devlist_mutex);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(em28xx_register_extension);
|
||||
|
@ -1887,6 +1889,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
|
|||
{
|
||||
struct em28xx *dev = NULL;
|
||||
|
||||
mutex_lock(&em28xx_devlist_mutex);
|
||||
list_for_each_entry(dev, &em28xx_devlist, devlist) {
|
||||
if (dev)
|
||||
ops->fini(dev);
|
||||
|
@ -1896,6 +1899,7 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
|
|||
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
|
||||
list_del(&ops->next);
|
||||
mutex_unlock(&em28xx_extension_devlist_lock);
|
||||
mutex_unlock(&em28xx_devlist_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(em28xx_unregister_extension);
|
||||
|
||||
|
@ -1921,6 +1925,60 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
|
|||
}
|
||||
|
||||
|
||||
static int register_analog_devices(struct em28xx *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* allocate and fill video video_device struct */
|
||||
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
|
||||
if (!dev->vdev) {
|
||||
em28xx_errdev("cannot allocate video_device.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* register v4l2 video video_device */
|
||||
ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
|
||||
video_nr[dev->devno]);
|
||||
if (ret) {
|
||||
em28xx_errdev("unable to register video device (error=%i).\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate and fill vbi video_device struct */
|
||||
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
|
||||
|
||||
/* register v4l2 vbi video_device */
|
||||
ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
|
||||
vbi_nr[dev->devno]);
|
||||
if (ret < 0) {
|
||||
em28xx_errdev("unable to register vbi device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
|
||||
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
|
||||
if (!dev->radio_dev) {
|
||||
em28xx_errdev("cannot allocate video_device.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
|
||||
radio_nr[dev->devno]);
|
||||
if (ret < 0) {
|
||||
em28xx_errdev("can't register radio device\n");
|
||||
return ret;
|
||||
}
|
||||
em28xx_info("Registered radio device as /dev/radio%d\n",
|
||||
dev->radio_dev->num);
|
||||
}
|
||||
|
||||
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
|
||||
dev->vdev->num, dev->vbi_dev->num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* em28xx_init_dev()
|
||||
* allocates and inits the device structs, registers i2c bus and v4l device
|
||||
|
@ -1936,6 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
|||
|
||||
dev->udev = udev;
|
||||
mutex_init(&dev->lock);
|
||||
mutex_init(&dev->ctrl_urb_lock);
|
||||
spin_lock_init(&dev->slock);
|
||||
init_waitqueue_head(&dev->open);
|
||||
init_waitqueue_head(&dev->wait_frame);
|
||||
|
@ -1953,8 +2012,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
|||
errCode = em28xx_config(dev);
|
||||
if (errCode) {
|
||||
em28xx_errdev("error configuring device\n");
|
||||
em28xx_devused &= ~(1<<dev->devno);
|
||||
kfree(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -2001,50 +2058,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
|||
return errCode;
|
||||
}
|
||||
|
||||
list_add_tail(&dev->devlist, &em28xx_devlist);
|
||||
|
||||
/* allocate and fill video video_device struct */
|
||||
dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
|
||||
if (NULL == dev->vdev) {
|
||||
em28xx_errdev("cannot allocate video_device.\n");
|
||||
goto fail_unreg;
|
||||
}
|
||||
|
||||
/* register v4l2 video video_device */
|
||||
retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
|
||||
video_nr[dev->devno]);
|
||||
if (retval) {
|
||||
em28xx_errdev("unable to register video device (error=%i).\n",
|
||||
retval);
|
||||
goto fail_unreg;
|
||||
}
|
||||
|
||||
/* Allocate and fill vbi video_device struct */
|
||||
dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
|
||||
/* register v4l2 vbi video_device */
|
||||
if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
|
||||
vbi_nr[dev->devno]) < 0) {
|
||||
em28xx_errdev("unable to register vbi device\n");
|
||||
retval = -ENODEV;
|
||||
goto fail_unreg;
|
||||
}
|
||||
|
||||
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
|
||||
dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
|
||||
if (NULL == dev->radio_dev) {
|
||||
em28xx_errdev("cannot allocate video_device.\n");
|
||||
goto fail_unreg;
|
||||
}
|
||||
retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
|
||||
radio_nr[dev->devno]);
|
||||
if (retval < 0) {
|
||||
em28xx_errdev("can't register radio device\n");
|
||||
goto fail_unreg;
|
||||
}
|
||||
em28xx_info("Registered radio device as /dev/radio%d\n",
|
||||
dev->radio_dev->num);
|
||||
}
|
||||
|
||||
/* init video dma queues */
|
||||
INIT_LIST_HEAD(&dev->vidq.active);
|
||||
INIT_LIST_HEAD(&dev->vidq.queued);
|
||||
|
@ -2071,8 +2084,14 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
|||
|
||||
video_mux(dev, 0);
|
||||
|
||||
em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
|
||||
dev->vdev->num, dev->vbi_dev->num);
|
||||
mutex_lock(&em28xx_devlist_mutex);
|
||||
list_add_tail(&dev->devlist, &em28xx_devlist);
|
||||
retval = register_analog_devices(dev);
|
||||
if (retval < 0) {
|
||||
em28xx_release_resources(dev);
|
||||
mutex_unlock(&em28xx_devlist_mutex);
|
||||
goto fail_reg_devices;
|
||||
}
|
||||
|
||||
mutex_lock(&em28xx_extension_devlist_lock);
|
||||
if (!list_empty(&em28xx_extension_devlist)) {
|
||||
|
@ -2082,13 +2101,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
|
|||
}
|
||||
}
|
||||
mutex_unlock(&em28xx_extension_devlist_lock);
|
||||
mutex_unlock(&em28xx_devlist_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_unreg:
|
||||
em28xx_release_resources(dev);
|
||||
fail_reg_devices:
|
||||
mutex_unlock(&dev->lock);
|
||||
kfree(dev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2231,8 +2249,12 @@ static int em28xx_usb_probe(struct usb_interface *interface,
|
|||
|
||||
/* allocate device struct */
|
||||
retval = em28xx_init_dev(&dev, udev, nr);
|
||||
if (retval)
|
||||
if (retval) {
|
||||
em28xx_devused &= ~(1<<dev->devno);
|
||||
kfree(dev);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
em28xx_info("Found %s\n", em28xx_boards[dev->model].name);
|
||||
|
||||
|
|
|
@ -102,6 +102,9 @@
|
|||
#define EM28XX_MIN_BUF 4
|
||||
#define EM28XX_DEF_BUF 8
|
||||
|
||||
/*Limits the max URB message size */
|
||||
#define URB_MAX_CTRL_SIZE 80
|
||||
|
||||
/* Params for validated field */
|
||||
#define EM28XX_BOARD_NOT_VALIDATED 1
|
||||
#define EM28XX_BOARD_VALIDATED 0
|
||||
|
@ -430,6 +433,7 @@ struct em28xx {
|
|||
|
||||
/* locks */
|
||||
struct mutex lock;
|
||||
struct mutex ctrl_urb_lock; /* protects urb_buf */
|
||||
/* spinlock_t queue_lock; */
|
||||
struct list_head inqueue, outqueue;
|
||||
wait_queue_head_t open, wait_frame, wait_stream;
|
||||
|
@ -451,6 +455,8 @@ struct em28xx {
|
|||
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
|
||||
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
|
||||
char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
|
||||
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
|
||||
|
||||
/* helper funcs that call usb_control_msg */
|
||||
int (*em28xx_write_regs) (struct em28xx *dev, u16 reg,
|
||||
char *buf, int len);
|
||||
|
|
|
@ -846,10 +846,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
int retry = 50;
|
||||
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
reg_w_val(gspca_dev, 0x0000, 0x00);
|
||||
reg_r(gspca_dev, 0x0002, 1);
|
||||
reg_w_val(gspca_dev, 0x0053, 0x00);
|
||||
|
|
|
@ -276,6 +276,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
/* Stop the state machine */
|
||||
if (dev->state != FPIX_NOP)
|
||||
wait_for_completion(&dev->can_close);
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
|
||||
|
||||
usb_free_urb(dev->control_urb);
|
||||
dev->control_urb = NULL;
|
||||
|
@ -385,6 +391,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
error:
|
||||
/* Free the ressources */
|
||||
sd_stopN(gspca_dev);
|
||||
sd_stop0(gspca_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -425,6 +432,7 @@ static const struct sd_desc sd_desc = {
|
|||
.init = sd_init,
|
||||
.start = sd_start,
|
||||
.stopN = sd_stopN,
|
||||
.stop0 = sd_stop0,
|
||||
};
|
||||
|
||||
/* -- device connect -- */
|
||||
|
|
|
@ -646,15 +646,14 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
gspca_dev->streaming = 0;
|
||||
atomic_set(&gspca_dev->nevent, 0);
|
||||
if (gspca_dev->present) {
|
||||
if (gspca_dev->sd_desc->stopN)
|
||||
gspca_dev->sd_desc->stopN(gspca_dev);
|
||||
destroy_urbs(gspca_dev);
|
||||
gspca_set_alt0(gspca_dev);
|
||||
if (gspca_dev->sd_desc->stop0)
|
||||
gspca_dev->sd_desc->stop0(gspca_dev);
|
||||
PDEBUG(D_STREAM, "stream off OK");
|
||||
}
|
||||
if (gspca_dev->present
|
||||
&& gspca_dev->sd_desc->stopN)
|
||||
gspca_dev->sd_desc->stopN(gspca_dev);
|
||||
destroy_urbs(gspca_dev);
|
||||
gspca_set_alt0(gspca_dev);
|
||||
if (gspca_dev->sd_desc->stop0)
|
||||
gspca_dev->sd_desc->stop0(gspca_dev);
|
||||
PDEBUG(D_STREAM, "stream off OK");
|
||||
}
|
||||
|
||||
static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
|
||||
|
@ -863,7 +862,7 @@ static int dev_open(struct inode *inode, struct file *file)
|
|||
int ret;
|
||||
|
||||
PDEBUG(D_STREAM, "%s open", current->comm);
|
||||
gspca_dev = (struct gspca_dev *) video_devdata(file);
|
||||
gspca_dev = video_drvdata(file);
|
||||
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (!gspca_dev->present) {
|
||||
|
@ -875,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
|
|||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* protect the subdriver against rmmod */
|
||||
if (!try_module_get(gspca_dev->module)) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
gspca_dev->users++;
|
||||
|
||||
/* one more user */
|
||||
|
@ -884,10 +890,10 @@ static int dev_open(struct inode *inode, struct file *file)
|
|||
#ifdef GSPCA_DEBUG
|
||||
/* activate the v4l2 debug */
|
||||
if (gspca_debug & D_V4L2)
|
||||
gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
|
||||
gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL
|
||||
| V4L2_DEBUG_IOCTL_ARG;
|
||||
else
|
||||
gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
|
||||
gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL
|
||||
| V4L2_DEBUG_IOCTL_ARG);
|
||||
#endif
|
||||
ret = 0;
|
||||
|
@ -921,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
|
|||
gspca_dev->memory = GSPCA_MEMORY_NO;
|
||||
}
|
||||
file->private_data = NULL;
|
||||
module_put(gspca_dev->module);
|
||||
mutex_unlock(&gspca_dev->queue_lock);
|
||||
|
||||
PDEBUG(D_STREAM, "close done");
|
||||
|
@ -1748,11 +1755,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void dev_release(struct video_device *vfd)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static struct file_operations dev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = dev_open,
|
||||
|
@ -1800,7 +1802,7 @@ static struct video_device gspca_template = {
|
|||
.name = "gspca main driver",
|
||||
.fops = &dev_fops,
|
||||
.ioctl_ops = &dev_ioctl_ops,
|
||||
.release = dev_release, /* mandatory */
|
||||
.release = video_device_release,
|
||||
.minor = -1,
|
||||
};
|
||||
|
||||
|
@ -1869,17 +1871,18 @@ int gspca_dev_probe(struct usb_interface *intf,
|
|||
init_waitqueue_head(&gspca_dev->wq);
|
||||
|
||||
/* init video stuff */
|
||||
memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
|
||||
gspca_dev->vdev.parent = &dev->dev;
|
||||
memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
|
||||
gspca_dev->vdev.fops = &gspca_dev->fops;
|
||||
gspca_dev->fops.owner = module; /* module protection */
|
||||
gspca_dev->vdev = video_device_alloc();
|
||||
memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template);
|
||||
gspca_dev->vdev->parent = &dev->dev;
|
||||
gspca_dev->module = module;
|
||||
gspca_dev->present = 1;
|
||||
ret = video_register_device(&gspca_dev->vdev,
|
||||
video_set_drvdata(gspca_dev->vdev, gspca_dev);
|
||||
ret = video_register_device(gspca_dev->vdev,
|
||||
VFL_TYPE_GRABBER,
|
||||
video_nr);
|
||||
if (ret < 0) {
|
||||
err("video_register_device err %d", ret);
|
||||
video_device_release(gspca_dev->vdev);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1887,7 +1890,8 @@ int gspca_dev_probe(struct usb_interface *intf,
|
|||
PDEBUG(D_PROBE, "probe ok");
|
||||
return 0;
|
||||
out:
|
||||
kref_put(&gspca_dev->kref, gspca_delete);
|
||||
kfree(gspca_dev->usb_buf);
|
||||
kfree(gspca_dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(gspca_dev_probe);
|
||||
|
@ -1905,7 +1909,7 @@ void gspca_disconnect(struct usb_interface *intf)
|
|||
usb_set_intfdata(intf, NULL);
|
||||
|
||||
/* We don't want people trying to open up the device */
|
||||
video_unregister_device(&gspca_dev->vdev);
|
||||
video_unregister_device(gspca_dev->vdev);
|
||||
|
||||
gspca_dev->present = 0;
|
||||
gspca_dev->streaming = 0;
|
||||
|
|
|
@ -97,7 +97,7 @@ struct sd_desc {
|
|||
cam_pkt_op pkt_scan;
|
||||
/* optional operations */
|
||||
cam_v_op stopN; /* called on stream off - main alt */
|
||||
cam_v_op stop0; /* called on stream off - alt 0 */
|
||||
cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
|
||||
cam_v_op dq_callback; /* called when a frame has been dequeued */
|
||||
cam_jpg_op get_jcomp;
|
||||
cam_jpg_op set_jcomp;
|
||||
|
@ -120,8 +120,8 @@ struct gspca_frame {
|
|||
};
|
||||
|
||||
struct gspca_dev {
|
||||
struct video_device vdev; /* !! must be the first item */
|
||||
struct file_operations fops;
|
||||
struct video_device *vdev;
|
||||
struct module *module; /* subdriver handling the device */
|
||||
struct usb_device *dev;
|
||||
struct kref kref;
|
||||
struct file *capt_file; /* file doing video capture */
|
||||
|
|
|
@ -749,10 +749,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
if (sd->sensor == SENSOR_PAC7302) {
|
||||
reg_w(gspca_dev, 0xff, 0x01);
|
||||
reg_w(gspca_dev, 0x78, 0x40);
|
||||
|
|
|
@ -2022,8 +2022,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
|
||||
}
|
||||
|
||||
|
|
|
@ -742,8 +742,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
|
||||
/* This maybe reset or power control */
|
||||
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
|
||||
reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
|
||||
|
|
|
@ -766,10 +766,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
if (sd->chip_revision == Rev012A) {
|
||||
reg_w_val(gspca_dev->dev, 0x8118, 0x29);
|
||||
reg_w_val(gspca_dev->dev, 0x8114, 0x08);
|
||||
|
|
|
@ -1633,10 +1633,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
reg_w(dev, 0xa0, 0x09, 0xb003);
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct usb_device *dev = gspca_dev->dev;
|
||||
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
reg_w(dev, 0x89, 0xffff, 0xffff);
|
||||
}
|
||||
|
||||
|
|
|
@ -7336,10 +7336,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* called on streamoff with alt 0 and on disconnect */
|
||||
static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
send_unknown(gspca_dev->dev, sd->sensor);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ struct s2255_dmaqueue {
|
|||
#define S2255_FW_FAILED 3
|
||||
#define S2255_FW_DISCONNECTING 4
|
||||
|
||||
#define S2255_FW_MARKER 0x22552f2f
|
||||
#define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
|
||||
/* 2255 read states */
|
||||
#define S2255_READ_IDLE 0
|
||||
#define S2255_READ_FRAME 1
|
||||
|
|
Загрузка…
Ссылка в новой задаче