/*
 * Driver for ST5481 USB ISDN modem
 *
 * Author       Frode Isaksen
 * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
 *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
 * 
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */

/* 
 * TODO:
 *
 * b layer1 delay?
 * hotplug / unregister issues
 * mod_inc/dec_use_count
 * unify parts of d/b channel usb handling
 * file header
 * avoid copy to isoc buffer?
 * improve usb delay?
 * merge l1 state machines?
 * clean up debug
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include "st5481.h"

MODULE_DESCRIPTION("ISDN4Linux: driver for ST5481 USB ISDN adapter");
MODULE_AUTHOR("Frode Isaksen");
MODULE_LICENSE("GPL");

static int protocol = 2;       /* EURO-ISDN Default */
module_param(protocol, int, 0);

static int number_of_leds = 2;       /* 2 LEDs on the adpater default */
module_param(number_of_leds, int, 0);

#ifdef CONFIG_HISAX_DEBUG
static int debug = 0;
module_param(debug, int, 0);
#endif
int st5481_debug;

static LIST_HEAD(adapter_list);

/* ======================================================================
 * registration/deregistration with the USB layer
 */

/*
 * This function will be called when the adapter is plugged
 * into the USB bus.
 */
static int probe_st5481(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct st5481_adapter *adapter;
	struct hisax_b_if *b_if[2];
	int retval, i;

	printk(KERN_INFO "st541: found adapter VendorId %04x, ProductId %04x, LEDs %d\n",
	     le16_to_cpu(dev->descriptor.idVendor),
	     le16_to_cpu(dev->descriptor.idProduct),
	     number_of_leds);

	adapter = kzalloc(sizeof(struct st5481_adapter), GFP_KERNEL);
	if (!adapter)
		return -ENOMEM;

	adapter->number_of_leds = number_of_leds;
	adapter->usb_dev = dev;

	adapter->hisax_d_if.owner = THIS_MODULE;
	adapter->hisax_d_if.ifc.priv = adapter;
	adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1;

	for (i = 0; i < 2; i++) {
		adapter->bcs[i].adapter = adapter;
		adapter->bcs[i].channel = i;
		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
		adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
	}
	list_add(&adapter->list, &adapter_list);

	retval = st5481_setup_usb(adapter);
	if (retval < 0)
		goto err;

	retval = st5481_setup_d(adapter);
	if (retval < 0)
		goto err_usb;

	retval = st5481_setup_b(&adapter->bcs[0]);
	if (retval < 0)
		goto err_d;

	retval = st5481_setup_b(&adapter->bcs[1]);
	if (retval < 0)
		goto err_b;

	for (i = 0; i < 2; i++)
		b_if[i] = &adapter->bcs[i].b_if;

	if (hisax_register(&adapter->hisax_d_if, b_if, "st5481_usb",
			protocol) != 0)
		goto err_b1;

	st5481_start(adapter);

	usb_set_intfdata(intf, adapter);
	return 0;

 err_b1:
	st5481_release_b(&adapter->bcs[1]);
 err_b:
	st5481_release_b(&adapter->bcs[0]);
 err_d:
	st5481_release_d(adapter);
 err_usb:
	st5481_release_usb(adapter);
 err:
	return -EIO;
}

/*
 * This function will be called when the adapter is removed
 * from the USB bus.
 */
static void disconnect_st5481(struct usb_interface *intf)
{
	struct st5481_adapter *adapter = usb_get_intfdata(intf);

	DBG(1,"");

	usb_set_intfdata(intf, NULL);
	if (!adapter)
		return;
	
	list_del(&adapter->list);

	st5481_stop(adapter);
	st5481_release_b(&adapter->bcs[1]);
	st5481_release_b(&adapter->bcs[0]);
	st5481_release_d(adapter);
	// we would actually better wait for completion of outstanding urbs
	mdelay(2);
	st5481_release_usb(adapter);

	hisax_unregister(&adapter->hisax_d_if);

	kfree(adapter);
}

/*
 * The last 4 bits in the Product Id is set with 4 pins on the chip.
 */
static struct usb_device_id st5481_ids[] = {
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x0) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x1) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x2) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x3) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x4) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x5) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x6) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x7) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x8) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0x9) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xA) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xB) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xC) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xD) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xE) },
	{ USB_DEVICE(ST_VENDOR_ID, ST5481_PRODUCT_ID+0xF) },
	{ }
};
MODULE_DEVICE_TABLE (usb, st5481_ids);

static struct usb_driver st5481_usb_driver = {
	.name =		"st5481_usb",
	.probe =	probe_st5481,
	.disconnect =	disconnect_st5481,
	.id_table =	st5481_ids,
};

static int __init st5481_usb_init(void)
{
	int retval;

#ifdef CONFIG_HISAX_DEBUG
	st5481_debug = debug;
#endif

	printk(KERN_INFO "hisax_st5481: ST5481 USB ISDN driver $Revision: 2.4.2.3 $\n");

	retval = st5481_d_init();
	if (retval < 0)
		goto out;

	retval = usb_register(&st5481_usb_driver);
	if (retval < 0)
		goto out_d_exit;

	return 0;

 out_d_exit:
	st5481_d_exit();
 out:
	return retval;
}

static void __exit st5481_usb_exit(void)
{
	usb_deregister(&st5481_usb_driver);
	st5481_d_exit();
}

module_init(st5481_usb_init);
module_exit(st5481_usb_exit);
