2019-01-21 19:34:53 +01:00
// SPDX-License-Identifier: GPL-2.0
2012-05-02 15:16:39 +00:00
/*
* Copyright ( C ) 2011 , 2012 Cavium , Inc .
*/
# include <linux/platform_device.h>
# include <linux/device.h>
# include <linux/of_mdio.h>
# include <linux/module.h>
# include <linux/phy.h>
# include <linux/mdio-mux.h>
2015-04-27 10:37:31 +02:00
# include <linux/gpio/consumer.h>
2012-05-02 15:16:39 +00:00
2014-11-25 10:31:18 +01:00
# define DRV_VERSION "1.1"
2012-05-02 15:16:39 +00:00
# define DRV_DESCRIPTION "GPIO controlled MDIO bus multiplexer driver"
struct mdio_mux_gpio_state {
2015-04-27 10:37:31 +02:00
struct gpio_descs * gpios ;
2012-05-02 15:16:39 +00:00
void * mux_handle ;
} ;
static int mdio_mux_gpio_switch_fn ( int current_child , int desired_child ,
void * data )
{
struct mdio_mux_gpio_state * s = data ;
2018-09-05 23:50:05 +02:00
DECLARE_BITMAP ( values , BITS_PER_TYPE ( desired_child ) ) ;
2012-05-02 15:16:39 +00:00
if ( current_child = = desired_child )
return 0 ;
2018-09-05 23:50:05 +02:00
values [ 0 ] = desired_child ;
2015-04-27 10:37:31 +02:00
2015-05-13 11:04:56 +02:00
gpiod_set_array_value_cansleep ( s - > gpios - > ndescs , s - > gpios - > desc ,
2018-09-05 23:50:07 +02:00
s - > gpios - > info , values ) ;
2012-05-02 15:16:39 +00:00
return 0 ;
}
2012-12-03 09:24:14 -05:00
static int mdio_mux_gpio_probe ( struct platform_device * pdev )
2012-05-02 15:16:39 +00:00
{
struct mdio_mux_gpio_state * s ;
2018-06-25 15:49:49 -07:00
struct gpio_descs * gpios ;
2012-05-02 15:16:39 +00:00
int r ;
2020-07-21 15:01:57 +08:00
gpios = devm_gpiod_get_array ( & pdev - > dev , NULL , GPIOD_OUT_LOW ) ;
2018-06-25 15:49:49 -07:00
if ( IS_ERR ( gpios ) )
return PTR_ERR ( gpios ) ;
2018-09-05 23:50:05 +02:00
s = devm_kzalloc ( & pdev - > dev , sizeof ( * s ) , GFP_KERNEL ) ;
2020-07-21 15:01:57 +08:00
if ( ! s )
2012-05-02 15:16:39 +00:00
return - ENOMEM ;
2018-06-25 15:49:49 -07:00
s - > gpios = gpios ;
2012-05-02 15:16:39 +00:00
2017-09-04 18:30:14 +02:00
r = mdio_mux_init ( & pdev - > dev , pdev - > dev . of_node ,
2016-06-10 11:03:45 +05:30
mdio_mux_gpio_switch_fn , & s - > mux_handle , s , NULL ) ;
2012-05-02 15:16:39 +00:00
2020-07-21 15:01:57 +08:00
if ( r ! = 0 )
2015-04-27 10:37:31 +02:00
return r ;
pdev - > dev . platform_data = s ;
return 0 ;
2012-05-02 15:16:39 +00:00
}
2012-12-03 09:24:14 -05:00
static int mdio_mux_gpio_remove ( struct platform_device * pdev )
2012-05-02 15:16:39 +00:00
{
2013-08-30 14:09:26 +09:00
struct mdio_mux_gpio_state * s = dev_get_platdata ( & pdev - > dev ) ;
2012-05-02 15:16:39 +00:00
mdio_mux_uninit ( s - > mux_handle ) ;
return 0 ;
}
2015-03-17 19:40:23 +01:00
static const struct of_device_id mdio_mux_gpio_match [ ] = {
2012-05-02 15:16:39 +00:00
{
. compatible = " mdio-mux-gpio " ,
} ,
{
/* Legacy compatible property. */
. compatible = " cavium,mdio-mux-sn74cbtlv3253 " ,
} ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , mdio_mux_gpio_match ) ;
static struct platform_driver mdio_mux_gpio_driver = {
. driver = {
. name = " mdio-mux-gpio " ,
. of_match_table = mdio_mux_gpio_match ,
} ,
. probe = mdio_mux_gpio_probe ,
2012-12-03 09:24:14 -05:00
. remove = mdio_mux_gpio_remove ,
2012-05-02 15:16:39 +00:00
} ;
module_platform_driver ( mdio_mux_gpio_driver ) ;
MODULE_DESCRIPTION ( DRV_DESCRIPTION ) ;
MODULE_VERSION ( DRV_VERSION ) ;
MODULE_AUTHOR ( " David Daney " ) ;
2019-01-21 19:34:53 +01:00
MODULE_LICENSE ( " GPL v2 " ) ;