diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-driver.c | 7 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-driver.h | 18 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-fileops.c | 8 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-irq.c | 36 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-streams.c | 35 | ||||
-rw-r--r-- | linux/drivers/media/video/tveeprom.c | 2 |
6 files changed, 65 insertions, 41 deletions
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c index f10d4e7c5..19f66d9b8 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.c +++ b/linux/drivers/media/video/ivtv/ivtv-driver.c @@ -181,7 +181,7 @@ MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); MODULE_PARM_DESC(debug, "Debug level (bitmask). Default: errors only\n" - "\t\t\t(debug = 511 gives full debugging)"); + "\t\t\t(debug = 1023 gives full debugging)"); MODULE_PARM_DESC(ivtv_pci_latency, "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" "\t\t\tDefault: Yes"); @@ -623,6 +623,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */ itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */ + mutex_init(&itv->serialize_lock); mutex_init(&itv->i2c_bus_lock); mutex_init(&itv->udma.lock); @@ -1328,9 +1329,9 @@ static int module_start(void) return -1; } - if (ivtv_debug < 0 || ivtv_debug > 511) { + if (ivtv_debug < 0 || ivtv_debug > 1023) { ivtv_debug = 0; - printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 511!\n"); + printk(KERN_INFO "ivtv: debug value must be >= 0 and <= 1023!\n"); } if (pci_register_driver(&ivtv_pci_driver)) { diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.h b/linux/drivers/media/video/ivtv/ivtv-driver.h index 54648ee73..15ee09a61 100644 --- a/linux/drivers/media/video/ivtv/ivtv-driver.h +++ b/linux/drivers/media/video/ivtv/ivtv-driver.h @@ -271,6 +271,8 @@ extern const u32 yuv_offset[4]; #define IVTV_DBGFLG_IRQ (1 << 6) #define IVTV_DBGFLG_DEC (1 << 7) #define IVTV_DBGFLG_YUV (1 << 8) +/* Flag to turn on high volume debugging */ +#define IVTV_DBGFLG_HIGHVOL (1 << 9) /* NOTE: extra space before comma in 'itv->num , ## args' is required for gcc-2.95, otherwise it won't compile. */ @@ -289,6 +291,21 @@ extern const u32 yuv_offset[4]; #define IVTV_DEBUG_DEC(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_DEC, "dec", fmt , ## args) #define IVTV_DEBUG_YUV(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) +#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ + do { \ + if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ + printk(KERN_INFO "ivtv%d " type ": " fmt, itv->num , ## args); \ + } while (0) +#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warning", fmt , ## args) +#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info",fmt , ## args) +#define IVTV_DEBUG_HI_API(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_API, "api", fmt , ## args) +#define IVTV_DEBUG_HI_DMA(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DMA, "dma", fmt , ## args) +#define IVTV_DEBUG_HI_IOCTL(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IOCTL, "ioctl", fmt , ## args) +#define IVTV_DEBUG_HI_I2C(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_I2C, "i2c", fmt , ## args) +#define IVTV_DEBUG_HI_IRQ(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_IRQ, "irq", fmt , ## args) +#define IVTV_DEBUG_HI_DEC(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_DEC, "dec", fmt , ## args) +#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args) + #define IVTV_FB_DEBUG(x, type, fmt, args...) \ do { \ if ((x) & ivtv_debug) \ @@ -729,6 +746,7 @@ struct ivtv { int search_pack_header; spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ + struct mutex serialize_lock; /* lock used to serialize starting streams */ /* User based DMA for OSD */ struct ivtv_user_dma udma; diff --git a/linux/drivers/media/video/ivtv/ivtv-fileops.c b/linux/drivers/media/video/ivtv/ivtv-fileops.c index 555d5e636..ee7e884e9 100644 --- a/linux/drivers/media/video/ivtv/ivtv-fileops.c +++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c @@ -406,7 +406,7 @@ static ssize_t ivtv_read_pos(struct ivtv_stream *s, char __user *ubuf, size_t co ssize_t rc = count ? ivtv_read(s, ubuf, count, non_block) : 0; struct ivtv *itv = s->itv; - IVTV_DEBUG_INFO("read %zd from %s, got %zd\n", count, s->name, rc); + IVTV_DEBUG_HI_INFO("read %zd from %s, got %zd\n", count, s->name, rc); if (rc > 0) pos += rc; return rc; @@ -497,7 +497,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ struct ivtv_stream *s = &itv->streams[id->type]; int rc; - IVTV_DEBUG_IOCTL("read %zd bytes from %s\n", count, s->name); + IVTV_DEBUG_HI_IOCTL("read %zd bytes from %s\n", count, s->name); rc = ivtv_start_capture(id); if (rc) @@ -535,7 +535,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c int rc; DEFINE_WAIT(wait); - IVTV_DEBUG_IOCTL("write %zd bytes to %s\n", count, s->name); + IVTV_DEBUG_HI_IOCTL("write %zd bytes to %s\n", count, s->name); if (s->type != IVTV_DEC_STREAM_TYPE_MPG && s->type != IVTV_DEC_STREAM_TYPE_YUV && @@ -643,7 +643,7 @@ retry: to transfer the rest. */ if (count && !(filp->f_flags & O_NONBLOCK)) goto retry; - IVTV_DEBUG_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); + IVTV_DEBUG_HI_INFO("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused); return bytes_written; } diff --git a/linux/drivers/media/video/ivtv/ivtv-irq.c b/linux/drivers/media/video/ivtv/ivtv-irq.c index 4825d1749..7996371ec 100644 --- a/linux/drivers/media/video/ivtv/ivtv-irq.c +++ b/linux/drivers/media/video/ivtv/ivtv-irq.c @@ -48,7 +48,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) struct list_head *p; int i = 0; - IVTV_DEBUG_DMA("ivtv_pio_work_handler\n"); + IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n"); if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS || s->v4l2dev == NULL || !ivtv_use_pio(s)) { itv->cur_pio_stream = -1; @@ -56,7 +56,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv) write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); return; } - IVTV_DEBUG_DMA("Process PIO %s\n", s->name); + IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name); buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); list_for_each(p, &s->q_dma.list) { struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); @@ -193,7 +193,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA bytes_needed += UVsize; } - IVTV_DEBUG_DMA("%s %s: 0x%08x bytes at 0x%08x\n", + IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset); rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed); @@ -248,7 +248,7 @@ static void dma_post(struct ivtv_stream *s) u32 *u32buf; int x = 0; - IVTV_DEBUG_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", + IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, s->dma_offset); list_for_each(p, &s->q_dma.list) { buf = list_entry(p, struct ivtv_buffer, list); @@ -327,7 +327,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) unsigned long flags = 0; int idx = 0; - IVTV_DEBUG_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); + IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset); buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); list_for_each(p, &s->q_predma.list) { struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); @@ -374,7 +374,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; int i; - IVTV_DEBUG_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); + IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name); if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); @@ -403,7 +403,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) itv->vbi.dma_offset = s_vbi->dma_offset; s_vbi->SG_length = 0; set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); - IVTV_DEBUG_DMA("include DMA for %s\n", s->name); + IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name); } /* Mark last buffer size for Interrupt flag */ @@ -437,7 +437,7 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); - IVTV_DEBUG_DMA("start DMA for %s\n", s->name); + IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); /* put SG Handle into register 0x0c */ write_reg(s->SG_handle, IVTV_REG_DECDMAADDR); write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); @@ -453,7 +453,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) struct ivtv_buffer *buf; int hw_stream_type; - IVTV_DEBUG_IRQ("DEC DMA READ\n"); + IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); del_timer(&itv->dma_timer); if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS)); @@ -468,7 +468,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; hw_stream_type = 0; } - IVTV_DEBUG_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); + IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); ivtv_stream_sync_for_cpu(s); @@ -501,7 +501,7 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) del_timer(&itv->dma_timer); ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); - IVTV_DEBUG_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); + IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags)) data[1] = 3; else if (data[1] > 2) @@ -538,7 +538,7 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) return; } s = &itv->streams[itv->cur_pio_stream]; - IVTV_DEBUG_IRQ("ENC PIO COMPLETE %s\n", s->name); + IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); s->SG_length = 0; clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); clear_bit(IVTV_F_I_PIO, &itv->i_flags); @@ -596,7 +596,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv) /* Get DMA destination and size arguments from card */ ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data); - IVTV_DEBUG_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); + IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]); if (data[0] > 2 || data[1] == 0 || data[2] == 0) { IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n", @@ -616,7 +616,7 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s; - IVTV_DEBUG_IRQ("ENC START VBI CAP\n"); + IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n"); s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; /* If more than two VBI buffers are pending, then @@ -650,7 +650,7 @@ static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv) u32 data[CX2341X_MBOX_MAX_DATA]; struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI]; - IVTV_DEBUG_IRQ("DEC VBI REINSERT\n"); + IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n"); if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) && !stream_enc_dma_append(s, data)) { set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags); @@ -675,7 +675,7 @@ static void ivtv_irq_dec_data_req(struct ivtv *itv) itv->dma_data_req_offset = data[1]; s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; } - IVTV_DEBUG_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, + IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused, itv->dma_data_req_offset, itv->dma_data_req_size); if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) { set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags); @@ -801,10 +801,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id) /* Exclude interrupts noted below from the output, otherwise the log is flooded with these messages */ if (combo & ~0xff6d0400) - IVTV_DEBUG_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); + IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo); if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) { - IVTV_DEBUG_IRQ("DEC DMA COMPLETE\n"); + IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n"); } if (combo & IVTV_IRQ_DMA_READ) { diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c index 6af88ae92..287117187 100644 --- a/linux/drivers/media/video/ivtv/ivtv-streams.c +++ b/linux/drivers/media/video/ivtv/ivtv-streams.c @@ -446,6 +446,9 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) if (s->v4l2dev == NULL) return -EINVAL; + /* Big serialization lock to ensure no two streams are started + simultaneously: that can give all sorts of weird results. */ + mutex_lock(&itv->serialize_lock); IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name); switch (s->type) { @@ -487,6 +490,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) 0, sizeof(itv->vbi.sliced_mpeg_size)); break; default: + mutex_unlock(&itv->serialize_lock); return -EINVAL; } s->subtype = subtype; @@ -568,6 +572,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype)) { IVTV_DEBUG_WARN( "Error starting capture!\n"); + mutex_unlock(&itv->serialize_lock); return -EINVAL; } @@ -583,6 +588,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) /* you're live! sit back and await interrupts :) */ atomic_inc(&itv->capturing); + mutex_unlock(&itv->serialize_lock); return 0; } @@ -762,17 +768,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) /* when: 0 = end of GOP 1 = NOW!, type: 0 = mpeg, subtype: 3 = video+audio */ ivtv_vapi(itv, CX2341X_ENC_STOP_CAPTURE, 3, stopmode, cap_type, s->subtype); - /* only run these if we're shutting down the last cap */ - if (atomic_read(&itv->capturing) - 1 == 0) { - /* event notification (off) */ - if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { - /* type: 0 = refresh */ - /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ - ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); - ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); - } - } - then = jiffies; if (!test_bit(IVTV_F_S_PASSTHROUGH, &s->s_flags)) { @@ -812,7 +807,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) then = jiffies; /* Make sure DMA is complete */ add_wait_queue(&s->waitq, &wait); - set_current_state(TASK_INTERRUPTIBLE); do { /* check if DMA is pending */ if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */ @@ -827,9 +821,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) { break; } - - ivtv_sleep_timeout(HZ / 100, 1); - } while (then + HZ * 2 > jiffies); + } while (!ivtv_sleep_timeout(HZ / 100, 1) && then + HZ * 2 > jiffies); set_current_state(TASK_RUNNING); remove_wait_queue(&s->waitq, &wait); @@ -840,17 +832,30 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) /* Clear capture and no-read bits */ clear_bit(IVTV_F_S_STREAMING, &s->s_flags); + /* ensure these global cleanup actions are done only once */ + mutex_lock(&itv->serialize_lock); + if (s->type == IVTV_ENC_STREAM_TYPE_VBI) ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP); if (atomic_read(&itv->capturing) > 0) { + mutex_unlock(&itv->serialize_lock); return 0; } /* Set the following Interrupt mask bits for capture */ ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); + /* event notification (off) */ + if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) { + /* type: 0 = refresh */ + /* on/off: 0 = off, intr: 0x10000000, mbox_id: -1: none */ + ivtv_vapi(itv, CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_ENC_VIM_RST, -1); + ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VIM_RST); + } + wake_up(&s->waitq); + mutex_unlock(&itv->serialize_lock); return 0; } diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c index e97f666c7..7a36c525a 100644 --- a/linux/drivers/media/video/tveeprom.c +++ b/linux/drivers/media/video/tveeprom.c @@ -187,7 +187,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"}, { TUNER_ABSENT, "Thompson DTT757"}, /* 80-89 */ - { TUNER_ABSENT, "Philips FQ1216LME MK3"}, + { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216LME MK3"}, { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, |