From: Marek Vasut <marek.vasut@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] ulpi: add generic ULPI functionality
Date: Sat, 5 Nov 2011 22:37:10 +0100 [thread overview]
Message-ID: <201111052237.11105.marek.vasut@gmail.com> (raw)
In-Reply-To: <1320526223-30474-1-git-send-email-fermata7@gmail.com>
> Add generic functions for ULPI init and setting bits in
> ULPI registers.
>
> Signed-off-by: Jana Rapava <fermata7@gmail.com>
> Cc: Marek Vasut <marek.vasut@gmail.com>
> Cc: Remy Bohmer <linux@bohmer.net>
> Cc: Stefano Babic <sbabic@denx.de>
> Cc: Igor Grinberg <grinberg@compulab.co.il>
> ---
> Makefile | 1 +
> drivers/usb/ulpi/Makefile | 44 ++++++++++++++
> drivers/usb/ulpi/ulpi-viewport.c | 87 +++++++++++++++++++++++++++
> drivers/usb/ulpi/ulpi.c | 123
> ++++++++++++++++++++++++++++++++++++++ include/usb/ulpi.h |
> 16 +++++
> 5 files changed, 271 insertions(+), 0 deletions(-)
> create mode 100644 drivers/usb/ulpi/Makefile
> create mode 100644 drivers/usb/ulpi/ulpi-viewport.c
> create mode 100644 drivers/usb/ulpi/ulpi.c
>
> diff --git a/Makefile b/Makefile
> index 571c3eb..a475cb9 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -283,6 +283,7 @@ LIBS += drivers/usb/gadget/libusb_gadget.o
> LIBS += drivers/usb/host/libusb_host.o
> LIBS += drivers/usb/musb/libusb_musb.o
> LIBS += drivers/usb/phy/libusb_phy.o
> +LIBS += drivers/usb/ulpi/libusb_ulpi.o
> LIBS += drivers/video/libvideo.o
> LIBS += drivers/watchdog/libwatchdog.o
> LIBS += common/libcommon.o
> diff --git a/drivers/usb/ulpi/Makefile b/drivers/usb/ulpi/Makefile
> new file mode 100644
> index 0000000..f7b6e20
> --- /dev/null
> +++ b/drivers/usb/ulpi/Makefile
> @@ -0,0 +1,44 @@
> +#
> +# Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# 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_ulpi.o
> +
> +COBJS-$(CONFIG_USB_ULPI) += ulpi.o ulpi-viewport.o
> +
> +COBJS := $(COBJS-y)
> +SRCS := $(COBJS:.o=.c)
> +OBJS := $(addprefix $(obj),$(COBJS))
> +
> +all: $(LIB)
> +
> +$(LIB): $(obj).depend $(OBJS)
> + $(call cmd_link_o_target, $(OBJS))
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/drivers/usb/ulpi/ulpi-viewport.c
> b/drivers/usb/ulpi/ulpi-viewport.c new file mode 100644
> index 0000000..a0c213e
> --- /dev/null
> +++ b/drivers/usb/ulpi/ulpi-viewport.c
> @@ -0,0 +1,87 @@
> +/*
> + * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
> + * Based on:
> + * linux/drivers/usb/otg/ulpi_viewport.c
> + *
> + * Original Copyright follow:
> + * Copyright (C) 2011 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * 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.
> + *
> + */
> +
> +#include <watchdog.h>
> +#include <asm/io.h>
> +#include <usb/ulpi.h>
> +#include <usb/ehci-fsl.h>
> +
> +/* ULPI viewport control bits */
> +#define ULPI_WU (1 << 31)
> +#define ULPI_SS (1 << 27)
> +#define ULPI_RWRUN (1 << 30)
> +#define ULPI_RWCTRL (1 << 29)
> +
> +#define ULPI_ADDR_SHIFT 16
> +#define ulpi_write_mask(value) ((value) & 0xff)
> +#define ulpi_read_mask(value) (((value) >> 8) & 0xff)
> +
> +int ulpi_wait(struct usb_ehci *ehci, u32 ulpi_value, u32 ulpi_mask)
static
So this works only with EHCI? How generic is it then ?
> +{
> + int timeout = ULPI_TIMEOUT;
> + u32 tmp;
> +
> + writel(ulpi_value, &ehci->ulpi_viewpoint);
> +
> + /* Wait for the bits in ulpi_mask to become zero. */
> + while (--timeout) {
> + tmp = readl(&ehci->ulpi_viewpoint);
> + if (!(tmp & ulpi_mask))
> + break;
> + WATCHDOG_RESET();
> + }
> +
> + return !timeout;
> +}
> +
> +int ulpi_wakeup(struct usb_ehci *ehci)
static
> +{
> + if (readl(&ehci->ulpi_viewpoint) & ULPI_SS)
> + return 0; /* already awake */
> + return ulpi_wait(ehci, ULPI_WU, ULPI_WU);
> +}
> +
> +void ulpi_write(struct usb_ehci *ehci, u32 reg, u32 value)
> +{
> + u32 tmp;
> + if (ulpi_wakeup(ehci)) {
> + printf("ULPI wakeup timed out\n");
> + return;
> + }
> +
> + tmp = ulpi_wait(ehci, ULPI_RWRUN | ULPI_RWCTRL |
> + reg << ULPI_ADDR_SHIFT | ulpi_write_mask(value), ULPI_RWRUN);
> + if (tmp)
> + printf("ULPI write timed out\n");
> +}
> +
> +u32 ulpi_read(struct usb_ehci *ehci, u32 reg)
> +{
> + if (ulpi_wakeup(ehci)) {
> + printf("ULPI wakeup timed out\n");
> + return 0;
> + }
> +
> + if (ulpi_wait(ehci, ULPI_RWRUN | reg << ULPI_ADDR_SHIFT, ULPI_RWRUN)) {
> + printf("ULPI read timed out\n");
> + return 0;
> + }
> +
> + return ulpi_read_mask(readl(&ehci->ulpi_viewpoint));
> +}
> diff --git a/drivers/usb/ulpi/ulpi.c b/drivers/usb/ulpi/ulpi.c
> new file mode 100644
> index 0000000..b1c482a
> --- /dev/null
> +++ b/drivers/usb/ulpi/ulpi.c
> @@ -0,0 +1,123 @@
> +/*
> + * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
> + * Based on:
> + * linux/drivers/usb/otg/ulpi.c
> + * Generic ULPI USB transceiver support
> + *
> + * Original Copyright follow:
> + * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
> + *
> + * Based on sources from
> + *
> + * Sascha Hauer <s.hauer@pengutronix.de>
> + * Freescale Semiconductors
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <usb/ulpi.h>
> +#include <usb/ehci-fsl.h>
> +#include <exports.h>
> +
> +#ifdef DEBUG
> +#define debug(fmt, args...) printf(fmt, ##args)
> +#else
> +#define debug(fmt, args...)
> +#endif /* DEBUG */
#include <common.h>
> +
> +void ulpi_integrity_check(struct usb_ehci *ehci, struct ulpi_regs *ulpi)
> +{
> + u32 tmp = 0;
> + int i;
> + for (i = 0; i < 2; i++) {
> + ulpi_write(ehci, (u32)&ulpi->scratch_write,
> + ULPI_TEST_VALUE << i);
> + tmp = ulpi_read(ehci, (u32)&ulpi->scratch_write);
> +
> + if (tmp != (ULPI_TEST_VALUE << i)) {
> + printf("ULPI integrity check failed\n");
> + return;
> + }
> + }
> +}
> +
> +/*
> + * This is a family of wrapper functions which sets bits in ULPI
> registers. + * Access mode could be WRITE, SET or CLEAR.
> + * For further informations see ULPI 1.1 specification.
> + */
> +void ulpi_otg_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags)
break params in half, not past fn
> +{
> + switch (access_mode) {
> + case WRITE:
> + ulpi_write(ehci, (u32)&ulpi->otg_ctrl_write, flags);
> + break;
> + case SET:
> + ulpi_write(ehci, (u32)&ulpi->otg_ctrl_set, flags);
> + break;
> + case CLEAR:
> + ulpi_write(ehci, (u32)&ulpi->otg_ctrl_clear, flags);
> + break;
> + }
> +}
> +
> +void ulpi_function_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags) +{
> + switch (access_mode) {
> + case WRITE:
> + ulpi_write(ehci, (u32)&ulpi->function_ctrl_write, flags);
> + break;
> + case SET:
> + ulpi_write(ehci, (u32)&ulpi->function_ctrl_set, flags);
> + break;
> + case CLEAR:
> + ulpi_write(ehci, (u32)&ulpi->function_ctrl_clear, flags);
> + break;
> + }
> +}
> +
> +void ulpi_iface_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags) +{
> + switch (access_mode) {
> + case WRITE:
> + ulpi_write(ehci, (u32)&ulpi->iface_ctrl_write, flags);
> + break;
> + case SET:
> + ulpi_write(ehci, (u32)&ulpi->iface_ctrl_set, flags);
> + break;
> + case CLEAR:
> + ulpi_write(ehci, (u32)&ulpi->iface_ctrl_clear, flags);
> + break;
> + }
> +
> +}
Is this crap from linux or something?
> +
> +void ulpi_init(struct usb_ehci *ehci, struct ulpi_regs *ulpi)
> +{
> + u32 tmp = 0;
> + int reg;
> +
> + /* Assemble ID from four ULPI ID registers (8 bits each). */
> + for (reg = ULPI_ID_REGS_COUNT - 1; reg >= 0; reg--)
> + tmp |= ulpi_read(ehci, reg) << (reg * 8);
> +
> + /* Split ID into vendor and product ID. */
> + debug("Found ULPI TX, ID %04x:%04x\n", tmp >> 16, tmp & 0xffff);
> +
> + ulpi_integrity_check(ehci, ulpi);
> +}
> diff --git a/include/usb/ulpi.h b/include/usb/ulpi.h
> index 1519cc5..a8625a1 100644
> --- a/include/usb/ulpi.h
> +++ b/include/usb/ulpi.h
> @@ -15,6 +15,8 @@
> #ifndef __USB_ULPI_H
> #define __USB_ULPI_H
>
> +#include <usb/ehci-fsl.h>
> +
> #define ULPI_ID_REGS_COUNT 4
> #define ULPI_TEST_VALUE 0x55
> #define ULPI_TIMEOUT 1000 /* some reasonable value */
> @@ -25,6 +27,11 @@
> #define ULPI_RWRUN (1 << 30)
> #define ULPI_RWCTRL (1 << 29)
>
> +/* ULPI access modes */
> +#define WRITE 0x00
> +#define SET 0x01
> +#define CLEAR 0x02
> +
> struct ulpi_regs {
> /* Vendor ID and Product ID: 0x00 - 0x03 Read-only */
> u8 vendor_id_low;
> @@ -201,4 +208,13 @@ struct ulpi_regs {
> void ulpi_write(struct usb_ehci *ehci, u32 reg, u32 value);
> u32 ulpi_read(struct usb_ehci *ehci, u32 reg);
>
> +void ulpi_init(struct usb_ehci *ehci, struct ulpi_regs *ulpi);
> +
> +void ulpi_otg_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags); +void ulpi_function_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags); +void ulpi_iface_ctrl_flags
> + (struct usb_ehci *ehci, struct ulpi_regs *ulpi, int access_mode, u32
> flags); +
> #endif /* __USB_ULPI_H */
next prev parent reply other threads:[~2011-11-05 21:37 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-05 20:50 [U-Boot] [PATCH] ulpi: add generic ULPI functionality Jana Rapava
2011-11-05 21:37 ` Marek Vasut [this message]
2011-11-05 23:08 ` Jana Rapava
2011-11-05 23:13 ` Marek Vasut
2011-11-05 23:32 ` Jana Rapava
2011-11-05 23:35 ` Marek Vasut
2011-11-08 11:08 ` Igor Grinberg
2011-11-08 11:33 ` Igor Grinberg
2011-11-12 1:09 ` Jana Rapava
2011-11-14 7:40 ` Igor Grinberg
2011-11-12 17:29 ` [U-Boot] [PATCH v2] " Jana Rapava
2011-11-14 8:13 ` Igor Grinberg
2011-11-24 12:22 ` [U-Boot] [PATCH v3]ulpi: " Jana Rapava
2011-11-24 13:26 ` Igor Grinberg
2011-11-24 14:21 ` Marek Vasut
2011-11-25 18:39 ` Jana Rapava
2011-11-27 7:50 ` Igor Grinberg
2011-11-25 20:05 ` [U-Boot] [PATCH v4] ulpi: " Jana Rapava
2011-11-27 4:00 ` Simon Glass
2011-11-27 8:08 ` Igor Grinberg
2011-11-27 22:37 ` Jana Rapava
2011-11-27 23:34 ` Simon Glass
2011-11-27 22:30 ` Jana Rapava
2011-11-28 0:19 ` [U-Boot] [PATCH v5] " Jana Rapava
2011-11-28 7:39 ` Igor Grinberg
2011-11-28 17:06 ` Simon Glass
2011-11-28 19:43 ` [U-Boot] [PATCH v6] " Jana Rapava
2011-11-28 20:56 ` Simon Glass
2011-12-01 11:12 ` Igor Grinberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201111052237.11105.marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.