2008-09-29 14:07:14 -07:00
/* arch/arm/mach-msm/vreg.c
*
* Copyright ( C ) 2008 Google , Inc .
2008-12-12 19:33:55 -05:00
* Copyright ( c ) 2009 , Code Aurora Forum . All rights reserved .
2008-09-29 14:07:14 -07:00
* Author : Brian Swetland < swetland @ google . com >
*
* This software is licensed under the terms of the GNU General Public
* License version 2 , as published by the Free Software Foundation , and
* may be copied , distributed , and modified under those terms .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
*/
# include <linux/kernel.h>
# include <linux/device.h>
# include <linux/init.h>
# include <linux/debugfs.h>
2009-06-29 14:13:04 -05:00
# include <linux/string.h>
2008-09-29 14:07:14 -07:00
# include <mach/vreg.h>
# include "proc_comm.h"
struct vreg {
const char * name ;
unsigned id ;
2008-12-12 19:33:55 -05:00
int status ;
2009-06-29 14:13:04 -05:00
unsigned refcnt ;
2008-09-29 14:07:14 -07:00
} ;
2009-06-29 14:13:04 -05:00
# define VREG(_name, _id, _status, _refcnt) \
{ . name = _name , . id = _id , . status = _status , . refcnt = _refcnt }
2008-09-29 14:07:14 -07:00
static struct vreg vregs [ ] = {
2009-06-29 14:13:04 -05:00
VREG ( " msma " , 0 , 0 , 0 ) ,
VREG ( " msmp " , 1 , 0 , 0 ) ,
VREG ( " msme1 " , 2 , 0 , 0 ) ,
VREG ( " msmc1 " , 3 , 0 , 0 ) ,
VREG ( " msmc2 " , 4 , 0 , 0 ) ,
VREG ( " gp3 " , 5 , 0 , 0 ) ,
VREG ( " msme2 " , 6 , 0 , 0 ) ,
VREG ( " gp4 " , 7 , 0 , 0 ) ,
VREG ( " gp1 " , 8 , 0 , 0 ) ,
VREG ( " tcxo " , 9 , 0 , 0 ) ,
VREG ( " pa " , 10 , 0 , 0 ) ,
VREG ( " rftx " , 11 , 0 , 0 ) ,
VREG ( " rfrx1 " , 12 , 0 , 0 ) ,
VREG ( " rfrx2 " , 13 , 0 , 0 ) ,
VREG ( " synt " , 14 , 0 , 0 ) ,
VREG ( " wlan " , 15 , 0 , 0 ) ,
VREG ( " usb " , 16 , 0 , 0 ) ,
VREG ( " boost " , 17 , 0 , 0 ) ,
VREG ( " mmc " , 18 , 0 , 0 ) ,
VREG ( " ruim " , 19 , 0 , 0 ) ,
VREG ( " msmc0 " , 20 , 0 , 0 ) ,
VREG ( " gp2 " , 21 , 0 , 0 ) ,
VREG ( " gp5 " , 22 , 0 , 0 ) ,
VREG ( " gp6 " , 23 , 0 , 0 ) ,
VREG ( " rf " , 24 , 0 , 0 ) ,
VREG ( " rf_vco " , 26 , 0 , 0 ) ,
VREG ( " mpll " , 27 , 0 , 0 ) ,
VREG ( " s2 " , 28 , 0 , 0 ) ,
VREG ( " s3 " , 29 , 0 , 0 ) ,
VREG ( " rfubm " , 30 , 0 , 0 ) ,
VREG ( " ncp " , 31 , 0 , 0 ) ,
2009-07-24 17:21:21 -07:00
VREG ( " gp7 " , 32 , 0 , 0 ) ,
VREG ( " gp8 " , 33 , 0 , 0 ) ,
VREG ( " gp9 " , 34 , 0 , 0 ) ,
VREG ( " gp10 " , 35 , 0 , 0 ) ,
VREG ( " gp11 " , 36 , 0 , 0 ) ,
VREG ( " gp12 " , 37 , 0 , 0 ) ,
VREG ( " gp13 " , 38 , 0 , 0 ) ,
VREG ( " gp14 " , 39 , 0 , 0 ) ,
VREG ( " gp15 " , 40 , 0 , 0 ) ,
VREG ( " gp16 " , 41 , 0 , 0 ) ,
VREG ( " gp17 " , 42 , 0 , 0 ) ,
VREG ( " s4 " , 43 , 0 , 0 ) ,
VREG ( " usb2 " , 44 , 0 , 0 ) ,
VREG ( " wlan2 " , 45 , 0 , 0 ) ,
VREG ( " xo_out " , 46 , 0 , 0 ) ,
VREG ( " lvsw0 " , 47 , 0 , 0 ) ,
VREG ( " lvsw1 " , 48 , 0 , 0 ) ,
2008-09-29 14:07:14 -07:00
} ;
struct vreg * vreg_get ( struct device * dev , const char * id )
{
int n ;
for ( n = 0 ; n < ARRAY_SIZE ( vregs ) ; n + + ) {
if ( ! strcmp ( vregs [ n ] . name , id ) )
return vregs + n ;
}
2010-03-04 12:38:05 -08:00
return ERR_PTR ( - ENOENT ) ;
2008-09-29 14:07:14 -07:00
}
void vreg_put ( struct vreg * vreg )
{
}
int vreg_enable ( struct vreg * vreg )
{
unsigned id = vreg - > id ;
unsigned enable = 1 ;
2008-12-12 19:33:55 -05:00
2009-06-29 14:13:04 -05:00
if ( vreg - > refcnt = = 0 )
vreg - > status = msm_proc_comm ( PCOM_VREG_SWITCH , & id , & enable ) ;
if ( ( vreg - > refcnt < UINT_MAX ) & & ( ! vreg - > status ) )
vreg - > refcnt + + ;
2008-12-12 19:33:55 -05:00
return vreg - > status ;
2008-09-29 14:07:14 -07:00
}
2008-12-12 19:33:55 -05:00
int vreg_disable ( struct vreg * vreg )
2008-09-29 14:07:14 -07:00
{
unsigned id = vreg - > id ;
unsigned enable = 0 ;
2008-12-12 19:33:55 -05:00
2009-06-29 14:13:04 -05:00
if ( ! vreg - > refcnt )
return 0 ;
if ( vreg - > refcnt = = 1 )
vreg - > status = msm_proc_comm ( PCOM_VREG_SWITCH , & id , & enable ) ;
if ( ! vreg - > status )
vreg - > refcnt - - ;
2008-12-12 19:33:55 -05:00
return vreg - > status ;
2008-09-29 14:07:14 -07:00
}
int vreg_set_level ( struct vreg * vreg , unsigned mv )
{
unsigned id = vreg - > id ;
2008-12-12 19:33:55 -05:00
vreg - > status = msm_proc_comm ( PCOM_VREG_SET_LEVEL , & id , & mv ) ;
return vreg - > status ;
2008-09-29 14:07:14 -07:00
}
# if defined(CONFIG_DEBUG_FS)
static int vreg_debug_set ( void * data , u64 val )
{
struct vreg * vreg = data ;
switch ( val ) {
case 0 :
vreg_disable ( vreg ) ;
break ;
case 1 :
vreg_enable ( vreg ) ;
break ;
default :
vreg_set_level ( vreg , val ) ;
break ;
}
return 0 ;
}
static int vreg_debug_get ( void * data , u64 * val )
{
2008-12-12 19:33:55 -05:00
struct vreg * vreg = data ;
if ( ! vreg - > status )
* val = 0 ;
else
* val = 1 ;
return 0 ;
2008-09-29 14:07:14 -07:00
}
2009-06-29 14:13:04 -05:00
static int vreg_debug_count_set ( void * data , u64 val )
{
struct vreg * vreg = data ;
if ( val > UINT_MAX )
val = UINT_MAX ;
vreg - > refcnt = val ;
return 0 ;
}
static int vreg_debug_count_get ( void * data , u64 * val )
{
struct vreg * vreg = data ;
* val = vreg - > refcnt ;
return 0 ;
}
2008-09-29 14:07:14 -07:00
DEFINE_SIMPLE_ATTRIBUTE ( vreg_fops , vreg_debug_get , vreg_debug_set , " %llu \n " ) ;
2009-06-29 14:13:04 -05:00
DEFINE_SIMPLE_ATTRIBUTE ( vreg_count_fops , vreg_debug_count_get ,
vreg_debug_count_set , " %llu \n " ) ;
2008-09-29 14:07:14 -07:00
static int __init vreg_debug_init ( void )
{
struct dentry * dent ;
int n ;
2009-06-29 14:13:04 -05:00
char name [ 32 ] ;
const char * refcnt_name = " _refcnt " ;
2008-09-29 14:07:14 -07:00
dent = debugfs_create_dir ( " vreg " , 0 ) ;
if ( IS_ERR ( dent ) )
return 0 ;
2009-06-29 14:13:04 -05:00
for ( n = 0 ; n < ARRAY_SIZE ( vregs ) ; n + + ) {
2008-09-29 14:07:14 -07:00
( void ) debugfs_create_file ( vregs [ n ] . name , 0644 ,
dent , vregs + n , & vreg_fops ) ;
2009-06-29 14:13:04 -05:00
strlcpy ( name , vregs [ n ] . name , sizeof ( name ) ) ;
strlcat ( name , refcnt_name , sizeof ( name ) ) ;
( void ) debugfs_create_file ( name , 0644 ,
dent , vregs + n , & vreg_count_fops ) ;
}
2008-09-29 14:07:14 -07:00
return 0 ;
}
device_initcall ( vreg_debug_init ) ;
# endif