aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2013-03-08 06:25:18 -0500
committerFelipe Balbi <balbi@ti.com>2013-03-18 05:18:10 -0400
commitc38a4f3f508d47e51c3f28e8946b1482ebf47fee (patch)
tree73113d484b2fd0faca6306c6036464763cd3b0f5
parentb774212ea5f13911a5e0211a7088e42dad46b4c8 (diff)
usb: phy: isp1301: implement PHY API
this patch implements ->init() and ->set_vbus() methods for isp1301 transceiver driver. Later patches can now come in order to remove the hackery from ohci-nxp and lpc32xx udc drivers. Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/phy/phy-isp1301.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/usb/phy/phy-isp1301.c b/drivers/usb/phy/phy-isp1301.c
index 5e0f14369145..225ae6c97eeb 100644
--- a/drivers/usb/phy/phy-isp1301.c
+++ b/drivers/usb/phy/phy-isp1301.c
@@ -14,6 +14,7 @@
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/usb/phy.h> 16#include <linux/usb/phy.h>
17#include <linux/usb/isp1301.h>
17 18
18#define DRV_NAME "isp1301" 19#define DRV_NAME "isp1301"
19 20
@@ -24,6 +25,8 @@ struct isp1301 {
24 struct i2c_client *client; 25 struct i2c_client *client;
25}; 26};
26 27
28#define phy_to_isp(p) (container_of((p), struct isp1301, phy))
29
27static const struct i2c_device_id isp1301_id[] = { 30static const struct i2c_device_id isp1301_id[] = {
28 { "isp1301", 0 }, 31 { "isp1301", 0 },
29 { } 32 { }
@@ -31,6 +34,60 @@ static const struct i2c_device_id isp1301_id[] = {
31 34
32static struct i2c_client *isp1301_i2c_client; 35static struct i2c_client *isp1301_i2c_client;
33 36
37static int __isp1301_write(struct isp1301 *isp, u8 reg, u8 value, u8 clear)
38{
39 return i2c_smbus_write_byte_data(isp->client, reg | clear, value);
40}
41
42static int isp1301_write(struct isp1301 *isp, u8 reg, u8 value)
43{
44 return __isp1301_write(isp, reg, value, 0);
45}
46
47static int isp1301_clear(struct isp1301 *isp, u8 reg, u8 value)
48{
49 return __isp1301_write(isp, reg, value, ISP1301_I2C_REG_CLEAR_ADDR);
50}
51
52static int isp1301_phy_init(struct usb_phy *phy)
53{
54 struct isp1301 *isp = phy_to_isp(phy);
55
56 /* Disable transparent UART mode first */
57 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_UART_EN);
58 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, ~MC1_SPEED_REG);
59 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG);
60 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_2, ~0);
61 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_PSW_EN
62 | MC2_SPD_SUSP_CTRL));
63
64 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, ~0);
65 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0);
66 isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLDOWN
67 | OTG1_DP_PULLDOWN));
68 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLUP
69 | OTG1_DP_PULLUP));
70
71 /* mask all interrupts */
72 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_LATCH, ~0);
73 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_FALLING, ~0);
74 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_RISING, ~0);
75
76 return 0;
77}
78
79static int isp1301_phy_set_vbus(struct usb_phy *phy, int on)
80{
81 struct isp1301 *isp = phy_to_isp(phy);
82
83 if (on)
84 isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
85 else
86 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
87
88 return 0;
89}
90
34static int isp1301_probe(struct i2c_client *client, 91static int isp1301_probe(struct i2c_client *client,
35 const struct i2c_device_id *i2c_id) 92 const struct i2c_device_id *i2c_id)
36{ 93{
@@ -46,6 +103,8 @@ static int isp1301_probe(struct i2c_client *client,
46 103
47 phy = &isp->phy; 104 phy = &isp->phy;
48 phy->label = DRV_NAME; 105 phy->label = DRV_NAME;
106 phy->init = isp1301_phy_init;
107 phy->set_vbus = isp1301_phy_set_vbus;
49 phy->type = USB_PHY_TYPE_USB2; 108 phy->type = USB_PHY_TYPE_USB2;
50 109
51 i2c_set_clientdata(client, isp); 110 i2c_set_clientdata(client, isp);