[U-Boot] [PATCH 3/8] TWL4030 Add usb PHY support

Jean-Christophe PLAGNIOL-VILLARD plagnioj at jcrosoft.com
Sat Sep 5 02:02:56 CEST 2009


On 15:12 Fri 04 Sep     , Tom Rix wrote:
> The twl4030 provides a PHY device for connecting a link device,
> like musb, to physical connection.
> 
> This change adds the twl4030 usb registers and functions for
> initializing the PHY as required by omap3.
> 
> Signed-off-by: Tom Rix <Tom.Rix at windriver.com>
> ---
>  Makefile                  |    1 +
>  drivers/usb/phy/Makefile  |   44 +++++++++++
>  drivers/usb/phy/twl4030.c |  184 +++++++++++++++++++++++++++++++++++++++++++++
>  include/twl4030.h         |  143 +++++++++++++++++++++++++++++++----
>  4 files changed, 357 insertions(+), 15 deletions(-)
>  create mode 100644 drivers/usb/phy/Makefile
>  create mode 100644 drivers/usb/phy/twl4030.c
> 
> diff --git a/Makefile b/Makefile
> index 329e0f5..dcaa1dc 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -241,6 +241,7 @@ LIBS += drivers/twserial/libtws.a
>  LIBS += drivers/usb/gadget/libusb_gadget.a
>  LIBS += drivers/usb/host/libusb_host.a
>  LIBS += drivers/usb/musb/libusb_musb.a
> +LIBS += drivers/usb/phy/libusb_phy.a
>  LIBS += drivers/video/libvideo.a
>  LIBS += drivers/watchdog/libwatchdog.a
>  LIBS += common/libcommon.a
> diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
> new file mode 100644
> index 0000000..200b907
> --- /dev/null
> +++ b/drivers/usb/phy/Makefile
> @@ -0,0 +1,44 @@
> +#
> +# Copyright (c) 2009 Wind River Systems, Inc.
> +# Tom Rix <Tom.Rix at windriver.com>
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	:= $(obj)libusb_phy.a
> +
> +COBJS-$(CONFIG_TWL4030_USB) += twl4030.o
> +COBJS-y := twl4030.o
> +
> +COBJS	:= $(COBJS-y)
> +SRCS	:= $(COBJS:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS))
> +
> +all:	$(LIB)
> +
> +$(LIB):	$(obj).depend $(OBJS)
> +	$(AR) $(ARFLAGS) $@ $(OBJS)
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/drivers/usb/phy/twl4030.c b/drivers/usb/phy/twl4030.c
> new file mode 100644
> index 0000000..32f1df3
> --- /dev/null
> +++ b/drivers/usb/phy/twl4030.c
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright (c) 2009 Wind River Systems, Inc.
> + * Tom Rix <Tom.Rix at windriver.com>
> + *
> + * This is file is based on
> + * repository git.gitorious.org/u-boot-omap3/mainline.git,
> + * branch omap3-dev-usb, file drivers/usb/gadget/twl4030_usb.c
> + *
> + * This is the unique part of its copyright :
> + *
> + * ------------------------------------------------------------------------
> + *
> + *  * (C) Copyright 2009 Atin Malaviya (atin.malaviya at gmail.com)
> + *
> + * Based on: twl4030_usb.c in linux 2.6 (drivers/i2c/chips/twl4030_usb.c)
> + * Copyright (C) 2004-2007 Texas Instruments
> + * Copyright (C) 2008 Nokia Corporation
> + * Contact: Felipe Balbi <felipe.balbi at nokia.com>
> + *
> + * Author: Atin Malaviya (atin.malaviya at gmail.com)
> + *
> + * ------------------------------------------------------------------------
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <twl4030.h>
> +
> +/* Defines for bits in registers */
> +#define OPMODE_MASK		(3 << 3)
> +#define XCVRSELECT_MASK		(3 << 0)
> +#define CARKITMODE		(1 << 2)
> +#define OTG_ENAB		(1 << 5)
> +#define PHYPWD			(1 << 0)
> +#define CLOCKGATING_EN		(1 << 2)
> +#define CLK32K_EN		(1 << 1)
> +#define REQ_PHY_DPLL_CLK	(1 << 0)
> +#define PHY_DPLL_CLK		(1 << 0)
> +
> +static int twl4030_usb_write(u8 address, u8 data)
> +{
> +	int ret;
please add an empty line
> +	ret = twl4030_i2c_write_u8(TWL4030_CHIP_USB, data, address);
> +	if (ret != 0)
> +		printf("TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
> +
> +	return ret;
> +}
> +
> +static int twl4030_usb_read(u8 address)
> +{
> +	u8 data;
> +	int ret;
please add an empty line
> +	ret = twl4030_i2c_read_u8(TWL4030_CHIP_USB, &data, address);

> +	if (ret == 0)
> +		ret = data;
> +	else
> +		printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
> +
> +	return ret;
why not this and avoid the copy of data
	if (ret != 0) {
		printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
		return ret;
	}

	return data;
}

> +
> +static void twl4030_phy_power(void)
> +{
> +	u8 pwr, clk;
please add an empty line
> +	/* Power the PHY */
> +	pwr = twl4030_usb_read(TWL4030_USB_PHY_PWR_CTRL);
> +	pwr &= ~PHYPWD;
> +	twl4030_usb_write(TWL4030_USB_PHY_PWR_CTRL, pwr);
please add an empty line to make it more readable
> +	/* Enable clocks */
> +	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
> +	clk |= CLOCKGATING_EN | CLK32K_EN;
> +	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
> +}
> +
> +/*
> + * Initiaze the ULPI interface
> + * ULPI : Universal Transceiver Macrocell Low Pin Interface
> + * An interface between the USB link controller like musb and the
> + * the PHY or transceiver that drives the actual bus.
> + */
> +int twl4030_usb_ulpi_init(void)
> +{
> +	long timeout = 1000 * 1000; /* 1 sec */;
> +	u8 clk, sts, pwr;
> +
> +	/* twl4030 ldo init */
> +	twl4030_usb_ldo_init();
> +
> +	/* Enable the twl4030 phy */
> +	twl4030_phy_power();
> +
> +	/* Enable DPLL to access PHY registers over I2C */
> +	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
> +	clk |= REQ_PHY_DPLL_CLK;
> +	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
> +
> +	/* Check if the PHY DPLL is locked */
> +	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
> +	while (!(sts & PHY_DPLL_CLK) && 0 < timeout) {
> +		udelay(10);
> +		sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
> +		timeout -= 10;
> +	}
why not set time to 100 * 1000
	and just decrease by 1
> +
> +	/* Final check */
> +	sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
> +	if (!(sts & PHY_DPLL_CLK)) {
> +		printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n");
> +		return -1;
> +	}
> +
> +	/*
> +	 * There are two circuit blocks attached to the PHY,
> +	 * Carkit and USB OTG.  Disable Carkit and enable USB OTG
> +	 */
> +	twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE);
> +	pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL);
> +	pwr |= OTG_ENAB;
> +	twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr);
please add an empty line to make it more readable
> +	/* Clear the opmode bits to ensure normal encode */
> +	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK);
please add an empty line to make it more readable
> +	/* Clear the xcvrselect bits to enable the high speed transeiver */
> +	twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK);
> +
> +	/* Let ULPI control the DPLL clock */
> +	clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
> +	clk &= ~REQ_PHY_DPLL_CLK;
> +	twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
> +
> +	return 0;
> +}
> diff --git a/include/twl4030.h b/include/twl4030.h
> index f260ecb..feaec47 100644
> --- a/include/twl4030.h
> +++ b/include/twl4030.h
> @@ -342,21 +342,129 @@
>  #define TWL4030_KEYPAD_CTRL_SOFT_NRST			(1 << 0)
>  
>  /* USB */
> -#define TWL4030_USB_FUNC_CTRL				(0x04)
> -#define TWL4030_USB_OPMODE_MASK				(3 << 3)
> -#define TWL4030_USB_XCVRSELECT_MASK			(3 << 0)
> -#define TWL4030_USB_IFC_CTRL				(0x07)
> -#define TWL4030_USB_CARKITMODE				(1 << 2)
> -#define TWL4030_USB_POWER_CTRL				(0xAC)
> -#define TWL4030_USB_OTG_ENAB				(1 << 5)
> -#define TWL4030_USB_PHY_PWR_CTRL			(0xFD)
> -#define TWL4030_USB_PHYPWD				(1 << 0)
> -#define TWL4030_USB_PHY_CLK_CTRL			(0xFE)
> -#define TWL4030_USB_CLOCKGATING_EN			(1 << 2)
> -#define TWL4030_USB_CLK32K_EN				(1 << 1)
> -#define TWL4030_USB_REQ_PHY_DPLL_CLK			(1 << 0)
> -#define TWL4030_USB_PHY_CLK_CTRL_STS			(0xFF)
> -#define TWL4030_USB_PHY_DPLL_CLK			(1 << 0)
make some enums by group of function will be better as it simplify the code
> +#define TWL4030_USB_VENDOR_ID_LO			0x00
> +#define TWL4030_USB_VENDOR_ID_HI			0x01
> +#define TWL4030_USB_PRODUCT_ID_LO			0x02
> +#define TWL4030_USB_PRODUCT_ID_HI			0x03
> +#define TWL4030_USB_FUNC_CTRL				0x04
> +#define TWL4030_USB_FUNC_CTRL_SET			0x05
> +#define TWL4030_USB_FUNC_CTRL_CLR			0x06
> +#define TWL4030_USB_IFC_CTRL				0x07
> +#define TWL4030_USB_IFC_CTRL_SET			0x08
> +#define TWL4030_USB_IFC_CTRL_CLR			0x09
> +#define TWL4030_USB_OTG_CTRL				0x0A
> +#define TWL4030_USB_OTG_CTRL_SET			0x0B
> +#define TWL4030_USB_OTG_CTRL_CLR			0x0C
> +#define TWL4030_USB_USB_INT_EN_RISE			0x0D
> +#define TWL4030_USB_USB_INT_EN_RISE_SET			0x0E
> +#define TWL4030_USB_USB_INT_EN_RISE_CLR			0x0F
> +#define TWL4030_USB_USB_INT_EN_FALL			0x10
> +#define TWL4030_USB_USB_INT_EN_FALL_SET			0x11
> +#define TWL4030_USB_USB_INT_EN_FALL_CLR			0x12
> +#define TWL4030_USB_USB_INT_STS				0x13
> +#define TWL4030_USB_USB_INT_LATCH			0x14
> +#define TWL4030_USB_DEBUG				0x15
> +#define TWL4030_USB_SCRATCH_REG				0x16
> +#define TWL4030_USB_SCRATCH_REG_SET			0x17
> +#define TWL4030_USB_SCRATCH_REG_CLR			0x18
> +#define TWL4030_USB_CARKIT_CTRL				0x19
> +#define TWL4030_USB_CARKIT_CTRL_SET			0x1A
> +#define TWL4030_USB_CARKIT_CTRL_CLR			0x1B
> +#define TWL4030_USB_CARKIT_INT_DELAY			0x1C
> +#define TWL4030_USB_CARKIT_INT_EN			0x1D
> +#define TWL4030_USB_CARKIT_INT_EN_SET			0x1E
> +#define TWL4030_USB_CARKIT_INT_EN_CLR			0x1F
> +#define TWL4030_USB_CARKIT_INT_STS			0x20
> +#define TWL4030_USB_CARKIT_INT_LATCH			0x21
> +#define TWL4030_USB_CARKIT_PLS_CTRL			0x22
> +#define TWL4030_USB_CARKIT_PLS_CTRL_SET			0x23
> +#define TWL4030_USB_CARKIT_PLS_CTRL_CLR			0x24
> +#define TWL4030_USB_TRANS_POS_WIDTH			0x25
> +#define TWL4030_USB_TRANS_NEG_WIDTH			0x26
> +#define TWL4030_USB_RCV_PLTY_RECOVERY			0x27
> +#define TWL4030_USB_MCPC_CTRL				0x30
> +#define TWL4030_USB_MCPC_CTRL_SET			0x31
> +#define TWL4030_USB_MCPC_CTRL_CLR			0x32
> +#define TWL4030_USB_MCPC_IO_CTRL			0x33
> +#define TWL4030_USB_MCPC_IO_CTRL_SET			0x34

Best Regards,
J.


More information about the U-Boot mailing list