[PATCH 5/7] Celleb: Supports VFD on Celleb 2

Ishizaki Kou kou.ishizaki at toshiba.co.jp
Thu Sep 27 17:56:31 EST 2007


This is a patch to support VFD on Celleb 2.
VFD is a small LCD to show miscellaneous messages.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki at toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Kconfig
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
@@ -7,3 +7,9 @@ config PPC_CELLEB
 	select PPC_UDBG_BEAT
 	select USB_OHCI_BIG_ENDIAN_MMIO
 	select USB_EHCI_BIG_ENDIAN_MMIO
+	select PPC_RTAS
+
+config PPC_CELLEB2_INDICATOR
+	tristate "Support for Toshiba's Cell Reference Set 'Celleb 2's VFD"
+	default m
+	depends on PPC_CELLEB
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Makefile
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)	+= udbg_beat.o
 obj-$(CONFIG_SERIAL_TXX9)	+= scc_sio.o
 obj-$(CONFIG_SPU_BASE)		+= spu_priv1.o
+obj-$(CONFIG_PPC_CELLEB2_INDICATOR)	+= indicator.o
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/indicator.c
===================================================================
--- /dev/null
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/indicator.c
@@ -0,0 +1,202 @@
+/*
+ * LED/VFD support for Celleb
+ *
+ * (C) Copyright 2007 TOSHIBA CORPORATION
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/of.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+
+#include <asm/rtas.h>
+#include <asm/machdep.h>
+#include <asm/semaphore.h>
+
+static const u32 *display_cols;
+static u32 display_width, display_lines;
+static u32 token_display_character, token_set_indicator;
+static DECLARE_MUTEX(display_lock);
+static DECLARE_MUTEX(indicator_lock);
+
+static int celleb_display_show(struct seq_file *m, void *v)
+{
+	u32 i;
+
+	seq_printf(m, "--- Celleb Subdisplay ---\n");
+	seq_printf(m, "Lines: %u\n", display_lines);
+	if (display_cols)
+		for (i = 0; i < display_lines; i++)
+			seq_printf(m, "Columns(%u): %u\n", i, display_cols[i]);
+	else
+		seq_printf(m, "Columns(All): %u\n", display_width);
+	return 0;
+}
+
+static ssize_t celleb_display_write(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos)
+{
+	int rc;
+	size_t i;
+	char d;
+
+	rc = down_interruptible(&indicator_lock);
+	if (rc != 0)
+		return rc;
+	for (i = 0; i < count; i++) {
+		rc = get_user(d, &buf[i]);
+		if (rc != 0) {
+			up(&display_lock);
+			return rc;
+		}
+		do {
+			rc = rtas_call(token_display_character, 1, 1, NULL, d);
+		} while (rtas_busy_delay(rc));
+	}
+	up(&display_lock);
+	return i;
+}
+
+static int celleb_display_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, celleb_display_show, NULL);
+}
+
+static int celleb_indicator_show(struct seq_file *m, void *v)
+{
+	return 0;
+}
+
+static ssize_t celleb_indicator_write(struct file *file,
+		const char __user *buf, size_t count, loff_t *ppos)
+{
+	int rc;
+	size_t i;
+	char d;
+
+	rc = down_interruptible(&indicator_lock);
+	if (rc != 0)
+		return rc;
+	for (i = 0; i < count; i++) {
+		rc = get_user(d, &buf[i]);
+		if (rc != 0) {
+			up(&indicator_lock);
+			return rc;
+		}
+		do {
+			rc = rtas_call(token_set_indicator, 1, 1, NULL, d);
+		} while (rtas_busy_delay(rc));
+	}
+	up(&indicator_lock);
+	return i;
+}
+
+static int celleb_indicator_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, celleb_indicator_show, NULL);
+}
+
+const struct file_operations celleb_display_operations = {
+	.open		= celleb_display_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.write		= celleb_display_write,
+	.release	= single_release,
+};
+
+const struct file_operations celleb_indicator_operations = {
+	.open		= celleb_indicator_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.write		= celleb_indicator_write,
+	.release	= single_release,
+};
+
+static int __init celleb_indicator_init(void)
+{
+	struct device_node *rtas_node = NULL;
+	struct proc_dir_entry *entry;
+	const u32 *p;
+
+	if (!machine_is(celleb))
+		return -ENODEV;
+
+	rtas_node = of_find_node_by_name(NULL, "rtas");
+	if (rtas_node == NULL)
+		return -ENODEV;
+
+	display_cols = of_get_property(rtas_node,
+		"ibm,display-truncation-length", NULL);
+	if ((p = of_get_property(rtas_node,
+		"ibm,display-line-length", NULL)) != NULL)
+		display_width = *p;
+	else
+		display_width = 0;
+	if ((p = of_get_property(rtas_node,
+		"ibm,display-number-of-lines", NULL)) != NULL)
+		display_lines = *p;
+	else
+		display_lines = 0;
+
+	if ((p = of_get_property(rtas_node,
+		"display-character", NULL)) != NULL)
+		token_display_character = *p;
+	else
+		token_display_character = 0;
+
+	if ((p = of_get_property(rtas_node,
+		"set-indicator", NULL)) != NULL)
+		token_set_indicator = *p;
+	else
+		token_set_indicator = 0;
+
+	if (token_display_character != 0
+		&& display_lines != 0
+		&& (display_width != 0 || display_cols)) {
+		entry = create_proc_entry("ppc64/rtas/toshiba,display",
+			S_IRUGO|S_IWUSR, NULL);
+		if (entry)
+			entry->proc_fops = &celleb_display_operations;
+	}
+
+	if (token_set_indicator != 0) {
+		entry = create_proc_entry("ppc64/rtas/toshiba,indicator",
+			S_IRUGO|S_IWUSR, NULL);
+		if (entry)
+			entry->proc_fops = &celleb_indicator_operations;
+	}
+	of_node_put(rtas_node);
+
+	return 0;
+}
+
+static void __exit celleb_indicator_exit(void)
+{
+	remove_proc_entry("ppc64/rtas/toshiba,display", NULL);
+	remove_proc_entry("ppc64/rtas/toshiba,indicator", NULL);
+}
+
+module_init(celleb_indicator_init);
+module_exit(celleb_indicator_exit);
+MODULE_AUTHOR("Toshiba Corporation");
+MODULE_DESCRIPTION("VFD/LED support for Toshiba Cell Reference Set");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");



More information about the Linuxppc-dev mailing list