RE: [PATCH - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-17 Thread Nori, Sekhar
On Wed, Dec 16, 2009 at 13:11:57, Hans Verkuil wrote:
 On Wednesday 16 December 2009 00:37:52 Karicheri, Muralidharan wrote:
  Hans,
 
  I remember there was a comment against an earlier patch that asks
  for combining such statements since it makes the function appear
  as big. Not sure who had made that comment. That is the reason you
  find code like this in this patch. It was initially done with multiple
  OR statements to construct the value to be written to the register as you 
  stated below as
 
  val = bc-horz.win_count_calc 
 ISIF_HORZ_BC_WIN_COUNT_MASK;
  val |= !!bc-horz.base_win_sel_calc 
 ISIF_HORZ_BC_WIN_SEL_SHIFT;
 
  I have checked few other drivers such as bt819.c ir-kbd-i2c.c,
  mt9m111.c etc, where similar statements are found, but they have used 
  hardcoded values masks which makes it appears less complex. But I
  like to reduce magic numbers as much possible in the code.

 Personally I have mixed feelings about the use for symbolic names for things
 like this. The problem is that they do not help me understanding the code.
 The names tend to be long, leading to these broken up lines, and if I want
 to know how the bits are distributed in the value I continuously have to
 do the look up in the header containing these defines.

 Frankly, I have a similar problem with using symbolic names for registers.
 Every time I need to look up a register in the datasheet I first need to
 look up the register number the register name maps to. All datasheets seem
 to be organized around the register addresses and there rarely is a datasheet
 that has an index of symbolic names.

 Using hard-coded numbers together with a well written comment tends to be much
 more readable in my opinion. I don't really think there is anything magic 
 about
 these numbers: these are exactly the numbers that I need to know whenever I
 have to deal with the datasheet. Having to go through a layer of obfuscation
 is just plain irritating to me.

 However, I seem to be a minority when it comes to this and I've given up
 arguing for this...

 Note that all this assumes that the datasheet is publicly available. If it
 is a reversed engineered driver or based on NDA datasheets only, then the
 symbolic names may be all there is to make you understand what is going on.


[...]


 That seems overkill. I actually think it can be improved a lot by visually
 grouping the lines:

  val = (bc-horz.win_count_calc 
  ISIF_HORZ_BC_WIN_COUNT_MASK) |
((!!bc-horz.base_win_sel_calc) 
  ISIF_HORZ_BC_WIN_SEL_SHIFT) |
((!!bc-horz.clamp_pix_limit) 
  ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
((bc-horz.win_h_sz_calc 
  ISIF_HORZ_BC_WIN_H_SIZE_MASK) 
  ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
((bc-horz.win_v_sz_calc 
  ISIF_HORZ_BC_WIN_V_SIZE_MASK) 
  ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);

 Now I can at least see the various values that are ORed.


I liked this piece of code from drivers/mtd/nand/s3c2410.c. Serves as
a good template to do this sort of thing.

#define S3C2410_NFCONF_TACLS(x)((x)8)
#define S3C2410_NFCONF_TWRPH0(x)   ((x)4)
#define S3C2410_NFCONF_TWRPH1(x)   ((x)0)

[Okay, spaces around '', please :)]

[...]

if (plat != NULL) {
tacls = s3c_nand_calc_rate(plat-tacls, clkrate, tacls_max);
twrph0 = s3c_nand_calc_rate(plat-twrph0, clkrate, 8);
twrph1 = s3c_nand_calc_rate(plat-twrph1, clkrate, 8);
}

[...]

mask = (S3C2410_NFCONF_TACLS(3) |
S3C2410_NFCONF_TWRPH0(7) |
S3C2410_NFCONF_TWRPH1(7));
set = S3C2410_NFCONF_EN;
set |= S3C2410_NFCONF_TACLS(tacls - 1);
set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

[...]

cfg = readl(info-regs + S3C2410_NFCONF);
cfg = ~mask;
cfg |= set;
writel(cfg, info-regs + S3C2410_NFCONF);

And Murali said:

 Huh? That does not explain why apparently bc-horz.win_h_sz_calc can be
 larger
 than ISIF_HORZ_BC_WIN_H_SIZE_MASK.
 because the values come from the user and since we can't use the enum
 for the types, I have to make sure the value is within range. Other way
 to do is to check the value in the validate() function. I am inclined to
 do the validation so that the  statements with masks can be removed while 
 setting it in
 the register.

Agree fully here. Either a separate validate function or
an if check before using the values. Results with masking
or without masking are both unpredictable.

Thanks,
Sekhar

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More 

RE: [PATCH - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-16 Thread Karicheri, Muralidharan
hans,


 Yes, isif_config_bclamp() set values in the register.

Huh? That does not explain why apparently bc-horz.win_h_sz_calc can be
larger
than ISIF_HORZ_BC_WIN_H_SIZE_MASK.
because the values come from the user and since we can't use the enum
for the types, I have to make sure the value is within range. Other way
to do is to check the value in the validate() function. I am inclined to
do the validation so that the  statements with masks can be removed while 
setting it in the register.


Regards,

   Hans


 
 It would be interesting to know if people know of good ways of making
 awkward
 code like this more elegant (or at least less awkward).
 
 Regards,
 
 Hans
 
 --
 Hans Verkuil - video4linux developer - sponsored by TANDBERG



--
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
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 - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-15 Thread Hans Verkuil
On Thursday 10 December 2009 18:00:29 m-kariche...@ti.com wrote:
 From: Muralidharan Karicheri m-kariche...@ti.com
 
 Added a experimental IOCTL, to read the CCDC parameters.
 Default handler was not getting the original pointer from the core.
 So a wrapper function added to handle the default handler properly.
 Also fixed a bug in the probe() in the linux-next tree
 
 Signed-off-by: Muralidharan Karicheri m-kariche...@ti.com
 ---
  drivers/media/video/davinci/vpfe_capture.c |  119 
 +---
  include/media/davinci/vpfe_capture.h   |   12 ++-
  2 files changed, 81 insertions(+), 50 deletions(-)
 
 diff --git a/drivers/media/video/davinci/vpfe_capture.c 
 b/drivers/media/video/davinci/vpfe_capture.c
 index 091750e..8c6d856 100644
 --- a/drivers/media/video/davinci/vpfe_capture.c
 +++ b/drivers/media/video/davinci/vpfe_capture.c
 @@ -759,12 +759,83 @@ static unsigned int vpfe_poll(struct file *file, 
 poll_table *wait)
   return 0;
  }
  
 +static long vpfe_param_handler(struct file *file, void *priv,
 + int cmd, void *param)
 +{
 + struct vpfe_device *vpfe_dev = video_drvdata(file);
 + int ret = 0;
 +
 + v4l2_dbg(1, debug, vpfe_dev-v4l2_dev, vpfe_param_handler\n);
 +
 + if (NULL == param) {
 + v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
 + Invalid user ptr\n);

Shouldn't there be an error return here? It looks weird.

 + }
 +
 + if (vpfe_dev-started) {
 + /* only allowed if streaming is not started */
 + v4l2_err(vpfe_dev-v4l2_dev, device already started\n);
 + return -EBUSY;
 + }
 +
 +
 + switch (cmd) {
 + case VPFE_CMD_S_CCDC_RAW_PARAMS:
 + v4l2_warn(vpfe_dev-v4l2_dev,
 +   VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n);
 + ret = mutex_lock_interruptible(vpfe_dev-lock);
 + if (ret)
 + return ret;
 + ret = ccdc_dev-hw_ops.set_params(param);
 + if (ret) {
 + v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
 + Error in setting parameters in CCDC\n);
 + goto unlock_out;
 + }
 +
 + if (vpfe_get_ccdc_image_format(vpfe_dev, vpfe_dev-fmt)  0) {
 + v4l2_err(vpfe_dev-v4l2_dev,
 + Invalid image format at CCDC\n);
 + ret = -EINVAL;
 + }
 +unlock_out:
 + mutex_unlock(vpfe_dev-lock);
 + break;
 + case VPFE_CMD_G_CCDC_RAW_PARAMS:
 + v4l2_warn(vpfe_dev-v4l2_dev,
 +   VPFE_CMD_G_CCDC_RAW_PARAMS: experimental ioctl\n);
 + if (!ccdc_dev-hw_ops.get_params) {
 + ret = -EINVAL;
 + break;
 + }
 + ret = ccdc_dev-hw_ops.get_params(param);
 + if (ret) {
 + v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
 + Error in getting parameters from CCDC\n);
 + }
 + break;
 +
 + default:
 + ret = -EINVAL;

Please add a break statement here.

 + }
 + return ret;
 +}
 +
 +static long vpfe_ioctl(struct file *file, unsigned int cmd, unsigned long 
 arg)
 +{
 + if (cmd == VPFE_CMD_S_CCDC_RAW_PARAMS ||
 + cmd == VPFE_CMD_G_CCDC_RAW_PARAMS)
 + return vpfe_param_handler(file, file-private_data, cmd,
 +  (void *)arg);
 + return video_ioctl2(file, cmd, arg);
 +}
 +
  /* vpfe capture driver file operations */
  static const struct v4l2_file_operations vpfe_fops = {
   .owner = THIS_MODULE,
   .open = vpfe_open,
   .release = vpfe_release,
 - .unlocked_ioctl = video_ioctl2,
 + .unlocked_ioctl = vpfe_ioctl,
   .mmap = vpfe_mmap,
   .poll = vpfe_poll
  };
 @@ -1682,50 +1753,6 @@ unlock_out:
   return ret;
  }
  
 -
 -static long vpfe_param_handler(struct file *file, void *priv,
 - int cmd, void *param)
 -{
 - struct vpfe_device *vpfe_dev = video_drvdata(file);
 - int ret = 0;
 -
 - v4l2_dbg(1, debug, vpfe_dev-v4l2_dev, vpfe_param_handler\n);
 -
 - if (vpfe_dev-started) {
 - /* only allowed if streaming is not started */
 - v4l2_err(vpfe_dev-v4l2_dev, device already started\n);
 - return -EBUSY;
 - }
 -
 - ret = mutex_lock_interruptible(vpfe_dev-lock);
 - if (ret)
 - return ret;
 -
 - switch (cmd) {
 - case VPFE_CMD_S_CCDC_RAW_PARAMS:
 - v4l2_warn(vpfe_dev-v4l2_dev,
 -   VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n);
 - ret = ccdc_dev-hw_ops.set_params(param);
 - if (ret) {
 - v4l2_err(vpfe_dev-v4l2_dev,
 - Error in setting parameters in CCDC\n);
 - goto unlock_out;
 - }
 - if 

Re: [PATCH - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-15 Thread Hans Verkuil
Note that the other patches from this series are fine as far as I am concerned.

One general note: I always have difficulties with constructions like this:

 + val = (bc-horz.win_count_calc 
 + ISIF_HORZ_BC_WIN_COUNT_MASK) |
 + ((!!bc-horz.base_win_sel_calc) 
 + ISIF_HORZ_BC_WIN_SEL_SHIFT) |
 + ((!!bc-horz.clamp_pix_limit) 
 + ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
 + ((bc-horz.win_h_sz_calc 
 + ISIF_HORZ_BC_WIN_H_SIZE_MASK) 
 + ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
 + ((bc-horz.win_v_sz_calc 
 + ISIF_HORZ_BC_WIN_V_SIZE_MASK) 
 + ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);

It's just about impossible for me to parse. And some of the patches in this
series are full of such constructs.

Unfortunately, I do not have a magic bullet solution. In some cases I suspect
that a static inline function can help.

In other cases it might help to split it up in smaller parts. For example:

u32 tmp;

val = bc-horz.win_count_calc 
ISIF_HORZ_BC_WIN_COUNT_MASK;
val |= !!bc-horz.base_win_sel_calc 
ISIF_HORZ_BC_WIN_SEL_SHIFT;
val |= !!bc-horz.clamp_pix_limit 
ISIF_HORZ_BC_PIX_LIMIT_SHIFT;
tmp = bc-horz.win_h_sz_calc 
ISIF_HORZ_BC_WIN_H_SIZE_MASK;
val |= tmp  ISIF_HORZ_BC_WIN_H_SIZE_SHIFT;
tmp = bc-horz.win_v_sz_calc 
ISIF_HORZ_BC_WIN_V_SIZE_MASK;
val |= tmp  ISIF_HORZ_BC_WIN_V_SIZE_SHIFT;

Of course, in this particular piece of code from the function 
isif_config_bclamp()
I am also wondering why bc-horz.win_h_sz_calc and bc-horz.win_v_sz_calc need 
to
be ANDed anyway. I would expect that to happen when these values are set. But I
did not look at this in-depth, so I may well have missed some subtlety here.

It would be interesting to know if people know of good ways of making awkward
code like this more elegant (or at least less awkward).

Regards,

Hans

-- 
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
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 - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-15 Thread Karicheri, Muralidharan
Hans,

I remember there was a comment against an earlier patch that asks
for combining such statements since it makes the function appear
as big. Not sure who had made that comment. That is the reason you
find code like this in this patch. It was initially done with multiple
OR statements to construct the value to be written to the register as you 
stated below as 

val = bc-horz.win_count_calc 
   ISIF_HORZ_BC_WIN_COUNT_MASK;
val |= !!bc-horz.base_win_sel_calc 
   ISIF_HORZ_BC_WIN_SEL_SHIFT;

I have checked few other drivers such as bt819.c ir-kbd-i2c.c,
mt9m111.c etc, where similar statements are found, but they have used hardcoded 
values masks which makes it appears less complex. But I 
like to reduce magic numbers as much possible in the code.

I think what I can do is to  combine maximum of 2 such expressions in a 
statement which might make it less complex to read. Such as 

val = (bc-horz.win_count_calc 
ISIF_HORZ_BC_WIN_COUNT_MASK) |
((!!bc-horz.base_win_sel_calc) 
ISIF_HORZ_BC_WIN_SEL_SHIFT);

val |= (!!bc-horz.clamp_pix_limit) 
 ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
 ((bc-horz.win_h_sz_calc 
 ISIF_HORZ_BC_WIN_H_SIZE_MASK) 
 ISIF_HORZ_BC_WIN_H_SIZE_SHIFT);
val |= ((bc-horz.win_v_sz_calc 
 ISIF_HORZ_BC_WIN_V_SIZE_MASK) 
 ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);

Also to make the line fits in 80 characters, I will consider reducing
the number of characters in #define names such as

val = (bc-horz.win_count_calc  HZ_BC_WIN_CNT_MASK) |
((!!bc-horz.base_win_sel_calc)  HZ_BC_WIN_SEL_SHIFT) |
(!!bc-horz.clamp_pix_limit)  HZ_BC_PIX_LIMIT_SHIFT);

Let me know if you don't agree.


Of course, in this particular piece of code from the function
isif_config_bclamp()
I am also wondering why bc-horz.win_h_sz_calc and bc-horz.win_v_sz_calc
need to
be ANDed anyway. I would expect that to happen when these values are set.
But I
did not look at this in-depth, so I may well have missed some subtlety here.

Yes, isif_config_bclamp() set values in the register.


It would be interesting to know if people know of good ways of making
awkward
code like this more elegant (or at least less awkward).

Regards,

   Hans

--
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
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 - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-15 Thread Hans Verkuil
On Wednesday 16 December 2009 00:37:52 Karicheri, Muralidharan wrote:
 Hans,
 
 I remember there was a comment against an earlier patch that asks
 for combining such statements since it makes the function appear
 as big. Not sure who had made that comment. That is the reason you
 find code like this in this patch. It was initially done with multiple
 OR statements to construct the value to be written to the register as you 
 stated below as 
 
 val = bc-horz.win_count_calc 
  ISIF_HORZ_BC_WIN_COUNT_MASK;
 val |= !!bc-horz.base_win_sel_calc 
  ISIF_HORZ_BC_WIN_SEL_SHIFT;
 
 I have checked few other drivers such as bt819.c ir-kbd-i2c.c,
 mt9m111.c etc, where similar statements are found, but they have used 
 hardcoded values masks which makes it appears less complex. But I 
 like to reduce magic numbers as much possible in the code.

Personally I have mixed feelings about the use for symbolic names for things
like this. The problem is that they do not help me understanding the code.
The names tend to be long, leading to these broken up lines, and if I want
to know how the bits are distributed in the value I continuously have to
do the look up in the header containing these defines.

Frankly, I have a similar problem with using symbolic names for registers.
Every time I need to look up a register in the datasheet I first need to
look up the register number the register name maps to. All datasheets seem
to be organized around the register addresses and there rarely is a datasheet
that has an index of symbolic names.

Using hard-coded numbers together with a well written comment tends to be much
more readable in my opinion. I don't really think there is anything magic about
these numbers: these are exactly the numbers that I need to know whenever I
have to deal with the datasheet. Having to go through a layer of obfuscation
is just plain irritating to me.

However, I seem to be a minority when it comes to this and I've given up
arguing for this...

Note that all this assumes that the datasheet is publicly available. If it
is a reversed engineered driver or based on NDA datasheets only, then the
symbolic names may be all there is to make you understand what is going on.

 
 I think what I can do is to  combine maximum of 2 such expressions in a 
 statement which might make it less complex to read. Such as 
 
 val = (bc-horz.win_count_calc 
   ISIF_HORZ_BC_WIN_COUNT_MASK) |
   ((!!bc-horz.base_win_sel_calc) 
   ISIF_HORZ_BC_WIN_SEL_SHIFT);
 
 val |= (!!bc-horz.clamp_pix_limit) 
ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
((bc-horz.win_h_sz_calc 
ISIF_HORZ_BC_WIN_H_SIZE_MASK) 
ISIF_HORZ_BC_WIN_H_SIZE_SHIFT);
 val |= ((bc-horz.win_v_sz_calc 
ISIF_HORZ_BC_WIN_V_SIZE_MASK) 
ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);
 
 Also to make the line fits in 80 characters, I will consider reducing
 the number of characters in #define names such as
 
 val = (bc-horz.win_count_calc  HZ_BC_WIN_CNT_MASK) |
 ((!!bc-horz.base_win_sel_calc)  HZ_BC_WIN_SEL_SHIFT) |
 (!!bc-horz.clamp_pix_limit)  HZ_BC_PIX_LIMIT_SHIFT);
 
 Let me know if you don't agree.

That seems overkill. I actually think it can be improved a lot by visually
grouping the lines:

 val = (bc-horz.win_count_calc 
 ISIF_HORZ_BC_WIN_COUNT_MASK) |
   ((!!bc-horz.base_win_sel_calc) 
 ISIF_HORZ_BC_WIN_SEL_SHIFT) |
   ((!!bc-horz.clamp_pix_limit) 
 ISIF_HORZ_BC_PIX_LIMIT_SHIFT) |
   ((bc-horz.win_h_sz_calc 
 ISIF_HORZ_BC_WIN_H_SIZE_MASK) 
 ISIF_HORZ_BC_WIN_H_SIZE_SHIFT) |
   ((bc-horz.win_v_sz_calc 
 ISIF_HORZ_BC_WIN_V_SIZE_MASK) 
 ISIF_HORZ_BC_WIN_V_SIZE_SHIFT);

Now I can at least see the various values that are ORed.

 
 
 Of course, in this particular piece of code from the function
 isif_config_bclamp()
 I am also wondering why bc-horz.win_h_sz_calc and bc-horz.win_v_sz_calc
 need to
 be ANDed anyway. I would expect that to happen when these values are set.
 But I
 did not look at this in-depth, so I may well have missed some subtlety here.
 
 Yes, isif_config_bclamp() set values in the register.

Huh? That does not explain why apparently bc-horz.win_h_sz_calc can be larger
than ISIF_HORZ_BC_WIN_H_SIZE_MASK.

Regards,

Hans

 
 
 It would be interesting to know if people know of good ways of making
 awkward
 code like this more elegant (or at least less awkward).
 
 Regards,
 
  Hans
 
 --
 Hans Verkuil - video4linux developer - sponsored by TANDBERG
 
 

-- 
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
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  

[PATCH - v1 4/6] V4L - vpfe_capture bug fix and enhancements

2009-12-10 Thread m-karicheri2
From: Muralidharan Karicheri m-kariche...@ti.com

Added a experimental IOCTL, to read the CCDC parameters.
Default handler was not getting the original pointer from the core.
So a wrapper function added to handle the default handler properly.
Also fixed a bug in the probe() in the linux-next tree

Signed-off-by: Muralidharan Karicheri m-kariche...@ti.com
---
 drivers/media/video/davinci/vpfe_capture.c |  119 +---
 include/media/davinci/vpfe_capture.h   |   12 ++-
 2 files changed, 81 insertions(+), 50 deletions(-)

diff --git a/drivers/media/video/davinci/vpfe_capture.c 
b/drivers/media/video/davinci/vpfe_capture.c
index 091750e..8c6d856 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -759,12 +759,83 @@ static unsigned int vpfe_poll(struct file *file, 
poll_table *wait)
return 0;
 }
 
+static long vpfe_param_handler(struct file *file, void *priv,
+   int cmd, void *param)
+{
+   struct vpfe_device *vpfe_dev = video_drvdata(file);
+   int ret = 0;
+
+   v4l2_dbg(1, debug, vpfe_dev-v4l2_dev, vpfe_param_handler\n);
+
+   if (NULL == param) {
+   v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
+   Invalid user ptr\n);
+   }
+
+   if (vpfe_dev-started) {
+   /* only allowed if streaming is not started */
+   v4l2_err(vpfe_dev-v4l2_dev, device already started\n);
+   return -EBUSY;
+   }
+
+
+   switch (cmd) {
+   case VPFE_CMD_S_CCDC_RAW_PARAMS:
+   v4l2_warn(vpfe_dev-v4l2_dev,
+ VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n);
+   ret = mutex_lock_interruptible(vpfe_dev-lock);
+   if (ret)
+   return ret;
+   ret = ccdc_dev-hw_ops.set_params(param);
+   if (ret) {
+   v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
+   Error in setting parameters in CCDC\n);
+   goto unlock_out;
+   }
+
+   if (vpfe_get_ccdc_image_format(vpfe_dev, vpfe_dev-fmt)  0) {
+   v4l2_err(vpfe_dev-v4l2_dev,
+   Invalid image format at CCDC\n);
+   ret = -EINVAL;
+   }
+unlock_out:
+   mutex_unlock(vpfe_dev-lock);
+   break;
+   case VPFE_CMD_G_CCDC_RAW_PARAMS:
+   v4l2_warn(vpfe_dev-v4l2_dev,
+ VPFE_CMD_G_CCDC_RAW_PARAMS: experimental ioctl\n);
+   if (!ccdc_dev-hw_ops.get_params) {
+   ret = -EINVAL;
+   break;
+   }
+   ret = ccdc_dev-hw_ops.get_params(param);
+   if (ret) {
+   v4l2_dbg(1, debug, vpfe_dev-v4l2_dev,
+   Error in getting parameters from CCDC\n);
+   }
+   break;
+
+   default:
+   ret = -EINVAL;
+   }
+   return ret;
+}
+
+static long vpfe_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+   if (cmd == VPFE_CMD_S_CCDC_RAW_PARAMS ||
+   cmd == VPFE_CMD_G_CCDC_RAW_PARAMS)
+   return vpfe_param_handler(file, file-private_data, cmd,
+(void *)arg);
+   return video_ioctl2(file, cmd, arg);
+}
+
 /* vpfe capture driver file operations */
 static const struct v4l2_file_operations vpfe_fops = {
.owner = THIS_MODULE,
.open = vpfe_open,
.release = vpfe_release,
-   .unlocked_ioctl = video_ioctl2,
+   .unlocked_ioctl = vpfe_ioctl,
.mmap = vpfe_mmap,
.poll = vpfe_poll
 };
@@ -1682,50 +1753,6 @@ unlock_out:
return ret;
 }
 
-
-static long vpfe_param_handler(struct file *file, void *priv,
-   int cmd, void *param)
-{
-   struct vpfe_device *vpfe_dev = video_drvdata(file);
-   int ret = 0;
-
-   v4l2_dbg(1, debug, vpfe_dev-v4l2_dev, vpfe_param_handler\n);
-
-   if (vpfe_dev-started) {
-   /* only allowed if streaming is not started */
-   v4l2_err(vpfe_dev-v4l2_dev, device already started\n);
-   return -EBUSY;
-   }
-
-   ret = mutex_lock_interruptible(vpfe_dev-lock);
-   if (ret)
-   return ret;
-
-   switch (cmd) {
-   case VPFE_CMD_S_CCDC_RAW_PARAMS:
-   v4l2_warn(vpfe_dev-v4l2_dev,
- VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n);
-   ret = ccdc_dev-hw_ops.set_params(param);
-   if (ret) {
-   v4l2_err(vpfe_dev-v4l2_dev,
-   Error in setting parameters in CCDC\n);
-   goto unlock_out;
-   }
-   if (vpfe_get_ccdc_image_format(vpfe_dev, vpfe_dev-fmt)  0) {
-   v4l2_err(vpfe_dev-v4l2_dev,
-