2008-07-05 12:02:55 +04:00
/*
2010-02-15 11:42:59 +03:00
* arch / arm / plat - mxc / iomux - v1 . c
2008-07-05 12:02:55 +04:00
*
2010-02-15 18:57:09 +03:00
* Copyright ( C ) 2004 Sascha Hauer , Synertronixx GmbH
* Copyright ( C ) 2009 Uwe Kleine - Koenig , Pengutronix
2008-07-05 12:02:55 +04:00
*
2010-02-15 11:42:59 +03:00
* Common code for i . MX1 , i . MX21 and i . MX27
2008-07-05 12:02:55 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2010-02-15 18:57:09 +03:00
* along with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2008-07-05 12:02:55 +04:00
*/
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/string.h>
# include <linux/gpio.h>
# include <asm/mach/map.h>
2012-09-13 09:26:00 +04:00
2012-09-14 10:14:45 +04:00
# include "hardware.h"
2012-09-13 09:26:00 +04:00
# include "iomux-v1.h"
2008-07-05 12:02:55 +04:00
2010-02-15 18:57:09 +03:00
static void __iomem * imx_iomuxv1_baseaddr ;
2010-02-15 11:47:55 +03:00
static unsigned imx_iomuxv1_numports ;
2010-02-15 18:57:09 +03:00
static inline unsigned long imx_iomuxv1_readl ( unsigned offset )
{
return __raw_readl ( imx_iomuxv1_baseaddr + offset ) ;
}
static inline void imx_iomuxv1_writel ( unsigned long val , unsigned offset )
{
__raw_writel ( val , imx_iomuxv1_baseaddr + offset ) ;
}
static inline void imx_iomuxv1_rmwl ( unsigned offset ,
unsigned long mask , unsigned long value )
{
unsigned long reg = imx_iomuxv1_readl ( offset ) ;
reg & = ~ mask ;
reg | = value ;
imx_iomuxv1_writel ( reg , offset ) ;
}
static inline void imx_iomuxv1_set_puen (
unsigned int port , unsigned int pin , int on )
{
unsigned long mask = 1 < < pin ;
imx_iomuxv1_rmwl ( MXC_PUEN ( port ) , mask , on ? mask : 0 ) ;
}
static inline void imx_iomuxv1_set_ddir (
unsigned int port , unsigned int pin , int out )
{
unsigned long mask = 1 < < pin ;
imx_iomuxv1_rmwl ( MXC_DDIR ( port ) , mask , out ? mask : 0 ) ;
}
static inline void imx_iomuxv1_set_gpr (
unsigned int port , unsigned int pin , int af )
{
unsigned long mask = 1 < < pin ;
imx_iomuxv1_rmwl ( MXC_GPR ( port ) , mask , af ? mask : 0 ) ;
}
static inline void imx_iomuxv1_set_gius (
unsigned int port , unsigned int pin , int inuse )
{
unsigned long mask = 1 < < pin ;
imx_iomuxv1_rmwl ( MXC_GIUS ( port ) , mask , inuse ? mask : 0 ) ;
}
static inline void imx_iomuxv1_set_ocr (
unsigned int port , unsigned int pin , unsigned int ocr )
{
unsigned long shift = ( pin & 0xf ) < < 1 ;
unsigned long mask = 3 < < shift ;
unsigned long value = ocr < < shift ;
unsigned long offset = pin < 16 ? MXC_OCR1 ( port ) : MXC_OCR2 ( port ) ;
imx_iomuxv1_rmwl ( offset , mask , value ) ;
}
static inline void imx_iomuxv1_set_iconfa (
unsigned int port , unsigned int pin , unsigned int aout )
{
unsigned long shift = ( pin & 0xf ) < < 1 ;
unsigned long mask = 3 < < shift ;
unsigned long value = aout < < shift ;
unsigned long offset = pin < 16 ? MXC_ICONFA1 ( port ) : MXC_ICONFA2 ( port ) ;
imx_iomuxv1_rmwl ( offset , mask , value ) ;
}
static inline void imx_iomuxv1_set_iconfb (
unsigned int port , unsigned int pin , unsigned int bout )
{
unsigned long shift = ( pin & 0xf ) < < 1 ;
unsigned long mask = 3 < < shift ;
unsigned long value = bout < < shift ;
unsigned long offset = pin < 16 ? MXC_ICONFB1 ( port ) : MXC_ICONFB2 ( port ) ;
imx_iomuxv1_rmwl ( offset , mask , value ) ;
}
2010-02-15 11:47:55 +03:00
int mxc_gpio_mode ( int gpio_mode )
2008-07-05 12:02:55 +04:00
{
unsigned int pin = gpio_mode & GPIO_PIN_MASK ;
unsigned int port = ( gpio_mode & GPIO_PORT_MASK ) > > GPIO_PORT_SHIFT ;
unsigned int ocr = ( gpio_mode & GPIO_OCR_MASK ) > > GPIO_OCR_SHIFT ;
2010-02-15 18:57:09 +03:00
unsigned int aout = ( gpio_mode > > GPIO_AOUT_SHIFT ) & 3 ;
unsigned int bout = ( gpio_mode > > GPIO_BOUT_SHIFT ) & 3 ;
2008-07-05 12:02:55 +04:00
2010-02-15 11:47:55 +03:00
if ( port > = imx_iomuxv1_numports )
return - EINVAL ;
2008-07-05 12:02:55 +04:00
/* Pullup enable */
2010-02-15 18:57:09 +03:00
imx_iomuxv1_set_puen ( port , pin , gpio_mode & GPIO_PUEN ) ;
2008-07-05 12:02:55 +04:00
/* Data direction */
2010-02-15 18:57:09 +03:00
imx_iomuxv1_set_ddir ( port , pin , gpio_mode & GPIO_OUT ) ;
2008-07-05 12:02:55 +04:00
/* Primary / alternate function */
2010-02-15 18:57:09 +03:00
imx_iomuxv1_set_gpr ( port , pin , gpio_mode & GPIO_AF ) ;
2008-07-05 12:02:55 +04:00
/* use as gpio? */
2010-02-15 18:57:09 +03:00
imx_iomuxv1_set_gius ( port , pin , ! ( gpio_mode & ( GPIO_PF | GPIO_AF ) ) ) ;
imx_iomuxv1_set_ocr ( port , pin , ocr ) ;
imx_iomuxv1_set_iconfa ( port , pin , aout ) ;
imx_iomuxv1_set_iconfb ( port , pin , bout ) ;
2010-02-15 11:47:55 +03:00
return 0 ;
2008-07-05 12:02:55 +04:00
}
EXPORT_SYMBOL ( mxc_gpio_mode ) ;
2010-02-15 11:47:55 +03:00
static int imx_iomuxv1_setup_multiple ( const int * list , unsigned count )
{
size_t i ;
2011-06-22 18:31:00 +04:00
int ret = 0 ;
2010-02-15 11:47:55 +03:00
for ( i = 0 ; i < count ; + + i ) {
ret = mxc_gpio_mode ( list [ i ] ) ;
if ( ret )
return ret ;
}
return ret ;
}
2008-07-05 12:02:55 +04:00
int mxc_gpio_setup_multiple_pins ( const int * pin_list , unsigned count ,
2008-11-04 18:48:46 +03:00
const char * label )
2008-07-05 12:02:55 +04:00
{
2010-02-15 11:47:55 +03:00
int ret ;
2008-07-05 12:02:55 +04:00
2010-02-15 11:47:55 +03:00
ret = imx_iomuxv1_setup_multiple ( pin_list , count ) ;
2008-11-04 18:48:46 +03:00
return ret ;
}
EXPORT_SYMBOL ( mxc_gpio_setup_multiple_pins ) ;
2008-07-05 12:02:55 +04:00
2011-02-17 17:08:12 +03:00
int __init imx_iomuxv1_init ( void __iomem * base , int numports )
2010-02-15 18:57:09 +03:00
{
2011-02-17 17:08:12 +03:00
imx_iomuxv1_baseaddr = base ;
imx_iomuxv1_numports = numports ;
2010-02-15 18:57:09 +03:00
return 0 ;
}