/*
 *  display-sysfs.c - Display output driver sysfs interface
 *
 *  Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  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; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  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/module.h>
#include <linux/display.h>
#include <linux/ctype.h>
#include <linux/idr.h>
#include <linux/err.h>

static ssize_t display_show_name(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct display_device *dsp = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
}

static ssize_t display_show_type(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct display_device *dsp = dev_get_drvdata(dev);
	return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
}

static ssize_t display_show_contrast(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct display_device *dsp = dev_get_drvdata(dev);
	ssize_t rc = -ENXIO;

	mutex_lock(&dsp->lock);
	if (likely(dsp->driver) && dsp->driver->get_contrast)
		rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
	mutex_unlock(&dsp->lock);
	return rc;
}

static ssize_t display_store_contrast(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct display_device *dsp = dev_get_drvdata(dev);
	ssize_t ret = -EINVAL, size;
	int contrast;
	char *endp;

	contrast = simple_strtoul(buf, &endp, 0);
	size = endp - buf;

	if (*endp && isspace(*endp))
		size++;

	if (size != count)
		return ret;

	mutex_lock(&dsp->lock);
	if (likely(dsp->driver && dsp->driver->set_contrast)) {
		pr_debug("display: set contrast to %d\n", contrast);
		dsp->driver->set_contrast(dsp, contrast);
		ret = count;
	}
	mutex_unlock(&dsp->lock);
	return ret;
}

static ssize_t display_show_max_contrast(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct display_device *dsp = dev_get_drvdata(dev);
	ssize_t rc = -ENXIO;

	mutex_lock(&dsp->lock);
	if (likely(dsp->driver))
		rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
	mutex_unlock(&dsp->lock);
	return rc;
}

static struct device_attribute display_attrs[] = {
	__ATTR(name, S_IRUGO, display_show_name, NULL),
	__ATTR(type, S_IRUGO, display_show_type, NULL),
	__ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
	__ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
};

static int display_suspend(struct device *dev, pm_message_t state)
{
	struct display_device *dsp = dev_get_drvdata(dev);

	mutex_lock(&dsp->lock);
	if (likely(dsp->driver->suspend))
		dsp->driver->suspend(dsp, state);
	mutex_unlock(&dsp->lock);
	return 0;
};

static int display_resume(struct device *dev)
{
	struct display_device *dsp = dev_get_drvdata(dev);

	mutex_lock(&dsp->lock);
	if (likely(dsp->driver->resume))
		dsp->driver->resume(dsp);
	mutex_unlock(&dsp->lock);
	return 0;
};

static struct mutex allocated_dsp_lock;
static DEFINE_IDR(allocated_dsp);
static struct class *display_class;

struct display_device *display_device_register(struct display_driver *driver,
						struct device *parent, void *devdata)
{
	struct display_device *new_dev = NULL;
	int ret = -EINVAL;

	if (unlikely(!driver))
		return ERR_PTR(ret);

	mutex_lock(&allocated_dsp_lock);
	ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
	mutex_unlock(&allocated_dsp_lock);
	if (!ret)
		return ERR_PTR(ret);

	new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
	if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
		// Reserve the index for this display
		mutex_lock(&allocated_dsp_lock);
		ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
		mutex_unlock(&allocated_dsp_lock);

		if (!ret) {
			new_dev->dev = device_create(display_class, parent, 0,
						"display%d", new_dev->idx);
			if (!IS_ERR(new_dev->dev)) {
				dev_set_drvdata(new_dev->dev, new_dev);
				new_dev->parent = parent;
				new_dev->driver = driver;
				mutex_init(&new_dev->lock);
				return new_dev;
			}
			mutex_lock(&allocated_dsp_lock);
			idr_remove(&allocated_dsp, new_dev->idx);
			mutex_unlock(&allocated_dsp_lock);
			ret = -EINVAL;
		}
	}
	kfree(new_dev);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(display_device_register);

void display_device_unregister(struct display_device *ddev)
{
	if (!ddev)
		return;
	// Free device
	mutex_lock(&ddev->lock);
	device_unregister(ddev->dev);
	mutex_unlock(&ddev->lock);
	// Mark device index as avaliable
	mutex_lock(&allocated_dsp_lock);
	idr_remove(&allocated_dsp, ddev->idx);
	mutex_unlock(&allocated_dsp_lock);
	kfree(ddev);
}
EXPORT_SYMBOL(display_device_unregister);

static int __init display_class_init(void)
{
	display_class = class_create(THIS_MODULE, "display");
	if (IS_ERR(display_class)) {
		printk(KERN_ERR "Failed to create display class\n");
		display_class = NULL;
		return -EINVAL;
	}
	display_class->dev_attrs = display_attrs;
	display_class->suspend = display_suspend;
	display_class->resume = display_resume;
	mutex_init(&allocated_dsp_lock);
	return 0;
}

static void __exit display_class_exit(void)
{
	class_destroy(display_class);
}

module_init(display_class_init);
module_exit(display_class_exit);

MODULE_DESCRIPTION("Display Hardware handling");
MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
MODULE_LICENSE("GPL");

