2010-03-12 11:29:11 +03:00
/*
* MUSB OTG driver debugfs support
*
* Copyright 2010 Nokia Corporation
* Contact : Felipe Balbi < felipe . balbi @ nokia . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA
* 02110 - 1301 USA
*
* THIS SOFTWARE IS PROVIDED " AS IS " AND ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN
* NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF
* USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
*/
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/debugfs.h>
# include <linux/seq_file.h>
# include <asm/uaccess.h>
# include "musb_core.h"
# include "musb_debug.h"
struct musb_register_map {
char * name ;
unsigned offset ;
unsigned size ;
} ;
static const struct musb_register_map musb_regmap [ ] = {
{ " FAddr " , 0x00 , 8 } ,
{ " Power " , 0x01 , 8 } ,
{ " Frame " , 0x0c , 16 } ,
{ " Index " , 0x0e , 8 } ,
{ " Testmode " , 0x0f , 8 } ,
{ " TxMaxPp " , 0x10 , 16 } ,
{ " TxCSRp " , 0x12 , 16 } ,
{ " RxMaxPp " , 0x14 , 16 } ,
{ " RxCSR " , 0x16 , 16 } ,
{ " RxCount " , 0x18 , 16 } ,
{ " ConfigData " , 0x1f , 8 } ,
{ " DevCtl " , 0x60 , 8 } ,
{ " MISC " , 0x61 , 8 } ,
{ " TxFIFOsz " , 0x62 , 8 } ,
{ " RxFIFOsz " , 0x63 , 8 } ,
{ " TxFIFOadd " , 0x64 , 16 } ,
{ " RxFIFOadd " , 0x66 , 16 } ,
{ " VControl " , 0x68 , 32 } ,
{ " HWVers " , 0x6C , 16 } ,
{ " EPInfo " , 0x78 , 8 } ,
{ " RAMInfo " , 0x79 , 8 } ,
{ " LinkInfo " , 0x7A , 8 } ,
{ " VPLen " , 0x7B , 8 } ,
{ " HS_EOF1 " , 0x7C , 8 } ,
{ " FS_EOF1 " , 0x7D , 8 } ,
{ " LS_EOF1 " , 0x7E , 8 } ,
{ " SOFT_RST " , 0x7F , 8 } ,
{ " DMA_CNTLch0 " , 0x204 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch0 " , 0x208 , 32 } ,
{ " DMA_COUNTch0 " , 0x20C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch1 " , 0x214 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch1 " , 0x218 , 32 } ,
{ " DMA_COUNTch1 " , 0x21C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch2 " , 0x224 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch2 " , 0x228 , 32 } ,
{ " DMA_COUNTch2 " , 0x22C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch3 " , 0x234 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch3 " , 0x238 , 32 } ,
{ " DMA_COUNTch3 " , 0x23C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch4 " , 0x244 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch4 " , 0x248 , 32 } ,
{ " DMA_COUNTch4 " , 0x24C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch5 " , 0x254 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch5 " , 0x258 , 32 } ,
{ " DMA_COUNTch5 " , 0x25C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch6 " , 0x264 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch6 " , 0x268 , 32 } ,
{ " DMA_COUNTch6 " , 0x26C , 32 } ,
2010-03-12 11:29:11 +03:00
{ " DMA_CNTLch7 " , 0x274 , 16 } ,
2010-07-08 12:32:59 +04:00
{ " DMA_ADDRch7 " , 0x278 , 32 } ,
{ " DMA_COUNTch7 " , 0x27C , 32 } ,
2010-03-12 11:29:11 +03:00
{ } /* Terminating Entry */
} ;
static int musb_regdump_show ( struct seq_file * s , void * unused )
{
struct musb * musb = s - > private ;
unsigned i ;
seq_printf ( s , " MUSB (M)HDRC Register Dump \n " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( musb_regmap ) ; i + + ) {
switch ( musb_regmap [ i ] . size ) {
case 8 :
seq_printf ( s , " %-12s: %02x \n " , musb_regmap [ i ] . name ,
musb_readb ( musb - > mregs , musb_regmap [ i ] . offset ) ) ;
break ;
case 16 :
seq_printf ( s , " %-12s: %04x \n " , musb_regmap [ i ] . name ,
musb_readw ( musb - > mregs , musb_regmap [ i ] . offset ) ) ;
break ;
case 32 :
seq_printf ( s , " %-12s: %08x \n " , musb_regmap [ i ] . name ,
musb_readl ( musb - > mregs , musb_regmap [ i ] . offset ) ) ;
break ;
}
}
return 0 ;
}
static int musb_regdump_open ( struct inode * inode , struct file * file )
{
return single_open ( file , musb_regdump_show , inode - > i_private ) ;
}
static int musb_test_mode_show ( struct seq_file * s , void * unused )
{
struct musb * musb = s - > private ;
unsigned test ;
test = musb_readb ( musb - > mregs , MUSB_TESTMODE ) ;
if ( test & MUSB_TEST_FORCE_HOST )
seq_printf ( s , " force host \n " ) ;
if ( test & MUSB_TEST_FIFO_ACCESS )
seq_printf ( s , " fifo access \n " ) ;
if ( test & MUSB_TEST_FORCE_FS )
seq_printf ( s , " force full-speed \n " ) ;
if ( test & MUSB_TEST_FORCE_HS )
seq_printf ( s , " force high-speed \n " ) ;
if ( test & MUSB_TEST_PACKET )
seq_printf ( s , " test packet \n " ) ;
if ( test & MUSB_TEST_K )
seq_printf ( s , " test K \n " ) ;
if ( test & MUSB_TEST_J )
seq_printf ( s , " test J \n " ) ;
if ( test & MUSB_TEST_SE0_NAK )
seq_printf ( s , " test SE0 NAK \n " ) ;
return 0 ;
}
static const struct file_operations musb_regdump_fops = {
. open = musb_regdump_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
static int musb_test_mode_open ( struct inode * inode , struct file * file )
{
return single_open ( file , musb_test_mode_show , inode - > i_private ) ;
}
static ssize_t musb_test_mode_write ( struct file * file ,
const char __user * ubuf , size_t count , loff_t * ppos )
{
2010-09-06 14:52:01 +04:00
struct seq_file * s = file - > private_data ;
struct musb * musb = s - > private ;
2010-03-12 11:29:11 +03:00
u8 test = 0 ;
char buf [ 18 ] ;
memset ( buf , 0x00 , sizeof ( buf ) ) ;
if ( copy_from_user ( & buf , ubuf , min_t ( size_t , sizeof ( buf ) - 1 , count ) ) )
return - EFAULT ;
if ( ! strncmp ( buf , " force host " , 9 ) )
test = MUSB_TEST_FORCE_HOST ;
if ( ! strncmp ( buf , " fifo access " , 11 ) )
test = MUSB_TEST_FIFO_ACCESS ;
if ( ! strncmp ( buf , " force full-speed " , 15 ) )
test = MUSB_TEST_FORCE_FS ;
if ( ! strncmp ( buf , " force high-speed " , 15 ) )
test = MUSB_TEST_FORCE_HS ;
if ( ! strncmp ( buf , " test packet " , 10 ) ) {
test = MUSB_TEST_PACKET ;
musb_load_testpacket ( musb ) ;
}
if ( ! strncmp ( buf , " test K " , 6 ) )
test = MUSB_TEST_K ;
if ( ! strncmp ( buf , " test J " , 6 ) )
test = MUSB_TEST_J ;
if ( ! strncmp ( buf , " test SE0 NAK " , 12 ) )
test = MUSB_TEST_SE0_NAK ;
musb_writeb ( musb - > mregs , MUSB_TESTMODE , test ) ;
return count ;
}
static const struct file_operations musb_test_mode_fops = {
. open = musb_test_mode_open ,
. write = musb_test_mode_write ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = single_release ,
} ;
2012-11-19 22:21:48 +04:00
int musb_init_debugfs ( struct musb * musb )
2010-03-12 11:29:11 +03:00
{
struct dentry * root ;
struct dentry * file ;
int ret ;
2012-08-31 15:09:50 +04:00
root = debugfs_create_dir ( dev_name ( musb - > controller ) , NULL ) ;
2012-01-31 16:19:00 +04:00
if ( ! root ) {
ret = - ENOMEM ;
2010-03-12 11:29:11 +03:00
goto err0 ;
}
file = debugfs_create_file ( " regdump " , S_IRUGO , root , musb ,
& musb_regdump_fops ) ;
2012-01-31 16:19:00 +04:00
if ( ! file ) {
ret = - ENOMEM ;
2010-03-12 11:29:11 +03:00
goto err1 ;
}
file = debugfs_create_file ( " testmode " , S_IRUGO | S_IWUSR ,
root , musb , & musb_test_mode_fops ) ;
2012-01-31 16:19:00 +04:00
if ( ! file ) {
ret = - ENOMEM ;
2010-03-12 11:29:11 +03:00
goto err1 ;
}
2012-08-31 15:09:50 +04:00
musb - > debugfs_root = root ;
2010-03-12 11:29:11 +03:00
return 0 ;
err1 :
debugfs_remove_recursive ( root ) ;
err0 :
return ret ;
}
2010-03-25 14:25:18 +03:00
void /* __init_or_exit */ musb_exit_debugfs ( struct musb * musb )
2010-03-12 11:29:11 +03:00
{
2012-08-31 15:09:50 +04:00
debugfs_remove_recursive ( musb - > debugfs_root ) ;
2010-03-12 11:29:11 +03:00
}