/* * 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);