2018-12-05 15:53:39 +03:00
/* SPDX-License-Identifier: GPL-2.0+ */
2015-07-14 05:40:01 +03:00
/*
2017-03-15 20:38:14 +03:00
* Copyright ( C ) 2015 - 2017 Socionext Inc .
* Author : Masahiro Yamada < yamada . masahiro @ socionext . com >
2015-07-14 05:40:01 +03:00
*/
# ifndef __PINCTRL_UNIPHIER_H__
# define __PINCTRL_UNIPHIER_H__
2018-10-16 07:09:58 +03:00
# include <linux/bits.h>
2017-09-02 20:26:18 +03:00
# include <linux/build_bug.h>
2015-07-14 05:40:01 +03:00
# include <linux/kernel.h>
# include <linux/types.h>
2016-05-31 11:05:12 +03:00
struct platform_device ;
2015-07-14 05:40:01 +03:00
/* input enable control register bit */
# define UNIPHIER_PIN_IECTRL_SHIFT 0
2017-07-31 09:21:09 +03:00
# define UNIPHIER_PIN_IECTRL_BITS 3
2015-07-14 05:40:01 +03:00
# define UNIPHIER_PIN_IECTRL_MASK ((1UL << (UNIPHIER_PIN_IECTRL_BITS)) \
- 1 )
/* drive strength control register number */
# define UNIPHIER_PIN_DRVCTRL_SHIFT ((UNIPHIER_PIN_IECTRL_SHIFT) + \
( UNIPHIER_PIN_IECTRL_BITS ) )
# define UNIPHIER_PIN_DRVCTRL_BITS 9
# define UNIPHIER_PIN_DRVCTRL_MASK ((1UL << (UNIPHIER_PIN_DRVCTRL_BITS)) \
- 1 )
2016-05-31 11:05:13 +03:00
/* drive control type */
# define UNIPHIER_PIN_DRV_TYPE_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \
2015-07-14 05:40:01 +03:00
( UNIPHIER_PIN_DRVCTRL_BITS ) )
2016-05-31 11:05:13 +03:00
# define UNIPHIER_PIN_DRV_TYPE_BITS 3
# define UNIPHIER_PIN_DRV_TYPE_MASK ((1UL << (UNIPHIER_PIN_DRV_TYPE_BITS)) \
2015-07-14 05:40:01 +03:00
- 1 )
/* pull-up / pull-down register number */
2016-05-31 11:05:13 +03:00
# define UNIPHIER_PIN_PUPDCTRL_SHIFT ((UNIPHIER_PIN_DRV_TYPE_SHIFT) + \
( UNIPHIER_PIN_DRV_TYPE_BITS ) )
2015-07-14 05:40:01 +03:00
# define UNIPHIER_PIN_PUPDCTRL_BITS 9
# define UNIPHIER_PIN_PUPDCTRL_MASK ((1UL << (UNIPHIER_PIN_PUPDCTRL_BITS))\
- 1 )
/* direction of pull register */
# define UNIPHIER_PIN_PULL_DIR_SHIFT ((UNIPHIER_PIN_PUPDCTRL_SHIFT) + \
( UNIPHIER_PIN_PUPDCTRL_BITS ) )
# define UNIPHIER_PIN_PULL_DIR_BITS 3
# define UNIPHIER_PIN_PULL_DIR_MASK ((1UL << (UNIPHIER_PIN_PULL_DIR_BITS))\
- 1 )
# if UNIPHIER_PIN_PULL_DIR_SHIFT + UNIPHIER_PIN_PULL_DIR_BITS > BITS_PER_LONG
# error "unable to pack pin attributes."
# endif
# define UNIPHIER_PIN_IECTRL_NONE (UNIPHIER_PIN_IECTRL_MASK)
2017-07-31 09:21:09 +03:00
# define UNIPHIER_PIN_IECTRL_EXIST 0
2015-07-14 05:40:01 +03:00
2016-05-31 11:05:13 +03:00
/* drive control type */
enum uniphier_pin_drv_type {
UNIPHIER_PIN_DRV_1BIT , /* 2 level control: 4/8 mA */
UNIPHIER_PIN_DRV_2BIT , /* 4 level control: 8/12/16/20 mA */
2016-05-31 11:05:14 +03:00
UNIPHIER_PIN_DRV_3BIT , /* 8 level control: 4/5/7/9/11/12/14/16 mA */
2016-05-31 11:05:13 +03:00
UNIPHIER_PIN_DRV_FIXED4 , /* fixed to 4mA */
UNIPHIER_PIN_DRV_FIXED5 , /* fixed to 5mA */
UNIPHIER_PIN_DRV_FIXED8 , /* fixed to 8mA */
2015-07-14 05:40:01 +03:00
UNIPHIER_PIN_DRV_NONE , /* no support (input only pin) */
} ;
/* direction of pull register (no pin supports bi-directional pull biasing) */
enum uniphier_pin_pull_dir {
UNIPHIER_PIN_PULL_UP , /* pull-up or disabled */
UNIPHIER_PIN_PULL_DOWN , /* pull-down or disabled */
UNIPHIER_PIN_PULL_UP_FIXED , /* always pull-up */
UNIPHIER_PIN_PULL_DOWN_FIXED , /* always pull-down */
UNIPHIER_PIN_PULL_NONE , /* no pull register */
} ;
# define UNIPHIER_PIN_IECTRL(x) \
( ( ( x ) & ( UNIPHIER_PIN_IECTRL_MASK ) ) < < ( UNIPHIER_PIN_IECTRL_SHIFT ) )
# define UNIPHIER_PIN_DRVCTRL(x) \
( ( ( x ) & ( UNIPHIER_PIN_DRVCTRL_MASK ) ) < < ( UNIPHIER_PIN_DRVCTRL_SHIFT ) )
2016-05-31 11:05:13 +03:00
# define UNIPHIER_PIN_DRV_TYPE(x) \
( ( ( x ) & ( UNIPHIER_PIN_DRV_TYPE_MASK ) ) < < ( UNIPHIER_PIN_DRV_TYPE_SHIFT ) )
2015-07-14 05:40:01 +03:00
# define UNIPHIER_PIN_PUPDCTRL(x) \
( ( ( x ) & ( UNIPHIER_PIN_PUPDCTRL_MASK ) ) < < ( UNIPHIER_PIN_PUPDCTRL_SHIFT ) )
# define UNIPHIER_PIN_PULL_DIR(x) \
( ( ( x ) & ( UNIPHIER_PIN_PULL_DIR_MASK ) ) < < ( UNIPHIER_PIN_PULL_DIR_SHIFT ) )
2016-05-31 11:05:13 +03:00
# define UNIPHIER_PIN_ATTR_PACKED(iectrl, drvctrl, drv_type, pupdctrl, pull_dir)\
2015-07-14 05:40:01 +03:00
( UNIPHIER_PIN_IECTRL ( iectrl ) | \
UNIPHIER_PIN_DRVCTRL ( drvctrl ) | \
2016-05-31 11:05:13 +03:00
UNIPHIER_PIN_DRV_TYPE ( drv_type ) | \
2015-07-14 05:40:01 +03:00
UNIPHIER_PIN_PUPDCTRL ( pupdctrl ) | \
UNIPHIER_PIN_PULL_DIR ( pull_dir ) )
static inline unsigned int uniphier_pin_get_iectrl ( void * drv_data )
{
return ( ( unsigned long ) drv_data > > UNIPHIER_PIN_IECTRL_SHIFT ) &
UNIPHIER_PIN_IECTRL_MASK ;
}
static inline unsigned int uniphier_pin_get_drvctrl ( void * drv_data )
{
return ( ( unsigned long ) drv_data > > UNIPHIER_PIN_DRVCTRL_SHIFT ) &
UNIPHIER_PIN_DRVCTRL_MASK ;
}
2016-05-31 11:05:13 +03:00
static inline unsigned int uniphier_pin_get_drv_type ( void * drv_data )
2015-07-14 05:40:01 +03:00
{
2016-05-31 11:05:13 +03:00
return ( ( unsigned long ) drv_data > > UNIPHIER_PIN_DRV_TYPE_SHIFT ) &
UNIPHIER_PIN_DRV_TYPE_MASK ;
2015-07-14 05:40:01 +03:00
}
static inline unsigned int uniphier_pin_get_pupdctrl ( void * drv_data )
{
return ( ( unsigned long ) drv_data > > UNIPHIER_PIN_PUPDCTRL_SHIFT ) &
UNIPHIER_PIN_PUPDCTRL_MASK ;
}
static inline unsigned int uniphier_pin_get_pull_dir ( void * drv_data )
{
return ( ( unsigned long ) drv_data > > UNIPHIER_PIN_PULL_DIR_SHIFT ) &
UNIPHIER_PIN_PULL_DIR_MASK ;
}
struct uniphier_pinctrl_group {
const char * name ;
const unsigned * pins ;
unsigned num_pins ;
2016-05-31 11:05:18 +03:00
const int * muxvals ;
2015-07-14 05:40:01 +03:00
} ;
struct uniphier_pinmux_function {
const char * name ;
const char * const * groups ;
unsigned num_groups ;
} ;
struct uniphier_pinctrl_socdata {
2016-05-31 11:05:12 +03:00
const struct pinctrl_pin_desc * pins ;
unsigned int npins ;
2015-07-14 05:40:01 +03:00
const struct uniphier_pinctrl_group * groups ;
int groups_count ;
const struct uniphier_pinmux_function * functions ;
int functions_count ;
2017-07-31 09:21:08 +03:00
int ( * get_gpio_muxval ) ( unsigned int pin , unsigned int gpio_offset ) ;
2016-05-31 11:05:16 +03:00
unsigned int caps ;
2016-05-31 11:05:17 +03:00
# define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(1)
2016-05-31 11:05:16 +03:00
# define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(0)
2015-07-14 05:40:01 +03:00
} ;
# define UNIPHIER_PINCTRL_PIN(a, b, c, d, e, f, g) \
{ \
. number = a , \
. name = b , \
. drv_data = ( void * ) UNIPHIER_PIN_ATTR_PACKED ( c , d , e , f , g ) , \
}
2017-07-31 09:21:08 +03:00
# define __UNIPHIER_PINCTRL_GROUP(grp, mux) \
2015-07-14 05:40:01 +03:00
{ \
. name = # grp , \
. pins = grp # # _pins , \
. num_pins = ARRAY_SIZE ( grp # # _pins ) , \
2017-07-31 09:21:08 +03:00
. muxvals = mux , \
2015-07-14 05:40:01 +03:00
}
# define UNIPHIER_PINCTRL_GROUP(grp) \
2017-07-31 09:21:08 +03:00
__UNIPHIER_PINCTRL_GROUP ( grp , \
grp # # _muxvals + \
BUILD_BUG_ON_ZERO ( ARRAY_SIZE ( grp # # _pins ) ! = \
ARRAY_SIZE ( grp # # _muxvals ) ) )
2015-07-14 05:40:01 +03:00
2017-07-31 09:21:08 +03:00
# define UNIPHIER_PINCTRL_GROUP_GPIO(grp) \
__UNIPHIER_PINCTRL_GROUP ( grp , NULL )
2015-07-14 05:40:01 +03:00
# define UNIPHIER_PINMUX_FUNCTION(func) \
{ \
. name = # func , \
. groups = func # # _groups , \
. num_groups = ARRAY_SIZE ( func # # _groups ) , \
}
int uniphier_pinctrl_probe ( struct platform_device * pdev ,
struct uniphier_pinctrl_socdata * socdata ) ;
2017-07-31 09:21:10 +03:00
extern const struct dev_pm_ops uniphier_pinctrl_pm_ops ;
2015-07-14 05:40:01 +03:00
# endif /* __PINCTRL_UNIPHIER_H__ */