/* Kernel DVB framework calls this when the feed needs to start. * The CX18 framework should enable the transport DMA handling * and queue processing. */ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct cx18_stream *stream = (struct cx18_stream *) demux->priv; struct cx18 *cx = stream->cx; int ret; u32 v; CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", feed->pid, feed->index); mutex_lock(&cx->serialize_lock); ret = cx18_init_on_first_open(cx); mutex_unlock(&cx->serialize_lock); if (ret) { CX18_ERR("Failed to initialize firmware starting DVB feed\n"); return ret; } ret = -EINVAL; switch (cx->card->type) { case CX18_CARD_HVR_1600_ESMT: case CX18_CARD_HVR_1600_SAMSUNG: v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL); v |= 0x00400000; /* Serial Mode */ v |= 0x00002000; /* Data Length - Byte */ v |= 0x00010000; /* Error - Polarity */ v |= 0x00020000; /* Error - Passthru */ v |= 0x000c0000; /* Error - Ignore */ cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); break; default: /* Assumption - Parallel transport - Signalling * undefined or default. */ break; } if (!demux->dmx.frontend) return -EINVAL; if (stream) { mutex_lock(&stream->dvb.feedlock); if (stream->dvb.feeding++ == 0) { CX18_DEBUG_INFO("Starting Transport DMA\n"); ret = cx18_start_v4l2_encode_stream(stream); if (ret < 0) { CX18_DEBUG_INFO( "Failed to start Transport DMA\n"); stream->dvb.feeding--; } } else ret = 0; mutex_unlock(&stream->dvb.feedlock); } return ret; }
int cx18_v4l2_open(struct file *filp) { 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", video_dev->minor); mutex_unlock(&cx->serialize_lock); return -ENXIO; } res = cx18_serialized_open(s, filp); mutex_unlock(&cx->serialize_lock); return res; }
int cx18_v4l2_open(struct inode *inode, struct file *filp) { int res, x, y = 0; struct cx18 *cx = NULL; struct cx18_stream *s = NULL; int minor = iminor(inode); /* 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->v4l2dev && s->v4l2dev->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; } mutex_lock(&cx->serialize_lock); if (cx18_init_on_first_open(cx)) { CX18_ERR("Failed to initialize on minor %d\n", minor); mutex_unlock(&cx->serialize_lock); return -ENXIO; } res = cx18_serialized_open(s, filp); mutex_unlock(&cx->serialize_lock); return res; }