/*
 * Copyright (C) 2010 Texas Instruments Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/err.h>

#include <media/v4l2-device.h>
#include <media/davinci/vpbe_types.h>
#include <media/davinci/vpbe.h>
#include <media/davinci/vpss.h>
#include <media/davinci/vpbe_venc.h>

#define VPBE_DEFAULT_OUTPUT	"Composite"
#define VPBE_DEFAULT_MODE	"ntsc"

static char *def_output = VPBE_DEFAULT_OUTPUT;
static char *def_mode = VPBE_DEFAULT_MODE;
static int debug;

module_param(def_output, charp, S_IRUGO);
module_param(def_mode, charp, S_IRUGO);
module_param(debug, int, 0644);

MODULE_PARM_DESC(def_output, "vpbe output name (default:Composite)");
MODULE_PARM_DESC(def_mode, "vpbe output mode name (default:ntsc");
MODULE_PARM_DESC(debug, "Debug level 0-1");

MODULE_DESCRIPTION("TI DMXXX VPBE Display controller");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Texas Instruments");

/**
 * vpbe_current_encoder_info - Get config info for current encoder
 * @vpbe_dev - vpbe device ptr
 *
 * Return ptr to current encoder config info
 */
static struct encoder_config_info*
vpbe_current_encoder_info(struct vpbe_device *vpbe_dev)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int index = vpbe_dev->current_sd_index;

	return ((index == 0) ? &cfg->venc :
				&cfg->ext_encoders[index-1]);
}

/**
 * vpbe_find_encoder_sd_index - Given a name find encoder sd index
 *
 * @vpbe_config - ptr to vpbe cfg
 * @output_index - index used by application
 *
 * Return sd index of the encoder
 */
static int vpbe_find_encoder_sd_index(struct vpbe_config *cfg,
			     int index)
{
	char *encoder_name = cfg->outputs[index].subdev_name;
	int i;

	/* Venc is always first	*/
	if (!strcmp(encoder_name, cfg->venc.module_name))
		return 0;

	for (i = 0; i < cfg->num_ext_encoders; i++) {
		if (!strcmp(encoder_name,
		     cfg->ext_encoders[i].module_name))
			return i+1;
	}

	return -EINVAL;
}

/**
 * vpbe_g_cropcap - Get crop capabilities of the display
 * @vpbe_dev - vpbe device ptr
 * @cropcap - cropcap is a ptr to struct v4l2_cropcap
 *
 * Update the crop capabilities in crop cap for current
 * mode
 */
static int vpbe_g_cropcap(struct vpbe_device *vpbe_dev,
			  struct v4l2_cropcap *cropcap)
{
	if (NULL == cropcap)
		return -EINVAL;
	cropcap->bounds.left = 0;
	cropcap->bounds.top = 0;
	cropcap->bounds.width = vpbe_dev->current_timings.xres;
	cropcap->bounds.height = vpbe_dev->current_timings.yres;
	cropcap->defrect = cropcap->bounds;

	return 0;
}

/**
 * vpbe_enum_outputs - enumerate outputs
 * @vpbe_dev - vpbe device ptr
 * @output - ptr to v4l2_output structure
 *
 * Enumerates the outputs available at the vpbe display
 * returns the status, -EINVAL if end of output list
 */
static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
			     struct v4l2_output *output)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int temp_index = output->index;

	if (temp_index >= cfg->num_outputs)
		return -EINVAL;

	*output = cfg->outputs[temp_index].output;
	output->index = temp_index;

	return 0;
}

static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode,
			      int output_index)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	struct vpbe_enc_mode_info var;
	int curr_output = output_index;
	int i;

	if (NULL == mode)
		return -EINVAL;

	for (i = 0; i < cfg->outputs[curr_output].num_modes; i++) {
		var = cfg->outputs[curr_output].modes[i];
		if (!strcmp(mode, var.name)) {
			vpbe_dev->current_timings = var;
			return 0;
		}
	}

	return -EINVAL;
}

static int vpbe_get_current_mode_info(struct vpbe_device *vpbe_dev,
				      struct vpbe_enc_mode_info *mode_info)
{
	if (NULL == mode_info)
		return -EINVAL;

	*mode_info = vpbe_dev->current_timings;

	return 0;
}

/* Get std by std id */
static int vpbe_get_std_info(struct vpbe_device *vpbe_dev,
			     v4l2_std_id std_id)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	struct vpbe_enc_mode_info var;
	int curr_output = vpbe_dev->current_out_index;
	int i;

	for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
		var = cfg->outputs[curr_output].modes[i];
		if ((var.timings_type & VPBE_ENC_STD) &&
		  (var.std_id & std_id)) {
			vpbe_dev->current_timings = var;
			return 0;
		}
	}

	return -EINVAL;
}

static int vpbe_get_std_info_by_name(struct vpbe_device *vpbe_dev,
				char *std_name)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	struct vpbe_enc_mode_info var;
	int curr_output = vpbe_dev->current_out_index;
	int i;

	for (i = 0; i < vpbe_dev->cfg->outputs[curr_output].num_modes; i++) {
		var = cfg->outputs[curr_output].modes[i];
		if (!strcmp(var.name, std_name)) {
			vpbe_dev->current_timings = var;
			return 0;
		}
	}

	return -EINVAL;
}

/**
 * vpbe_set_output - Set output
 * @vpbe_dev - vpbe device ptr
 * @index - index of output
 *
 * Set vpbe output to the output specified by the index
 */
static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index)
{
	struct encoder_config_info *curr_enc_info =
			vpbe_current_encoder_info(vpbe_dev);
	struct vpbe_config *cfg = vpbe_dev->cfg;
	struct venc_platform_data *venc_device = vpbe_dev->venc_device;
	enum v4l2_mbus_pixelcode if_params;
	int enc_out_index;
	int sd_index;
	int ret = 0;

	if (index >= cfg->num_outputs)
		return -EINVAL;

	mutex_lock(&vpbe_dev->lock);

	sd_index = vpbe_dev->current_sd_index;
	enc_out_index = cfg->outputs[index].output.index;
	/*
	 * Currently we switch the encoder based on output selected
	 * by the application. If media controller is implemented later
	 * there is will be an API added to setup_link between venc
	 * and external encoder. So in that case below comparison always
	 * match and encoder will not be switched. But if application
	 * chose not to use media controller, then this provides current
	 * way of switching encoder at the venc output.
	 */
	if (strcmp(curr_enc_info->module_name,
		   cfg->outputs[index].subdev_name)) {
		/* Need to switch the encoder at the output */
		sd_index = vpbe_find_encoder_sd_index(cfg, index);
		if (sd_index < 0) {
			ret = -EINVAL;
			goto out;
		}

		if_params = cfg->outputs[index].if_params;
		venc_device->setup_if_config(if_params);
		if (ret)
			goto out;
	}

	/* Set output at the encoder */
	ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
				       s_routing, 0, enc_out_index, 0);
	if (ret)
		goto out;

	/*
	 * It is assumed that venc or extenal encoder will set a default
	 * mode in the sub device. For external encoder or LCD pannel output,
	 * we also need to set up the lcd port for the required mode. So setup
	 * the lcd port for the default mode that is configured in the board
	 * arch/arm/mach-davinci/board-dm355-evm.setup file for the external
	 * encoder.
	 */
	ret = vpbe_get_mode_info(vpbe_dev,
				 cfg->outputs[index].default_mode, index);
	if (!ret) {
		struct osd_state *osd_device = vpbe_dev->osd_device;

		osd_device->ops.set_left_margin(osd_device,
			vpbe_dev->current_timings.left_margin);
		osd_device->ops.set_top_margin(osd_device,
		vpbe_dev->current_timings.upper_margin);
		vpbe_dev->current_sd_index = sd_index;
		vpbe_dev->current_out_index = index;
	}
out:
	mutex_unlock(&vpbe_dev->lock);
	return ret;
}

static int vpbe_set_default_output(struct vpbe_device *vpbe_dev)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int ret = 0;
	int i;

	for (i = 0; i < cfg->num_outputs; i++) {
		if (!strcmp(def_output,
			    cfg->outputs[i].output.name)) {
			ret = vpbe_set_output(vpbe_dev, i);
			if (!ret)
				vpbe_dev->current_out_index = i;
			return ret;
		}
	}
	return ret;
}

/**
 * vpbe_get_output - Get output
 * @vpbe_dev - vpbe device ptr
 *
 * return current vpbe output to the the index
 */
static unsigned int vpbe_get_output(struct vpbe_device *vpbe_dev)
{
	return vpbe_dev->current_out_index;
}

/**
 * vpbe_s_dv_timings - Set the given preset timings in the encoder
 *
 * Sets the timings if supported by the current encoder. Return the status.
 * 0 - success & -EINVAL on error
 */
static int vpbe_s_dv_timings(struct vpbe_device *vpbe_dev,
		    struct v4l2_dv_timings *dv_timings)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int out_index = vpbe_dev->current_out_index;
	struct vpbe_output *output = &cfg->outputs[out_index];
	int sd_index = vpbe_dev->current_sd_index;
	int ret, i;


	if (!(cfg->outputs[out_index].output.capabilities &
	    V4L2_OUT_CAP_DV_TIMINGS))
		return -EINVAL;

	for (i = 0; i < output->num_modes; i++) {
		if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS &&
		    !memcmp(&output->modes[i].dv_timings,
				dv_timings, sizeof(*dv_timings)))
			break;
	}
	if (i >= output->num_modes)
		return -EINVAL;
	vpbe_dev->current_timings = output->modes[i];
	mutex_lock(&vpbe_dev->lock);

	ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
					s_dv_timings, dv_timings);
	if (!ret && (vpbe_dev->amp != NULL)) {
		/* Call amplifier subdevice */
		ret = v4l2_subdev_call(vpbe_dev->amp, video,
				s_dv_timings, dv_timings);
	}
	/* set the lcd controller output for the given mode */
	if (!ret) {
		struct osd_state *osd_device = vpbe_dev->osd_device;

		osd_device->ops.set_left_margin(osd_device,
		vpbe_dev->current_timings.left_margin);
		osd_device->ops.set_top_margin(osd_device,
		vpbe_dev->current_timings.upper_margin);
	}
	mutex_unlock(&vpbe_dev->lock);

	return ret;
}

/**
 * vpbe_g_dv_timings - Get the timings in the current encoder
 *
 * Get the timings in the current encoder. Return the status. 0 - success
 * -EINVAL on error
 */
static int vpbe_g_dv_timings(struct vpbe_device *vpbe_dev,
		     struct v4l2_dv_timings *dv_timings)
{
	if (vpbe_dev->current_timings.timings_type &
	  VPBE_ENC_DV_TIMINGS) {
		*dv_timings = vpbe_dev->current_timings.dv_timings;
		return 0;
	}

	return -EINVAL;
}

/**
 * vpbe_enum_dv_timings - Enumerate the dv timings in the current encoder
 *
 * Get the timings in the current encoder. Return the status. 0 - success
 * -EINVAL on error
 */
static int vpbe_enum_dv_timings(struct vpbe_device *vpbe_dev,
			 struct v4l2_enum_dv_timings *timings)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int out_index = vpbe_dev->current_out_index;
	struct vpbe_output *output = &cfg->outputs[out_index];
	int j = 0;
	int i;

	if (!(output->output.capabilities & V4L2_OUT_CAP_DV_TIMINGS))
		return -EINVAL;

	for (i = 0; i < output->num_modes; i++) {
		if (output->modes[i].timings_type == VPBE_ENC_DV_TIMINGS) {
			if (j == timings->index)
				break;
			j++;
		}
	}

	if (i == output->num_modes)
		return -EINVAL;
	timings->timings = output->modes[i].dv_timings;
	return 0;
}

/**
 * vpbe_s_std - Set the given standard in the encoder
 *
 * Sets the standard if supported by the current encoder. Return the status.
 * 0 - success & -EINVAL on error
 */
static int vpbe_s_std(struct vpbe_device *vpbe_dev, v4l2_std_id std_id)
{
	struct vpbe_config *cfg = vpbe_dev->cfg;
	int out_index = vpbe_dev->current_out_index;
	int sd_index = vpbe_dev->current_sd_index;
	int ret;

	if (!(cfg->outputs[out_index].output.capabilities &
		V4L2_OUT_CAP_STD))
		return -EINVAL;

	ret = vpbe_get_std_info(vpbe_dev, std_id);
	if (ret)
		return ret;

	mutex_lock(&vpbe_dev->lock);

	ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video,
			       s_std_output, std_id);
	/* set the lcd controller output for the given mode */
	if (!ret) {
		struct osd_state *osd_device = vpbe_dev->osd_device;

		osd_device->ops.set_left_margin(osd_device,
		vpbe_dev->current_timings.left_margin);
		osd_device->ops.set_top_margin(osd_device,
		vpbe_dev->current_timings.upper_margin);
	}
	mutex_unlock(&vpbe_dev->lock);

	return ret;
}

/**
 * vpbe_g_std - Get the standard in the current encoder
 *
 * Get the standard in the current encoder. Return the status. 0 - success
 * -EINVAL on error
 */
static int vpbe_g_std(struct vpbe_device *vpbe_dev, v4l2_std_id *std_id)
{
	struct vpbe_enc_mode_info *cur_timings = &vpbe_dev->current_timings;

	if (cur_timings->timings_type & VPBE_ENC_STD) {
		*std_id = cur_timings->std_id;
		return 0;
	}

	return -EINVAL;
}

/**
 * vpbe_set_mode - Set mode in the current encoder using mode info
 *
 * Use the mode string to decide what timings to set in the encoder
 * This is typically useful when fbset command is used to change the current
 * timings by specifying a string to indicate the timings.
 */
static int vpbe_set_mode(struct vpbe_device *vpbe_dev,
			 struct vpbe_enc_mode_info *mode_info)
{
	struct vpbe_enc_mode_info *preset_mode = NULL;
	struct vpbe_config *cfg = vpbe_dev->cfg;
	struct v4l2_dv_timings dv_timings;
	struct osd_state *osd_device;
	int out_index = vpbe_dev->current_out_index;
	int ret = 0;
	int i;

	if ((NULL == mode_info) || (NULL == mode_info->name))
		return -EINVAL;

	for (i = 0; i < cfg->outputs[out_index].num_modes; i++) {
		if (!strcmp(mode_info->name,
		     cfg->outputs[out_index].modes[i].name)) {
			preset_mode = &cfg->outputs[out_index].modes[i];
			/*
			 * it may be one of the 3 timings type. Check and
			 * invoke right API
			 */
			if (preset_mode->timings_type & VPBE_ENC_STD)
				return vpbe_s_std(vpbe_dev,
						 preset_mode->std_id);
			if (preset_mode->timings_type &
						VPBE_ENC_DV_TIMINGS) {
				dv_timings =
					preset_mode->dv_timings;
				return vpbe_s_dv_timings(vpbe_dev, &dv_timings);
			}
		}
	}

	/* Only custom timing should reach here */
	if (preset_mode == NULL)
		return -EINVAL;

	mutex_lock(&vpbe_dev->lock);

	osd_device = vpbe_dev->osd_device;
	vpbe_dev->current_timings = *preset_mode;
	osd_device->ops.set_left_margin(osd_device,
		vpbe_dev->current_timings.left_margin);
	osd_device->ops.set_top_margin(osd_device,
		vpbe_dev->current_timings.upper_margin);

	mutex_unlock(&vpbe_dev->lock);

	return ret;
}

static int vpbe_set_default_mode(struct vpbe_device *vpbe_dev)
{
	int ret;

	ret = vpbe_get_std_info_by_name(vpbe_dev, def_mode);
	if (ret)
		return ret;

	/* set the default mode in the encoder */
	return vpbe_set_mode(vpbe_dev, &vpbe_dev->current_timings);
}

static int platform_device_get(struct device *dev, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct vpbe_device *vpbe_dev = data;

	if (strstr(pdev->name, "vpbe-osd") != NULL)
		vpbe_dev->osd_device = platform_get_drvdata(pdev);
	if (strstr(pdev->name, "vpbe-venc") != NULL)
		vpbe_dev->venc_device = dev_get_platdata(&pdev->dev);

	return 0;
}

/**
 * vpbe_initialize() - Initialize the vpbe display controller
 * @vpbe_dev - vpbe device ptr
 *
 * Master frame buffer device drivers calls this to initialize vpbe
 * display controller. This will then registers v4l2 device and the sub
 * devices and sets a current encoder sub device for display. v4l2 display
 * device driver is the master and frame buffer display device driver is
 * the slave. Frame buffer display driver checks the initialized during
 * probe and exit if not initialized. Returns status.
 */
static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
{
	struct encoder_config_info *enc_info;
	struct amp_config_info *amp_info;
	struct v4l2_subdev **enc_subdev;
	struct osd_state *osd_device;
	struct i2c_adapter *i2c_adap;
	int num_encoders;
	int ret = 0;
	int err;
	int i;

	/*
	 * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
	 * from the platform device by iteration of platform drivers and
	 * matching with device name
	 */
	if (NULL == vpbe_dev || NULL == dev) {
		printk(KERN_ERR "Null device pointers.\n");
		return -ENODEV;
	}

	if (vpbe_dev->initialized)
		return 0;

	mutex_lock(&vpbe_dev->lock);

	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		/* We have dac clock available for platform */
		vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
		if (IS_ERR(vpbe_dev->dac_clk)) {
			ret =  PTR_ERR(vpbe_dev->dac_clk);
			goto fail_mutex_unlock;
		}
		if (clk_prepare_enable(vpbe_dev->dac_clk)) {
			ret =  -ENODEV;
			goto fail_mutex_unlock;
		}
	}

	/* first enable vpss clocks */
	vpss_enable_clock(VPSS_VPBE_CLOCK, 1);

	/* First register a v4l2 device */
	ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
	if (ret) {
		v4l2_err(dev->driver,
			"Unable to register v4l2 device.\n");
		goto fail_clk_put;
	}
	v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");

	err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
			       platform_device_get);
	if (err < 0) {
		ret = err;
		goto fail_dev_unregister;
	}

	vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
					   vpbe_dev->cfg->venc.module_name);
	/* register venc sub device */
	if (vpbe_dev->venc == NULL) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"vpbe unable to init venc sub device\n");
		ret = -ENODEV;
		goto fail_dev_unregister;
	}
	/* initialize osd device */
	osd_device = vpbe_dev->osd_device;

	if (NULL != osd_device->ops.initialize) {
		err = osd_device->ops.initialize(osd_device);
		if (err) {
			v4l2_err(&vpbe_dev->v4l2_dev,
				 "unable to initialize the OSD device");
			err = -ENOMEM;
			goto fail_dev_unregister;
		}
	}

	/*
	 * Register any external encoders that are configured. At index 0 we
	 * store venc sd index.
	 */
	num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
	vpbe_dev->encoders = kmalloc(
				sizeof(struct v4l2_subdev *)*num_encoders,
				GFP_KERNEL);
	if (NULL == vpbe_dev->encoders) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"unable to allocate memory for encoders sub devices");
		ret = -ENOMEM;
		goto fail_dev_unregister;
	}

	i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
	for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
		if (i == 0) {
			/* venc is at index 0 */
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = vpbe_dev->venc;
			continue;
		}
		enc_info = &vpbe_dev->cfg->ext_encoders[i];
		if (enc_info->is_i2c) {
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = v4l2_i2c_new_subdev_board(
						&vpbe_dev->v4l2_dev, i2c_adap,
						&enc_info->board_info, NULL);
			if (*enc_subdev)
				v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  enc_info->module_name);
			else {
				v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
					 " failed to register",
					 enc_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
		} else
			v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
				 " currently not supported");
	}
	/* Add amplifier subdevice for dm365 */
	if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
			vpbe_dev->cfg->amp != NULL) {
		amp_info = vpbe_dev->cfg->amp;
		if (amp_info->is_i2c) {
			vpbe_dev->amp = v4l2_i2c_new_subdev_board(
			&vpbe_dev->v4l2_dev, i2c_adap,
			&amp_info->board_info, NULL);
			if (!vpbe_dev->amp) {
				v4l2_err(&vpbe_dev->v4l2_dev,
					 "amplifier %s failed to register",
					 amp_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
			v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  amp_info->module_name);
		} else {
			    vpbe_dev->amp = NULL;
			    v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
			    " currently not supported");
		}
	} else {
	    vpbe_dev->amp = NULL;
	}

	/* set the current encoder and output to that of venc by default */
	vpbe_dev->current_sd_index = 0;
	vpbe_dev->current_out_index = 0;

	mutex_unlock(&vpbe_dev->lock);

	printk(KERN_NOTICE "Setting default output to %s\n", def_output);
	ret = vpbe_set_default_output(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
			 def_output);
		return ret;
	}

	printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
	ret = vpbe_set_default_mode(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
			 def_mode);
		return ret;
	}
	vpbe_dev->initialized = 1;
	/* TBD handling of bootargs for default output and mode */
	return 0;

fail_kfree_encoders:
	kfree(vpbe_dev->encoders);
fail_dev_unregister:
	v4l2_device_unregister(&vpbe_dev->v4l2_dev);
fail_clk_put:
	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		clk_disable_unprepare(vpbe_dev->dac_clk);
		clk_put(vpbe_dev->dac_clk);
	}
fail_mutex_unlock:
	mutex_unlock(&vpbe_dev->lock);
	return ret;
}

/**
 * vpbe_deinitialize() - de-initialize the vpbe display controller
 * @dev - Master and slave device ptr
 *
 * vpbe_master and slave frame buffer devices calls this to de-initialize
 * the display controller. It is called when master and slave device
 * driver modules are removed and no longer requires the display controller.
 */
static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev)
{
	v4l2_device_unregister(&vpbe_dev->v4l2_dev);
	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		clk_disable_unprepare(vpbe_dev->dac_clk);
		clk_put(vpbe_dev->dac_clk);
	}

	kfree(vpbe_dev->amp);
	kfree(vpbe_dev->encoders);
	vpbe_dev->initialized = 0;
	/* disable vpss clocks */
	vpss_enable_clock(VPSS_VPBE_CLOCK, 0);
}

static struct vpbe_device_ops vpbe_dev_ops = {
	.g_cropcap = vpbe_g_cropcap,
	.enum_outputs = vpbe_enum_outputs,
	.set_output = vpbe_set_output,
	.get_output = vpbe_get_output,
	.s_dv_timings = vpbe_s_dv_timings,
	.g_dv_timings = vpbe_g_dv_timings,
	.enum_dv_timings = vpbe_enum_dv_timings,
	.s_std = vpbe_s_std,
	.g_std = vpbe_g_std,
	.initialize = vpbe_initialize,
	.deinitialize = vpbe_deinitialize,
	.get_mode_info = vpbe_get_current_mode_info,
	.set_mode = vpbe_set_mode,
};

static int vpbe_probe(struct platform_device *pdev)
{
	struct vpbe_device *vpbe_dev;
	struct vpbe_config *cfg;
	int ret = -EINVAL;

	if (pdev->dev.platform_data == NULL) {
		v4l2_err(pdev->dev.driver, "No platform data\n");
		return -ENODEV;
	}
	cfg = pdev->dev.platform_data;

	if (!cfg->module_name[0] ||
	    !cfg->osd.module_name[0] ||
	    !cfg->venc.module_name[0]) {
		v4l2_err(pdev->dev.driver, "vpbe display module names not"
			 " defined\n");
		return ret;
	}

	vpbe_dev = kzalloc(sizeof(*vpbe_dev), GFP_KERNEL);
	if (vpbe_dev == NULL) {
		v4l2_err(pdev->dev.driver, "Unable to allocate memory"
			 " for vpbe_device\n");
		return -ENOMEM;
	}
	vpbe_dev->cfg = cfg;
	vpbe_dev->ops = vpbe_dev_ops;
	vpbe_dev->pdev = &pdev->dev;

	if (cfg->outputs->num_modes > 0)
		vpbe_dev->current_timings = vpbe_dev->cfg->outputs[0].modes[0];
	else {
		kfree(vpbe_dev);
		return -ENODEV;
	}

	/* set the driver data in platform device */
	platform_set_drvdata(pdev, vpbe_dev);
	mutex_init(&vpbe_dev->lock);

	return 0;
}

static int vpbe_remove(struct platform_device *device)
{
	struct vpbe_device *vpbe_dev = platform_get_drvdata(device);

	kfree(vpbe_dev);

	return 0;
}

static struct platform_driver vpbe_driver = {
	.driver	= {
		.name	= "vpbe_controller",
		.owner	= THIS_MODULE,
	},
	.probe = vpbe_probe,
	.remove = vpbe_remove,
};

module_platform_driver(vpbe_driver);
