/*
 *  Driver for PC-speaker like devices found on various Sparc systems.
 *
 *  Copyright (c) 2002 Vojtech Pavlik
 *  Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net)
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/platform_device.h>

#include <asm/io.h>
#include <asm/ebus.h>
#include <asm/isa.h>

MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
MODULE_DESCRIPTION("Sparc Speaker beeper driver");
MODULE_LICENSE("GPL");

struct sparcspkr_state {
	const char		*name;
	unsigned long		iobase;
	int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
	spinlock_t		lock;
	struct input_dev	*input_dev;
};

static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
	struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
	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 = 1193182 / value;

	spin_lock_irqsave(&state->lock, flags);

	/* EBUS speaker only has on/off state, the frequency does not
	 * appear to be programmable.
	 */
	if (state->iobase & 0x2UL)
		outb(!!count, state->iobase);
	else
		outl(!!count, state->iobase);

	spin_unlock_irqrestore(&state->lock, flags);

	return 0;
}

static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
	struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent);
	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 = 1193182 / value;

	spin_lock_irqsave(&state->lock, flags);

	if (count) {
		/* enable counter 2 */
		outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61);
		/* set command for counter 2, 2 byte write */
		outb(0xB6, state->iobase + 0x43);
		/* select desired HZ */
		outb(count & 0xff, state->iobase + 0x42);
		outb((count >> 8) & 0xff, state->iobase + 0x42);
	} else {
		/* disable counter 2 */
		outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61);
	}

	spin_unlock_irqrestore(&state->lock, flags);

	return 0;
}

static int __devinit sparcspkr_probe(struct device *dev)
{
	struct sparcspkr_state *state = dev_get_drvdata(dev);
	struct input_dev *input_dev;
	int error;

	input_dev = input_allocate_device();
	if (!input_dev)
		return -ENOMEM;

	input_dev->name = state->name;
	input_dev->phys = "sparc/input0";
	input_dev->id.bustype = BUS_ISA;
	input_dev->id.vendor = 0x001f;
	input_dev->id.product = 0x0001;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = dev;

	input_dev->evbit[0] = BIT_MASK(EV_SND);
	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);

	input_dev->event = state->event;

	error = input_register_device(input_dev);
	if (error) {
		input_free_device(input_dev);
		return error;
	}

	state->input_dev = input_dev;

	return 0;
}

static int __devexit sparcspkr_remove(struct of_device *dev)
{
	struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
	struct input_dev *input_dev = state->input_dev;

	/* turn off the speaker */
	state->event(input_dev, EV_SND, SND_BELL, 0);

	input_unregister_device(input_dev);

	dev_set_drvdata(&dev->dev, NULL);
	kfree(state);

	return 0;
}

static int sparcspkr_shutdown(struct of_device *dev)
{
	struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
	struct input_dev *input_dev = state->input_dev;

	/* turn off the speaker */
	state->event(input_dev, EV_SND, SND_BELL, 0);

	return 0;
}

static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match)
{
	struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
	struct sparcspkr_state *state;
	int err;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	state->name = "Sparc EBUS Speaker";
	state->iobase = edev->resource[0].start;
	state->event = ebus_spkr_event;
	spin_lock_init(&state->lock);

	dev_set_drvdata(&dev->dev, state);

	err = sparcspkr_probe(&dev->dev);
	if (err) {
		dev_set_drvdata(&dev->dev, NULL);
		kfree(state);
	}

	return 0;
}

static struct of_device_id ebus_beep_match[] = {
	{
		.name = "beep",
	},
	{},
};

static struct of_platform_driver ebus_beep_driver = {
	.name		= "beep",
	.match_table	= ebus_beep_match,
	.probe		= ebus_beep_probe,
	.remove		= __devexit_p(sparcspkr_remove),
	.shutdown	= sparcspkr_shutdown,
};

static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match)
{
	struct sparc_isa_device *idev = to_isa_device(&dev->dev);
	struct sparcspkr_state *state;
	int err;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	state->name = "Sparc ISA Speaker";
	state->iobase = idev->resource.start;
	state->event = isa_spkr_event;
	spin_lock_init(&state->lock);

	dev_set_drvdata(&dev->dev, state);

	err = sparcspkr_probe(&dev->dev);
	if (err) {
		dev_set_drvdata(&dev->dev, NULL);
		kfree(state);
	}

	return 0;
}

static struct of_device_id isa_beep_match[] = {
	{
		.name = "dma",
	},
	{},
};

static struct of_platform_driver isa_beep_driver = {
	.name		= "beep",
	.match_table	= isa_beep_match,
	.probe		= isa_beep_probe,
	.remove		= __devexit_p(sparcspkr_remove),
	.shutdown	= sparcspkr_shutdown,
};

static int __init sparcspkr_init(void)
{
	int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type);

	if (!err) {
		err = of_register_driver(&isa_beep_driver, &isa_bus_type);
		if (err)
			of_unregister_driver(&ebus_beep_driver);
	}

	return err;
}

static void __exit sparcspkr_exit(void)
{
	of_unregister_driver(&ebus_beep_driver);
	of_unregister_driver(&isa_beep_driver);
}

module_init(sparcspkr_init);
module_exit(sparcspkr_exit);
