^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * NXP ISP1301 USB transceiver driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012 Roland Stigge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Roland Stigge <stigge@antcom.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/usb/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/usb/isp1301.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define DRV_NAME "isp1301"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct isp1301 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct usb_phy phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define phy_to_isp(p) (container_of((p), struct isp1301, phy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const struct i2c_device_id isp1301_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) { "isp1301", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_DEVICE_TABLE(i2c, isp1301_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static const struct of_device_id isp1301_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {.compatible = "nxp,isp1301" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_DEVICE_TABLE(of, isp1301_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static struct i2c_client *isp1301_i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static int __isp1301_write(struct isp1301 *isp, u8 reg, u8 value, u8 clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return i2c_smbus_write_byte_data(isp->client, reg | clear, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int isp1301_write(struct isp1301 *isp, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return __isp1301_write(isp, reg, value, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int isp1301_clear(struct isp1301 *isp, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return __isp1301_write(isp, reg, value, ISP1301_I2C_REG_CLEAR_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int isp1301_phy_init(struct usb_phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct isp1301 *isp = phy_to_isp(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Disable transparent UART mode first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_UART_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_1, ~MC1_SPEED_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_SPEED_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) isp1301_clear(isp, ISP1301_I2C_MODE_CONTROL_2, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_PSW_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) | MC2_SPD_SUSP_CTRL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) isp1301_write(isp, ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLDOWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) | OTG1_DP_PULLDOWN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, (OTG1_DM_PULLUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) | OTG1_DP_PULLUP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* mask all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) isp1301_clear(isp, ISP1301_I2C_INTERRUPT_LATCH, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) isp1301_clear(isp, ISP1301_I2C_INTERRUPT_FALLING, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) isp1301_clear(isp, ISP1301_I2C_INTERRUPT_RISING, ~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static int isp1301_phy_set_vbus(struct usb_phy *phy, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct isp1301 *isp = phy_to_isp(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) isp1301_write(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) isp1301_clear(isp, ISP1301_I2C_OTG_CONTROL_1, OTG1_VBUS_DRV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static int isp1301_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) const struct i2c_device_id *i2c_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct isp1301 *isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct usb_phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) isp = devm_kzalloc(&client->dev, sizeof(*isp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!isp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) isp->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mutex_init(&isp->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) phy = &isp->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) phy->dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) phy->label = DRV_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) phy->init = isp1301_phy_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) phy->set_vbus = isp1301_phy_set_vbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) phy->type = USB_PHY_TYPE_USB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) i2c_set_clientdata(client, isp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) usb_add_phy_dev(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) isp1301_i2c_client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int isp1301_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct isp1301 *isp = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) usb_remove_phy(&isp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) isp1301_i2c_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static struct i2c_driver isp1301_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .of_match_table = isp1301_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .probe = isp1301_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .remove = isp1301_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .id_table = isp1301_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) module_i2c_driver(isp1301_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int match(struct device *dev, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) const struct device_node *node = (const struct device_node *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return (dev->of_node == node) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) (dev->driver == &isp1301_driver.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct i2c_client *isp1301_get_client(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (node) { /* reference of ISP1301 I2C node via DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct device *dev = bus_find_device(&i2c_bus_type, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) node, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) } else { /* non-DT: only one ISP1301 chip supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return isp1301_i2c_client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) EXPORT_SYMBOL_GPL(isp1301_get_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) MODULE_DESCRIPTION("NXP ISP1301 USB transceiver driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) MODULE_LICENSE("GPL");