mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: V4L/DVB (5751): Ivtv: fix ia64 printk format warnings. V4L/DVB (5761): Fix broken b2c2 dependency on non x86 architectures V4L/DVB (5673): Fix audio stuttering for saa711x/ivtv when in radio mode. V4L/DVB (5736): Add V4L2_FBUF_CAP/FLAG_LOCAL/GLOBAL_INV_ALPHA V4L/DVB (5732): Add ivtv CROPCAP support and fix ivtv S_CROP for video output. V4L/DVB (5730): Remove unused V4L2_CAP_VIDEO_OUTPUT_POS V4L/DVB (5720): Usbvision: fix urb allocation and submits V4L/DVB (5716): Tda10086,tda826x: fix tuning, STR/SNR values V4L/DVB (5675): Move big PIO accesses from the interrupt handler to a workhandler V4L/DVB (5699): Cinergyt2: fix file release handler V4L/DVB (5700): Saa7111: fix picture settings cache bug V4L/DVB (5702): Fix Kconfig items to avoid linkedition errors
This commit is contained in:
commit
b44c0267b7
@ -4,5 +4,6 @@ config VIDEO_SAA7146
|
||||
|
||||
config VIDEO_SAA7146_VV
|
||||
tristate
|
||||
depends on VIDEO_DEV
|
||||
select VIDEO_BUF
|
||||
select VIDEO_SAA7146
|
||||
|
@ -1,8 +1,11 @@
|
||||
b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
|
||||
flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \
|
||||
flexcop-dma.o
|
||||
flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
|
||||
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
|
||||
|
||||
ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
|
||||
b2c2-flexcop-objs += flexcop-dma.o
|
||||
endif
|
||||
|
||||
b2c2-flexcop-pci-objs = flexcop-pci.o
|
||||
obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
|
||||
|
||||
|
@ -519,8 +519,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct cinergyt2 *cinergyt2 = dvbdev->priv;
|
||||
|
||||
if (mutex_lock_interruptible(&cinergyt2->sem))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&cinergyt2->sem);
|
||||
|
||||
if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
|
||||
cancel_delayed_work(&cinergyt2->query_work);
|
||||
|
@ -41,6 +41,7 @@ struct tda10086_state {
|
||||
/* private demod data */
|
||||
u32 frequency;
|
||||
u32 symbol_rate;
|
||||
bool has_lock;
|
||||
};
|
||||
|
||||
static int debug = 0;
|
||||
@ -116,7 +117,7 @@ static int tda10086_init(struct dvb_frontend* fe)
|
||||
// misc setup
|
||||
tda10086_write_byte(state, 0x01, 0x94);
|
||||
tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
|
||||
tda10086_write_byte(state, 0x03, 0x64);
|
||||
tda10086_write_byte(state, 0x03, 0xe4);
|
||||
tda10086_write_byte(state, 0x04, 0x43);
|
||||
tda10086_write_byte(state, 0x0c, 0x0c);
|
||||
tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
|
||||
@ -146,7 +147,7 @@ static int tda10086_init(struct dvb_frontend* fe)
|
||||
// setup AGC
|
||||
tda10086_write_byte(state, 0x05, 0x0B);
|
||||
tda10086_write_byte(state, 0x37, 0x63);
|
||||
tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
|
||||
tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
|
||||
tda10086_write_byte(state, 0x40, 0x64);
|
||||
tda10086_write_byte(state, 0x41, 0x4f);
|
||||
tda10086_write_byte(state, 0x42, 0x43);
|
||||
@ -398,6 +399,10 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
// modify parameters for tuning
|
||||
tda10086_write_byte(state, 0x02, 0x35);
|
||||
state->has_lock = false;
|
||||
|
||||
// set params
|
||||
if (fe->ops.tuner_ops.set_params) {
|
||||
fe->ops.tuner_ops.set_params(fe, fe_params);
|
||||
@ -542,8 +547,14 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
|
||||
*fe_status |= FE_HAS_VITERBI;
|
||||
if (val & 0x08)
|
||||
*fe_status |= FE_HAS_SYNC;
|
||||
if (val & 0x10)
|
||||
if (val & 0x10) {
|
||||
*fe_status |= FE_HAS_LOCK;
|
||||
if (!state->has_lock) {
|
||||
state->has_lock = true;
|
||||
// modify parameters for stable reception
|
||||
tda10086_write_byte(state, 0x02, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -555,7 +566,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
_str = tda10086_read_byte(state, 0x43);
|
||||
_str = 0xff - tda10086_read_byte(state, 0x43);
|
||||
*signal = (_str << 8) | _str;
|
||||
|
||||
return 0;
|
||||
@ -568,7 +579,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
|
||||
|
||||
dprintk ("%s\n", __FUNCTION__);
|
||||
|
||||
_snr = tda10086_read_byte(state, 0x1c);
|
||||
_snr = 0xff - tda10086_read_byte(state, 0x1c);
|
||||
*snr = (_snr << 8) | _snr;
|
||||
|
||||
return 0;
|
||||
|
@ -89,8 +89,8 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
|
||||
buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
|
||||
buf[3] = div >> 7;
|
||||
buf[4] = div << 1;
|
||||
buf[5] = 0xff; // basedband filter to max
|
||||
buf[6] = 0xfe; // gains at max + no RF attenuation
|
||||
buf[5] = 0x77; // baseband cut-off 19 MHz
|
||||
buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
|
||||
buf[7] = 0x83; // charge pumps at high, tests off
|
||||
buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
|
||||
buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
|
||||
|
@ -347,7 +347,7 @@ endmenu # encoder / decoder chips
|
||||
|
||||
config VIDEO_VIVI
|
||||
tristate "Virtual Video Driver"
|
||||
depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI
|
||||
depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV
|
||||
select VIDEO_BUF
|
||||
default n
|
||||
---help---
|
||||
|
@ -86,7 +86,7 @@
|
||||
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \
|
||||
V4L2_CAP_SLICED_VBI_CAPTURE)
|
||||
#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \
|
||||
V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_VIDEO_OUTPUT_POS)
|
||||
V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
|
||||
|
||||
struct ivtv_card_video_input {
|
||||
u8 video_type; /* video input type */
|
||||
|
@ -652,6 +652,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
|
||||
itv->dma_timer.data = (unsigned long)itv;
|
||||
|
||||
itv->cur_dma_stream = -1;
|
||||
itv->cur_pio_stream = -1;
|
||||
itv->audio_stereo_mode = AUDIO_STEREO;
|
||||
itv->audio_bilingual_mode = AUDIO_MONO_LEFT;
|
||||
|
||||
|
@ -237,6 +237,7 @@ extern const u32 yuv_offset[4];
|
||||
#define IVTV_IRQ_ENC_VBI_CAP (0x1 << 29)
|
||||
#define IVTV_IRQ_ENC_VIM_RST (0x1 << 28)
|
||||
#define IVTV_IRQ_ENC_DMA_COMPLETE (0x1 << 27)
|
||||
#define IVTV_IRQ_ENC_PIO_COMPLETE (0x1 << 25)
|
||||
#define IVTV_IRQ_DEC_AUD_MODE_CHG (0x1 << 24)
|
||||
#define IVTV_IRQ_DEC_DATA_REQ (0x1 << 22)
|
||||
#define IVTV_IRQ_DEC_DMA_COMPLETE (0x1 << 20)
|
||||
@ -247,7 +248,8 @@ extern const u32 yuv_offset[4];
|
||||
#define IVTV_IRQ_DEC_VSYNC (0x1 << 10)
|
||||
|
||||
/* IRQ Masks */
|
||||
#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|IVTV_IRQ_DMA_READ)
|
||||
#define IVTV_IRQ_MASK_INIT (IVTV_IRQ_DMA_ERR|IVTV_IRQ_ENC_DMA_COMPLETE|\
|
||||
IVTV_IRQ_DMA_READ|IVTV_IRQ_ENC_PIO_COMPLETE)
|
||||
|
||||
#define IVTV_IRQ_MASK_CAPTURE (IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_EOS)
|
||||
#define IVTV_IRQ_MASK_DECODE (IVTV_IRQ_DEC_DATA_REQ|IVTV_IRQ_DEC_AUD_MODE_CHG)
|
||||
@ -374,6 +376,9 @@ struct ivtv_mailbox_data {
|
||||
#define IVTV_F_S_STREAMOFF 7 /* signal end of stream EOS */
|
||||
#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
|
||||
|
||||
#define IVTV_F_S_PIO_PENDING 9 /* this stream has pending PIO */
|
||||
#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
|
||||
|
||||
/* per-ivtv, i_flags */
|
||||
#define IVTV_F_I_DMA 0 /* DMA in progress */
|
||||
#define IVTV_F_I_UDMA 1 /* UDMA in progress */
|
||||
@ -390,8 +395,11 @@ struct ivtv_mailbox_data {
|
||||
#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
|
||||
#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
|
||||
#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
|
||||
#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */
|
||||
#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */
|
||||
#define IVTV_F_I_HAVE_WORK 15 /* Used in the interrupt handler: there is work to be done */
|
||||
#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
|
||||
#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
|
||||
#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 */
|
||||
|
||||
/* Event notifications */
|
||||
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
|
||||
@ -484,6 +492,7 @@ struct ivtv_stream {
|
||||
|
||||
/* Base Dev SG Array for cx23415/6 */
|
||||
struct ivtv_SG_element *SGarray;
|
||||
struct ivtv_SG_element *PIOarray;
|
||||
dma_addr_t SG_handle;
|
||||
int SG_length;
|
||||
|
||||
@ -706,6 +715,7 @@ struct ivtv {
|
||||
atomic_t decoding; /* count number of active decoding streams */
|
||||
u32 irq_rr_idx; /* Round-robin stream index */
|
||||
int cur_dma_stream; /* index of stream doing DMA */
|
||||
int cur_pio_stream; /* index of stream doing PIO */
|
||||
u32 dma_data_req_offset;
|
||||
u32 dma_data_req_size;
|
||||
int output_mode; /* NONE, MPG, YUV, UDMA YUV, passthrough */
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "ivtv-yuv.h"
|
||||
#include "ivtv-controls.h"
|
||||
#include "ivtv-ioctl.h"
|
||||
#include "ivtv-cards.h"
|
||||
#include <media/saa7115.h>
|
||||
|
||||
/* This function tries to claim the stream for a specific file descriptor.
|
||||
If no one else is using this stream then the stream is claimed and
|
||||
@ -786,6 +788,13 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
|
||||
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
|
||||
/* Select correct audio input (i.e. TV tuner or Line in) */
|
||||
ivtv_audio_set_io(itv);
|
||||
if (itv->hw_flags & IVTV_HW_SAA711X)
|
||||
{
|
||||
struct v4l2_crystal_freq crystal_freq;
|
||||
crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
|
||||
crystal_freq.flags = 0;
|
||||
ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
|
||||
}
|
||||
/* Done! Unmute and continue. */
|
||||
ivtv_unmute(itv);
|
||||
ivtv_release_stream(s);
|
||||
@ -872,6 +881,13 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
|
||||
set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
|
||||
/* Select the correct audio input (i.e. radio tuner) */
|
||||
ivtv_audio_set_io(itv);
|
||||
if (itv->hw_flags & IVTV_HW_SAA711X)
|
||||
{
|
||||
struct v4l2_crystal_freq crystal_freq;
|
||||
crystal_freq.freq = SAA7115_FREQ_32_11_MHZ;
|
||||
crystal_freq.flags = SAA7115_FREQ_FL_APLL;
|
||||
ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
|
||||
}
|
||||
/* Done! Unmute and continue. */
|
||||
ivtv_unmute(itv);
|
||||
}
|
||||
|
@ -532,11 +532,6 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
|
||||
itv->yuv_info.yuv_forced_update = 1;
|
||||
return 0;
|
||||
}
|
||||
if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
|
||||
r.width, r.height, r.left, r.top))
|
||||
itv->main_rect = r;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -799,9 +794,39 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
|
||||
return ivtv_get_fmt(itv, id->type, fmt);
|
||||
}
|
||||
|
||||
case VIDIOC_CROPCAP: {
|
||||
struct v4l2_cropcap *cropcap = arg;
|
||||
|
||||
if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
|
||||
cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||||
return -EINVAL;
|
||||
cropcap->bounds.top = cropcap->bounds.left = 0;
|
||||
cropcap->bounds.width = 720;
|
||||
if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
|
||||
cropcap->bounds.height = itv->is_50hz ? 576 : 480;
|
||||
cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
|
||||
cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
|
||||
} else {
|
||||
cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
|
||||
cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
|
||||
cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
|
||||
}
|
||||
cropcap->defrect = cropcap->bounds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case VIDIOC_S_CROP: {
|
||||
struct v4l2_crop *crop = arg;
|
||||
|
||||
if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
|
||||
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
|
||||
if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
|
||||
crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
|
||||
itv->main_rect = crop->c;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
|
||||
@ -810,6 +835,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
|
||||
case VIDIOC_G_CROP: {
|
||||
struct v4l2_crop *crop = arg;
|
||||
|
||||
if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
|
||||
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
|
||||
crop->c = itv->main_rect;
|
||||
return 0;
|
||||
}
|
||||
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
|
||||
@ -977,7 +1007,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
|
||||
if (itv->hw_flags & IVTV_HW_CX25840) {
|
||||
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
|
||||
}
|
||||
IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
|
||||
IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
|
||||
|
||||
/* Tuner */
|
||||
ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
|
||||
@ -1207,7 +1237,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
|
||||
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
|
||||
(s->buffers * s->buf_size) / 1024, s->buffers);
|
||||
}
|
||||
IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
|
||||
IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
|
||||
IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
|
||||
break;
|
||||
}
|
||||
@ -1455,6 +1485,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
|
||||
case VIDIOC_S_FMT:
|
||||
case VIDIOC_TRY_FMT:
|
||||
case VIDIOC_ENUM_FMT:
|
||||
case VIDIOC_CROPCAP:
|
||||
case VIDIOC_G_CROP:
|
||||
case VIDIOC_S_CROP:
|
||||
case VIDIOC_G_FREQUENCY:
|
||||
|
@ -31,8 +31,6 @@
|
||||
|
||||
#define DMA_MAGIC_COOKIE 0x000001fe
|
||||
|
||||
#define SLICED_VBI_PIO 1
|
||||
|
||||
static void ivtv_dma_dec_start(struct ivtv_stream *s);
|
||||
|
||||
static const int ivtv_stream_map[] = {
|
||||
@ -42,12 +40,40 @@ static const int ivtv_stream_map[] = {
|
||||
IVTV_ENC_STREAM_TYPE_VBI,
|
||||
};
|
||||
|
||||
static inline int ivtv_use_pio(struct ivtv_stream *s)
|
||||
{
|
||||
struct ivtv *itv = s->itv;
|
||||
|
||||
return s->dma == PCI_DMA_NONE ||
|
||||
(SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
|
||||
static void ivtv_pio_work_handler(struct ivtv *itv)
|
||||
{
|
||||
struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
|
||||
struct ivtv_buffer *buf;
|
||||
struct list_head *p;
|
||||
int i = 0;
|
||||
|
||||
IVTV_DEBUG_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;
|
||||
/* trigger PIO complete user interrupt */
|
||||
write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
|
||||
return;
|
||||
}
|
||||
IVTV_DEBUG_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);
|
||||
u32 size = s->PIOarray[i].size & 0x3ffff;
|
||||
|
||||
/* Copy the data from the card to the buffer */
|
||||
if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
|
||||
memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size);
|
||||
}
|
||||
else {
|
||||
memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size);
|
||||
}
|
||||
if (s->PIOarray[i].size & 0x80000000)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
|
||||
}
|
||||
|
||||
void ivtv_irq_work_handler(struct work_struct *work)
|
||||
@ -56,8 +82,11 @@ void ivtv_irq_work_handler(struct work_struct *work)
|
||||
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
|
||||
ivtv_pio_work_handler(itv);
|
||||
|
||||
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
|
||||
vbi_work_handler(itv);
|
||||
ivtv_vbi_work_handler(itv);
|
||||
|
||||
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
|
||||
ivtv_yuv_work_handler(itv);
|
||||
@ -173,8 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
|
||||
}
|
||||
s->buffers_stolen = rc;
|
||||
|
||||
/* got the buffers, now fill in SGarray (DMA) or copy the data from the card
|
||||
to the buffers (PIO). */
|
||||
/* got the buffers, now fill in SGarray (DMA) */
|
||||
buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
|
||||
memset(buf->buf, 0, 128);
|
||||
list_for_each(p, &s->q_predma.list) {
|
||||
@ -182,21 +210,11 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
|
||||
|
||||
if (skip_bufs-- > 0)
|
||||
continue;
|
||||
if (!ivtv_use_pio(s)) {
|
||||
s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
|
||||
s->SGarray[idx].src = cpu_to_le32(offset);
|
||||
s->SGarray[idx].size = cpu_to_le32(s->buf_size);
|
||||
}
|
||||
s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle);
|
||||
s->SGarray[idx].src = cpu_to_le32(offset);
|
||||
s->SGarray[idx].size = cpu_to_le32(s->buf_size);
|
||||
buf->bytesused = (size < s->buf_size) ? size : s->buf_size;
|
||||
|
||||
/* If PIO, then copy the data from the card to the buffer */
|
||||
if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
|
||||
memcpy_fromio(buf->buf, itv->dec_mem + offset - IVTV_DECODER_OFFSET, buf->bytesused);
|
||||
}
|
||||
else if (ivtv_use_pio(s)) {
|
||||
memcpy_fromio(buf->buf, itv->enc_mem + offset, buf->bytesused);
|
||||
}
|
||||
|
||||
s->q_predma.bytesused += buf->bytesused;
|
||||
size -= buf->bytesused;
|
||||
offset += s->buf_size;
|
||||
@ -224,11 +242,6 @@ static void dma_post(struct ivtv_stream *s)
|
||||
u32 *u32buf;
|
||||
int x = 0;
|
||||
|
||||
if (ivtv_use_pio(s)) {
|
||||
if (s->q_predma.bytesused)
|
||||
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
|
||||
s->SG_length = 0;
|
||||
}
|
||||
IVTV_DEBUG_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) {
|
||||
@ -278,10 +291,14 @@ static void dma_post(struct ivtv_stream *s)
|
||||
if (buf)
|
||||
buf->bytesused += s->dma_last_offset;
|
||||
if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
|
||||
/* Parse and Groom VBI Data */
|
||||
s->q_dma.bytesused -= buf->bytesused;
|
||||
ivtv_process_vbi_data(itv, buf, 0, s->type);
|
||||
s->q_dma.bytesused += buf->bytesused;
|
||||
list_for_each(p, &s->q_dma.list) {
|
||||
buf = list_entry(p, struct ivtv_buffer, list);
|
||||
|
||||
/* Parse and Groom VBI Data */
|
||||
s->q_dma.bytesused -= buf->bytesused;
|
||||
ivtv_process_vbi_data(itv, buf, 0, s->type);
|
||||
s->q_dma.bytesused += buf->bytesused;
|
||||
}
|
||||
if (s->id == -1) {
|
||||
ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
|
||||
return;
|
||||
@ -351,10 +368,14 @@ 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);
|
||||
|
||||
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);
|
||||
s->SGarray[s->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
|
||||
|
||||
if (ivtv_use_dma(s))
|
||||
s->SGarray[s->SG_length - 1].size =
|
||||
cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256);
|
||||
|
||||
/* If this is an MPEG stream, and VBI data is also pending, then append the
|
||||
VBI DMA to the MPEG DMA and transfer both sets of data at once.
|
||||
@ -368,7 +389,8 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
|
||||
if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length &&
|
||||
s->SG_length + s_vbi->SG_length <= s->buffers) {
|
||||
ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
|
||||
s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
|
||||
if (ivtv_use_dma(s_vbi))
|
||||
s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256);
|
||||
for (i = 0; i < s_vbi->SG_length; i++) {
|
||||
s->SGarray[s->SG_length++] = s_vbi->SGarray[i];
|
||||
}
|
||||
@ -381,14 +403,26 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s)
|
||||
/* Mark last buffer size for Interrupt flag */
|
||||
s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000);
|
||||
|
||||
/* Sync Hardware SG List of buffers */
|
||||
ivtv_stream_sync_for_device(s);
|
||||
write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
|
||||
write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
|
||||
set_bit(IVTV_F_I_DMA, &itv->i_flags);
|
||||
itv->cur_dma_stream = s->type;
|
||||
itv->dma_timer.expires = jiffies + HZ / 10;
|
||||
add_timer(&itv->dma_timer);
|
||||
if (ivtv_use_pio(s)) {
|
||||
for (i = 0; i < s->SG_length; i++) {
|
||||
s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src);
|
||||
s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size);
|
||||
}
|
||||
set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
|
||||
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
|
||||
set_bit(IVTV_F_I_PIO, &itv->i_flags);
|
||||
itv->cur_pio_stream = s->type;
|
||||
}
|
||||
else {
|
||||
/* Sync Hardware SG List of buffers */
|
||||
ivtv_stream_sync_for_device(s);
|
||||
write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR);
|
||||
write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
|
||||
set_bit(IVTV_F_I_DMA, &itv->i_flags);
|
||||
itv->cur_dma_stream = s->type;
|
||||
itv->dma_timer.expires = jiffies + HZ / 10;
|
||||
add_timer(&itv->dma_timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void ivtv_dma_dec_start(struct ivtv_stream *s)
|
||||
@ -489,6 +523,40 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
|
||||
wake_up(&itv->dma_waitq);
|
||||
}
|
||||
|
||||
static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
|
||||
{
|
||||
struct ivtv_stream *s;
|
||||
|
||||
if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
|
||||
itv->cur_pio_stream = -1;
|
||||
return;
|
||||
}
|
||||
s = &itv->streams[itv->cur_pio_stream];
|
||||
IVTV_DEBUG_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);
|
||||
itv->cur_pio_stream = -1;
|
||||
dma_post(s);
|
||||
if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
|
||||
ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
|
||||
else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
|
||||
ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
|
||||
else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
|
||||
ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
|
||||
clear_bit(IVTV_F_I_PIO, &itv->i_flags);
|
||||
if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
|
||||
u32 tmp;
|
||||
|
||||
s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
|
||||
tmp = s->dma_offset;
|
||||
s->dma_offset = itv->vbi.dma_offset;
|
||||
dma_post(s);
|
||||
s->dma_offset = tmp;
|
||||
}
|
||||
wake_up(&itv->dma_waitq);
|
||||
}
|
||||
|
||||
static void ivtv_irq_dma_err(struct ivtv *itv)
|
||||
{
|
||||
u32 data[CX2341X_MBOX_MAX_DATA];
|
||||
@ -532,13 +600,7 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
|
||||
clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
|
||||
s = &itv->streams[ivtv_stream_map[data[0]]];
|
||||
if (!stream_enc_dma_append(s, data)) {
|
||||
if (ivtv_use_pio(s)) {
|
||||
dma_post(s);
|
||||
ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[0]);
|
||||
}
|
||||
else {
|
||||
set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
|
||||
}
|
||||
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -551,15 +613,6 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
|
||||
IVTV_DEBUG_IRQ("ENC START VBI CAP\n");
|
||||
s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
|
||||
|
||||
if (ivtv_use_pio(s)) {
|
||||
if (stream_enc_dma_append(s, data))
|
||||
return;
|
||||
if (s->q_predma.bytesused)
|
||||
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
|
||||
s->SG_length = 0;
|
||||
dma_post(s);
|
||||
return;
|
||||
}
|
||||
/* If more than two VBI buffers are pending, then
|
||||
clear the old ones and start with this new one.
|
||||
This can happen during transition stages when MPEG capturing is
|
||||
@ -582,11 +635,11 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
|
||||
if (!stream_enc_dma_append(s, data) &&
|
||||
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
|
||||
set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags);
|
||||
set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
|
||||
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
|
||||
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];
|
||||
@ -594,7 +647,7 @@ static void ivtv_irq_dev_vbi_reinsert(struct ivtv *itv)
|
||||
IVTV_DEBUG_IRQ("DEC VBI REINSERT\n");
|
||||
if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
|
||||
!stream_enc_dma_append(s, data)) {
|
||||
dma_post(s);
|
||||
set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -657,7 +710,6 @@ static void ivtv_irq_vsync(struct ivtv *itv)
|
||||
}
|
||||
if (frame != (itv->lastVsyncFrame & 1)) {
|
||||
struct ivtv_stream *s = ivtv_get_output_stream(itv);
|
||||
int work = 0;
|
||||
|
||||
itv->lastVsyncFrame += 1;
|
||||
if (frame == 0) {
|
||||
@ -678,7 +730,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
|
||||
/* Send VBI to saa7127 */
|
||||
if (frame) {
|
||||
set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
|
||||
work = 1;
|
||||
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
|
||||
}
|
||||
|
||||
/* Check if we need to update the yuv registers */
|
||||
@ -691,11 +743,9 @@ static void ivtv_irq_vsync(struct ivtv *itv)
|
||||
itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
|
||||
itv->yuv_info.yuv_forced_update = 0;
|
||||
set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
|
||||
work = 1;
|
||||
set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
|
||||
}
|
||||
}
|
||||
if (work)
|
||||
queue_work(itv->irq_work_queues, &itv->irq_work_queue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,6 +805,10 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
|
||||
ivtv_irq_enc_dma_complete(itv);
|
||||
}
|
||||
|
||||
if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
|
||||
ivtv_irq_enc_pio_complete(itv);
|
||||
}
|
||||
|
||||
if (combo & IVTV_IRQ_DMA_ERR) {
|
||||
ivtv_irq_dma_err(itv);
|
||||
}
|
||||
@ -768,7 +822,7 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
|
||||
}
|
||||
|
||||
if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
|
||||
ivtv_irq_dev_vbi_reinsert(itv);
|
||||
ivtv_irq_dec_vbi_reinsert(itv);
|
||||
}
|
||||
|
||||
if (combo & IVTV_IRQ_ENC_EOS) {
|
||||
@ -813,6 +867,22 @@ irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
|
||||
}
|
||||
}
|
||||
|
||||
if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
|
||||
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
|
||||
int idx = (i + itv->irq_rr_idx++) % IVTV_MAX_STREAMS;
|
||||
struct ivtv_stream *s = &itv->streams[idx];
|
||||
|
||||
if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
|
||||
continue;
|
||||
if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
|
||||
ivtv_dma_enc_start(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags))
|
||||
queue_work(itv->irq_work_queues, &itv->irq_work_queue);
|
||||
|
||||
spin_unlock(&itv->dma_reg_lock);
|
||||
|
||||
/* If we've just handled a 'forced' vsync, it's safest to say it
|
||||
|
@ -195,14 +195,26 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
|
||||
s->dma != PCI_DMA_NONE ? "DMA " : "",
|
||||
s->name, s->buffers, s->buf_size, s->buffers * s->buf_size / 1024);
|
||||
|
||||
/* Allocate DMA SG Arrays */
|
||||
if (s->dma != PCI_DMA_NONE) {
|
||||
s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
|
||||
if (s->SGarray == NULL) {
|
||||
IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
|
||||
if (ivtv_might_use_pio(s)) {
|
||||
s->PIOarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
|
||||
if (s->PIOarray == NULL) {
|
||||
IVTV_ERR("Could not allocate PIOarray for %s stream\n", s->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
s->SG_length = 0;
|
||||
}
|
||||
|
||||
/* Allocate DMA SG Arrays */
|
||||
s->SGarray = (struct ivtv_SG_element *)kzalloc(SGsize, GFP_KERNEL);
|
||||
if (s->SGarray == NULL) {
|
||||
IVTV_ERR("Could not allocate SGarray for %s stream\n", s->name);
|
||||
if (ivtv_might_use_pio(s)) {
|
||||
kfree(s->PIOarray);
|
||||
s->PIOarray = NULL;
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
s->SG_length = 0;
|
||||
if (ivtv_might_use_dma(s)) {
|
||||
s->SG_handle = pci_map_single(itv->dev, s->SGarray, SGsize, s->dma);
|
||||
ivtv_stream_sync_for_cpu(s);
|
||||
}
|
||||
@ -219,7 +231,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
|
||||
break;
|
||||
}
|
||||
INIT_LIST_HEAD(&buf->list);
|
||||
if (s->dma != PCI_DMA_NONE) {
|
||||
if (ivtv_might_use_dma(s)) {
|
||||
buf->dma_handle = pci_map_single(s->itv->dev,
|
||||
buf->buf, s->buf_size + 256, s->dma);
|
||||
ivtv_buf_sync_for_cpu(s, buf);
|
||||
@ -242,7 +254,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
|
||||
|
||||
/* empty q_free */
|
||||
while ((buf = ivtv_dequeue(s, &s->q_free))) {
|
||||
if (s->dma != PCI_DMA_NONE)
|
||||
if (ivtv_might_use_dma(s))
|
||||
pci_unmap_single(s->itv->dev, buf->dma_handle,
|
||||
s->buf_size + 256, s->dma);
|
||||
kfree(buf->buf);
|
||||
@ -256,6 +268,9 @@ void ivtv_stream_free(struct ivtv_stream *s)
|
||||
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
|
||||
s->SG_handle = IVTV_DMA_UNMAPPED;
|
||||
}
|
||||
kfree(s->SGarray);
|
||||
kfree(s->PIOarray);
|
||||
s->PIOarray = NULL;
|
||||
s->SGarray = NULL;
|
||||
s->SG_length = 0;
|
||||
}
|
||||
|
@ -20,18 +20,43 @@
|
||||
*/
|
||||
|
||||
#define IVTV_DMA_UNMAPPED ((u32) -1)
|
||||
#define SLICED_VBI_PIO 1
|
||||
|
||||
/* ivtv_buffer utility functions */
|
||||
|
||||
static inline int ivtv_might_use_pio(struct ivtv_stream *s)
|
||||
{
|
||||
return s->dma == PCI_DMA_NONE || (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI);
|
||||
}
|
||||
|
||||
static inline int ivtv_use_pio(struct ivtv_stream *s)
|
||||
{
|
||||
struct ivtv *itv = s->itv;
|
||||
|
||||
return s->dma == PCI_DMA_NONE ||
|
||||
(SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
|
||||
}
|
||||
|
||||
static inline int ivtv_might_use_dma(struct ivtv_stream *s)
|
||||
{
|
||||
return s->dma != PCI_DMA_NONE;
|
||||
}
|
||||
|
||||
static inline int ivtv_use_dma(struct ivtv_stream *s)
|
||||
{
|
||||
return !ivtv_use_pio(s);
|
||||
}
|
||||
|
||||
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
|
||||
{
|
||||
if (s->dma != PCI_DMA_NONE)
|
||||
if (ivtv_use_dma(s))
|
||||
pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
|
||||
s->buf_size + 256, s->dma);
|
||||
}
|
||||
|
||||
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
|
||||
{
|
||||
if (s->dma != PCI_DMA_NONE)
|
||||
if (ivtv_use_dma(s))
|
||||
pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
|
||||
s->buf_size + 256, s->dma);
|
||||
}
|
||||
@ -53,12 +78,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
|
||||
|
||||
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
|
||||
{
|
||||
pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
|
||||
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
|
||||
if (ivtv_use_dma(s))
|
||||
pci_dma_sync_single_for_cpu(s->itv->dev, s->SG_handle,
|
||||
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
|
||||
{
|
||||
pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
|
||||
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
|
||||
if (ivtv_use_dma(s))
|
||||
pci_dma_sync_single_for_device(s->itv->dev, s->SG_handle,
|
||||
sizeof(struct ivtv_SG_element) * s->buffers, PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
@ -868,7 +868,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
|
||||
if (!test_bit(IVTV_F_S_STREAMING, &s->s_flags))
|
||||
return 0;
|
||||
|
||||
IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", pts, flags);
|
||||
IVTV_DEBUG_INFO("Stop Decode at %llu, flags: %x\n", (unsigned long long)pts, flags);
|
||||
|
||||
/* Stop Decoder */
|
||||
if (!(flags & VIDEO_CMD_STOP_IMMEDIATELY) || pts) {
|
||||
|
@ -450,7 +450,7 @@ void ivtv_disable_vbi(struct ivtv *itv)
|
||||
}
|
||||
|
||||
|
||||
void vbi_work_handler(struct ivtv *itv)
|
||||
void ivtv_vbi_work_handler(struct ivtv *itv)
|
||||
{
|
||||
struct v4l2_sliced_vbi_data data;
|
||||
|
||||
|
@ -23,4 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
|
||||
int ivtv_used_line(struct ivtv *itv, int line, int field);
|
||||
void ivtv_disable_vbi(struct ivtv *itv);
|
||||
void ivtv_set_vbi(unsigned long arg);
|
||||
void vbi_work_handler(struct ivtv *itv);
|
||||
void ivtv_vbi_work_handler(struct ivtv *itv);
|
||||
|
@ -75,10 +75,6 @@ struct saa7111 {
|
||||
int norm;
|
||||
int input;
|
||||
int enable;
|
||||
int bright;
|
||||
int contrast;
|
||||
int hue;
|
||||
int sat;
|
||||
};
|
||||
|
||||
#define I2C_SAA7111 0x48
|
||||
@ -96,6 +92,17 @@ saa7111_write (struct i2c_client *client,
|
||||
return i2c_smbus_write_byte_data(client, reg, value);
|
||||
}
|
||||
|
||||
static inline void
|
||||
saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
|
||||
{
|
||||
struct saa7111 *decoder = i2c_get_clientdata(client);
|
||||
|
||||
if (decoder->reg[reg] != value) {
|
||||
decoder->reg[reg] = value;
|
||||
i2c_smbus_write_byte_data(client, reg, value);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
saa7111_write_block (struct i2c_client *client,
|
||||
const u8 *data,
|
||||
@ -439,28 +446,14 @@ saa7111_command (struct i2c_client *client,
|
||||
{
|
||||
struct video_picture *pic = arg;
|
||||
|
||||
if (decoder->bright != pic->brightness) {
|
||||
/* We want 0 to 255 we get 0-65535 */
|
||||
decoder->bright = pic->brightness;
|
||||
saa7111_write(client, 0x0a, decoder->bright >> 8);
|
||||
}
|
||||
if (decoder->contrast != pic->contrast) {
|
||||
/* We want 0 to 127 we get 0-65535 */
|
||||
decoder->contrast = pic->contrast;
|
||||
saa7111_write(client, 0x0b,
|
||||
decoder->contrast >> 9);
|
||||
}
|
||||
if (decoder->sat != pic->colour) {
|
||||
/* We want 0 to 127 we get 0-65535 */
|
||||
decoder->sat = pic->colour;
|
||||
saa7111_write(client, 0x0c, decoder->sat >> 9);
|
||||
}
|
||||
if (decoder->hue != pic->hue) {
|
||||
/* We want -128 to 127 we get 0-65535 */
|
||||
decoder->hue = pic->hue;
|
||||
saa7111_write(client, 0x0d,
|
||||
(decoder->hue - 32768) >> 8);
|
||||
}
|
||||
/* We want 0 to 255 we get 0-65535 */
|
||||
saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
|
||||
/* We want 0 to 127 we get 0-65535 */
|
||||
saa7111_write(client, 0x0b, pic->contrast >> 9);
|
||||
/* We want 0 to 127 we get 0-65535 */
|
||||
saa7111_write(client, 0x0c, pic->colour >> 9);
|
||||
/* We want -128 to 127 we get 0-65535 */
|
||||
saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -524,10 +517,6 @@ saa7111_detect_client (struct i2c_adapter *adapter,
|
||||
decoder->norm = VIDEO_MODE_NTSC;
|
||||
decoder->input = 0;
|
||||
decoder->enable = 1;
|
||||
decoder->bright = 32768;
|
||||
decoder->contrast = 32768;
|
||||
decoder->hue = 32768;
|
||||
decoder->sat = 32768;
|
||||
i2c_set_clientdata(client, decoder);
|
||||
|
||||
i = i2c_attach_client(client);
|
||||
|
@ -1414,6 +1414,11 @@ static void usbvision_isocIrq(struct urb *urb)
|
||||
if (!USBVISION_IS_OPERATIONAL(usbvision))
|
||||
return;
|
||||
|
||||
/* any urb with wrong status is ignored without acknowledgement */
|
||||
if (urb->status == -ENOENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
f = &usbvision->curFrame;
|
||||
|
||||
/* Manage streaming interruption */
|
||||
@ -1436,18 +1441,21 @@ static void usbvision_isocIrq(struct urb *urb)
|
||||
if (usbvision->streaming == Stream_On) {
|
||||
|
||||
/* If we collected enough data let's parse! */
|
||||
if (scratch_len(usbvision) > USBVISION_HEADER_LENGTH) { /* 12 == header_length */
|
||||
/*If we don't have a frame we're current working on, complain */
|
||||
if(!list_empty(&(usbvision->inqueue))) {
|
||||
if (!(*f)) {
|
||||
(*f) = list_entry(usbvision->inqueue.next,struct usbvision_frame, frame);
|
||||
}
|
||||
usbvision_parse_data(usbvision);
|
||||
}
|
||||
else {
|
||||
PDEBUG(DBG_IRQ, "received data, but no one needs it");
|
||||
scratch_reset(usbvision);
|
||||
if ((scratch_len(usbvision) > USBVISION_HEADER_LENGTH) &&
|
||||
(!list_empty(&(usbvision->inqueue))) ) {
|
||||
if (!(*f)) {
|
||||
(*f) = list_entry(usbvision->inqueue.next,
|
||||
struct usbvision_frame,
|
||||
frame);
|
||||
}
|
||||
usbvision_parse_data(usbvision);
|
||||
}
|
||||
else {
|
||||
/*If we don't have a frame
|
||||
we're current working on, complain */
|
||||
PDEBUG(DBG_IRQ,
|
||||
"received data, but no one needs it");
|
||||
scratch_reset(usbvision);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1466,10 +1474,10 @@ static void usbvision_isocIrq(struct urb *urb)
|
||||
urb->dev = usbvision->dev;
|
||||
errCode = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
|
||||
/* Disable this warning. By design of the driver. */
|
||||
// if(errCode) {
|
||||
// err("%s: usb_submit_urb failed: error %d", __FUNCTION__, errCode);
|
||||
// }
|
||||
if(errCode) {
|
||||
err("%s: usb_submit_urb failed: error %d",
|
||||
__FUNCTION__, errCode);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2394,7 +2402,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
|
||||
{
|
||||
struct usb_device *dev = usbvision->dev;
|
||||
int bufIdx, errCode, regValue;
|
||||
const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
|
||||
int sb_size;
|
||||
|
||||
if (!USBVISION_IS_OPERATIONAL(usbvision))
|
||||
return -EFAULT;
|
||||
@ -2408,11 +2416,14 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
|
||||
usbvision->last_error = errCode;
|
||||
return -EBUSY;
|
||||
}
|
||||
sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
|
||||
|
||||
regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
|
||||
regValue = (16 - usbvision_read_reg(usbvision,
|
||||
USBVISION_ALTER_REG)) & 0x0F;
|
||||
|
||||
usbvision->usb_bandwidth = regValue >> 1;
|
||||
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
|
||||
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
|
||||
usbvision->usb_bandwidth);
|
||||
|
||||
|
||||
|
||||
@ -2428,7 +2439,11 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
|
||||
return -ENOMEM;
|
||||
}
|
||||
usbvision->sbuf[bufIdx].urb = urb;
|
||||
usbvision->sbuf[bufIdx].data = usb_buffer_alloc(usbvision->dev, sb_size, GFP_KERNEL,&urb->transfer_dma);
|
||||
usbvision->sbuf[bufIdx].data =
|
||||
usb_buffer_alloc(usbvision->dev,
|
||||
sb_size,
|
||||
GFP_KERNEL,
|
||||
&urb->transfer_dma);
|
||||
urb->dev = dev;
|
||||
urb->context = usbvision;
|
||||
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
|
||||
@ -2442,21 +2457,26 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
|
||||
for (j = k = 0; j < USBVISION_URB_FRAMES; j++,
|
||||
k += usbvision->isocPacketSize) {
|
||||
urb->iso_frame_desc[j].offset = k;
|
||||
urb->iso_frame_desc[j].length = usbvision->isocPacketSize;
|
||||
urb->iso_frame_desc[j].length =
|
||||
usbvision->isocPacketSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Submit all URBs */
|
||||
for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) {
|
||||
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, GFP_KERNEL);
|
||||
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
|
||||
GFP_KERNEL);
|
||||
if (errCode) {
|
||||
err("%s: usb_submit_urb(%d) failed: error %d", __FUNCTION__, bufIdx, errCode);
|
||||
err("%s: usb_submit_urb(%d) failed: error %d",
|
||||
__FUNCTION__, bufIdx, errCode);
|
||||
}
|
||||
}
|
||||
|
||||
usbvision->streaming = Stream_Idle;
|
||||
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x", __FUNCTION__, usbvision->video_endp);
|
||||
PDEBUG(DBG_ISOC, "%s: streaming=1 usbvision->video_endp=$%02x",
|
||||
__FUNCTION__,
|
||||
usbvision->video_endp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2470,7 +2490,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
|
||||
void usbvision_stop_isoc(struct usb_usbvision *usbvision)
|
||||
{
|
||||
int bufIdx, errCode, regValue;
|
||||
const int sb_size = USBVISION_URB_FRAMES * USBVISION_MAX_ISOC_PACKET_SIZE;
|
||||
int sb_size = USBVISION_URB_FRAMES * usbvision->isocPacketSize;
|
||||
|
||||
if ((usbvision->streaming == Stream_Off) || (usbvision->dev == NULL))
|
||||
return;
|
||||
@ -2499,15 +2519,19 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
|
||||
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
|
||||
usbvision->ifaceAlt);
|
||||
if (errCode < 0) {
|
||||
err("%s: usb_set_interface() failed: error %d", __FUNCTION__, errCode);
|
||||
err("%s: usb_set_interface() failed: error %d",
|
||||
__FUNCTION__, errCode);
|
||||
usbvision->last_error = errCode;
|
||||
}
|
||||
regValue = (16 - usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
|
||||
usbvision->isocPacketSize = (regValue == 0) ? 0 : (regValue * 64) - 1;
|
||||
PDEBUG(DBG_ISOC, "ISO Packet Length:%d", usbvision->isocPacketSize);
|
||||
regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
|
||||
usbvision->isocPacketSize =
|
||||
(regValue == 0) ? 0 : (regValue * 64) - 1;
|
||||
PDEBUG(DBG_ISOC, "ISO Packet Length:%d",
|
||||
usbvision->isocPacketSize);
|
||||
|
||||
usbvision->usb_bandwidth = regValue >> 1;
|
||||
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec", usbvision->usb_bandwidth);
|
||||
PDEBUG(DBG_ISOC, "USB Bandwidth Usage: %dMbit/Sec",
|
||||
usbvision->usb_bandwidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,6 @@
|
||||
#define USBVISION_CLIPMASK_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT / 8) //bytesize of clipmask
|
||||
|
||||
#define USBVISION_URB_FRAMES 32
|
||||
#define USBVISION_MAX_ISOC_PACKET_SIZE 959 // NT1003 Specs Document says 1023
|
||||
|
||||
#define USBVISION_NUM_HEADERMARKER 20
|
||||
#define USBVISION_NUMFRAMES 3 /* Maximum number of frames an application can get */
|
||||
|
@ -243,8 +243,7 @@ struct v4l2_capability
|
||||
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
|
||||
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
|
||||
#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
|
||||
#define V4L2_CAP_VIDEO_OUTPUT_POS 0x00000200 /* Video output can have x,y coords */
|
||||
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000400 /* Can do video output overlay */
|
||||
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
|
||||
|
||||
#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
|
||||
#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
|
||||
@ -616,12 +615,16 @@ struct v4l2_framebuffer
|
||||
#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
|
||||
#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
|
||||
#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
|
||||
#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
|
||||
#define V4L2_FBUF_CAP_GLOBAL_INV_ALPHA 0x0080
|
||||
/* Flags for the 'flags' field. */
|
||||
#define V4L2_FBUF_FLAG_PRIMARY 0x0001
|
||||
#define V4L2_FBUF_FLAG_OVERLAY 0x0002
|
||||
#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
|
||||
#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
|
||||
#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
|
||||
#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
|
||||
#define V4L2_FBUF_FLAG_GLOBAL_INV_ALPHA 0x0040
|
||||
|
||||
struct v4l2_clip
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user