extractedLnx/linux-2.6.36/drivers/media/video/cpia.c_cpia_proc_write.c
static ssize_t cpia_proc_write(struct file *file, const char __user *buf,
size_t count, loff_t *pos)
{
struct cam_data *cam = PDE(file->f_path.dentry->d_inode)->data;
struct cam_params new_params;
char *page, *buffer;
int retval, find_colon;
int size = count;
unsigned long val = 0;
u32 command_flags = 0;
u8 new_mains;
/*
* This code to copy from buf to page is shamelessly copied
* from the comx driver
*/
if (count > PAGE_SIZE) {
printk(KERN_ERR "count is %zu > %d!!!\n", count, (int)PAGE_SIZE);
return -ENOSPC;
}
if (!(page = (char *)__get_free_page(GFP_KERNEL))) return -ENOMEM;
if(copy_from_user(page, buf, count))
{
retval = -EFAULT;
goto out;
}
if (page[count-1] == '\n')
page[count-1] = '\0';
else if (count < PAGE_SIZE)
page[count] = '\0';
else if (page[count]) {
retval = -EINVAL;
goto out;
}
buffer = page;
if (mutex_lock_interruptible(&cam->param_lock))
return -ERESTARTSYS;
/*
* Skip over leading whitespace
*/
while (count && isspace(*buffer)) {
--count;
++buffer;
}
memcpy(&new_params, &cam->params, sizeof(struct cam_params));
new_mains = cam->mainsFreq;
#define MATCH(x) (match(x, &buffer, &count, &find_colon, &retval))
#define VALUE (value(&buffer,&count, &retval))
#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
new_params.version.firmwareRevision == (y))
retval = 0;
while (count && !retval) {
find_colon = 1;
if (MATCH("brightness")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 100)
new_params.colourParams.brightness = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURPARAMS;
if(new_params.flickerControl.allowableOverExposure < 0)
new_params.flickerControl.allowableOverExposure =
-find_over_exposure(new_params.colourParams.brightness);
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
} else if (MATCH("contrast")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 100) {
/* contrast is in steps of 8, so round*/
val = ((val + 3) / 8) * 8;
/* 1-02 firmware limits contrast to 80*/
if (FIRMWARE_VERSION(1,2) && val > 80)
val = 80;
new_params.colourParams.contrast = val;
} else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURPARAMS;
} else if (MATCH("saturation")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 100)
new_params.colourParams.saturation = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURPARAMS;
} else if (MATCH("sensor_fps")) {
if (!retval)
val = VALUE;
if (!retval) {
/* find values so that sensorFPS is minimized,
* but >= val */
if (val > 30)
retval = -EINVAL;
else if (val > 25) {
new_params.sensorFps.divisor = 0;
new_params.sensorFps.baserate = 1;
} else if (val > 15) {
new_params.sensorFps.divisor = 0;
new_params.sensorFps.baserate = 0;
} else if (val > 12) {
new_params.sensorFps.divisor = 1;
new_params.sensorFps.baserate = 1;
} else if (val > 7) {
new_params.sensorFps.divisor = 1;
new_params.sensorFps.baserate = 0;
} else if (val > 6) {
new_params.sensorFps.divisor = 2;
new_params.sensorFps.baserate = 1;
} else if (val > 3) {
new_params.sensorFps.divisor = 2;
new_params.sensorFps.baserate = 0;
} else {
new_params.sensorFps.divisor = 3;
/* Either base rate would work here */
new_params.sensorFps.baserate = 1;
}
new_params.flickerControl.coarseJump =
flicker_jumps[new_mains]
[new_params.sensorFps.baserate]
[new_params.sensorFps.divisor];
if (new_params.flickerControl.flickerMode)
command_flags |= COMMAND_SETFLICKERCTRL;
}
command_flags |= COMMAND_SETSENSORFPS;
cam->exposure_status = EXPOSURE_NORMAL;
} else if (MATCH("stream_start_line")) {
if (!retval)
val = VALUE;
if (!retval) {
int max_line = 288;
if (new_params.format.videoSize == VIDEOSIZE_QCIF)
max_line = 144;
if (val <= max_line)
new_params.streamStartLine = val/2;
else
retval = -EINVAL;
}
} else if (MATCH("sub_sample")) {
if (!retval && MATCH("420"))
new_params.format.subSample = SUBSAMPLE_420;
else if (!retval && MATCH("422"))
new_params.format.subSample = SUBSAMPLE_422;
else
retval = -EINVAL;
command_flags |= COMMAND_SETFORMAT;
} else if (MATCH("yuv_order")) {
if (!retval && MATCH("YUYV"))
new_params.format.yuvOrder = YUVORDER_YUYV;
else if (!retval && MATCH("UYVY"))
new_params.format.yuvOrder = YUVORDER_UYVY;
else
retval = -EINVAL;
command_flags |= COMMAND_SETFORMAT;
} else if (MATCH("ecp_timing")) {
if (!retval && MATCH("normal"))
new_params.ecpTiming = 0;
else if (!retval && MATCH("slow"))
new_params.ecpTiming = 1;
else
retval = -EINVAL;
command_flags |= COMMAND_SETECPTIMING;
} else if (MATCH("color_balance_mode")) {
if (!retval && MATCH("manual"))
new_params.colourBalance.balanceMode = 3;
else if (!retval && MATCH("auto"))
new_params.colourBalance.balanceMode = 2;
else
retval = -EINVAL;
command_flags |= COMMAND_SETCOLOURBALANCE;
} else if (MATCH("red_gain")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 212) {
new_params.colourBalance.redGain = val;
new_params.colourBalance.balanceMode = 1;
} else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURBALANCE;
} else if (MATCH("green_gain")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 212) {
new_params.colourBalance.greenGain = val;
new_params.colourBalance.balanceMode = 1;
} else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURBALANCE;
} else if (MATCH("blue_gain")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 212) {
new_params.colourBalance.blueGain = val;
new_params.colourBalance.balanceMode = 1;
} else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOLOURBALANCE;
} else if (MATCH("max_gain")) {
if (!retval)
val = VALUE;
if (!retval) {
/* 1-02 firmware limits gain to 2 */
if (FIRMWARE_VERSION(1,2) && val > 2)
val = 2;
switch(val) {
case 1:
new_params.exposure.gainMode = 1;
break;
case 2:
new_params.exposure.gainMode = 2;
break;
case 4:
new_params.exposure.gainMode = 3;
break;
case 8:
new_params.exposure.gainMode = 4;
break;
default:
retval = -EINVAL;
break;
}
}
command_flags |= COMMAND_SETEXPOSURE;
} else if (MATCH("exposure_mode")) {
if (!retval && MATCH("auto"))
new_params.exposure.expMode = 2;
else if (!retval && MATCH("manual")) {
if (new_params.exposure.expMode == 2)
new_params.exposure.expMode = 3;
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
new_params.flickerControl.flickerMode = 0;
} else
retval = -EINVAL;
command_flags |= COMMAND_SETEXPOSURE;
} else if (MATCH("centre_weight")) {
if (!retval && MATCH("on"))
new_params.exposure.centreWeight = 1;
else if (!retval && MATCH("off"))
new_params.exposure.centreWeight = 2;
else
retval = -EINVAL;
command_flags |= COMMAND_SETEXPOSURE;
} else if (MATCH("gain")) {
if (!retval)
val = VALUE;
if (!retval) {
switch(val) {
case 1:
new_params.exposure.gain = 0;
break;
case 2:
new_params.exposure.gain = 1;
break;
case 4:
new_params.exposure.gain = 2;
break;
case 8:
new_params.exposure.gain = 3;
break;
default:
retval = -EINVAL;
break;
}
new_params.exposure.expMode = 1;
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETEXPOSURE;
if (new_params.exposure.gain >
new_params.exposure.gainMode-1)
retval = -EINVAL;
}
} else if (MATCH("fine_exp")) {
if (!retval)
val = VALUE/2;
if (!retval) {
if (val < 256) {
/* 1-02 firmware limits fineExp/2 to 127*/
if (FIRMWARE_VERSION(1,2) && val > 127)
val = 127;
new_params.exposure.fineExp = val;
new_params.exposure.expMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
} else
retval = -EINVAL;
}
} else if (MATCH("coarse_exp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= MAX_EXP) {
if (FIRMWARE_VERSION(1,2) &&
val > MAX_EXP_102)
val = MAX_EXP_102;
new_params.exposure.coarseExpLo =
val & 0xff;
new_params.exposure.coarseExpHi =
val >> 8;
new_params.exposure.expMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
} else
retval = -EINVAL;
}
} else if (MATCH("red_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= COMP_RED && val <= 255) {
new_params.exposure.redComp = val;
new_params.exposure.compMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("green1_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= COMP_GREEN1 && val <= 255) {
new_params.exposure.green1Comp = val;
new_params.exposure.compMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("green2_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= COMP_GREEN2 && val <= 255) {
new_params.exposure.green2Comp = val;
new_params.exposure.compMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("blue_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= COMP_BLUE && val <= 255) {
new_params.exposure.blueComp = val;
new_params.exposure.compMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("apcor_gain1")) {
if (!retval)
val = VALUE;
if (!retval) {
command_flags |= COMMAND_SETAPCOR;
if (val <= 0xff)
new_params.apcor.gain1 = val;
else
retval = -EINVAL;
}
} else if (MATCH("apcor_gain2")) {
if (!retval)
val = VALUE;
if (!retval) {
command_flags |= COMMAND_SETAPCOR;
if (val <= 0xff)
new_params.apcor.gain2 = val;
else
retval = -EINVAL;
}
} else if (MATCH("apcor_gain4")) {
if (!retval)
val = VALUE;
if (!retval) {
command_flags |= COMMAND_SETAPCOR;
if (val <= 0xff)
new_params.apcor.gain4 = val;
else
retval = -EINVAL;
}
} else if (MATCH("apcor_gain8")) {
if (!retval)
val = VALUE;
if (!retval) {
command_flags |= COMMAND_SETAPCOR;
if (val <= 0xff)
new_params.apcor.gain8 = val;
else
retval = -EINVAL;
}
} else if (MATCH("vl_offset_gain1")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.vlOffset.gain1 = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETVLOFFSET;
} else if (MATCH("vl_offset_gain2")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.vlOffset.gain2 = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETVLOFFSET;
} else if (MATCH("vl_offset_gain4")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.vlOffset.gain4 = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETVLOFFSET;
} else if (MATCH("vl_offset_gain8")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.vlOffset.gain8 = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETVLOFFSET;
} else if (MATCH("flicker_control")) {
if (!retval && MATCH("on")) {
set_flicker(&new_params, &command_flags, 1);
} else if (!retval && MATCH("off")) {
set_flicker(&new_params, &command_flags, 0);
} else
retval = -EINVAL;
command_flags |= COMMAND_SETFLICKERCTRL;
} else if (MATCH("mains_frequency")) {
if (!retval && MATCH("50")) {
new_mains = 0;
new_params.flickerControl.coarseJump =
flicker_jumps[new_mains]
[new_params.sensorFps.baserate]
[new_params.sensorFps.divisor];
if (new_params.flickerControl.flickerMode)
command_flags |= COMMAND_SETFLICKERCTRL;
} else if (!retval && MATCH("60")) {
new_mains = 1;
new_params.flickerControl.coarseJump =
flicker_jumps[new_mains]
[new_params.sensorFps.baserate]
[new_params.sensorFps.divisor];
if (new_params.flickerControl.flickerMode)
command_flags |= COMMAND_SETFLICKERCTRL;
} else
retval = -EINVAL;
} else if (MATCH("allowable_overexposure")) {
if (!retval && MATCH("auto")) {
new_params.flickerControl.allowableOverExposure =
-find_over_exposure(new_params.colourParams.brightness);
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
} else {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff) {
new_params.flickerControl.
allowableOverExposure = val;
if(new_params.flickerControl.flickerMode != 0)
command_flags |= COMMAND_SETFLICKERCTRL;
} else
retval = -EINVAL;
}
}
} else if (MATCH("compression_mode")) {
if (!retval && MATCH("none"))
new_params.compression.mode =
CPIA_COMPRESSION_NONE;
else if (!retval && MATCH("auto"))
new_params.compression.mode =
CPIA_COMPRESSION_AUTO;
else if (!retval && MATCH("manual"))
new_params.compression.mode =
CPIA_COMPRESSION_MANUAL;
else
retval = -EINVAL;
command_flags |= COMMAND_SETCOMPRESSION;
} else if (MATCH("decimation_enable")) {
if (!retval && MATCH("off"))
new_params.compression.decimation = 0;
else if (!retval && MATCH("on"))
new_params.compression.decimation = 1;
else
retval = -EINVAL;
command_flags |= COMMAND_SETCOMPRESSION;
} else if (MATCH("compression_target")) {
if (!retval && MATCH("quality"))
new_params.compressionTarget.frTargeting =
CPIA_COMPRESSION_TARGET_QUALITY;
else if (!retval && MATCH("framerate"))
new_params.compressionTarget.frTargeting =
CPIA_COMPRESSION_TARGET_FRAMERATE;
else
retval = -EINVAL;
command_flags |= COMMAND_SETCOMPRESSIONTARGET;
} else if (MATCH("target_framerate")) {
if (!retval)
val = VALUE;
if (!retval) {
if(val > 0 && val <= 30)
new_params.compressionTarget.targetFR = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONTARGET;
} else if (MATCH("target_quality")) {
if (!retval)
val = VALUE;
if (!retval) {
if(val > 0 && val <= 64)
new_params.compressionTarget.targetQ = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONTARGET;
} else if (MATCH("y_threshold")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val < 32)
new_params.yuvThreshold.yThreshold = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETYUVTHRESH;
} else if (MATCH("uv_threshold")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val < 32)
new_params.yuvThreshold.uvThreshold = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETYUVTHRESH;
} else if (MATCH("hysteresis")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.hysteresis = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("threshold_max")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.threshMax = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("small_step")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.smallStep = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("large_step")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.largeStep = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("decimation_hysteresis")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.decimationHysteresis = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("fr_diff_step_thresh")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.frDiffStepThresh = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("q_diff_step_thresh")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.qDiffStepThresh = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("decimation_thresh_mod")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val <= 0xff)
new_params.compressionParams.decimationThreshMod = val;
else
retval = -EINVAL;
}
command_flags |= COMMAND_SETCOMPRESSIONPARAMS;
} else if (MATCH("toplight")) {
if (!retval && MATCH("on"))
new_params.qx3.toplight = 1;
else if (!retval && MATCH("off"))
new_params.qx3.toplight = 0;
else
retval = -EINVAL;
command_flags |= COMMAND_SETLIGHTS;
} else if (MATCH("bottomlight")) {
if (!retval && MATCH("on"))
new_params.qx3.bottomlight = 1;
else if (!retval && MATCH("off"))
new_params.qx3.bottomlight = 0;
else
retval = -EINVAL;
command_flags |= COMMAND_SETLIGHTS;
} else {
DBG("No match found\n");
retval = -EINVAL;
}
if (!retval) {
while (count && isspace(*buffer) && *buffer != '\n') {
--count;
++buffer;
}
if (count) {
if (*buffer == '\0' && count != 1)
retval = -EINVAL;
else if (*buffer != '\n' && *buffer != ';' &&
*buffer != '\0')
retval = -EINVAL;
else {
--count;
++buffer;
}
}
}
}
#undef MATCH
#undef VALUE
#undef FIRMWARE_VERSION
if (!retval) {
if (command_flags & COMMAND_SETCOLOURPARAMS) {
/* Adjust cam->vp to reflect these changes */
cam->vp.brightness =
new_params.colourParams.brightness*65535/100;
cam->vp.contrast =
new_params.colourParams.contrast*65535/100;
cam->vp.colour =
new_params.colourParams.saturation*65535/100;
}
if((command_flags & COMMAND_SETEXPOSURE) &&
new_params.exposure.expMode == 2)
cam->exposure_status = EXPOSURE_NORMAL;
memcpy(&cam->params, &new_params, sizeof(struct cam_params));
cam->mainsFreq = new_mains;
cam->cmd_queue |= command_flags;
retval = size;
} else
DBG("error: %d\n", retval);
mutex_unlock(&cam->param_lock);
out:
free_page((unsigned long)page);
return retval;
}
Generated by GNU enscript 1.6.4.