blob: 406c5af2da5cdc371e8c20020f8379f67f2e37a2 [file] [log] [blame]
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +05301/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +05306 */
7
8#include <linux/module.h>
9#include <linux/platform_device.h>
Pavankumar Kondeti2d0cdcc2010-12-07 17:54:05 +053010#include <linux/pm_runtime.h>
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053011#include <linux/usb/msm_hsusb_hw.h>
12#include <linux/usb/ulpi.h>
Alexander Shishkin62bb84e2012-05-08 23:29:01 +030013#include <linux/usb/gadget.h>
Alexander Shishkine443b332012-05-11 17:25:46 +030014#include <linux/usb/chipidea.h>
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053015
Alexander Shishkine443b332012-05-11 17:25:46 +030016#include "ci.h"
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053017
Richard Zhao26c696c2012-07-07 22:56:40 +080018#define MSM_USB_BASE (ci->hw_bank.abs)
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053019
Richard Zhao26c696c2012-07-07 22:56:40 +080020static void ci13xxx_msm_notify_event(struct ci13xxx *ci, unsigned event)
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053021{
Richard Zhao26c696c2012-07-07 22:56:40 +080022 struct device *dev = ci->gadget.dev.parent;
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053023 int val;
24
25 switch (event) {
26 case CI13XXX_CONTROLLER_RESET_EVENT:
27 dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
28 writel(0, USB_AHBBURST);
29 writel(0, USB_AHBMODE);
30 break;
31 case CI13XXX_CONTROLLER_STOPPED_EVENT:
32 dev_dbg(dev, "CI13XXX_CONTROLLER_STOPPED_EVENT received\n");
33 /*
34 * Put the transceiver in non-driving mode. Otherwise host
35 * may not detect soft-disconnection.
36 */
Richard Zhao26c696c2012-07-07 22:56:40 +080037 val = usb_phy_io_read(ci->transceiver, ULPI_FUNC_CTRL);
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053038 val &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
39 val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING;
Richard Zhao26c696c2012-07-07 22:56:40 +080040 usb_phy_io_write(ci->transceiver, val, ULPI_FUNC_CTRL);
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053041 break;
42 default:
Richard Zhao26c696c2012-07-07 22:56:40 +080043 dev_dbg(dev, "unknown ci13xxx event\n");
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053044 break;
45 }
46}
47
Richard Zhao77c44002012-06-29 17:48:53 +080048static struct ci13xxx_platform_data ci13xxx_msm_platdata = {
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053049 .name = "ci13xxx_msm",
50 .flags = CI13XXX_REGS_SHARED |
51 CI13XXX_REQUIRE_TRANSCEIVER |
52 CI13XXX_PULLUP_ON_VBUS |
53 CI13XXX_DISABLE_STREAMING,
54
55 .notify_event = ci13xxx_msm_notify_event,
56};
57
Felipe Balbi17d2fcc2012-06-29 17:48:51 +080058static int __devinit ci13xxx_msm_probe(struct platform_device *pdev)
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053059{
Alexander Shishkin62bb84e2012-05-08 23:29:01 +030060 struct platform_device *plat_ci;
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053061
62 dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n");
63
Richard Zhaocbc6dc22012-07-07 22:56:41 +080064 plat_ci = ci13xxx_add_device(&pdev->dev,
65 pdev->resource, pdev->num_resources,
66 &ci13xxx_msm_platdata);
67 if (IS_ERR(plat_ci)) {
68 dev_err(&pdev->dev, "ci13xxx_add_device failed!\n");
69 return PTR_ERR(plat_ci);
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053070 }
71
Felipe Balbi6bf83592012-06-29 17:48:52 +080072 platform_set_drvdata(pdev, plat_ci);
73
Pavankumar Kondeti2d0cdcc2010-12-07 17:54:05 +053074 pm_runtime_no_callbacks(&pdev->dev);
75 pm_runtime_enable(&pdev->dev);
76
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053077 return 0;
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053078}
79
Felipe Balbi6bf83592012-06-29 17:48:52 +080080static int __devexit ci13xxx_msm_remove(struct platform_device *pdev)
81{
82 struct platform_device *plat_ci = platform_get_drvdata(pdev);
83
84 pm_runtime_disable(&pdev->dev);
Richard Zhaocbc6dc22012-07-07 22:56:41 +080085 ci13xxx_remove_device(plat_ci);
Felipe Balbi6bf83592012-06-29 17:48:52 +080086
87 return 0;
88}
89
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053090static struct platform_driver ci13xxx_msm_driver = {
91 .probe = ci13xxx_msm_probe,
Bill Pemberton76904172012-11-19 13:21:08 -050092 .remove = ci13xxx_msm_remove,
Pavankumar Kondeti33f82f382010-12-07 17:54:03 +053093 .driver = { .name = "msm_hsusb", },
94};
Felipe Balbi6bf83592012-06-29 17:48:52 +080095
96module_platform_driver(ci13xxx_msm_driver);
97
Sebastian Andrzej Siewior86081d72011-06-29 16:41:55 +030098MODULE_ALIAS("platform:msm_hsusb");
Marc Kleine-Budde4703d2e2011-10-10 18:38:11 +020099MODULE_LICENSE("GPL v2");