1c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda/*
2c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda * R8A66597 UDC
3c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda *
4c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda * Copyright (C) 2007-2009 Renesas Solutions Corp.
5c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda *
65db05c09ac107ef957b7a052d7bba8190c93b460Yoshihiro Shimoda * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
7c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda *
8c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda * This program is free software; you can redistribute it and/or modify
9c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda * it under the terms of the GNU General Public License as published by
10c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda * the Free Software Foundation; version 2 of the License.
11c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda */
12c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
13c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#ifndef __R8A66597_H__
14c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define __R8A66597_H__
15c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
16d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm#ifdef CONFIG_HAVE_CLK
17d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm#include <linux/clk.h>
18d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm#endif
19d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm
20c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#include <linux/usb/r8a66597.h>
21c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
22c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_SAMPLING	10
23c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
24c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_NUM_PIPE	8
25c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_NUM_BULK	3
26c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_NUM_ISOC	2
27c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_NUM_INT	2
28c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
29c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_BASE_PIPENUM_BULK	3
30c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_BASE_PIPENUM_ISOC	1
31c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_BASE_PIPENUM_INT	6
32c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
33c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_BASE_BUFNUM	6
34c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define R8A66597_MAX_BUFNUM	0x4F
35c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
36c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define is_bulk_pipe(pipenum)	\
37c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
38c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	 (pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
39c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define is_interrupt_pipe(pipenum)	\
40c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
41c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	 (pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
42c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define is_isoc_pipe(pipenum)	\
43c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
44c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
45c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
46b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda#define r8a66597_is_sudmac(r8a66597)	(r8a66597->pdata->sudmac)
47c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastruct r8a66597_pipe_info {
48c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	pipe;
49c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	epnum;
50c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	maxpacket;
51c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	type;
52c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	interval;
53c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16	dir_in;
54c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda};
55c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
56c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastruct r8a66597_request {
57c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct usb_request	req;
58c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct list_head	queue;
59c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda};
60c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
61c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastruct r8a66597_ep {
62c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct usb_ep		ep;
63c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct r8a66597		*r8a66597;
64b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	struct r8a66597_dma	*dma;
65c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
66c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct list_head	queue;
67c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned		busy:1;
689e7291c1124655980ab05fc89930de8e218c7d64Yoshihiro Shimoda	unsigned		wedge:1;
69c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned		internal_ccpl:1;	/* use only control */
70c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
71c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	/* this member can able to after r8a66597_enable */
72c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned		use_dma:1;
73c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			pipenum;
74c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			type;
75c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	const struct usb_endpoint_descriptor	*desc;
76c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	/* register address */
77c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char		fifoaddr;
78c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char		fifosel;
79c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char		fifoctr;
80c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char		pipectr;
81b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	unsigned char		pipetre;
82b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	unsigned char		pipetrn;
83b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda};
84b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda
85b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimodastruct r8a66597_dma {
86b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	unsigned		used:1;
87b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	unsigned		dir:1;	/* 1 = IN(write), 0 = OUT(read) */
88c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda};
89c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
90c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastruct r8a66597 {
91c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	spinlock_t		lock;
92e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt	void __iomem		*reg;
93b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	void __iomem		*sudmac_reg;
94c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
95d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm#ifdef CONFIG_HAVE_CLK
96d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm	struct clk *clk;
97d2e27bdf2870e507dd4abba1f56ca84ee6ae7232Magnus Damm#endif
98c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct r8a66597_platdata	*pdata;
99c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
100c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct usb_gadget		gadget;
101c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct usb_gadget_driver	*driver;
102c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
103c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct r8a66597_ep	ep[R8A66597_MAX_NUM_PIPE];
104c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct r8a66597_ep	*pipenum2ep[R8A66597_MAX_NUM_PIPE];
105c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct r8a66597_ep	*epaddr2ep[16];
106b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	struct r8a66597_dma	dma;
107c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
108c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct timer_list	timer;
109c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	struct usb_request	*ep0_req;	/* for internal request */
110c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			ep0_data;	/* for internal request */
111c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			old_vbus;
112c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			scount;
113c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16			old_dvsq;
114c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
115c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	/* pipe config */
116c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char bulk;
117c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char interrupt;
118c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char isochronous;
119c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned char num_dma;
120c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
121c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	unsigned irq_sense_low:1;
122c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda};
123c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
124c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define gadget_to_r8a66597(_gadget)	\
125c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		container_of(_gadget, struct r8a66597, gadget)
126c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
12712158f4280b4d42ef03b70a47d11b48dd8aad511Yoshihiro Shimoda#define r8a66597_to_dev(r8a66597)	(r8a66597->gadget.dev.parent)
128c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
129c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastatic inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
130c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda{
131e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt	return ioread16(r8a66597->reg + offset);
132c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda}
133c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
134c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastatic inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
13559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm				      unsigned long offset,
13659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm				      unsigned char *buf,
137c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda				      int len)
138c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda{
139e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt	void __iomem *fifoaddr = r8a66597->reg + offset;
14092d3489ec58b5897a407b07ad9954497a119d3d0Javier Martinez Canillas	unsigned int data = 0;
14159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	int i;
14259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
143c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	if (r8a66597->pdata->on_chip) {
14459c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* 32-bit accesses for on_chip controllers */
14559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
14659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* aligned buf case */
14759c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		if (len >= 4 && !((unsigned long)buf & 0x03)) {
148e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt			ioread32_rep(fifoaddr, buf, len / 4);
14959c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf += len & ~0x03;
15059c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			len &= 0x03;
15159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		}
15259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
15359c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* unaligned buf case */
15459c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		for (i = 0; i < len; i++) {
15559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			if (!(i & 0x03))
156e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt				data = ioread32(fifoaddr);
15759c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
15859c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
159c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		}
160c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	} else {
16159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* 16-bit accesses for external controllers */
16259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
16359c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* aligned buf case */
16459c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		if (len >= 2 && !((unsigned long)buf & 0x01)) {
165e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt			ioread16_rep(fifoaddr, buf, len / 2);
16659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf += len & ~0x01;
16759c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			len &= 0x01;
16859c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		}
16959c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
17059c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* unaligned buf case */
17159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		for (i = 0; i < len; i++) {
17259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			if (!(i & 0x01))
173e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt				data = ioread16(fifoaddr);
17459c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
17559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
17659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		}
177c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	}
178c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda}
179c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
180c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastatic inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
181c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda				  unsigned long offset)
182c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda{
183e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt	iowrite16(val, r8a66597->reg + offset);
184c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda}
185c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
1865c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimodastatic inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
1875c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda				 u16 val, u16 pat, unsigned long offset)
1885c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda{
1895c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	u16 tmp;
1905c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	tmp = r8a66597_read(r8a66597, offset);
1915c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	tmp = tmp & (~pat);
1925c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	tmp = tmp | val;
1935c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	r8a66597_write(r8a66597, tmp, offset);
1945c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda}
1955c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda
1965c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda#define r8a66597_bclr(r8a66597, val, offset)	\
1975c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda			r8a66597_mdfy(r8a66597, 0, val, offset)
1985c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda#define r8a66597_bset(r8a66597, val, offset)	\
1995c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda			r8a66597_mdfy(r8a66597, val, 0, offset)
2005c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda
201c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastatic inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
2020a85577627fc81936d3dbdfb349964024adcb01dYoshihiro Shimoda				       struct r8a66597_ep *ep,
20359c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm				       unsigned char *buf,
204c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda				       int len)
205c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda{
2060a85577627fc81936d3dbdfb349964024adcb01dYoshihiro Shimoda	void __iomem *fifoaddr = r8a66597->reg + ep->fifoaddr;
20759c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	int adj = 0;
20859c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	int i;
209c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
210c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	if (r8a66597->pdata->on_chip) {
21159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* 32-bit access only if buf is 32-bit aligned */
21259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		if (len >= 4 && !((unsigned long)buf & 0x03)) {
213e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt			iowrite32_rep(fifoaddr, buf, len / 4);
21459c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf += len & ~0x03;
21559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			len &= 0x03;
216c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		}
217c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	} else {
21859c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		/* 16-bit access only if buf is 16-bit aligned */
21959c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		if (len >= 2 && !((unsigned long)buf & 0x01)) {
220e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt			iowrite16_rep(fifoaddr, buf, len / 2);
22159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			buf += len & ~0x01;
22259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			len &= 0x01;
223c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		}
224c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	}
22559c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
22659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	/* adjust fifo address in the little endian case */
22759c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) {
22859c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		if (r8a66597->pdata->on_chip)
22959c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			adj = 0x03; /* 32-bit wide */
23059c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm		else
23159c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm			adj = 0x01; /* 16-bit wide */
23259c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	}
23359c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm
2345c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	if (r8a66597->pdata->wr0_shorted_to_wr1)
2355c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda		r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
23659c82d12aa898c2f373b7e44bdea0b7c762cecccMagnus Damm	for (i = 0; i < len; i++)
237e8b48669de54d390644c77cd26d5c9fccbc1e0a1Paul Mundt		iowrite8(buf[i], fifoaddr + adj - (i & adj));
2385c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda	if (r8a66597->pdata->wr0_shorted_to_wr1)
2395c481a639068ac34bd1dcd183f37b7a65d0e3841Yoshihiro Shimoda		r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
240c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda}
241c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
242c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimodastatic inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
243c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda{
244c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	u16 clock = 0;
245c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
246c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	switch (pdata->xtal) {
247c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_12MHZ:
248c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		clock = XTAL12;
249c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		break;
250c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_24MHZ:
251c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		clock = XTAL24;
252c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		break;
253c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	case R8A66597_PLATDATA_XTAL_48MHZ:
254c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		clock = XTAL48;
255c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		break;
256c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	default:
257c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
258c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda		break;
259c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	}
260c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
261c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	return clock;
262c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda}
263c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
264b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimodastatic inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597,
265b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda				       unsigned long offset)
266b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda{
267b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	return ioread32(r8a66597->sudmac_reg + offset);
268b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda}
269b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda
270b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimodastatic inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val,
271b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda					 unsigned long offset)
272b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda{
273b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda	iowrite32(val, r8a66597->sudmac_reg + offset);
274b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda}
275b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda
276c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define get_pipectr_addr(pipenum)	(PIPE1CTR + (pipenum - 1) * 2)
277b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda#define get_pipetre_addr(pipenum)	(PIPE1TRE + (pipenum - 1) * 4)
278b8a56e17e18cca2402b390c10b8d7f3cd0f6265bYoshihiro Shimoda#define get_pipetrn_addr(pipenum)	(PIPE1TRN + (pipenum - 1) * 4)
279c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
280c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define enable_irq_ready(r8a66597, pipenum)	\
281c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, BRDYENB)
282c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define disable_irq_ready(r8a66597, pipenum)	\
283c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, BRDYENB)
284c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define enable_irq_empty(r8a66597, pipenum)	\
285c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, BEMPENB)
286c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define disable_irq_empty(r8a66597, pipenum)	\
287c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, BEMPENB)
288c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define enable_irq_nrdy(r8a66597, pipenum)	\
289c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	enable_pipe_irq(r8a66597, pipenum, NRDYENB)
290c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#define disable_irq_nrdy(r8a66597, pipenum)	\
291c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda	disable_pipe_irq(r8a66597, pipenum, NRDYENB)
292c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
293c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda#endif	/* __R8A66597_H__ */
294c41442474a26984abaa094e96e42182868eab658Yoshihiro Shimoda
295