2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2014-10-03 11:31:57 +04:00
/*
* 74 xx MMIO GPIO driver
*
* Copyright ( C ) 2014 Alexander Shiyan < shc_work @ mail . ru >
*/
2022-07-19 01:02:52 +03:00
# include <linux/bits.h>
2014-10-03 11:31:57 +04:00
# include <linux/err.h>
2015-12-04 16:02:58 +03:00
# include <linux/gpio/driver.h>
2022-07-19 01:02:50 +03:00
# include <linux/mod_devicetable.h>
# include <linux/module.h>
2014-10-03 11:31:57 +04:00
# include <linux/platform_device.h>
2022-07-19 01:02:50 +03:00
# include <linux/property.h>
2014-10-03 11:31:57 +04:00
2022-07-26 12:14:48 +03:00
# define MMIO_74XX_DIR_IN BIT(8)
# define MMIO_74XX_DIR_OUT BIT(9)
2022-07-19 01:02:52 +03:00
# define MMIO_74XX_BIT_CNT(x) ((x) & GENMASK(7, 0))
2014-10-03 11:31:57 +04:00
struct mmio_74xx_gpio_priv {
2015-12-04 16:02:58 +03:00
struct gpio_chip gc ;
2014-10-03 11:31:57 +04:00
unsigned flags ;
} ;
static const struct of_device_id mmio_74xx_gpio_ids [ ] = {
{
. compatible = " ti,741g125 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 1 ) ,
} ,
{
. compatible = " ti,742g125 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 2 ) ,
} ,
{
. compatible = " ti,74125 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 4 ) ,
} ,
{
. compatible = " ti,74365 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 6 ) ,
} ,
{
. compatible = " ti,74244 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 8 ) ,
} ,
{
. compatible = " ti,741624 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_IN | 16 ) ,
} ,
{
. compatible = " ti,741g74 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 1 ) ,
} ,
{
. compatible = " ti,7474 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 2 ) ,
} ,
{
. compatible = " ti,74175 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 4 ) ,
} ,
{
. compatible = " ti,74174 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 6 ) ,
} ,
{
. compatible = " ti,74273 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 8 ) ,
} ,
{
. compatible = " ti,7416374 " ,
. data = ( const void * ) ( MMIO_74XX_DIR_OUT | 16 ) ,
} ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , mmio_74xx_gpio_ids ) ;
static int mmio_74xx_get_direction ( struct gpio_chip * gc , unsigned offset )
{
2015-12-04 16:02:58 +03:00
struct mmio_74xx_gpio_priv * priv = gpiochip_get_data ( gc ) ;
2014-10-03 11:31:57 +04:00
2019-11-06 11:54:12 +03:00
if ( priv - > flags & MMIO_74XX_DIR_OUT )
return GPIO_LINE_DIRECTION_OUT ;
return GPIO_LINE_DIRECTION_IN ;
2014-10-03 11:31:57 +04:00
}
static int mmio_74xx_dir_in ( struct gpio_chip * gc , unsigned int gpio )
{
2015-12-04 16:02:58 +03:00
struct mmio_74xx_gpio_priv * priv = gpiochip_get_data ( gc ) ;
2014-10-03 11:31:57 +04:00
2022-07-19 01:02:51 +03:00
if ( priv - > flags & MMIO_74XX_DIR_IN )
return 0 ;
return - ENOTSUPP ;
2014-10-03 11:31:57 +04:00
}
static int mmio_74xx_dir_out ( struct gpio_chip * gc , unsigned int gpio , int val )
{
2015-12-04 16:02:58 +03:00
struct mmio_74xx_gpio_priv * priv = gpiochip_get_data ( gc ) ;
2014-10-03 11:31:57 +04:00
if ( priv - > flags & MMIO_74XX_DIR_OUT ) {
gc - > set ( gc , gpio , val ) ;
return 0 ;
}
return - ENOTSUPP ;
}
static int mmio_74xx_gpio_probe ( struct platform_device * pdev )
{
struct mmio_74xx_gpio_priv * priv ;
void __iomem * dat ;
int err ;
priv = devm_kzalloc ( & pdev - > dev , sizeof ( * priv ) , GFP_KERNEL ) ;
if ( ! priv )
return - ENOMEM ;
2022-07-19 01:02:50 +03:00
priv - > flags = ( uintptr_t ) device_get_match_data ( & pdev - > dev ) ;
2018-04-30 10:38:08 +03:00
2019-03-11 21:54:40 +03:00
dat = devm_platform_ioremap_resource ( pdev , 0 ) ;
2014-10-03 11:31:57 +04:00
if ( IS_ERR ( dat ) )
return PTR_ERR ( dat ) ;
2015-12-04 16:02:58 +03:00
err = bgpio_init ( & priv - > gc , & pdev - > dev ,
2014-10-03 11:31:57 +04:00
DIV_ROUND_UP ( MMIO_74XX_BIT_CNT ( priv - > flags ) , 8 ) ,
dat , NULL , NULL , NULL , NULL , 0 ) ;
if ( err )
return err ;
2015-12-04 16:02:58 +03:00
priv - > gc . direction_input = mmio_74xx_dir_in ;
priv - > gc . direction_output = mmio_74xx_dir_out ;
priv - > gc . get_direction = mmio_74xx_get_direction ;
priv - > gc . ngpio = MMIO_74XX_BIT_CNT ( priv - > flags ) ;
priv - > gc . owner = THIS_MODULE ;
2014-10-03 11:31:57 +04:00
platform_set_drvdata ( pdev , priv ) ;
2016-02-22 15:13:28 +03:00
return devm_gpiochip_add_data ( & pdev - > dev , & priv - > gc , priv ) ;
2014-10-03 11:31:57 +04:00
}
static struct platform_driver mmio_74xx_gpio_driver = {
. driver = {
. name = " 74xx-mmio-gpio " ,
. of_match_table = mmio_74xx_gpio_ids ,
} ,
. probe = mmio_74xx_gpio_probe ,
} ;
module_platform_driver ( mmio_74xx_gpio_driver ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Alexander Shiyan <shc_work@mail.ru> " ) ;
MODULE_DESCRIPTION ( " 74xx MMIO GPIO driver " ) ;