2010-12-07 17:54:03 +05:30
/* Copyright (c) 2010, Code Aurora Forum. 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 .
*/
# include <linux/module.h>
# include <linux/platform_device.h>
2010-12-07 17:54:05 +05:30
# include <linux/pm_runtime.h>
2010-12-07 17:54:03 +05:30
# include <linux/usb/msm_hsusb_hw.h>
# include <linux/usb/ulpi.h>
2012-05-08 23:29:01 +03:00
# include <linux/usb/gadget.h>
2012-05-11 17:25:46 +03:00
# include <linux/usb/chipidea.h>
2010-12-07 17:54:03 +05:30
2012-05-11 17:25:46 +03:00
# include "ci.h"
2010-12-07 17:54:03 +05:30
2012-07-07 22:56:40 +08:00
# define MSM_USB_BASE (ci->hw_bank.abs)
2010-12-07 17:54:03 +05:30
2013-06-24 14:46:36 +03:00
static void ci_hdrc_msm_notify_event ( struct ci_hdrc * ci , unsigned event )
2010-12-07 17:54:03 +05:30
{
2012-07-07 22:56:40 +08:00
struct device * dev = ci - > gadget . dev . parent ;
2010-12-07 17:54:03 +05:30
int val ;
switch ( event ) {
2013-06-24 14:46:36 +03:00
case CI_HDRC_CONTROLLER_RESET_EVENT :
dev_dbg ( dev , " CI_HDRC_CONTROLLER_RESET_EVENT received \n " ) ;
2010-12-07 17:54:03 +05:30
writel ( 0 , USB_AHBBURST ) ;
writel ( 0 , USB_AHBMODE ) ;
break ;
2013-06-24 14:46:36 +03:00
case CI_HDRC_CONTROLLER_STOPPED_EVENT :
dev_dbg ( dev , " CI_HDRC_CONTROLLER_STOPPED_EVENT received \n " ) ;
2010-12-07 17:54:03 +05:30
/*
* Put the transceiver in non - driving mode . Otherwise host
* may not detect soft - disconnection .
*/
2012-07-07 22:56:40 +08:00
val = usb_phy_io_read ( ci - > transceiver , ULPI_FUNC_CTRL ) ;
2010-12-07 17:54:03 +05:30
val & = ~ ULPI_FUNC_CTRL_OPMODE_MASK ;
val | = ULPI_FUNC_CTRL_OPMODE_NONDRIVING ;
2012-07-07 22:56:40 +08:00
usb_phy_io_write ( ci - > transceiver , val , ULPI_FUNC_CTRL ) ;
2010-12-07 17:54:03 +05:30
break ;
default :
2013-06-24 14:46:36 +03:00
dev_dbg ( dev , " unknown ci_hdrc event \n " ) ;
2010-12-07 17:54:03 +05:30
break ;
}
}
2013-06-24 14:46:36 +03:00
static struct ci_hdrc_platform_data ci_hdrc_msm_platdata = {
. name = " ci_hdrc_msm " ,
. flags = CI_HDRC_REGS_SHARED |
CI_HDRC_REQUIRE_TRANSCEIVER |
CI_HDRC_PULLUP_ON_VBUS |
CI_HDRC_DISABLE_STREAMING ,
2010-12-07 17:54:03 +05:30
2013-06-24 14:46:36 +03:00
. notify_event = ci_hdrc_msm_notify_event ,
2010-12-07 17:54:03 +05:30
} ;
2013-06-24 14:46:36 +03:00
static int ci_hdrc_msm_probe ( struct platform_device * pdev )
2010-12-07 17:54:03 +05:30
{
2012-05-08 23:29:01 +03:00
struct platform_device * plat_ci ;
2010-12-07 17:54:03 +05:30
2013-06-24 14:46:36 +03:00
dev_dbg ( & pdev - > dev , " ci_hdrc_msm_probe \n " ) ;
2010-12-07 17:54:03 +05:30
2013-06-24 14:46:36 +03:00
plat_ci = ci_hdrc_add_device ( & pdev - > dev ,
2012-07-07 22:56:41 +08:00
pdev - > resource , pdev - > num_resources ,
2013-06-24 14:46:36 +03:00
& ci_hdrc_msm_platdata ) ;
2012-07-07 22:56:41 +08:00
if ( IS_ERR ( plat_ci ) ) {
2013-06-24 14:46:36 +03:00
dev_err ( & pdev - > dev , " ci_hdrc_add_device failed! \n " ) ;
2012-07-07 22:56:41 +08:00
return PTR_ERR ( plat_ci ) ;
2010-12-07 17:54:03 +05:30
}
2012-06-29 17:48:52 +08:00
platform_set_drvdata ( pdev , plat_ci ) ;
2010-12-07 17:54:05 +05:30
pm_runtime_no_callbacks ( & pdev - > dev ) ;
pm_runtime_enable ( & pdev - > dev ) ;
2010-12-07 17:54:03 +05:30
return 0 ;
}
2013-06-24 14:46:36 +03:00
static int ci_hdrc_msm_remove ( struct platform_device * pdev )
2012-06-29 17:48:52 +08:00
{
struct platform_device * plat_ci = platform_get_drvdata ( pdev ) ;
pm_runtime_disable ( & pdev - > dev ) ;
2013-06-24 14:46:36 +03:00
ci_hdrc_remove_device ( plat_ci ) ;
2012-06-29 17:48:52 +08:00
return 0 ;
}
2013-06-24 14:46:36 +03:00
static struct platform_driver ci_hdrc_msm_driver = {
. probe = ci_hdrc_msm_probe ,
. remove = ci_hdrc_msm_remove ,
2010-12-07 17:54:03 +05:30
. driver = { . name = " msm_hsusb " , } ,
} ;
2013-06-24 14:46:36 +03:00
module_platform_driver ( ci_hdrc_msm_driver ) ;
2011-10-10 18:38:11 +02:00
2012-06-29 17:48:52 +08:00
MODULE_ALIAS ( " platform:msm_hsusb " ) ;
2013-06-24 14:46:36 +03:00
MODULE_ALIAS ( " platform:ci13xxx_msm " ) ;
2011-10-10 18:38:11 +02:00
MODULE_LICENSE ( " GPL v2 " ) ;