/*
 * Driver for the Diolan DLN-2 USB adapter
 *
 * Copyright (c) 2014 Intel Corporation
 *
 * Derived from:
 *  i2c-diolan-u2c.c
 *  Copyright (c) 2010-2011 Ericsson AB
 *
 * 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, version 2.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/dln2.h>
#include <linux/rculist.h>

struct dln2_header {
	__le16 size;
	__le16 id;
	__le16 echo;
	__le16 handle;
};

struct dln2_response {
	struct dln2_header hdr;
	__le16 result;
};

#define DLN2_GENERIC_MODULE_ID		0x00
#define DLN2_GENERIC_CMD(cmd)		DLN2_CMD(cmd, DLN2_GENERIC_MODULE_ID)
#define CMD_GET_DEVICE_VER		DLN2_GENERIC_CMD(0x30)
#define CMD_GET_DEVICE_SN		DLN2_GENERIC_CMD(0x31)

#define DLN2_HW_ID			0x200
#define DLN2_USB_TIMEOUT		200	/* in ms */
#define DLN2_MAX_RX_SLOTS		16
#define DLN2_MAX_URBS			16
#define DLN2_RX_BUF_SIZE		512

enum dln2_handle {
	DLN2_HANDLE_EVENT = 0,		/* don't change, hardware defined */
	DLN2_HANDLE_CTRL,
	DLN2_HANDLE_GPIO,
	DLN2_HANDLE_I2C,
	DLN2_HANDLE_SPI,
	DLN2_HANDLES
};

/*
 * Receive context used between the receive demultiplexer and the transfer
 * routine. While sending a request the transfer routine will look for a free
 * receive context and use it to wait for a response and to receive the URB and
 * thus the response data.
 */
struct dln2_rx_context {
	/* completion used to wait for a response */
	struct completion done;

	/* if non-NULL the URB contains the response */
	struct urb *urb;

	/* if true then this context is used to wait for a response */
	bool in_use;
};

/*
 * Receive contexts for a particular DLN2 module (i2c, gpio, etc.). We use the
 * handle header field to identify the module in dln2_dev.mod_rx_slots and then
 * the echo header field to index the slots field and find the receive context
 * for a particular request.
 */
struct dln2_mod_rx_slots {
	/* RX slots bitmap */
	DECLARE_BITMAP(bmap, DLN2_MAX_RX_SLOTS);

	/* used to wait for a free RX slot */
	wait_queue_head_t wq;

	/* used to wait for an RX operation to complete */
	struct dln2_rx_context slots[DLN2_MAX_RX_SLOTS];

	/* avoid races between alloc/free_rx_slot and dln2_rx_transfer */
	spinlock_t lock;
};

enum dln2_endpoint {
	DLN2_EP_OUT	= 0,
	DLN2_EP_IN	= 1,
};

struct dln2_dev {
	struct usb_device *usb_dev;
	struct usb_interface *interface;
	u8 ep_in;
	u8 ep_out;

	struct urb *rx_urb[DLN2_MAX_URBS];
	void *rx_buf[DLN2_MAX_URBS];

	struct dln2_mod_rx_slots mod_rx_slots[DLN2_HANDLES];

	struct list_head event_cb_list;
	spinlock_t event_cb_lock;

	bool disconnect;
	int active_transfers;
	wait_queue_head_t disconnect_wq;
	spinlock_t disconnect_lock;
};

struct dln2_event_cb_entry {
	struct list_head list;
	u16 id;
	struct platform_device *pdev;
	dln2_event_cb_t callback;
};

int dln2_register_event_cb(struct platform_device *pdev, u16 id,
			   dln2_event_cb_t event_cb)
{
	struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent);
	struct dln2_event_cb_entry *i, *entry;
	unsigned long flags;
	int ret = 0;

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

	entry->id = id;
	entry->callback = event_cb;
	entry->pdev = pdev;

	spin_lock_irqsave(&dln2->event_cb_lock, flags);

	list_for_each_entry(i, &dln2->event_cb_list, list) {
		if (i->id == id) {
			ret = -EBUSY;
			break;
		}
	}

	if (!ret)
		list_add_rcu(&entry->list, &dln2->event_cb_list);

	spin_unlock_irqrestore(&dln2->event_cb_lock, flags);

	if (ret)
		kfree(entry);

	return ret;
}
EXPORT_SYMBOL(dln2_register_event_cb);

void dln2_unregister_event_cb(struct platform_device *pdev, u16 id)
{
	struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent);
	struct dln2_event_cb_entry *i;
	unsigned long flags;
	bool found = false;

	spin_lock_irqsave(&dln2->event_cb_lock, flags);

	list_for_each_entry(i, &dln2->event_cb_list, list) {
		if (i->id == id) {
			list_del_rcu(&i->list);
			found = true;
			break;
		}
	}

	spin_unlock_irqrestore(&dln2->event_cb_lock, flags);

	if (found) {
		synchronize_rcu();
		kfree(i);
	}
}
EXPORT_SYMBOL(dln2_unregister_event_cb);

/*
 * Returns true if a valid transfer slot is found. In this case the URB must not
 * be resubmitted immediately in dln2_rx as we need the data when dln2_transfer
 * is woke up. It will be resubmitted there.
 */
static bool dln2_transfer_complete(struct dln2_dev *dln2, struct urb *urb,
				   u16 handle, u16 rx_slot)
{
	struct device *dev = &dln2->interface->dev;
	struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
	struct dln2_rx_context *rxc;
	unsigned long flags;
	bool valid_slot = false;

	if (rx_slot >= DLN2_MAX_RX_SLOTS)
		goto out;

	rxc = &rxs->slots[rx_slot];

	spin_lock_irqsave(&rxs->lock, flags);
	if (rxc->in_use && !rxc->urb) {
		rxc->urb = urb;
		complete(&rxc->done);
		valid_slot = true;
	}
	spin_unlock_irqrestore(&rxs->lock, flags);

out:
	if (!valid_slot)
		dev_warn(dev, "bad/late response %d/%d\n", handle, rx_slot);

	return valid_slot;
}

static void dln2_run_event_callbacks(struct dln2_dev *dln2, u16 id, u16 echo,
				     void *data, int len)
{
	struct dln2_event_cb_entry *i;

	rcu_read_lock();

	list_for_each_entry_rcu(i, &dln2->event_cb_list, list) {
		if (i->id == id) {
			i->callback(i->pdev, echo, data, len);
			break;
		}
	}

	rcu_read_unlock();
}

static void dln2_rx(struct urb *urb)
{
	struct dln2_dev *dln2 = urb->context;
	struct dln2_header *hdr = urb->transfer_buffer;
	struct device *dev = &dln2->interface->dev;
	u16 id, echo, handle, size;
	u8 *data;
	int len;
	int err;

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
	case -EPIPE:
		/* this urb is terminated, clean up */
		dev_dbg(dev, "urb shutting down with status %d\n", urb->status);
		return;
	default:
		dev_dbg(dev, "nonzero urb status received %d\n", urb->status);
		goto out;
	}

	if (urb->actual_length < sizeof(struct dln2_header)) {
		dev_err(dev, "short response: %d\n", urb->actual_length);
		goto out;
	}

	handle = le16_to_cpu(hdr->handle);
	id = le16_to_cpu(hdr->id);
	echo = le16_to_cpu(hdr->echo);
	size = le16_to_cpu(hdr->size);

	if (size != urb->actual_length) {
		dev_err(dev, "size mismatch: handle %x cmd %x echo %x size %d actual %d\n",
			handle, id, echo, size, urb->actual_length);
		goto out;
	}

	if (handle >= DLN2_HANDLES) {
		dev_warn(dev, "invalid handle %d\n", handle);
		goto out;
	}

	data = urb->transfer_buffer + sizeof(struct dln2_header);
	len = urb->actual_length - sizeof(struct dln2_header);

	if (handle == DLN2_HANDLE_EVENT) {
		dln2_run_event_callbacks(dln2, id, echo, data, len);
	} else {
		/* URB will be re-submitted in _dln2_transfer (free_rx_slot) */
		if (dln2_transfer_complete(dln2, urb, handle, echo))
			return;
	}

out:
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0)
		dev_err(dev, "failed to resubmit RX URB: %d\n", err);
}

static void *dln2_prep_buf(u16 handle, u16 cmd, u16 echo, const void *obuf,
			   int *obuf_len, gfp_t gfp)
{
	int len;
	void *buf;
	struct dln2_header *hdr;

	len = *obuf_len + sizeof(*hdr);
	buf = kmalloc(len, gfp);
	if (!buf)
		return NULL;

	hdr = (struct dln2_header *)buf;
	hdr->id = cpu_to_le16(cmd);
	hdr->size = cpu_to_le16(len);
	hdr->echo = cpu_to_le16(echo);
	hdr->handle = cpu_to_le16(handle);

	memcpy(buf + sizeof(*hdr), obuf, *obuf_len);

	*obuf_len = len;

	return buf;
}

static int dln2_send_wait(struct dln2_dev *dln2, u16 handle, u16 cmd, u16 echo,
			  const void *obuf, int obuf_len)
{
	int ret = 0;
	int len = obuf_len;
	void *buf;
	int actual;

	buf = dln2_prep_buf(handle, cmd, echo, obuf, &len, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	ret = usb_bulk_msg(dln2->usb_dev,
			   usb_sndbulkpipe(dln2->usb_dev, dln2->ep_out),
			   buf, len, &actual, DLN2_USB_TIMEOUT);

	kfree(buf);

	return ret;
}

static bool find_free_slot(struct dln2_dev *dln2, u16 handle, int *slot)
{
	struct dln2_mod_rx_slots *rxs;
	unsigned long flags;

	if (dln2->disconnect) {
		*slot = -ENODEV;
		return true;
	}

	rxs = &dln2->mod_rx_slots[handle];

	spin_lock_irqsave(&rxs->lock, flags);

	*slot = find_first_zero_bit(rxs->bmap, DLN2_MAX_RX_SLOTS);

	if (*slot < DLN2_MAX_RX_SLOTS) {
		struct dln2_rx_context *rxc = &rxs->slots[*slot];

		set_bit(*slot, rxs->bmap);
		rxc->in_use = true;
	}

	spin_unlock_irqrestore(&rxs->lock, flags);

	return *slot < DLN2_MAX_RX_SLOTS;
}

static int alloc_rx_slot(struct dln2_dev *dln2, u16 handle)
{
	int ret;
	int slot;

	/*
	 * No need to timeout here, the wait is bounded by the timeout in
	 * _dln2_transfer.
	 */
	ret = wait_event_interruptible(dln2->mod_rx_slots[handle].wq,
				       find_free_slot(dln2, handle, &slot));
	if (ret < 0)
		return ret;

	return slot;
}

static void free_rx_slot(struct dln2_dev *dln2, u16 handle, int slot)
{
	struct dln2_mod_rx_slots *rxs;
	struct urb *urb = NULL;
	unsigned long flags;
	struct dln2_rx_context *rxc;

	rxs = &dln2->mod_rx_slots[handle];

	spin_lock_irqsave(&rxs->lock, flags);

	clear_bit(slot, rxs->bmap);

	rxc = &rxs->slots[slot];
	rxc->in_use = false;
	urb = rxc->urb;
	rxc->urb = NULL;
	reinit_completion(&rxc->done);

	spin_unlock_irqrestore(&rxs->lock, flags);

	if (urb) {
		int err;
		struct device *dev = &dln2->interface->dev;

		err = usb_submit_urb(urb, GFP_KERNEL);
		if (err < 0)
			dev_err(dev, "failed to resubmit RX URB: %d\n", err);
	}

	wake_up_interruptible(&rxs->wq);
}

static int _dln2_transfer(struct dln2_dev *dln2, u16 handle, u16 cmd,
			  const void *obuf, unsigned obuf_len,
			  void *ibuf, unsigned *ibuf_len)
{
	int ret = 0;
	int rx_slot;
	struct dln2_response *rsp;
	struct dln2_rx_context *rxc;
	struct device *dev = &dln2->interface->dev;
	const unsigned long timeout = msecs_to_jiffies(DLN2_USB_TIMEOUT);
	struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
	int size;

	spin_lock(&dln2->disconnect_lock);
	if (!dln2->disconnect)
		dln2->active_transfers++;
	else
		ret = -ENODEV;
	spin_unlock(&dln2->disconnect_lock);

	if (ret)
		return ret;

	rx_slot = alloc_rx_slot(dln2, handle);
	if (rx_slot < 0) {
		ret = rx_slot;
		goto out_decr;
	}

	ret = dln2_send_wait(dln2, handle, cmd, rx_slot, obuf, obuf_len);
	if (ret < 0) {
		dev_err(dev, "USB write failed: %d\n", ret);
		goto out_free_rx_slot;
	}

	rxc = &rxs->slots[rx_slot];

	ret = wait_for_completion_interruptible_timeout(&rxc->done, timeout);
	if (ret <= 0) {
		if (!ret)
			ret = -ETIMEDOUT;
		goto out_free_rx_slot;
	} else {
		ret = 0;
	}

	if (dln2->disconnect) {
		ret = -ENODEV;
		goto out_free_rx_slot;
	}

	/* if we got here we know that the response header has been checked */
	rsp = rxc->urb->transfer_buffer;
	size = le16_to_cpu(rsp->hdr.size);

	if (size < sizeof(*rsp)) {
		ret = -EPROTO;
		goto out_free_rx_slot;
	}

	if (le16_to_cpu(rsp->result) > 0x80) {
		dev_dbg(dev, "%d received response with error %d\n",
			handle, le16_to_cpu(rsp->result));
		ret = -EREMOTEIO;
		goto out_free_rx_slot;
	}

	if (!ibuf)
		goto out_free_rx_slot;

	if (*ibuf_len > size - sizeof(*rsp))
		*ibuf_len = size - sizeof(*rsp);

	memcpy(ibuf, rsp + 1, *ibuf_len);

out_free_rx_slot:
	free_rx_slot(dln2, handle, rx_slot);
out_decr:
	spin_lock(&dln2->disconnect_lock);
	dln2->active_transfers--;
	spin_unlock(&dln2->disconnect_lock);
	if (dln2->disconnect)
		wake_up(&dln2->disconnect_wq);

	return ret;
}

int dln2_transfer(struct platform_device *pdev, u16 cmd,
		  const void *obuf, unsigned obuf_len,
		  void *ibuf, unsigned *ibuf_len)
{
	struct dln2_platform_data *dln2_pdata;
	struct dln2_dev *dln2;
	u16 handle;

	dln2 = dev_get_drvdata(pdev->dev.parent);
	dln2_pdata = dev_get_platdata(&pdev->dev);
	handle = dln2_pdata->handle;

	return _dln2_transfer(dln2, handle, cmd, obuf, obuf_len, ibuf,
			      ibuf_len);
}
EXPORT_SYMBOL(dln2_transfer);

static int dln2_check_hw(struct dln2_dev *dln2)
{
	int ret;
	__le32 hw_type;
	int len = sizeof(hw_type);

	ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_VER,
			     NULL, 0, &hw_type, &len);
	if (ret < 0)
		return ret;
	if (len < sizeof(hw_type))
		return -EREMOTEIO;

	if (le32_to_cpu(hw_type) != DLN2_HW_ID) {
		dev_err(&dln2->interface->dev, "Device ID 0x%x not supported\n",
			le32_to_cpu(hw_type));
		return -ENODEV;
	}

	return 0;
}

static int dln2_print_serialno(struct dln2_dev *dln2)
{
	int ret;
	__le32 serial_no;
	int len = sizeof(serial_no);
	struct device *dev = &dln2->interface->dev;

	ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_SN, NULL, 0,
			     &serial_no, &len);
	if (ret < 0)
		return ret;
	if (len < sizeof(serial_no))
		return -EREMOTEIO;

	dev_info(dev, "Diolan DLN2 serial %u\n", le32_to_cpu(serial_no));

	return 0;
}

static int dln2_hw_init(struct dln2_dev *dln2)
{
	int ret;

	ret = dln2_check_hw(dln2);
	if (ret < 0)
		return ret;

	return dln2_print_serialno(dln2);
}

static void dln2_free_rx_urbs(struct dln2_dev *dln2)
{
	int i;

	for (i = 0; i < DLN2_MAX_URBS; i++) {
		usb_free_urb(dln2->rx_urb[i]);
		kfree(dln2->rx_buf[i]);
	}
}

static void dln2_stop_rx_urbs(struct dln2_dev *dln2)
{
	int i;

	for (i = 0; i < DLN2_MAX_URBS; i++)
		usb_kill_urb(dln2->rx_urb[i]);
}

static void dln2_free(struct dln2_dev *dln2)
{
	dln2_free_rx_urbs(dln2);
	usb_put_dev(dln2->usb_dev);
	kfree(dln2);
}

static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
			      struct usb_host_interface *hostif)
{
	int i;
	const int rx_max_size = DLN2_RX_BUF_SIZE;

	for (i = 0; i < DLN2_MAX_URBS; i++) {
		dln2->rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL);
		if (!dln2->rx_buf[i])
			return -ENOMEM;

		dln2->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
		if (!dln2->rx_urb[i])
			return -ENOMEM;

		usb_fill_bulk_urb(dln2->rx_urb[i], dln2->usb_dev,
				  usb_rcvbulkpipe(dln2->usb_dev, dln2->ep_in),
				  dln2->rx_buf[i], rx_max_size, dln2_rx, dln2);
	}

	return 0;
}

static int dln2_start_rx_urbs(struct dln2_dev *dln2, gfp_t gfp)
{
	struct device *dev = &dln2->interface->dev;
	int ret;
	int i;

	for (i = 0; i < DLN2_MAX_URBS; i++) {
		ret = usb_submit_urb(dln2->rx_urb[i], gfp);
		if (ret < 0) {
			dev_err(dev, "failed to submit RX URB: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

static struct dln2_platform_data dln2_pdata_gpio = {
	.handle = DLN2_HANDLE_GPIO,
};

/* Only one I2C port seems to be supported on current hardware */
static struct dln2_platform_data dln2_pdata_i2c = {
	.handle = DLN2_HANDLE_I2C,
	.port = 0,
};

/* Only one SPI port supported */
static struct dln2_platform_data dln2_pdata_spi = {
	.handle = DLN2_HANDLE_SPI,
	.port = 0,
};

static const struct mfd_cell dln2_devs[] = {
	{
		.name = "dln2-gpio",
		.platform_data = &dln2_pdata_gpio,
		.pdata_size = sizeof(struct dln2_platform_data),
	},
	{
		.name = "dln2-i2c",
		.platform_data = &dln2_pdata_i2c,
		.pdata_size = sizeof(struct dln2_platform_data),
	},
	{
		.name = "dln2-spi",
		.platform_data = &dln2_pdata_spi,
		.pdata_size = sizeof(struct dln2_platform_data),
	},
};

static void dln2_stop(struct dln2_dev *dln2)
{
	int i, j;

	/* don't allow starting new transfers */
	spin_lock(&dln2->disconnect_lock);
	dln2->disconnect = true;
	spin_unlock(&dln2->disconnect_lock);

	/* cancel in progress transfers */
	for (i = 0; i < DLN2_HANDLES; i++) {
		struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[i];
		unsigned long flags;

		spin_lock_irqsave(&rxs->lock, flags);

		/* cancel all response waiters */
		for (j = 0; j < DLN2_MAX_RX_SLOTS; j++) {
			struct dln2_rx_context *rxc = &rxs->slots[j];

			if (rxc->in_use)
				complete(&rxc->done);
		}

		spin_unlock_irqrestore(&rxs->lock, flags);
	}

	/* wait for transfers to end */
	wait_event(dln2->disconnect_wq, !dln2->active_transfers);

	dln2_stop_rx_urbs(dln2);
}

static void dln2_disconnect(struct usb_interface *interface)
{
	struct dln2_dev *dln2 = usb_get_intfdata(interface);

	dln2_stop(dln2);

	mfd_remove_devices(&interface->dev);

	dln2_free(dln2);
}

static int dln2_probe(struct usb_interface *interface,
		      const struct usb_device_id *usb_id)
{
	struct usb_host_interface *hostif = interface->cur_altsetting;
	struct usb_endpoint_descriptor *epin;
	struct usb_endpoint_descriptor *epout;
	struct device *dev = &interface->dev;
	struct dln2_dev *dln2;
	int ret;
	int i, j;

	if (hostif->desc.bInterfaceNumber != 0 ||
	    hostif->desc.bNumEndpoints < 2)
		return -ENODEV;

	epout = &hostif->endpoint[DLN2_EP_OUT].desc;
	if (!usb_endpoint_is_bulk_out(epout))
		return -ENODEV;
	epin = &hostif->endpoint[DLN2_EP_IN].desc;
	if (!usb_endpoint_is_bulk_in(epin))
		return -ENODEV;

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

	dln2->ep_out = epout->bEndpointAddress;
	dln2->ep_in = epin->bEndpointAddress;
	dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
	dln2->interface = interface;
	usb_set_intfdata(interface, dln2);
	init_waitqueue_head(&dln2->disconnect_wq);

	for (i = 0; i < DLN2_HANDLES; i++) {
		init_waitqueue_head(&dln2->mod_rx_slots[i].wq);
		spin_lock_init(&dln2->mod_rx_slots[i].lock);
		for (j = 0; j < DLN2_MAX_RX_SLOTS; j++)
			init_completion(&dln2->mod_rx_slots[i].slots[j].done);
	}

	spin_lock_init(&dln2->event_cb_lock);
	spin_lock_init(&dln2->disconnect_lock);
	INIT_LIST_HEAD(&dln2->event_cb_list);

	ret = dln2_setup_rx_urbs(dln2, hostif);
	if (ret)
		goto out_free;

	ret = dln2_start_rx_urbs(dln2, GFP_KERNEL);
	if (ret)
		goto out_stop_rx;

	ret = dln2_hw_init(dln2);
	if (ret < 0) {
		dev_err(dev, "failed to initialize hardware\n");
		goto out_stop_rx;
	}

	ret = mfd_add_hotplug_devices(dev, dln2_devs, ARRAY_SIZE(dln2_devs));
	if (ret != 0) {
		dev_err(dev, "failed to add mfd devices to core\n");
		goto out_stop_rx;
	}

	return 0;

out_stop_rx:
	dln2_stop_rx_urbs(dln2);

out_free:
	dln2_free(dln2);

	return ret;
}

static int dln2_suspend(struct usb_interface *iface, pm_message_t message)
{
	struct dln2_dev *dln2 = usb_get_intfdata(iface);

	dln2_stop(dln2);

	return 0;
}

static int dln2_resume(struct usb_interface *iface)
{
	struct dln2_dev *dln2 = usb_get_intfdata(iface);

	dln2->disconnect = false;

	return dln2_start_rx_urbs(dln2, GFP_NOIO);
}

static const struct usb_device_id dln2_table[] = {
	{ USB_DEVICE(0xa257, 0x2013) },
	{ }
};

MODULE_DEVICE_TABLE(usb, dln2_table);

static struct usb_driver dln2_driver = {
	.name = "dln2",
	.probe = dln2_probe,
	.disconnect = dln2_disconnect,
	.id_table = dln2_table,
	.suspend = dln2_suspend,
	.resume = dln2_resume,
};

module_usb_driver(dln2_driver);

MODULE_AUTHOR("Octavian Purdila <octavian.purdila@intel.com>");
MODULE_DESCRIPTION("Core driver for the Diolan DLN2 interface adapter");
MODULE_LICENSE("GPL v2");
