#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>

#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <asm/arch/hardware.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/udc.h>
#include <asm/arch/asus535-gpio.h>

static int p535_udc_is_connected(void)
{
    printk("p535_udc_is_connected = %d\n", gpio_get_value(GPIO_NR_P535_USB_CABLE_DETECT));
    return (gpio_get_value(GPIO_NR_P535_USB_CABLE_DETECT) != 0);
}

static void p535_udc_command(int command)
{
    printk("p535_udc_command enter, command = %d\n", command);
    switch (command)
    {
	case PXA2XX_UDC_CMD_DISCONNECT:
	    gpio_set_value(GPIO_NR_P535_USB_PULLUP, 0);
	    break;
	case PXA2XX_UDC_CMD_CONNECT:
	    gpio_set_value(GPIO_NR_P535_USB_PULLUP, 1);
	    break;
	default:
	    printk("%s: unknown command '%d'.", __FUNCTION__, command);
    }
}

static struct pxa2xx_udc_mach_info p535_udc_info = {
    .udc_is_connected = p535_udc_is_connected,
    .udc_command = p535_udc_command,
};

static int p535_udc_probe(struct platform_device *pdev)
{
    printk("******Probing Asus P535 UDC*****\n");
    pxa_set_udc_info(&p535_udc_info);
    
    return 0;
}

static int p535_udc_remove(struct platform_device *pdev)
{
    return 0;
}

static struct platform_driver p535_udc_driver = {
    .driver = {
	.name = "p535-udc",
    },
    .probe = p535_udc_probe,
    .remove = p535_udc_remove,
    //.suspend = a730_udc_suspend,
    //.resume = a730_udc_resume,
};

static int __init p535_udc_init(void)
{
/*    if (!machine_is_a730()) return -ENODEV;*/
    pxa_gpio_mode(GPIO_NR_P535_USB_PULLUP_MD);
/*
    printk("Probing Asus P535 UDC\n");
    pxa_set_udc_info(&p535_udc_info);

    return 0;
*/

    return platform_driver_register(&p535_udc_driver);

}

static void __exit p535_udc_exit(void)
{
    return;
}

module_init(p535_udc_init);
module_exit(p535_udc_exit);

MODULE_AUTHOR("Xiao Huang <reed.huang@gmail.com");
MODULE_DESCRIPTION("Asus P535 UDC support");
MODULE_LICENSE("GPL");
