Re: [PATCH] saa7134: automatic norm detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Hans,

Thank you for comments, I will rework the patch and document the new
event type.

Let me explain why I created a new thread.
My company is engaged in the monitoring of TV air. All TV channels are
recorded 24/7 for further analysis. But some local TV channels change
the standard over time (SECAM->PAL, PAL->SECAM). So the recording
software must be notified about these changes to set a new standard and
record the picture but not the noise.

Regards,
Mikhail

On Fri, 2014-03-28 at 09:37 +0100, Hans Verkuil wrote:
> Hi Mikhail,
> 
> Thank you for the patch. However, it does need some work before I can accept it.
> 
> First of all, run your patch through scripts/checkpatch.pl to ensure it complies
> to the kernel coding style.
> 
> Secondly, split up this single patch in smaller ones: in particular the addition
> of the new event type needs to be in a patch of its own.
> 
> Thirdly, you need to document the new event type in the DocBook documentation as
> well. API additions are only accepted if the documentation is updated at the same
> time.
> 
> I also wonder why you need a thread to watch for signal changes. It's not wrong,
> but in practice a TV input signal rarely if ever changes format. It can be different
> between different countries or when testing with a signal generator, but the normal
> case is that you are just interested in the current standard, and not how it might
> change over time. That would simplify the code a lot. This is what other drivers
> that implement querystd do.
> 
> Regards,
> 
> 	Hans
> 
> On 03/24/2014 12:42 PM, Mikhail Domrachev wrote:
> > saa7134: automatic norm detection switched on
> > saa7134: vidioc_querystd added
> > saa7134: notification about TV norm changes via V4L2 event interface added
> > videodev2: new event type added
> > 
> > Signed-off-by: Mikhail Domrachev <mihail.domrychev@xxxxxxxxx>
> > 
> > ---
> >  drivers/media/pci/saa7134/saa7134-empress.c |   1 +
> >  drivers/media/pci/saa7134/saa7134-reg.h     |   7 +
> >  drivers/media/pci/saa7134/saa7134-tvaudio.c |  56 +++---
> >  drivers/media/pci/saa7134/saa7134-video.c   | 274 ++++++++++++++++++++++++++--
> >  drivers/media/pci/saa7134/saa7134.h         |  14 +-
> >  include/uapi/linux/videodev2.h              |   2 +
> >  6 files changed, 311 insertions(+), 43 deletions(-)
> > 
> > diff --git a/drivers/media/pci/saa7134/saa7134-empress.c b/drivers/media/pci/saa7134/saa7134-empress.c
> > index 0a9047e..a150deb 100644
> > --- a/drivers/media/pci/saa7134/saa7134-empress.c
> > +++ b/drivers/media/pci/saa7134/saa7134-empress.c
> > @@ -262,6 +262,7 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = {
> >  	.vidioc_s_input			= saa7134_s_input,
> >  	.vidioc_s_std			= saa7134_s_std,
> >  	.vidioc_g_std			= saa7134_g_std,
> > +	.vidioc_querystd		= saa7134_querystd,
> >  	.vidioc_log_status		= v4l2_ctrl_log_status,
> >  	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
> >  	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
> > diff --git a/drivers/media/pci/saa7134/saa7134-reg.h b/drivers/media/pci/saa7134/saa7134-reg.h
> > index e7e0af1..d3be05c 100644
> > --- a/drivers/media/pci/saa7134/saa7134-reg.h
> > +++ b/drivers/media/pci/saa7134/saa7134-reg.h
> > @@ -369,6 +369,13 @@
> >  #define SAA7135_DSP_RWCLEAR_RERR		    1
> >  
> >  #define SAA7133_I2S_AUDIO_CONTROL               0x591
> > +
> > +#define SAA7134_STDDETECT_AUFD                  (1 << 7)
> > +#define SAA7134_STDDETECT_FCTC                  (1 << 2)
> > +#define SAA7134_STDDETECT_LDEL                  (1 << 5)
> > +#define SAA7134_STDDETECT_AUTO0                 (1 << 1)
> > +#define SAA7134_STDDETECT_AUTO1                 (1 << 2)
> > +
> >  /* ------------------------------------------------------------------ */
> >  /*
> >   * Local variables:
> > diff --git a/drivers/media/pci/saa7134/saa7134-tvaudio.c b/drivers/media/pci/saa7134/saa7134-tvaudio.c
> > index 0f34e09..6380e49 100644
> > --- a/drivers/media/pci/saa7134/saa7134-tvaudio.c
> > +++ b/drivers/media/pci/saa7134/saa7134-tvaudio.c
> > @@ -315,7 +315,7 @@ static void tvaudio_setmode(struct saa7134_dev *dev,
> >  
> >  static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
> >  {
> > -	if (dev->thread.scan1 == dev->thread.scan2 &&
> > +	if (dev->audio_thread.scan1 == dev->audio_thread.scan2 &&
> >  	    !kthread_should_stop()) {
> >  		if (timeout < 0) {
> >  			set_current_state(TASK_INTERRUPTIBLE);
> > @@ -325,7 +325,7 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
> >  						(msecs_to_jiffies(timeout));
> >  		}
> >  	}
> > -	return dev->thread.scan1 != dev->thread.scan2;
> > +	return dev->audio_thread.scan1 != dev->audio_thread.scan2;
> >  }
> >  
> >  static int tvaudio_checkcarrier(struct saa7134_dev *dev, struct mainscan *scan)
> > @@ -488,8 +488,8 @@ static int tvaudio_thread(void *data)
> >  	restart:
> >  		try_to_freeze();
> >  
> > -		dev->thread.scan1 = dev->thread.scan2;
> > -		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
> > +		dev->audio_thread.scan1 = dev->audio_thread.scan2;
> > +		dprintk("tvaudio thread scan start [%d]\n",dev->audio_thread.scan1);
> >  		dev->tvaudio  = NULL;
> >  
> >  		saa_writeb(SAA7134_MONITOR_SELECT,   0xa0);
> > @@ -528,7 +528,7 @@ static int tvaudio_thread(void *data)
> >  			tvaudio_setmode(dev,&tvaudio[0],NULL);
> >  			for (i = 0; i < ARRAY_SIZE(mainscan); i++) {
> >  				carr_vals[i] = tvaudio_checkcarrier(dev, mainscan+i);
> > -				if (dev->thread.scan1 != dev->thread.scan2)
> > +				if (dev->audio_thread.scan1 != dev->audio_thread.scan2)
> >  					goto restart;
> >  			}
> >  			for (max1 = 0, max2 = 0, i = 0; i < ARRAY_SIZE(mainscan); i++) {
> > @@ -604,11 +604,11 @@ static int tvaudio_thread(void *data)
> >  				goto restart;
> >  			if (kthread_should_stop())
> >  				break;
> > -			if (UNSET == dev->thread.mode) {
> > +			if (UNSET == dev->audio_thread.mode) {
> >  				rx = tvaudio_getstereo(dev, &tvaudio[audio]);
> >  				mode = saa7134_tvaudio_rx2mode(rx);
> >  			} else {
> > -				mode = dev->thread.mode;
> > +				mode = dev->audio_thread.mode;
> >  			}
> >  			if (lastmode != mode) {
> >  				tvaudio_setstereo(dev,&tvaudio[audio],mode);
> > @@ -618,7 +618,7 @@ static int tvaudio_thread(void *data)
> >  	}
> >  
> >   done:
> > -	dev->thread.stopped = 1;
> > +	dev->audio_thread.stopped = 1;
> >  	return 0;
> >  }
> >  
> > @@ -785,8 +785,8 @@ static int tvaudio_thread_ddep(void *data)
> >  	restart:
> >  		try_to_freeze();
> >  
> > -		dev->thread.scan1 = dev->thread.scan2;
> > -		dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
> > +		dev->audio_thread.scan1 = dev->audio_thread.scan2;
> > +		dprintk("tvaudio thread scan start [%d]\n",dev->audio_thread.scan1);
> >  
> >  		if (audio_ddep >= 0x04 && audio_ddep <= 0x0e) {
> >  			/* insmod option override */
> > @@ -803,16 +803,18 @@ static int tvaudio_thread_ddep(void *data)
> >  			}
> >  		} else {
> >  			/* (let chip) scan for sound carrier */
> > +			v4l2_std_id id = dev->tvnorm->id;
> >  			norms = 0;
> > -			if (dev->tvnorm->id & (V4L2_STD_B | V4L2_STD_GH))
> > +
> > +			if (id & (V4L2_STD_B | V4L2_STD_GH))
> >  				norms |= 0x04;
> > -			if (dev->tvnorm->id & V4L2_STD_PAL_I)
> > +			if (id & V4L2_STD_PAL_I)
> >  				norms |= 0x20;
> > -			if (dev->tvnorm->id & V4L2_STD_DK)
> > +			if (id & V4L2_STD_DK)
> >  				norms |= 0x08;
> > -			if (dev->tvnorm->id & V4L2_STD_MN)
> > +			if (id & V4L2_STD_MN)
> >  				norms |= 0x40;
> > -			if (dev->tvnorm->id & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))
> > +			if (id & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))
> >  				norms |= 0x10;
> >  			if (0 == norms)
> >  				norms = 0x7c; /* all */
> > @@ -862,7 +864,7 @@ static int tvaudio_thread_ddep(void *data)
> >  	}
> >  
> >   done:
> > -	dev->thread.stopped = 1;
> > +	dev->audio_thread.stopped = 1;
> >  	return 0;
> >  }
> >  
> > @@ -1024,13 +1026,13 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
> >  		break;
> >  	}
> >  
> > -	dev->thread.thread = NULL;
> > -	dev->thread.scan1 = dev->thread.scan2 = 0;
> > +	dev->audio_thread.thread = NULL;
> > +	dev->audio_thread.scan1 = dev->audio_thread.scan2 = 0;
> >  	if (my_thread) {
> >  		saa7134_tvaudio_init(dev);
> >  		/* start tvaudio thread */
> > -		dev->thread.thread = kthread_run(my_thread, dev, "%s", dev->name);
> > -		if (IS_ERR(dev->thread.thread)) {
> > +		dev->audio_thread.thread = kthread_run(my_thread, dev, "%s", dev->name);
> > +		if (IS_ERR(dev->audio_thread.thread)) {
> >  			printk(KERN_WARNING "%s: kernel_thread() failed\n",
> >  			       dev->name);
> >  			/* XXX: missing error handling here */
> > @@ -1051,8 +1053,8 @@ int saa7134_tvaudio_close(struct saa7134_dev *dev)
> >  int saa7134_tvaudio_fini(struct saa7134_dev *dev)
> >  {
> >  	/* shutdown tvaudio thread */
> > -	if (dev->thread.thread && !dev->thread.stopped)
> > -		kthread_stop(dev->thread.thread);
> > +	if (dev->audio_thread.thread && !dev->audio_thread.stopped)
> > +		kthread_stop(dev->audio_thread.thread);
> >  
> >  	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
> >  	return 0;
> > @@ -1064,12 +1066,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
> >  		dprintk("sound IF not in use, skipping scan\n");
> >  		dev->automute = 0;
> >  		saa7134_tvaudio_setmute(dev);
> > -	} else if (dev->thread.thread) {
> > -		dev->thread.mode = UNSET;
> > -		dev->thread.scan2++;
> > +	} else if (dev->audio_thread.thread) {
> > +		dev->audio_thread.mode = UNSET;
> > +		dev->audio_thread.scan2++;
> >  
> > -		if (!dev->insuspend && !dev->thread.stopped)
> > -			wake_up_process(dev->thread.thread);
> > +		if (!dev->insuspend && !dev->audio_thread.stopped)
> > +			wake_up_process(dev->audio_thread.thread);
> >  	} else {
> >  		dev->automute = 0;
> >  		saa7134_tvaudio_setmute(dev);
> > diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
> > index eb472b5..2528b6d 100644
> > --- a/drivers/media/pci/saa7134/saa7134-video.c
> > +++ b/drivers/media/pci/saa7134/saa7134-video.c
> > @@ -24,6 +24,9 @@
> >  #include <linux/list.h>
> >  #include <linux/module.h>
> >  #include <linux/kernel.h>
> > +#include <linux/kthread.h>
> > +#include <linux/delay.h>
> > +#include <linux/freezer.h>
> >  #include <linux/slab.h>
> >  #include <linux/sort.h>
> >  
> > @@ -452,19 +455,28 @@ static void video_mux(struct saa7134_dev *dev, int input)
> >  
> >  static void saa7134_set_decoder(struct saa7134_dev *dev)
> >  {
> > -	int luma_control, sync_control, mux;
> > +	int luma_control, sync_control, chroma_ctrl1, analog_adc, vgate_misc, mux;
> >  
> >  	struct saa7134_tvnorm *norm = dev->tvnorm;
> >  	mux = card_in(dev, dev->ctl_input).vmux;
> >  
> >  	luma_control = norm->luma_control;
> >  	sync_control = norm->sync_control;
> > +	chroma_ctrl1 = norm->chroma_ctrl1;
> > +	analog_adc = 0x01;
> > +	vgate_misc = norm->vgate_misc;
> >  
> >  	if (mux > 5)
> >  		luma_control |= 0x80; /* svideo */
> >  	if (noninterlaced || dev->nosignal)
> >  		sync_control |= 0x20;
> >  
> > +	/* switch on auto standard detection */
> > +	sync_control |= SAA7134_STDDETECT_AUFD;
> > +	chroma_ctrl1 |= SAA7134_STDDETECT_AUTO0;
> > +	chroma_ctrl1 &= ~SAA7134_STDDETECT_FCTC;
> > +	luma_control &= ~SAA7134_STDDETECT_LDEL;
> > +
> >  	/* setup video decoder */
> >  	saa_writeb(SAA7134_INCR_DELAY,            0x08);
> >  	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
> > @@ -487,16 +499,16 @@ static void saa7134_set_decoder(struct saa7134_dev *dev)
> >  		dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
> >  
> >  	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
> > -	saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
> > +	saa_writeb(SAA7134_CHROMA_CTRL1,          chroma_ctrl1);
> >  	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
> >  
> >  	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2);
> >  	saa_writeb(SAA7134_MODE_DELAY_CTRL,       0x00);
> >  
> > -	saa_writeb(SAA7134_ANALOG_ADC,            0x01);
> > +	saa_writeb(SAA7134_ANALOG_ADC,            analog_adc);
> >  	saa_writeb(SAA7134_VGATE_START,           0x11);
> >  	saa_writeb(SAA7134_VGATE_STOP,            0xfe);
> > -	saa_writeb(SAA7134_MISC_VGATE_MSB,        norm->vgate_misc);
> > +	saa_writeb(SAA7134_MISC_VGATE_MSB,        vgate_misc);
> >  	saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
> >  	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
> >  }
> > @@ -1686,6 +1698,98 @@ int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id)
> >  }
> >  EXPORT_SYMBOL_GPL(saa7134_g_std);
> >  
> > +static v4l2_std_id saa7134_read_std(struct saa7134_dev* dev)
> > +{
> > +    static v4l2_std_id stds[] = { V4L2_STD_ALL, V4L2_STD_NTSC, V4L2_STD_PAL, V4L2_STD_SECAM };
> > +    v4l2_std_id result = 0;
> > +
> > +    u8 st1 = saa_readb(SAA7134_STATUS_VIDEO1);
> > +    u8 st2 = saa_readb(SAA7134_STATUS_VIDEO2);
> > +
> > +    if (!(st2 & 0x1)) //RDCAP == 0
> > +        result = V4L2_STD_ALL;
> > +    else
> > +        result = stds[st1 & 0x03];
> > +
> > +    return result;
> > +}
> > +
> > +static const char* saa7134_std_to_str(v4l2_std_id std)
> > +{
> > +    switch (std) {
> > +    case V4L2_STD_NTSC:
> > +        return "NTSC";
> > +    case V4L2_STD_PAL:
> > +        return "PAL";
> > +    case V4L2_STD_SECAM:
> > +        return "SECAM";
> > +    default:
> > +        return "(no signal)";
> > +    }
> > +}
> > +
> > +int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std)
> > +{
> > +	struct saa7134_dev *dev = video_drvdata(file);
> > +
> > +	v4l2_std_id dcstd = saa7134_read_std(dev);
> > +	if (dcstd != V4L2_STD_ALL)
> > +	    *std &= dcstd;
> > +	else
> > +	    *std = dcstd;
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(saa7134_querystd);
> > +
> > +static int saa7134_std_sleep(struct saa7134_dev *dev, int timeout)
> > +{
> > +    int cmp = (atomic_read(&dev->std_thread.scan1) == atomic_read(&dev->std_thread.scan2));
> > +
> > +    if (cmp && !kthread_should_stop()) {
> > +        if (timeout < 0) {
> > +            set_current_state(TASK_INTERRUPTIBLE);
> > +            schedule();
> > +        } else {
> > +            schedule_timeout_interruptible(msecs_to_jiffies(timeout));
> > +        }
> > +    }
> > +    cmp = (atomic_read(&dev->std_thread.scan1) != atomic_read(&dev->std_thread.scan2));
> > +    return cmp;
> > +}
> > +
> > +static int saa7134_standard_detector_thread(void* arg)
> > +{
> > +    struct saa7134_dev *dev = arg;
> > +    v4l2_std_id dcstd = 0;
> > +    struct v4l2_event event;
> > +
> > +    set_freezable();
> > +    for (;;) {
> > +        saa7134_std_sleep(dev,-1);
> > +        if (kthread_should_stop())
> > +            goto done;
> > +restart:
> > +        try_to_freeze();
> > +
> > +        atomic_set(&dev->std_thread.scan1, atomic_read(&dev->std_thread.scan2));
> > +
> > +        if (saa7134_std_sleep(dev,3000))
> > +            goto restart;
> > +        dcstd = saa7134_read_std(dev);
> > +
> > +        dprintk("Standard detected: %s", saa7134_std_to_str(dcstd));
> > +        memset(&event, 0, sizeof(event));
> > +        event.type = V4L2_EVENT_SIGNALCHANGED;
> > +        memcpy(event.u.data, &dcstd, sizeof(dcstd));
> > +        v4l2_event_queue(dev->video_dev, &event);
> > +    }
> > +
> > +done:
> > +    dev->std_thread.stopped = 1;
> > +    return 0;
> > +}
> > +
> >  static int saa7134_cropcap(struct file *file, void *priv,
> >  					struct v4l2_cropcap *cap)
> >  {
> > @@ -1793,13 +1897,13 @@ int saa7134_s_tuner(struct file *file, void *priv,
> >  	if (0 != t->index)
> >  		return -EINVAL;
> >  
> > -	mode = dev->thread.mode;
> > +	mode = dev->audio_thread.mode;
> >  	if (UNSET == mode) {
> >  		rx   = saa7134_tvaudio_getstereo(dev);
> >  		mode = saa7134_tvaudio_rx2mode(rx);
> >  	}
> >  	if (mode != t->audmode)
> > -		dev->thread.mode = t->audmode;
> > +		dev->audio_thread.mode = t->audmode;
> >  
> >  	return 0;
> >  }
> > @@ -2053,6 +2157,18 @@ static int radio_s_tuner(struct file *file, void *priv,
> >  	return 0;
> >  }
> >  
> > +static int saa7134_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
> > +{
> > +	if (sub->type == V4L2_EVENT_SIGNALCHANGED)
> > +	{
> > +		return v4l2_event_subscribe(fh, sub, SAA7134_EVENTS_QUEUE_SIZE, NULL);
> > +	}
> > +	else
> > +	{
> > +		return v4l2_ctrl_subscribe_event(fh, sub);
> > +	}
> > +}
> > +
> >  static const struct v4l2_file_operations video_fops =
> >  {
> >  	.owner	  = THIS_MODULE,
> > @@ -2084,6 +2200,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
> >  	.vidioc_dqbuf			= saa7134_dqbuf,
> >  	.vidioc_s_std			= saa7134_s_std,
> >  	.vidioc_g_std			= saa7134_g_std,
> > +	.vidioc_querystd		= saa7134_querystd,
> >  	.vidioc_enum_input		= saa7134_enum_input,
> >  	.vidioc_g_input			= saa7134_g_input,
> >  	.vidioc_s_input			= saa7134_s_input,
> > @@ -2103,7 +2220,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
> >  	.vidioc_s_register              = vidioc_s_register,
> >  #endif
> >  	.vidioc_log_status		= v4l2_ctrl_log_status,
> > -	.vidioc_subscribe_event		= v4l2_ctrl_subscribe_event,
> > +	.vidioc_subscribe_event		= saa7134_subscribe_event,
> >  	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
> >  };
> >  
> > @@ -2272,6 +2389,9 @@ int saa7134_video_init1(struct saa7134_dev *dev)
> >  
> >  void saa7134_video_fini(struct saa7134_dev *dev)
> >  {
> > +    if (dev->std_thread.thread && !dev->std_thread.stopped)
> > +        kthread_stop(dev->std_thread.thread);
> > +
> >  	/* free stuff */
> >  	saa7134_pgtable_free(dev->pci, &dev->pt_cap);
> >  	saa7134_pgtable_free(dev->pci, &dev->pt_vbi);
> > @@ -2324,23 +2444,144 @@ int saa7134_video_init2(struct saa7134_dev *dev)
> >  	v4l2_ctrl_handler_setup(&dev->ctrl_handler);
> >  	saa7134_tvaudio_setmute(dev);
> >  	saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
> > +
> > +
> > +    dev->std_thread.thread = NULL;
> > +    dev->std_thread.stopped = 0;
> > +    atomic_set(&dev->std_thread.scan1, 0);
> > +    atomic_set(&dev->std_thread.scan2, 0);
> > +
> > +    dev->std_thread.thread = kthread_run(saa7134_standard_detector_thread, dev, "%s", dev->name);
> > +    if (IS_ERR(dev->std_thread.thread)) {
> > +        printk(KERN_ALERT "%s: kthread_run(saa7134_standard_detector_thread) failed\n", dev->name);
> > +        dev->std_thread.thread = NULL;
> > +        dev->std_thread.stopped = 1;
> > +    }
> > +    return 0;
> > +}
> > +
> > +static int saa7134_std_do_scan(struct saa7134_dev *dev)
> > +{
> > +    if (dev->std_thread.thread) {
> > +        atomic_inc(&dev->std_thread.scan2);
> > +        if (!dev->insuspend && !dev->std_thread.stopped)
> > +            wake_up_process(dev->std_thread.thread);
> > +    }
> >  	return 0;
> >  }
> >  
> >  void saa7134_irq_video_signalchange(struct saa7134_dev *dev)
> >  {
> > -	static const char *st[] = {
> > -		"(no signal)", "NTSC", "PAL", "SECAM" };
> > -	u32 st1,st2;
> > +	static const char* st1_6_hlck[] =
> > +	{
> > +	[0] = "HPLL is locked; clock LLC is locked to line frequency",
> > +	[1] = "HPLL is not locked"
> > +	};
> > +	static const char* st1_5_sltca[] =
> > +	{
> > +	[0] = "Video AGC is in normal operation mode",
> > +	[1] = "Video AGC is in gain recover mode (increase) after peak attack"
> > +	};
> > +	static const char* st1_4_glimt[] =
> > +	{
> > +	[0] = "Video AGC is in normal operation mode",
> > +	[1] = "Video AGC is on its top limit, i.e. input signal is too large, out of AGC range"
> > +	};
> > +	static const char* st1_3_glimb[] =
> > +	{
> > +	[0] = "video AGC is in normal operation mode",
> > +	[1] = "video AGC is on its bottom limit. Input signal is too small, out of AGC range"
> > +	};
> > +	static const char* st1_2_wipa[] =
> > +	{
> > +	[0] = "White or Color Peak Control loop is not activated",
> > +	[1] = "White or Color Peak Control was triggered in previous line"
> > +	};
> > +	struct st1_1_0_dcstd_descr
> > +	{
> > +		const char* name;
> > +		v4l2_std_id stdid;
> > +	};
> > +	static struct st1_1_0_dcstd_descr st1_1_0_dcstd[] =
> > +	{
> > +	[0] = { "No color signal could be detected. The video is assumed being B/W", V4L2_STD_UNKNOWN},
> > +	[1] = { "NTSC signal detected", V4L2_STD_NTSC},
> > +	[2] = { "PAL signal detected", V4L2_STD_PAL},
> > +	[3] = { "SECAM signal detected", V4L2_STD_SECAM}
> > +	};
> > +	static const char* st2_7_intl[] =
> > +	{
> > +	[0] = "Video input is detected as non-interlaced",
> > +	[1] = "Video input is detected as interlaced"
> > +	};
> > +	static const char* st2_6_hlvln[] =
> > +	{
> > +	[0] = "Horizontal and vertical synchronization is achieved",
> > +	[1] = "Either horizontal or vertical synchronization is lost"
> > +	};
> > +	static const char* st2_5_fidt[] =
> > +	{
> > +	[0] = "Video input is detected with 50 Hz field rate",
> > +	[1] = "Video input is detected with 60 Hz field rate"
> > +	};
> > +	static const char* st2_3_type3[] =
> > +	{
> > +	[0] = "normal video signal",
> > +	[1] = "Macrovision copy protection type 3 detected"
> > +	};
> > +	static const char* st2_2_colstr[] =
> > +	{
> > +	[0] = "normal video signal",
> > +	[1] = "Macrovision Color Stripe scheme detected"
> > +	};
> > +	static const char* st2_1_copro[] =
> > +	{
> > +	[0] = "normal video signal, No Macrovision copy protection scheme detected",
> > +	[1] = "Copy protection detected according Macrovision (including 7.01)"
> > +	};
> > +	static const char* st2_0_rdcap[] =
> > +	{
> > +	[0] = "One or more of the decoder control loops are not locked",
> > +	[1] = "Ready for capture. All control loops are locked: Horizontal, Vertical, color subcarrier, chroma gain control"
> > +	};
> > +
> > +	u8 st1,st2;
> >  
> >  	st1 = saa_readb(SAA7134_STATUS_VIDEO1);
> >  	st2 = saa_readb(SAA7134_STATUS_VIDEO2);
> > -	dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
> > -		(st1 & 0x40) ? "not locked" : "locked",
> > -		(st2 & 0x40) ? "no"         : "yes",
> > -		st[st1 & 0x03]);
> > -	dev->nosignal = (st1 & 0x40) || (st2 & 0x40)  || !(st2 & 0x1);
> >  
> > +	dprintk("saa7134: DEBUG. Status byte 1:\n"
> > +			"HLCK  = %s\n"
> > +			"SLTCA = %s\n"
> > +			"GLIMT = %s\n"
> > +			"GLIMB = %s\n"
> > +			"WIPA  = %s\n"
> > +			"DCSTD = %s\n",
> > +			st1_6_hlck[((st1 & (1 << 6)) ? 1 : 0)],
> > +			st1_5_sltca[((st1 & (1 << 5)) ? 1 : 0)],
> > +			st1_4_glimt[((st1 & (1 << 4)) ? 1 : 0)],
> > +			st1_3_glimb[((st1 & (1 << 3)) ? 1 : 0)],
> > +			st1_2_wipa[((st1 & (1 << 2)) ? 1 : 0)],
> > +			st1_1_0_dcstd[st1 & 0x03].name
> > +			);
> > +	dprintk("saa7134: DEBUG. Status byte 2:\n"
> > +			"INTL  = %s\n"
> > +			"HLVLN = %s\n"
> > +			"FIDT = %s\n"
> > +			"TYPE3 = %s\n"
> > +			"COLSTR  = %s\n"
> > +			"COPRO = %s\n"
> > +			"RDCAP = %s\n",
> > +			st2_7_intl[((st2 & (1 << 7)) ? 1 : 0)],
> > +			st2_6_hlvln[((st2 & (1 << 6)) ? 1 : 0)],
> > +			st2_5_fidt[((st2 & (1 << 5)) ? 1 : 0)],
> > +			st2_3_type3[((st2 & (1 << 3)) ? 1 : 0)],
> > +			st2_2_colstr[((st2 & (1 << 2)) ? 1 : 0)],
> > +			st2_1_copro[((st2 & (1 << 1)) ? 1 : 0)],
> > +			st2_0_rdcap[((st2 & (1 << 0)) ? 1 : 0)]
> > +			);
> > +
> > +	dev->nosignal = (st1 & 0x40) || (st2 & 0x40)  || !(st2 & 0x1);
> >  	if (dev->nosignal) {
> >  		/* no video signal -> mute audio */
> >  		if (dev->ctl_automute)
> > @@ -2358,6 +2599,8 @@ void saa7134_irq_video_signalchange(struct saa7134_dev *dev)
> >  
> >  	if (dev->mops && dev->mops->signal_change)
> >  		dev->mops->signal_change(dev);
> > +
> > +	saa7134_std_do_scan(dev);
> >  }
> >  
> > 
> > @@ -2393,6 +2636,7 @@ void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
> >  	spin_unlock(&dev->slock);
> >  }
> >  
> > +
> >  /* ----------------------------------------------------------- */
> >  /*
> >   * Local variables:
> > diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
> > index 2474e84..0e5bd3d 100644
> > --- a/drivers/media/pci/saa7134/saa7134.h
> > +++ b/drivers/media/pci/saa7134/saa7134.h
> > @@ -342,6 +342,8 @@ struct saa7134_card_ir {
> >  #define SAA7134_MAXBOARDS 32
> >  #define SAA7134_INPUT_MAX 8
> >  
> > +#define SAA7134_EVENTS_QUEUE_SIZE 10
> > +
> >  /* ----------------------------------------------------------- */
> >  /* Since we support 2 remote types, lets tell them apart       */
> >  
> > @@ -450,6 +452,14 @@ struct saa7134_thread {
> >  	unsigned int		   stopped;
> >  };
> >  
> > +/* tv standard thread status */
> > +struct saa7134_thread_std {
> > +    struct task_struct             *thread;
> > +    atomic_t                       scan1;
> > +    atomic_t                       scan2;
> > +    unsigned int                   stopped;
> > +};
> > +
> >  /* buffer for one video/vbi/ts frame */
> >  struct saa7134_buf {
> >  	/* common v4l buffer stuff -- must be first */
> > @@ -623,7 +633,8 @@ struct saa7134_dev {
> >  
> >  	/* other global state info */
> >  	unsigned int               automute;
> > -	struct saa7134_thread      thread;
> > +	struct saa7134_thread      audio_thread;
> > +	struct saa7134_thread_std  std_thread;
> >  	struct saa7134_input       *input;
> >  	struct saa7134_input       *hw_input;
> >  	unsigned int               hw_mute;
> > @@ -779,6 +790,7 @@ extern struct video_device saa7134_radio_template;
> >  
> >  int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id);
> >  int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id);
> > +int saa7134_querystd(struct file *file, void *priv, v4l2_std_id *std);
> >  int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i);
> >  int saa7134_g_input(struct file *file, void *priv, unsigned int *i);
> >  int saa7134_s_input(struct file *file, void *priv, unsigned int i);
> > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> > index e35ad6c..806057b 100644
> > --- a/include/uapi/linux/videodev2.h
> > +++ b/include/uapi/linux/videodev2.h
> > @@ -1765,8 +1765,10 @@ struct v4l2_streamparm {
> >  #define V4L2_EVENT_EOS				2
> >  #define V4L2_EVENT_CTRL				3
> >  #define V4L2_EVENT_FRAME_SYNC			4
> > +#define V4L2_EVENT_SIGNALCHANGED                5
> >  #define V4L2_EVENT_PRIVATE_START		0x08000000
> >  
> > +
> >  /* Payload for V4L2_EVENT_VSYNC */
> >  struct v4l2_event_vsync {
> >  	/* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */
> > 


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux