Chinaunix首页 | 论坛 | 博客
  • 博客访问: 451365
  • 博文数量: 150
  • 博客积分: 2706
  • 博客等级: 少校
  • 技术积分: 1200
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-09 11:41
文章分类

全部博文(150)

文章存档

2012年(7)

2011年(6)

2010年(68)

2009年(69)

我的朋友

分类: LINUX

2009-12-21 11:35:15

GPIO操作:
GPIO Read Mode
The programming sequence for reading input signals is as follows:
1. Configure IOMUX to select GPIO mode (via IOMUXC).
2. Configure the GPIO direction register (GDR) to input.
3. Read value from the data register or pad status register.

GPIO Write Mode
The programming sequence for driving output signals should be as follows:
1. Configure IOMUX to select GPIO mode (via IOMUXC).
2. Configure GPIO direction register (GDR) to output.
3. Write value to data register (DR).
 
Linux中的程序定义:
/*!
 * various IOMUX functions
 */
typedef enum iomux_pin_config {
 MUX_CONFIG_FUNC = 0, /*!< used as function */
 MUX_CONFIG_ALT1, /*!< used as alternate function 1 */
 MUX_CONFIG_ALT2, /*!< used as alternate function 2 */
 MUX_CONFIG_ALT3, /*!< used as alternate function 3 */
 MUX_CONFIG_ALT4, /*!< used as alternate function 4 */
 MUX_CONFIG_ALT5, /*!< used as alternate function 5 */
 MUX_CONFIG_ALT6, /*!< used as alternate function 6 */
 MUX_CONFIG_ALT7, /*!< used as alternate function 7 */
 MUX_CONFIG_SION = 0x1 << 4, /*!< used as LOOPBACK:MUX SION bit */
 MUX_CONFIG_GPIO = MUX_CONFIG_ALT5, /*!< used as GPIO */
} iomux_pin_cfg_t;

/*!
 * IOMUX register (base) addresses
 */
enum iomux_reg_addr {
 IOMUXGPR0 = IO_ADDRESS(IOMUXC_BASE_ADDR), /*!< General p urpose 0 */
 IOMUXGPR1 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004, /*!< General purpose 1 */
 IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + MUX_I_START, /*!< MUX control */
 IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_END, /*!< last MUX control register */
 IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START, /*!< Pad control */
 IOMUXSW_PAD_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_END, /*!< last Pad control register */
 IOMUXSW_INPUT_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + INPUT_CTL_START, /*!< input select register */
 IOMUXSW_INPUT_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + INPUT_CTL_END, /*!< last input select register */
};
 
[arch/arm/plat-mxc/gpio.c]
extern struct mxc_gpio_port mxc_gpio_ports[];
struct gpio_port {
 u32 num;  /*!< gpio port number */
 u32 base;  /*!< gpio port base VA */
#ifdef MXC_GPIO_SPLIT_IRQ_2
 u16 irq_0_15, irq_16_31;
#else
 u16 irq;  /*!< irq number to the core */
#endif
 u16 virtual_irq_start; /*!< virtual irq start number */
 u32 reserved_map; /*!< keep track of which pins are in use */
 u32 irq_is_level_map; /*!< if a pin's irq is level sensitive. default is edge */
 u32 suspend_wakeup;
 u32 saved_wakeup;
 spinlock_t lock; /*!< lock when operating on the port */
};
/*!
 * Number of GPIO port as defined in the IC Spec
 */
#define GPIO_PORT_NUM           3
static struct gpio_port gpio_port[GPIO_PORT_NUM];
 
[arch/arm/mach-mx35/devices.c]
struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
 {
  .num = 0,
  .base = IO_ADDRESS(GPIO1_BASE_ADDR), //#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) [include/asm-
arm/arch-mxc/mx35.h]
  .irq = MXC_INT_GPIO1,  //#define MXC_INT_GPIO1 52//[include/asm-arm/arch-mxc/mx35.h]
  .virtual_irq_start = MXC_GPIO_INT_BASE,   //#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES)  //64
  },
 {
  .num = 1,
  .base = IO_ADDRESS(GPIO2_BASE_ADDR),
  .irq = MXC_INT_GPIO2,
  .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN,
  },
 {
  .num = 2,
  .base = IO_ADDRESS(GPIO3_BASE_ADDR),
  .irq = MXC_INT_GPIO3,
  .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
  },
};
/*!
 * This function initializes the GPIO hardware and disables all the
 * interrupts. It registers functions for core interrupt handling code,
 * for irq-chip based architectures for each interrupt source.
 */
static int __init _mxc_gpio_init(void)
{
 int i;
 struct gpio_port *port;
 printk(KERN_INFO "MXC GPIO hardware\n");
 for (i = 0; i < GPIO_PORT_NUM; i++) {
  int j, gpio_count = GPIO_NUM_PIN;
  port = &gpio_port[i];
  port->base = mxc_gpio_ports[i].base;
  port->num = mxc_gpio_ports[i].num;
#ifdef MXC_GPIO_SPLIT_IRQ_2
  port->irq_0_15 = mxc_gpio_ports[i].irq_0_15;
  port->irq_16_31 = mxc_gpio_ports[i].irq_16_31;
#else
  port->irq = mxc_gpio_ports[i].irq;
#endif
  port->virtual_irq_start = mxc_gpio_ports[i].virtual_irq_start;
  port->reserved_map = 0;
  spin_lock_init(&port->lock);
  /* disable the interrupt and clear the status */
  __raw_writel(0, port->base + GPIO_IMR);
  __raw_writel(0xFFFFFFFF, port->base + GPIO_ISR);
  for (j = port->virtual_irq_start;
       j < port->virtual_irq_start + gpio_count; j++) {
   set_irq_chip(j, &gpio_irq_chip);
   set_irq_handler(j, handle_edge_irq);
   set_irq_flags(j, IRQF_VALID);
  }
#ifndef MXC_MUX_GPIO_INTERRUPTS
#ifdef MXC_GPIO_SPLIT_IRQ_2
  set_irq_chained_handler(port->irq_0_15, mxc_gpio_irq_handler);
  set_irq_data(port->irq_0_15, port);
  set_irq_chained_handler(port->irq_16_31, mxc_gpio_irq_handler);
  set_irq_data(port->irq_16_31, port);
#else
  set_irq_chained_handler(port->irq, mxc_gpio_irq_handler);
  set_irq_data(port->irq, port);
#endif
#endif
 }
#ifdef MXC_MUX_GPIO_INTERRUPTS
 set_irq_chained_handler(port->irq, mxc_gpio_mux_irq_handler);
 set_irq_data(mxc_gpio_ports[0].irq, gpio_port);
#endif
 return 0;
}
可以看出GPIO的设定形式如下:
 * -------------------------------------------------------------------
 * 31-29 | 28 - 24 |23 - 21| 20 - 10| 9 - 0
 * -------------------------------------------------------------------
 * IO_P  |  IO_I   | RSVD  | PAD_I | MUX_I
 * -------------------------------------------------------------------
在MX35平台上,其中IO_PORT代表的是3组GPIO之一,IO_I是GPIO Index(0~31), PAD_I与MUX_I跟IC_SPEC中的IOMUXC_SW_PAD_CTL_PAD_*与


int mxc_request_gpio(iomux_pin_name_t pin)
{
 struct gpio_port *port;
 u32 index, gpio = IOMUX_TO_GPIO(pin);

 if (check_gpio(gpio) < 0)
  return -EINVAL;

 port = get_gpio_port(gpio);
 index = GPIO_TO_INDEX(gpio);

 return _request_gpio(port, index);
}
_request_gpio的工作主要是检查相应的GPIO是否有在使用,若已经被占用(port->reserved_map & (1 << index)),就返回Error信息; 否则就标志占用:port->reserved_map |= (1 << index);


mxc_free_gpio做的事情跟mxc_request_gpio相反

 

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