[U-Boot] [PATCH V3] Davinci: add a pin multiplexer configuration API

Davinci: add a pin multiplexer configuration API.
Creates a method allowing pin settings to be logically grouped into data structure arrays and provids an API to configure the PINMUX settings to enable the relevant pin functions.
Signed-off-by: Nick Thompson nick.thompson@gefanuc.com --- Applies to: u-boot-ti
Changes from last patch: removed compiler warning (implicit type cast)
The PINMUXn definitions are already present in hardware.h.
The number of PINMUX fields per register and the width of the fields needs to be set per SoC. The initial settings are appropriate for at least DA8xx devices. These should be modified in misc.h to support other devices as required.
board/davinci/common/misc.c | 47 ++++++++++++++++++++++++++++++++++++++++++- board/davinci/common/misc.h | 12 +++++++++++ 2 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/board/davinci/common/misc.c b/board/davinci/common/misc.c index ffdc20b..9c05f3e 100644 --- a/board/davinci/common/misc.c +++ b/board/davinci/common/misc.c @@ -1,6 +1,7 @@ /* * Miscelaneous DaVinci functions. * + * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, nick.thompson@gefanuc.com * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net * Copyright (C) 2008 Lyrtech <www.lyrtech.com> * Copyright (C) 2004 Texas Instruments. @@ -27,7 +28,8 @@ #include <i2c.h> #include <net.h> #include <asm/arch/hardware.h> - +#include <asm/io.h> +#include "misc.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -109,3 +111,46 @@ void dv_configure_mac_address(uint8_t *rom_enetaddr) }
#endif /* DAVINCI_EMAC */ + +/* + * Change the setting of a pin multiplexer field. + * + * Takes an array of pinmux settings similar to: + * + * struct pinmux_config uart_pins[] = { + * { PINMUX8, 2, 7 }, + * { PINMUX9, 2, 0 } + * }; + * + * Stepping through the array, each PINMUXn register has the given value + * set in the pin mux field specified. + * + * The number of pins in the array must be passed (ARRAY_SIZE can provide + * this value conveniently). + * + * Returns 0 if all field numbers and values are in the correct range, + * else returns -1. + */ +int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins) +{ + int i; + + for (i = 0; i < n_pins; i++) { + int value = pins[i].value; + const int field = pins[i].field; + + if (field < PIN_MUX_NUM_FIELDS && + (value & ~PIN_MUX_FIELD_MASK) == 0) { + const int offset = field * PIN_MUX_FIELD_SIZE; + const dv_reg *mux = pins[i].mux; + const unsigned int mask = PIN_MUX_FIELD_MASK << offset; + + value <<= offset; + writel(value | (readl(mux) & (~mask)), mux); + } else { + return -1; + } + } + + return 0; +} diff --git a/board/davinci/common/misc.h b/board/davinci/common/misc.h index dc3cc41..f6d8b1b 100644 --- a/board/davinci/common/misc.h +++ b/board/davinci/common/misc.h @@ -22,8 +22,20 @@ #ifndef __MISC_H #define __MISC_H
+/* pin muxer definitions */ +#define PIN_MUX_NUM_FIELDS 8 /* Per register */ +#define PIN_MUX_FIELD_SIZE 4 /* n in bits */ +#define PIN_MUX_FIELD_MASK ((1 << PIN_MUX_FIELD_SIZE) - 1) + +/* pin definition */ +struct pinmux_config { + dv_reg *mux; /* Address of mux register */ + unsigned char value; /* Value to set in field */ + unsigned char field; /* field number */ +};
int dvevm_read_mac_address(uint8_t *buf); void dv_configure_mac_address(uint8_t *rom_enetaddr); +int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins);
#endif /* __MISC_H */

Nick Thompson wrote:
Davinci: add a pin multiplexer configuration API.
Creates a method allowing pin settings to be logically grouped into data structure arrays and provids an API to configure the PINMUX settings to enable the relevant pin functions.
Signed-off-by: Nick Thompson nick.thompson@gefanuc.com
Applies to: u-boot-ti
Changes from last patch: removed compiler warning (implicit type cast)
The PINMUXn definitions are already present in hardware.h.
The number of PINMUX fields per register and the width of the fields needs to be set per SoC. The initial settings are appropriate for at least DA8xx devices. These should be modified in misc.h to support other devices as required.
board/davinci/common/misc.c | 47 ++++++++++++++++++++++++++++++++++++++++++- board/davinci/common/misc.h | 12 +++++++++++ 2 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/board/davinci/common/misc.c b/board/davinci/common/misc.c index ffdc20b..9c05f3e 100644 --- a/board/davinci/common/misc.c +++ b/board/davinci/common/misc.c @@ -1,6 +1,7 @@ /*
- Miscelaneous DaVinci functions.
- Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, nick.thompson@gefanuc.com
- Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net
- Copyright (C) 2008 Lyrtech <www.lyrtech.com>
- Copyright (C) 2004 Texas Instruments.
@@ -27,7 +28,8 @@ #include <i2c.h> #include <net.h> #include <asm/arch/hardware.h>
+#include <asm/io.h> +#include "misc.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -109,3 +111,46 @@ void dv_configure_mac_address(uint8_t *rom_enetaddr) }
#endif /* DAVINCI_EMAC */
+/*
- Change the setting of a pin multiplexer field.
- Takes an array of pinmux settings similar to:
- struct pinmux_config uart_pins[] = {
- { PINMUX8, 2, 7 },
- { PINMUX9, 2, 0 }
Change to match lowercasing of next patches
- };
- Stepping through the array, each PINMUXn register has the given value
- set in the pin mux field specified.
- The number of pins in the array must be passed (ARRAY_SIZE can provide
- this value conveniently).
- Returns 0 if all field numbers and values are in the correct range,
- else returns -1.
- */
+int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins) +{
- int i;
It would be better if this loop was broken into an error checker and a mux setter.
If there is an error, the mux pins will be left half done.
- for (i = 0; i < n_pins; i++) {
int value = pins[i].value;
Why extend value with an int? better to use unsigned int.
const int field = pins[i].field;
if (field < PIN_MUX_NUM_FIELDS &&
(value & ~PIN_MUX_FIELD_MASK) == 0) {
const int offset = field * PIN_MUX_FIELD_SIZE;
const dv_reg *mux = pins[i].mux;
const unsigned int mask = PIN_MUX_FIELD_MASK << offset;
value <<= offset;
writel(value | (readl(mux) & (~mask)), mux);
} else {
return -1;
}
- }
- return 0;
+} diff --git a/board/davinci/common/misc.h b/board/davinci/common/misc.h index dc3cc41..f6d8b1b 100644 --- a/board/davinci/common/misc.h +++ b/board/davinci/common/misc.h @@ -22,8 +22,20 @@ #ifndef __MISC_H #define __MISC_H
+/* pin muxer definitions */ +#define PIN_MUX_NUM_FIELDS 8 /* Per register */ +#define PIN_MUX_FIELD_SIZE 4 /* n in bits */ +#define PIN_MUX_FIELD_MASK ((1 << PIN_MUX_FIELD_SIZE) - 1)
+/* pin definition */ +struct pinmux_config {
- dv_reg *mux; /* Address of mux register */
- unsigned char value; /* Value to set in field */
- unsigned char field; /* field number */
+};
int dvevm_read_mac_address(uint8_t *buf); void dv_configure_mac_address(uint8_t *rom_enetaddr); +int davinci_configure_pin_mux(const struct pinmux_config *pins, int n_pins);
#endif /* __MISC_H */
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
participants (2)
-
Nick Thompson
-
Tom