V4L/DVB (5922): ivtv, cx25840: postpone fw load until first use
The firmware is now loaded when the driver is actually used for the first time. This allows the driver to be compiled in-kernel instead of as a module. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
fa8a7529ba
commit
c976bc8233
@ -64,7 +64,6 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
|
||||
obj-$(CONFIG_VIDEO_MEYE) += meye.o
|
||||
obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
|
||||
obj-$(CONFIG_VIDEO_CX88) += cx88/
|
||||
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
|
||||
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
|
||||
obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
|
||||
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
|
||||
@ -117,6 +116,8 @@ obj-$(CONFIG_USB_KONICAWC) += usbvideo/
|
||||
obj-$(CONFIG_USB_VICAM) += usbvideo/
|
||||
obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/
|
||||
|
||||
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
|
||||
|
||||
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
|
||||
|
@ -625,6 +625,22 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd,
|
||||
struct v4l2_tuner *vt = arg;
|
||||
struct v4l2_routing *route = arg;
|
||||
|
||||
/* ignore these commands */
|
||||
switch (cmd) {
|
||||
case TUNER_SET_TYPE_ADDR:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!state->is_initialized) {
|
||||
v4l_dbg(1, cx25840_debug, client, "cmd %08x triggered fw load\n", cmd);
|
||||
/* initialize on first use */
|
||||
state->is_initialized = 1;
|
||||
if (state->is_cx25836)
|
||||
cx25836_initialize(client);
|
||||
else
|
||||
cx25840_initialize(client, 1);
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
/* ioctls to allow direct access to the
|
||||
@ -906,11 +922,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
|
||||
|
||||
i2c_attach_client(client);
|
||||
|
||||
if (state->is_cx25836)
|
||||
cx25836_initialize(client);
|
||||
else
|
||||
cx25840_initialize(client, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ struct cx25840_state {
|
||||
u32 id;
|
||||
u32 rev;
|
||||
int is_cx25836;
|
||||
int is_initialized;
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -814,7 +814,6 @@ static void ivtv_request_module(struct ivtv *itv, const char *name)
|
||||
|
||||
static void ivtv_load_and_init_modules(struct ivtv *itv)
|
||||
{
|
||||
struct v4l2_control ctrl;
|
||||
u32 hw = itv->card->hw_all;
|
||||
int i;
|
||||
|
||||
@ -896,11 +895,6 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
|
||||
}
|
||||
|
||||
if (hw & IVTV_HW_CX25840) {
|
||||
/* CX25840_CID_ENABLE_PVR150_WORKAROUND */
|
||||
ctrl.id = V4L2_CID_PRIVATE_BASE;
|
||||
ctrl.value = itv->pvr150_workaround;
|
||||
itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
|
||||
|
||||
itv->vbi.raw_decoder_line_size = 1444;
|
||||
itv->vbi.raw_decoder_sav_odd_field = 0x20;
|
||||
itv->vbi.raw_decoder_sav_even_field = 0x60;
|
||||
@ -946,12 +940,9 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *pci_id)
|
||||
{
|
||||
int retval = 0;
|
||||
int video_input;
|
||||
int yuv_buf_size;
|
||||
int vbi_buf_size;
|
||||
int fw_retry_count = 3;
|
||||
struct ivtv *itv;
|
||||
struct v4l2_frequency vf;
|
||||
|
||||
spin_lock(&ivtv_cards_lock);
|
||||
|
||||
@ -1038,22 +1029,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
|
||||
goto free_io;
|
||||
}
|
||||
|
||||
while (--fw_retry_count > 0) {
|
||||
/* load firmware */
|
||||
if (ivtv_firmware_init(itv) == 0)
|
||||
break;
|
||||
if (fw_retry_count > 1)
|
||||
IVTV_WARN("Retry loading firmware\n");
|
||||
}
|
||||
if (fw_retry_count == 0) {
|
||||
IVTV_ERR("Error initializing firmware\n");
|
||||
goto free_i2c;
|
||||
}
|
||||
|
||||
/* Try and get firmware versions */
|
||||
IVTV_DEBUG_INFO("Getting firmware version..\n");
|
||||
ivtv_firmware_versions(itv);
|
||||
|
||||
/* Check yuv output filter table */
|
||||
if (itv->has_cx23415) ivtv_yuv_filter_check(itv);
|
||||
|
||||
@ -1157,44 +1132,16 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
|
||||
ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
|
||||
}
|
||||
|
||||
vf.tuner = 0;
|
||||
vf.type = V4L2_TUNER_ANALOG_TV;
|
||||
vf.frequency = 6400; /* the tuner 'baseline' frequency */
|
||||
|
||||
/* Set initial frequency. For PAL/SECAM broadcasts no
|
||||
'default' channel exists AFAIK. */
|
||||
if (itv->std == V4L2_STD_NTSC_M_JP) {
|
||||
vf.frequency = 1460; /* ch. 1 91250*16/1000 */
|
||||
}
|
||||
else if (itv->std & V4L2_STD_NTSC_M) {
|
||||
vf.frequency = 1076; /* ch. 4 67250*16/1000 */
|
||||
}
|
||||
|
||||
/* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
|
||||
are not. */
|
||||
itv->tuner_std = itv->std;
|
||||
|
||||
video_input = itv->active_input;
|
||||
itv->active_input++; /* Force update of input */
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
|
||||
|
||||
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
|
||||
in one place. */
|
||||
itv->std++; /* Force full standard initialization */
|
||||
itv->std_out = itv->std;
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
|
||||
|
||||
retval = ivtv_streams_setup(itv);
|
||||
if (retval) {
|
||||
IVTV_ERR("Error %d setting up streams\n", retval);
|
||||
goto free_i2c;
|
||||
}
|
||||
|
||||
if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
|
||||
ivtv_init_mpeg_decoder(itv);
|
||||
}
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
|
||||
|
||||
IVTV_DEBUG_IRQ("Masking interrupts\n");
|
||||
/* clear interrupt mask, effectively disabling interrupts */
|
||||
ivtv_set_irq_mask(itv, 0xffffffff);
|
||||
@ -1206,26 +1153,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
|
||||
IVTV_ERR("Failed to register irq %d\n", retval);
|
||||
goto free_streams;
|
||||
}
|
||||
|
||||
/* On a cx23416 this seems to be able to enable DMA to the chip? */
|
||||
if (!itv->has_cx23415)
|
||||
write_reg_sync(0x03, IVTV_REG_DMACONTROL);
|
||||
|
||||
/* Default interrupts enabled. For the PVR350 this includes the
|
||||
decoder VSYNC interrupt, which is always on. It is not only used
|
||||
during decoding but also by the OSD.
|
||||
Some old PVR250 cards had a cx23415, so testing for that is too
|
||||
general. Instead test if the card has video output capability. */
|
||||
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
|
||||
else
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
|
||||
|
||||
if (itv->has_cx23415)
|
||||
ivtv_set_osd_alpha(itv);
|
||||
|
||||
IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
|
||||
|
||||
return 0;
|
||||
|
||||
free_irq:
|
||||
@ -1255,55 +1183,126 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
|
||||
return retval;
|
||||
}
|
||||
|
||||
int ivtv_init_on_first_open(struct ivtv *itv)
|
||||
{
|
||||
struct v4l2_frequency vf;
|
||||
int fw_retry_count = 3;
|
||||
int video_input;
|
||||
|
||||
while (--fw_retry_count > 0) {
|
||||
/* load firmware */
|
||||
if (ivtv_firmware_init(itv) == 0)
|
||||
break;
|
||||
if (fw_retry_count > 1)
|
||||
IVTV_WARN("Retry loading firmware\n");
|
||||
}
|
||||
if (fw_retry_count == 0) {
|
||||
IVTV_ERR("Error initializing firmware\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try and get firmware versions */
|
||||
IVTV_DEBUG_INFO("Getting firmware version..\n");
|
||||
ivtv_firmware_versions(itv);
|
||||
|
||||
if (itv->card->hw_all & IVTV_HW_CX25840) {
|
||||
struct v4l2_control ctrl;
|
||||
|
||||
/* CX25840_CID_ENABLE_PVR150_WORKAROUND */
|
||||
ctrl.id = V4L2_CID_PRIVATE_BASE;
|
||||
ctrl.value = itv->pvr150_workaround;
|
||||
itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl);
|
||||
}
|
||||
|
||||
vf.tuner = 0;
|
||||
vf.type = V4L2_TUNER_ANALOG_TV;
|
||||
vf.frequency = 6400; /* the tuner 'baseline' frequency */
|
||||
|
||||
/* Set initial frequency. For PAL/SECAM broadcasts no
|
||||
'default' channel exists AFAIK. */
|
||||
if (itv->std == V4L2_STD_NTSC_M_JP) {
|
||||
vf.frequency = 1460; /* ch. 1 91250*16/1000 */
|
||||
}
|
||||
else if (itv->std & V4L2_STD_NTSC_M) {
|
||||
vf.frequency = 1076; /* ch. 4 67250*16/1000 */
|
||||
}
|
||||
|
||||
video_input = itv->active_input;
|
||||
itv->active_input++; /* Force update of input */
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
|
||||
|
||||
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
|
||||
in one place. */
|
||||
itv->std++; /* Force full standard initialization */
|
||||
itv->std_out = itv->std;
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
|
||||
|
||||
if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
|
||||
ivtv_init_mpeg_decoder(itv);
|
||||
}
|
||||
ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
|
||||
|
||||
/* On a cx23416 this seems to be able to enable DMA to the chip? */
|
||||
if (!itv->has_cx23415)
|
||||
write_reg_sync(0x03, IVTV_REG_DMACONTROL);
|
||||
|
||||
/* Default interrupts enabled. For the PVR350 this includes the
|
||||
decoder VSYNC interrupt, which is always on. It is not only used
|
||||
during decoding but also by the OSD.
|
||||
Some old PVR250 cards had a cx23415, so testing for that is too
|
||||
general. Instead test if the card has video output capability. */
|
||||
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
|
||||
ivtv_set_osd_alpha(itv);
|
||||
}
|
||||
else
|
||||
ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ivtv_remove(struct pci_dev *pci_dev)
|
||||
{
|
||||
struct ivtv *itv = pci_get_drvdata(pci_dev);
|
||||
|
||||
IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num);
|
||||
|
||||
/* Stop all captures */
|
||||
IVTV_DEBUG_INFO("Stopping all streams\n");
|
||||
if (atomic_read(&itv->capturing) > 0)
|
||||
ivtv_stop_all_captures(itv);
|
||||
if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) {
|
||||
/* Stop all captures */
|
||||
IVTV_DEBUG_INFO("Stopping all streams\n");
|
||||
if (atomic_read(&itv->capturing) > 0)
|
||||
ivtv_stop_all_captures(itv);
|
||||
|
||||
/* Stop all decoding */
|
||||
IVTV_DEBUG_INFO("Stopping decoding\n");
|
||||
if (atomic_read(&itv->decoding) > 0) {
|
||||
int type;
|
||||
/* Stop all decoding */
|
||||
IVTV_DEBUG_INFO("Stopping decoding\n");
|
||||
if (atomic_read(&itv->decoding) > 0) {
|
||||
int type;
|
||||
|
||||
if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
|
||||
type = IVTV_DEC_STREAM_TYPE_YUV;
|
||||
else
|
||||
type = IVTV_DEC_STREAM_TYPE_MPG;
|
||||
ivtv_stop_v4l2_decode_stream(&itv->streams[type],
|
||||
VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
|
||||
if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
|
||||
type = IVTV_DEC_STREAM_TYPE_YUV;
|
||||
else
|
||||
type = IVTV_DEC_STREAM_TYPE_MPG;
|
||||
ivtv_stop_v4l2_decode_stream(&itv->streams[type],
|
||||
VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
|
||||
}
|
||||
ivtv_halt_firmware(itv);
|
||||
}
|
||||
|
||||
/* Interrupts */
|
||||
IVTV_DEBUG_INFO("Disabling interrupts\n");
|
||||
ivtv_set_irq_mask(itv, 0xffffffff);
|
||||
del_timer_sync(&itv->dma_timer);
|
||||
|
||||
/* Stop all Work Queues */
|
||||
IVTV_DEBUG_INFO("Stop Work Queues\n");
|
||||
flush_workqueue(itv->irq_work_queues);
|
||||
destroy_workqueue(itv->irq_work_queues);
|
||||
|
||||
IVTV_DEBUG_INFO("Stopping Firmware\n");
|
||||
ivtv_halt_firmware(itv);
|
||||
|
||||
IVTV_DEBUG_INFO("Unregistering v4l devices\n");
|
||||
ivtv_streams_cleanup(itv);
|
||||
IVTV_DEBUG_INFO("Freeing dma resources\n");
|
||||
ivtv_udma_free(itv);
|
||||
|
||||
exit_ivtv_i2c(itv);
|
||||
|
||||
IVTV_DEBUG_INFO(" Releasing irq\n");
|
||||
free_irq(itv->dev->irq, (void *)itv);
|
||||
ivtv_iounmap(itv);
|
||||
|
||||
IVTV_DEBUG_INFO(" Releasing mem\n");
|
||||
release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
|
||||
release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE);
|
||||
if (itv->has_cx23415)
|
||||
|
@ -398,6 +398,8 @@ struct ivtv_mailbox_data {
|
||||
#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
|
||||
#define IVTV_F_I_PIO 19 /* PIO in progress */
|
||||
#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
|
||||
#define IVTV_F_I_INITED 21 /* set after first open */
|
||||
#define IVTV_F_I_FAILED 22 /* set if first open failed */
|
||||
|
||||
/* Event notifications */
|
||||
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
|
||||
@ -838,6 +840,9 @@ int ivtv_waitq(wait_queue_head_t *waitq);
|
||||
struct tveeprom; /* forward reference */
|
||||
void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv);
|
||||
|
||||
/* First-open initialization: load firmware, init cx25840, etc. */
|
||||
int ivtv_init_on_first_open(struct ivtv *itv);
|
||||
|
||||
/* This is a PCI post thing, where if the pci register is not read, then
|
||||
the write doesn't always take effect right away. By reading back the
|
||||
register any pending PCI writes will be performed (in order), and so
|
||||
|
@ -850,6 +850,15 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (!test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags))
|
||||
if (ivtv_init_on_first_open(itv))
|
||||
set_bit(IVTV_F_I_FAILED, &itv->i_flags);
|
||||
|
||||
if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) {
|
||||
printk(KERN_WARNING "ivtv: failed to initialize on minor %d\n", minor);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
if (y == IVTV_DEC_STREAM_TYPE_MPG &&
|
||||
test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
|
||||
return -EBUSY;
|
||||
|
Loading…
Reference in New Issue
Block a user