/*
* linux/drivers/usb/gadget/s3c2410_udc.c
*
* Samsung S3C24xx series on-chip full speed USB device controllers
*
* Copyright (C) 2004-2007 Herbert P�tzl - Arnaud Patard
* Additional cleanups by Ben Dooks <[email protected]>
*
* 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/usb.h>
#include <linux/usb/gadget.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/unaligned.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
#include <plat/regs-udc.h>
#include <plat/udc.h>
#include "s3c2410_udc.h"
#define DRIVER_DESC "S3C2410 USB Device Controller Gadget"
#define DRIVER_VERSION "29 Apr 2007"
#define DRIVER_AUTHOR "Herbert P�tzl <[email protected]>, " \
"Arnaud Patard <[email protected]>"
static const char gadget_name[] = "s3c2410_udc";
static const char driver_desc[] = DRIVER_DESC;
static struct s3c2410_udc *the_controller;
static struct clk *udc_clock;
static struct clk *usb_bus_clock;
static void __iomem *base_addr;
static u64 rsrc_start;
static u64 rsrc_len;
static struct dentry *s3c2410_udc_debugfs_root;
static inline u32 udc_read(u32 reg)
{
return readb(base_addr + reg);
}
static inline void udc_write(u32 value, u32 reg)
{
writeb(value, base_addr + reg);
}
static inline void udc_writeb(void __iomem *base, u32 value, u32 reg)
{
writeb(value, base + reg);
}
static struct s3c2410_udc_mach_info *udc_info;
/*************************** DEBUG FUNCTION ***************************/
#define DEBUG_NORMAL 1
#define DEBUG_VERBOSE 2
#ifdef CONFIG_USB_S3C2410_DEBUG
#define USB_S3C2410_DEBUG_LEVEL 0
static uint32_t s3c2410_ticks = 0;
static int dprintk(int level, const char *fmt, ...)
{
static char printk_buf[1024];
static long prevticks;
static int invocation;
va_list args;
int len;
if (level > USB_S3C2410_DEBUG_LEVEL)
return 0;
if (s3c2410_ticks != prevticks) {
prevticks = s3c2410_ticks;
invocation = 0;
}
len = scnprintf(printk_buf,
sizeof(printk_buf), "%1lu.%02d USB: ",
prevticks, invocation++);
va_start(args, fmt);
len = vscnprintf(printk_buf+len,
sizeof(printk_buf)-len, fmt, args);
va_end(args);
return printk(KERN_DEBUG "%s", printk_buf);
}
#else
static int dprintk(int level, const char *fmt, ...)
{
return 0;
}
#endif
static int s3c2410_udc_debugfs_seq_show(struct seq_file *m, void *p)
{
u32 addr_reg,pwr_reg,ep_int_reg,usb_int_reg;
u32 ep_int_en_reg, usb_int_en_reg, ep0_csr;
u32 ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2;
u32 ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2;
addr_reg = udc_read(S3C2410_UDC_FUNC_ADDR_REG);
pwr_reg = udc_read(S3C2410_UDC_PWR_REG);
ep_int_reg = udc_read(S3C2410_UDC_EP_INT_REG);
usb_int_reg = udc_read(S3C2410_UDC_USB_INT_REG);
ep_int_en_reg = udc_read(S3C2410_UDC_EP_INT_EN_REG);
usb_int_en_reg = udc_read(S3C2410_UDC_USB_INT_EN_REG);
udc_write(0, S3C2410_UDC_INDEX_REG);
ep0_csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
udc_write(1, S3C2410_UDC_INDEX_REG);
ep1_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
ep1_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
ep1_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
ep1_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
udc_write(2, S3C2410_UDC_INDEX_REG);
ep2_i_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
ep2_i_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
ep2_o_csr1 = udc_read(S3C2410_UDC_IN_CSR1_REG);
ep2_o_csr2 = udc_read(S3C2410_UDC_IN_CSR2_REG);
seq_printf(m, "FUNC_ADDR_REG : 0x%04X\n"
"PWR_REG : 0x%04X\n"
"EP_INT_REG : 0x%04X\n"
"USB_INT_REG : 0x%04X\n"
"EP_INT_EN_REG : 0x%04X\n"
"USB_INT_EN_REG : 0x%04X\n"
"EP0_CSR : 0x%04X\n"
"EP1_I_CSR1 : 0x%04X\n"
"EP1_I_CSR2 : 0x%04X\n"
"EP1_O_CSR1 : 0x%04X\n"
"EP1_O_CSR2 : 0x%04X\n"
"EP2_I_CSR1 : 0x%04X\n"
"EP2_I_CSR2 : 0x%04X\n"
"EP2_O_CSR1 : 0x%04X\n"
"EP2_O_CSR2 : 0x%04X\n",
addr_reg,pwr_reg,ep_int_reg,usb_int_reg,
ep_int_en_reg, usb_int_en_reg, ep0_csr,
ep1_i_csr1,ep1_i_csr2,ep1_o_csr1,ep1_o_csr2,
ep2_i_csr1,ep2_i_csr2,ep2_o_csr1,ep2_o_csr2
);
return 0;
}
static int s3c2410_udc_debugfs_fops_open(struct inode *inode,
struct file *file)
{
return single_open(file, s3c2410_udc_debugfs_seq_show, NULL);
}
static const struct file_operations s3c2410_udc_debugfs_fops = {
.open = s3c2410_udc_debugfs_fops_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.owner = THIS_MODULE,
};
/* io macros */
static inline void s3c2410_udc_clear_ep0_opr(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, S3C2410_UDC_EP0_CSR_SOPKTRDY,
S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_clear_ep0_sst(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
writeb(0x00, base + S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_clear_ep0_se(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, S3C2410_UDC_EP0_CSR_SSE, S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_set_ep0_ipr(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, S3C2410_UDC_EP0_CSR_IPKRDY, S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_set_ep0_de(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, S3C2410_UDC_EP0_CSR_DE, S3C2410_UDC_EP0_CSR_REG);
}
inline void s3c2410_udc_set_ep0_ss(void __iomem *b)
{
udc_writeb(b, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(b, S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_set_ep0_de_out(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base,(S3C2410_UDC_EP0_CSR_SOPKTRDY
| S3C2410_UDC_EP0_CSR_DE),
S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_set_ep0_sse_out(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, (S3C2410_UDC_EP0_CSR_SOPKTRDY
| S3C2410_UDC_EP0_CSR_SSE),
S3C2410_UDC_EP0_CSR_REG);
}
static inline void s3c2410_udc_set_ep0_de_in(void __iomem *base)
{
udc_writeb(base, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
udc_writeb(base, (S3C2410_UDC_EP0_CSR_IPKRDY
| S3C2410_UDC_EP0_CSR_DE),
S3C2410_UDC_EP0_CSR_REG);
}
/*------------------------- I/O ----------------------------------*/
/*
* s3c2410_udc_done
*/
static void s3c2410_udc_done(struct s3c2410_ep *ep,
struct s3c2410_request *req, int status)
{
unsigned halted = ep->halted;
list_del_init(&req->queue);
if (likely (req->req.status == -EINPROGRESS))
req->req.status = status;
else
status = req->req.status;
ep->halted = 1;
req->req.complete(&ep->ep, &req->req);
ep->halted = halted;
}
stati
s3c2410_udc.rar_s3c2410_udc
版权申诉
98 浏览量
2022-09-19
18:43:13
上传
评论
收藏 11KB RAR 举报
小波思基
- 粉丝: 72
- 资源: 1万+
最新资源
- Python 程序语言设计模式思路-行为型模式:策略模式:将算法封装成独立的类,并使它们可以互相替换及支付模式数据压缩
- main.py
- Last Loaded Test.DBK
- Screenshot_20240520_163011.jpg
- ubuntu-python3-whisper-tornado docker镜像 Dockerfile
- ubuntu-python3-whisper-tornado docker镜像07
- 新录音 8.m4a
- ubuntu-python3-whisper-tornado docker镜像
- ubuntu-python3-whisper-tornado docker镜像
- ubuntu-python3-whisper-tornado docker镜像09
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈