extractedLnx/linux-2.2.26/drivers/char/cpia.c_cpia_write_proc.c
static int cpia_write_proc(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct cam_data *cam = data;
struct cam_params new_params;
int retval, find_colon;
int size = count;
unsigned long val;
u32 command_flags = 0;
u8 new_mains;
if (down_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) \
({ \
int _len = strlen(x), _ret, _colon_found; \
_ret = (_len <= count && strncmp(buffer, x, _len) == 0); \
if (_ret) { \
buffer += _len; \
count -= _len; \
if (find_colon) { \
_colon_found = 0; \
while (count && (*buffer == ' ' || *buffer == '\t' || \
(!_colon_found && *buffer == ':'))) { \
if (*buffer == ':') \
_colon_found = 1; \
--count; \
++buffer; \
} \
if (!count || !_colon_found) \
retval = -EINVAL; \
find_colon = 0; \
} \
} \
_ret; \
})
#define FIRMWARE_VERSION(x,y) (new_params.version.firmwareVersion == (x) && \
new_params.version.firmwareRevision == (y))
#define VALUE \
({ \
char *_p; \
unsigned long int _ret; \
_ret = simple_strtoul(buffer, &_p, 0); \
if (_p == buffer) \
retval = -EINVAL; \
else { \
count -= _p - buffer; \
buffer = _p; \
} \
_ret; \
})
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;
} 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;
} 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.balanceModeIsAuto = 0;
else if (!retval && MATCH("auto"))
new_params.colourBalance.balanceModeIsAuto = 1;
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;
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;
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;
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;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
} 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;
new_params.exposure.expMode = 1;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
break;
case 2:
new_params.exposure.gain = 1;
new_params.exposure.expMode = 1;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
break;
case 4:
new_params.exposure.gain = 2;
new_params.exposure.expMode = 1;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
break;
case 8:
new_params.exposure.gain = 3;
new_params.exposure.expMode = 1;
new_params.flickerControl.flickerMode = 0;
command_flags |= COMMAND_SETFLICKERCTRL;
break;
default:
retval = -EINVAL;
break;
}
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;
if (!retval) {
if (val < 256) {
/* 1-02 firmware limits fineExp 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;
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 < 65536) {
/* 1-02 firmware limits
* coarseExp to 255 */
if (FIRMWARE_VERSION(1,2) && val > 255)
val = 255;
new_params.exposure.coarseExpLo =
val & 0xff;
new_params.exposure.coarseExpHi =
val >> 8;
new_params.exposure.expMode = 1;
command_flags |= COMMAND_SETEXPOSURE;
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 >= 220 && val <= 255) {
new_params.exposure.redComp = val;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("green1_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= 214 && val <= 255) {
new_params.exposure.green1Comp = val;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("green2_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= 214 && val <= 255) {
new_params.exposure.green2Comp = val;
command_flags |= COMMAND_SETEXPOSURE;
} else
retval = -EINVAL;
}
} else if (MATCH("blue_comp")) {
if (!retval)
val = VALUE;
if (!retval) {
if (val >= 230 && val <= 255) {
new_params.exposure.blueComp = val;
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")) {
new_params.flickerControl.flickerMode = 1;
new_params.exposure.expMode = 2;
command_flags |= COMMAND_SETEXPOSURE;
} else if (!retval && MATCH("off"))
new_params.flickerControl.flickerMode = 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)
val = VALUE;
if (!retval) {
if (val <= 0xff) {
new_params.flickerControl.
allowableOverExposure = val;
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")) { /* GA 4/14/00 */
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")) { /* GA 4/14/00 */
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 != '\n' && *buffer != ';')
retval = -EINVAL;
else {
--count;
++buffer;
}
}
}
}
#undef MATCH
#undef FIRMWARE_VERSION
#undef VALUE
#undef FIND_VALUE
#undef FIND_END
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;
}
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);
up(&cam->param_lock);
return retval;
}
Generated by GNU enscript 1.6.4.