/*
 *  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>
#include <linux/kdev_t.h>
#include <linux/slab.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 (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,
						     MKDEV(0, 0), new_dev,
						     "display%d", new_dev->idx);
			if (!IS_ERR(new_dev->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");

