/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 *
 */


#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/usb/ch11.h>
#include <linux/usb/hcd.h>

#define TEST_SE0_NAK_PID		0x0101
#define TEST_J_PID			0x0102
#define TEST_K_PID			0x0103
#define TEST_PACKET_PID			0x0104
#define TEST_HS_HOST_PORT_SUSPEND_RESUME 0x0106
#define TEST_SINGLE_STEP_GET_DEV_DESC	0x0107
#define TEST_SINGLE_STEP_SET_FEATURE	0x0108

static int ehset_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
	int status = -1;
	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_device *rh_udev = dev->bus->root_hub;
	struct usb_device *hub_udev = dev->parent;
	int port1 = dev->portnum;
	int test_mode = le16_to_cpu(dev->descriptor.idProduct);

	switch (test_mode) {
	case TEST_SE0_NAK_PID:
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
			(3 << 8) | port1, NULL, 0, 1000);
		break;
	case TEST_J_PID:
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
			(1 << 8) | port1, NULL, 0, 1000);
		break;
	case TEST_K_PID:
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
			(2 << 8) | port1, NULL, 0, 1000);
		break;
	case TEST_PACKET_PID:
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
			(4 << 8) | port1, NULL, 0, 1000);
		break;
	case TEST_HS_HOST_PORT_SUSPEND_RESUME:
		/* Test: wait for 15secs -> suspend -> 15secs delay -> resume */
		msleep(15 * 1000);
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT,
			USB_PORT_FEAT_SUSPEND, port1, NULL, 0, 1000);
		if (status < 0)
			break;
		msleep(15 * 1000);
		status = usb_control_msg(hub_udev, usb_sndctrlpipe(hub_udev, 0),
			USB_REQ_CLEAR_FEATURE, USB_RT_PORT,
			USB_PORT_FEAT_SUSPEND, port1, NULL, 0, 1000);
		break;
	case TEST_SINGLE_STEP_GET_DEV_DESC:
		/* Test: wait for 15secs -> GetDescriptor request */
		msleep(15 * 1000);
		{
			struct usb_device_descriptor *buf;
			buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
			if (!buf)
				return -ENOMEM;

			status = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
				USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
				USB_DT_DEVICE << 8, 0,
				buf, USB_DT_DEVICE_SIZE,
				USB_CTRL_GET_TIMEOUT);
			kfree(buf);
		}
		break;
	case TEST_SINGLE_STEP_SET_FEATURE:
		/* GetDescriptor's SETUP request -> 15secs delay -> IN & STATUS
		 * Issue request to ehci root hub driver with portnum = 1
		 */
		status = usb_control_msg(rh_udev, usb_sndctrlpipe(rh_udev, 0),
			USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST,
			(6 << 8) | 1, NULL, 0, 60 * 1000);

		break;
	default:
		pr_err("%s: undefined test mode ( %X )\n", __func__, test_mode);
		return -EINVAL;
	}

	return (status < 0) ? status : 0;
}

static void ehset_disconnect(struct usb_interface *intf)
{
}

static struct usb_device_id ehset_id_table[] = {
	{ USB_DEVICE(0x1a0a, TEST_SE0_NAK_PID) },
	{ USB_DEVICE(0x1a0a, TEST_J_PID) },
	{ USB_DEVICE(0x1a0a, TEST_K_PID) },
	{ USB_DEVICE(0x1a0a, TEST_PACKET_PID) },
	{ USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
	{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
	{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
	{ }			/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, ehset_id_table);

static struct usb_driver ehset_driver = {
	.name =		"usb_ehset_test",
	.probe =	ehset_probe,
	.disconnect =	ehset_disconnect,
	.id_table =	ehset_id_table,
};

static int __init ehset_init(void)
{
	return usb_register(&ehset_driver);
}

static void __exit ehset_exit(void)
{
	usb_deregister(&ehset_driver);
}

module_init(ehset_init);
module_exit(ehset_exit);

MODULE_DESCRIPTION("USB Driver for EHSET Test Fixture");
MODULE_LICENSE("GPL v2");
