Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | /* * 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/device.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 device *dev, struct device_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 device *dev, struct device_attribute *attr, const char *buf, size_t size) { unsigned int ch = dev->id; tx_7segled_putc(ch, buf[0]); return size; } static DEVICE_ATTR_WO(ascii); static DEVICE_ATTR_WO(raw); static ssize_t map_seg7_show(struct device *dev, struct device_attribute *attr, char *buf) { memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map)); return sizeof(txx9_seg7map); } static ssize_t map_seg7_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { if (size != sizeof(txx9_seg7map)) return -EINVAL; memcpy(&txx9_seg7map, buf, size); return size; } static DEVICE_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store); static struct bus_type tx_7segled_subsys = { .name = "7segled", .dev_name = "7segled", }; static void tx_7segled_release(struct device *dev) { kfree(dev); } static int __init tx_7segled_init_sysfs(void) { int error, i; if (!tx_7segled_num) return -ENODEV; error = subsys_system_register(&tx_7segled_subsys, NULL); if (error) return error; error = device_create_file(tx_7segled_subsys.dev_root, &dev_attr_map_seg7); if (error) return error; for (i = 0; i < tx_7segled_num; i++) { struct device *dev; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { error = -ENODEV; break; } dev->id = i; dev->bus = &tx_7segled_subsys; dev->release = &tx_7segled_release; error = device_register(dev); if (error) { put_device(dev); return error; } device_create_file(dev, &dev_attr_ascii); device_create_file(dev, &dev_attr_raw); } return error; } device_initcall(tx_7segled_init_sysfs); |