2013-11-29 12:11:34 +01:00
/*
* MOXA ART SoCs GPIO driver .
*
* Copyright ( C ) 2013 Jonas Jensen
*
* Jonas Jensen < jonas . jensen @ gmail . com >
*
* 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/err.h>
# include <linux/init.h>
# include <linux/irq.h>
# include <linux/io.h>
# include <linux/gpio.h>
# include <linux/platform_device.h>
# include <linux/module.h>
# include <linux/of_address.h>
# include <linux/of_gpio.h>
# include <linux/pinctrl/consumer.h>
# include <linux/delay.h>
# include <linux/timer.h>
# include <linux/bitops.h>
# define GPIO_DATA_OUT 0x00
# define GPIO_DATA_IN 0x04
# define GPIO_PIN_DIRECTION 0x08
struct moxart_gpio_chip {
struct gpio_chip gpio ;
2013-12-02 11:27:59 +01:00
void __iomem * base ;
2013-11-29 12:11:34 +01:00
} ;
static inline struct moxart_gpio_chip * to_moxart_gpio ( struct gpio_chip * chip )
{
return container_of ( chip , struct moxart_gpio_chip , gpio ) ;
}
static int moxart_gpio_request ( struct gpio_chip * chip , unsigned offset )
{
return pinctrl_request_gpio ( offset ) ;
}
static void moxart_gpio_free ( struct gpio_chip * chip , unsigned offset )
{
pinctrl_free_gpio ( offset ) ;
}
static int moxart_gpio_direction_input ( struct gpio_chip * chip , unsigned offset )
{
struct moxart_gpio_chip * gc = to_moxart_gpio ( chip ) ;
2013-12-02 11:27:59 +01:00
void __iomem * ioaddr = gc - > base + GPIO_PIN_DIRECTION ;
2013-11-29 12:11:34 +01:00
writel ( readl ( ioaddr ) & ~ BIT ( offset ) , ioaddr ) ;
return 0 ;
}
static int moxart_gpio_direction_output ( struct gpio_chip * chip ,
unsigned offset , int value )
{
struct moxart_gpio_chip * gc = to_moxart_gpio ( chip ) ;
2013-12-02 11:27:59 +01:00
void __iomem * ioaddr = gc - > base + GPIO_PIN_DIRECTION ;
2013-11-29 12:11:34 +01:00
writel ( readl ( ioaddr ) | BIT ( offset ) , ioaddr ) ;
return 0 ;
}
static void moxart_gpio_set ( struct gpio_chip * chip , unsigned offset , int value )
{
struct moxart_gpio_chip * gc = to_moxart_gpio ( chip ) ;
2013-12-02 11:27:59 +01:00
void __iomem * ioaddr = gc - > base + GPIO_DATA_OUT ;
2013-11-29 12:11:34 +01:00
u32 reg = readl ( ioaddr ) ;
if ( value )
reg = reg | BIT ( offset ) ;
else
reg = reg & ~ BIT ( offset ) ;
writel ( reg , ioaddr ) ;
}
static int moxart_gpio_get ( struct gpio_chip * chip , unsigned offset )
{
struct moxart_gpio_chip * gc = to_moxart_gpio ( chip ) ;
2013-12-02 11:27:59 +01:00
u32 ret = readl ( gc - > base + GPIO_PIN_DIRECTION ) ;
2013-11-29 12:11:34 +01:00
if ( ret & BIT ( offset ) )
2013-12-02 11:27:59 +01:00
return ! ! ( readl ( gc - > base + GPIO_DATA_OUT ) & BIT ( offset ) ) ;
2013-11-29 12:11:34 +01:00
else
2013-12-02 11:27:59 +01:00
return ! ! ( readl ( gc - > base + GPIO_DATA_IN ) & BIT ( offset ) ) ;
2013-11-29 12:11:34 +01:00
}
static struct gpio_chip moxart_template_chip = {
. label = " moxart-gpio " ,
. request = moxart_gpio_request ,
. free = moxart_gpio_free ,
. direction_input = moxart_gpio_direction_input ,
. direction_output = moxart_gpio_direction_output ,
. set = moxart_gpio_set ,
. get = moxart_gpio_get ,
. ngpio = 32 ,
2013-12-16 10:11:34 +08:00
. owner = THIS_MODULE ,
2013-11-29 12:11:34 +01:00
} ;
static int moxart_gpio_probe ( struct platform_device * pdev )
{
struct device * dev = & pdev - > dev ;
struct resource * res ;
struct moxart_gpio_chip * mgc ;
int ret ;
mgc = devm_kzalloc ( dev , sizeof ( * mgc ) , GFP_KERNEL ) ;
if ( ! mgc ) {
dev_err ( dev , " can't allocate GPIO chip container \n " ) ;
return - ENOMEM ;
}
mgc - > gpio = moxart_template_chip ;
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2013-12-02 11:27:59 +01:00
mgc - > base = devm_ioremap_resource ( dev , res ) ;
2013-12-16 10:12:38 +08:00
if ( IS_ERR ( mgc - > base ) )
2013-12-02 11:27:59 +01:00
return PTR_ERR ( mgc - > base ) ;
2013-11-29 12:11:34 +01:00
mgc - > gpio . dev = dev ;
ret = gpiochip_add ( & mgc - > gpio ) ;
if ( ret ) {
dev_err ( dev , " %s: gpiochip_add failed \n " ,
dev - > of_node - > full_name ) ;
return ret ;
}
return 0 ;
}
static const struct of_device_id moxart_gpio_match [ ] = {
{ . compatible = " moxa,moxart-gpio " } ,
{ }
} ;
static struct platform_driver moxart_gpio_driver = {
. driver = {
. name = " moxart-gpio " ,
. owner = THIS_MODULE ,
. of_match_table = moxart_gpio_match ,
} ,
. probe = moxart_gpio_probe ,
} ;
module_platform_driver ( moxart_gpio_driver ) ;
MODULE_DESCRIPTION ( " MOXART GPIO chip driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Jonas Jensen <jonas.jensen@gmail.com> " ) ;