mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 15:13:52 +00:00
V4L/DVB (10756): cx18: Slim down instance handling, build names from v4l2_device.name
Convert card instance handling to a lighter weight mechanism like ivtv. Also convert name strings and debug messages to use v4l2_device.name. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
1a2670465e
commit
5811cf99df
@ -39,10 +39,6 @@
|
||||
|
||||
#include <media/tveeprom.h>
|
||||
|
||||
|
||||
/* var to keep track of the number of array elements in use */
|
||||
int cx18_cards_active;
|
||||
|
||||
/* If you have already X v4l cards, then set this to X. This way
|
||||
the device numbers stay matched. Example: you have a WinTV card
|
||||
without radio and a Compro H900 with. Normally this would give a
|
||||
@ -50,12 +46,6 @@ int cx18_cards_active;
|
||||
setting this to 1 you ensure that radio0 is now also radio1. */
|
||||
int cx18_first_minor;
|
||||
|
||||
/* Master variable for all cx18 info */
|
||||
struct cx18 *cx18_cards[CX18_MAX_CARDS];
|
||||
|
||||
/* Protects cx18_cards_active */
|
||||
DEFINE_SPINLOCK(cx18_cards_lock);
|
||||
|
||||
/* add your revision and whatnot here */
|
||||
static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
|
||||
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
|
||||
@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
|
||||
|
||||
static atomic_t cx18_instance = ATOMIC_INIT(0);
|
||||
|
||||
/* Parameter declarations */
|
||||
static int cardtype[CX18_MAX_CARDS];
|
||||
static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
@ -491,9 +483,9 @@ static void cx18_process_options(struct cx18 *cx)
|
||||
cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
|
||||
}
|
||||
|
||||
cx->options.cardtype = cardtype[cx->num];
|
||||
cx->options.tuner = tuner[cx->num];
|
||||
cx->options.radio = radio[cx->num];
|
||||
cx->options.cardtype = cardtype[cx->instance];
|
||||
cx->options.tuner = tuner[cx->instance];
|
||||
cx->options.radio = radio[cx->instance];
|
||||
|
||||
cx->std = cx18_parse_std(cx);
|
||||
if (cx->options.cardtype == -1) {
|
||||
@ -550,7 +542,7 @@ done:
|
||||
}
|
||||
|
||||
/* Precondition: the cx18 structure has been memset to 0. Only
|
||||
the dev and num fields have been filled in.
|
||||
the dev and instance fields have been filled in.
|
||||
No assumptions on the card type may be made here (see cx18_init_struct2
|
||||
for that).
|
||||
*/
|
||||
@ -567,7 +559,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
|
||||
mutex_init(&cx->epu2apu_mb_lock);
|
||||
mutex_init(&cx->epu2cpu_mb_lock);
|
||||
|
||||
cx->work_queue = create_singlethread_workqueue(cx->name);
|
||||
cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
|
||||
if (cx->work_queue == NULL) {
|
||||
CX18_ERR("Unable to create work hander thread\n");
|
||||
return -ENOMEM;
|
||||
@ -647,15 +639,16 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
|
||||
CX18_DEBUG_INFO("Enabling pci device\n");
|
||||
|
||||
if (pci_enable_device(pci_dev)) {
|
||||
CX18_ERR("Can't enable device %d!\n", cx->num);
|
||||
CX18_ERR("Can't enable device %d!\n", cx->instance);
|
||||
return -EIO;
|
||||
}
|
||||
if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
|
||||
CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
|
||||
CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
|
||||
return -EIO;
|
||||
}
|
||||
if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
|
||||
CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
|
||||
CX18_ERR("Cannot request encoder memory region, card %d\n",
|
||||
cx->instance);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -741,44 +734,42 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
|
||||
u32 devtype;
|
||||
struct cx18 *cx;
|
||||
|
||||
spin_lock(&cx18_cards_lock);
|
||||
|
||||
/* Make sure we've got a place for this card */
|
||||
if (cx18_cards_active == CX18_MAX_CARDS) {
|
||||
printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
|
||||
cx18_cards_active);
|
||||
spin_unlock(&cx18_cards_lock);
|
||||
/* FIXME - module parameter arrays constrain max instances */
|
||||
i = atomic_inc_return(&cx18_instance) - 1;
|
||||
if (i >= CX18_MAX_CARDS) {
|
||||
printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
|
||||
"limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
|
||||
if (!cx) {
|
||||
spin_unlock(&cx18_cards_lock);
|
||||
if (cx == NULL) {
|
||||
printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
|
||||
i);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cx18_cards[cx18_cards_active] = cx;
|
||||
cx->num = cx18_cards_active++;
|
||||
snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
|
||||
CX18_INFO("Initializing card #%d\n", cx->num);
|
||||
|
||||
spin_unlock(&cx18_cards_lock);
|
||||
|
||||
cx->pci_dev = pci_dev;
|
||||
cx->instance = i;
|
||||
|
||||
retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
|
||||
if (retval) {
|
||||
CX18_ERR("Call to v4l2_device_register() failed\n");
|
||||
goto err;
|
||||
printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
|
||||
"\n", cx->instance);
|
||||
kfree(cx);
|
||||
return retval;
|
||||
}
|
||||
CX18_DEBUG_INFO("registered v4l2_device name: %s\n", cx->v4l2_dev.name);
|
||||
snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
|
||||
cx->instance);
|
||||
CX18_INFO("Initializing card %d\n", cx->instance);
|
||||
|
||||
cx18_process_options(cx);
|
||||
if (cx->options.cardtype == -1) {
|
||||
retval = -ENODEV;
|
||||
goto unregister_v4l2;
|
||||
goto err;
|
||||
}
|
||||
if (cx18_init_struct1(cx)) {
|
||||
retval = -ENOMEM;
|
||||
goto unregister_v4l2;
|
||||
goto err;
|
||||
}
|
||||
|
||||
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
|
||||
@ -829,8 +820,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
|
||||
goto free_map;
|
||||
}
|
||||
|
||||
CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
|
||||
|
||||
if (cx->card->hw_all & CX18_HW_TVEEPROM) {
|
||||
/* Based on the model number the cardtype may be changed.
|
||||
The PCI IDs are not always reliable. */
|
||||
@ -847,7 +836,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
|
||||
|
||||
/* Register IRQ */
|
||||
retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
|
||||
IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
|
||||
IRQF_SHARED | IRQF_DISABLED,
|
||||
cx->v4l2_dev.name, (void *)cx);
|
||||
if (retval) {
|
||||
CX18_ERR("Failed to register irq %d\n", retval);
|
||||
goto free_i2c;
|
||||
@ -933,8 +923,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
|
||||
goto free_streams;
|
||||
}
|
||||
|
||||
CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
|
||||
|
||||
CX18_INFO("Initialized card: %s\n", cx->card_name);
|
||||
return 0;
|
||||
|
||||
free_streams:
|
||||
@ -949,18 +938,13 @@ free_mem:
|
||||
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
|
||||
free_workqueue:
|
||||
destroy_workqueue(cx->work_queue);
|
||||
unregister_v4l2:
|
||||
v4l2_device_unregister(&cx->v4l2_dev);
|
||||
err:
|
||||
if (retval == 0)
|
||||
retval = -ENODEV;
|
||||
CX18_ERR("Error %d on initialization\n", retval);
|
||||
|
||||
i = cx->num;
|
||||
spin_lock(&cx18_cards_lock);
|
||||
kfree(cx18_cards[i]);
|
||||
cx18_cards[i] = NULL;
|
||||
spin_unlock(&cx18_cards_lock);
|
||||
v4l2_device_unregister(&cx->v4l2_dev);
|
||||
kfree(cx);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -1069,9 +1053,9 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
|
||||
static void cx18_remove(struct pci_dev *pci_dev)
|
||||
{
|
||||
struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
|
||||
struct cx18 *cx = container_of(v4l2_dev, struct cx18, v4l2_dev);
|
||||
struct cx18 *cx = to_cx18(v4l2_dev);
|
||||
|
||||
CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
|
||||
CX18_DEBUG_INFO("Removing Card\n");
|
||||
|
||||
/* Stop all captures */
|
||||
CX18_DEBUG_INFO("Stopping all streams\n");
|
||||
@ -1099,10 +1083,12 @@ static void cx18_remove(struct pci_dev *pci_dev)
|
||||
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
|
||||
|
||||
pci_disable_device(cx->pci_dev);
|
||||
/* FIXME - we leak cx->vbi.sliced_mpeg_data[i] allocations */
|
||||
|
||||
CX18_INFO("Removed %s\n", cx->card_name);
|
||||
|
||||
v4l2_device_unregister(v4l2_dev);
|
||||
|
||||
CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
|
||||
kfree(cx);
|
||||
}
|
||||
|
||||
/* define a pci_driver for card detection */
|
||||
@ -1117,8 +1103,6 @@ static int module_start(void)
|
||||
{
|
||||
printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
|
||||
|
||||
memset(cx18_cards, 0, sizeof(cx18_cards));
|
||||
|
||||
/* Validate parameters */
|
||||
if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
|
||||
printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
|
||||
@ -1141,16 +1125,7 @@ static int module_start(void)
|
||||
|
||||
static void module_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
pci_unregister_driver(&cx18_pci_driver);
|
||||
|
||||
for (i = 0; i < cx18_cards_active; i++) {
|
||||
if (cx18_cards[i] == NULL)
|
||||
continue;
|
||||
kfree(cx18_cards[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module_init(module_start);
|
||||
|
@ -144,12 +144,12 @@
|
||||
/* Flag to turn on high volume debugging */
|
||||
#define CX18_DBGFLG_HIGHVOL (1 << 8)
|
||||
|
||||
/* NOTE: extra space before comma in 'cx->num , ## args' is required for
|
||||
/* NOTE: extra space before comma in 'fmt , ## args' is required for
|
||||
gcc-2.95, otherwise it won't compile. */
|
||||
#define CX18_DEBUG(x, type, fmt, args...) \
|
||||
do { \
|
||||
if ((x) & cx18_debug) \
|
||||
printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
|
||||
v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
|
||||
} while (0)
|
||||
#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
|
||||
#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
|
||||
@ -163,7 +163,7 @@
|
||||
#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
|
||||
do { \
|
||||
if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
|
||||
printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
|
||||
v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
|
||||
} while (0)
|
||||
#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
|
||||
#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
|
||||
@ -175,9 +175,9 @@
|
||||
#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
|
||||
|
||||
/* Standard kernel messages */
|
||||
#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
|
||||
#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
|
||||
#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
|
||||
#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
|
||||
#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
|
||||
#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
|
||||
|
||||
/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
|
||||
#define MPEG_FRAME_TYPE_IFRAME 1
|
||||
@ -445,8 +445,7 @@ struct cx18_i2c_algo_callback_data {
|
||||
|
||||
/* Struct to hold info about cx18 cards */
|
||||
struct cx18 {
|
||||
int num; /* board number, -1 during init! */
|
||||
char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
|
||||
int instance;
|
||||
struct pci_dev *pci_dev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
|
||||
@ -455,8 +454,8 @@ struct cx18 {
|
||||
const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
|
||||
u8 is_50hz;
|
||||
u8 is_60hz;
|
||||
u8 is_out_50hz;
|
||||
u8 is_out_60hz;
|
||||
u8 is_out_50hz; /* FIXME - remove, we don't have an output decoder */
|
||||
u8 is_out_60hz; /* FIXME - remove, we don't have an output decoder */
|
||||
u8 nof_inputs; /* number of video inputs */
|
||||
u8 nof_audio_inputs; /* number of audio inputs */
|
||||
u16 buffer_id; /* buffer ID counter */
|
||||
@ -547,11 +546,13 @@ struct cx18 {
|
||||
v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
|
||||
};
|
||||
|
||||
static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
|
||||
{
|
||||
return container_of(v4l2_dev, struct cx18, v4l2_dev);
|
||||
}
|
||||
|
||||
/* Globals */
|
||||
extern struct cx18 *cx18_cards[];
|
||||
extern int cx18_cards_active;
|
||||
extern int cx18_first_minor;
|
||||
extern spinlock_t cx18_cards_lock;
|
||||
|
||||
/*==============Prototypes==================*/
|
||||
|
||||
|
@ -682,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
|
||||
|
||||
int cx18_v4l2_open(struct file *filp)
|
||||
{
|
||||
int res, x, y = 0;
|
||||
struct cx18 *cx = NULL;
|
||||
struct cx18_stream *s = NULL;
|
||||
int minor = video_devdata(filp)->minor;
|
||||
|
||||
/* Find which card this open was on */
|
||||
spin_lock(&cx18_cards_lock);
|
||||
for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
|
||||
/* find out which stream this open was on */
|
||||
for (y = 0; y < CX18_MAX_STREAMS; y++) {
|
||||
if (cx18_cards[x] == NULL)
|
||||
continue;
|
||||
s = &cx18_cards[x]->streams[y];
|
||||
if (s->video_dev && s->video_dev->minor == minor) {
|
||||
cx = cx18_cards[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&cx18_cards_lock);
|
||||
|
||||
if (cx == NULL) {
|
||||
/* Couldn't find a device registered
|
||||
on that minor, shouldn't happen! */
|
||||
printk(KERN_WARNING "No cx18 device found on minor %d\n",
|
||||
minor);
|
||||
return -ENXIO;
|
||||
}
|
||||
int res;
|
||||
struct video_device *video_dev = video_devdata(filp);
|
||||
struct cx18_stream *s = video_get_drvdata(video_dev);
|
||||
struct cx18 *cx = s->cx;;
|
||||
|
||||
mutex_lock(&cx->serialize_lock);
|
||||
if (cx18_init_on_first_open(cx)) {
|
||||
CX18_ERR("Failed to initialize on minor %d\n", minor);
|
||||
CX18_ERR("Failed to initialize on minor %d\n",
|
||||
video_dev->minor);
|
||||
mutex_unlock(&cx->serialize_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ int init_cx18_i2c(struct cx18 *cx)
|
||||
cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
|
||||
|
||||
sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
|
||||
" #%d-%d", cx->num, i);
|
||||
" #%d-%d", cx->instance, i);
|
||||
i2c_set_adapdata(&cx->i2c_adap[i], cx);
|
||||
|
||||
memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
|
||||
|
@ -387,20 +387,17 @@ static int cx18_g_chip_ident(struct file *file, void *fh,
|
||||
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
|
||||
{
|
||||
struct v4l2_dbg_register *regs = arg;
|
||||
unsigned long flags;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&cx18_cards_lock, flags);
|
||||
regs->size = 4;
|
||||
if (cmd == VIDIOC_DBG_G_REGISTER)
|
||||
regs->val = cx18_read_enc(cx, regs->reg);
|
||||
else
|
||||
cx18_write_enc(cx, regs->val, regs->reg);
|
||||
spin_unlock_irqrestore(&cx18_cards_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -847,7 +844,7 @@ static int cx18_log_status(struct file *file, void *fh)
|
||||
int i;
|
||||
|
||||
CX18_INFO("================= START STATUS CARD #%d "
|
||||
"=================\n", cx->num);
|
||||
"=================\n", cx->instance);
|
||||
CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
|
||||
if (cx->hw_flags & CX18_HW_TVEEPROM) {
|
||||
struct tveeprom tv;
|
||||
@ -865,7 +862,7 @@ static int cx18_log_status(struct file *file, void *fh)
|
||||
mutex_unlock(&cx->gpio_lock);
|
||||
CX18_INFO("Tuner: %s\n",
|
||||
test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
|
||||
cx2341x_log_status(&cx->params, cx->name);
|
||||
cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
|
||||
CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
|
||||
for (i = 0; i < CX18_MAX_STREAMS; i++) {
|
||||
struct cx18_stream *s = &cx->streams[i];
|
||||
@ -880,7 +877,8 @@ static int cx18_log_status(struct file *file, void *fh)
|
||||
CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
|
||||
(long long)cx->mpg_data_received,
|
||||
(long long)cx->vbi_data_inserted);
|
||||
CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
|
||||
CX18_INFO("================== END STATUS CARD #%d "
|
||||
"==================\n", cx->instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
|
||||
struct cx18_stream *s = &cx->streams[type];
|
||||
u32 cap = cx->v4l2_cap;
|
||||
int num_offset = cx18_stream_info[type].num_offset;
|
||||
int num = cx->num + cx18_first_minor + num_offset;
|
||||
int num = cx->instance + cx18_first_minor + num_offset;
|
||||
|
||||
/* These four fields are always initialized. If video_dev == NULL, then
|
||||
this stream is not in use. In that case no other fields but these
|
||||
@ -170,11 +170,11 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
snprintf(s->video_dev->name, sizeof(s->video_dev->name), "cx18-%d",
|
||||
cx->num);
|
||||
snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
|
||||
cx->v4l2_dev.name, s->name);
|
||||
|
||||
s->video_dev->num = num;
|
||||
s->video_dev->parent = &cx->pci_dev->dev;
|
||||
s->video_dev->v4l2_dev = &cx->v4l2_dev;
|
||||
s->video_dev->fops = &cx18_v4l2_enc_fops;
|
||||
s->video_dev->release = video_device_release;
|
||||
s->video_dev->tvnorms = V4L2_STD_ALL;
|
||||
@ -239,6 +239,7 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
|
||||
num = s_mpg->video_dev->num
|
||||
+ cx18_stream_info[type].num_offset;
|
||||
}
|
||||
video_set_drvdata(s->video_dev, s);
|
||||
|
||||
/* Register device. First try the desired minor, then any free one. */
|
||||
ret = video_register_device(s->video_dev, vfl_type, num);
|
||||
|
Loading…
Reference in New Issue
Block a user