Re: [RFC/PATCH 03/19] cx18: Use the control framework.

2010-12-12 Thread Hans Verkuil
On Sunday, December 12, 2010 19:46:33 Andy Walls wrote:
> Hi Hans,
> 
> It looks like it should.  I'm looking at things on my phone  while out and 
> about - not the best environment for code review.
> 
> You just need to ensure default vol is >= 0 and <= 65535 which may not be the 
> case if reg 8d4 has a value near 0. 
> 
> Two other topics while I'm here:
> 
> 1. Why set the vol step to 655, when the volume will actaully step at 
> increments of 512?

The goal of the exercise is to convert to the control framework. I don't like to
mix changes like that with lots of other unrelated changes, so I kept this the
same as it was.

> 2. Why should failure to initialize a data structure for user controls mean 
> failure to init otherwise working hardware?  We never let user control init 
> cause subdev driver probe failure before, so why now?  I'd prefer a working 
> device without user controls in case of user control init failure.

Huh? If you fail to allocate the memory for such data structures then I'm
pretty sure you will encounter other problems as well. It's a highly unlikely
scenario anyway since if you have so little memory that you can't allocate these
data structures, then it is just about impossible that you could allocate the
memory for the video buffers.

Regards,

Hans

> 
> Regards,
> Andy
> 
> Hans Verkuil  wrote:
> 
> >On Sunday, December 12, 2010 19:09:36 Andy Walls wrote:
> >> Hans,
> >> 
> >> This has at least the same two problems the change for cx25840 had:
> >> 
> >> 1. Volume control init should use 65535 not 65335
> >> 
> >> 2. You cannot trust reg 0x8d4 to have a value in it for the default volume 
> >> that won't give an ERANGE error when you go to init the volume control.  
> >> Subdev probe will fail. See my previous cx25840 patches sent to the list, 
> >> awaiting action.
> >> 
> >> (The cx25840 code that trusts the volume register to be in range is 
> >> already in 2.6.36 and breaks IR and analog for CX23885/7/8 chips.)
> >> 
> >> I'll give this whole patch a harder look later this evening if I can.
> >> 
> >> Regards,
> >> Andy
> >> 
> >
> >Would the patch below fix these issues? It compiles, but I didn't test it.
> >
> >Regards,
> >
> > Hans
> >
> >diff --git a/drivers/media/video/cx18/cx18-av-core.c 
> >b/drivers/media/video/cx18/cx18-av-core.c
> >index e1f58f1..73b6f4d 100644
> >--- a/drivers/media/video/cx18/cx18-av-core.c
> >+++ b/drivers/media/video/cx18/cx18-av-core.c
> >@@ -248,8 +248,22 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
> > /*  CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
> > /*} */
> > cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
> >-default_volume = 228 - cx18_av_read(cx, 0x8d4);
> >-default_volume = ((default_volume / 2) + 23) << 9;
> >+default_volume = cx18_av_read(cx, 0x8d4);
> >+/*
> >+ * Enforce the legacy volume scale mapping limits to avoid -ERANGE
> >+ * errors when initializing the volume control
> >+ */
> >+if (default_volume > 228) {
> >+/* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
> >+default_volume = 228;
> >+cx18_av_write(cx, 0x8d4, 228);
> >+}
> >+else if (default_volume < 20) {
> >+/* Top out at + 8 dB, v4l2 vol range 0xfe00-0x */
> >+default_volume = 20;
> >+cx18_av_write(cx, 0x8d4, 20);
> >+}
> >+default_volume = (((228 - default_volume) >> 1) + 23) << 9;
> > state->volume->cur.val = state->volume->default_value = default_volume;
> > v4l2_ctrl_handler_setup(&state->hdl);
> > }
> >@@ -1359,7 +1373,7 @@ int cx18_av_probe(struct cx18 *cx)
> > 
> > state->volume = v4l2_ctrl_new_std(&state->hdl,
> > &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
> >-0, 65335, 65535 / 100, 0);
> >+0, 65535, 65535 / 100, 0);
> > v4l2_ctrl_new_std(&state->hdl,
> > &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
> > 0, 1, 1, 0);
> >
> 
> 

-- 
Hans Verkuil - video4linux developer - sponsored by Cisco
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] s5p-fimc: fix the value of YUV422 1plane formats

2010-12-12 Thread Hyunwoong Kim
Some color formats are mismatched in s5p-fimc driver.
CICICTRL[1:0], order422_out, should be set 2b'00 not 2b'11 to use 
V4L2_PIX_FMT_YUYV.
Because in V4L2 standard V4L2_PIX_FMT_YUYV means "start + 0: Y'00 Cb00 Y'01 
Cr00 Y'02 Cb01 Y'03 Cr01".
According to datasheet 2b'00 is right value for V4L2_PIX_FMT_YUYV.


  bit |MSBLSB

  00  |  Cr1Y3Cb1Y2Cr0Y1Cb0Y0

  01  |  Cb1Y3Cr1Y2Cb0Y1Cr0Y0

  10  |  Y3Cr1Y2Cb1Y1Cr0Y0Cb0

  11  |  Y3Cb1Y2Cr1Y1Cb0Y0Cr0


V4L2_PIX_FMT_YVYU, V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_VYUY are also mismatched 
with datasheet.
MSCTRL[17:16], order2p_in, is also mismatched in V4L2_PIX_FMT_UYVY, 
V4L2_PIX_FMT_YVYU.

Signed-off-by: Hyunwoong Kim 
Reviewed-by: Jonghun Han 
---

I wonder why fimc_fmt struct has fourcc and color together as member of 
structure.
It seems that the meaning of color is the same as fourcc's meaning.

 drivers/media/video/s5p-fimc/fimc-core.h |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/media/video/s5p-fimc/fimc-core.h 
b/drivers/media/video/s5p-fimc/fimc-core.h
index a707060..4efc1a1 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -96,15 +96,15 @@ enum fimc_color_fmt {
 #define fimc_fmt_is_rgb(x) ((x) & 0x10)
 
 /* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */
-#defineS5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY
-#defineS5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB
-#defineS5P_FIMC_OUT_YCRYCB S5P_CIOCTRL_ORDER422_CBYCRY
-#defineS5P_FIMC_OUT_YCBYCR S5P_CIOCTRL_ORDER422_YCBYCR
+#defineS5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_YCBYCR
+#defineS5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_CBYCRY
+#defineS5P_FIMC_OUT_YCRYCB S5P_CIOCTRL_ORDER422_YCRYCB
+#defineS5P_FIMC_OUT_YCBYCR S5P_CIOCTRL_ORDER422_CRYCBY
 
 /* Input Y/Cb/Cr components order for 1 plane YCbCr 4:2:2 color formats. */
 #defineS5P_FIMC_IN_CRYCBY  S5P_MSCTRL_ORDER422_CRYCBY
-#defineS5P_FIMC_IN_CBYCRY  S5P_MSCTRL_ORDER422_YCRYCB
-#defineS5P_FIMC_IN_YCRYCB  S5P_MSCTRL_ORDER422_CBYCRY
+#defineS5P_FIMC_IN_CBYCRY  S5P_MSCTRL_ORDER422_CBYCRY
+#defineS5P_FIMC_IN_YCRYCB  S5P_MSCTRL_ORDER422_YCRYCB
 #defineS5P_FIMC_IN_YCBYCR  S5P_MSCTRL_ORDER422_YCBYCR
 
 /* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
-- 
1.6.2.5

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


Re: [patch v2] [media] bttv: take correct lock in bttv_open()

2010-12-12 Thread Sergej Pupykin

On 12.12.2010 19:58, Dan Carpenter wrote:

We're trying to make sure that no one is writing to the btv->init struct
while we copy it over to the newly allocated "fh" struct.  The original
code doesn't make sense because "fh->cap.vb_lock" hasn't been
initialized and no one else can be writing to it anyway.

This patch also crashes the system. Unfortunately machine hangs, so I 
can not copy-paste trace. It was something about nosemaphore called from 
bttv_open. (something like previous reports)


I replace lock with btv->lock:

mutex_lock(&btv->lock);
*fh = btv->init;
mutex_unlock(&btv->lock);

Probably it is overkill and may be incorrect, but it starts working.

Also I found another issue: tvtime hangs on exit in D-state, so it looks 
like there is a problem near bttv_release function or something like this.

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


[GIT PATCHES FOR 2.6.38] gspca_sonixb: Various updates / fixes

2010-12-12 Thread Hans de Goede

Hi Mauro et al,

Some bugfixes and support for a new sensor in the sonixb driver.

The following changes since commit dedb94adebe0fbdd9cafdbb170337810d8638bc9:

  [media] timblogiw: Fix a merge conflict with v4l2_i2c_new_subdev_board 
changes (2010-12-11 09:07:52 -0200)

are available in the git repository at:
  git://linuxtv.org/hgoede/gspca.git gspca-for_v2.6.38

Hans de Goede (3):
  gspca_sonixb: Make sonixb handle 0c45:6007 instead of sn9c102
  gspca_sonixb: Rewrite start of frame detection
  gspca_sonixb: Add support for 0c45:602a

 drivers/media/video/gspca/sonixb.c |  232 +---
 drivers/media/video/sn9c102/sn9c102_devtable.h |4 +-
 2 files changed, 166 insertions(+), 70 deletions(-)

Thanks & Regards,

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


Re: [RFC/PATCH 03/19] cx18: Use the control framework.

2010-12-12 Thread Andy Walls
Hi Hans,

It looks like it should.  I'm looking at things on my phone  while out and 
about - not the best environment for code review.

You just need to ensure default vol is >= 0 and <= 65535 which may not be the 
case if reg 8d4 has a value near 0. 

Two other topics while I'm here:

1. Why set the vol step to 655, when the volume will actaully step at 
increments of 512?

2. Why should failure to initialize a data structure for user controls mean 
failure to init otherwise working hardware?  We never let user control init 
cause subdev driver probe failure before, so why now?  I'd prefer a working 
device without user controls in case of user control init failure.

Regards,
Andy

Hans Verkuil  wrote:

>On Sunday, December 12, 2010 19:09:36 Andy Walls wrote:
>> Hans,
>> 
>> This has at least the same two problems the change for cx25840 had:
>> 
>> 1. Volume control init should use 65535 not 65335
>> 
>> 2. You cannot trust reg 0x8d4 to have a value in it for the default volume 
>> that won't give an ERANGE error when you go to init the volume control.  
>> Subdev probe will fail. See my previous cx25840 patches sent to the list, 
>> awaiting action.
>> 
>> (The cx25840 code that trusts the volume register to be in range is already 
>> in 2.6.36 and breaks IR and analog for CX23885/7/8 chips.)
>> 
>> I'll give this whole patch a harder look later this evening if I can.
>> 
>> Regards,
>> Andy
>> 
>
>Would the patch below fix these issues? It compiles, but I didn't test it.
>
>Regards,
>
>   Hans
>
>diff --git a/drivers/media/video/cx18/cx18-av-core.c 
>b/drivers/media/video/cx18/cx18-av-core.c
>index e1f58f1..73b6f4d 100644
>--- a/drivers/media/video/cx18/cx18-av-core.c
>+++ b/drivers/media/video/cx18/cx18-av-core.c
>@@ -248,8 +248,22 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
> /*CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
> /*} */
>   cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
>-  default_volume = 228 - cx18_av_read(cx, 0x8d4);
>-  default_volume = ((default_volume / 2) + 23) << 9;
>+  default_volume = cx18_av_read(cx, 0x8d4);
>+  /*
>+   * Enforce the legacy volume scale mapping limits to avoid -ERANGE
>+   * errors when initializing the volume control
>+   */
>+  if (default_volume > 228) {
>+  /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
>+  default_volume = 228;
>+  cx18_av_write(cx, 0x8d4, 228);
>+  }
>+  else if (default_volume < 20) {
>+  /* Top out at + 8 dB, v4l2 vol range 0xfe00-0x */
>+  default_volume = 20;
>+  cx18_av_write(cx, 0x8d4, 20);
>+  }
>+  default_volume = (((228 - default_volume) >> 1) + 23) << 9;
>   state->volume->cur.val = state->volume->default_value = default_volume;
>   v4l2_ctrl_handler_setup(&state->hdl);
> }
>@@ -1359,7 +1373,7 @@ int cx18_av_probe(struct cx18 *cx)
> 
>   state->volume = v4l2_ctrl_new_std(&state->hdl,
>   &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
>-  0, 65335, 65535 / 100, 0);
>+  0, 65535, 65535 / 100, 0);
>   v4l2_ctrl_new_std(&state->hdl,
>   &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
>   0, 1, 1, 0);
>
>-- 
>Hans Verkuil - video4linux developer - sponsored by Cisco
>--
>To unsubscribe from this list: send the line "unsubscribe linux-media" in
>the body of a message to majord...@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
N�r��yb�X��ǧv�^�)޺{.n�+{���bj)w*jg����ݢj/���z�ޖ��2�ޙ&�)ߡ�a�����G���h��j:+v���w��٥

Re: [RFC/PATCH 03/19] cx18: Use the control framework.

2010-12-12 Thread Hans Verkuil
On Sunday, December 12, 2010 19:09:36 Andy Walls wrote:
> Hans,
> 
> This has at least the same two problems the change for cx25840 had:
> 
> 1. Volume control init should use 65535 not 65335
> 
> 2. You cannot trust reg 0x8d4 to have a value in it for the default volume 
> that won't give an ERANGE error when you go to init the volume control.  
> Subdev probe will fail. See my previous cx25840 patches sent to the list, 
> awaiting action.
> 
> (The cx25840 code that trusts the volume register to be in range is already 
> in 2.6.36 and breaks IR and analog for CX23885/7/8 chips.)
> 
> I'll give this whole patch a harder look later this evening if I can.
> 
> Regards,
> Andy
> 

Would the patch below fix these issues? It compiles, but I didn't test it.

Regards,

Hans

diff --git a/drivers/media/video/cx18/cx18-av-core.c 
b/drivers/media/video/cx18/cx18-av-core.c
index e1f58f1..73b6f4d 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -248,8 +248,22 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
 /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
 /*} */
cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
-   default_volume = 228 - cx18_av_read(cx, 0x8d4);
-   default_volume = ((default_volume / 2) + 23) << 9;
+   default_volume = cx18_av_read(cx, 0x8d4);
+   /*
+* Enforce the legacy volume scale mapping limits to avoid -ERANGE
+* errors when initializing the volume control
+*/
+   if (default_volume > 228) {
+   /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
+   default_volume = 228;
+   cx18_av_write(cx, 0x8d4, 228);
+   }
+   else if (default_volume < 20) {
+   /* Top out at + 8 dB, v4l2 vol range 0xfe00-0x */
+   default_volume = 20;
+   cx18_av_write(cx, 0x8d4, 20);
+   }
+   default_volume = (((228 - default_volume) >> 1) + 23) << 9;
state->volume->cur.val = state->volume->default_value = default_volume;
v4l2_ctrl_handler_setup(&state->hdl);
 }
@@ -1359,7 +1373,7 @@ int cx18_av_probe(struct cx18 *cx)
 
state->volume = v4l2_ctrl_new_std(&state->hdl,
&cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
-   0, 65335, 65535 / 100, 0);
+   0, 65535, 65535 / 100, 0);
v4l2_ctrl_new_std(&state->hdl,
&cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
0, 1, 1, 0);

-- 
Hans Verkuil - video4linux developer - sponsored by Cisco
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[cron job] v4l-dvb daily build: WARNINGS

2010-12-12 Thread Hans Verkuil
This message is generated daily by a cron job that builds v4l-dvb for
the kernels and architectures in the list below.

Results of the daily build of v4l-dvb:

date:Sun Dec 12 19:00:09 CET 2010
git master:   59365d136d205cc20fe666ca7f89b1c5001b0d5a
git media-master: gcc version:  i686-linux-gcc (GCC) 4.5.1
host hardware:x86_64
host os:  2.6.32.5

linux-git-armv5: WARNINGS
linux-git-armv5-davinci: WARNINGS
linux-git-armv5-ixp: WARNINGS
linux-git-armv5-omap2: WARNINGS
linux-git-i686: WARNINGS
linux-git-m32r: WARNINGS
linux-git-mips: WARNINGS
linux-git-powerpc64: WARNINGS
linux-git-x86_64: WARNINGS
spec-git: OK
sparse: ERRORS

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Sunday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Sunday.tar.bz2

The V4L-DVB specification from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/media.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH 03/19] cx18: Use the control framework.

2010-12-12 Thread Andy Walls
Hans,

This has at least the same two problems the change for cx25840 had:

1. Volume control init should use 65535 not 65335

2. You cannot trust reg 0x8d4 to have a value in it for the default volume that 
won't give an ERANGE error when you go to init the volume control.  Subdev 
probe will fail. See my previous cx25840 patches sent to the list, awaiting 
action.

(The cx25840 code that trusts the volume register to be in range is already in 
2.6.36 and breaks IR and analog for CX23885/7/8 chips.)

I'll give this whole patch a harder look later this evening if I can.

Regards,
Andy

Hans Verkuil  wrote:

>Signed-off-by: Hans Verkuil 
>---
> drivers/media/video/cx18/cx18-av-audio.c |   92 ++-
> drivers/media/video/cx18/cx18-av-core.c  |  162 ++---
> drivers/media/video/cx18/cx18-av-core.h  |   12 +-
> drivers/media/video/cx18/cx18-controls.c |  285 --
> drivers/media/video/cx18/cx18-controls.h |7 +-
> drivers/media/video/cx18/cx18-driver.c   |   30 ++--
> drivers/media/video/cx18/cx18-driver.h   |2 +-
> drivers/media/video/cx18/cx18-fileops.c  |   32 +---
> drivers/media/video/cx18/cx18-ioctl.c|   24 +--
> drivers/media/video/cx18/cx18-mailbox.c  |5 +-
> drivers/media/video/cx18/cx18-mailbox.h  |5 -
> drivers/media/video/cx18/cx18-streams.c  |   16 +-
> 12 files changed, 160 insertions(+), 512 deletions(-)
>
>diff --git a/drivers/media/video/cx18/cx18-av-audio.c 
>b/drivers/media/video/cx18/cx18-av-audio.c
>index 43d09a2..4a24ffb 100644
>--- a/drivers/media/video/cx18/cx18-av-audio.c
>+++ b/drivers/media/video/cx18/cx18-av-audio.c
>@@ -342,17 +342,6 @@ void cx18_av_audio_set_path(struct cx18 *cx)
>   }
> }
> 
>-static int get_volume(struct cx18 *cx)
>-{
>-  /* Volume runs +18dB to -96dB in 1/2dB steps
>-   * change to fit the msp3400 -114dB to +12dB range */
>-
>-  /* check PATH1_VOLUME */
>-  int vol = 228 - cx18_av_read(cx, 0x8d4);
>-  vol = (vol / 2) + 23;
>-  return vol << 9;
>-}
>-
> static void set_volume(struct cx18 *cx, int volume)
> {
>   /* First convert the volume to msp3400 values (0-127) */
>@@ -369,52 +358,18 @@ static void set_volume(struct cx18 *cx, int volume)
>   cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
> }
> 
>-static int get_bass(struct cx18 *cx)
>-{
>-  /* bass is 49 steps +12dB to -12dB */
>-
>-  /* check PATH1_EQ_BASS_VOL */
>-  int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
>-  bass = (((48 - bass) * 0x) + 47) / 48;
>-  return bass;
>-}
>-
> static void set_bass(struct cx18 *cx, int bass)
> {
>   /* PATH1_EQ_BASS_VOL */
>   cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0x));
> }
> 
>-static int get_treble(struct cx18 *cx)
>-{
>-  /* treble is 49 steps +12dB to -12dB */
>-
>-  /* check PATH1_EQ_TREBLE_VOL */
>-  int treble = cx18_av_read(cx, 0x8db) & 0x3f;
>-  treble = (((48 - treble) * 0x) + 47) / 48;
>-  return treble;
>-}
>-
> static void set_treble(struct cx18 *cx, int treble)
> {
>   /* PATH1_EQ_TREBLE_VOL */
>   cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0x));
> }
> 
>-static int get_balance(struct cx18 *cx)
>-{
>-  /* balance is 7 bit, 0 to -96dB */
>-
>-  /* check PATH1_BAL_LEVEL */
>-  int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
>-  /* check PATH1_BAL_LEFT */
>-  if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
>-  balance = 0x80 - balance;
>-  else
>-  balance = 0x80 + balance;
>-  return balance << 8;
>-}
>-
> static void set_balance(struct cx18 *cx, int balance)
> {
>   int bal = balance >> 8;
>@@ -431,12 +386,6 @@ static void set_balance(struct cx18 *cx, int balance)
>   }
> }
> 
>-static int get_mute(struct cx18 *cx)
>-{
>-  /* check SRC1_MUTE_EN */
>-  return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
>-}
>-
> static void set_mute(struct cx18 *cx, int mute)
> {
>   struct cx18_av_state *state = &cx->av_state;
>@@ -490,50 +439,33 @@ int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 
>freq)
>   return retval;
> }
> 
>-int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
>+static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
> {
>-  switch (ctrl->id) {
>-  case V4L2_CID_AUDIO_VOLUME:
>-  ctrl->value = get_volume(cx);
>-  break;
>-  case V4L2_CID_AUDIO_BASS:
>-  ctrl->value = get_bass(cx);
>-  break;
>-  case V4L2_CID_AUDIO_TREBLE:
>-  ctrl->value = get_treble(cx);
>-  break;
>-  case V4L2_CID_AUDIO_BALANCE:
>-  ctrl->value = get_balance(cx);
>-  break;
>-  case V4L2_CID_AUDIO_MUTE:
>-  ctrl->value = get_mute(cx);
>-  break;
>-  default:
>-  return -EINVAL;
>-  }
>-  return 0;
>-}
>+  struct v4l2_subdev *sd = to_sd(ctrl);
>+  struct cx18 *cx = v4l2_get_subdevdata(sd);
> 
>-int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l

Re: user accesses in ivtv-fileops.c:ivtv_v4l2_write ?

2010-12-12 Thread Dr. David Alan Gilbert
* Andy Walls (awa...@md.metrocast.net) wrote:
> On Sun, 2010-11-28 at 17:40 +, Dr. David Alan Gilbert wrote:
> > Hi,
> >   Sparse pointed me at the following line in ivtv-fileops.c's 
> > ivtv_v4l2_write:
> > 
> > ivtv_write_vbi(itv, (const struct v4l2_sliced_vbi_data 
> > *)user_buf, elems);
> > 
> 
> Hi David,
> 
> Let me know if this patch works for your sparse build and adequately
> addresses the problem.

Hi Andy,
  Yes that seems to fix it.
The only other comment I have is that it would probably be better if
ivtv_write_vbi_from_user() were to return an error if the copy_from_user
were to fail and then pass that all the way back up so that if an app passed
a bad pointer in it would get an EFAULT or the like.

Thanks,

Dave
-- 
 -Open up your eyes, open up your mind, open up your code ---   
/ Dr. David Alan Gilbert|   Running GNU/Linux   | Happy  \ 
\ gro.gilbert @ treblig.org |   | In Hex /
 \ _|_ http://www.treblig.org   |___/
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC/PATCH 12/19] tvp5150: use the control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tvp5150.c |  157 -
 1 files changed, 46 insertions(+), 111 deletions(-)

diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 5892766..959d690 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "tvp5150_reg.h"
 
@@ -24,58 +25,14 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0-2)");
 
-/* supported controls */
-static struct v4l2_queryctrl tvp5150_qctrl[] = {
-   {
-   .id = V4L2_CID_BRIGHTNESS,
-   .type = V4L2_CTRL_TYPE_INTEGER,
-   .name = "Brightness",
-   .minimum = 0,
-   .maximum = 255,
-   .step = 1,
-   .default_value = 128,
-   .flags = 0,
-   }, {
-   .id = V4L2_CID_CONTRAST,
-   .type = V4L2_CTRL_TYPE_INTEGER,
-   .name = "Contrast",
-   .minimum = 0,
-   .maximum = 255,
-   .step = 0x1,
-   .default_value = 128,
-   .flags = 0,
-   }, {
-.id = V4L2_CID_SATURATION,
-.type = V4L2_CTRL_TYPE_INTEGER,
-.name = "Saturation",
-.minimum = 0,
-.maximum = 255,
-.step = 0x1,
-.default_value = 128,
-.flags = 0,
-   }, {
-   .id = V4L2_CID_HUE,
-   .type = V4L2_CTRL_TYPE_INTEGER,
-   .name = "Hue",
-   .minimum = -128,
-   .maximum = 127,
-   .step = 0x1,
-   .default_value = 0,
-   .flags = 0,
-   }
-};
-
 struct tvp5150 {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
 
v4l2_std_id norm;   /* Current set standard */
u32 input;
u32 output;
int enable;
-   int bright;
-   int contrast;
-   int hue;
-   int sat;
 };
 
 static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
@@ -83,6 +40,11 @@ static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev 
*sd)
return container_of(sd, struct tvp5150, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tvp5150, hdl)->sd;
+}
+
 static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
 {
struct i2c_client *c = v4l2_get_subdevdata(sd);
@@ -810,64 +772,28 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
tvp5150_write_inittab(sd, tvp5150_init_enable);
 
/* Initialize image preferences */
-   tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright);
-   tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast);
-   tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast);
-   tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue);
+   v4l2_ctrl_handler_setup(&decoder->hdl);
 
tvp5150_set_std(sd, decoder->norm);
return 0;
 };
 
-static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   v4l2_dbg(1, debug, sd, "g_ctrl called\n");
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL);
-   return 0;
-   case V4L2_CID_CONTRAST:
-   ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL);
-   return 0;
-   case V4L2_CID_SATURATION:
-   ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL);
-   return 0;
-   case V4L2_CID_HUE:
-   ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL);
-   return 0;
-   }
-   return -EINVAL;
-}
-
-static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   u8 i, n;
-   n = ARRAY_SIZE(tvp5150_qctrl);
-
-   for (i = 0; i < n; i++) {
-   if (ctrl->id != tvp5150_qctrl[i].id)
-   continue;
-   if (ctrl->value < tvp5150_qctrl[i].minimum ||
-   ctrl->value > tvp5150_qctrl[i].maximum)
-   return -ERANGE;
-   v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
-   ctrl->id, ctrl->value);
-   break;
-   }
+   struct v4l2_subdev *sd = to_sd(ctrl);
 
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
-   tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value);
+   tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
return 0;
case V4L2_CID_CONTRAST:
-   tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value);
+   tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
return 0;
case V4L2_CID_SATURATION:

[RFC/PATCH 03/19] cx18: Use the control framework.

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/cx18/cx18-av-audio.c |   92 ++-
 drivers/media/video/cx18/cx18-av-core.c  |  162 ++---
 drivers/media/video/cx18/cx18-av-core.h  |   12 +-
 drivers/media/video/cx18/cx18-controls.c |  285 --
 drivers/media/video/cx18/cx18-controls.h |7 +-
 drivers/media/video/cx18/cx18-driver.c   |   30 ++--
 drivers/media/video/cx18/cx18-driver.h   |2 +-
 drivers/media/video/cx18/cx18-fileops.c  |   32 +---
 drivers/media/video/cx18/cx18-ioctl.c|   24 +--
 drivers/media/video/cx18/cx18-mailbox.c  |5 +-
 drivers/media/video/cx18/cx18-mailbox.h  |5 -
 drivers/media/video/cx18/cx18-streams.c  |   16 +-
 12 files changed, 160 insertions(+), 512 deletions(-)

diff --git a/drivers/media/video/cx18/cx18-av-audio.c 
b/drivers/media/video/cx18/cx18-av-audio.c
index 43d09a2..4a24ffb 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -342,17 +342,6 @@ void cx18_av_audio_set_path(struct cx18 *cx)
}
 }
 
-static int get_volume(struct cx18 *cx)
-{
-   /* Volume runs +18dB to -96dB in 1/2dB steps
-* change to fit the msp3400 -114dB to +12dB range */
-
-   /* check PATH1_VOLUME */
-   int vol = 228 - cx18_av_read(cx, 0x8d4);
-   vol = (vol / 2) + 23;
-   return vol << 9;
-}
-
 static void set_volume(struct cx18 *cx, int volume)
 {
/* First convert the volume to msp3400 values (0-127) */
@@ -369,52 +358,18 @@ static void set_volume(struct cx18 *cx, int volume)
cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
 }
 
-static int get_bass(struct cx18 *cx)
-{
-   /* bass is 49 steps +12dB to -12dB */
-
-   /* check PATH1_EQ_BASS_VOL */
-   int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
-   bass = (((48 - bass) * 0x) + 47) / 48;
-   return bass;
-}
-
 static void set_bass(struct cx18 *cx, int bass)
 {
/* PATH1_EQ_BASS_VOL */
cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0x));
 }
 
-static int get_treble(struct cx18 *cx)
-{
-   /* treble is 49 steps +12dB to -12dB */
-
-   /* check PATH1_EQ_TREBLE_VOL */
-   int treble = cx18_av_read(cx, 0x8db) & 0x3f;
-   treble = (((48 - treble) * 0x) + 47) / 48;
-   return treble;
-}
-
 static void set_treble(struct cx18 *cx, int treble)
 {
/* PATH1_EQ_TREBLE_VOL */
cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0x));
 }
 
-static int get_balance(struct cx18 *cx)
-{
-   /* balance is 7 bit, 0 to -96dB */
-
-   /* check PATH1_BAL_LEVEL */
-   int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
-   /* check PATH1_BAL_LEFT */
-   if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
-   balance = 0x80 - balance;
-   else
-   balance = 0x80 + balance;
-   return balance << 8;
-}
-
 static void set_balance(struct cx18 *cx, int balance)
 {
int bal = balance >> 8;
@@ -431,12 +386,6 @@ static void set_balance(struct cx18 *cx, int balance)
}
 }
 
-static int get_mute(struct cx18 *cx)
-{
-   /* check SRC1_MUTE_EN */
-   return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
-}
-
 static void set_mute(struct cx18 *cx, int mute)
 {
struct cx18_av_state *state = &cx->av_state;
@@ -490,50 +439,33 @@ int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
return retval;
 }
 
-int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   switch (ctrl->id) {
-   case V4L2_CID_AUDIO_VOLUME:
-   ctrl->value = get_volume(cx);
-   break;
-   case V4L2_CID_AUDIO_BASS:
-   ctrl->value = get_bass(cx);
-   break;
-   case V4L2_CID_AUDIO_TREBLE:
-   ctrl->value = get_treble(cx);
-   break;
-   case V4L2_CID_AUDIO_BALANCE:
-   ctrl->value = get_balance(cx);
-   break;
-   case V4L2_CID_AUDIO_MUTE:
-   ctrl->value = get_mute(cx);
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
+   struct v4l2_subdev *sd = to_sd(ctrl);
+   struct cx18 *cx = v4l2_get_subdevdata(sd);
 
-int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
-{
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
-   set_volume(cx, ctrl->value);
+   set_volume(cx, ctrl->val);
break;
case V4L2_CID_AUDIO_BASS:
-   set_bass(cx, ctrl->value);
+   set_bass(cx, ctrl->val);
break;
case V4L2_CID_AUDIO_TREBLE:
-   set_treble(cx, ctrl->value);
+   set_treble(cx, ctrl->val);
break;
case V4L2_CID_AUDIO_BALANCE:
-   set_balance(cx, ctrl->value);
+   set_balance(cx, ctrl->val);
break;
case V4L2_CID_AUDIO_MUTE:
-   set_mute(cx

[RFC/PATCH 08/19] tda7432: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tda7432.c |  277 -
 1 files changed, 106 insertions(+), 171 deletions(-)

diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 3941f95..2e430a6 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -35,6 +35,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #ifndef VIDEO_AUDIO_BALANCE
@@ -50,7 +51,7 @@ static int loudness; /* disable loudness by default */
 static int debug;   /* insmod parameter */
 module_param(debug, int, S_IRUGO | S_IWUSR);
 module_param(loudness, int, S_IRUGO);
-MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
+MODULE_PARM_DESC(maxvol, "Set maximum volume to +20db (0), default is 0db(1)");
 module_param(maxvol, int, S_IRUGO | S_IWUSR);
 
 
@@ -59,13 +60,17 @@ module_param(maxvol, int, S_IRUGO | S_IWUSR);
 
 struct tda7432 {
struct v4l2_subdev sd;
-   int addr;
-   int input;
-   int volume;
-   int muted;
-   int bass, treble;
-   int lf, lr, rf, rr;
-   int loud;
+   struct v4l2_ctrl_handler hdl;
+   struct {
+   /* bass/treble cluster */
+   struct v4l2_ctrl *bass;
+   struct v4l2_ctrl *treble;
+   };
+   struct {
+   /* mute/balance cluster */
+   struct v4l2_ctrl *mute;
+   struct v4l2_ctrl *balance;
+   };
 };
 
 static inline struct tda7432 *to_state(struct v4l2_subdev *sd)
@@ -73,6 +78,11 @@ static inline struct tda7432 *to_state(struct v4l2_subdev 
*sd)
return container_of(sd, struct tda7432, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tda7432, hdl)->sd;
+}
+
 /* The TDA7432 is made by STS-Thompson
  * http://www.st.com
  * http://us.st.com/stonline/books/pdf/docs/4056.pdf
@@ -226,24 +236,22 @@ static int tda7432_write(struct v4l2_subdev *sd, int 
subaddr, int val)
 static int tda7432_set(struct v4l2_subdev *sd)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
-   struct tda7432 *t = to_state(sd);
unsigned char buf[16];
 
-   v4l2_dbg(1, debug, sd,
-   "tda7432: 
7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n",
-   t->input, t->volume, t->bass, t->treble, t->lf, t->lr,
-   t->rf, t->rr, t->loud);
buf[0]  = TDA7432_IN;
-   buf[1]  = t->input;
-   buf[2]  = t->volume;
-   buf[3]  = t->bass;
-   buf[4]  = t->treble;
-   buf[5]  = t->lf;
-   buf[6]  = t->lr;
-   buf[7]  = t->rf;
-   buf[8]  = t->rr;
-   buf[9]  = t->loud;
-   if (10 != i2c_master_send(client, buf, 10)) {
+   buf[1]  = TDA7432_STEREO_IN |  /* Main (stereo) input   */
+ TDA7432_BASS_SYM  |  /* Symmetric bass cut*/
+ TDA7432_BASS_NORM;   /* Normal bass range */
+   buf[2]  = 0x3b;
+   if (loudness)/* Turn loudness on? */
+   buf[2] |= TDA7432_LD_ON;
+   buf[3]  = TDA7432_TREBLE_0DB | (TDA7432_BASS_0DB << 4);
+   buf[4]  = TDA7432_ATTEN_0DB;
+   buf[5]  = TDA7432_ATTEN_0DB;
+   buf[6]  = TDA7432_ATTEN_0DB;
+   buf[7]  = TDA7432_ATTEN_0DB;
+   buf[8]  = loudness;
+   if (9 != i2c_master_send(client, buf, 9)) {
v4l2_err(sd, "I/O error, trying tda7432_set\n");
return -1;
}
@@ -251,174 +259,77 @@ static int tda7432_set(struct v4l2_subdev *sd)
return 0;
 }
 
-static void do_tda7432_init(struct v4l2_subdev *sd)
-{
-   struct tda7432 *t = to_state(sd);
-
-   v4l2_dbg(2, debug, sd, "In tda7432_init\n");
-
-   t->input  = TDA7432_STEREO_IN |  /* Main (stereo) input   */
-   TDA7432_BASS_SYM  |  /* Symmetric bass cut*/
-   TDA7432_BASS_NORM;   /* Normal bass range */
-   t->volume =  0x3b ;  /* -27dB Volume
*/
-   if (loudness)/* Turn loudness on? */
-   t->volume |= TDA7432_LD_ON;
-   t->muted= 1;
-   t->treble   = TDA7432_TREBLE_0DB; /* 0dB Treble*/
-   t->bass = TDA7432_BASS_0DB;  /* 0dB Bass  */
-   t->lf = TDA7432_ATTEN_0DB;   /* 0dB attenuation   */
-   t->lr = TDA7432_ATTEN_0DB;   /* 0dB attenuation   */
-   t->rf = TDA7432_ATTEN_0DB;   /* 0dB attenuation   */
-   t->rr = TDA7432_ATTEN_0DB;   /* 0dB attenuation   */
-   t->loud   = loudness;/* insmod parameter  */
-
-   tda7432_set(sd);
-}
-
-static int tda7432_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct tda7432 *t = to_state(sd);
-
-   switch (ctrl->id) {
-   case V4L2_CID_AUDIO_MUTE:
-   ctrl->value=t->muted;
-   return 0;
-   case V4L2_CID_AUD

[RFC/PATCH 13/19] vpx3220: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/vpx3220.c |  137 +++--
 1 files changed, 51 insertions(+), 86 deletions(-)

diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 91a01b3..75301d1 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
 MODULE_AUTHOR("Laurent Pinchart");
@@ -44,16 +45,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 struct vpx3220 {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
unsigned char reg[255];
 
v4l2_std_id norm;
int ident;
int input;
int enable;
-   int bright;
-   int contrast;
-   int hue;
-   int sat;
 };
 
 static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
@@ -61,6 +59,11 @@ static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev 
*sd)
return container_of(sd, struct vpx3220, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct vpx3220, hdl)->sd;
+}
+
 static char *inputs[] = { "internal", "composite", "svideo" };
 
 /* --- */
@@ -417,88 +420,26 @@ static int vpx3220_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }
 
-static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_BRIGHTNESS:
-   v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
-   break;
-
-   case V4L2_CID_CONTRAST:
-   v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
-   break;
-
-   case V4L2_CID_SATURATION:
-   v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
-   break;
-
-   case V4L2_CID_HUE:
-   v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
-   break;
-
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
-static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int vpx3220_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct vpx3220 *decoder = to_vpx3220(sd);
+   struct v4l2_subdev *sd = to_sd(ctrl);
 
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
-   ctrl->value = decoder->bright;
-   break;
+   vpx3220_write(sd, 0xe6, ctrl->val);
+   return 0;
case V4L2_CID_CONTRAST:
-   ctrl->value = decoder->contrast;
-   break;
+   /* Bit 7 and 8 is for noise shaping */
+   vpx3220_write(sd, 0xe7, ctrl->val + 192);
+   return 0;
case V4L2_CID_SATURATION:
-   ctrl->value = decoder->sat;
-   break;
+   vpx3220_fp_write(sd, 0xa0, ctrl->val);
+   return 0;
case V4L2_CID_HUE:
-   ctrl->value = decoder->hue;
-   break;
-   default:
-   return -EINVAL;
+   vpx3220_fp_write(sd, 0x1c, ctrl->val);
+   return 0;
}
-   return 0;
-}
-
-static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct vpx3220 *decoder = to_vpx3220(sd);
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   if (decoder->bright != ctrl->value) {
-   decoder->bright = ctrl->value;
-   vpx3220_write(sd, 0xe6, decoder->bright);
-   }
-   break;
-   case V4L2_CID_CONTRAST:
-   if (decoder->contrast != ctrl->value) {
-   /* Bit 7 and 8 is for noise shaping */
-   decoder->contrast = ctrl->value;
-   vpx3220_write(sd, 0xe7, decoder->contrast + 192);
-   }
-   break;
-   case V4L2_CID_SATURATION:
-   if (decoder->sat != ctrl->value) {
-   decoder->sat = ctrl->value;
-   vpx3220_fp_write(sd, 0xa0, decoder->sat);
-   }
-   break;
-   case V4L2_CID_HUE:
-   if (decoder->hue != ctrl->value) {
-   decoder->hue = ctrl->value;
-   vpx3220_fp_write(sd, 0x1c, decoder->hue);
-   }
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
+   return -EINVAL;
 }
 
 static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct 
v4l2_dbg_chip_ident *chip)
@@ -511,12 +452,20 @@ static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, 
struct v4l2_dbg_chip_ide
 
 /* --- */
 
+static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
+   .s_ctrl = vpx3220_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops vpx3220_c

[RFC/PATCH 15/19] v4l2-ctrls: use const char * const * for the menu arrays

2010-12-12 Thread Hans Verkuil
This prevents checkpatch warnings generated when defining
'static const char *foo[]' arrays. It makes sense to use
const char * const * anyway since the pointers in the array
are indeed const.

Signed-off-by: Hans Verkuil 
---
 drivers/media/video/cx2341x.c  |8 ++--
 drivers/media/video/pvrusb2/pvrusb2-ctrl.c |6 +-
 drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h |2 +-
 drivers/media/video/v4l2-common.c  |6 +-
 drivers/media/video/v4l2-ctrls.c   |   46 ++--
 include/media/cx2341x.h|2 +-
 include/media/v4l2-common.h|6 +-
 include/media/v4l2-ctrls.h |4 +-
 8 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index e5c3c8d..103ef6b 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -853,9 +853,9 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params 
*params,
 }
 EXPORT_SYMBOL(cx2341x_ctrl_query);
 
-const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
+const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, 
u32 id)
 {
-   static const char *mpeg_stream_type_without_ts[] = {
+   static const char * const mpeg_stream_type_without_ts[] = {
"MPEG-2 Program Stream",
"",
"MPEG-1 System Stream",
@@ -952,7 +952,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, 
int busy,
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
struct v4l2_queryctrl qctrl;
-   const char **menu_items = NULL;
+   const char * const *menu_items = NULL;
 
qctrl.id = ctrl->id;
err = cx2341x_ctrl_query(params, &qctrl);
@@ -1135,7 +1135,7 @@ EXPORT_SYMBOL(cx2341x_update);
 
 static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 
id)
 {
-   const char **menu = cx2341x_ctrl_get_menu(p, id);
+   const char * const *menu = cx2341x_ctrl_get_menu(p, id);
struct v4l2_ext_control ctrl;
 
if (menu == NULL)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c 
b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 55ea914..7d5a713 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -203,7 +203,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
*blen = 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
if (cptr->info->type == pvr2_ctl_enum) {
-   const char **names;
+   const char * const *names;
names = cptr->info->def.type_enum.value_names;
if (pvr2_ctrl_range_check(cptr,val) == 0) {
if (names[val]) {
@@ -367,7 +367,7 @@ static const char *boolNames[] = {
 
 static int parse_token(const char *ptr,unsigned int len,
   int *valptr,
-  const char **names,unsigned int namecnt)
+  const char * const *names, unsigned int namecnt)
 {
char buf[33];
unsigned int slen;
@@ -559,7 +559,7 @@ int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr,
*len = scnprintf(buf,maxlen,"%s",val ? "true" : "false");
ret = 0;
} else if (cptr->info->type == pvr2_ctl_enum) {
-   const char **names;
+   const char * const *names;
names = cptr->info->def.type_enum.value_names;
if ((val >= 0) &&
(val < cptr->info->def.type_enum.count)) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h 
b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index cb4057b..ac94a8b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -115,7 +115,7 @@ struct pvr2_ctl_info {
} type_int;
struct { /* enumerated control */
unsigned int count;   /* enum value count */
-   const char **value_names; /* symbol names */
+   const char * const *value_names; /* symbol names */
} type_enum;
struct { /* bitmask control */
unsigned int valid_bits; /* bits in use */
diff --git a/drivers/media/video/v4l2-common.c 
b/drivers/media/video/v4l2-common.c
index b5eb1f3..3f0871b 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -150,7 +150,7 @@ EXPORT_SYMBOL(v4l2_prio_check);
struct v4l2_queryctrl and the available menu items. Note that
menu_items may be NULL, in that case it is ignored. */
 int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl 
*

[RFC/PATCH 14/19] tvp7002: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tvp7002.c |  117 +++--
 1 files changed, 43 insertions(+), 74 deletions(-)

diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index e63b40f..2c4a6fd 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "tvp7002_reg.h"
 
 MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
@@ -421,13 +422,13 @@ static const struct tvp7002_preset_definition 
tvp7002_presets[] = {
 /* Device definition */
 struct tvp7002 {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
const struct tvp7002_config *pdata;
 
int ver;
int streaming;
 
const struct tvp7002_preset_definition *current_preset;
-   u8 gain;
 };
 
 /*
@@ -441,6 +442,11 @@ static inline struct tvp7002 *to_tvp7002(struct 
v4l2_subdev *sd)
return container_of(sd, struct tvp7002, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
+}
+
 /*
  * tvp7002_read - Read a value from a register in an TVP7002
  * @sd: ptr to v4l2_subdev struct
@@ -606,78 +612,25 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
 }
 
 /*
- * tvp7002_g_ctrl() - Get a control
- * @sd: ptr to v4l2_subdev struct
- * @ctrl: ptr to v4l2_control struct
- *
- * Get a control for a TVP7002 decoder device.
- * Returns zero when successful or -EINVAL if register access fails.
- */
-static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct tvp7002 *device = to_tvp7002(sd);
-
-   switch (ctrl->id) {
-   case V4L2_CID_GAIN:
-   ctrl->value = device->gain;
-   return 0;
-   default:
-   return -EINVAL;
-   }
-}
-
-/*
  * tvp7002_s_ctrl() - Set a control
- * @sd: ptr to v4l2_subdev struct
- * @ctrl: ptr to v4l2_control struct
+ * @ctrl: ptr to v4l2_ctrl struct
  *
  * Set a control in TVP7002 decoder device.
  * Returns zero when successful or -EINVAL if register access fails.
  */
-static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct tvp7002 *device = to_tvp7002(sd);
+   struct v4l2_subdev *sd = to_sd(ctrl);
int error = 0;
 
switch (ctrl->id) {
case V4L2_CID_GAIN:
-   tvp7002_write_err(sd, TVP7002_R_FINE_GAIN,
-   ctrl->value & 0xff, &error);
-   tvp7002_write_err(sd, TVP7002_G_FINE_GAIN,
-   ctrl->value & 0xff, &error);
-   tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
-   ctrl->value & 0xff, &error);
-
-   if (error < 0)
-   return error;
-
-   /* Set only after knowing there is no error */
-   device->gain = ctrl->value & 0xff;
-   return 0;
-   default:
-   return -EINVAL;
-   }
-}
-
-/*
- * tvp7002_queryctrl() - Query a control
- * @sd: ptr to v4l2_subdev struct
- * @qc: ptr to v4l2_queryctrl struct
- *
- * Query a control of a TVP7002 decoder device.
- * Returns zero when successful or -EINVAL if register read fails.
- */
-static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_GAIN:
-   /*
-* Gain is supported [0-255, default=0, step=1]
-*/
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
-   default:
-   return -EINVAL;
+   tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
+   tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
+   tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
+   return error;
}
+   return -EINVAL;
 }
 
 /*
@@ -924,7 +877,7 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
device->streaming ? "yes" : "no");
 
/* Print the current value of the gain control */
-   v4l2_info(sd, "Gain: %u\n", device->gain);
+   v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
 
return 0;
 }
@@ -946,13 +899,21 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, 
preset);
 }
 
+static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
+   .s_ctrl = tvp7002_s_ctrl,
+};
+
 /* V4L2 core operation handlers */
 static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
.g_chip_ident = tvp7002_g_chip_ident,
.log_status = tvp7002_log_status,
-   .g_ctrl = tvp7002_g_ctrl,
-   .s_ctrl = tvp7002_s_ctrl,
-   .queryctrl = tvp7002_queryc

[RFC/PATCH 19/19] v4l2-ctrls: only check def for menu, integer and boolean controls

2010-12-12 Thread Hans Verkuil
The 'def' field is only valid for menus, integers and booleans.

Signed-off-by: Hans Verkuil 
---
 drivers/media/video/v4l2-ctrls.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 6c0fadc..8f81efc 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -962,13 +962,20 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct 
v4l2_ctrl_handler *hdl,
 
/* Sanity checks */
if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE ||
-   def < min || def > max || max < min ||
+   max < min ||
(type == V4L2_CTRL_TYPE_INTEGER && step == 0) ||
(type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
(type == V4L2_CTRL_TYPE_STRING && max == 0)) {
handler_set_err(hdl, -ERANGE);
return NULL;
}
+   if ((type == V4L2_CTRL_TYPE_INTEGER ||
+type == V4L2_CTRL_TYPE_MENU ||
+type == V4L2_CTRL_TYPE_BOOLEAN) &&
+   (def < min || def > max)) {
+   handler_set_err(hdl, -ERANGE);
+   return NULL;
+   }
 
if (type == V4L2_CTRL_TYPE_BUTTON)
flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
-- 
1.7.0.4

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


[RFC/PATCH 17/19] v4l: fix handling of v4l2_input.capabilities

2010-12-12 Thread Hans Verkuil
The v4l core sets the v4l2_input.capabilities field based on the supplied
v4l2_ioctl_ops. However, several drivers do a memset or memcpy of the v4l2_input
struct, thus overwriting that field incorrectly.

Either remove the memset (which is already done by the v4l core), or add the
proper capabilities field in case of a memcpy.

The same is also true for v4l2_output, but that only affected the ivtv driver.

Signed-off-by: Hans Verkuil 
---
 drivers/media/dvb/ttpci/av7110_v4l.c |4 
 drivers/media/dvb/ttpci/budget-av.c  |6 --
 drivers/media/video/cx18/cx18-cards.c|1 -
 drivers/media/video/cx23885/cx23885-video.c  |1 -
 drivers/media/video/et61x251/et61x251_core.c |1 +
 drivers/media/video/hexium_gemini.c  |   18 +-
 drivers/media/video/hexium_orion.c   |   18 +-
 drivers/media/video/ivtv/ivtv-cards.c|2 --
 drivers/media/video/mxb.c|8 
 drivers/media/video/saa7134/saa7134-video.c  |1 -
 drivers/media/video/sn9c102/sn9c102_core.c   |1 +
 drivers/media/video/timblogiw.c  |1 -
 drivers/media/video/vino.c   |3 ---
 drivers/media/video/zoran/zoran_driver.c |6 --
 drivers/staging/cx25821/cx25821-video.c  |2 --
 15 files changed, 32 insertions(+), 41 deletions(-)

diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c 
b/drivers/media/dvb/ttpci/av7110_v4l.c
index ac20c5b..cdd31ca 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -100,6 +100,7 @@ static struct v4l2_input inputs[4] = {
.tuner  = 0, /* ignored */
.std= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+   .capabilities   = V4L2_IN_CAP_STD,
}, {
.index  = 1,
.name   = "Television",
@@ -108,6 +109,7 @@ static struct v4l2_input inputs[4] = {
.tuner  = 0,
.std= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+   .capabilities   = V4L2_IN_CAP_STD,
}, {
.index  = 2,
.name   = "Video",
@@ -116,6 +118,7 @@ static struct v4l2_input inputs[4] = {
.tuner  = 0,
.std= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+   .capabilities   = V4L2_IN_CAP_STD,
}, {
.index  = 3,
.name   = "Y/C",
@@ -124,6 +127,7 @@ static struct v4l2_input inputs[4] = {
.tuner  = 0,
.std= V4L2_STD_PAL_BG|V4L2_STD_NTSC_M,
.status = 0,
+   .capabilities   = V4L2_IN_CAP_STD,
}
 };
 
diff --git a/drivers/media/dvb/ttpci/budget-av.c 
b/drivers/media/dvb/ttpci/budget-av.c
index 97afc01..e957d76 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1406,8 +1406,10 @@ static int budget_av_detach(struct saa7146_dev *dev)
 
 #define KNC1_INPUTS 2
 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
-   {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | 
V4L2_STD_NTSC_M, 0},
-   {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | 
V4L2_STD_NTSC_M, 0},
+   { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
+   V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
+   { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
+   V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
 };
 
 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
diff --git a/drivers/media/video/cx18/cx18-cards.c 
b/drivers/media/video/cx18/cx18-cards.c
index 52ba913..8717773 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -546,7 +546,6 @@ int cx18_get_input(struct cx18 *cx, u16 index, struct 
v4l2_input *input)
"Component 1"
};
 
-   memset(input, 0, sizeof(*input));
if (index >= cx->nof_inputs)
return -EINVAL;
input->index = index;
diff --git a/drivers/media/video/cx23885/cx23885-video.c 
b/drivers/media/video/cx23885/cx23885-video.c
index 8b2fb8a..fa08ea3 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1155,7 +1155,6 @@ static int cx23885_enum_input(struct cx23885_dev *dev, 
struct v4l2_input *i)
if (0 == INPUT(n)->type)
return -EINVAL;
 
-   memset(i, 0, sizeof(*i));
i->index = n;
i->type  = V4L2_INPUT_TYPE_CAMERA;
strcpy(i->name, iname[INPUT(n)->type]);
diff --git a/drivers/media/video/et61x251/et61x251_core.c 
b/drivers/media/video/et61x251/et61x251_core.c
index a5cfc76..f5892ee 100644
--- a/drivers/media/video/et61x251/et6

[RFC/PATCH 18/19] em28xx: fix incorrect s_ctrl error code and wrong call to res_free

2010-12-12 Thread Hans Verkuil
Calling subdevs to handle s_ctrl returned a non-zero return code even if
everything went fine.

Calling STREAMOFF if no STREAMON happened earlier would hit a BUG_ON
in res_free.

Signed-off-by: Hans Verkuil 
---
 drivers/media/video/em28xx/em28xx-video.c |   14 +-
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/media/video/em28xx/em28xx-video.c 
b/drivers/media/video/em28xx/em28xx-video.c
index 908e3bc..37d6f16 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1434,7 +1434,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
/* It isn't an AC97 control. Sends it to the v4l2 dev interface */
if (rc == 1) {
-   v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
+   rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, 
s_ctrl, ctrl);
 
/*
 * In the case of non-AC97 volume controls, we still need
@@ -1708,11 +1708,15 @@ static int vidioc_streamoff(struct file *file, void 
*priv,
fh, type, fh->resources, dev->resources);
 
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-   videobuf_streamoff(&fh->vb_vidq);
-   res_free(fh, EM28XX_RESOURCE_VIDEO);
+   if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
+   videobuf_streamoff(&fh->vb_vidq);
+   res_free(fh, EM28XX_RESOURCE_VIDEO);
+   }
} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-   videobuf_streamoff(&fh->vb_vbiq);
-   res_free(fh, EM28XX_RESOURCE_VBI);
+   if (res_check(fh, EM28XX_RESOURCE_VBI)) {
+   videobuf_streamoff(&fh->vb_vbiq);
+   res_free(fh, EM28XX_RESOURCE_VBI);
+   }
}
 
return 0;
-- 
1.7.0.4

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


[RFC/PATCH 11/19] tvp514x: use the control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tvp514x.c |  236 ++---
 1 files changed, 57 insertions(+), 179 deletions(-)

diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 45bcf03..9b3e828 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "tvp514x_regs.h"
@@ -97,6 +98,7 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int 
enable);
  */
 struct tvp514x_decoder {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
const struct tvp514x_platform_data *pdata;
 
@@ -238,6 +240,11 @@ static inline struct tvp514x_decoder *to_decoder(struct 
v4l2_subdev *sd)
return container_of(sd, struct tvp514x_decoder, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
+}
+
 
 /**
  * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
@@ -719,213 +726,54 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
 }
 
 /**
- * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
- * @sd: pointer to standard V4L2 sub-device structure
- * @qctrl: standard V4L2 v4l2_queryctrl structure
- *
- * If the requested control is supported, returns the control information.
- * Otherwise, returns -EINVAL if the control is not supported.
- */
-static int
-tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
-{
-   int err = -EINVAL;
-
-   if (qctrl == NULL)
-   return err;
-
-   switch (qctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   /* Brightness supported is (0-255), */
-   err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
-   break;
-   case V4L2_CID_CONTRAST:
-   case V4L2_CID_SATURATION:
-   /**
-* Saturation and Contrast supported is -
-*  Contrast: 0 - 255 (Default - 128)
-*  Saturation: 0 - 255 (Default - 128)
-*/
-   err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
-   break;
-   case V4L2_CID_HUE:
-   /* Hue Supported is -
-*  Hue - -180 - +180 (Default - 0, Step - +180)
-*/
-   err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
-   break;
-   case V4L2_CID_AUTOGAIN:
-   /**
-* Auto Gain supported is -
-*  0 - 1 (Default - 1)
-*/
-   err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
-   break;
-   default:
-   v4l2_err(sd, "invalid control id %d\n", qctrl->id);
-   return err;
-   }
-
-   v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - 
%d\n",
-   qctrl->name, qctrl->minimum, qctrl->maximum,
-   qctrl->default_value);
-
-   return err;
-}
-
-/**
- * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
- * @sd: pointer to standard V4L2 sub-device structure
- * @ctrl: pointer to v4l2_control structure
- *
- * If the requested control is supported, returns the control's current
- * value from the decoder. Otherwise, returns -EINVAL if the control is not
- * supported.
- */
-static int
-tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct tvp514x_decoder *decoder = to_decoder(sd);
-
-   if (ctrl == NULL)
-   return -EINVAL;
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
-   break;
-   case V4L2_CID_CONTRAST:
-   ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
-   break;
-   case V4L2_CID_SATURATION:
-   ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
-   break;
-   case V4L2_CID_HUE:
-   ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
-   if (ctrl->value == 0x7F)
-   ctrl->value = 180;
-   else if (ctrl->value == 0x80)
-   ctrl->value = -180;
-   else
-   ctrl->value = 0;
-
-   break;
-   case V4L2_CID_AUTOGAIN:
-   ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
-   if ((ctrl->value & 0x3) == 3)
-   ctrl->value = 1;
-   else
-   ctrl->value = 0;
-
-   break;
-   default:
-   v4l2_err(sd, "invalid control id %d\n", ctrl->id);
-   return -EINVAL;
-   }
-
-   v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n",
-   ctrl->id, ctrl->value);
-

[RFC/PATCH 16/19] vivi: convert to the control framework and add test controls.

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/vivi.c |  228 +++-
 1 files changed, 139 insertions(+), 89 deletions(-)

diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 9797e5a..6e1f37f 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define VIVI_MODULE_NAME "vivi"
@@ -162,13 +163,20 @@ static LIST_HEAD(vivi_devlist);
 struct vivi_dev {
struct list_head   vivi_devlist;
struct v4l2_device v4l2_dev;
+   struct v4l2_ctrl_handler   ctrl_handler;
 
/* controls */
-   intbrightness;
-   intcontrast;
-   intsaturation;
-   inthue;
-   intvolume;
+   struct v4l2_ctrl   *brightness;
+   struct v4l2_ctrl   *contrast;
+   struct v4l2_ctrl   *saturation;
+   struct v4l2_ctrl   *hue;
+   struct v4l2_ctrl   *volume;
+   struct v4l2_ctrl   *button;
+   struct v4l2_ctrl   *boolean;
+   struct v4l2_ctrl   *int32;
+   struct v4l2_ctrl   *int64;
+   struct v4l2_ctrl   *menu;
+   struct v4l2_ctrl   *string;
 
spinlock_t slock;
struct mutex   mutex;
@@ -181,6 +189,7 @@ struct vivi_dev {
/* Several counters */
unsigned   ms;
unsigned long  jiffies;
+   unsigned   button_pressed;
 
intmv_count;/* Controls bars movement */
 
@@ -472,14 +481,30 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct 
vivi_buffer *buf)
dev->width, dev->height, dev->input);
gen_text(dev, vbuf, line++ * 16, 16, str);
 
+   mutex_lock(&dev->ctrl_handler.lock);
snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation 
%3d, hue %d ",
-   dev->brightness,
-   dev->contrast,
-   dev->saturation,
-   dev->hue);
+   dev->brightness->cur.val,
+   dev->contrast->cur.val,
+   dev->saturation->cur.val,
+   dev->hue->cur.val);
gen_text(dev, vbuf, line++ * 16, 16, str);
-   snprintf(str, sizeof(str), " volume %3d ", dev->volume);
+   snprintf(str, sizeof(str), " volume %3d ", dev->volume->cur.val);
gen_text(dev, vbuf, line++ * 16, 16, str);
+   snprintf(str, sizeof(str), " int32 %d, int64 %lld ",
+   dev->int32->cur.val,
+   dev->int64->cur.val64);
+   gen_text(dev, vbuf, line++ * 16, 16, str);
+   snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
+   dev->boolean->cur.val,
+   dev->menu->qmenu[dev->menu->cur.val],
+   dev->string->cur.string);
+   mutex_unlock(&dev->ctrl_handler.lock);
+   gen_text(dev, vbuf, line++ * 16, 16, str);
+   if (dev->button_pressed) {
+   dev->button_pressed--;
+   snprintf(str, sizeof(str), " button pressed!");
+   gen_text(dev, vbuf, line++ * 16, 16, str);
+   }
 
dev->mv_count += 2;
 
@@ -947,80 +972,14 @@ static int vidioc_s_input(struct file *file, void *priv, 
unsigned int i)
 }
 
 /* --- controls -- */
-static int vidioc_queryctrl(struct file *file, void *priv,
-   struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_AUDIO_VOLUME:
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200);
-   case V4L2_CID_BRIGHTNESS:
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
-   case V4L2_CID_CONTRAST:
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16);
-   case V4L2_CID_SATURATION:
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
-   case V4L2_CID_HUE:
-   return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
-   }
-   return -EINVAL;
-}
 
-static int vidioc_g_ctrl(struct file *file, void *priv,
-struct v4l2_control *ctrl)
+static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct vivi_dev *dev = video_drvdata(file);
+   struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, 
ctrl_handler);
 
-   switch (ctrl->id) {
-   case V4L2_CID_AUDIO_VOLUME:
-   ctrl->value = dev->volume;
-   return 0;
-   case V4L2_CID_BRIGHTNESS:
-   ctrl->value = dev->brightness;
-   return 0;
-   case V4L2_CID_CONTRAST:
-   ctrl->value = dev->contrast;
-   return 0;
-   case V4L2_CID_SATURATION:
-

[RFC/PATCH 04/19] adv7343: use control framework

2010-12-12 Thread Hans Verkuil
Also fixed a memory leak in the probe function if an error occurred.
The gain control range was also fixed (a proper range from -64 to 64).

Signed-off-by: Hans Verkuil 
---
 drivers/media/video/adv7343.c  |  167 +---
 drivers/media/video/adv7343_regs.h |8 +--
 2 files changed, 63 insertions(+), 112 deletions(-)

diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 41b2930..021fab2 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "adv7343_regs.h"
 
@@ -41,15 +42,13 @@ MODULE_PARM_DESC(debug, "Debug level 0-1");
 
 struct adv7343_state {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
u8 reg00;
u8 reg01;
u8 reg02;
u8 reg35;
u8 reg80;
u8 reg82;
-   int bright;
-   int hue;
-   int gain;
u32 output;
v4l2_std_id std;
 };
@@ -59,6 +58,11 @@ static inline struct adv7343_state *to_state(struct 
v4l2_subdev *sd)
return container_of(sd, struct adv7343_state, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct adv7343_state, hdl)->sd;
+}
+
 static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -268,111 +272,22 @@ static int adv7343_log_status(struct v4l2_subdev *sd)
return 0;
 }
 
-static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_BRIGHTNESS:
-   return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
-   ADV7343_BRIGHTNESS_MAX, 1,
-   ADV7343_BRIGHTNESS_DEF);
-   case V4L2_CID_HUE:
-   return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
-   ADV7343_HUE_MAX, 1 ,
-   ADV7343_HUE_DEF);
-   case V4L2_CID_GAIN:
-   return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
-   ADV7343_GAIN_MAX, 1,
-   ADV7343_GAIN_DEF);
-   default:
-   break;
-   }
-
-   return 0;
-}
-
-static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct adv7343_state *state = to_state(sd);
-   int err = 0;
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
-   ctrl->value > ADV7343_BRIGHTNESS_MAX) {
-   v4l2_dbg(1, debug, sd,
-   "invalid brightness settings %d\n",
-   ctrl->value);
-   return -ERANGE;
-   }
-
-   state->bright = ctrl->value;
-   err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
-   state->bright);
-   break;
-
-   case V4L2_CID_HUE:
-   if (ctrl->value < ADV7343_HUE_MIN ||
-   ctrl->value > ADV7343_HUE_MAX) {
-   v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
-   ctrl->value);
-   return -ERANGE;
-   }
-
-   state->hue = ctrl->value;
-   err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
-   break;
-
-   case V4L2_CID_GAIN:
-   if (ctrl->value < ADV7343_GAIN_MIN ||
-   ctrl->value > ADV7343_GAIN_MAX) {
-   v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
-   ctrl->value);
-   return -ERANGE;
-   }
-
-   if ((ctrl->value > POSITIVE_GAIN_MAX) &&
-   (ctrl->value < NEGATIVE_GAIN_MIN)) {
-   v4l2_dbg(1, debug, sd,
-   "gain settings not within the specified 
range\n");
-   return -ERANGE;
-   }
-
-   state->gain = ctrl->value;
-   err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
-   break;
-
-   default:
-   return -EINVAL;
-   }
-
-   if (err < 0)
-   v4l2_err(sd, "Failed to set the encoder controls\n");
-
-   return err;
-}
-
-static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct adv7343_state *state = to_state(sd);
+   struct v4l2_subdev *sd = to_sd(ctrl);
 
   

[RFC/PATCH 10/19] tlv320aic23b: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tlv320aic23b.c |   74 +++-
 1 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/drivers/media/video/tlv320aic23b.c 
b/drivers/media/video/tlv320aic23b.c
index dfc4dd7..286ec7e 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("tlv320aic23b driver");
 MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
 
 struct tlv320aic23b_state {
struct v4l2_subdev sd;
-   u8 muted;
+   struct v4l2_ctrl_handler hdl;
 };
 
 static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
@@ -49,6 +50,11 @@ static inline struct tlv320aic23b_state *to_state(struct 
v4l2_subdev *sd)
return container_of(sd, struct tlv320aic23b_state, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tlv320aic23b_state, hdl)->sd;
+}
+
 static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val)
 {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -85,44 +91,44 @@ static int tlv320aic23b_s_clock_freq(struct v4l2_subdev 
*sd, u32 freq)
return 0;
 }
 
-static int tlv320aic23b_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control 
*ctrl)
-{
-   struct tlv320aic23b_state *state = to_state(sd);
-
-   if (ctrl->id != V4L2_CID_AUDIO_MUTE)
-   return -EINVAL;
-   ctrl->value = state->muted;
-   return 0;
-}
-
-static int tlv320aic23b_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control 
*ctrl)
+static int tlv320aic23b_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct tlv320aic23b_state *state = to_state(sd);
-
-   if (ctrl->id != V4L2_CID_AUDIO_MUTE)
-   return -EINVAL;
-   state->muted = ctrl->value;
-   tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
-   /* set gain on both channels to +3.0 dB */
-   if (!state->muted)
-   tlv320aic23b_write(sd, 0, 0x119);
-   return 0;
+   struct v4l2_subdev *sd = to_sd(ctrl);
+
+   switch (ctrl->id) {
+   case V4L2_CID_AUDIO_MUTE:
+   tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
+   /* set gain on both channels to +3.0 dB */
+   if (!ctrl->val)
+   tlv320aic23b_write(sd, 0, 0x119);
+   return 0;
+   }
+   return -EINVAL;
 }
 
 static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
 {
struct tlv320aic23b_state *state = to_state(sd);
 
-   v4l2_info(sd, "Input: %s\n", state->muted ? "muted" : "active");
+   v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
return 0;
 }
 
 /* --- */
 
+static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
+   .s_ctrl = tlv320aic23b_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
.log_status = tlv320aic23b_log_status,
-   .g_ctrl = tlv320aic23b_g_ctrl,
-   .s_ctrl = tlv320aic23b_s_ctrl,
+   .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+   .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+   .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+   .g_ctrl = v4l2_subdev_g_ctrl,
+   .s_ctrl = v4l2_subdev_s_ctrl,
+   .queryctrl = v4l2_subdev_queryctrl,
+   .querymenu = v4l2_subdev_querymenu,
 };
 
 static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {
@@ -161,7 +167,6 @@ static int tlv320aic23b_probe(struct i2c_client *client,
return -ENOMEM;
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops);
-   state->muted = 0;
 
/* Initialize tlv320aic23b */
 
@@ -177,15 +182,30 @@ static int tlv320aic23b_probe(struct i2c_client *client,
tlv320aic23b_write(sd, 8, 0x000);
/* activate digital interface */
tlv320aic23b_write(sd, 9, 0x001);
+
+   v4l2_ctrl_handler_init(&state->hdl, 1);
+   v4l2_ctrl_new_std(&state->hdl, &tlv320aic23b_ctrl_ops,
+   V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
+   sd->ctrl_handler = &state->hdl;
+   if (state->hdl.error) {
+   int err = state->hdl.error;
+
+   v4l2_ctrl_handler_free(&state->hdl);
+   kfree(state);
+   return err;
+   }
+   v4l2_ctrl_handler_setup(&state->hdl);
return 0;
 }
 
 static int tlv320aic23b_remove(struct i2c_client *client)
 {
struct v4l2_subdev *sd = i2c_get_clientdata(client);
+   struct tlv320aic23b_state *state = to_state(sd);
 
v4l2_device_unregister_subdev(sd);
-   kfree(to_state(sd));
+   v4l2_ctrl_handler_free(&state->hdl);
+   kfree(state);
return 0;
 }
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to

[RFC/PATCH 09/19] tda9875: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tda9875.c |  192 -
 1 files changed, 57 insertions(+), 135 deletions(-)

diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 35b6ff5..6d8ff21 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 static int debug; /* insmod parameter */
@@ -38,8 +39,12 @@ MODULE_LICENSE("GPL");
 /* This is a superset of the TDA9875 */
 struct tda9875 {
struct v4l2_subdev sd;
-   int rvol, lvol;
-   int bass, treble;
+   struct v4l2_ctrl_handler hdl;
+   struct {
+   /* volume/balance cluster */
+   struct v4l2_ctrl *volume;
+   struct v4l2_ctrl *balance;
+   };
 };
 
 static inline struct tda9875 *to_state(struct v4l2_subdev *sd)
@@ -47,6 +52,11 @@ static inline struct tda9875 *to_state(struct v4l2_subdev 
*sd)
return container_of(sd, struct tda9875, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct tda9875, hdl)->sd;
+}
+
 #define dprintk  if (debug) printk
 
 /* The TDA9875 is made by Philips Semiconductor
@@ -134,28 +144,8 @@ static int i2c_read_register(struct i2c_client *client, 
int addr, int reg)
return read[0];
 }
 
-static void tda9875_set(struct v4l2_subdev *sd)
-{
-   struct tda9875 *tda = to_state(sd);
-   unsigned char a;
-
-   v4l2_dbg(1, debug, sd, "tda9875_set(%04x,%04x,%04x,%04x)\n",
-   tda->lvol, tda->rvol, tda->bass, tda->treble);
-
-   a = tda->lvol & 0xff;
-   tda9875_write(sd, TDA9875_MVL, a);
-   a =tda->rvol & 0xff;
-   tda9875_write(sd, TDA9875_MVR, a);
-   a =tda->bass & 0xff;
-   tda9875_write(sd, TDA9875_MBA, a);
-   a =tda->treble  & 0xff;
-   tda9875_write(sd, TDA9875_MTR, a);
-}
-
 static void do_tda9875_init(struct v4l2_subdev *sd)
 {
-   struct tda9875 *t = to_state(sd);
-
v4l2_dbg(1, debug, sd, "In tda9875_init\n");
tda9875_write(sd, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
tda9875_write(sd, TDA9875_MSR, 0x03);/* Monitor 0b0XXX*/
@@ -189,138 +179,49 @@ static void do_tda9875_init(struct v4l2_subdev *sd)
tda9875_write(sd, TDA9875_ATR, 0x00);   /* Aux Aigus Main 0dB*/
 
tda9875_write(sd, TDA9875_MUT, 0xcc);   /* General mute  */
-
-   t->lvol = t->rvol = 0;  /* 0dB */
-   t->bass = 0;/* 0dB */
-   t->treble = 0;  /* 0dB */
-   tda9875_set(sd);
 }
 
-
-static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int tda9875_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+   struct v4l2_subdev *sd = to_sd(ctrl);
struct tda9875 *t = to_state(sd);
+   int volume, balance, left, right;
 
switch (ctrl->id) {
case V4L2_CID_AUDIO_VOLUME:
-   {
-   int left = (t->lvol+84)*606;
-   int right = (t->rvol+84)*606;
-
-   ctrl->value=max(left,right);
-   return 0;
-   }
-   case V4L2_CID_AUDIO_BALANCE:
-   {
-   int left = (t->lvol+84)*606;
-   int right = (t->rvol+84)*606;
-   int volume = max(left,right);
-   int balance = (32768*min(left,right))/
- (volume ? volume : 1);
-   ctrl->value=(leftvolume->val + 84;
+   balance = t->balance->val;
+   left = (min(255 - balance, 128) * volume) / 128 - 84;
+   right = (min(balance, 128) * volume) / 128 - 84;
+   tda9875_write(sd, TDA9875_MVL, left);
+   tda9875_write(sd, TDA9875_MVR, right);
return 0;
-   }
case V4L2_CID_AUDIO_BASS:
-   ctrl->value = (t->bass+12)*2427;/* min -12 max +15 */
+   tda9875_write(sd, TDA9875_MBA, ctrl->val & 0x1f);
return 0;
case V4L2_CID_AUDIO_TREBLE:
-   ctrl->value = (t->treble+12)*2730;/* min -12 max +12 */
+   tda9875_write(sd, TDA9875_MTR, ctrl->val & 0x1f);
return 0;
}
return -EINVAL;
 }
 
-static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct tda9875 *t = to_state(sd);
-   int chvol = 0, volume = 0, balance = 0, left, right;
-
-   switch (ctrl->id) {
-   case V4L2_CID_AUDIO_VOLUME:
-   left = (t->lvol+84)*606;
-   right = (t->rvol+84)*606;
-
-   volume = max(left,right);
-   balance = (32768*min(left,right))/
- (volume ? volume : 1);
-   balance =(leftvalue;
-
-   chvol=1;
-   break;
-   case V4L2_CID_AUDIO_BALANCE:
-   left = (t->lvol+84)*606;
-   right = (t->rvol+84)*606;
-
-   volume=max(left

[RFC/PATCH 05/19] bt819: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/bt819.c |  129 --
 1 files changed, 49 insertions(+), 80 deletions(-)

diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index c38300f..f872044 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
@@ -52,16 +53,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 struct bt819 {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
unsigned char reg[32];
 
v4l2_std_id norm;
int ident;
int input;
int enable;
-   int bright;
-   int contrast;
-   int hue;
-   int sat;
 };
 
 static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
@@ -69,6 +67,11 @@ static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
return container_of(sd, struct bt819, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct bt819, hdl)->sd;
+}
+
 struct timing {
int hactive;
int hdelay;
@@ -333,71 +336,35 @@ static int bt819_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }
 
-static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_BRIGHTNESS:
-   v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
-   break;
-
-   case V4L2_CID_CONTRAST:
-   v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
-   break;
-
-   case V4L2_CID_SATURATION:
-   v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
-   break;
-
-   case V4L2_CID_HUE:
-   v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
-   break;
-
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
-static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+   struct v4l2_subdev *sd = to_sd(ctrl);
struct bt819 *decoder = to_bt819(sd);
int temp;
 
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
-   if (decoder->bright == ctrl->value)
-   break;
-   decoder->bright = ctrl->value;
-   bt819_write(decoder, 0x0a, decoder->bright);
+   bt819_write(decoder, 0x0a, ctrl->val);
break;
 
case V4L2_CID_CONTRAST:
-   if (decoder->contrast == ctrl->value)
-   break;
-   decoder->contrast = ctrl->value;
-   bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
-   bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 
0x01));
+   bt819_write(decoder, 0x0c, ctrl->val & 0xff);
+   bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
break;
 
case V4L2_CID_SATURATION:
-   if (decoder->sat == ctrl->value)
-   break;
-   decoder->sat = ctrl->value;
-   bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
-   bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
+   bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
+   bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
 
/* Ratio between U gain and V gain must stay the same as
   the ratio between the default U and V gain values. */
-   temp = (decoder->sat * 180) / 254;
+   temp = (ctrl->val * 180) / 254;
bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
break;
 
case V4L2_CID_HUE:
-   if (decoder->hue == ctrl->value)
-   break;
-   decoder->hue = ctrl->value;
-   bt819_write(decoder, 0x0f, decoder->hue);
+   bt819_write(decoder, 0x0f, ctrl->val);
break;
 
default:
@@ -406,29 +373,6 @@ static int bt819_s_ctrl(struct v4l2_subdev *sd, struct 
v4l2_control *ctrl)
return 0;
 }
 
-static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct bt819 *decoder = to_bt819(sd);
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   ctrl->value = decoder->bright;
-   break;
-   case V4L2_CID_CONTRAST:
-   ctrl->value = decoder->contrast;
-   break;
-   case V4L2_CID_SATURATION:
-   ctrl->value = decoder->sat;
-   break;
-   case V4L2_CID_HUE:
-   ctrl->value = decoder->hue;
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
 static int bt819_g_chip_ident(struct v4l2_

[RFC/PATCH 06/19] ov7670: use the control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/ov7670.c |  296 -
 1 files changed, 116 insertions(+), 180 deletions(-)

diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index c881a64..9d6458f 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ov7670.h"
 
@@ -191,9 +192,23 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 struct ov7670_format_struct;  /* coming later */
 struct ov7670_info {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
+   struct {
+   /* gain cluster */
+   struct v4l2_ctrl *auto_gain;
+   struct v4l2_ctrl *gain;
+   };
+   struct {
+   /* exposure cluster */
+   struct v4l2_ctrl *auto_exposure;
+   struct v4l2_ctrl *exposure;
+   };
+   struct {
+   /* saturation/hue cluster */
+   struct v4l2_ctrl *saturation;
+   struct v4l2_ctrl *hue;
+   };
struct ov7670_format_struct *fmt;  /* Current format */
-   unsigned char sat;  /* Saturation value */
-   int hue;/* Hue value */
int min_width;  /* Filter out smaller sizes */
int min_height; /* Filter out smaller sizes */
int clock_speed;/* External clock speed (MHz) */
@@ -206,6 +221,11 @@ static inline struct ov7670_info *to_state(struct 
v4l2_subdev *sd)
return container_of(sd, struct ov7670_info, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct ov7670_info, hdl)->sd;
+}
+
 
 
 /*
@@ -1043,23 +1063,23 @@ static int ov7670_cosine(int theta)
 
 
 static void ov7670_calc_cmatrix(struct ov7670_info *info,
-   int matrix[CMATRIX_LEN])
+   int matrix[CMATRIX_LEN], int sat, int hue)
 {
int i;
/*
 * Apply the current saturation setting first.
 */
for (i = 0; i < CMATRIX_LEN; i++)
-   matrix[i] = (info->fmt->cmatrix[i]*info->sat) >> 7;
+   matrix[i] = (info->fmt->cmatrix[i] * sat) >> 7;
/*
 * Then, if need be, rotate the hue value.
 */
-   if (info->hue != 0) {
+   if (hue != 0) {
int sinth, costh, tmpmatrix[CMATRIX_LEN];
 
memcpy(tmpmatrix, matrix, CMATRIX_LEN*sizeof(int));
-   sinth = ov7670_sine(info->hue);
-   costh = ov7670_cosine(info->hue);
+   sinth = ov7670_sine(hue);
+   costh = ov7670_cosine(hue);
 
matrix[0] = (matrix[3]*sinth + matrix[0]*costh)/1000;
matrix[1] = (matrix[4]*sinth + matrix[1]*costh)/1000;
@@ -1072,60 +1092,21 @@ static void ov7670_calc_cmatrix(struct ov7670_info 
*info,
 
 
 
-static int ov7670_s_sat(struct v4l2_subdev *sd, int value)
-{
-   struct ov7670_info *info = to_state(sd);
-   int matrix[CMATRIX_LEN];
-   int ret;
-
-   info->sat = value;
-   ov7670_calc_cmatrix(info, matrix);
-   ret = ov7670_store_cmatrix(sd, matrix);
-   return ret;
-}
-
-static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value)
-{
-   struct ov7670_info *info = to_state(sd);
-
-   *value = info->sat;
-   return 0;
-}
-
-static int ov7670_s_hue(struct v4l2_subdev *sd, int value)
+static int ov7670_s_sat_hue(struct v4l2_subdev *sd, int sat, int hue)
 {
struct ov7670_info *info = to_state(sd);
int matrix[CMATRIX_LEN];
int ret;
 
-   if (value < -180 || value > 180)
-   return -EINVAL;
-   info->hue = value;
-   ov7670_calc_cmatrix(info, matrix);
+   ov7670_calc_cmatrix(info, matrix, sat, hue);
ret = ov7670_store_cmatrix(sd, matrix);
return ret;
 }
 
 
-static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value)
-{
-   struct ov7670_info *info = to_state(sd);
-
-   *value = info->hue;
-   return 0;
-}
-
-
 /*
  * Some weird registers seem to store values in a sign/magnitude format!
  */
-static unsigned char ov7670_sm_to_abs(unsigned char v)
-{
-   if ((v & 0x80) == 0)
-   return v + 128;
-   return 128 - (v & 0x7f);
-}
-
 
 static unsigned char ov7670_abs_to_sm(unsigned char v)
 {
@@ -1147,40 +1128,11 @@ static int ov7670_s_brightness(struct v4l2_subdev *sd, 
int value)
return ret;
 }
 
-static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value)
-{
-   unsigned char v = 0;
-   int ret = ov7670_read(sd, REG_BRIGHT, &v);
-
-   *value = ov7670_sm_to_abs(v);
-   return ret;
-}
-
 static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
 {
return ov7670_write(sd, REG_CONTRAS, (unsigned char) value);
 }
 
-static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value)
-{
-   unsigned char v = 0;
-

[RFC/PATCH 02/19] tvaudio: use the control framework, fix vol/balance bugs

2010-12-12 Thread Hans Verkuil
Implement the control framework in tvaudio.

While doing that I noticed that the handling of balance was completely
broken. It's now fixed.

Signed-off-by: Hans Verkuil 
---
 drivers/media/video/tvaudio.c |  221 ++---
 1 files changed, 75 insertions(+), 146 deletions(-)

diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index a25e2b5..e1534f8 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -87,13 +88,13 @@ struct CHIPDESC {
audiocmd   init;
 
/* which register has which value */
-   intleftreg,rightreg,treblereg,bassreg;
+   intleftreg, rightreg, treblereg, bassreg;
 
-   /* initialize with (defaults to 65535/65535/32768/32768 */
-   intleftinit,rightinit,trebleinit,bassinit;
+   /* initialize with (defaults to 65535/32768/32768 */
+   intvolinit, trebleinit, bassinit;
 
/* functions to convert the values (v4l -> chip) */
-   getvalue volfunc,treblefunc,bassfunc;
+   getvalue volfunc, treblefunc, bassfunc;
 
/* get/set mode */
getmode  getmode;
@@ -109,6 +110,12 @@ struct CHIPDESC {
 /* current state of the chip */
 struct CHIPSTATE {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
+   struct {
+   /* volume/balance cluster */
+   struct v4l2_ctrl *volume;
+   struct v4l2_ctrl *balance;
+   };
 
/* chip-specific description - should point to
   an entry at CHIPDESC table */
@@ -118,7 +125,7 @@ struct CHIPSTATE {
audiocmd   shadow;
 
/* current settings */
-   __u16 left,right,treble,bass,muted,mode;
+   u16 muted, mode;
int prevmode;
int radio;
int input;
@@ -135,6 +142,11 @@ static inline struct CHIPSTATE *to_state(struct 
v4l2_subdev *sd)
return container_of(sd, struct CHIPSTATE, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct CHIPSTATE, hdl)->sd;
+}
+
 
 /* -- */
 /* i2c I/O functions  */
@@ -1450,8 +1462,7 @@ static struct CHIPDESC chiplist[] = {
.rightreg   = TDA9875_MVR,
.bassreg= TDA9875_MBA,
.treblereg  = TDA9875_MTR,
-   .leftinit   = 58880,
-   .rightinit  = 58880,
+   .volinit= 58880,
},
{
.name   = "tda9850",
@@ -1607,118 +1618,39 @@ static struct CHIPDESC chiplist[] = {
 
 /* -- */
 
-static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
-   struct v4l2_control *ctrl)
+static int tvaudio_s_ctrl(struct v4l2_ctrl *ctrl)
 {
+   struct v4l2_subdev *sd = to_sd(ctrl);
struct CHIPSTATE *chip = to_state(sd);
struct CHIPDESC *desc = chip->desc;
 
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
-   if (!(desc->flags & CHIP_HAS_INPUTSEL))
-   break;
-   ctrl->value=chip->muted;
-   return 0;
-   case V4L2_CID_AUDIO_VOLUME:
-   if (!(desc->flags & CHIP_HAS_VOLUME))
-   break;
-   ctrl->value = max(chip->left,chip->right);
-   return 0;
-   case V4L2_CID_AUDIO_BALANCE:
-   {
-   int volume;
-   if (!(desc->flags & CHIP_HAS_VOLUME))
-   break;
-   volume = max(chip->left,chip->right);
-   if (volume)
-   ctrl->value=(32768*min(chip->left,chip->right))/volume;
-   else
-   ctrl->value=32768;
-   return 0;
-   }
-   case V4L2_CID_AUDIO_BASS:
-   if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-   break;
-   ctrl->value = chip->bass;
-   return 0;
-   case V4L2_CID_AUDIO_TREBLE:
-   if (!(desc->flags & CHIP_HAS_BASSTREBLE))
-   break;
-   ctrl->value = chip->treble;
-   return 0;
-   }
-   return -EINVAL;
-}
-
-static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
-   struct v4l2_control *ctrl)
-{
-   struct CHIPSTATE *chip = to_state(sd);
-   struct CHIPDESC *desc = chip->desc;
-
-   switch (ctrl->id) {
-   case V4L2_CID_AUDIO_MUTE:
-   if (!(desc->flags & CHIP_HAS_INPUTSEL))
-   break;
-
-   if (ctrl->value < 0 || ctrl->value >= 2)
-   return -ERANGE;
-   chip->muted = ctrl->value;
+   chip->muted = ctrl->val;
if (chip->muted)

chip_write_ma

[RFC/PATCH 00/19] Convert subdevs to the control fw and related fixes

2010-12-12 Thread Hans Verkuil
This patch series converts a number of subdev drivers to use the control
framework. In addition, it also converts the cx18 and vivi drivers to the 
control
framework.

This has been tested with the vivi, cx18 and em28xx drivers.

As a result of these tests bugs relating to ENUM_INPUT/OUTPUT and some
incorrect checks in em28xx and the control framework were fixed.

It would be great if someone can check the tvaudio and tda drivers in
particular.

Regards,

Hans

Hans Verkuil (19):
  cs5345: use the control framework
  tvaudio: use the control framework, fix vol/balance bugs
  cx18: Use the control framework.
  adv7343: use control framework
  bt819: use control framework
  ov7670: use the control framework
  saa7110: use control framework
  tda7432: use control framework
  tda9875: use control framework
  tlv320aic23b: use control framework
  tvp514x: use the control framework
  tvp5150: use the control framework
  vpx3220: use control framework
  tvp7002: use control framework
  v4l2-ctrls: use const char * const * for the menu arrays
  vivi: convert to the control framework and add test controls.
  v4l: fix handling of v4l2_input.capabilities
  em28xx: fix incorrect s_ctrl error code and wrong call to res_free
  v4l2-ctrls: only check def for menu, integer and boolean controls

 drivers/media/dvb/ttpci/av7110_v4l.c   |4 +
 drivers/media/dvb/ttpci/budget-av.c|6 +-
 drivers/media/video/adv7343.c  |  167 ---
 drivers/media/video/adv7343_regs.h |8 +-
 drivers/media/video/bt819.c|  129 --
 drivers/media/video/cs5345.c   |   87 --
 drivers/media/video/cx18/cx18-av-audio.c   |   92 +--
 drivers/media/video/cx18/cx18-av-core.c|  162 ---
 drivers/media/video/cx18/cx18-av-core.h|   12 +-
 drivers/media/video/cx18/cx18-cards.c  |1 -
 drivers/media/video/cx18/cx18-controls.c   |  285 +++-
 drivers/media/video/cx18/cx18-controls.h   |7 +-
 drivers/media/video/cx18/cx18-driver.c |   30 ++-
 drivers/media/video/cx18/cx18-driver.h |2 +-
 drivers/media/video/cx18/cx18-fileops.c|   32 +--
 drivers/media/video/cx18/cx18-ioctl.c  |   24 +-
 drivers/media/video/cx18/cx18-mailbox.c|5 +-
 drivers/media/video/cx18/cx18-mailbox.h|5 -
 drivers/media/video/cx18/cx18-streams.c|   16 +-
 drivers/media/video/cx2341x.c  |8 +-
 drivers/media/video/cx23885/cx23885-video.c|1 -
 drivers/media/video/em28xx/em28xx-video.c  |   14 +-
 drivers/media/video/et61x251/et61x251_core.c   |1 +
 drivers/media/video/hexium_gemini.c|   18 +-
 drivers/media/video/hexium_orion.c |   18 +-
 drivers/media/video/ivtv/ivtv-cards.c  |2 -
 drivers/media/video/mxb.c  |8 +-
 drivers/media/video/ov7670.c   |  296 
 drivers/media/video/pvrusb2/pvrusb2-ctrl.c |6 +-
 drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h |2 +-
 drivers/media/video/saa7110.c  |  115 +++-
 drivers/media/video/saa7134/saa7134-video.c|1 -
 drivers/media/video/sn9c102/sn9c102_core.c |1 +
 drivers/media/video/tda7432.c  |  277 +++---
 drivers/media/video/tda9875.c  |  192 -
 drivers/media/video/timblogiw.c|1 -
 drivers/media/video/tlv320aic23b.c |   74 +++--
 drivers/media/video/tvaudio.c  |  221 +--
 drivers/media/video/tvp514x.c  |  236 
 drivers/media/video/tvp5150.c  |  157 +++
 drivers/media/video/tvp7002.c  |  117 +++-
 drivers/media/video/v4l2-common.c  |6 +-
 drivers/media/video/v4l2-ctrls.c   |   55 ++--
 drivers/media/video/vino.c |3 -
 drivers/media/video/vivi.c |  228 +--
 drivers/media/video/vpx3220.c  |  137 --
 drivers/media/video/zoran/zoran_driver.c   |6 -
 drivers/staging/cx25821/cx25821-video.c|2 -
 include/media/cx2341x.h|2 +-
 include/media/v4l2-common.h|6 +-
 include/media/v4l2-ctrls.h |4 +-
 51 files changed, 1203 insertions(+), 2086 deletions(-)

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


[RFC/PATCH 07/19] saa7110: use control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/saa7110.c |  115 
 1 files changed, 46 insertions(+), 69 deletions(-)

diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 7913f93..9966420 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
 MODULE_AUTHOR("Pauline Middelink");
@@ -53,15 +54,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
 struct saa7110 {
struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
u8 reg[SAA7110_NR_REG];
 
v4l2_std_id norm;
int input;
int enable;
-   int bright;
-   int contrast;
-   int hue;
-   int sat;
 
wait_queue_head_t wq;
 };
@@ -71,6 +69,11 @@ static inline struct saa7110 *to_saa7110(struct v4l2_subdev 
*sd)
return container_of(sd, struct saa7110, sd);
 }
 
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
+}
+
 /* --- */
 /* I2C support functions  */
 /* --- */
@@ -326,73 +329,22 @@ static int saa7110_s_stream(struct v4l2_subdev *sd, int 
enable)
return 0;
 }
 
-static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
-   switch (qc->id) {
-   case V4L2_CID_BRIGHTNESS:
-   return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
-   case V4L2_CID_CONTRAST:
-   case V4L2_CID_SATURATION:
-   return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
-   case V4L2_CID_HUE:
-   return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
-static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   struct saa7110 *decoder = to_saa7110(sd);
-
-   switch (ctrl->id) {
-   case V4L2_CID_BRIGHTNESS:
-   ctrl->value = decoder->bright;
-   break;
-   case V4L2_CID_CONTRAST:
-   ctrl->value = decoder->contrast;
-   break;
-   case V4L2_CID_SATURATION:
-   ctrl->value = decoder->sat;
-   break;
-   case V4L2_CID_HUE:
-   ctrl->value = decoder->hue;
-   break;
-   default:
-   return -EINVAL;
-   }
-   return 0;
-}
-
-static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   struct saa7110 *decoder = to_saa7110(sd);
+   struct v4l2_subdev *sd = to_sd(ctrl);
 
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
-   if (decoder->bright != ctrl->value) {
-   decoder->bright = ctrl->value;
-   saa7110_write(sd, 0x19, decoder->bright);
-   }
+   saa7110_write(sd, 0x19, ctrl->val);
break;
case V4L2_CID_CONTRAST:
-   if (decoder->contrast != ctrl->value) {
-   decoder->contrast = ctrl->value;
-   saa7110_write(sd, 0x13, decoder->contrast);
-   }
+   saa7110_write(sd, 0x13, ctrl->val);
break;
case V4L2_CID_SATURATION:
-   if (decoder->sat != ctrl->value) {
-   decoder->sat = ctrl->value;
-   saa7110_write(sd, 0x12, decoder->sat);
-   }
+   saa7110_write(sd, 0x12, ctrl->val);
break;
case V4L2_CID_HUE:
-   if (decoder->hue != ctrl->value) {
-   decoder->hue = ctrl->value;
-   saa7110_write(sd, 0x07, decoder->hue);
-   }
+   saa7110_write(sd, 0x07, ctrl->val);
break;
default:
return -EINVAL;
@@ -409,11 +361,19 @@ static int saa7110_g_chip_ident(struct v4l2_subdev *sd, 
struct v4l2_dbg_chip_ide
 
 /* --- */
 
+static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
+   .s_ctrl = saa7110_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops saa7110_core_ops = {
.g_chip_ident = saa7110_g_chip_ident,
-   .g_ctrl = saa7110_g_ctrl,
-   .s_ctrl = saa7110_s_ctrl,
-   .queryctrl = saa7110_queryctrl,
+   .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+   .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+   .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+   .g_ctrl = v4l2_subdev_g_ctrl,
+   .s_ctrl = v4l2_subdev_s_ctrl,
+   .queryctrl = v4l2_subdev_queryctrl,
+   .querymenu = v4l2_subdev_querymenu,
.s_std = saa7110_s_std,

[RFC/PATCH 01/19] cs5345: use the control framework

2010-12-12 Thread Hans Verkuil
Signed-off-by: Hans Verkuil 
---
 drivers/media/video/cs5345.c |   87 -
 1 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 9358fe7..5909f25 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
 MODULE_AUTHOR("Hans Verkuil");
@@ -36,6 +37,20 @@ module_param(debug, bool, 0644);
 
 MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
 
+struct cs5345_state {
+   struct v4l2_subdev sd;
+   struct v4l2_ctrl_handler hdl;
+};
+
+static inline struct cs5345_state *to_state(struct v4l2_subdev *sd)
+{
+   return container_of(sd, struct cs5345_state, sd);
+}
+
+static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
+{
+   return &container_of(ctrl->handler, struct cs5345_state, hdl)->sd;
+}
 
 /* --- */
 
@@ -65,33 +80,20 @@ static int cs5345_s_routing(struct v4l2_subdev *sd,
return 0;
 }
 
-static int cs5345_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-   if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
-   ctrl->value = (cs5345_read(sd, 0x04) & 0x08) != 0;
-   return 0;
-   }
-   if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
-   return -EINVAL;
-   ctrl->value = cs5345_read(sd, 0x07) & 0x3f;
-   if (ctrl->value >= 32)
-   ctrl->value = ctrl->value - 64;
-   return 0;
-}
+   struct v4l2_subdev *sd = to_sd(ctrl);
 
-static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
-   if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
-   cs5345_write(sd, 0x04, ctrl->value ? 0x80 : 0);
+   switch (ctrl->id) {
+   case V4L2_CID_AUDIO_MUTE:
+   cs5345_write(sd, 0x04, ctrl->val ? 0x80 : 0);
+   return 0;
+   case V4L2_CID_AUDIO_VOLUME:
+   cs5345_write(sd, 0x07, ((u8)ctrl->val) & 0x3f);
+   cs5345_write(sd, 0x08, ((u8)ctrl->val) & 0x3f);
return 0;
}
-   if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
-   return -EINVAL;
-   if (ctrl->value > 24 || ctrl->value < -24)
-   return -EINVAL;
-   cs5345_write(sd, 0x07, ((u8)ctrl->value) & 0x3f);
-   cs5345_write(sd, 0x08, ((u8)ctrl->value) & 0x3f);
-   return 0;
+   return -EINVAL;
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -144,11 +146,20 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
 
 /* --- */
 
+static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
+   .s_ctrl = cs5345_s_ctrl,
+};
+
 static const struct v4l2_subdev_core_ops cs5345_core_ops = {
.log_status = cs5345_log_status,
.g_chip_ident = cs5345_g_chip_ident,
-   .g_ctrl = cs5345_g_ctrl,
-   .s_ctrl = cs5345_s_ctrl,
+   .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+   .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+   .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+   .g_ctrl = v4l2_subdev_g_ctrl,
+   .s_ctrl = v4l2_subdev_s_ctrl,
+   .queryctrl = v4l2_subdev_queryctrl,
+   .querymenu = v4l2_subdev_querymenu,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cs5345_g_register,
.s_register = cs5345_s_register,
@@ -169,6 +180,7 @@ static const struct v4l2_subdev_ops cs5345_ops = {
 static int cs5345_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
+   struct cs5345_state *state;
struct v4l2_subdev *sd;
 
/* Check if the adapter supports the needed features */
@@ -178,11 +190,28 @@ static int cs5345_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
 
-   sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
-   if (sd == NULL)
+   state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
+   if (state == NULL)
return -ENOMEM;
+   sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &cs5345_ops);
 
+   v4l2_ctrl_handler_init(&state->hdl, 2);
+   v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
+   V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
+   v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
+   V4L2_CID_AUDIO_VOLUME, -24, 24, 1, 0);
+   sd->ctrl_handler = &state->hdl;
+   if (state->hdl.error) {
+   int err = state->hdl.error;
+
+   v4l2_ctrl_handler_free(&state->hdl);
+   kfree(state);
+   return err;
+   }
+   /* set volume/mute */
+   v4l2_ctrl_handler_setup(&state->hdl);
+
cs5345_write(sd, 0x02, 0x00);
cs5345_write(sd, 0x04

[patch v2] [media] bttv: take correct lock in bttv_open()

2010-12-12 Thread Dan Carpenter
We're trying to make sure that no one is writing to the btv->init struct
while we copy it over to the newly allocated "fh" struct.  The original
code doesn't make sense because "fh->cap.vb_lock" hasn't been
initialized and no one else can be writing to it anyway.

Addresses: https://bugzilla.kernel.org/show_bug.cgi?id=24602 

Signed-off-by: Dan Carpenter 
---
Sergej could you test this one?

diff --git a/drivers/media/video/bt8xx/bttv-driver.c 
b/drivers/media/video/bt8xx/bttv-driver.c
index a529619..6c8f4b0 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3302,9 +3302,9 @@ static int bttv_open(struct file *file)
 * Let's first copy btv->init at fh, holding cap.vb_lock, and then work
 * with the rest of init, holding btv->lock.
 */
-   mutex_lock(&fh->cap.vb_lock);
+   mutex_lock(&btv->init.cap.vb_lock);
*fh = btv->init;
-   mutex_unlock(&fh->cap.vb_lock);
+   mutex_unlock(&btv->init.cap.vb_lock);
 
fh->type = type;
fh->ov.setup_ok = 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] bttv: fix mutex use before init

2010-12-12 Thread Torsten Kaiser
On Sun, Dec 12, 2010 at 2:15 PM, Dave Young  wrote:
> oops happen in bttv_open while locking uninitialized mutex fh->cap.vb_lock
> add mutex_init before usage

I have seen the same problem twice since I switched of the BKL in
2.6.37-rc2, but only had the time today to search for the cause.
(It only happend on two boots out of probably more then 50, so I only
investigated after it happened a second time with -rc5)

The cause was making this change to bttv_open() and radio_open() to
remove the BKL from them:
+   mutex_lock(&fh->cap.vb_lock);
*fh = btv->init;
+   mutex_unlock(&fh->cap.vb_lock);

This is wrong because of two things:
First: The fh->cap.vb_lock has not been initialised, as you noted.
Second: The middle line will overwrite the mutex!

Just adding mutex_init() will not really help the second problem and
seems to be wrong from the point that cap.vb_lock already has a
mutex_init() via videobuf_queue_sg_init().

I'm not sure what the correct fix is, but I would rather suggest this:

 * change &fh->cap.vb_lock in bttv_open() AND radio_open() to
&btv->init.cap.vb_lock
 * add a mutex_init(&btv->init.cap.vb_lock) to the setup of init in bttv_probe()

> Signed-off-by: Dave Young 
> Tested-by: Chris Clayton 
> ---
>  drivers/media/video/bt8xx/bttv-driver.c |    2 ++
>  1 file changed, 2 insertions(+)
>
> --- linux-2.6.orig/drivers/media/video/bt8xx/bttv-driver.c      2010-11-27 
> 11:21:30.0 +0800
> +++ linux-2.6/drivers/media/video/bt8xx/bttv-driver.c   2010-12-12 
> 16:31:39.63338 +0800
> @@ -3291,6 +3291,8 @@ static int bttv_open(struct file *file)
>        fh = kmalloc(sizeof(*fh), GFP_KERNEL);
>        if (unlikely(!fh))
>                return -ENOMEM;
> +
> +       mutex_init(&fh->cap.vb_lock);
>        file->private_data = fh;
>
>        /*
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] bttv: fix mutex use before init

2010-12-12 Thread Dave Young
oops happen in bttv_open while locking uninitialized mutex fh->cap.vb_lock
add mutex_init before usage

Signed-off-by: Dave Young 
Tested-by: Chris Clayton 
---
 drivers/media/video/bt8xx/bttv-driver.c |2 ++
 1 file changed, 2 insertions(+)

--- linux-2.6.orig/drivers/media/video/bt8xx/bttv-driver.c  2010-11-27 
11:21:30.0 +0800
+++ linux-2.6/drivers/media/video/bt8xx/bttv-driver.c   2010-12-12 
16:31:39.63338 +0800
@@ -3291,6 +3291,8 @@ static int bttv_open(struct file *file)
fh = kmalloc(sizeof(*fh), GFP_KERNEL);
if (unlikely(!fh))
return -ENOMEM;
+
+   mutex_init(&fh->cap.vb_lock);
file->private_data = fh;
 
/*
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Oops in 2.6.37-rc{3,4,5}

2010-12-12 Thread Chris Clayton
On Sunday 12 December 2010, Dave Young wrote:
> On Fri, Dec 10, 2010 at 10:34:06PM +, Chris Clayton wrote:
> > I'm not subscribed, so please cc me on any reply.
> >
> > With rc kernels from 2.6.37, X frequently (approx 3 boots out of every 4)
> > fails to start. dmesg shows the oops below. I can bisect over the weekend
> > - probably Sunday - if no answer comes up in the meantime. I get the same
> > oops with rc3, rc and rc5. rc2 doesn't get as far as trying to start X.
> > Happy to test patches or provide additional diagnostics, but I'll be off
> > line soon until 20:00 or so UK time tomorrow.



> >
> > [drm] Initialized i915 1.6.0 20080730 for :00:02.0 on minor 0
> > BUG: unable to handle kernel NULL pointer dereference at   (null)
> > IP: [] __mutex_lock_slowpath+0x9f/0x170
> > *pdpt = 34676001 *pde = 
> > Oops: 0002 [#1] PREEMPT SMP
> > last sysfs file: /sys/module/drm_kms_helper/initstate
> > Modules linked in: i915 drm_kms_helper drm fb fbdev cfbcopyarea video
> > backlight output cfbimgblt cfbfillrect xt_state iptable_filter
> > ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_conntrack
> > nf_defrag_ipv4 saa7134_alsa tda10048 saa7134_dvb videobuf_dvb dvb_core
> > mt20xx tea5767 tda9887 msp3400 gspca_zc3xx gspca_main tda18271 tda8290
> > ir_lirc_codec tuner lirc_dev bttv i2c_algo_bit btcx_risc snd_bt87x
> > ir_common uhci_hcd ir_core saa7134 v4l2_common videodev v4l1_compat
> > ehci_hcd videobuf_dma_sg videobuf_core tveeprom evdev [last unloaded:
> > floppy]
> >
> > Pid: 1725, comm: X Not tainted 2.6.37-rc5+ #476 EG41MF-US2H/EG41MF-US2H
> > EIP: 0060:[] EFLAGS: 00013246 CPU: 3
> > EIP is at __mutex_lock_slowpath+0x9f/0x170
> > EAX:  EBX: f4403410 ECX: f4403420 EDX: f4641dd8
> > ESI: f4403414 EDI:  EBP: f4403418 ESP: f4641dd4
> >  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> > Process X (pid: 1725, ti=f464 task=f3c67390 task.ti=f464)
> > Stack:
> >  f3c67390 f4403418  f46a3800 f4403410 f4fd14f0 f425f600 f4403400
> >  c13228a6 f4fd1000 f4fd14f0 f8841b6c c10aabb2  0514 f4c34000
> >  f4df72c0 c10aabf7 f4403410 0001 f425f600 ffed f425f604 f46bfe40
> > Call Trace:
> >  [] ? mutex_lock+0x16/0x30
> >  [] ? bttv_open+0xac/0x280 [bttv]
> >  [] ? cdev_get+0x52/0x90
> >  [] ? exact_lock+0x7/0x10
> >  [] ? v4l2_open+0xb7/0xd0 [videodev]
> >  [] ? chrdev_open+0xda/0x1b0
> >  [] ? __dentry_open+0xd5/0x280
> >  [] ? nameidata_to_filp+0x68/0x70
> >  [] ? chrdev_open+0x0/0x1b0
> >  [] ? do_last.clone.32+0x34f/0x5a0
> >  [] ? do_filp_open+0x383/0x550
> >  [] ? getname+0x28/0xf0
> >  [] ? do_sys_open+0x58/0x110
> >  [] ? filp_close+0x49/0x70
> >  [] ? sys_open+0x2c/0x40
> >  [] ? sysenter_do_call+0x12/0x26
> >  [] ? timer_cpu_notify+0x1b4/0x233
> > Code: 83 78 18 63 7f b6 8d b6 00 00 00 00 8d 73 04 8d 6b 08 89 f0 e8 f3
> > 10 00 00 8b 43 0c 8d 54 24 04 89 44 24 08 89 53 0c 89 6c 24 04 <89> 10 8b
> > 04 24 ba ff ff ff ff 89 44 24 0c 89 d0 87 03 83 f8 01
> > EIP: [] __mutex_lock_slowpath+0x9f/0x170 SS:ESP 0068:f4641dd4
> > CR2: 
> > ---[ end trace 5ac4e44ad0dc7959 ]---



> Could you try following patch?
>
> --- linux-2.6.orig/drivers/media/video/bt8xx/bttv-driver.c2010-11-27
> 11:21:30.0 +0800 +++
> linux-2.6/drivers/media/video/bt8xx/bttv-driver.c 2010-12-12
> 16:31:39.63338 +0800 @@ -3291,6 +3291,8 @@ static int bttv_open(struct
> file *file)
>   fh = kmalloc(sizeof(*fh), GFP_KERNEL);
>   if (unlikely(!fh))
>   return -ENOMEM;
> +
> + mutex_init(&fh->cap.vb_lock);
>   file->private_data = fh;
>
>   /*

Yes Dave, that's fixed it thanks. Six successful boots, which never happened 
without the patch.

Tested-by: Chris Clayton 

-- 
The more I see, the more I know. The more I know, the less I understand. 
Changing Man - Paul Weller
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Oops in 2.6.37-rc{3,4,5}

2010-12-12 Thread Dave Young
On Fri, Dec 10, 2010 at 10:34:06PM +, Chris Clayton wrote:
> I'm not subscribed, so please cc me on any reply.
> 
> With rc kernels from 2.6.37, X frequently (approx 3 boots out of every 4) 
> fails 
> to start. dmesg shows the oops below. I can bisect over the weekend - 
> probably 
> Sunday - if no answer comes up in the meantime. I get the same oops with rc3, 
> rc and rc5. rc2 doesn't get as far as trying to start X. Happy to test 
> patches 
> or provide additional diagnostics, but I'll be off line soon until 20:00 or 
> so 
> UK time tomorrow.
> 
> The hardware in my system is:
> 00:00.0 Host bridge: Intel Corporation 4 Series Chipset DRAM Controller (rev 
> 03)
> 00:02.0 VGA compatible controller: Intel Corporation 4 Series Chipset 
> Integrated 
> Graphics Controller (rev 03)
> 00:02.1 Display controller: Intel Corporation 4 Series Chipset Integrated 
> Graphics Controller (rev 03)
> 00:1b.0 Audio device: Intel Corporation 82801G (ICH7 Family) High Definition 
> Audio Controller (rev 01)
> 00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 1 
> (rev 01)
> 00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express Port 2 
> (rev 01)
> 00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI 
> Controller #1 (rev 01)
> 00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI 
> Controller #2 (rev 01)
> 00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI 
> Controller #3 (rev 01)
> 00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB UHCI 
> Controller #4 (rev 01)
> 00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2 EHCI 
> Controller (rev 01)
> 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev e1)
> 00:1f.0 ISA bridge: Intel Corporation 82801GB/GR (ICH7 Family) LPC Interface 
> Bridge (rev 01)
> 00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE Controller 
> (rev 01)
> 00:1f.2 IDE interface: Intel Corporation 82801GB/GR/GH (ICH7 Family) SATA IDE 
> Controller (rev 01)
> 00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 
> 01)
> 02:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B 
> PCI 
> Express Gigabit Ethernet controller (rev 02)
> 03:00.0 Multimedia controller: Philips Semiconductors SAA7131/SAA7133/SAA7135 
> Video Broadcast Decoder (rev d1)
> 03:01.0 Multimedia video controller: Brooktree Corporation Bt878 Video 
> Capture 
> (rev 11)
> 03:01.1 Multimedia controller: Brooktree Corporation Bt878 Audio Capture (rev 
> 11)
> 03:07.0 FireWire (IEEE 1394): Texas Instruments TSB43AB23 IEEE-1394a-2000 
> Controller (PHY/Link)
> 
> ==OOPS==
> 
> 
> [drm] Initialized i915 1.6.0 20080730 for :00:02.0 on minor 0
> BUG: unable to handle kernel NULL pointer dereference at   (null)
> IP: [] __mutex_lock_slowpath+0x9f/0x170
> *pdpt = 34676001 *pde =  
> Oops: 0002 [#1] PREEMPT SMP 
> last sysfs file: /sys/module/drm_kms_helper/initstate
> Modules linked in: i915 drm_kms_helper drm fb fbdev cfbcopyarea video 
> backlight 
> output cfbimgblt cfbfillrect xt_state iptable_filter ipt_MASQUERADE 
> iptable_nat 
> nf_nat nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 saa7134_alsa tda10048 
> saa7134_dvb videobuf_dvb dvb_core mt20xx tea5767 tda9887 msp3400 gspca_zc3xx 
> gspca_main tda18271 tda8290 ir_lirc_codec tuner lirc_dev bttv i2c_algo_bit 
> btcx_risc snd_bt87x ir_common uhci_hcd ir_core saa7134 v4l2_common videodev 
> v4l1_compat ehci_hcd videobuf_dma_sg videobuf_core tveeprom evdev [last 
> unloaded: floppy]
> 
> Pid: 1725, comm: X Not tainted 2.6.37-rc5+ #476 EG41MF-US2H/EG41MF-US2H
> EIP: 0060:[] EFLAGS: 00013246 CPU: 3
> EIP is at __mutex_lock_slowpath+0x9f/0x170
> EAX:  EBX: f4403410 ECX: f4403420 EDX: f4641dd8
> ESI: f4403414 EDI:  EBP: f4403418 ESP: f4641dd4
>  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> Process X (pid: 1725, ti=f464 task=f3c67390 task.ti=f464)
> Stack:
>  f3c67390 f4403418  f46a3800 f4403410 f4fd14f0 f425f600 f4403400
>  c13228a6 f4fd1000 f4fd14f0 f8841b6c c10aabb2  0514 f4c34000
>  f4df72c0 c10aabf7 f4403410 0001 f425f600 ffed f425f604 f46bfe40
> Call Trace:
>  [] ? mutex_lock+0x16/0x30
>  [] ? bttv_open+0xac/0x280 [bttv]
>  [] ? cdev_get+0x52/0x90
>  [] ? exact_lock+0x7/0x10
>  [] ? v4l2_open+0xb7/0xd0 [videodev]
>  [] ? chrdev_open+0xda/0x1b0
>  [] ? __dentry_open+0xd5/0x280
>  [] ? nameidata_to_filp+0x68/0x70
>  [] ? chrdev_open+0x0/0x1b0
>  [] ? do_last.clone.32+0x34f/0x5a0
>  [] ? do_filp_open+0x383/0x550
>  [] ? getname+0x28/0xf0
>  [] ? do_sys_open+0x58/0x110
>  [] ? filp_close+0x49/0x70
>  [] ? sys_open+0x2c/0x40
>  [] ? sysenter_do_call+0x12/0x26
>  [] ? timer_cpu_notify+0x1b4/0x233
> Code: 83 78 18 63 7f b6 8d b6 00 00 00 00 8d 73 04 8d 6b 08 89 f0 e8 f3 10 00 
> 00 
> 8b 43 0c 8d 54 24 04 89 44 24 08 89 53 0c 89 6c 24 04 <89> 10 8b 04 24 ba ff 
> ff 
> ff f