2012-10-09 20:05:56 +04:00
/*
* CLPS711X GPIO driver
*
2013-04-26 19:47:28 +04:00
* Copyright ( C ) 2012 , 2013 Alexander Shiyan < shc_work @ mail . ru >
2012-10-09 20:05:56 +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 .
*/
2013-04-26 19:47:28 +04:00
# include <linux/err.h>
2012-10-09 20:05:56 +04:00
# include <linux/gpio.h>
# include <linux/module.h>
2013-04-26 19:47:28 +04:00
# include <linux/basic_mmio_gpio.h>
2012-10-09 20:05:56 +04:00
# include <linux/platform_device.h>
2013-04-26 19:47:28 +04:00
static int clps711x_gpio_probe ( struct platform_device * pdev )
2012-10-09 20:05:56 +04:00
{
2013-04-26 19:47:30 +04:00
struct device_node * np = pdev - > dev . of_node ;
2013-04-26 19:47:28 +04:00
void __iomem * dat , * dir ;
struct bgpio_chip * bgc ;
struct resource * res ;
2013-04-26 19:47:30 +04:00
int err , id = np ? of_alias_get_id ( np , " gpio " ) : pdev - > id ;
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
if ( ( id < 0 ) | | ( id > 4 ) )
return - ENODEV ;
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
bgc = devm_kzalloc ( & pdev - > dev , sizeof ( * bgc ) , GFP_KERNEL ) ;
if ( ! bgc )
return - ENOMEM ;
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
dat = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( dat ) )
return PTR_ERR ( dat ) ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 1 ) ;
dir = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( dir ) )
return PTR_ERR ( dir ) ;
switch ( id ) {
case 3 :
/* PORTD is inverted logic for direction register */
err = bgpio_init ( bgc , & pdev - > dev , 1 , dat , NULL , NULL ,
NULL , dir , 0 ) ;
break ;
default :
err = bgpio_init ( bgc , & pdev - > dev , 1 , dat , NULL , NULL ,
dir , NULL , 0 ) ;
break ;
}
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
if ( err )
return err ;
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
switch ( id ) {
case 4 :
/* PORTE is 3 lines only */
bgc - > gc . ngpio = 3 ;
break ;
default :
break ;
}
2012-10-24 12:34:46 +04:00
2013-04-26 19:47:28 +04:00
bgc - > gc . base = id * 8 ;
2014-02-04 18:25:27 +04:00
bgc - > gc . owner = THIS_MODULE ;
2013-04-26 19:47:28 +04:00
platform_set_drvdata ( pdev , bgc ) ;
2012-10-24 12:34:46 +04:00
2013-04-26 19:47:28 +04:00
return gpiochip_add ( & bgc - > gc ) ;
2012-10-24 12:34:46 +04:00
}
2013-04-26 19:47:28 +04:00
static int clps711x_gpio_remove ( struct platform_device * pdev )
2012-10-24 12:34:46 +04:00
{
2013-04-26 19:47:28 +04:00
struct bgpio_chip * bgc = platform_get_drvdata ( pdev ) ;
2012-10-24 12:34:46 +04:00
2013-04-26 19:47:28 +04:00
return bgpio_remove ( bgc ) ;
2012-10-24 12:34:46 +04:00
}
2013-12-24 18:08:53 +04:00
static const struct of_device_id __maybe_unused clps711x_gpio_ids [ ] = {
2013-04-26 19:47:30 +04:00
{ . compatible = " cirrus,clps711x-gpio " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , clps711x_gpio_ids ) ;
2013-04-26 19:47:28 +04:00
static struct platform_driver clps711x_gpio_driver = {
. driver = {
2013-04-26 19:47:30 +04:00
. name = " clps711x-gpio " ,
2013-12-24 18:08:53 +04:00
. of_match_table = of_match_ptr ( clps711x_gpio_ids ) ,
2013-04-26 19:47:28 +04:00
} ,
. probe = clps711x_gpio_probe ,
. remove = clps711x_gpio_remove ,
2012-10-09 20:05:56 +04:00
} ;
2013-04-26 19:47:28 +04:00
module_platform_driver ( clps711x_gpio_driver ) ;
2012-10-09 20:05:56 +04:00
2013-04-26 19:47:28 +04:00
MODULE_LICENSE ( " GPL " ) ;
2012-10-09 20:05:56 +04:00
MODULE_AUTHOR ( " Alexander Shiyan <shc_work@mail.ru> " ) ;
MODULE_DESCRIPTION ( " CLPS711X GPIO driver " ) ;
2014-02-04 13:39:15 +04:00
MODULE_ALIAS ( " platform:clps711x-gpio " ) ;