mirror of https://gitee.com/openkylin/linux.git
usb: gadget: udc: lpc32xx: add support for stotg04 phy
The STOTG04 phy is used as a drop-in replacement of the ISP1301 but some bits doesn't have exactly the same meaning and this can lead to issues. Detect the phy dynamically and avoid writing to reserved bits. Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
f584fa8c1f
commit
2a60f5eafa
|
@ -115,6 +115,11 @@ struct lpc32xx_ep {
|
|||
bool wedge;
|
||||
};
|
||||
|
||||
enum atx_type {
|
||||
ISP1301,
|
||||
STOTG04,
|
||||
};
|
||||
|
||||
/*
|
||||
* Common UDC structure
|
||||
*/
|
||||
|
@ -149,6 +154,7 @@ struct lpc32xx_udc {
|
|||
u8 last_vbus;
|
||||
int pullup;
|
||||
int poweron;
|
||||
enum atx_type atx;
|
||||
|
||||
/* Work queues related to I2C support */
|
||||
struct work_struct pullup_job;
|
||||
|
@ -550,6 +556,15 @@ static inline void remove_debug_file(struct lpc32xx_udc *udc) {}
|
|||
/* Primary initialization sequence for the ISP1301 transceiver */
|
||||
static void isp1301_udc_configure(struct lpc32xx_udc *udc)
|
||||
{
|
||||
u8 value;
|
||||
s32 vendor, product;
|
||||
|
||||
vendor = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00);
|
||||
product = i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02);
|
||||
|
||||
if (vendor == 0x0483 && product == 0xa0c4)
|
||||
udc->atx = STOTG04;
|
||||
|
||||
/* LPC32XX only supports DAT_SE0 USB mode */
|
||||
/* This sequence is important */
|
||||
|
||||
|
@ -569,8 +584,12 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
|
|||
*/
|
||||
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
|
||||
(ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR), ~0);
|
||||
|
||||
value = MC2_BI_DI;
|
||||
if (udc->atx != STOTG04)
|
||||
value |= MC2_SPD_SUSP_CTRL;
|
||||
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
|
||||
ISP1301_I2C_MODE_CONTROL_2, (MC2_BI_DI | MC2_SPD_SUSP_CTRL));
|
||||
ISP1301_I2C_MODE_CONTROL_2, value);
|
||||
|
||||
/* Driver VBUS_DRV high or low depending on board setup */
|
||||
if (udc->board->vbus_drv_pol != 0)
|
||||
|
@ -610,12 +629,11 @@ static void isp1301_udc_configure(struct lpc32xx_udc *udc)
|
|||
i2c_smbus_write_byte_data(udc->isp1301_i2c_client,
|
||||
ISP1301_I2C_INTERRUPT_RISING, INT_SESS_VLD | INT_VBUS_VLD);
|
||||
|
||||
dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n",
|
||||
i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x00));
|
||||
dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n",
|
||||
i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x02));
|
||||
dev_info(udc->dev, "ISP1301 Vendor ID : 0x%04x\n", vendor);
|
||||
dev_info(udc->dev, "ISP1301 Product ID : 0x%04x\n", product);
|
||||
dev_info(udc->dev, "ISP1301 Version ID : 0x%04x\n",
|
||||
i2c_smbus_read_word_data(udc->isp1301_i2c_client, 0x14));
|
||||
|
||||
}
|
||||
|
||||
/* Enables or disables the USB device pullup via the ISP1301 transceiver */
|
||||
|
@ -658,6 +676,10 @@ static void isp1301_pullup_enable(struct lpc32xx_udc *udc, int en_pullup,
|
|||
/* Powers up or down the ISP1301 transceiver */
|
||||
static void isp1301_set_powerstate(struct lpc32xx_udc *udc, int enable)
|
||||
{
|
||||
/* There is no "global power down" register for stotg04 */
|
||||
if (udc->atx == STOTG04)
|
||||
return;
|
||||
|
||||
if (enable != 0)
|
||||
/* Power up ISP1301 - this ISP1301 will automatically wakeup
|
||||
when VBUS is detected */
|
||||
|
|
Loading…
Reference in New Issue