1/* 2 * 7 Segment LED routines 3 * Based on RBTX49xx patch from CELF patch archive. 4 * 5 * This file is subject to the terms and conditions of the GNU General Public 6 * License. See the file "COPYING" in the main directory of this archive 7 * for more details. 8 * 9 * (C) Copyright TOSHIBA CORPORATION 2005-2007 10 * All Rights Reserved. 11 */ 12#include <linux/sysdev.h> 13#include <linux/slab.h> 14#include <linux/map_to_7segment.h> 15#include <asm/txx9/generic.h> 16 17static unsigned int tx_7segled_num; 18static void (*tx_7segled_putc)(unsigned int pos, unsigned char val); 19 20void __init txx9_7segled_init(unsigned int num, 21 void (*putc)(unsigned int pos, unsigned char val)) 22{ 23 tx_7segled_num = num; 24 tx_7segled_putc = putc; 25} 26 27static SEG7_CONVERSION_MAP(txx9_seg7map, MAP_ASCII7SEG_ALPHANUM_LC); 28 29int txx9_7segled_putc(unsigned int pos, char c) 30{ 31 if (pos >= tx_7segled_num) 32 return -EINVAL; 33 c = map_to_seg7(&txx9_seg7map, c); 34 if (c < 0) 35 return c; 36 tx_7segled_putc(pos, c); 37 return 0; 38} 39 40static ssize_t ascii_store(struct sys_device *dev, 41 struct sysdev_attribute *attr, 42 const char *buf, size_t size) 43{ 44 unsigned int ch = dev->id; 45 txx9_7segled_putc(ch, buf[0]); 46 return size; 47} 48 49static ssize_t raw_store(struct sys_device *dev, 50 struct sysdev_attribute *attr, 51 const char *buf, size_t size) 52{ 53 unsigned int ch = dev->id; 54 tx_7segled_putc(ch, buf[0]); 55 return size; 56} 57 58static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store); 59static SYSDEV_ATTR(raw, 0200, NULL, raw_store); 60 61static ssize_t map_seg7_show(struct sysdev_class *class, 62 struct sysdev_class_attribute *attr, 63 char *buf) 64{ 65 memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map)); 66 return sizeof(txx9_seg7map); 67} 68 69static ssize_t map_seg7_store(struct sysdev_class *class, 70 struct sysdev_class_attribute *attr, 71 const char *buf, size_t size) 72{ 73 if (size != sizeof(txx9_seg7map)) 74 return -EINVAL; 75 memcpy(&txx9_seg7map, buf, size); 76 return size; 77} 78 79static SYSDEV_CLASS_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store); 80 81static struct sysdev_class tx_7segled_sysdev_class = { 82 .name = "7segled", 83}; 84 85static int __init tx_7segled_init_sysfs(void) 86{ 87 int error, i; 88 if (!tx_7segled_num) 89 return -ENODEV; 90 error = sysdev_class_register(&tx_7segled_sysdev_class); 91 if (error) 92 return error; 93 error = sysdev_class_create_file(&tx_7segled_sysdev_class, 94 &attr_map_seg7); 95 if (error) 96 return error; 97 for (i = 0; i < tx_7segled_num; i++) { 98 struct sys_device *dev; 99 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 100 if (!dev) { 101 error = -ENODEV; 102 break; 103 } 104 dev->id = i; 105 dev->cls = &tx_7segled_sysdev_class; 106 error = sysdev_register(dev); 107 if (!error) { 108 sysdev_create_file(dev, &attr_ascii); 109 sysdev_create_file(dev, &attr_raw); 110 } 111 } 112 return error; 113} 114 115device_initcall(tx_7segled_init_sysfs); 116