imx233: add pinctrl debug code to track pin uses

Past development has proved that one can mistakely use
the same pin for two uses without noticing. Since this
causes extremely hard to find bugs, the infrastructure
will allow to register pin uses and panic when a conflict
is detected. The pinctrl debug now shows the pin uses
when its support is compiled in.

Change-Id: Idb2d5235ce09207d77aa474d6f158e72b933761a
This commit is contained in:
Amaury Pouly 2012-05-10 00:08:03 +02:00
parent d29a11b7a8
commit 645680d62b
13 changed files with 122 additions and 6 deletions

View file

@ -399,13 +399,25 @@ bool dbg_hw_info_pinctrl(void)
{ {
lcd_setfont(FONT_SYSFIXED); lcd_setfont(FONT_SYSFIXED);
#ifdef IMX233_PINCTRL_DEBUG
unsigned top_user = 0;
#endif
while(1) while(1)
{ {
int button = get_action(CONTEXT_STD, HZ / 10); int button = get_action(CONTEXT_STD, HZ / 10);
switch(button) switch(button)
{ {
case ACTION_STD_NEXT: case ACTION_STD_NEXT:
#ifdef IMX233_PINCTRL_DEBUG
top_user++;
break;
#endif
case ACTION_STD_PREV: case ACTION_STD_PREV:
#ifdef IMX233_PINCTRL_DEBUG
if(top_user > 0)
top_user--;
break;
#endif
case ACTION_STD_OK: case ACTION_STD_OK:
case ACTION_STD_MENU: case ACTION_STD_MENU:
lcd_setfont(FONT_UI); lcd_setfont(FONT_UI);
@ -418,6 +430,23 @@ bool dbg_hw_info_pinctrl(void)
lcd_clear_display(); lcd_clear_display();
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
lcd_putsf(0, i, "DIN%d = 0x%08x", i, imx233_get_gpio_input_mask(i, 0xffffffff)); lcd_putsf(0, i, "DIN%d = 0x%08x", i, imx233_get_gpio_input_mask(i, 0xffffffff));
#ifdef IMX233_PINCTRL_DEBUG
unsigned cur_line = 6;
unsigned last_line = lcd_getheight() / font_get(lcd_getfont())->height;
unsigned cur_idx = 0;
for(int bank = 0; bank < 4; bank++)
for(int pin = 0; pin < 32; pin++)
{
const char *owner = imx233_pinctrl_get_pin_use(bank, pin);
if(owner == NULL)
continue;
if(cur_idx++ >= top_user && cur_line < last_line)
lcd_putsf(0, cur_line++, "B%dP%02d %s", bank, pin, owner);
}
if(cur_idx < top_user)
top_user = cur_idx - 1;
#endif
lcd_update(); lcd_update();
yield(); yield();
} }

View file

@ -57,6 +57,8 @@ void imx233_i2c_init(void)
{ {
imx233_reset_block(&HW_I2C_CTRL0); imx233_reset_block(&HW_I2C_CTRL0);
/* setup pins (must be done when shutdown) */ /* setup pins (must be done when shutdown) */
imx233_pinctrl_acquire_pin(0, 30, "i2c");
imx233_pinctrl_acquire_pin(0, 31, "i2c");
imx233_set_pin_function(0, 30, PINCTRL_FUNCTION_MAIN); imx233_set_pin_function(0, 30, PINCTRL_FUNCTION_MAIN);
imx233_set_pin_function(0, 31, PINCTRL_FUNCTION_MAIN); imx233_set_pin_function(0, 31, PINCTRL_FUNCTION_MAIN);
/* clear softreset */ /* clear softreset */

View file

@ -63,6 +63,7 @@ int mmc_init(void)
#ifdef SANSA_FUZEPLUS #ifdef SANSA_FUZEPLUS
/** Sansa Fuze+ has an internal eMMC 8-bit wide flash, power gate is pin PWM3 /** Sansa Fuze+ has an internal eMMC 8-bit wide flash, power gate is pin PWM3
* and power up time is 20ms */ * and power up time is 20ms */
imx233_pinctrl_acquire_pin(1, 29, "emmc power");
imx233_set_pin_function(1, 29, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 29, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(1, 29, true); imx233_enable_gpio_output(1, 29, true);
imx233_set_gpio_output(1, 29, false); imx233_set_gpio_output(1, 29, false);

View file

@ -21,8 +21,47 @@
#include "system.h" #include "system.h"
#include "system-target.h" #include "system-target.h"
#include "cpu.h" #include "cpu.h"
#include "string.h"
#include "pinctrl-imx233.h" #include "pinctrl-imx233.h"
#ifdef IMX233_PINCTRL_DEBUG
// 4 banks of 32 pins
static const char *pin_use[4][32];
void imx233_pinctrl_acquire_pin(unsigned bank, unsigned pin, const char *name)
{
if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name)
panicf("acquire B%dP%02d for %s, was %s!", bank, pin, name, pin_use[bank][pin]);
pin_use[bank][pin] = name;
}
void imx233_pinctrl_acquire_pin_mask(unsigned bank, uint32_t mask, const char *name)
{
for(unsigned pin = 0; pin < 32; pin++)
if(mask & (1 << pin))
imx233_pinctrl_acquire_pin(bank, pin, name);
}
void imx233_pinctrl_release_pin(unsigned bank, unsigned pin, const char *name)
{
if(pin_use[bank][pin] != NULL && pin_use[bank][pin] != name)
panicf("release B%dP%02d for %s: was %s!", bank, pin, name, pin_use[bank][pin]);
pin_use[bank][pin] = NULL;
}
void imx233_pinctrl_release_pin_mask(unsigned bank, uint32_t mask, const char *name)
{
for(unsigned pin = 0; pin < 32; pin++)
if(mask & (1 << pin))
imx233_pinctrl_release_pin(bank, pin, name);
}
const char *imx233_pinctrl_get_pin_use(unsigned bank, unsigned pin)
{
return pin_use[bank][pin];
}
#endif
static pin_irq_cb_t pin_cb[3][32]; /* 3 banks, 32 pins/bank */ static pin_irq_cb_t pin_cb[3][32]; /* 3 banks, 32 pins/bank */
static void INT_GPIO(int bank) static void INT_GPIO(int bank)

View file

@ -23,7 +23,10 @@
#ifndef __PINCTRL_IMX233_H__ #ifndef __PINCTRL_IMX233_H__
#define __PINCTRL_IMX233_H__ #define __PINCTRL_IMX233_H__
#include "cpu.h" #include "config.h"
// set to debug pinctrl use
#define IMX233_PINCTRL_DEBUG
#define HW_PINCTRL_BASE 0x80018000 #define HW_PINCTRL_BASE 0x80018000
@ -51,6 +54,20 @@
#define PINCTRL_DRIVE_12mA 2 #define PINCTRL_DRIVE_12mA 2
#define PINCTRL_DRIVE_16mA 3 /* not available on all pins */ #define PINCTRL_DRIVE_16mA 3 /* not available on all pins */
#ifdef IMX233_PINCTRL_DEBUG
void imx233_pinctrl_acquire_pin(unsigned bank, unsigned pin, const char *name);
void imx233_pinctrl_acquire_pin_mask(unsigned bank, uint32_t mask, const char *name);
void imx233_pinctrl_release_pin(unsigned bank, unsigned pin, const char *name);
void imx233_pinctrl_release_pin_mask(unsigned bank, uint32_t mask, const char *name);
const char *imx233_pinctrl_get_pin_use(unsigned bank, unsigned pin);
#else
#define imx233_pinctrl_acquire_pin(...)
#define imx233_pinctrl_acquire_pin_mask(...)
#define imx233_pinctrl_release_pin(...)
#define imx233_pinctrl_release_pin_mask(...)
#define imx233_pinctrl_get_pin_use(...) NULL
#endif
typedef void (*pin_irq_cb_t)(int bank, int pin); typedef void (*pin_irq_cb_t)(int bank, int pin);
static inline void imx233_pinctrl_init(void) static inline void imx233_pinctrl_init(void)

View file

@ -114,6 +114,7 @@ void power_off(void)
sleep(HZ / 2); sleep(HZ / 2);
#ifdef SANSA_FUZEPLUS #ifdef SANSA_FUZEPLUS
/* This pin seems to be important to shutdown the hardware properly */ /* This pin seems to be important to shutdown the hardware properly */
imx233_pinctrl_acquire_pin(0, 9, "power off");
imx233_set_pin_function(0, 9, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 9, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(0, 9, true); imx233_enable_gpio_output(0, 9, true);
imx233_set_gpio_output(0, 9, true); imx233_set_gpio_output(0, 9, true);

View file

@ -41,6 +41,7 @@ void _backlight_set_brightness(int brightness)
bool _backlight_init(void) bool _backlight_init(void)
{ {
imx233_pinctrl_acquire_pin(1, 28, "backlight");
imx233_set_pin_function(1, 28, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 28, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_drive_strength(1, 28, PINCTRL_DRIVE_8mA); imx233_set_pin_drive_strength(1, 28, PINCTRL_DRIVE_8mA);
imx233_enable_gpio_output(1, 28, true); imx233_enable_gpio_output(1, 28, true);

View file

@ -301,7 +301,8 @@ void button_init_device(void)
* The B0P26 line seems to be related to the touchpad * The B0P26 line seems to be related to the touchpad
*/ */
/* touchpad CE ? */ /* touchpad power */
imx233_pinctrl_acquire_pin(0, 26, "touchpad power");
imx233_set_pin_function(0, 26, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 26, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(0, 26, false); imx233_enable_gpio_output(0, 26, false);
imx233_set_pin_drive_strength(0, 26, PINCTRL_DRIVE_8mA); imx233_set_pin_drive_strength(0, 26, PINCTRL_DRIVE_8mA);
@ -324,10 +325,12 @@ void button_init_device(void)
create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0, create_thread(rmi_thread, rmi_stack, sizeof(rmi_stack), 0,
rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU)); rmi_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
/* enable interrupt */ /* enable interrupt */
imx233_pinctrl_acquire_pin(0, 27, "touchpad int");
imx233_set_pin_function(0, 27, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 27, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(0, 27, false); imx233_enable_gpio_output(0, 27, false);
imx233_setup_pin_irq(0, 27, true, true, false, &rmi_attn_cb); imx233_setup_pin_irq(0, 27, true, true, false, &rmi_attn_cb);
/* Volume down */ /* Volume down */
imx233_pinctrl_acquire_pin(1, 30, "volume down");
imx233_set_pin_function(1, 30, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 30, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(1, 30, false); imx233_enable_gpio_output(1, 30, false);
} }
@ -336,6 +339,10 @@ void button_init_device(void)
void button_init_device(void) void button_init_device(void)
{ {
/* Volume down */
imx233_pinctrl_acquire_pin(1, 30, "volume down");
imx233_set_pin_function(1, 30, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(1, 30, false);
} }
int touchpad_read_device(void) int touchpad_read_device(void)

View file

@ -87,6 +87,8 @@ struct i2c_interface fmradio_i2c =
void fmradio_i2c_init(void) void fmradio_i2c_init(void)
{ {
imx233_pinctrl_acquire_pin(1, 24, "fmradio i2c");
imx233_pinctrl_acquire_pin(1, 22, "fmradio i2c");
imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 24, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(1, 22, PINCTRL_FUNCTION_GPIO);
fmradio_i2c_bus = i2c_add_node(&fmradio_i2c); fmradio_i2c_bus = i2c_add_node(&fmradio_i2c);

View file

@ -56,6 +56,13 @@ static void setup_lcd_pins(bool use_lcdif)
/* WARNING /* WARNING
* the B1P22 and B1P24 pins are used by the tuner i2c! Do NOT drive * the B1P22 and B1P24 pins are used by the tuner i2c! Do NOT drive
* them as lcd_dotclk and lcd_hsync or it will break the tuner! */ * them as lcd_dotclk and lcd_hsync or it will break the tuner! */
imx233_pinctrl_acquire_pin(1, 18, "lcd reset");
imx233_pinctrl_acquire_pin(1, 19, "lcd rs");
imx233_pinctrl_acquire_pin(1, 20, "lcd wr");
imx233_pinctrl_acquire_pin(1, 21, "lcd cs");
imx233_pinctrl_acquire_pin(1, 23, "lcd enable");
imx233_pinctrl_acquire_pin(1, 25, "lcd vsync");
imx233_pinctrl_acquire_pin_mask(1, 0x3ffff, "lcd data");
if(use_lcdif) if(use_lcdif)
{ {
imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */ imx233_set_pin_function(1, 25, PINCTRL_FUNCTION_GPIO); /* lcd_vsync */
@ -71,7 +78,7 @@ static void setup_lcd_pins(bool use_lcdif)
else else
{ {
__REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */ __REG_SET(HW_PINCTRL_MUXSEL(2)) = 0xffffffff; /* lcd_d{0-15} */
imx233_enable_gpio_output_mask(1, 0x3ffffff, false); /* lcd_{d{0-17},reset,rs,wr,cs,dotclk,enable,hsync,vsync} */ imx233_enable_gpio_output_mask(1, 0x2bfffff, false); /* lcd_{d{0-17},reset,rs,wr,cs,enable,vsync} */
imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */ imx233_set_pin_function(1, 16, PINCTRL_FUNCTION_GPIO); /* lcd_d16 */
imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */ imx233_set_pin_function(1, 17, PINCTRL_FUNCTION_GPIO); /* lcd_d17 */
imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */ imx233_set_pin_function(1, 19, PINCTRL_FUNCTION_GPIO); /* lcd_rs */

View file

@ -33,6 +33,7 @@ bool tuner_power(bool enable)
if(enable != tuner_enable) if(enable != tuner_enable)
{ {
/* CE is B029 (active high) */ /* CE is B029 (active high) */
imx233_pinctrl_acquire_pin(0, 29, "tuner power");
imx233_set_pin_function(0, 29, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 29, PINCTRL_FUNCTION_GPIO);
imx233_set_pin_drive_strength(0, 29, PINCTRL_DRIVE_4mA); imx233_set_pin_drive_strength(0, 29, PINCTRL_DRIVE_4mA);
imx233_enable_gpio_output(0, 29, enable); imx233_enable_gpio_output(0, 29, enable);

View file

@ -64,6 +64,7 @@ void sd_power(bool on)
{ {
#ifdef SANSA_FUZEPLUS #ifdef SANSA_FUZEPLUS
/* The Fuze+ uses pin B0P8 for whatever reason, power ? */ /* The Fuze+ uses pin B0P8 for whatever reason, power ? */
imx233_pinctrl_acquire_pin(0, 8, "sd power");
imx233_set_pin_function(0, 8, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(0, 8, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(0, 8, true); imx233_enable_gpio_output(0, 8, true);
imx233_set_gpio_output(0, 8, !on); imx233_set_gpio_output(0, 8, !on);

View file

@ -150,12 +150,15 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
/* SSP_{CMD,SCK} */ /* SSP_{CMD,SCK} */
imx233_set_pin_drive_strength(2, 0, drive_strength); imx233_set_pin_drive_strength(2, 0, drive_strength);
imx233_set_pin_drive_strength(2, 6, drive_strength); imx233_set_pin_drive_strength(2, 6, drive_strength);
imx233_pinctrl_acquire_pin(2, 0, "ssp1 cmd");
imx233_pinctrl_acquire_pin(2, 6, "ssp1 sck");
imx233_set_pin_function(2, 0, PINCTRL_FUNCTION_MAIN); imx233_set_pin_function(2, 0, PINCTRL_FUNCTION_MAIN);
imx233_set_pin_function(2, 6, PINCTRL_FUNCTION_MAIN); imx233_set_pin_function(2, 6, PINCTRL_FUNCTION_MAIN);
imx233_enable_pin_pullup(2, 0, enable_pullups); imx233_enable_pin_pullup(2, 0, enable_pullups);
/* SSP_DATA{0-3} */ /* SSP_DATA{0-3} */
for(unsigned i = 0; i < MIN(bus_width, 4); i++) for(unsigned i = 0; i < MIN(bus_width, 4); i++)
{ {
imx233_pinctrl_acquire_pin(2, 2 + i, "ssp1 data");
imx233_set_pin_drive_strength(2, 2 + i, drive_strength); imx233_set_pin_drive_strength(2, 2 + i, drive_strength);
imx233_set_pin_function(2, 2 + i, PINCTRL_FUNCTION_MAIN); imx233_set_pin_function(2, 2 + i, PINCTRL_FUNCTION_MAIN);
imx233_enable_pin_pullup(2, 2 + i, enable_pullups); imx233_enable_pin_pullup(2, 2 + i, enable_pullups);
@ -166,12 +169,14 @@ void imx233_ssp_setup_ssp1_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
{ {
if(use_alt) if(use_alt)
{ {
imx233_pinctrl_acquire_pin(0, 22 + i, "ssp1 data");
imx233_set_pin_drive_strength(0, 22 + i, drive_strength); imx233_set_pin_drive_strength(0, 22 + i, drive_strength);
imx233_set_pin_function(0, 22 + i, PINCTRL_FUNCTION_ALT2); imx233_set_pin_function(0, 22 + i, PINCTRL_FUNCTION_ALT2);
imx233_enable_pin_pullup(0, 22 + i, enable_pullups); imx233_enable_pin_pullup(0, 22 + i, enable_pullups);
} }
else else
{ {
imx233_pinctrl_acquire_pin(0, 4 + i, "ssp1 data");
imx233_set_pin_drive_strength(0, 4 + i, drive_strength); imx233_set_pin_drive_strength(0, 4 + i, drive_strength);
imx233_set_pin_function(0, 4 + i, PINCTRL_FUNCTION_ALT2); imx233_set_pin_function(0, 4 + i, PINCTRL_FUNCTION_ALT2);
imx233_enable_pin_pullup(0, 4 + i, enable_pullups); imx233_enable_pin_pullup(0, 4 + i, enable_pullups);
@ -183,6 +188,8 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
unsigned drive_strength) unsigned drive_strength)
{ {
/* SSP_{CMD,SCK} */ /* SSP_{CMD,SCK} */
imx233_pinctrl_acquire_pin(0, 20, "ssp2 cmd");
imx233_pinctrl_acquire_pin(0, 24, "ssp2 sck");
imx233_set_pin_drive_strength(0, 20, drive_strength); imx233_set_pin_drive_strength(0, 20, drive_strength);
imx233_set_pin_drive_strength(0, 24, drive_strength); imx233_set_pin_drive_strength(0, 24, drive_strength);
imx233_set_pin_function(0, 20, PINCTRL_FUNCTION_ALT2); imx233_set_pin_function(0, 20, PINCTRL_FUNCTION_ALT2);
@ -191,13 +198,13 @@ void imx233_ssp_setup_ssp2_sd_mmc_pins(bool enable_pullups, unsigned bus_width,
/* SSP_DATA{0-7}*/ /* SSP_DATA{0-7}*/
for(unsigned i = 0; i < bus_width; i++) for(unsigned i = 0; i < bus_width; i++)
{ {
imx233_pinctrl_acquire_pin(0, i, "ssp2 data");
imx233_set_pin_drive_strength(0, i, drive_strength); imx233_set_pin_drive_strength(0, i, drive_strength);
imx233_set_pin_function(0, i, PINCTRL_FUNCTION_ALT2); imx233_set_pin_function(0, i, PINCTRL_FUNCTION_ALT2);
imx233_enable_pin_pullup(0, i, enable_pullups); imx233_enable_pin_pullup(0, i, enable_pullups);
imx233_enable_gpio_output(0, i, false);
imx233_set_gpio_output(0, i, false);
} }
imx233_enable_gpio_output_mask(0, 0x11000ff, false);
imx233_set_gpio_output_mask(0, 0x11000ff, false);
} }
void imx233_ssp_set_mode(int ssp, unsigned mode) void imx233_ssp_set_mode(int ssp, unsigned mode)
@ -348,6 +355,7 @@ void imx233_ssp_sdmmc_setup_detect(int ssp, bool enable, ssp_detect_cb_t fn, boo
ssp_detect_cb[ssp - 1] = fn; ssp_detect_cb[ssp - 1] = fn;
if(enable) if(enable)
{ {
imx233_pinctrl_acquire_pin(bank, pin, ssp == 1 ? "ssp1 detect" : "ssp2 detect");
imx233_set_pin_function(bank, pin, PINCTRL_FUNCTION_GPIO); imx233_set_pin_function(bank, pin, PINCTRL_FUNCTION_GPIO);
imx233_enable_gpio_output(bank, pin, false); imx233_enable_gpio_output(bank, pin, false);
} }