/*
 * Copyright (C) 2006 - 2007 Ivo van Doorn
 * Copyright (C) 2007 Dmitry Torokhov
 *
 * 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.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/capability.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/rfkill.h>

MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("RF switch support");
MODULE_LICENSE("GPL");

static LIST_HEAD(rfkill_list);	/* list of registered rf switches */
static DEFINE_MUTEX(rfkill_mutex);

static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];


static void rfkill_led_trigger(struct rfkill *rfkill,
			       enum rfkill_state state)
{
#ifdef CONFIG_RFKILL_LEDS
	struct led_trigger *led = &rfkill->led_trigger;

	if (!led->name)
		return;
	if (state == RFKILL_STATE_OFF)
		led_trigger_event(led, LED_OFF);
	else
		led_trigger_event(led, LED_FULL);
#endif /* CONFIG_RFKILL_LEDS */
}

static int rfkill_toggle_radio(struct rfkill *rfkill,
				enum rfkill_state state)
{
	int retval;

	retval = mutex_lock_interruptible(&rfkill->mutex);
	if (retval)
		return retval;

	if (state != rfkill->state) {
		retval = rfkill->toggle_radio(rfkill->data, state);
		if (!retval) {
			rfkill->state = state;
			rfkill_led_trigger(rfkill, state);
		}
	}

	mutex_unlock(&rfkill->mutex);
	return retval;
}

/**
 * rfkill_switch_all - Toggle state of all switches of given type
 * @type: type of interfaces to be affeceted
 * @state: the new state
 *
 * This function toggles state of all switches of given type unless
 * a specific switch is claimed by userspace in which case it is
 * left alone.
 */

void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
{
	struct rfkill *rfkill;

	mutex_lock(&rfkill_mutex);

	rfkill_states[type] = state;

	list_for_each_entry(rfkill, &rfkill_list, node) {
		if (!rfkill->user_claim)
			rfkill_toggle_radio(rfkill, state);
	}

	mutex_unlock(&rfkill_mutex);
}
EXPORT_SYMBOL(rfkill_switch_all);

static ssize_t rfkill_name_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%s\n", rfkill->name);
}

static ssize_t rfkill_type_show(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);
	const char *type;

	switch (rfkill->type) {
	case RFKILL_TYPE_WLAN:
		type = "wlan";
		break;
	case RFKILL_TYPE_BLUETOOTH:
		type = "bluetooth";
		break;
	case RFKILL_TYPE_UWB:
		type = "ultrawideband";
		break;
	default:
		BUG();
	}

	return sprintf(buf, "%s\n", type);
}

static ssize_t rfkill_state_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%d\n", rfkill->state);
}

static ssize_t rfkill_state_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct rfkill *rfkill = to_rfkill(dev);
	unsigned int state = simple_strtoul(buf, NULL, 0);
	int error;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	error = rfkill_toggle_radio(rfkill,
			state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
	if (error)
		return error;

	return count;
}

static ssize_t rfkill_claim_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct rfkill *rfkill = to_rfkill(dev);

	return sprintf(buf, "%d", rfkill->user_claim);
}

static ssize_t rfkill_claim_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct rfkill *rfkill = to_rfkill(dev);
	bool claim = !!simple_strtoul(buf, NULL, 0);
	int error;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	/*
	 * Take the global lock to make sure the kernel is not in
	 * the middle of rfkill_switch_all
	 */
	error = mutex_lock_interruptible(&rfkill_mutex);
	if (error)
		return error;

	if (rfkill->user_claim_unsupported) {
		error = -EOPNOTSUPP;
		goto out_unlock;
	}
	if (rfkill->user_claim != claim) {
		if (!claim)
			rfkill_toggle_radio(rfkill,
					    rfkill_states[rfkill->type]);
		rfkill->user_claim = claim;
	}

out_unlock:
	mutex_unlock(&rfkill_mutex);

	return error ? error : count;
}

static struct device_attribute rfkill_dev_attrs[] = {
	__ATTR(name, S_IRUGO, rfkill_name_show, NULL),
	__ATTR(type, S_IRUGO, rfkill_type_show, NULL),
	__ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
	__ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
	__ATTR_NULL
};

static void rfkill_release(struct device *dev)
{
	struct rfkill *rfkill = to_rfkill(dev);

	kfree(rfkill);
	module_put(THIS_MODULE);
}

#ifdef CONFIG_PM
static int rfkill_suspend(struct device *dev, pm_message_t state)
{
	struct rfkill *rfkill = to_rfkill(dev);

	if (dev->power.power_state.event != state.event) {
		if (state.event == PM_EVENT_SUSPEND) {
			mutex_lock(&rfkill->mutex);

			if (rfkill->state == RFKILL_STATE_ON)
				rfkill->toggle_radio(rfkill->data,
						     RFKILL_STATE_OFF);

			mutex_unlock(&rfkill->mutex);
		}

		dev->power.power_state = state;
	}

	return 0;
}

static int rfkill_resume(struct device *dev)
{
	struct rfkill *rfkill = to_rfkill(dev);

	if (dev->power.power_state.event != PM_EVENT_ON) {
		mutex_lock(&rfkill->mutex);

		if (rfkill->state == RFKILL_STATE_ON)
			rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON);

		mutex_unlock(&rfkill->mutex);
	}

	dev->power.power_state = PMSG_ON;
	return 0;
}
#else
#define rfkill_suspend NULL
#define rfkill_resume NULL
#endif

static struct class rfkill_class = {
	.name		= "rfkill",
	.dev_release	= rfkill_release,
	.dev_attrs	= rfkill_dev_attrs,
	.suspend	= rfkill_suspend,
	.resume		= rfkill_resume,
};

static int rfkill_add_switch(struct rfkill *rfkill)
{
	int retval;

	retval = mutex_lock_interruptible(&rfkill_mutex);
	if (retval)
		return retval;

	retval = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]);
	if (retval)
		goto out;

	list_add_tail(&rfkill->node, &rfkill_list);

 out:
	mutex_unlock(&rfkill_mutex);
	return retval;
}

static void rfkill_remove_switch(struct rfkill *rfkill)
{
	mutex_lock(&rfkill_mutex);
	list_del_init(&rfkill->node);
	rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF);
	mutex_unlock(&rfkill_mutex);
}

/**
 * rfkill_allocate - allocate memory for rfkill structure.
 * @parent: device that has rf switch on it
 * @type: type of the switch (RFKILL_TYPE_*)
 *
 * This function should be called by the network driver when it needs
 * rfkill structure. Once the structure is allocated the driver shoud
 * finish its initialization by setting name, private data, enable_radio
 * and disable_radio methods and then register it with rfkill_register().
 * NOTE: If registration fails the structure shoudl be freed by calling
 * rfkill_free() otherwise rfkill_unregister() should be used.
 */
struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type)
{
	struct rfkill *rfkill;
	struct device *dev;

	rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
	if (!rfkill)
		return NULL;

	mutex_init(&rfkill->mutex);
	INIT_LIST_HEAD(&rfkill->node);
	rfkill->type = type;

	dev = &rfkill->dev;
	dev->class = &rfkill_class;
	dev->parent = parent;
	device_initialize(dev);

	__module_get(THIS_MODULE);

	return rfkill;
}
EXPORT_SYMBOL(rfkill_allocate);

/**
 * rfkill_free - Mark rfkill structure for deletion
 * @rfkill: rfkill structure to be destroyed
 *
 * Decrements reference count of rfkill structure so it is destoryed.
 * Note that rfkill_free() should _not_ be called after rfkill_unregister().
 */
void rfkill_free(struct rfkill *rfkill)
{
	if (rfkill)
		put_device(&rfkill->dev);
}
EXPORT_SYMBOL(rfkill_free);

static void rfkill_led_trigger_register(struct rfkill *rfkill)
{
#ifdef CONFIG_RFKILL_LEDS
	int error;

	rfkill->led_trigger.name = rfkill->dev.bus_id;
	error = led_trigger_register(&rfkill->led_trigger);
	if (error)
		rfkill->led_trigger.name = NULL;
#endif /* CONFIG_RFKILL_LEDS */
}

static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
{
#ifdef CONFIG_RFKILL_LEDS
	if (rfkill->led_trigger.name)
		led_trigger_unregister(&rfkill->led_trigger);
#endif
}

/**
 * rfkill_register - Register a rfkill structure.
 * @rfkill: rfkill structure to be registered
 *
 * This function should be called by the network driver when the rfkill
 * structure needs to be registered. Immediately from registration the
 * switch driver should be able to service calls to toggle_radio.
 */
int rfkill_register(struct rfkill *rfkill)
{
	static atomic_t rfkill_no = ATOMIC_INIT(0);
	struct device *dev = &rfkill->dev;
	int error;

	if (!rfkill->toggle_radio)
		return -EINVAL;

	error = rfkill_add_switch(rfkill);
	if (error)
		return error;

	snprintf(dev->bus_id, sizeof(dev->bus_id),
		 "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);

	error = device_add(dev);
	if (error) {
		rfkill_remove_switch(rfkill);
		return error;
	}
	rfkill_led_trigger_register(rfkill);

	return 0;
}
EXPORT_SYMBOL(rfkill_register);

/**
 * rfkill_unregister - Uegister a rfkill structure.
 * @rfkill: rfkill structure to be unregistered
 *
 * This function should be called by the network driver during device
 * teardown to destroy rfkill structure. Note that rfkill_free() should
 * _not_ be called after rfkill_unregister().
 */
void rfkill_unregister(struct rfkill *rfkill)
{
	rfkill_led_trigger_unregister(rfkill);
	device_del(&rfkill->dev);
	rfkill_remove_switch(rfkill);
	put_device(&rfkill->dev);
}
EXPORT_SYMBOL(rfkill_unregister);

/*
 * Rfkill module initialization/deinitialization.
 */
static int __init rfkill_init(void)
{
	int error;
	int i;

	for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)
		rfkill_states[i] = RFKILL_STATE_ON;

	error = class_register(&rfkill_class);
	if (error) {
		printk(KERN_ERR "rfkill: unable to register rfkill class\n");
		return error;
	}

	return 0;
}

static void __exit rfkill_exit(void)
{
	class_unregister(&rfkill_class);
}

module_init(rfkill_init);
module_exit(rfkill_exit);
