2012-06-20 17:29:04 +09: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-15 23:50:47 +01:00
2012-12-15 23:50:48 +01:00
# include <linux/device.h>
2012-06-20 17:29:04 +09:00
# include <linux/gpio.h>
2012-12-15 23:50:52 +01:00
# include <linux/init.h>
2012-06-20 17:29:04 +09:00
# include <linux/module.h>
2012-07-10 12:08:14 +09:00
# include <linux/pinctrl/consumer.h>
2012-12-15 23:50:52 +01:00
# include <linux/slab.h>
# include <linux/spinlock.h>
2012-06-20 17:29:04 +09:00
2012-12-15 23:50:44 +01:00
# include "core.h"
2013-02-16 18:34:32 +01:00
struct sh_pfc_gpio_data_reg {
const struct pinmux_data_reg * info ;
2015-02-27 18:38:04 +01:00
u32 shadow ;
2013-02-16 18:34:32 +01:00
} ;
2013-03-08 17:43:54 +01:00
struct sh_pfc_gpio_pin {
u8 dbit ;
u8 dreg ;
} ;
2012-06-20 17:29:04 +09:00
struct sh_pfc_chip {
2013-03-08 17:43:54 +01:00
struct sh_pfc * pfc ;
struct gpio_chip gpio_chip ;
2013-02-17 00:26:33 +01:00
2013-03-08 17:43:54 +01:00
struct sh_pfc_window * mem ;
2013-02-16 18:34:32 +01:00
struct sh_pfc_gpio_data_reg * regs ;
2013-03-08 17:43:54 +01:00
struct sh_pfc_gpio_pin * pins ;
2012-06-20 17:29:04 +09:00
} ;
static struct sh_pfc * gpio_to_pfc ( struct gpio_chip * gc )
{
2015-12-08 10:24:54 +01:00
struct sh_pfc_chip * chip = gpiochip_get_data ( gc ) ;
return chip - > pfc ;
2012-06-20 17:29:04 +09:00
}
2013-07-15 13:25:08 +02:00
static void gpio_get_data_reg ( struct sh_pfc_chip * chip , unsigned int offset ,
2013-02-16 18:34:32 +01:00
struct sh_pfc_gpio_data_reg * * reg ,
unsigned int * bit )
2013-02-15 02:04:55 +01:00
{
2013-07-15 13:25:08 +02:00
int idx = sh_pfc_get_pin_index ( chip - > pfc , offset ) ;
2013-03-08 17:43:54 +01:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
2013-02-15 02:04:55 +01:00
2013-03-08 17:43:54 +01:00
* reg = & chip - > regs [ gpio_pin - > dreg ] ;
* bit = gpio_pin - > dbit ;
2013-02-15 02:04:55 +01:00
}
2015-02-27 18:38:04 +01:00
static u32 gpio_read_data_reg ( struct sh_pfc_chip * chip ,
const struct pinmux_data_reg * dreg )
2013-02-15 02:04:55 +01:00
{
2015-03-12 11:09:16 +01:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-17 00:26:33 +01:00
return sh_pfc_read_raw_reg ( mem , dreg - > reg_width ) ;
}
2013-02-15 02:04:55 +01:00
2013-02-17 00:26:33 +01:00
static void gpio_write_data_reg ( struct sh_pfc_chip * chip ,
2015-02-27 18:38:04 +01:00
const struct pinmux_data_reg * dreg , u32 value )
2013-02-17 00:26:33 +01:00
{
2015-03-12 11:09:16 +01:00
phys_addr_t address = dreg - > reg ;
void __iomem * mem = address - chip - > mem - > phys + chip - > mem - > virt ;
2013-02-15 02:04:55 +01:00
2013-02-17 00:26:33 +01:00
sh_pfc_write_raw_reg ( mem , dreg - > reg_width , value ) ;
}
2013-02-15 02:04:55 +01:00
2013-07-15 13:25:08 +02:00
static void gpio_setup_data_reg ( struct sh_pfc_chip * chip , unsigned idx )
2013-02-17 00:26:33 +01:00
{
2013-03-08 17:43:54 +01:00
struct sh_pfc * pfc = chip - > pfc ;
2013-07-15 13:25:08 +02:00
struct sh_pfc_gpio_pin * gpio_pin = & chip - > pins [ idx ] ;
const struct sh_pfc_pin * pin = & pfc - > info - > pins [ idx ] ;
2013-02-17 00:26:33 +01:00
const struct pinmux_data_reg * dreg ;
unsigned int bit ;
unsigned int i ;
2013-02-15 02:04:55 +01:00
2015-03-12 11:09:15 +01:00
for ( i = 0 , dreg = pfc - > info - > data_regs ; dreg - > reg_width ; + + i , + + dreg ) {
2013-02-17 00:26:33 +01:00
for ( bit = 0 ; bit < dreg - > reg_width ; bit + + ) {
2013-03-08 17:43:54 +01:00
if ( dreg - > enum_ids [ bit ] = = pin - > enum_id ) {
gpio_pin - > dreg = i ;
gpio_pin - > dbit = bit ;
2013-02-15 02:04:55 +01:00
return ;
}
}
}
BUG ( ) ;
}
2013-02-17 00:26:33 +01:00
static int gpio_setup_data_regs ( struct sh_pfc_chip * chip )
2013-02-15 02:04:55 +01:00
{
2013-02-17 00:26:33 +01:00
struct sh_pfc * pfc = chip - > pfc ;
2013-02-16 18:34:32 +01:00
const struct pinmux_data_reg * dreg ;
2013-02-17 00:26:33 +01:00
unsigned int i ;
2013-02-15 02:04:55 +01:00
2013-02-16 18:34:32 +01: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 02:04:55 +01:00
2013-02-17 00:26:33 +01:00
for ( i = 0 ; i < pfc - > info - > nr_pins ; i + + ) {
if ( pfc - > info - > pins [ i ] . enum_id = = 0 )
continue ;
2013-03-08 17:43:54 +01:00
gpio_setup_data_reg ( chip , i ) ;
2013-02-15 02:04:55 +01:00
}
2013-02-17 00:26:33 +01:00
return 0 ;
2013-02-15 02:04:55 +01:00
}
2012-12-06 14:49:25 +01:00
/* -----------------------------------------------------------------------------
* Pin GPIOs
*/
2012-06-20 17:29:04 +09:00
2012-12-06 14:49:25 +01:00
static int gpio_pin_request ( struct gpio_chip * gc , unsigned offset )
2012-06-20 17:29:04 +09:00
{
2013-02-14 22:12:11 +01:00
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-03-08 17:43:54 +01:00
int idx = sh_pfc_get_pin_index ( pfc , offset ) ;
2013-02-14 22:12:11 +01:00
2013-03-08 17:43:54 +01:00
if ( idx < 0 | | pfc - > info - > pins [ idx ] . enum_id = = 0 )
2013-02-14 22:12:11 +01:00
return - EINVAL ;
2012-12-06 14:49:25 +01:00
return pinctrl_request_gpio ( offset ) ;
2012-06-20 17:29:04 +09:00
}
2012-12-06 14:49:25 +01:00
static void gpio_pin_free ( struct gpio_chip * gc , unsigned offset )
2012-06-20 17:29:04 +09:00
{
2012-12-06 14:49:25 +01:00
return pinctrl_free_gpio ( offset ) ;
2012-06-20 17:29:04 +09:00
}
2013-02-17 00:26:33 +01:00
static void gpio_pin_set_value ( struct sh_pfc_chip * chip , unsigned offset ,
int value )
2012-06-20 17:29:04 +09:00
{
2013-02-16 18:34:32 +01:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 02:04:55 +01:00
unsigned int bit ;
2015-03-12 11:09:14 +01:00
unsigned int pos ;
2012-06-20 17:29:04 +09:00
2013-02-16 18:34:32 +01:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 02:04:55 +01:00
2013-02-16 18:34:32 +01:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 02:04:55 +01:00
if ( value )
2015-02-27 18:38:04 +01:00
reg - > shadow | = BIT ( pos ) ;
2013-02-15 02:04:55 +01:00
else
2015-02-27 18:38:04 +01:00
reg - > shadow & = ~ BIT ( pos ) ;
2013-02-15 02:04:55 +01:00
2013-02-16 18:34:32 +01:00
gpio_write_data_reg ( chip , reg - > info , reg - > shadow ) ;
2012-06-20 17:29:04 +09:00
}
2012-12-06 14:49:25 +01:00
static int gpio_pin_direction_input ( struct gpio_chip * gc , unsigned offset )
2012-07-10 12:08:14 +09:00
{
return pinctrl_gpio_direction_input ( offset ) ;
}
2012-12-06 14:49:25 +01:00
static int gpio_pin_direction_output ( struct gpio_chip * gc , unsigned offset ,
2012-07-10 12:08:14 +09:00
int value )
{
2015-12-08 10:24:54 +01:00
gpio_pin_set_value ( gpiochip_get_data ( gc ) , offset , value ) ;
2012-07-10 12:08:14 +09:00
return pinctrl_gpio_direction_output ( offset ) ;
}
2012-12-06 14:49:25 +01:00
static int gpio_pin_get ( struct gpio_chip * gc , unsigned offset )
2012-06-20 17:29:04 +09:00
{
2015-12-08 10:24:54 +01:00
struct sh_pfc_chip * chip = gpiochip_get_data ( gc ) ;
2013-02-16 18:34:32 +01:00
struct sh_pfc_gpio_data_reg * reg ;
2013-02-15 02:04:55 +01:00
unsigned int bit ;
2015-03-12 11:09:14 +01:00
unsigned int pos ;
2012-12-06 14:49:25 +01:00
2013-02-16 18:34:32 +01:00
gpio_get_data_reg ( chip , offset , & reg , & bit ) ;
2013-02-15 02:04:55 +01:00
2013-02-16 18:34:32 +01:00
pos = reg - > info - > reg_width - ( bit + 1 ) ;
2013-02-15 02:04:55 +01:00
2013-02-16 18:34:32 +01:00
return ( gpio_read_data_reg ( chip , reg - > info ) > > pos ) & 1 ;
2012-06-20 17:29:04 +09:00
}
2012-12-06 14:49:25 +01:00
static void gpio_pin_set ( struct gpio_chip * gc , unsigned offset , int value )
2012-06-20 17:29:04 +09:00
{
2015-12-08 10:24:54 +01:00
gpio_pin_set_value ( gpiochip_get_data ( gc ) , offset , value ) ;
2012-06-20 17:29:04 +09:00
}
2012-12-06 14:49:25 +01:00
static int gpio_pin_to_irq ( struct gpio_chip * gc , unsigned offset )
2012-06-20 17:29:04 +09:00
{
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-12-11 04:26:21 +01:00
unsigned int i , k ;
2013-01-03 14:12:14 +01:00
for ( i = 0 ; i < pfc - > info - > gpio_irq_size ; i + + ) {
2013-12-16 20:25:15 +01:00
const short * gpios = pfc - > info - > gpio_irq [ i ] . gpios ;
2013-01-03 14:12:14 +01:00
2013-12-11 04:26:22 +01:00
for ( k = 0 ; gpios [ k ] > = 0 ; k + + ) {
2013-01-03 14:12:14 +01:00
if ( gpios [ k ] = = offset )
2013-12-11 04:26:26 +01:00
goto found ;
2012-06-20 17:29:04 +09:00
}
}
return - ENOSYS ;
2013-12-11 04:26:26 +01:00
found :
2015-09-22 10:08:13 +03:00
return pfc - > irqs [ i ] ;
2012-06-20 17:29:04 +09:00
}
2013-02-17 00:26:33 +01:00
static int gpio_pin_setup ( struct sh_pfc_chip * chip )
2012-06-20 17:29:04 +09:00
{
struct sh_pfc * pfc = chip - > pfc ;
struct gpio_chip * gc = & chip - > gpio_chip ;
2013-02-17 00:26:33 +01:00
int ret ;
2013-07-15 13:36:39 +02:00
chip - > pins = devm_kzalloc ( pfc - > dev , pfc - > info - > nr_pins *
sizeof ( * chip - > pins ) , GFP_KERNEL ) ;
2013-03-08 17:43:54 +01:00
if ( chip - > pins = = NULL )
return - ENOMEM ;
2013-02-17 00:26:33 +01:00
ret = gpio_setup_data_regs ( chip ) ;
if ( ret < 0 )
return ret ;
2012-06-20 17:29:04 +09:00
2012-12-06 14:49:25 +01: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 17:29:04 +09:00
2012-12-15 23:51:20 +01:00
gc - > label = pfc - > info - > name ;
2015-11-04 09:56:26 +01:00
gc - > parent = pfc - > dev ;
2012-06-20 17:29:04 +09:00
gc - > owner = THIS_MODULE ;
2012-11-28 17:51:00 +01:00
gc - > base = 0 ;
2013-07-15 13:48:56 +02:00
gc - > ngpio = pfc - > nr_gpio_pins ;
2013-02-17 00:26:33 +01:00
return 0 ;
2012-06-20 17:29:04 +09:00
}
2012-12-06 14:49:25 +01:00
/* -----------------------------------------------------------------------------
* Function GPIOs
*/
2015-08-04 15:55:19 +02:00
# ifdef CONFIG_SUPERH
2012-12-06 14:49:25 +01:00
static int gpio_function_request ( struct gpio_chip * gc , unsigned offset )
{
2013-03-10 18:00:02 +01:00
static bool __print_once ;
2012-12-06 14:49:25 +01:00
struct sh_pfc * pfc = gpio_to_pfc ( gc ) ;
2013-02-14 17:36:56 +01:00
unsigned int mark = pfc - > info - > func_gpios [ offset ] . enum_id ;
2012-12-06 14:49:25 +01:00
unsigned long flags ;
2013-03-10 16:38:23 +01:00
int ret ;
2012-12-06 14:49:25 +01:00
2013-03-10 18:00:02 +01: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 14:49:25 +01:00
2013-02-14 17:36:56 +01:00
if ( mark = = 0 )
2013-03-10 16:38:23 +01:00
return - EINVAL ;
2012-12-06 14:49:25 +01:00
spin_lock_irqsave ( & pfc - > lock , flags ) ;
2013-03-10 16:38:23 +01:00
ret = sh_pfc_config_mux ( pfc , mark , PINMUX_TYPE_FUNCTION ) ;
2012-12-06 14:49:25 +01:00
spin_unlock_irqrestore ( & pfc - > lock , flags ) ;
2013-03-10 16:38:23 +01:00
2012-12-06 14:49:25 +01:00
return ret ;
}
2013-02-17 00:26:33 +01:00
static int gpio_function_setup ( struct sh_pfc_chip * chip )
2012-12-06 14:49:25 +01: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 13:48:56 +02:00
gc - > base = pfc - > nr_gpio_pins ;
2012-12-06 14:49:25 +01:00
gc - > ngpio = pfc - > info - > nr_func_gpios ;
2013-02-17 00:26:33 +01:00
return 0 ;
2012-12-06 14:49:25 +01:00
}
2015-08-04 15:55:19 +02:00
# endif
2012-12-06 14:49:25 +01:00
/* -----------------------------------------------------------------------------
* Register / unregister
*/
static struct sh_pfc_chip *
2013-03-10 03:19:44 +01:00
sh_pfc_add_gpiochip ( struct sh_pfc * pfc , int ( * setup ) ( struct sh_pfc_chip * ) ,
struct sh_pfc_window * mem )
2012-06-20 17:29:04 +09:00
{
struct sh_pfc_chip * chip ;
int ret ;
2012-12-15 23:50:48 +01:00
chip = devm_kzalloc ( pfc - > dev , sizeof ( * chip ) , GFP_KERNEL ) ;
2012-06-20 17:29:04 +09:00
if ( unlikely ( ! chip ) )
2012-12-06 14:49:25 +01:00
return ERR_PTR ( - ENOMEM ) ;
2012-06-20 17:29:04 +09:00
2013-03-10 03:19:44 +01:00
chip - > mem = mem ;
2012-06-20 17:29:04 +09:00
chip - > pfc = pfc ;
2013-02-17 00:26:33 +01:00
ret = setup ( chip ) ;
if ( ret < 0 )
return ERR_PTR ( ret ) ;
2012-06-20 17:29:04 +09:00
2015-12-08 10:24:54 +01:00
ret = gpiochip_add_data ( & chip - > gpio_chip , chip ) ;
2012-12-15 23:50:48 +01:00
if ( unlikely ( ret < 0 ) )
2012-12-06 14:49:25 +01:00
return ERR_PTR ( ret ) ;
2013-03-10 18:00:02 +01: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 14:49:25 +01:00
return chip ;
}
int sh_pfc_register_gpiochip ( struct sh_pfc * pfc )
{
struct sh_pfc_chip * chip ;
2015-03-12 11:09:16 +01:00
phys_addr_t address ;
2013-02-15 01:33:38 +01:00
unsigned int i ;
2012-12-06 14:49:25 +01:00
2013-03-10 03:19:44 +01:00
if ( pfc - > info - > data_regs = = NULL )
return 0 ;
2013-03-10 03:19:44 +01: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 11:09:16 +01:00
address = pfc - > info - > data_regs [ 0 ] . reg ;
2013-03-10 03:19:44 +01:00
for ( i = 0 ; i < pfc - > num_windows ; + + i ) {
2013-12-11 04:26:25 +01:00
struct sh_pfc_window * window = & pfc - > windows [ i ] ;
2013-03-10 03:19:44 +01:00
2015-03-12 11:09:16 +01:00
if ( address > = window - > phys & &
address < window - > phys + window - > size )
2013-03-10 03:19:44 +01:00
break ;
}
if ( i = = pfc - > num_windows )
return 0 ;
2013-12-11 04:26:26 +01:00
/* If we have IRQ resources make sure their number is correct. */
2015-09-22 10:08:13 +03:00
if ( pfc - > num_irqs ! = pfc - > info - > gpio_irq_size ) {
2013-12-11 04:26:26 +01:00
dev_err ( pfc - > dev , " invalid number of IRQ resources \n " ) ;
return - EINVAL ;
}
2013-02-15 01:33:38 +01:00
/* Register the real GPIOs chip. */
2013-12-11 04:26:25 +01:00
chip = sh_pfc_add_gpiochip ( pfc , gpio_pin_setup , & pfc - > windows [ i ] ) ;
2012-12-06 14:49:25 +01:00
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
2012-12-15 23:50:46 +01:00
pfc - > gpio = chip ;
2012-06-20 17:29:04 +09:00
2015-08-04 15:55:17 +02:00
if ( IS_ENABLED ( CONFIG_OF ) & & pfc - > dev - > of_node )
return 0 ;
2013-07-15 21:10:54 +02:00
2015-08-27 22:07:23 +02: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 01:33:38 +01:00
}
2013-03-08 00:45:12 +01:00
2013-02-15 01:33:38 +01:00
/* Register the function GPIOs chip. */
2013-03-07 14:31:57 +01:00
if ( pfc - > info - > nr_func_gpios = = 0 )
return 0 ;
2013-03-10 03:19:44 +01:00
chip = sh_pfc_add_gpiochip ( pfc , gpio_function_setup , NULL ) ;
2012-12-06 14:49:25 +01:00
if ( IS_ERR ( chip ) )
return PTR_ERR ( chip ) ;
pfc - > func = chip ;
2015-08-04 15:55:19 +02:00
# endif /* CONFIG_SUPERH */
2012-06-20 17:29:04 +09:00
return 0 ;
}
2012-12-15 23:50:46 +01:00
int sh_pfc_unregister_gpiochip ( struct sh_pfc * pfc )
2012-06-20 17:29:04 +09:00
{
2014-07-12 22:30:13 +02:00
gpiochip_remove ( & pfc - > gpio - > gpio_chip ) ;
2015-08-04 15:55:19 +02:00
# ifdef CONFIG_SUPERH
2014-07-12 22:30:13 +02:00
gpiochip_remove ( & pfc - > func - > gpio_chip ) ;
2015-08-04 15:55:19 +02:00
# endif
2014-07-12 22:30:13 +02:00
return 0 ;
2012-06-20 17:29:04 +09:00
}