2008-11-07 17:15:42 +03:00
/*
2010-03-01 17:41:59 +03:00
* Driver for GE FPGA based GPIO
2008-11-07 17:15:42 +03:00
*
2010-03-01 17:41:59 +03:00
* Author : Martyn Welch < martyn . welch @ ge . com >
2008-11-07 17:15:42 +03:00
*
2010-03-01 17:41:59 +03:00
* 2008 ( c ) GE Intelligent Platforms Embedded Systems , Inc .
2008-11-07 17:15:42 +03:00
*
* 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 .
*/
/* TODO
*
* Configuration of output modes ( totem - pole / open - drain )
* Interrupt configuration - interrupts are always generated the FPGA relies on
2012-03-12 21:12:58 +04:00
* the I / O interrupt controllers mask to stop them propergating
2008-11-07 17:15:42 +03:00
*/
# include <linux/kernel.h>
# include <linux/io.h>
2015-01-19 08:22:06 +03:00
# include <linux/slab.h>
2008-11-07 17:15:42 +03:00
# include <linux/of_device.h>
# include <linux/of_gpio.h>
2014-12-01 15:09:37 +03:00
# include <linux/of_address.h>
2011-05-27 21:23:32 +04:00
# include <linux/module.h>
2014-12-01 15:09:37 +03:00
# include <linux/basic_mmio_gpio.h>
2008-11-07 17:15:42 +03:00
# define GEF_GPIO_DIRECT 0x00
# define GEF_GPIO_IN 0x04
# define GEF_GPIO_OUT 0x08
# define GEF_GPIO_TRIG 0x0C
# define GEF_GPIO_POLAR_A 0x10
# define GEF_GPIO_POLAR_B 0x14
# define GEF_GPIO_INT_STAT 0x18
# define GEF_GPIO_OVERRUN 0x1C
# define GEF_GPIO_MODE 0x20
2014-04-12 09:41:31 +04:00
static const struct of_device_id gef_gpio_ids [ ] = {
{
. compatible = " gef,sbc610-gpio " ,
. data = ( void * ) 19 ,
} , {
. compatible = " gef,sbc310-gpio " ,
. data = ( void * ) 6 ,
} , {
. compatible = " ge,imp3a-gpio " ,
. data = ( void * ) 16 ,
} ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , gef_gpio_ids ) ;
2008-11-07 17:15:42 +03:00
2014-04-12 09:41:31 +04:00
static int __init gef_gpio_probe ( struct platform_device * pdev )
2008-11-07 17:15:42 +03:00
{
2014-04-12 09:41:31 +04:00
const struct of_device_id * of_id =
of_match_device ( gef_gpio_ids , & pdev - > dev ) ;
2014-12-01 15:09:37 +03:00
struct bgpio_chip * bgc ;
void __iomem * regs ;
int ret ;
2014-04-12 09:41:31 +04:00
2014-12-01 15:09:37 +03:00
bgc = devm_kzalloc ( & pdev - > dev , sizeof ( * bgc ) , GFP_KERNEL ) ;
if ( ! bgc )
2014-04-12 09:41:31 +04:00
return - ENOMEM ;
2014-12-01 15:09:37 +03:00
regs = of_iomap ( pdev - > dev . of_node , 0 ) ;
if ( ! regs )
return - ENOMEM ;
ret = bgpio_init ( bgc , & pdev - > dev , 4 , regs + GEF_GPIO_IN ,
regs + GEF_GPIO_OUT , NULL , NULL ,
regs + GEF_GPIO_DIRECT , BGPIOF_BIG_ENDIAN_BYTE_ORDER ) ;
if ( ret ) {
dev_err ( & pdev - > dev , " bgpio_init failed \n " ) ;
goto err0 ;
}
2014-04-12 09:41:31 +04:00
/* Setup pointers to chip functions */
2015-01-21 04:50:06 +03:00
bgc - > gc . label = devm_kstrdup ( & pdev - > dev , pdev - > dev . of_node - > full_name ,
GFP_KERNEL ) ;
if ( ! bgc - > gc . label ) {
ret = - ENOMEM ;
2014-12-01 15:09:37 +03:00
goto err0 ;
2015-01-21 04:50:06 +03:00
}
2014-12-01 15:09:37 +03:00
bgc - > gc . base = - 1 ;
bgc - > gc . ngpio = ( u16 ) ( uintptr_t ) of_id - > data ;
bgc - > gc . of_gpio_n_cells = 2 ;
bgc - > gc . of_node = pdev - > dev . of_node ;
2014-04-12 09:41:31 +04:00
/* This function adds a memory mapped GPIO chip */
2014-12-01 15:09:37 +03:00
ret = gpiochip_add ( & bgc - > gc ) ;
if ( ret )
2015-01-21 04:50:06 +03:00
goto err0 ;
2014-12-01 15:09:37 +03:00
return 0 ;
err0 :
iounmap ( regs ) ;
pr_err ( " %s: GPIO chip registration failed \n " ,
pdev - > dev . of_node - > full_name ) ;
return ret ;
2014-04-12 09:41:31 +04:00
} ;
2012-03-12 21:13:00 +04:00
2014-04-12 09:41:31 +04:00
static struct platform_driver gef_gpio_driver = {
. driver = {
. name = " gef-gpio " ,
. of_match_table = gef_gpio_ids ,
} ,
2008-11-07 17:15:42 +03:00
} ;
2014-04-12 09:41:31 +04:00
module_platform_driver_probe ( gef_gpio_driver , gef_gpio_probe ) ;
2008-11-07 17:15:42 +03:00
2010-03-01 17:41:59 +03:00
MODULE_DESCRIPTION ( " GE I/O FPGA GPIO driver " ) ;
MODULE_AUTHOR ( " Martyn Welch <martyn.welch@ge.com " ) ;
2008-11-07 17:15:42 +03:00
MODULE_LICENSE ( " GPL " ) ;