Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1153015
  • 博文数量: 222
  • 博客积分: 5262
  • 博客等级: 大校
  • 技术积分: 3028
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-22 19:10
文章分类

全部博文(222)

文章存档

2012年(2)

2011年(192)

2010年(28)

分类: 嵌入式

2011-05-11 15:46:29

接着上篇的分析,首先追踪下源码:arch/arm/mach-mx27/mx27ads_gpio.c

gpio_sensor_active -> gpio_request_mux -> gpio_config_mux

gpio_config_mux用于完成相应pin需要模式的配置:

  gpio_config_mux - just configure the mode of the gpio pin.
  pin   a pin number as defined in \b #iomux_pin_name_t
  mode  a module as define in \b #gpio_mux_mode_t;
 * GPIO_MUX_PRIMARY set pin to work as primary function.
 * GPIO_MUX_ALT set pin to work as alternate function.
 * GPIO_MUX_GPIO set pin to work as output function based the data register
 * GPIO_MUX_INPUT1 set pin to work as input function connected with  A_OUT
 * GPIO_MUX_INPUT2 set pin to work as input function connected with B_OUT
 * GPIO_MUX_OUTPUT1 set pin to work as output function connected with A_IN
 * GPIO_MUX_OUTPUT2 set pin to work as output function connected with B_IN
 * GPIO_MUX_OUTPUT3 set pin to work as output function connected with C_IN
       0 if successful, Non-zero otherwise
 */

int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
{
 unsigned long lock_flags;
 u32 gius_reg, gpr_reg;
 struct mxc_gpio_port *port;
 u32 index, gpio = IOMUX_TO_GPIO(pin);

 port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
 index = GPIO_TO_INDEX(gpio);

首先定义了一个端口结构体mxc_gpio_port,其中包含了一个端口所必须的信息:

struct mxc_gpio_port {
 u32 num;  /*!< gpio port number */
 u32 base;  /*!< gpio port base VA */
 u16 irq;  /*!< irq number to the core */
 u16 virtual_irq_start; /*!< virtual irq start number */
};

通过IOMUX_TO_GPIO函数找到对应pin的GPIO索引。

再看port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
其中mxc_gpio_ports为gpio端口列表,如下:

struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
 {
  .num = 0,
  .base = IO_ADDRESS(GPIO_BASE_ADDR),
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE,
  },
 {
  .num = 1,
  .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x100,
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN,
  },
 {
  .num = 2,
  .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x200,
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 2,
  },
 {
  .num = 3,
  .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x300,
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 3,
  },
 {
  .num = 4,
  .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x400,
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 4,
  },
 {
  .num = 5,
  .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x500,
  .irq = INT_GPIO,
  .virtual_irq_start = MXC_GPIO_BASE + GPIO_NUM_PIN * 5,
  },
};

通过GPIO_TO_PORT找到对应pin的端口号,然后用端口列表找到对应端口的相应信息。

index = GPIO_TO_INDEX(gpio);

用于找到对应端口的引脚。这里有个个人理解,index为GPIO模块中对应端口中的引脚,而参数pin是mx27芯片所有管脚中的索引。

继续看源码:

 pr_debug("%s: Configuring PORT %c, bit %d\n",__FUNCTION__, port->num + 'A', index);

 spin_lock_irqsave(&gpio_mux_lock, lock_flags);    //保存终端状态

 gius_reg = __raw_readl(port->base + GPIO_GIUS); 
 gpr_reg = __raw_readl(port->base + GPIO_GPR);

 这两句主要定位需要的寄存器。

继续源码:

 switch (mode) {
 case GPIO_MUX_PRIMARY:
  gius_reg &= ~(1L << index);
  gpr_reg &= ~(1L << index);
  break;
 case GPIO_MUX_ALT:
  gius_reg &= ~(1L << index);
  gpr_reg |= (1L << index);
  break;
 case GPIO_MUX_GPIO:
  gius_reg |= (1L << index);
  _gpio_set_ocr(port, index, GPIO_OUTPUT_DR);
  break;
 case GPIO_MUX_INPUT1:
  gius_reg |= (1L << index);
  _gpio_set_iconfa(port, index, GPIO_INPUT_GPIO);
  break;
 case GPIO_MUX_INPUT2:
  gius_reg |= (1L << index);
  _gpio_set_iconfb(port, index, GPIO_INPUT_GPIO);
  break;
 case GPIO_MUX_OUTPUT1:
  gius_reg |= (1L << index);
  _gpio_set_ocr(port, index, GPIO_OUTPUT_A);
  break;
 case GPIO_MUX_OUTPUT2:
  gius_reg |= (1L << index);
  _gpio_set_ocr(port, index, GPIO_OUTPUT_B);
  break;
 case GPIO_MUX_OUTPUT3:
  gius_reg |= (1L << index);
  _gpio_set_ocr(port, index, GPIO_OUTPUT_C);
  break;
 default:
  spin_unlock_irqrestore(&gpio_mux_lock, lock_flags);
  return -1;
 }

以上根据传入的不同mode,进行设置。

 __raw_writel(gius_reg, port->base + GPIO_GIUS);
 __raw_writel(gpr_reg, port->base + GPIO_GPR);  //写入寄存器

 spin_unlock_irqrestore(&gpio_mux_lock, lock_flags);  //恢复终端状态
 return 0;

}

the reserved bits (unimplemented GPIO bits)

阅读(2142) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~