|
|
|
@ -34,11 +34,13 @@ struct mpc85xx_gpio_data { |
|
|
|
|
uint gpio_count; |
|
|
|
|
/* The GPDAT register cannot be used to determine the value of output
|
|
|
|
|
* pins on MPC8572/MPC8536, so we shadow it and use the shadowed value |
|
|
|
|
* for output pins */ |
|
|
|
|
* for output pins |
|
|
|
|
*/ |
|
|
|
|
u32 dat_shadow; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
inline u32 gpio_mask(unsigned gpio) { |
|
|
|
|
inline u32 gpio_mask(uint gpio) |
|
|
|
|
{ |
|
|
|
|
return (1U << (31 - (gpio))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -92,7 +94,7 @@ static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base, |
|
|
|
|
clrbits_be32(&base->gpodr, gpios); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio) |
|
|
|
|
static int mpc85xx_gpio_direction_input(struct udevice *dev, uint gpio) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_data *data = dev_get_priv(dev); |
|
|
|
|
|
|
|
|
@ -100,8 +102,7 @@ static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio, |
|
|
|
|
int value) |
|
|
|
|
static int mpc85xx_gpio_set_value(struct udevice *dev, uint gpio, int value) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_data *data = dev_get_priv(dev); |
|
|
|
|
|
|
|
|
@ -115,46 +116,46 @@ static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio, |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_direction_output(struct udevice *dev, unsigned gpio, |
|
|
|
|
static int mpc85xx_gpio_direction_output(struct udevice *dev, uint gpio, |
|
|
|
|
int value) |
|
|
|
|
{ |
|
|
|
|
return mpc85xx_gpio_set_value(dev, gpio, value); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio) |
|
|
|
|
static int mpc85xx_gpio_get_value(struct udevice *dev, uint gpio) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_data *data = dev_get_priv(dev); |
|
|
|
|
|
|
|
|
|
if (!!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio))) { |
|
|
|
|
/* Output -> use shadowed value */ |
|
|
|
|
return !!(data->dat_shadow & gpio_mask(gpio)); |
|
|
|
|
} else { |
|
|
|
|
/* Input -> read value from GPDAT register */ |
|
|
|
|
return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Input -> read value from GPDAT register */ |
|
|
|
|
return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_get_open_drain(struct udevice *dev, unsigned gpio) |
|
|
|
|
static int mpc85xx_gpio_get_open_drain(struct udevice *dev, uint 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, |
|
|
|
|
static int mpc85xx_gpio_set_open_drain(struct udevice *dev, uint gpio, |
|
|
|
|
int value) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_data *data = dev_get_priv(dev); |
|
|
|
|
|
|
|
|
|
if (value) { |
|
|
|
|
if (value) |
|
|
|
|
mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio)); |
|
|
|
|
} else { |
|
|
|
|
else |
|
|
|
|
mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio) |
|
|
|
|
static int mpc85xx_gpio_get_function(struct udevice *dev, uint gpio) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_data *data = dev_get_priv(dev); |
|
|
|
|
int dir; |
|
|
|
@ -164,14 +165,15 @@ static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if CONFIG_IS_ENABLED(OF_CONTROL) |
|
|
|
|
static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) { |
|
|
|
|
static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) |
|
|
|
|
{ |
|
|
|
|
struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev); |
|
|
|
|
fdt_addr_t addr; |
|
|
|
|
fdt_size_t size; |
|
|
|
|
|
|
|
|
|
addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, |
|
|
|
|
dev_of_offset(dev), "reg", 0, &size, false); |
|
|
|
|
|
|
|
|
|
dev_of_offset(dev), |
|
|
|
|
"reg", 0, &size, false); |
|
|
|
|
plat->addr = addr; |
|
|
|
|
plat->size = size; |
|
|
|
|
plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), |
|
|
|
@ -229,7 +231,7 @@ static const struct dm_gpio_ops gpio_mpc85xx_ops = { |
|
|
|
|
.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, |
|
|
|
|
.get_function = mpc85xx_gpio_get_function, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static const struct udevice_id mpc85xx_gpio_ids[] = { |
|
|
|
|