2012-06-20 12:29:04 +04:00
/*
* SuperH Pin Function Controller GPIO driver .
*
* Copyright ( C ) 2008 Magnus Damm
* Copyright ( C ) 2009 - 2012 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
2012-12-16 02:50:47 +04:00
2012-12-16 02:50:48 +04:00
# include <linux/device.h>
2012-06-20 12:29:04 +04:00
# include <linux/gpio.h>
2012-12-16 02:50:52 +04:00
# include <linux/init.h>
2012-06-20 12:29:04 +04:00
# include <linux/module.h>
2012-07-10 07:08:14 +04:00
# include <linux/pinctrl/consumer.h>
2012-12-16 02:50:52 +04:00
# include <linux/slab.h>
# include <linux/spinlock.h>
2012-06-20 12:29:04 +04:00
2012-12-16 02:50:44 +04:00
# include "core.h"
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg {
const struct pinmux_data_reg * info ;
2015-02-27 20:38:04 +03:00
u32 shadow ;
2013-02-16 21:34:32 +04:00
} ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin {
u8 dbit ;
u8 dreg ;
} ;
2012-06-20 12:29:04 +04:00
struct sh_pfc_chip {
2013-03-08 20:43:54 +04:00
struct sh_pfc * pfc ;
struct gpio_chip gpio_chip ;
2013-02-17 03:26:33 +04:00
2013-03-08 20:43:54 +04:00
struct sh_pfc_window * mem ;
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * regs ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin * pins ;
2012-06-20 12:29:04 +04:00
} ;
static struct sh_pfc_chip * gpio_to_pfc_chip ( struct gpio_chip * gc )
{
return container_of ( gc , struct sh_pfc_chip , gpio_chip ) ;
}
static struct sh_pfc * gpio_to_pfc ( struct gpio_chip * gc )
{
return gpio_to_pfc_chip ( gc ) - > pfc ;
}
2013-07-15 15:25:08 +04:00
static void gpio_get_data_reg ( struct sh_pfc_chip * chip , unsigned int offset ,
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * * reg ,
unsigned int * bit )
2013-02-15 05:04:55 +04:00
{
2013-07-15 15:25:08 +04:00
int idx = sh_pfc_get_pin_index ( chip - > pfc , offset ) ;
2013-03-08 20:43:54 +04:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
2013-02-15 05:04:55 +04:00
2013-03-08 20:43:54 +04:00
* reg = & chip - > regs [ gpio_pin - > dreg ] ;
* bit = gpio_pin - > dbit ;
2013-02-15 05:04:55 +04:00
}
2015-02-27 20:38:04 +03:00
static u32 gpio_read_data_reg ( struct sh_pfc_chip * chip ,
const struct pinmux_data_reg * dreg )
2013-02-15 05:04:55 +04:00
{
2015-03-12 13:09:16 +03:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-17 03:26:33 +04:00
return sh_pfc_read_raw_reg ( mem , dreg - > reg_width ) ;
}
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
static void gpio_write_data_reg ( struct sh_pfc_chip * chip ,
2015-02-27 20:38:04 +03:00
const struct pinmux_data_reg * dreg , u32 value )
2013-02-17 03:26:33 +04:00
{
2015-03-12 13:09:16 +03:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
sh_pfc_write_raw_reg ( mem , dreg - > reg_width , value ) ;
}
2013-02-15 05:04:55 +04:00
2013-07-15 15:25:08 +04:00
static void gpio_setup_data_reg ( struct sh_pfc_chip * chip , unsigned idx )
2013-02-17 03:26:33 +04:00
{
2013-03-08 20:43:54 +04:00
struct sh_pfc * pfc = chip - > pfc ;
2013-07-15 15:25:08 +04:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
2013-02-17 03:26:33 +04:00
const struct pinmux_data_reg * dreg ;
unsigned int bit ;
unsigned int i ;
2013-02-15 05:04:55 +04:00
2015-03-12 13:09:15 +03:00
for ( i = 0 , dreg = pfc - > info - > data_regs ; dreg - > reg_width ; + + i , + + dreg ) {
2013-02-17 03:26:33 +04:00
for ( bit = 0 ; bit < dreg - > reg_width ; bit + + ) {
2013-03-08 20:43:54 +04:00
if ( dreg - > enum_ids [ bit ] = = pin - > enum_id ) {
gpio_pin - > dreg = i ;
gpio_pin - > dbit = bit ;
2013-02-15 05:04:55 +04:00
return ;
}
}
}
BUG ( ) ;
}
2013-02-17 03:26:33 +04:00
static int gpio_setup_data_regs ( struct sh_pfc_chip * chip )
2013-02-15 05:04:55 +04:00
{
2013-02-17 03:26:33 +04:00
struct sh_pfc * pfc = chip - > pfc ;
2013-02-16 21:34:32 +04:00
const struct pinmux_data_reg * dreg ;
2013-02-17 03:26:33 +04:00
unsigned int i ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
/* Count the number of data registers, allocate memory and initialize
* them .
*/
for ( i = 0 ; pfc - > info - > data_regs [ i ] . reg_width ; + + i )
;
chip - > regs = devm_kzalloc ( pfc - > dev , i * sizeof ( * chip - > regs ) ,
GFP_KERNEL ) ;
if ( chip - > regs = = NULL )
return - ENOMEM ;
for ( i = 0 , dreg = pfc - > info - > data_regs ; dreg - > reg_width ; + + i , + + dreg ) {
chip - > regs [ i ] . info = dreg ;
chip - > regs [ i ] . shadow = gpio_read_data_reg ( chip , dreg ) ;
}
2013-02-15 05:04:55 +04:00
2013-02-17 03:26:33 +04:00
for ( i = 0 ; i < pfc - > info - > nr_pins ; i + + ) {
if ( pfc - > info - > pins [ i ] . enum_id = = 0 )
continue ;
2013-03-08 20:43:54 +04:00
gpio_setup_data_reg ( chip , i ) ;
2013-02-15 05:04:55 +04:00
}
2013-02-17 03:26:33 +04:00
return 0 ;
2013-02-15 05:04:55 +04:00
}
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Pin GPIOs
*/
2012-06-20 12:29:04 +04:00
2012-12-06 17:49:25 +04:00
static int gpio_pin_request ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2013-02-15 01:12:11 +04:00
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-03-08 20:43:54 +04:00
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
2013-02-15 01:12:11 +04:00
2013-03-08 20:43:54 +04:00
if ( idx < 0 | | pfc - > info - > pins [ idx ] . enum_id = = 0 )
2013-02-15 01:12:11 +04:00
return - EINVAL ;
2012-12-06 17:49:25 +04:00
return pinctrl_request_gpio ( offset ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static void gpio_pin_free ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2012-12-06 17:49:25 +04:00
return pinctrl_free_gpio ( offset ) ;
2012-06-20 12:29:04 +04:00
}
2013-02-17 03:26:33 +04:00
static void gpio_pin_set_value ( struct sh_pfc_chip * chip , unsigned offset ,
int value )
2012-06-20 12:29:04 +04:00
{
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 05:04:55 +04:00
unsigned int bit ;
2015-03-12 13:09:14 +03:00
unsigned int pos ;
2012-06-20 12:29:04 +04:00
2013-02-16 21:34:32 +04:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 05:04:55 +04:00
if ( value )
2015-02-27 20:38:04 +03:00
reg - > shadow | = BIT ( pos ) ;
2013-02-15 05:04:55 +04:00
else
2015-02-27 20:38:04 +03:00
reg - > shadow & = ~ BIT ( pos ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
gpio_write_data_reg ( chip , reg - > info , reg - > shadow ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_direction_input ( struct gpio_chip * gc , unsigned offset )
2012-07-10 07:08:14 +04:00
{
return pinctrl_gpio_direction_input ( offset ) ;
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_direction_output ( struct gpio_chip * gc , unsigned offset ,
2012-07-10 07:08:14 +04:00
int value )
{
2013-02-17 03:26:33 +04:00
gpio_pin_set_value ( gpio_to_pfc_chip ( gc ) , offset , value ) ;
2012-07-10 07:08:14 +04:00
return pinctrl_gpio_direction_output ( offset ) ;
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_get ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
2013-02-17 03:26:33 +04:00
struct sh_pfc_chip * chip = gpio_to_pfc_chip ( gc ) ;
2013-02-16 21:34:32 +04:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 05:04:55 +04:00
unsigned int bit ;
2015-03-12 13:09:14 +03:00
unsigned int pos ;
2012-12-06 17:49:25 +04:00
2013-02-16 21:34:32 +04:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 05:04:55 +04:00
2013-02-16 21:34:32 +04:00
return ( gpio_read_data_reg ( chip , reg - > info ) > > pos ) & 1 ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static void gpio_pin_set ( struct gpio_chip * gc , unsigned offset , int value )
2012-06-20 12:29:04 +04:00
{
2013-02-17 03:26:33 +04:00
gpio_pin_set_value ( gpio_to_pfc_chip ( gc ) , offset , value ) ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
static int gpio_pin_to_irq ( struct gpio_chip * gc , unsigned offset )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-12-11 07:26:21 +04:00
unsigned int i , k ;
2013-01-03 17:12:14 +04:00
for ( i = 0 ; i < pfc - > info - > gpio_irq_size ; i + + ) {
2013-12-16 23:25:15 +04:00
const short * gpios = pfc - > info - > gpio_irq [ i ] . gpios ;
2013-01-03 17:12:14 +04:00
2013-12-11 07:26:22 +04:00
for ( k = 0 ; gpios [ k ] > = 0 ; k + + ) {
2013-01-03 17:12:14 +04:00
if ( gpios [ k ] = = offset )
2013-12-11 07:26:26 +04:00
goto found ;
2012-06-20 12:29:04 +04:00
}
}
return - ENOSYS ;
2013-12-11 07:26:26 +04:00
found :
if ( pfc - > num_irqs )
return pfc - > irqs [ i ] ;
else
return pfc - > info - > gpio_irq [ i ] . irq ;
2012-06-20 12:29:04 +04:00
}
2013-02-17 03:26:33 +04:00
static int gpio_pin_setup ( struct sh_pfc_chip * chip )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc * pfc = chip - > pfc ;
struct gpio_chip * gc = & chip - > gpio_chip ;
2013-02-17 03:26:33 +04:00
int ret ;
2013-07-15 15:36:39 +04:00
chip - > pins = devm_kzalloc ( pfc - > dev , pfc - > info - > nr_pins *
sizeof ( * chip - > pins ) , GFP_KERNEL ) ;
2013-03-08 20:43:54 +04:00
if ( chip - > pins = = NULL )
return - ENOMEM ;
2013-02-17 03:26:33 +04:00
ret = gpio_setup_data_regs ( chip ) ;
if ( ret < 0 )
return ret ;
2012-06-20 12:29:04 +04:00
2012-12-06 17:49:25 +04:00
gc - > request = gpio_pin_request ;
gc - > free = gpio_pin_free ;
gc - > direction_input = gpio_pin_direction_input ;
gc - > get = gpio_pin_get ;
gc - > direction_output = gpio_pin_direction_output ;
gc - > set = gpio_pin_set ;
gc - > to_irq = gpio_pin_to_irq ;
2012-06-20 12:29:04 +04:00
2012-12-16 02:51:20 +04:00
gc - > label = pfc - > info - > name ;
2012-12-06 17:49:25 +04:00
gc - > dev = pfc - > dev ;
2012-06-20 12:29:04 +04:00
gc - > owner = THIS_MODULE ;
2012-11-28 20:51:00 +04:00
gc - > base = 0 ;
2013-07-15 15:48:56 +04:00
gc - > ngpio = pfc - > nr_gpio_pins ;
2013-02-17 03:26:33 +04:00
return 0 ;
2012-06-20 12:29:04 +04:00
}
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Function GPIOs
*/
2015-08-04 16:55:19 +03:00
# ifdef CONFIG_SUPERH
2012-12-06 17:49:25 +04:00
static int gpio_function_request ( struct gpio_chip * gc , unsigned offset )
{
2013-03-10 21:00:02 +04:00
static bool __print_once ;
2012-12-06 17:49:25 +04:00
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-02-14 20:36:56 +04:00
unsigned int mark = pfc - > info - > func_gpios [ offset ] . enum_id ;
2012-12-06 17:49:25 +04:00
unsigned long flags ;
2013-03-10 19:38:23 +04:00
int ret ;
2012-12-06 17:49:25 +04:00
2013-03-10 21:00:02 +04:00
if ( ! __print_once ) {
dev_notice ( pfc - > dev ,
" Use of GPIO API for function requests is deprecated. "
" Convert to pinctrl \n " ) ;
__print_once = true ;
}
2012-12-06 17:49:25 +04:00
2013-02-14 20:36:56 +04:00
if ( mark = = 0 )
2013-03-10 19:38:23 +04:00
return - EINVAL ;
2012-12-06 17:49:25 +04:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 19:38:23 +04:00
ret = sh_pfc_config_mux ( pfc , mark , PINMUX_TYPE_FUNCTION ) ;
2012-12-06 17:49:25 +04:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2013-03-10 19:38:23 +04:00
2012-12-06 17:49:25 +04:00
return ret ;
}
2013-02-17 03:26:33 +04:00
static int gpio_function_setup ( struct sh_pfc_chip * chip )
2012-12-06 17:49:25 +04:00
{
struct sh_pfc * pfc = chip - > pfc ;
struct gpio_chip * gc = & chip - > gpio_chip ;
gc - > request = gpio_function_request ;
gc - > label = pfc - > info - > name ;
gc - > owner = THIS_MODULE ;
2013-07-15 15:48:56 +04:00
gc - > base = pfc - > nr_gpio_pins ;
2012-12-06 17:49:25 +04:00
gc - > ngpio = pfc - > info - > nr_func_gpios ;
2013-02-17 03:26:33 +04:00
return 0 ;
2012-12-06 17:49:25 +04:00
}
2015-08-04 16:55:19 +03:00
# endif
2012-12-06 17:49:25 +04:00
/* -----------------------------------------------------------------------------
* Register / unregister
*/
static struct sh_pfc_chip *
2013-03-10 06:19:44 +04:00
sh_pfc_add_gpiochip ( struct sh_pfc * pfc , int ( * setup ) ( struct sh_pfc_chip * ) ,
struct sh_pfc_window * mem )
2012-06-20 12:29:04 +04:00
{
struct sh_pfc_chip * chip ;
int ret ;
2012-12-16 02:50:48 +04:00
chip = devm_kzalloc ( pfc - > dev , sizeof ( * chip ) , GFP_KERNEL ) ;
2012-06-20 12:29:04 +04:00
if ( unlikely ( ! chip ) )
2012-12-06 17:49:25 +04:00
return ERR_PTR ( - ENOMEM ) ;
2012-06-20 12:29:04 +04:00
2013-03-10 06:19:44 +04:00
chip - > mem = mem ;
2012-06-20 12:29:04 +04:00
chip - > pfc = pfc ;
2013-02-17 03:26:33 +04:00
ret = setup ( chip ) ;
if ( ret < 0 )
return ERR_PTR ( ret ) ;
2012-06-20 12:29:04 +04:00
ret = gpiochip_add ( & chip - > gpio_chip ) ;
2012-12-16 02:50:48 +04:00
if ( unlikely ( ret < 0 ) )
2012-12-06 17:49:25 +04:00
return ERR_PTR ( ret ) ;
2013-03-10 21:00:02 +04:00
dev_info ( pfc - > dev , " %s handling gpio %u -> %u \n " ,
chip - > gpio_chip . label , chip - > gpio_chip . base ,
chip - > gpio_chip . base + chip - > gpio_chip . ngpio - 1 ) ;
2012-12-06 17:49:25 +04:00
return chip ;
}
int sh_pfc_register_gpiochip ( struct sh_pfc * pfc )
{
struct sh_pfc_chip * chip ;
2015-03-12 13:09:16 +03:00
phys_addr_t address ;
2013-02-15 04:33:38 +04:00
unsigned int i ;
2012-12-06 17:49:25 +04:00
2013-03-10 06:19:44 +04:00
if ( pfc - > info - > data_regs = = NULL )
return 0 ;
2013-03-10 06:19:44 +04:00
/* Find the memory window that contain the GPIO registers. Boards that
* register a separate GPIO device will not supply a memory resource
* that covers the data registers . In that case don ' t try to handle
* GPIOs .
*/
2015-03-12 13:09:16 +03:00
address = pfc - > info - > data_regs [ 0 ] . reg ;
2013-03-10 06:19:44 +04:00
for ( i = 0 ; i < pfc - > num_windows ; + + i ) {
2013-12-11 07:26:25 +04:00
struct sh_pfc_window * window = & pfc - > windows [ i ] ;
2013-03-10 06:19:44 +04:00
2015-03-12 13:09:16 +03:00
if ( address > = window - > phys & &
address < window - > phys + window - > size )
2013-03-10 06:19:44 +04:00
break ;
}
if ( i = = pfc - > num_windows )
return 0 ;
2013-12-11 07:26:26 +04:00
/* If we have IRQ resources make sure their number is correct. */
if ( pfc - > num_irqs & & pfc - > num_irqs ! = pfc - > info - > gpio_irq_size ) {
dev_err ( pfc - > dev , " invalid number of IRQ resources \n " ) ;
return - EINVAL ;
}
2013-02-15 04:33:38 +04:00
/* Register the real GPIOs chip. */
2013-12-11 07:26:25 +04:00
chip = sh_pfc_add_gpiochip ( pfc , gpio_pin_setup , & pfc - > windows [ i ] ) ;
2012-12-06 17:49:25 +04:00
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
2012-12-16 02:50:46 +04:00
pfc - > gpio = chip ;
2012-06-20 12:29:04 +04:00
2015-08-04 16:55:17 +03:00
if ( IS_ENABLED ( CONFIG_OF ) & & pfc - > dev - > of_node )
return 0 ;
2013-07-15 23:10:54 +04:00
2015-08-27 23:07:23 +03:00
# ifdef CONFIG_SUPERH
/*
* Register the GPIO to pin mappings . As pins with GPIO ports
* must come first in the ranges , skip the pins without GPIO
* ports by stopping at the first range that contains such a
* pin .
*/
for ( i = 0 ; i < pfc - > nr_ranges ; + + i ) {
const struct sh_pfc_pin_range * range = & pfc - > ranges [ i ] ;
int ret ;
if ( range - > start > = pfc - > nr_gpio_pins )
break ;
ret = gpiochip_add_pin_range ( & chip - > gpio_chip ,
dev_name ( pfc - > dev ) , range - > start , range - > start ,
range - > end - range - > start + 1 ) ;
if ( ret < 0 )
return ret ;
2013-02-15 04:33:38 +04:00
}
2013-03-08 03:45:12 +04:00
2013-02-15 04:33:38 +04:00
/* Register the function GPIOs chip. */
2013-03-07 17:31:57 +04:00
if ( pfc - > info - > nr_func_gpios = = 0 )
return 0 ;
2013-03-10 06:19:44 +04:00
chip = sh_pfc_add_gpiochip ( pfc , gpio_function_setup , NULL ) ;
2012-12-06 17:49:25 +04:00
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
pfc - > func = chip ;
2015-08-04 16:55:19 +03:00
# endif /* CONFIG_SUPERH */
2012-06-20 12:29:04 +04:00
return 0 ;
}
2012-12-16 02:50:46 +04:00
int sh_pfc_unregister_gpiochip ( struct sh_pfc * pfc )
2012-06-20 12:29:04 +04:00
{
2014-07-13 00:30:13 +04:00
gpiochip_remove ( & pfc - > gpio - > gpio_chip ) ;
2015-08-04 16:55:19 +03:00
# ifdef CONFIG_SUPERH
2014-07-13 00:30:13 +04:00
gpiochip_remove ( & pfc - > func - > gpio_chip ) ;
2015-08-04 16:55:19 +03:00
# endif
2014-07-13 00:30:13 +04:00
return 0 ;
2012-06-20 12:29:04 +04:00
}