drivers/input/misc/Kconfig | 12 +++ drivers/input/misc/Makefile | 1 drivers/input/misc/nslu2spkr.c | 148 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+) --- linux-2.6.15/drivers/input/misc/Kconfig 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/input/misc/Kconfig 1970-01-01 00:00:00.000000000 +0000 @@ -40,6 +40,18 @@ config INPUT_M68K_BEEP tristate "M68k Beeper support" depends on M68K +config INPUT_NSLU2_BEEPER + tristate "NSLU2 Beeper support" + depends on MACH_NSLU2 + help + Say Y here if you want the embedded beeper on the LinkSys NSLU2 + to be used for bells and whistles. + + If unsure, say Y. + + To compile this driver as a module, choose M here: the + module will be called nslu2spkr. + config INPUT_UINPUT tristate "User level driver support" help --- linux-2.6.15/drivers/input/misc/Makefile 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/input/misc/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -10,3 +10,4 @@ obj-$(CONFIG_INPUT_M68K_BEEP) += m68ksp obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o +obj-$(CONFIG_INPUT_NSLU2_BEEPER) += nslu2spkr.o --- linux-2.6.15/drivers/input/misc/nslu2spkr.c 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.15/drivers/input/misc/nslu2spkr.c 1970-01-01 00:00:00.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * drivers/input/misc/nslu2spkr.c + * + * NSLU2 Beeper driver + * + * Copyright (C) 2005 Tower Technologies + * + * based on nslu2-io.c + * Copyright (C) 2004 Karen Spearel + * + * Author: Alessandro Zummo + * Maintainers: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static unsigned int beep_on_startup = 1; +module_param(beep_on_startup, bool, 0); +MODULE_PARM_DESC(beep_on_startup, "Play a beep on module startup"); + +DEFINE_SPINLOCK(beep_lock); + +static int nslu2_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) +{ + unsigned int count = 0; + unsigned long flags; + + if (type != EV_SND) + return -1; + + switch (code) { + case SND_BELL: + if (value) value = 1000; + case SND_TONE: + break; + default: + return -1; + } + + if (value > 20 && value < 32767) + count = (NSLU2_FREQ / (value*4)) - 1; + + spin_lock_irqsave(&beep_lock, flags); + + if (count) { + + gpio_line_config(NSLU2_GPIO_BUZZ, IXP4XX_GPIO_OUT); + gpio_line_set(NSLU2_GPIO_BUZZ, IXP4XX_GPIO_LOW); + + *IXP4XX_OSRT2 = (count & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; + + } else { + + gpio_line_config(NSLU2_GPIO_BUZZ, IXP4XX_GPIO_IN); + gpio_line_set(NSLU2_GPIO_BUZZ, IXP4XX_GPIO_HIGH); + + *IXP4XX_OSRT2 = 0; + } + + spin_unlock_irqrestore(&beep_lock, flags); + + return 0; +} + +static struct input_dev nslu2_spkr_dev = { + .phys = "ixp420/gpio4", + .name = "NSLU2 Beeper", + .evbit[0] = BIT(EV_SND), + .sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE), + .event = nslu2_spkr_event, + .id = { + .bustype = BUS_HOST, + .vendor = 0x001f, + .product = 0x0001, + .version = 0x0100 + } +}; + +static irqreturn_t nslu2_spkr_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + /* clear interrupt */ + *IXP4XX_OSST = IXP4XX_OSST_TIMER_2_PEND; + + /* flip the beeper output */ + *IXP4XX_GPIO_GPOUTR ^= NSLU2_BZ_BM; + + return IRQ_HANDLED; +} + +static int __init nslu2_spkr_init(void) +{ + if (!(machine_is_nslu2())) + return -ENODEV; + + if (request_irq(IRQ_IXP4XX_TIMER2, &nslu2_spkr_handler, + SA_INTERRUPT | SA_TIMER, "nslu2-beeper", NULL < 0)) { + + printk(KERN_INFO "NSLU2 beeper: IRQ %d not available\n", + IRQ_IXP4XX_TIMER2); + + return -EIO; + } + + input_register_device(&nslu2_spkr_dev); + + /* do a little beep to tell the world we are alive */ + if (beep_on_startup) + { + nslu2_spkr_event(NULL, EV_SND, SND_TONE, 440); + msleep(120); + nslu2_spkr_event(NULL, EV_SND, SND_TONE, 0); + } + + printk(KERN_INFO "NSLU2: beeper\n"); + return 0; +} + +static void __exit nslu2_spkr_exit(void) +{ + input_unregister_device(&nslu2_spkr_dev); + + disable_irq(IRQ_IXP4XX_TIMER2); + + /* turn it off */ + nslu2_spkr_event(NULL, EV_SND, SND_BELL, 0); + + free_irq(IRQ_IXP4XX_TIMER2, NULL); +} + +module_init(nslu2_spkr_init); +module_exit(nslu2_spkr_exit); + +MODULE_AUTHOR("Alessandro Zummo "); +MODULE_DESCRIPTION("NSLU2 Beeper driver"); +MODULE_LICENSE("GPL");