m66592-udc.c revision f34c32f13ce8c539f3f582562358e39a86b00e83
14cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/* 24cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * M66592 UDC (USB gadget) 34cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 44cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * Copyright (C) 2006-2007 Renesas Solutions Corp. 54cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 64cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com> 74cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 84cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * This program is free software; you can redistribute it and/or modify 94cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * it under the terms of the GNU General Public License as published by 104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * the Free Software Foundation; version 2 of the License. 114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * This program is distributed in the hope that it will be useful, 134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * but WITHOUT ANY WARRANTY; without even the implied warranty of 144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * GNU General Public License for more details. 164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * You should have received a copy of the GNU General Public License 184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * along with this program; if not, write to the Free Software 194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda * 214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda */ 224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#include <linux/module.h> 244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#include <linux/interrupt.h> 25598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda#include <linux/delay.h> 26598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda#include <linux/io.h> 274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#include <linux/platform_device.h> 28598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#include <linux/usb/ch9.h> 309454a57ab5922e5cd25321cae9d1a8cbeb3e2e85David Brownell#include <linux/usb/gadget.h> 314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#include "m66592-udc.h" 334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 34598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 35598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro ShimodaMODULE_DESCRIPTION("M66592 USB gadget driver"); 364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro ShimodaMODULE_LICENSE("GPL"); 374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro ShimodaMODULE_AUTHOR("Yoshihiro Shimoda"); 38f34c32f13ce8c539f3f582562358e39a86b00e83Kay SieversMODULE_ALIAS("platform:m66592_udc"); 394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 408c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#define DRIVER_VERSION "18 Oct 2007" 414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/* module parameters */ 438c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 448c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimodastatic unsigned short endian = M66592_LITTLE; 458c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimodamodule_param(endian, ushort, 0644); 468c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro ShimodaMODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)"); 478c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#else 484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic unsigned short clock = M66592_XTAL24; 494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_param(clock, ushort, 0644); 50598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro ShimodaMODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " 51598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda "(default=16384)"); 52598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic unsigned short vif = M66592_LDRV; 544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_param(vif, ushort, 0644); 55598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro ShimodaMODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); 56598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 57598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimodastatic unsigned short endian; 584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_param(endian, ushort, 0644); 59598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro ShimodaMODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); 60598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic unsigned short irq_sense = M66592_INTL; 624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_param(irq_sense, ushort, 0644); 63598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro ShimodaMODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " 64598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda "(default=2)"); 658c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif 664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic const char udc_name[] = "m66592_udc"; 684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic const char *m66592_ep_name[] = { 694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda "ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7" 704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda}; 714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void disable_controller(struct m66592 *m66592); 734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req); 744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req); 754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, 764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda gfp_t gfp_flags); 774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void transfer_complete(struct m66592_ep *ep, 79598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda struct m66592_request *req, int status); 80598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline u16 get_usb_speed(struct m66592 *m66592) 834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return (m66592_read(m66592, M66592_DVSTCTR) & M66592_RHST); 854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, 88598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda unsigned long reg) 894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_INTENB0); 934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, 94598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_INTENB0); 954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, (1 << pipenum), reg); 964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, tmp, M66592_INTENB0); 974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, 100598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda unsigned long reg) 1014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 1034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_INTENB0); 1054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, 106598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_INTENB0); 1074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, (1 << pipenum), reg); 1084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, tmp, M66592_INTENB0); 1094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_usb_connect(struct m66592 *m66592) 1124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); 1144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, 115598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_INTENB0); 1164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); 1174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); 1194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_usb_disconnect(struct m66592 *m66592) 122598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__releases(m66592->lock) 123598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__acquires(m66592->lock) 1244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); 1264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, 127598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_INTENB0); 1284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); 1294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 1304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.speed = USB_SPEED_UNKNOWN; 1324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock(&m66592->lock); 1334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->driver->disconnect(&m66592->gadget); 1344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock(&m66592->lock); 1354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_controller(m66592); 1374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&m66592->ep[0].queue); 1384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) 1414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pid = 0; 1434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long offset; 1444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) 1464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pid = m66592_read(m66592, M66592_DCPCTR) & M66592_PID; 1474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else if (pipenum < M66592_MAX_NUM_PIPE) { 1484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda offset = get_pipectr_addr(pipenum); 1494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pid = m66592_read(m66592, offset) & M66592_PID; 1504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 15100274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("unexpect pipe num (%d)\n", pipenum); 1524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return pid; 1544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, 157598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 pid) 1584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long offset; 1604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) 1624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, pid, M66592_PID, M66592_DCPCTR); 1634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else if (pipenum < M66592_MAX_NUM_PIPE) { 1644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda offset = get_pipectr_addr(pipenum); 1654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, pid, M66592_PID, offset); 1664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 16700274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("unexpect pipe num (%d)\n", pipenum); 1684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void pipe_start(struct m66592 *m66592, u16 pipenum) 1714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_reg_set_pid(m66592, pipenum, M66592_PID_BUF); 1734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void pipe_stop(struct m66592 *m66592, u16 pipenum) 1764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_reg_set_pid(m66592, pipenum, M66592_PID_NAK); 1784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void pipe_stall(struct m66592 *m66592, u16 pipenum) 1814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_reg_set_pid(m66592, pipenum, M66592_PID_STALL); 1834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 1844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline u16 control_reg_get(struct m66592 *m66592, u16 pipenum) 1864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 ret = 0; 1884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long offset; 1894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) 1914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = m66592_read(m66592, M66592_DCPCTR); 1924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else if (pipenum < M66592_MAX_NUM_PIPE) { 1934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda offset = get_pipectr_addr(pipenum); 1944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = m66592_read(m66592, offset); 1954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 19600274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("unexpect pipe num (%d)\n", pipenum); 1974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return ret; 1994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 2004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void control_reg_sqclr(struct m66592 *m66592, u16 pipenum) 2024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 2034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long offset; 2044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, pipenum); 2064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) 2084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_SQCLR, M66592_DCPCTR); 2094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else if (pipenum < M66592_MAX_NUM_PIPE) { 2104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda offset = get_pipectr_addr(pipenum); 2114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_SQCLR, offset); 2124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 21300274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("unexpect pipe num(%d)\n", pipenum); 2144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 2154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline int get_buffer_size(struct m66592 *m66592, u16 pipenum) 2174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 2184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 2194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int size; 2204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) { 2224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_DCPCFG); 2234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((tmp & M66592_CNTMD) != 0) 2244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = 256; 2254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else { 2264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_DCPMAXP); 2274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = tmp & M66592_MAXP; 2284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 2294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 2304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, pipenum, M66592_PIPESEL); 2314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_PIPECFG); 2324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((tmp & M66592_CNTMD) != 0) { 2334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_PIPEBUF); 2344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = ((tmp >> 10) + 1) * 64; 2354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 2364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_PIPEMAXP); 2374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = tmp & M66592_MXPS; 2384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 2394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 2404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return size; 2424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 2434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic inline void pipe_change(struct m66592 *m66592, u16 pipenum) 2454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 2464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep = m66592->pipenum2ep[pipenum]; 2474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->use_dma) 2494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 2504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, pipenum, M66592_CURPIPE, ep->fifosel); 2524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ndelay(450); 2544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_MBW, ep->fifosel); 2564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 2574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int pipe_buffer_setting(struct m66592 *m66592, 259598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda struct m66592_pipe_info *info) 2604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 2614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 bufnum = 0, buf_bsize = 0; 2624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipecfg = 0; 2634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (info->pipe == 0) 2654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -EINVAL; 2664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, info->pipe, M66592_PIPESEL); 2684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 2694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (info->dir_in) 2704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipecfg |= M66592_DIR; 2714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipecfg |= info->type; 2724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipecfg |= info->epnum; 2734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (info->type) { 2744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_INT: 2754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufnum = 4 + (info->pipe - M66592_BASE_PIPENUM_INT); 2764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf_bsize = 0; 2774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 2784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_BULK: 2794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufnum = m66592->bi_bufnum + 2804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda (info->pipe - M66592_BASE_PIPENUM_BULK) * 16; 2814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bi_bufnum += 16; 2824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf_bsize = 7; 2834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipecfg |= M66592_DBLB; 2844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!info->dir_in) 2854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipecfg |= M66592_SHTNAK; 2864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 2874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_ISO: 2884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufnum = m66592->bi_bufnum + 2894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16; 2904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bi_bufnum += 16; 2914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf_bsize = 7; 2924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 2934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 2944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { 29500274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("m66592 pipe memory is insufficient(%d)\n", 296598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592->bi_bufnum); 2974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ENOMEM; 2984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 2994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, pipecfg, M66592_PIPECFG); 3014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, (buf_bsize << 10) | (bufnum), M66592_PIPEBUF); 3024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, info->maxpacket, M66592_PIPEMAXP); 3034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (info->interval) 3044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info->interval--; 3054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, info->interval, M66592_PIPEPERI); 3064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 3084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 3094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void pipe_buffer_release(struct m66592 *m66592, 3114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_pipe_info *info) 3124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 3134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (info->pipe == 0) 3144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 3154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (info->type) { 3174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_BULK: 3184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (is_bulk_pipe(info->pipe)) 3194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bi_bufnum -= 16; 3204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 3214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_ISO: 3224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (is_isoc_pipe(info->pipe)) 3234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bi_bufnum -= 16; 3244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 3254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 3264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (is_bulk_pipe(info->pipe)) { 3284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bulk--; 3294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else if (is_interrupt_pipe(info->pipe)) 3304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->interrupt--; 3314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else if (is_isoc_pipe(info->pipe)) { 3324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->isochronous--; 3334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (info->type == M66592_BULK) 3344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bulk--; 3354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 33600274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("ep_release: unexpect pipenum (%d)\n", 337598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda info->pipe); 3384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 3394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void pipe_initialize(struct m66592_ep *ep) 3414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 3424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 3434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel); 3454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_ACLRM, ep->pipectr); 3474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, 0, ep->pipectr); 3484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_SQCLR, ep->pipectr); 3494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->use_dma) { 3504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, ep->pipenum, M66592_CURPIPE, ep->fifosel); 3514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ndelay(450); 3534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_MBW, ep->fifosel); 3554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 3564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 3574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, 359598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda const struct usb_endpoint_descriptor *desc, 360598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 pipenum, int dma) 3614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 3624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((pipenum != 0) && dma) { 3634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->num_dma == 0) { 3644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->num_dma++; 3654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->use_dma = 1; 3664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoaddr = M66592_D0FIFO; 3674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifosel = M66592_D0FIFOSEL; 3684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoctr = M66592_D0FIFOCTR; 3694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifotrn = M66592_D0FIFOTRN; 3708c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) 3714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else if (m66592->num_dma == 1) { 3724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->num_dma++; 3734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->use_dma = 1; 3744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoaddr = M66592_D1FIFO; 3754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifosel = M66592_D1FIFOSEL; 3764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoctr = M66592_D1FIFOCTR; 3774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifotrn = M66592_D1FIFOTRN; 3788c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif 3794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 3804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->use_dma = 0; 3814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoaddr = M66592_CFIFO; 3824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifosel = M66592_CFIFOSEL; 3834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoctr = M66592_CFIFOCTR; 3844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifotrn = 0; 3854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 3864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 3874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->use_dma = 0; 3884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoaddr = M66592_CFIFO; 3894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifosel = M66592_CFIFOSEL; 3904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifoctr = M66592_CFIFOCTR; 3914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->fifotrn = 0; 3924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 3934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 3944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->pipectr = get_pipectr_addr(pipenum); 3954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->pipenum = pipenum; 396598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); 3974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->pipenum2ep[pipenum] = ep; 3984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; 3994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&ep->queue); 4004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 4014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_ep_release(struct m66592_ep *ep) 4034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 4044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 4054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum = ep->pipenum; 4064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pipenum == 0) 4084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 4094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->use_dma) 4114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->num_dma--; 4124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->pipenum = 0; 4134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->busy = 0; 4144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->use_dma = 0; 4154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 4164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int alloc_pipe_config(struct m66592_ep *ep, 418598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda const struct usb_endpoint_descriptor *desc) 4194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 4204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 4214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_pipe_info info; 4224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int dma = 0; 4234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int *counter; 4244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int ret; 4254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->desc = desc; 4274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda BUG_ON(ep->pipenum); 4294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 430598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { 4314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_ENDPOINT_XFER_BULK: 4324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->bulk >= M66592_MAX_NUM_BULK) { 4334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { 43400274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("bulk pipe is insufficient\n"); 4354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ENODEV; 4364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 437598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda info.pipe = M66592_BASE_PIPENUM_ISOC 438598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda + m66592->isochronous; 4394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda counter = &m66592->isochronous; 4404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 4424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.pipe = M66592_BASE_PIPENUM_BULK + m66592->bulk; 4434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda counter = &m66592->bulk; 4444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.type = M66592_BULK; 4464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda dma = 1; 4474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 4484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_ENDPOINT_XFER_INT: 4494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->interrupt >= M66592_MAX_NUM_INT) { 45000274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("interrupt pipe is insufficient\n"); 4514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ENODEV; 4524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.pipe = M66592_BASE_PIPENUM_INT + m66592->interrupt; 4544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.type = M66592_INT; 4554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda counter = &m66592->interrupt; 4564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 4574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_ENDPOINT_XFER_ISOC: 4584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { 45900274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("isochronous pipe is insufficient\n"); 4604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ENODEV; 4614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.pipe = M66592_BASE_PIPENUM_ISOC + m66592->isochronous; 4634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.type = M66592_ISO; 4644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda counter = &m66592->isochronous; 4654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 4664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 46700274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("unexpect xfer type\n"); 4684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -EINVAL; 4694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->type = info.type; 4714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 473598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); 4744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.interval = desc->bInterval; 4754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) 4764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.dir_in = 1; 4774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 4784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.dir_in = 0; 4794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = pipe_buffer_setting(m66592, &info); 4814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ret < 0) { 48200274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("pipe_buffer_setting fail\n"); 4834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return ret; 4844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 4854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda (*counter)++; 4874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((counter == &m66592->isochronous) && info.type == M66592_BULK) 4884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bulk++; 4894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_ep_setting(m66592, ep, desc, info.pipe, dma); 4914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_initialize(ep); 4924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 4944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 4954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 4964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int free_pipe_config(struct m66592_ep *ep) 4974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 4984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 4994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_pipe_info info; 5004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.pipe = ep->pipenum; 5024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda info.type = ep->type; 5034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_buffer_release(m66592, &info); 5044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_ep_release(ep); 5054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 5074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 5104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void pipe_irq_enable(struct m66592 *m66592, u16 pipenum) 5114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda enable_irq_ready(m66592, pipenum); 5134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda enable_irq_nrdy(m66592, pipenum); 5144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void pipe_irq_disable(struct m66592 *m66592, u16 pipenum) 5174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_ready(m66592, pipenum); 5194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_nrdy(m66592, pipenum); 5204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/* if complete is true, gadget driver complete function is not call */ 5234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void control_end(struct m66592 *m66592, unsigned ccpl) 5244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].internal_ccpl = ccpl; 5264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, 0); 5274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_CCPL, M66592_DCPCTR); 5284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) 5314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 5334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, ep->pipenum); 5354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, 536598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda (M66592_ISEL | M66592_CURPIPE), 537598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_CFIFOSEL); 5384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_BCLR, ep->fifoctr); 5394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (req->req.length == 0) { 5404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_BVAL, ep->fifoctr); 5414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, 0); 5424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, 0); 5434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 5444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS); 5454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_ep0_write(ep, req); 5464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 5474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void start_packet_write(struct m66592_ep *ep, struct m66592_request *req) 5504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 5524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 5534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, ep->pipenum); 5554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_empty(m66592, ep->pipenum); 5564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, ep->pipenum); 5574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, ep->fifoctr); 5594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (unlikely((tmp & M66592_FRDY) == 0)) 5604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_enable(m66592, ep->pipenum); 5614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 5624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_packet_write(ep, req); 5634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) 5664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 5684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum = ep->pipenum; 5694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->pipenum == 0) { 5714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, M66592_PIPE0, 572598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda (M66592_ISEL | M66592_CURPIPE), 573598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_CFIFOSEL); 5744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_BCLR, ep->fifoctr); 5754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, pipenum); 5764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_enable(m66592, pipenum); 5774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 5784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->use_dma) { 5794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_TRCLR, ep->fifosel); 5804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, pipenum); 5814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_TRENB, ep->fifosel); 5824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, 583598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda (req->req.length + ep->ep.maxpacket - 1) 584598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda / ep->ep.maxpacket, 585598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda ep->fifotrn); 5864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 5874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, pipenum); /* trigger once */ 5884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_enable(m66592, pipenum); 5894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 5904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 5924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void start_packet(struct m66592_ep *ep, struct m66592_request *req) 5934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 5944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->desc->bEndpointAddress & USB_DIR_IN) 5954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet_write(ep, req); 5964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 5974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet_read(ep, req); 5984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 5994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void start_ep0(struct m66592_ep *ep, struct m66592_request *req) 6014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 6024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 ctsq; 6034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ctsq = m66592_read(ep->m66592, M66592_INTSTS0) & M66592_CTSQ; 6054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctsq) { 6074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_RDDS: 6084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_ep0_write(ep, req); 6094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 6104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_WRDS: 6114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet_read(ep, req); 6124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 6134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_WRND: 6154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(ep->m66592, 0); 6164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 6174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 61800274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("start_ep0: unexpect ctsq(%x)\n", ctsq); 6194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 6204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 6214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 6224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6238c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 6248c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimodastatic void init_controller(struct m66592 *m66592) 6258c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda{ 6268c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda usbf_start_clock(); 6278c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ 6288c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); 6298c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 6308c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); 6318c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda 6328c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda /* This is a workaound for SH7722 2nd cut */ 6338c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, 0x8000, M66592_DVSTCTR); 6348c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, 0x1000, M66592_TESTMODE); 6358c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bclr(m66592, 0x8000, M66592_DVSTCTR); 6368c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda 6378c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, M66592_INTL, M66592_INTENB1); 6388c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda 6398c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_write(m66592, 0, M66592_CFBCFG); 6408c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_write(m66592, 0, M66592_D0FBCFG); 6418c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, endian, M66592_CFBCFG); 6428c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_bset(m66592, endian, M66592_D0FBCFG); 6438c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda} 6448c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#else /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ 6454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void init_controller(struct m66592 *m66592) 6464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 6474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), 648598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_PINCFG); 6494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ 6504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); 6514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); 6534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); 6544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_USBE, M66592_SYSCFG); 6554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 6574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda msleep(3); 6594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); 6614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda msleep(1); 6634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); 6654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); 6674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, 668598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_DMA0CFG); 6694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 6708c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif /* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ 6714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void disable_controller(struct m66592 *m66592) 6734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 6748c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 6758c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda usbf_stop_clock(); 6768c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#else 6774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); 6784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda udelay(1); 6794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); 6804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda udelay(1); 6814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG); 6824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda udelay(1); 6834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG); 6848c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif 6854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 6864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_start_xclock(struct m66592 *m66592) 6884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 6898c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 6908c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda usbf_start_clock(); 6918c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#else 6924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 6934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 6944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_SYSCFG); 6954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!(tmp & M66592_XCKE)) 6964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG); 6978c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif 6984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 6994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 7014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void transfer_complete(struct m66592_ep *ep, 702598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda struct m66592_request *req, int status) 703598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__releases(m66592->lock) 704598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__acquires(m66592->lock) 7054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 7064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int restart = 0; 7074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (unlikely(ep->pipenum == 0)) { 7094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->internal_ccpl) { 7104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->internal_ccpl = 0; 7114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 7124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda list_del_init(&req->queue); 7164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN) 7174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.status = -ESHUTDOWN; 7184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 7194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.status = status; 7204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!list_empty(&ep->queue)) 7224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda restart = 1; 7234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 724598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_unlock(&ep->m66592->lock); 725598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda req->req.complete(&ep->ep, &req->req); 726598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_lock(&ep->m66592->lock); 7274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (restart) { 7294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 7304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->desc) 7314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet(ep, req); 7324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 7344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) 7364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 7374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int i; 738598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 tmp; 7394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned bufsize; 7404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size_t size; 7414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda void *buf; 7424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum = ep->pipenum; 7434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 7444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, pipenum); 7464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_ISEL, ep->fifosel); 7474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda i = 0; 7494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda do { 7504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, ep->fifoctr); 7514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (i++ > 100000) { 75200274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("pipe0 is busy. maybe cpu i/o bus " 7534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda "conflict. please power off this controller."); 7544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 7554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ndelay(1); 7574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } while ((tmp & M66592_FRDY) == 0); 7584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* prepare parameters */ 7604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufsize = get_buffer_size(m66592, pipenum); 7614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf = req->req.buf + req->req.actual; 7624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = min(bufsize, req->req.length - req->req.actual); 7634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* write fifo */ 7654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (req->req.buf) { 7664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (size > 0) 7674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write_fifo(m66592, ep->fifoaddr, buf, size); 7684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((size == 0) || ((size % ep->ep.maxpacket) != 0)) 7694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_BVAL, ep->fifoctr); 7704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* update parameters */ 7734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.actual += size; 7744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* check transfer finish */ 776598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((!req->req.zero && (req->req.actual == req->req.length)) 777598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size % ep->ep.maxpacket) 778598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size == 0)) { 7794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_ready(m66592, pipenum); 7804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_empty(m66592, pipenum); 7814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 7824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_ready(m66592, pipenum); 7834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda enable_irq_empty(m66592, pipenum); 7844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 7854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, pipenum); 7864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 7874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) 7894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 7904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 7914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned bufsize; 7924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size_t size; 7934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda void *buf; 7944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum = ep->pipenum; 7954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 7964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 7974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, pipenum); 7984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, ep->fifoctr); 7994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (unlikely((tmp & M66592_FRDY) == 0)) { 8004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, pipenum); 8014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_disable(m66592, pipenum); 80200274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("write fifo not ready. pipnum=%d\n", pipenum); 8034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 8044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* prepare parameters */ 8074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufsize = get_buffer_size(m66592, pipenum); 8084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf = req->req.buf + req->req.actual; 8094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = min(bufsize, req->req.length - req->req.actual); 8104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* write fifo */ 8124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (req->req.buf) { 8134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write_fifo(m66592, ep->fifoaddr, buf, size); 814598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((size == 0) 815598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || ((size % ep->ep.maxpacket) != 0) 816598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || ((bufsize != ep->ep.maxpacket) 817598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda && (bufsize > size))) 8184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_BVAL, ep->fifoctr); 8194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* update parameters */ 8224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.actual += size; 8234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* check transfer finish */ 824598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((!req->req.zero && (req->req.actual == req->req.length)) 825598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size % ep->ep.maxpacket) 826598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size == 0)) { 8274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_ready(m66592, pipenum); 8284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda enable_irq_empty(m66592, pipenum); 8294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 8304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_empty(m66592, pipenum); 8314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_enable(m66592, pipenum); 8324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 8344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) 8364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 8374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 8384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int rcv_len, bufsize, req_len; 8394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int size; 8404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda void *buf; 8414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum = ep->pipenum; 8424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = ep->m66592; 8434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int finish = 0; 8444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_change(m66592, pipenum); 8464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, ep->fifoctr); 8474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (unlikely((tmp & M66592_FRDY) == 0)) { 8484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.status = -EPIPE; 8494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, pipenum); 8504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_disable(m66592, pipenum); 85100274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("read fifo not ready"); 8524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; 8534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* prepare parameters */ 8564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda rcv_len = tmp & M66592_DTLN; 8574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bufsize = get_buffer_size(m66592, pipenum); 8584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda buf = req->req.buf + req->req.actual; 8604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req_len = req->req.length - req->req.actual; 8614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (rcv_len < bufsize) 8624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = min(rcv_len, req_len); 8634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 8644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda size = min(bufsize, req_len); 8654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* update parameters */ 8674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.actual += size; 8684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* check transfer finish */ 870598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((!req->req.zero && (req->req.actual == req->req.length)) 871598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size % ep->ep.maxpacket) 872598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || (size == 0)) { 8734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, pipenum); 8744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_disable(m66592, pipenum); 8754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda finish = 1; 8764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* read fifo */ 8794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (req->req.buf) { 8804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (size == 0) 8814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, M66592_BCLR, ep->fifoctr); 8824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 8834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_read_fifo(m66592, ep->fifoaddr, buf, size); 8844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 8854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((ep->pipenum != 0) && finish) 8874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, 0); 8884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 8894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) 8914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 8924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 check; 8934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum; 8944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 8954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 8964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 8974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { 8984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); 8994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, 900598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_CFIFOSEL); 9014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = &m66592->ep[0]; 9034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 9044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_packet_read(ep, req); 9054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 9064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) { 9074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda check = 1 << pipenum; 9084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((status & check) && (enb & check)) { 9094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~check, M66592_BRDYSTS); 9104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = m66592->pipenum2ep[pipenum]; 9114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, 9124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request, queue); 9134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->desc->bEndpointAddress & USB_DIR_IN) 9144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_packet_write(ep, req); 9154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 9164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_packet_read(ep, req); 9174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 9214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) 9234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 9244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 9254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 check; 9264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pipenum; 9274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 9284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 9294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((status & M66592_BEMP0) && (enb & M66592_BEMP0)) { 9314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_BEMP0, M66592_BEMPSTS); 9324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = &m66592->ep[0]; 9344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 9354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_ep0_write(ep, req); 9364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 9374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda for (pipenum = 1; pipenum < M66592_MAX_NUM_PIPE; pipenum++) { 9384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda check = 1 << pipenum; 9394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((status & check) && (enb & check)) { 9404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~check, M66592_BEMPSTS); 9414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = control_reg_get(m66592, pipenum); 9424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((tmp & M66592_INBUFM) == 0) { 9434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_irq_empty(m66592, pipenum); 9444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_disable(m66592, pipenum); 9454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, pipenum); 9464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = m66592->pipenum2ep[pipenum]; 9474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, 9484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request, 9494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda queue); 9504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!list_empty(&ep->queue)) 9514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, 0); 9524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 9574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) 959598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__releases(m66592->lock) 960598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__acquires(m66592->lock) 9614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 9624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 9634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 pid; 9644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 status = 0; 965598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 w_index = le16_to_cpu(ctrl->wIndex); 9664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctrl->bRequestType & USB_RECIP_MASK) { 9684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_DEVICE: 969598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda status = 1 << USB_DEVICE_SELF_POWERED; 9704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 9714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_INTERFACE: 9724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda status = 0; 9734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 9744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_ENDPOINT: 975598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; 9764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pid = control_reg_get_pid(m66592, ep->pipenum); 9774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (pid == M66592_PID_STALL) 978598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda status = 1 << USB_ENDPOINT_HALT; 9794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 9804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda status = 0; 9814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 9824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 9834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(m66592, 0); 9844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return; /* exit */ 9854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 9864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 987598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592->ep0_data = cpu_to_le16(status); 988598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592->ep0_req->buf = &m66592->ep0_data; 9894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep0_req->length = 2; 99053b67950026ee642b43615f46df22ec3d36b4a53Al Viro /* AV: what happens if we get called again before that gets through? */ 991598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_unlock(&m66592->lock); 9924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); 993598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_lock(&m66592->lock); 9944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 9954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 9964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) 9974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 9984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctrl->bRequestType & USB_RECIP_MASK) { 9994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_DEVICE: 10004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_INTERFACE: 10034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_ENDPOINT: { 10064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 10074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 1008598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 w_index = le16_to_cpu(ctrl->wIndex); 10094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1010598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; 10114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(m66592, ep->pipenum); 10124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_reg_sqclr(m66592, ep->pipenum); 10134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, 10174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request, queue); 10184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->busy) { 10194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->busy = 0; 10204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (list_empty(&ep->queue)) 10214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet(ep, req); 10234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else if (!list_empty(&ep->queue)) 10244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_start(m66592, ep->pipenum); 10254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 10264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 10284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(m66592, 0); 10294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 10314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 10324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) 10344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 10354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctrl->bRequestType & USB_RECIP_MASK) { 10374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_DEVICE: 10384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_INTERFACE: 10414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_RECIP_ENDPOINT: { 10444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 1045598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda u16 w_index = le16_to_cpu(ctrl->wIndex); 10464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1047598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; 10484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(m66592, ep->pipenum); 10494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 1); 10514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 10524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 10544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(m66592, 0); 10554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 10574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 10584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/* if return value is true, call class driver's setup() */ 10604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int setup_packet(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) 10614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 10624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 *p = (u16 *)ctrl; 10634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long offset = M66592_USBREQ; 10644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int i, ret = 0; 10654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* read fifo */ 10674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_VALID, M66592_INTSTS0); 10684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda for (i = 0; i < 4; i++) 10704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda p[i] = m66592_read(m66592, offset + i*2); 10714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* check request */ 10734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { 10744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctrl->bRequest) { 10754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_REQ_GET_STATUS: 10764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda get_status(m66592, ctrl); 10774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_REQ_CLEAR_FEATURE: 10794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda clear_feature(m66592, ctrl); 10804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case USB_REQ_SET_FEATURE: 10824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda set_feature(m66592, ctrl); 10834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 10854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = 1; 10864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 10874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 10884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else 10894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = 1; 10904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return ret; 10914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 10924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_update_usb_speed(struct m66592 *m66592) 10944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 10954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 speed = get_usb_speed(m66592); 10964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 10974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (speed) { 10984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_HSMODE: 10994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.speed = USB_SPEED_HIGH; 11004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_FSMODE: 11024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.speed = USB_SPEED_FULL; 11034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 11054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.speed = USB_SPEED_UNKNOWN; 110600274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("USB speed unknown\n"); 11074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 11084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 11094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_device_state(struct m66592 *m66592) 11114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 11124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 dvsq; 11134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda dvsq = m66592_read(m66592, M66592_INTSTS0) & M66592_DVSQ; 11154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_DVST, M66592_INTSTS0); 11164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (dvsq == M66592_DS_DFLT) { /* bus reset */ 11184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->driver->disconnect(&m66592->gadget); 11194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_update_usb_speed(m66592); 11204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 11214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) 11224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_update_usb_speed(m66592); 1123598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) 1124598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda && m66592->gadget.speed == USB_SPEED_UNKNOWN) 11254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_update_usb_speed(m66592); 11264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->old_dvsq = dvsq; 11284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 11294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void irq_control_stage(struct m66592 *m66592) 1131598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__releases(m66592->lock) 1132598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda__acquires(m66592->lock) 11334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 11344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct usb_ctrlrequest ctrl; 11354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 ctsq; 11364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ctsq = m66592_read(m66592, M66592_INTSTS0) & M66592_CTSQ; 11384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, ~M66592_CTRT, M66592_INTSTS0); 11394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda switch (ctsq) { 11414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_IDST: { 11424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 11434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 11444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = &m66592->ep[0]; 11454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 11464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, 0); 11474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 11484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_RDDS: 11514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_WRDS: 11524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_WRND: 11534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (setup_packet(m66592, &ctrl)) { 1154598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_unlock(&m66592->lock); 11554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) 11564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(m66592, 0); 1157598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_lock(&m66592->lock); 11584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 11594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_RDSS: 11614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda case M66592_CS_WRSS: 11624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda control_end(m66592, 0); 11634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda default: 116500274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("ctrl_stage: unexpect ctsq(%x)\n", ctsq); 11664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda break; 11674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 11684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 11694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic irqreturn_t m66592_irq(int irq, void *_m66592) 11714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 11724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = _m66592; 11734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 intsts0; 11744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 intenb0; 11754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 brdysts, nrdysts, bempsts; 11764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 brdyenb, nrdyenb, bempenb; 11774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 savepipe; 11784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 mask0; 11794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1180598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_lock(&m66592->lock); 1181598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 11824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda intsts0 = m66592_read(m66592, M66592_INTSTS0); 11834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda intenb0 = m66592_read(m66592, M66592_INTENB0); 11844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 11858c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#if defined(CONFIG_SUPERH_BUILT_IN_M66592) 11868c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda if (!intsts0 && !intenb0) { 11878c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda /* 11888c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda * When USB clock stops, it cannot read register. Even if a 11898c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda * clock stops, the interrupt occurs. So this driver turn on 11908c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda * a clock by this timing and do re-reading of register. 11918c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda */ 11928c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda m66592_start_xclock(m66592); 11938c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda intsts0 = m66592_read(m66592, M66592_INTSTS0); 11948c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda intenb0 = m66592_read(m66592, M66592_INTENB0); 11958c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda } 11968c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda#endif 11978c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda 11984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda savepipe = m66592_read(m66592, M66592_CFIFOSEL); 11994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda mask0 = intsts0 & intenb0; 12014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (mask0) { 12024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda brdysts = m66592_read(m66592, M66592_BRDYSTS); 12034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda nrdysts = m66592_read(m66592, M66592_NRDYSTS); 12044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bempsts = m66592_read(m66592, M66592_BEMPSTS); 12054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda brdyenb = m66592_read(m66592, M66592_BRDYENB); 12064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda nrdyenb = m66592_read(m66592, M66592_NRDYENB); 12074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda bempenb = m66592_read(m66592, M66592_BEMPENB); 12084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (mask0 & M66592_VBINT) { 1210598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592_write(m66592, 0xffff & ~M66592_VBINT, 1211598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda M66592_INTSTS0); 12124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_start_xclock(m66592); 12134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* start vbus sampling */ 12154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) 1216598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda & M66592_VBSTS; 12174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->scount = M66592_MAX_SAMPLING; 12184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda mod_timer(&m66592->timer, 1220598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda jiffies + msecs_to_jiffies(50)); 12214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (intsts0 & M66592_DVSQ) 12234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_device_state(m66592); 12244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1225598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) 1226598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda && (brdysts & brdyenb)) { 12274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_pipe_ready(m66592, brdysts, brdyenb); 12284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 1229598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) 1230598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda && (bempsts & bempenb)) { 12314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_pipe_empty(m66592, bempsts, bempenb); 12324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (intsts0 & M66592_CTRT) 12354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq_control_stage(m66592); 12364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_write(m66592, savepipe, M66592_CFIFOSEL); 12394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1240598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda spin_unlock(&m66592->lock); 12414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return IRQ_HANDLED; 12424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 12434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_timer(unsigned long _m66592) 12454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 12464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = (struct m66592 *)_m66592; 12474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 12484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda u16 tmp; 12494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&m66592->lock, flags); 12514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_SYSCFG); 12524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!(tmp & M66592_RCKE)) { 12534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG); 12544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda udelay(10); 12554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG); 12564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->scount > 0) { 12584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda tmp = m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS; 12594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (tmp == m66592->old_vbus) { 12604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->scount--; 12614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->scount == 0) { 12624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (tmp == M66592_VBSTS) 12634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_usb_connect(m66592); 12644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else 12654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_usb_disconnect(m66592); 12664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 12674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda mod_timer(&m66592->timer, 1268598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda jiffies + msecs_to_jiffies(50)); 12694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 12714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->scount = M66592_MAX_SAMPLING; 12724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->old_vbus = tmp; 12734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda mod_timer(&m66592->timer, 1274598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda jiffies + msecs_to_jiffies(50)); 12754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 12774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&m66592->lock, flags); 12784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 12794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 12814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_enable(struct usb_ep *_ep, 12824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda const struct usb_endpoint_descriptor *desc) 12834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 12844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 12854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 12874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return alloc_pipe_config(ep, desc); 12884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 12894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_disable(struct usb_ep *_ep) 12914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 12924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 12934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 12944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 12954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 12974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda BUG_ON(!ep); 12984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 12994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda while (!list_empty(&ep->queue)) { 13004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 13014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&ep->m66592->lock, flags); 13024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, -ECONNRESET); 13034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&ep->m66592->lock, flags); 13044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 13054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_irq_disable(ep->m66592, ep->pipenum); 13074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return free_pipe_config(ep); 13084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 13094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic struct usb_request *m66592_alloc_request(struct usb_ep *_ep, 13114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda gfp_t gfp_flags) 13124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 13134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 13144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = kzalloc(sizeof(struct m66592_request), gfp_flags); 13164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!req) 13174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return NULL; 13184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&req->queue); 13204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return &req->req; 13224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 13234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_free_request(struct usb_ep *_ep, struct usb_request *_req) 13254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 13264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 13274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = container_of(_req, struct m66592_request, req); 13294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda kfree(req); 13304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 13314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, 13334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda gfp_t gfp_flags) 13344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 13354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 13364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 13374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 13384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int request = 0; 13394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 13414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = container_of(_req, struct m66592_request, req); 13424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ep->m66592->gadget.speed == USB_SPEED_UNKNOWN) 13444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ESHUTDOWN; 13454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&ep->m66592->lock, flags); 13474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13484cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (list_empty(&ep->queue)) 13494cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda request = 1; 13504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda list_add_tail(&req->queue, &ep->queue); 13524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.actual = 0; 13534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req->req.status = -EINPROGRESS; 13544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1355a9475226977917afd5a85621f8a3d7f380a9da31David Brownell if (ep->desc == NULL) /* control */ 13564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_ep0(ep, req); 13574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda else { 13584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (request && !ep->busy) 13594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda start_packet(ep, req); 13604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 13614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&ep->m66592->lock, flags); 13634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 13654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 13664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_dequeue(struct usb_ep *_ep, struct usb_request *_req) 13684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 13694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 13704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 13714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 13724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 13744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = container_of(_req, struct m66592_request, req); 13754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&ep->m66592->lock, flags); 13774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!list_empty(&ep->queue)) 13784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda transfer_complete(ep, req, -ECONNRESET); 13794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&ep->m66592->lock, flags); 13804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 13824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 13834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_set_halt(struct usb_ep *_ep, int value) 13854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 13864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 13874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_request *req; 13884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 13894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int ret = 0; 13904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 13924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda req = list_entry(ep->queue.next, struct m66592_request, queue); 13934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 13944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&ep->m66592->lock, flags); 13954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!list_empty(&ep->queue)) { 13964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = -EAGAIN; 13974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto out; 13984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 13994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (value) { 14004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->busy = 1; 14014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stall(ep->m66592, ep->pipenum); 14024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } else { 14034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->busy = 0; 14044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(ep->m66592, ep->pipenum); 14054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 14064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodaout: 14084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&ep->m66592->lock, flags); 14094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return ret; 14104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 14114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void m66592_fifo_flush(struct usb_ep *_ep) 14134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 14144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep; 14154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 14164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep = container_of(_ep, struct m66592_ep, ep); 14184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&ep->m66592->lock, flags); 14194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (list_empty(&ep->queue) && !ep->busy) { 14204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda pipe_stop(ep->m66592, ep->pipenum); 14214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(ep->m66592, M66592_BCLR, ep->fifoctr); 14224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 14234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&ep->m66592->lock, flags); 14244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 14254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic struct usb_ep_ops m66592_ep_ops = { 14274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .enable = m66592_enable, 14284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .disable = m66592_disable, 14294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .alloc_request = m66592_alloc_request, 14314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .free_request = m66592_free_request, 14324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .queue = m66592_queue, 14344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .dequeue = m66592_dequeue, 14354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .set_halt = m66592_set_halt, 14374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .fifo_flush = m66592_fifo_flush, 14384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda}; 14394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 14414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic struct m66592 *the_controller; 14424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodaint usb_gadget_register_driver(struct usb_gadget_driver *driver) 14444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 14454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = the_controller; 14464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int retval; 14474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1448598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if (!driver 1449598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || driver->speed != USB_SPEED_HIGH 1450598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || !driver->bind 1451598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda || !driver->setup) 14524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -EINVAL; 14534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!m66592) 14544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -ENODEV; 14554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->driver) 14564cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return -EBUSY; 14574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* hook up the driver */ 14594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda driver->driver.bus = NULL; 14604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->driver = driver; 14614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.dev.driver = &driver->driver; 14624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda retval = device_add(&m66592->gadget.dev); 14644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (retval) { 146500274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("device_add error (%d)\n", retval); 14664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto error; 14674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 14684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda retval = driver->bind (&m66592->gadget); 14704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (retval) { 147100274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("bind to driver error (%d)\n", retval); 14724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda device_del(&m66592->gadget.dev); 14734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto error; 14744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 14754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bset(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); 14774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592_read(m66592, M66592_INTSTS0) & M66592_VBSTS) { 14784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_start_xclock(m66592); 14794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* start vbus sampling */ 14804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->old_vbus = m66592_read(m66592, 14814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda M66592_INTSTS0) & M66592_VBSTS; 14824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->scount = M66592_MAX_SAMPLING; 1483598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50)); 14844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 14854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 14874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodaerror: 14894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->driver = NULL; 14904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.dev.driver = NULL; 14914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return retval; 14934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 14944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro ShimodaEXPORT_SYMBOL(usb_gadget_register_driver); 14954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 14964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodaint usb_gadget_unregister_driver(struct usb_gadget_driver *driver) 14974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 14984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = the_controller; 14994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda unsigned long flags; 15004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1501598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda if (driver != m66592->driver || !driver->unbind) 1502598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda return -EINVAL; 1503598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 15044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_irqsave(&m66592->lock, flags); 15054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->gadget.speed != USB_SPEED_UNKNOWN) 15064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_usb_disconnect(m66592); 15074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_unlock_irqrestore(&m66592->lock, flags); 15084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_bclr(m66592, M66592_VBSE | M66592_URST, M66592_INTENB0); 15104cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15114cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda driver->unbind(&m66592->gadget); 1512eb0be47dbbdca133b1b94adc564297f25176b3abPatrik Sevallius m66592->gadget.dev.driver = NULL; 15134cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda init_controller(m66592); 15154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda disable_controller(m66592); 15164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda device_del(&m66592->gadget.dev); 15184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->driver = NULL; 15194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 15204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 15214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro ShimodaEXPORT_SYMBOL(usb_gadget_unregister_driver); 15224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 15244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int m66592_get_frame(struct usb_gadget *_gadget) 15254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 15264cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = gadget_to_m66592(_gadget); 15274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return m66592_read(m66592, M66592_FRMNUM) & 0x03FF; 15284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 15294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic struct usb_gadget_ops m66592_gadget_ops = { 15314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .get_frame = m66592_get_frame, 15324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda}; 15334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1534598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimodastatic int __exit m66592_remove(struct platform_device *pdev) 15354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 15364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); 15374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda del_timer_sync(&m66592->timer); 15394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda iounmap(m66592->reg); 15404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda free_irq(platform_get_irq(pdev, 0), m66592); 1541598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 15428c73aff6d3b772e5f373d78bc34fd47b10b35fefYoshihiro Shimoda usbf_stop_clock(); 15434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda kfree(m66592); 15444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 15454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 15464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1547598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimodastatic void nop_completion(struct usb_ep *ep, struct usb_request *r) 1548598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda{ 1549598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda} 1550598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 15514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda#define resource_len(r) (((r)->end - (r)->start) + 1) 1552598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda 15534cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int __init m66592_probe(struct platform_device *pdev) 15544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1555598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda struct resource *res; 1556598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda int irq; 15574cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda void __iomem *reg = NULL; 15584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592 *m66592 = NULL; 15594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int ret = 0; 15604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda int i; 15614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1563598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda (char *)udc_name); 15644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (!res) { 15654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = -ENODEV; 156600274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("platform_get_resource_byname error.\n"); 15674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto clean_up; 15684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 15694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda irq = platform_get_irq(pdev, 0); 15714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (irq < 0) { 15724cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = -ENODEV; 157300274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("platform_get_irq error.\n"); 15744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto clean_up; 15754cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 15764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda reg = ioremap(res->start, resource_len(res)); 15784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (reg == NULL) { 15794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ret = -ENOMEM; 158000274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("ioremap error.\n"); 15814cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto clean_up; 15824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 15834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda /* initialize ucd */ 15854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); 15864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592 == NULL) { 158700274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("kzalloc error\n"); 15884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto clean_up; 15894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 15904cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15914cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda spin_lock_init(&m66592->lock); 15924cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda dev_set_drvdata(&pdev->dev, m66592); 15934cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 15944cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.ops = &m66592_gadget_ops; 15954cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda device_initialize(&m66592->gadget.dev); 15964cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda strcpy(m66592->gadget.dev.bus_id, "gadget"); 15974cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.is_dualspeed = 1; 15984cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.dev.parent = &pdev->dev; 15994cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; 16004cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.dev.release = pdev->dev.release; 16014cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.name = udc_name; 16024cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16034cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda init_timer(&m66592->timer); 16044cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->timer.function = m66592_timer; 16054cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->timer.data = (unsigned long)m66592; 16064cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->reg = reg; 16074cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16084cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->bi_bufnum = M66592_BASE_BUFNUM; 16094cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 161015a1d5c9271219db2f1bc448247fb8ccbcc08418Yoshihiro Shimoda ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, 1611598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda udc_name, m66592); 16124cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (ret < 0) { 161300274921a052d3232d9f00856387fb269ac0af11David Brownell pr_err("request_irq error (%d)\n", ret); 16144cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda goto clean_up; 16154cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 16164cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16174cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&m66592->gadget.ep_list); 16184cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->gadget.ep0 = &m66592->ep[0].ep; 16194cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list); 16204cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda for (i = 0; i < M66592_MAX_NUM_PIPE; i++) { 16214cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda struct m66592_ep *ep = &m66592->ep[i]; 16224cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16234cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (i != 0) { 16244cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); 16254cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda list_add_tail(&m66592->ep[i].ep.ep_list, 1626598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda &m66592->gadget.ep_list); 16274cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 16284cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->m66592 = m66592; 16294cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda INIT_LIST_HEAD(&ep->queue); 16304cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->ep.name = m66592_ep_name[i]; 16314cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->ep.ops = &m66592_ep_ops; 16324cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda ep->ep.maxpacket = 512; 16334cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 16344cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].ep.maxpacket = 64; 16354cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].pipenum = 0; 16364cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].fifoaddr = M66592_CFIFO; 16374cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].fifosel = M66592_CFIFOSEL; 16384cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].fifoctr = M66592_CFIFOCTR; 16394cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].fifotrn = 0; 16404cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep[0].pipectr = get_pipectr_addr(0); 16414cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->pipenum2ep[0] = &m66592->ep[0]; 16424cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->epaddr2ep[0] = &m66592->ep[0]; 16434cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16444cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda the_controller = m66592; 16454cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16464cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); 16474cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->ep0_req == NULL) 1648598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda goto clean_up2; 1649598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda m66592->ep0_req->complete = nop_completion; 16504cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16514cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda init_controller(m66592); 16524cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1653598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); 16544cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return 0; 16554cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 1656598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimodaclean_up2: 1657598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda free_irq(irq, m66592); 16584cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodaclean_up: 16594cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592) { 16604cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (m66592->ep0_req) 16614cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); 16624cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda kfree(m66592); 16634cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda } 16644cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda if (reg) 16654cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda iounmap(reg); 16664cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16674cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda return ret; 16684cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 16694cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16704cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda/*-------------------------------------------------------------------------*/ 16714cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic struct platform_driver m66592_driver = { 1672598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda .remove = __exit_p(m66592_remove), 16734cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .driver = { 16744cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda .name = (char *) udc_name, 1675f34c32f13ce8c539f3f582562358e39a86b00e83Kay Sievers .owner = THIS_MODULE, 16764cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda }, 16774cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda}; 16784cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16794cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic int __init m66592_udc_init(void) 16804cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 1681598f22e11bef8171f2244128bf0341da38fe8a23Yoshihiro Shimoda return platform_driver_probe(&m66592_driver, m66592_probe); 16824cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 16834cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_init(m66592_udc_init); 16844cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda 16854cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodastatic void __exit m66592_udc_cleanup(void) 16864cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda{ 16874cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda platform_driver_unregister(&m66592_driver); 16884cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimoda} 16894cf2503c6801a69fee25030475eceeefb36d1b56Yoshihiro Shimodamodule_exit(m66592_udc_cleanup); 1690