/*
 * ccdc_ioctl - CCDC module private ioctl's
 * @sd: VPFE CCDC V4L2 subdevice
 * @cmd: ioctl command
 * @arg: ioctl argument
 *
 * Return 0 on success or a negative error code otherwise.
 */
static long resizer_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
	struct vpfe_resizer_device *resizer = v4l2_get_subdevdata(sd);
	struct imp_logical_channel *rsz_conf_chan = &resizer->channel;
	struct device *dev = resizer->subdev.v4l2_dev->dev;
	int ret = 0;

	switch (cmd) {

	case RSZ_S_CONFIG:
		{
			struct rsz_channel_config *user_config =
			    (struct rsz_channel_config *)arg;

			dev_dbg(dev, "RSZ_S_CONFIG:\n");

			if (!ret) {
				ret = imp_set_resizer_config(dev,
						     rsz_conf_chan,
							user_config);

			}
		}
		break;

	case RSZ_G_CONFIG:
		{
			struct rsz_channel_config *user_config =
			    (struct rsz_channel_config *)arg;

			dev_err(dev, "RSZ_G_CONFIG:%d:%d\n",
				user_config->chain,
				user_config->len);
			if (ISNULL(user_config->config)) {
				ret = -EINVAL;
				dev_err(dev,
					"error in PREV_GET_CONFIG\n");
				goto ERROR;
			}

			ret =
			    imp_get_resize_config(dev, rsz_conf_chan,
						  user_config);

		}
		break;
	default:
		printk(KERN_ERR "invalid command\n");
	}

ERROR:
	return ret;
}
Exemple #2
0
/*
=====================rsz_ioctl===========================
This function	will process IOCTL commands sent by
the application	and
control the device IO operations.
*/
static int rsz_doioctl(struct inode *inode, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	int ret = 0, prio;
	unsigned mode, user_mode;
	/*get the configuratin of this channel from
	   private_date member of file */
	struct imp_logical_channel *rsz_conf_chan =
	    (struct imp_logical_channel *)file->private_data;

	if (ISNULL(rsz_conf_chan)) {
		dev_err(rsz_device, "channel ptr is null\n");
		return -EFAULT;
	}

	if (ISNULL((void *)arg)) {
		dev_err(rsz_device, "arg ptr is null\n");
		return -EFAULT;
	}

	mode = imp_hw_if->get_resize_oper_mode();
	switch (cmd) {
	case RSZ_QUERYBUF:
	case RSZ_REQBUF:
	case RSZ_RESIZE:
	case RSZ_RECONFIG:
		{
			if (mode == IMP_MODE_CONTINUOUS)
				return -EACCES;
		}
		break;
	}

	switch (cmd) {
	case RSZ_S_OPER_MODE:
		{
			dev_dbg(rsz_device, "RSZ_S_OPER_MODE:\n");
			user_mode = *((unsigned long *)arg);
			if (rsz_conf_chan->mode != IMP_MODE_INVALID) {
				dev_err(rsz_device,
					"Mode set for this channel already\n");
				ret = -EINVAL;
				goto ERROR;
			}

			if (user_mode >= IMP_MODE_INVALID) {
				dev_err(rsz_device, "Invalid mode\n");
				ret = -EINVAL;
				goto ERROR;
			}

			imp_hw_if->set_resize_oper_mode(user_mode);
			mode = imp_hw_if->get_resize_oper_mode();

			if (user_mode != mode) {
				dev_err(rsz_device,
					"Operation mode doesn't match"
					" with current hw mode\n");
				ret = -EINVAL;
				goto ERROR;
			}
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				rsz_conf_chan->mode = mode;
				mutex_unlock(&(rsz_conf_chan->lock));
			}
			dev_dbg(rsz_device,
				"RSZ_S_OPER_MODE: Operation mode set to %d",
				user_mode);
		}
		break;
		/* if case is to query for buffer address */
	case RSZ_G_OPER_MODE:
		{
			dev_dbg(rsz_device, "RSZ_G_OPER_MODE:\n");
			*((unsigned long *)arg) = rsz_conf_chan->mode;
			dev_dbg(rsz_device,
				"RSZ_G_OPER_MODE: mode = %d",
				rsz_conf_chan->mode);
		}
		break;

	case RSZ_S_CONFIG:
		{
			dev_dbg(rsz_device, "RSZ_S_CONFIG:\n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				ret = imp_set_resizer_config(rsz_device,
						     rsz_conf_chan,
						     (struct rsz_channel_config
						      *)arg);
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;

	case RSZ_G_CONFIG:
		{
			struct rsz_channel_config *user_config =
			    (struct rsz_channel_config *)arg;

			dev_err(rsz_device, "RSZ_G_CONFIG:%d:%d:%d\n",
				user_config->oper_mode, user_config->chain,
				user_config->len);
			if (ISNULL(user_config->config)) {
				ret = -EINVAL;
				dev_err(rsz_device,
					"error in PREV_GET_CONFIG\n");
				goto ERROR;
			}
			ret =
			    imp_get_resize_config(rsz_device, rsz_conf_chan,
						  user_config);
		}
		break;

	case RSZ_QUERYBUF:
		{
			dev_dbg(rsz_device, "RSZ_QUERYBUF:\n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				ret = imp_common_query_buffer(rsz_device,
						      rsz_conf_chan,
						      (struct imp_buffer *)arg);
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;

		/* if case is to request buffers */
	case RSZ_REQBUF:
		{
			dev_dbg(rsz_device, "RSZ_REQBUF:\n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				ret = imp_common_request_buffer(rsz_device,
							rsz_conf_chan,
							(struct imp_reqbufs *)
							arg);
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;
		/* if the case is to do resize */
	case RSZ_S_PRIORITY:
		{
			prio = *((unsigned long *)arg);

			dev_dbg(rsz_device, "RSZ_S_PRIORITY: priority = %d\n",
				prio);
			/* Check the prioroty range and assign the priority */
			if (prio > MAX_PRIORITY || prio < MIN_PRIORITY) {
				ret = -EINVAL;
				goto ERROR;
			} else {
				ret = mutex_lock_interruptible(
					&(rsz_conf_chan->lock));
				if (!ret) {
					rsz_conf_chan->priority = prio;
					mutex_unlock(&(rsz_conf_chan->lock));
				}
			}
			dev_dbg(rsz_device, "\n resizer_Priority:end");
		}
		break;
		/* This ioctl is used to get the priority of
		   the current logic channel */
	case RSZ_G_PRIORITY:
		{
			dev_dbg(rsz_device, "RSZ_S_PRIORITY: \n");
			/* Get the priority     from the channel */
			*((unsigned long *)arg) = rsz_conf_chan->priority;
		}
		break;

	case RSZ_RESIZE:
		{
			dev_dbg(rsz_device, "RSZ_RESIZE: \n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				ret = imp_common_start_resize(rsz_device,
						      rsz_conf_chan,
						      (struct imp_convert *)
						      arg);
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;

	case RSZ_RECONFIG:
		{
			dev_dbg(rsz_device, "RSZ_RECONFIG: \n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				ret = imp_common_reconfig_resizer(rsz_device,
						(struct rsz_reconfig *)arg,
						 rsz_conf_chan);
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;

#ifdef CONFIG_IMP_DEBUG
	case RSZ_DUMP_HW_CONFIG:
		{
			dev_dbg(rsz_device, "RSZ_DUMP_HW_CONFIG: \n");
			ret = mutex_lock_interruptible(&(rsz_conf_chan->lock));
			if (!ret) {
				if (imp_hw_if->dump_hw_config)
					imp_hw_if->dump_hw_config();
				mutex_unlock(&(rsz_conf_chan->lock));
			}
		}
		break;
#endif
	default:
		dev_dbg(rsz_device, "resizer_ioctl: Invalid Command Value");
		ret = -EINVAL;
	}

ERROR:
	return ret;
}				/*End of function IOCTL */