0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/i2c.h>
0013 #include <linux/usb/phy.h>
0014 #include <linux/usb/isp1301.h>
0015
0016 #define DRV_NAME "isp1301"
0017
0018 struct isp1301 {
0019 struct usb_phy phy;
0020 struct mutex mutex;
0021
0022 struct i2c_client *client;
0023 };
0024
0025 #define phy_to_isp(p) (container_of((p), struct isp1301, phy))
0026
0027 static const struct i2c_device_id isp1301_id[] = {
0028 { "isp1301", 0 },
0029 { }
0030 };
0031 MODULE_DEVICE_TABLE(i2c, isp1301_id);
0032
0033 static const struct of_device_id isp1301_of_match[] = {
0034 {.compatible = "nxp,isp1301" },
0035 { },
0036 };
0037 MODULE_DEVICE_TABLE(of, isp1301_of_match);
0038
0039 static struct i2c_client *isp1301_i2c_client;
0040
0041 static int __isp1301_write(struct isp1301 *isp, u8 reg, u8 value, u8 clear)
0042 {
0043 return i2c_smbus_write_byte_data(isp->client, reg | clear, value);
0044 }
0045
0046 static int isp1301_write(struct isp1301 *isp, u8 reg, u8 value)
0047 {
0048 return __isp1301_write(isp, reg, value, 0);
0049 }
0050
0051 static int isp1301_clear(struct isp1301 *isp, u8 reg, u8 value)
0052 {
0053 return __isp1301_write(isp, reg, value, ISP1301_I2C_REG_CLEAR_ADDR);
0054 }
0055
0056 static int isp1301_phy_init(struct usb_phy *phy)
0057 {
0058 struct isp1301 *isp = phy_to_isp(phy);
0059
0060
0061 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_UART_EN);
0062 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, ~MC1_SPEED_REG);
0063 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG);
0064 isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_2, ~0);
0065 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_PSW_EN
0066 | MC2_SPD_SUSP_CTRL));
0067
0068 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, ~0);
0069 isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0);
0070 isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLDOWN
0071 | OTG1_DP_PULLDOWN));
0072 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLUP
0073 | OTG1_DP_PULLUP));
0074
0075
0076 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_LATCH, ~0);
0077 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_FALLING, ~0);
0078 isp1301_clear(isp, ISP1301_I2C_INTERRUPT_RISING, ~0);
0079
0080 return 0;
0081 }
0082
0083 static int isp1301_phy_set_vbus(struct usb_phy *phy, int on)
0084 {
0085 struct isp1301 *isp = phy_to_isp(phy);
0086
0087 if (on)
0088 isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
0089 else
0090 isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
0091
0092 return 0;
0093 }
0094
0095 static int isp1301_probe(struct i2c_client *client,
0096 const struct i2c_device_id *i2c_id)
0097 {
0098 struct isp1301 *isp;
0099 struct usb_phy *phy;
0100
0101 isp = devm_kzalloc(&client->dev, sizeof(*isp), GFP_KERNEL);
0102 if (!isp)
0103 return -ENOMEM;
0104
0105 isp->client = client;
0106 mutex_init(&isp->mutex);
0107
0108 phy = &isp->phy;
0109 phy->dev = &client->dev;
0110 phy->label = DRV_NAME;
0111 phy->init = isp1301_phy_init;
0112 phy->set_vbus = isp1301_phy_set_vbus;
0113 phy->type = USB_PHY_TYPE_USB2;
0114
0115 i2c_set_clientdata(client, isp);
0116 usb_add_phy_dev(phy);
0117
0118 isp1301_i2c_client = client;
0119
0120 return 0;
0121 }
0122
0123 static int isp1301_remove(struct i2c_client *client)
0124 {
0125 struct isp1301 *isp = i2c_get_clientdata(client);
0126
0127 usb_remove_phy(&isp->phy);
0128 isp1301_i2c_client = NULL;
0129
0130 return 0;
0131 }
0132
0133 static struct i2c_driver isp1301_driver = {
0134 .driver = {
0135 .name = DRV_NAME,
0136 .of_match_table = isp1301_of_match,
0137 },
0138 .probe = isp1301_probe,
0139 .remove = isp1301_remove,
0140 .id_table = isp1301_id,
0141 };
0142
0143 module_i2c_driver(isp1301_driver);
0144
0145 struct i2c_client *isp1301_get_client(struct device_node *node)
0146 {
0147 struct i2c_client *client;
0148
0149
0150 client = of_find_i2c_device_by_node(node);
0151 if (client)
0152 return client;
0153
0154
0155 return isp1301_i2c_client;
0156 }
0157 EXPORT_SYMBOL_GPL(isp1301_get_client);
0158
0159 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
0160 MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver");
0161 MODULE_LICENSE("GPL");