2011-05-15 15:32:52 +04:00
/*
* arch / arm / plat - orion / mpp . c
*
* MPP functions for Marvell orion SoCs
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed " as is " without any
* warranty of any kind , whether express or implied .
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/mbus.h>
# include <linux/io.h>
# include <linux/gpio.h>
# include <mach/hardware.h>
2012-08-29 19:16:55 +04:00
# include <plat/orion-gpio.h>
2011-05-15 15:32:52 +04:00
# include <plat/mpp.h>
/* Address of the ith MPP control register */
2012-09-11 16:27:24 +04:00
static __init void __iomem * mpp_ctrl_addr ( unsigned int i ,
void __iomem * dev_bus )
2011-05-15 15:32:52 +04:00
{
return dev_bus + ( i ) * 4 ;
}
void __init orion_mpp_conf ( unsigned int * mpp_list , unsigned int variant_mask ,
2012-09-11 16:27:24 +04:00
unsigned int mpp_max , void __iomem * dev_bus )
2011-05-15 15:32:52 +04:00
{
unsigned int mpp_nr_regs = ( 1 + mpp_max / 8 ) ;
u32 mpp_ctrl [ mpp_nr_regs ] ;
int i ;
printk ( KERN_DEBUG " initial MPP regs: " ) ;
for ( i = 0 ; i < mpp_nr_regs ; i + + ) {
mpp_ctrl [ i ] = readl ( mpp_ctrl_addr ( i , dev_bus ) ) ;
printk ( " %08x " , mpp_ctrl [ i ] ) ;
}
printk ( " \n " ) ;
for ( ; * mpp_list ; mpp_list + + ) {
unsigned int num = MPP_NUM ( * mpp_list ) ;
unsigned int sel = MPP_SEL ( * mpp_list ) ;
int shift , gpio_mode ;
if ( num > mpp_max ) {
printk ( KERN_ERR " orion_mpp_conf: invalid MPP "
" number (%u) \n " , num ) ;
continue ;
}
2013-01-23 17:50:59 +04:00
if ( variant_mask & & ! ( * mpp_list & variant_mask ) ) {
2011-05-15 15:32:52 +04:00
printk ( KERN_WARNING
" orion_mpp_conf: requested MPP%u config "
" unavailable on this hardware \n " , num ) ;
continue ;
}
shift = ( num & 7 ) < < 2 ;
mpp_ctrl [ num / 8 ] & = ~ ( 0xf < < shift ) ;
mpp_ctrl [ num / 8 ] | = sel < < shift ;
gpio_mode = 0 ;
if ( * mpp_list & MPP_INPUT_MASK )
gpio_mode | = GPIO_INPUT_OK ;
if ( * mpp_list & MPP_OUTPUT_MASK )
gpio_mode | = GPIO_OUTPUT_OK ;
2012-02-08 18:52:07 +04:00
2011-05-15 15:32:52 +04:00
orion_gpio_set_valid ( num , gpio_mode ) ;
}
printk ( KERN_DEBUG " final MPP regs: " ) ;
for ( i = 0 ; i < mpp_nr_regs ; i + + ) {
writel ( mpp_ctrl [ i ] , mpp_ctrl_addr ( i , dev_bus ) ) ;
printk ( " %08x " , mpp_ctrl [ i ] ) ;
}
printk ( " \n " ) ;
}