2006-09-19 02:23:07 +04:00
/*
* arch / arm / plat - iop / gpio . c
* GPIO handling for Intel IOP3xx processors .
*
* Copyright ( C ) 2006 Lennert Buytenhek < buytenh @ wantstofly . org >
*
* 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 .
*/
# include <linux/device.h>
2008-07-09 02:07:48 +04:00
# include <linux/init.h>
# include <linux/types.h>
# include <linux/errno.h>
# include <linux/gpio.h>
2011-08-01 00:17:29 +04:00
# include <linux/export.h>
2013-09-09 18:39:51 +04:00
# include <linux/platform_device.h>
2013-09-09 18:54:32 +04:00
# include <linux/bitops.h>
# include <linux/io.h>
2013-09-09 17:00:40 +04:00
# define IOP3XX_N_GPIOS 8
2006-09-19 02:23:07 +04:00
2013-09-09 18:39:51 +04:00
# define GPIO_IN 0
# define GPIO_OUT 1
# define GPIO_LOW 0
# define GPIO_HIGH 1
/* Memory base offset */
static void __iomem * base ;
# define IOP3XX_GPIO_REG(reg) (base + (reg))
2013-09-09 18:54:32 +04:00
# define IOP3XX_GPOE IOP3XX_GPIO_REG(0x0000)
# define IOP3XX_GPID IOP3XX_GPIO_REG(0x0004)
# define IOP3XX_GPOD IOP3XX_GPIO_REG(0x0008)
2013-09-09 18:39:51 +04:00
2013-09-09 18:07:42 +04:00
static void gpio_line_config ( int line , int direction )
2006-09-19 02:23:07 +04:00
{
unsigned long flags ;
2013-09-09 18:54:32 +04:00
u32 val ;
2006-09-19 02:23:07 +04:00
local_irq_save ( flags ) ;
2013-09-09 18:54:32 +04:00
val = readl ( IOP3XX_GPOE ) ;
2006-09-19 02:23:07 +04:00
if ( direction = = GPIO_IN ) {
2013-09-09 18:54:32 +04:00
val | = BIT ( line ) ;
2006-09-19 02:23:07 +04:00
} else if ( direction = = GPIO_OUT ) {
2013-09-09 18:54:32 +04:00
val & = ~ BIT ( line ) ;
2006-09-19 02:23:07 +04:00
}
2013-09-09 18:54:32 +04:00
writel ( val , IOP3XX_GPOE ) ;
2006-09-19 02:23:07 +04:00
local_irq_restore ( flags ) ;
}
2013-09-09 18:07:42 +04:00
static int gpio_line_get ( int line )
2006-09-19 02:23:07 +04:00
{
2013-09-09 18:54:32 +04:00
return ! ! ( readl ( IOP3XX_GPID ) & BIT ( line ) ) ;
2006-09-19 02:23:07 +04:00
}
2013-09-09 18:07:42 +04:00
static void gpio_line_set ( int line , int value )
2006-09-19 02:23:07 +04:00
{
unsigned long flags ;
2013-09-09 18:54:32 +04:00
u32 val ;
2006-09-19 02:23:07 +04:00
local_irq_save ( flags ) ;
2013-09-09 18:54:32 +04:00
val = readl ( IOP3XX_GPOD ) ;
2006-09-19 02:23:07 +04:00
if ( value = = GPIO_LOW ) {
2013-09-09 18:54:32 +04:00
val & = ~ BIT ( line ) ;
2006-09-19 02:23:07 +04:00
} else if ( value = = GPIO_HIGH ) {
2013-09-09 18:54:32 +04:00
val | = BIT ( line ) ;
2006-09-19 02:23:07 +04:00
}
2013-09-09 18:54:32 +04:00
writel ( val , IOP3XX_GPOD ) ;
2006-09-19 02:23:07 +04:00
local_irq_restore ( flags ) ;
}
2008-07-09 02:07:48 +04:00
static int iop3xx_gpio_direction_input ( struct gpio_chip * chip , unsigned gpio )
{
gpio_line_config ( gpio , GPIO_IN ) ;
return 0 ;
}
static int iop3xx_gpio_direction_output ( struct gpio_chip * chip , unsigned gpio , int level )
{
gpio_line_set ( gpio , level ) ;
gpio_line_config ( gpio , GPIO_OUT ) ;
return 0 ;
}
static int iop3xx_gpio_get_value ( struct gpio_chip * chip , unsigned gpio )
{
return gpio_line_get ( gpio ) ;
}
static void iop3xx_gpio_set_value ( struct gpio_chip * chip , unsigned gpio , int value )
{
gpio_line_set ( gpio , value ) ;
}
static struct gpio_chip iop3xx_chip = {
. label = " iop3xx " ,
. direction_input = iop3xx_gpio_direction_input ,
. get = iop3xx_gpio_get_value ,
. direction_output = iop3xx_gpio_direction_output ,
. set = iop3xx_gpio_set_value ,
. base = 0 ,
. ngpio = IOP3XX_N_GPIOS ,
} ;
2013-09-09 18:39:51 +04:00
static int iop3xx_gpio_probe ( struct platform_device * pdev )
2008-07-09 02:07:48 +04:00
{
2013-09-09 18:39:51 +04:00
struct resource * res ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2013-09-09 18:59:54 +04:00
base = devm_ioremap_resource ( & pdev - > dev , res ) ;
2014-03-18 13:58:33 +04:00
if ( IS_ERR ( base ) )
return PTR_ERR ( base ) ;
2013-09-09 18:39:51 +04:00
2008-07-09 02:07:48 +04:00
return gpiochip_add ( & iop3xx_chip ) ;
}
2013-09-09 18:39:51 +04:00
static struct platform_driver iop3xx_gpio_driver = {
. driver = {
. name = " gpio-iop " ,
} ,
. probe = iop3xx_gpio_probe ,
} ;
static int __init iop3xx_gpio_init ( void )
{
return platform_driver_register ( & iop3xx_gpio_driver ) ;
}
arch_initcall ( iop3xx_gpio_init ) ;