/*
 * 7 Segment LED routines
 * Based on RBTX49xx patch from CELF patch archive.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * (C) Copyright TOSHIBA CORPORATION 2005-2007
 * All Rights Reserved.
 */
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/map_to_7segment.h>
#include <asm/txx9/generic.h>

static unsigned int tx_7segled_num;
static void (*tx_7segled_putc)(unsigned int pos, unsigned char val);

void __init txx9_7segled_init(unsigned int num,
			      void (*putc)(unsigned int pos, unsigned char val))
{
	tx_7segled_num = num;
	tx_7segled_putc = putc;
}

static SEG7_CONVERSION_MAP(txx9_seg7map, MAP_ASCII7SEG_ALPHANUM_LC);

int txx9_7segled_putc(unsigned int pos, char c)
{
	if (pos >= tx_7segled_num)
		return -EINVAL;
	c = map_to_seg7(&txx9_seg7map, c);
	if (c < 0)
		return c;
	tx_7segled_putc(pos, c);
	return 0;
}

static ssize_t ascii_store(struct sys_device *dev,
			   struct sysdev_attribute *attr,
			   const char *buf, size_t size)
{
	unsigned int ch = dev->id;
	txx9_7segled_putc(ch, buf[0]);
	return size;
}

static ssize_t raw_store(struct sys_device *dev,
			 struct sysdev_attribute *attr,
			 const char *buf, size_t size)
{
	unsigned int ch = dev->id;
	tx_7segled_putc(ch, buf[0]);
	return size;
}

static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store);
static SYSDEV_ATTR(raw, 0200, NULL, raw_store);

static ssize_t map_seg7_show(struct sysdev_class *class,
			     struct sysdev_class_attribute *attr,
			     char *buf)
{
	memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map));
	return sizeof(txx9_seg7map);
}

static ssize_t map_seg7_store(struct sysdev_class *class,
			      struct sysdev_class_attribute *attr,
			      const char *buf, size_t size)
{
	if (size != sizeof(txx9_seg7map))
		return -EINVAL;
	memcpy(&txx9_seg7map, buf, size);
	return size;
}

static SYSDEV_CLASS_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store);

static struct sysdev_class tx_7segled_sysdev_class = {
	.name	= "7segled",
};

static int __init tx_7segled_init_sysfs(void)
{
	int error, i;
	if (!tx_7segled_num)
		return -ENODEV;
	error = sysdev_class_register(&tx_7segled_sysdev_class);
	if (error)
		return error;
	error = sysdev_class_create_file(&tx_7segled_sysdev_class,
					 &attr_map_seg7);
	if (error)
		return error;
	for (i = 0; i < tx_7segled_num; i++) {
		struct sys_device *dev;
		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
		if (!dev) {
			error = -ENODEV;
			break;
		}
		dev->id = i;
		dev->cls = &tx_7segled_sysdev_class;
		error = sysdev_register(dev);
		if (!error) {
			sysdev_create_file(dev, &attr_ascii);
			sysdev_create_file(dev, &attr_raw);
		}
	}
	return error;
}

device_initcall(tx_7segled_init_sysfs);
