diff options
| author | mario.six@gdsys.cc <mario.six@gdsys.cc> | 2016-05-25 15:15:22 +0200 | 
|---|---|---|
| committer | York Sun <york.sun@nxp.com> | 2016-06-03 22:14:12 -0700 | 
| commit | 51781783c59ad0080621d777579eb8acd14aa0ed (patch) | |
| tree | 9bc3d558f520e04d407b5b582a98b525e4f1e832 /drivers/gpio/mpc85xx_gpio.c | |
| parent | 53ecdfb92034ce836ec94ba33ba0d8d27ea3c16c (diff) | |
dm: gpio: Implement open drain for MPC85XX GPIO
This patch implements the open-drain setting feature for the MPC85XX
GPIO controller.
Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: York Sun <york.sun@nxp.com>
Diffstat (limited to 'drivers/gpio/mpc85xx_gpio.c')
| -rw-r--r-- | drivers/gpio/mpc85xx_gpio.c | 41 | 
1 files changed, 41 insertions, 0 deletions
| diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c index 17755dfb924..04773e2b31c 100644 --- a/drivers/gpio/mpc85xx_gpio.c +++ b/drivers/gpio/mpc85xx_gpio.c @@ -73,6 +73,25 @@ static inline void mpc85xx_gpio_set_high(struct ccsr_gpio *base, u32 gpios)  	setbits_be32(&base->gpdir, gpios);  } +static inline int mpc85xx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask) +{ +	return in_be32(&base->gpodr) & mask; +} + +static inline void mpc85xx_gpio_open_drain_on(struct ccsr_gpio *base, u32 +					      gpios) +{ +	/* GPODR register 1 -> open drain on */ +	setbits_be32(&base->gpodr, gpios); +} + +static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base, +					       u32 gpios) +{ +	/* GPODR register 0 -> open drain off (actively driven) */ +	clrbits_be32(&base->gpodr, gpios); +} +  static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio)  {  	struct mpc85xx_gpio_data *data = dev_get_priv(dev); @@ -115,6 +134,26 @@ static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio)  	}  } +static int mpc85xx_gpio_get_open_drain(struct udevice *dev, unsigned gpio) +{ +	struct mpc85xx_gpio_data *data = dev_get_priv(dev); + +	return !!mpc85xx_gpio_open_drain_val(data->base, gpio_mask(gpio)); +} + +static int mpc85xx_gpio_set_open_drain(struct udevice *dev, unsigned gpio, +				       int value) +{ +	struct mpc85xx_gpio_data *data = dev_get_priv(dev); + +	if (value) { +		mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio)); +	} else { +		mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio)); +	} +	return 0; +} +  static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)  {  	struct mpc85xx_gpio_data *data = dev_get_priv(dev); @@ -168,6 +207,8 @@ static const struct dm_gpio_ops gpio_mpc85xx_ops = {  	.direction_output	= mpc85xx_gpio_direction_output,  	.get_value		= mpc85xx_gpio_get_value,  	.set_value		= mpc85xx_gpio_set_value, +	.get_open_drain		= mpc85xx_gpio_get_open_drain, +	.set_open_drain		= mpc85xx_gpio_set_open_drain,  	.get_function 		= mpc85xx_gpio_get_function,  }; | 
