2011-12-26 00:36:02 +04:00
/*
* Generic GPIO card - detect helper
*
* Copyright ( C ) 2011 , Guennadi Liakhovetski < g . liakhovetski @ gmx . de >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/err.h>
# include <linux/gpio.h>
2014-03-10 17:02:39 +04:00
# include <linux/gpio/consumer.h>
2011-12-26 00:36:02 +04:00
# include <linux/interrupt.h>
# include <linux/jiffies.h>
# include <linux/mmc/host.h>
2012-05-01 01:31:57 +04:00
# include <linux/mmc/slot-gpio.h>
2011-12-26 00:36:02 +04:00
# include <linux/module.h>
# include <linux/slab.h>
2012-05-01 01:31:57 +04:00
struct mmc_gpio {
2014-03-10 17:02:39 +04:00
struct gpio_desc * ro_gpio ;
struct gpio_desc * cd_gpio ;
bool override_ro_active_level ;
bool override_cd_active_level ;
2012-05-01 18:59:38 +04:00
char * ro_label ;
2012-05-01 01:31:57 +04:00
char cd_label [ 0 ] ;
2011-12-26 00:36:02 +04:00
} ;
2012-05-01 01:31:57 +04:00
static irqreturn_t mmc_gpio_cd_irqt ( int irq , void * dev_id )
2011-12-26 00:36:02 +04:00
{
/* Schedule a card detection after a debounce timeout */
2012-12-04 19:51:36 +04:00
struct mmc_host * host = dev_id ;
2014-04-09 02:19:43 +04:00
host - > trigger_card_event = true ;
2012-12-04 19:51:36 +04:00
mmc_detect_change ( host , msecs_to_jiffies ( 200 ) ) ;
2011-12-26 00:36:02 +04:00
return IRQ_HANDLED ;
}
2012-05-01 18:51:38 +04:00
static int mmc_gpio_alloc ( struct mmc_host * host )
{
size_t len = strlen ( dev_name ( host - > parent ) ) + 4 ;
struct mmc_gpio * ctx ;
mutex_lock ( & host - > slot . lock ) ;
ctx = host - > slot . handler_priv ;
if ( ! ctx ) {
/*
* devm_kzalloc ( ) can be called after device_initialize ( ) , even
* before device_add ( ) , i . e . , between mmc_alloc_host ( ) and
* mmc_add_host ( )
*/
2012-05-01 18:59:38 +04:00
ctx = devm_kzalloc ( & host - > class_dev , sizeof ( * ctx ) + 2 * len ,
2012-05-01 18:51:38 +04:00
GFP_KERNEL ) ;
if ( ctx ) {
2012-05-01 18:59:38 +04:00
ctx - > ro_label = ctx - > cd_label + len ;
2012-05-01 18:51:38 +04:00
snprintf ( ctx - > cd_label , len , " %s cd " , dev_name ( host - > parent ) ) ;
2012-05-01 18:59:38 +04:00
snprintf ( ctx - > ro_label , len , " %s ro " , dev_name ( host - > parent ) ) ;
2012-05-01 18:51:38 +04:00
host - > slot . handler_priv = ctx ;
}
}
mutex_unlock ( & host - > slot . lock ) ;
return ctx ? 0 : - ENOMEM ;
}
2012-05-01 18:59:38 +04:00
int mmc_gpio_get_ro ( struct mmc_host * host )
{
struct mmc_gpio * ctx = host - > slot . handler_priv ;
2014-03-10 17:02:39 +04:00
if ( ! ctx | | ! ctx - > ro_gpio )
2012-05-01 18:59:38 +04:00
return - ENOSYS ;
2014-03-10 17:02:39 +04:00
if ( ctx - > override_ro_active_level )
return ! gpiod_get_raw_value_cansleep ( ctx - > ro_gpio ) ^
! ! ( host - > caps2 & MMC_CAP2_RO_ACTIVE_HIGH ) ;
return gpiod_get_value_cansleep ( ctx - > ro_gpio ) ;
2012-05-01 18:59:38 +04:00
}
EXPORT_SYMBOL ( mmc_gpio_get_ro ) ;
2012-05-01 18:27:25 +04:00
int mmc_gpio_get_cd ( struct mmc_host * host )
{
struct mmc_gpio * ctx = host - > slot . handler_priv ;
2014-03-10 17:02:39 +04:00
if ( ! ctx | | ! ctx - > cd_gpio )
2012-05-01 18:27:25 +04:00
return - ENOSYS ;
2014-03-10 17:02:39 +04:00
if ( ctx - > override_cd_active_level )
return ! gpiod_get_raw_value_cansleep ( ctx - > cd_gpio ) ^
! ! ( host - > caps2 & MMC_CAP2_CD_ACTIVE_HIGH ) ;
return gpiod_get_value_cansleep ( ctx - > cd_gpio ) ;
2012-05-01 18:27:25 +04:00
}
EXPORT_SYMBOL ( mmc_gpio_get_cd ) ;
2012-12-11 18:32:18 +04:00
/**
* mmc_gpio_request_ro - request a gpio for write - protection
* @ host : mmc host
* @ gpio : gpio number requested
*
* As devm_ * managed functions are used in mmc_gpio_request_ro ( ) , client
* drivers do not need to explicitly call mmc_gpio_free_ro ( ) for freeing up ,
* if the requesting and freeing are only needed at probing and unbinding time
* for once . However , if client drivers do something special like runtime
* switching for write - protection , they are responsible for calling
* mmc_gpio_request_ro ( ) and mmc_gpio_free_ro ( ) as a pair on their own .
*
* Returns zero on success , else an error .
*/
2012-05-01 18:59:38 +04:00
int mmc_gpio_request_ro ( struct mmc_host * host , unsigned int gpio )
{
struct mmc_gpio * ctx ;
int ret ;
if ( ! gpio_is_valid ( gpio ) )
return - EINVAL ;
ret = mmc_gpio_alloc ( host ) ;
if ( ret < 0 )
return ret ;
ctx = host - > slot . handler_priv ;
2012-12-11 18:32:18 +04:00
ret = devm_gpio_request_one ( & host - > class_dev , gpio , GPIOF_DIR_IN ,
ctx - > ro_label ) ;
2012-09-10 06:56:48 +04:00
if ( ret < 0 )
return ret ;
2014-03-10 17:02:39 +04:00
ctx - > override_ro_active_level = true ;
ctx - > ro_gpio = gpio_to_desc ( gpio ) ;
2012-09-10 06:56:48 +04:00
return 0 ;
2012-05-01 18:59:38 +04:00
}
EXPORT_SYMBOL ( mmc_gpio_request_ro ) ;
2014-03-10 17:02:41 +04:00
void mmc_gpiod_request_cd_irq ( struct mmc_host * host )
2014-03-10 17:02:40 +04:00
{
struct mmc_gpio * ctx = host - > slot . handler_priv ;
int ret , irq ;
if ( host - > slot . cd_irq > = 0 | | ! ctx | | ! ctx - > cd_gpio )
return ;
irq = gpiod_to_irq ( ctx - > cd_gpio ) ;
/*
* Even if gpiod_to_irq ( ) returns a valid IRQ number , the platform might
* still prefer to poll , e . g . , because that IRQ number is already used
* by another unit and cannot be shared .
*/
if ( irq > = 0 & & host - > caps & MMC_CAP_NEEDS_POLL )
irq = - EINVAL ;
if ( irq > = 0 ) {
ret = devm_request_threaded_irq ( & host - > class_dev , irq ,
NULL , mmc_gpio_cd_irqt ,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT ,
ctx - > cd_label , host ) ;
if ( ret < 0 )
irq = ret ;
}
host - > slot . cd_irq = irq ;
if ( irq < 0 )
host - > caps | = MMC_CAP_NEEDS_POLL ;
}
2014-03-10 17:02:41 +04:00
EXPORT_SYMBOL ( mmc_gpiod_request_cd_irq ) ;
2014-03-10 17:02:40 +04:00
2012-12-11 18:32:18 +04:00
/**
* mmc_gpio_request_cd - request a gpio for card - detection
* @ host : mmc host
* @ gpio : gpio number requested
2013-08-08 14:38:31 +04:00
* @ debounce : debounce time in microseconds
2012-12-11 18:32:18 +04:00
*
* As devm_ * managed functions are used in mmc_gpio_request_cd ( ) , client
* drivers do not need to explicitly call mmc_gpio_free_cd ( ) for freeing up ,
* if the requesting and freeing are only needed at probing and unbinding time
* for once . However , if client drivers do something special like runtime
* switching for card - detection , they are responsible for calling
* mmc_gpio_request_cd ( ) and mmc_gpio_free_cd ( ) as a pair on their own .
*
2013-08-08 14:38:31 +04:00
* If GPIO debouncing is desired , set the debounce parameter to a non - zero
* value . The caller is responsible for ensuring that the GPIO driver associated
* with the GPIO supports debouncing , otherwise an error will be returned .
*
2012-12-11 18:32:18 +04:00
* Returns zero on success , else an error .
*/
2013-08-08 14:38:31 +04:00
int mmc_gpio_request_cd ( struct mmc_host * host , unsigned int gpio ,
unsigned int debounce )
2011-12-26 00:36:02 +04:00
{
2012-05-01 01:31:57 +04:00
struct mmc_gpio * ctx ;
2011-12-26 00:36:02 +04:00
int ret ;
2012-05-01 18:51:38 +04:00
ret = mmc_gpio_alloc ( host ) ;
if ( ret < 0 )
return ret ;
2011-12-26 00:36:02 +04:00
2012-05-01 18:51:38 +04:00
ctx = host - > slot . handler_priv ;
2011-12-26 00:36:02 +04:00
2012-12-11 18:32:18 +04:00
ret = devm_gpio_request_one ( & host - > class_dev , gpio , GPIOF_DIR_IN ,
ctx - > cd_label ) ;
2011-12-26 00:36:02 +04:00
if ( ret < 0 )
2012-05-01 18:51:38 +04:00
/*
* don ' t bother freeing memory . It might still get used by other
* slot functions , in any case it will be freed , when the device
* is destroyed .
*/
return ret ;
2011-12-26 00:36:02 +04:00
2013-08-08 14:38:31 +04:00
if ( debounce ) {
ret = gpio_set_debounce ( gpio , debounce ) ;
if ( ret < 0 )
return ret ;
}
2014-03-10 17:02:39 +04:00
ctx - > override_cd_active_level = true ;
ctx - > cd_gpio = gpio_to_desc ( gpio ) ;
2011-12-26 00:36:02 +04:00
2014-03-10 17:02:40 +04:00
mmc_gpiod_request_cd_irq ( host ) ;
2011-12-26 00:36:02 +04:00
return 0 ;
}
2012-05-01 01:31:57 +04:00
EXPORT_SYMBOL ( mmc_gpio_request_cd ) ;
2011-12-26 00:36:02 +04:00
2012-12-11 18:32:18 +04:00
/**
* mmc_gpio_free_ro - free the write - protection gpio
* @ host : mmc host
*
* It ' s provided only for cases that client drivers need to manually free
* up the write - protection gpio requested by mmc_gpio_request_ro ( ) .
*/
2012-05-01 18:59:38 +04:00
void mmc_gpio_free_ro ( struct mmc_host * host )
{
struct mmc_gpio * ctx = host - > slot . handler_priv ;
int gpio ;
2014-03-10 17:02:39 +04:00
if ( ! ctx | | ! ctx - > ro_gpio )
2012-05-01 18:59:38 +04:00
return ;
2014-03-10 17:02:39 +04:00
gpio = desc_to_gpio ( ctx - > ro_gpio ) ;
ctx - > ro_gpio = NULL ;
2012-05-01 18:59:38 +04:00
2012-12-11 18:32:18 +04:00
devm_gpio_free ( & host - > class_dev , gpio ) ;
2012-05-01 18:59:38 +04:00
}
EXPORT_SYMBOL ( mmc_gpio_free_ro ) ;
2012-12-11 18:32:18 +04:00
/**
* mmc_gpio_free_cd - free the card - detection gpio
* @ host : mmc host
*
* It ' s provided only for cases that client drivers need to manually free
* up the card - detection gpio requested by mmc_gpio_request_cd ( ) .
*/
2012-05-01 01:31:57 +04:00
void mmc_gpio_free_cd ( struct mmc_host * host )
2011-12-26 00:36:02 +04:00
{
2012-05-01 17:40:15 +04:00
struct mmc_gpio * ctx = host - > slot . handler_priv ;
2012-05-01 18:27:25 +04:00
int gpio ;
2011-12-26 00:36:02 +04:00
2014-03-10 17:02:39 +04:00
if ( ! ctx | | ! ctx - > cd_gpio )
2012-04-24 19:56:29 +04:00
return ;
2012-05-01 18:27:25 +04:00
if ( host - > slot . cd_irq > = 0 ) {
2012-12-11 18:32:18 +04:00
devm_free_irq ( & host - > class_dev , host - > slot . cd_irq , host ) ;
2012-05-01 18:27:25 +04:00
host - > slot . cd_irq = - EINVAL ;
}
2014-03-10 17:02:39 +04:00
gpio = desc_to_gpio ( ctx - > cd_gpio ) ;
ctx - > cd_gpio = NULL ;
2012-05-01 18:27:25 +04:00
2012-12-11 18:32:18 +04:00
devm_gpio_free ( & host - > class_dev , gpio ) ;
2011-12-26 00:36:02 +04:00
}
2012-05-01 01:31:57 +04:00
EXPORT_SYMBOL ( mmc_gpio_free_cd ) ;
2014-03-10 17:02:41 +04:00
/**
* mmc_gpiod_request_cd - request a gpio descriptor for card - detection
* @ host : mmc host
* @ con_id : function within the GPIO consumer
* @ idx : index of the GPIO to obtain in the consumer
* @ override_active_level : ignore % GPIO_ACTIVE_LOW flag
* @ debounce : debounce time in microseconds
*
* Use this function in place of mmc_gpio_request_cd ( ) to use the GPIO
* descriptor API . Note that it is paired with mmc_gpiod_free_cd ( ) not
* mmc_gpio_free_cd ( ) . Note also that it must be called prior to mmc_add_host ( )
* otherwise the caller must also call mmc_gpiod_request_cd_irq ( ) .
*
* Returns zero on success , else an error .
*/
int mmc_gpiod_request_cd ( struct mmc_host * host , const char * con_id ,
unsigned int idx , bool override_active_level ,
unsigned int debounce )
{
struct mmc_gpio * ctx ;
struct gpio_desc * desc ;
int ret ;
ret = mmc_gpio_alloc ( host ) ;
if ( ret < 0 )
return ret ;
ctx = host - > slot . handler_priv ;
if ( ! con_id )
con_id = ctx - > cd_label ;
desc = devm_gpiod_get_index ( host - > parent , con_id , idx ) ;
if ( IS_ERR ( desc ) )
return PTR_ERR ( desc ) ;
ret = gpiod_direction_input ( desc ) ;
if ( ret < 0 )
return ret ;
if ( debounce ) {
ret = gpiod_set_debounce ( desc , debounce ) ;
if ( ret < 0 )
return ret ;
}
ctx - > override_cd_active_level = override_active_level ;
ctx - > cd_gpio = desc ;
return 0 ;
}
EXPORT_SYMBOL ( mmc_gpiod_request_cd ) ;
/**
* mmc_gpiod_free_cd - free the card - detection gpio descriptor
* @ host : mmc host
*
* It ' s provided only for cases that client drivers need to manually free
* up the card - detection gpio requested by mmc_gpiod_request_cd ( ) .
*/
void mmc_gpiod_free_cd ( struct mmc_host * host )
{
struct mmc_gpio * ctx = host - > slot . handler_priv ;
if ( ! ctx | | ! ctx - > cd_gpio )
return ;
if ( host - > slot . cd_irq > = 0 ) {
devm_free_irq ( & host - > class_dev , host - > slot . cd_irq , host ) ;
host - > slot . cd_irq = - EINVAL ;
}
devm_gpiod_put ( & host - > class_dev , ctx - > cd_gpio ) ;
ctx - > cd_gpio = NULL ;
}
EXPORT_SYMBOL ( mmc_gpiod_free_cd ) ;