5 =>
(S3C2410_GPIO_A_START + S3C2410_GPIO_A_NR + CONFIG_S3C_GPIO_SPACE + 0) + 5 =>
ºÜÏÔÈ»£¬ S3C2410_GPB(5)¾ÍÊÇ´ÓGPAµÄÊ×µØÖ·+GPA¸öÊý+GPBµÄoffset¾ÍÊǵ±Ç°GPBµÄIOÆ«ÒÆÁ¿£¬¼´
0+32+5=37, ͬÀí
S3C2410_GPB(0) Ï൱ÓÚ 32
30 S3C2410_GPB(5) Ï൱ÓÚ 37
31 S3C2410_GPB(6) Ï൱ÓÚ 38
32 S3C2410_GPB(7) Ï൱ÓÚ 39
33 S3C2410_GPB(8) Ï൱ÓÚ 40
***************************************************************************
led_cfg_table[i]
36 //LED ¶ÔÓ¦¶Ë¿Ú½«ÒªÊä³öµÄ״̬Áбí
37 static unsigned int led_cfg_table [] = {
38 S3C2410_GPIO_OUTPUT,
39 S3C2410_GPIO_OUTPUT,
40 S3C2410_GPIO_OUTPUT,
41 S3C2410_GPIO_OUTPUT,
42 };
S3C2410_GPIO_OUTPUT¶¨ÒåÔÚmach/regs-gpio.h
#define S3C2410_GPIO_LEAVE (0xFFFFFFFF) // ×îºóÁ½Î»ÊÇÉèÖã¬11±íʾRESERVE
#define S3C2410_GPIO_INPUT (0xFFFFFFF0) /* not available on A */ // ×îºóÁ½Î»ÊÇÉèÖã¬00±íʾINPUT
#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1) // ×îºóÁ½Î»ÊÇÉèÖã¬01±íʾOUTPUT
#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */
#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* bank A => addr/cs/nand */
#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
***************************************************************************
¸ù¾ÝÇ°ÃæµÄ·ÖÎö£¬s3c2410´«ÈëÁ˵±Ç°GPIOµÄÆ«ÒÆµØÖ·£¬ÒÔ¼°OUTPUT״̬
ÏÖÔÚÎÒÃÇÉîÈëÇ°ÃæµÄÁ½¸öº¯Êý£º
¶¨ÒåÔÚlinux/arch/arm/plat-s3c/gpio-config.c
int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
{
struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin); //µÃµ½¶ÔÓ¦GPIO½á¹¹ÌåÊ×Ö¸Õ룬ÀïÃæ°üº¬Á˸ÃGPIOµÄ¸÷ÖÖ²ÎÊý
unsigned long flags;
int offset;
int ret;
if (!chip)
return -EINVAL; // ûÕÒµ½µÄ»°£¬·µ»Øinvalid
offset = pin - chip->chip.base; // ·ñÔòoffsetµÈÓÚ¸ÃGPIOÒý½ÅÏà¶ÔÓÚGPX£¨0£©µÄÆ«ÒÆÁ¿£¬Ã¿¸öÆ«ÒÆ1
s3c_gpio_lock(chip, flags); // ×ÔÐýËøËø×¡¸ÃGPIO£¬Í¨¹ýchipÖ¸ÕëÖ¸Ïòlock,¿´ÏÂÃæµÄdefineºÍͼ
ret = s3c_gpio_do_setcfg(chip, offset, config); //ÉèÖøÃGPIO״̬¼Ä´æÆ÷µÄÊýֵΪconfig
s3c_gpio_unlock(chip, flags); // ½âËø
// ×ÔÐýËø²Ù×÷
/* locking wrappers to deal with multiple access to the same gpio bank */
//#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
//#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
//s3c_gpio_do_setcfg²Ù×÷
static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
unsigned int off, unsigned int config)
{
return (chip->config->set_config)(chip, off, config);
}
//ÕâÀïµÄset_configÊÇÒ»¸öº¯ÊýÖ¸Õ룬ÓɺóÃæµÄ·ÖÎöÖªµÀ£¬Èç¹ûÕë¶ÔGPA,¸Ãº¯ÊýÖ¸ÕëÖ¸Ïòs3c_gpio_setcfg_s3c24xx_a , Èç¹ûÕë¶ÔGPXÓ¦¸ÃÊÇÖ¸Ïòs3c_gpio_setcfg_s3c24xx¡ª¡ªµ«·¢ÏÖ£¬Èç¹ûÊÇÆäËûGPX£¬¸ù±¾Ã»Óж¨Òåset_config!!! £¨Õâ¸öÎÊÌâÒѾ½â¾ö£¬¼ûºóÎÄs3c24xx_gpiolib_initº¯Êý£¬ÊÂʵÉÏ£¬ÆäÓàµÄconfigµÄÈ·Ö¸Ïòs3c_gpio_do_setcfgº¯Êý£©
struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
.set_config = s3c_gpio_setcfg_s3c24xx,
.get_config = s3c_gpio_getcfg_s3c24xx,
};
int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip, unsigned int off, unsigned int cfg)
{
void __iomem *reg = chip->base; // GPXCONµÄÎïÀí»ùµØÖ·
unsigned int shift = off; // ÿ¸öGPA¶ÔӦһλ
u32 con;
if (s3c_gpio_is_cfg_special(cfg)) { //OUTPUT״̬ÊÇ·ñΪ(0xfffffffX)£¬ÊÇ£¬·µ»Ø1
cfg &= 0xf; // cfg = 0xX
/* Map output to 0, and SFN2 to 1 */ ±¾ÊµÑé²»»áÔËÐе½Õâ
cfg -= 1;
if (cfg > 1)
return -EINVAL;
cfg <<= shift;
}
con = __raw_readl(reg); // ÏȶÁ³ö¸ÃGPXCONµÄÖµ£¬32λ
con &= ~(0x1 << shift); //
con |= cfg; //
__raw_writel(con, reg); // ½«ÐÂֵдÈëGPXCON
PS:
#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
#define _