Enscript Output

extractedLnx/linux-2.6.37/drivers/staging/cpia/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.