DM365 应用层gpio控制

 

方法一:通过/sys/文件接口操作IO端口 ,转自CSDN。

gpio_operation 通过/sys/文件接口操作IO端口 GPIO到文件系统的映射

* 控制GPIO的目录位于/sys/class/gpio

* /sys/class/gpio/export文件用于通知系统需要导出控制的GPIO引脚编号

* /sys/class/gpio/unexport 用于通知系统取消导出

* /sys/class/gpio/gpiochipX目录保存系统中GPIO寄存器的信息,包括每个寄存器控制引脚的起始编号base,寄存器名称,引脚总数 导出一个引脚的操作步骤

* 首先计算此引脚编号,引脚编号 = 控制引脚的寄存器基数 + 控制引脚寄存器位数

* 向/sys/class/gpio/export写入此编号,比如12号引脚,在shell中可以通过以下命令实现,命令成功后生成/sys/class/gpio/gpio12目录,如果没有出现相应的目录,说明此引脚不可导出:

    echo 12 > /sys/class/gpio/export

* direction文件,定义输入输入方向,可以通过下面命令定义为输出

    echo out > direction

* direction接受的参数:in, out, high, low。high/low同时设置方向为输出,并将value设置为相应的1/0。

* value文件是端口的数值,为1或0.

    echo 1 > value

 此驱动位于:drivers/gpio/gpiolib.c,需要打开 CONFIG_GPIO_SYSFS 宏定义

                  

方法二:通过proc文件系统访问

/**********************  应用层 *******************************/

#define GIO_DEV_PATH "/proc/gio/"
#define GIO_MAX_ID (103)

int gio_getname( char *pName, int gio_id )
{
 if( gio_id < 0 || gio_id > GIO_MAX_ID )
 {
  printf("gio id = %d over range!!\n", gio_id);
  return -1;
 }

 sprintf( pName, GIO_DEV_PATH"gio%d", gio_id );

 return 0;
}

int gio_write( int gio_id , int IsOn)
{
 int  fd_gio = 0;
 char data[5];
 int  result = 0;
 char  dev_name[25];
 int  cnt = 0;

 /* Don't do anything on EVM */
 if( gio_id < 0 || gio_id > GIO_MAX_ID )
 {
  printf("gio id = %d over range!!\n", gio_id);
  return -1;
 }

 if( gio_getname(dev_name,gio_id) < 0 )
 {
  printf("gio get name error!!\n");
  return -1;
 }

 fd_gio = open(dev_name, O_RDWR);

 if( !fd_gio )
 {
  printf("open device error !! gio = %d\n", gio_id);
  goto GIO_QUIT;
 }

 if( IsOn == 1 )
 {
  for( cnt = 0 ; cnt < sizeof(data) ; cnt ++ )
  {
   data[cnt]='1';
  }
 }
 else if( IsOn == 0 )
 {
  for( cnt = 0 ; cnt < sizeof(data) ; cnt ++ )
  {
   data[cnt]='0';
  }

 }else{
  goto GIO_QUIT;
 }

 result = write(fd_gio,  data, 1);
 if( result <= 0 )
 {
  printf("write device error !! gio = %d\n", gio_id);
  close(fd_gio);
  goto GIO_QUIT;
 }

GIO_QUIT:
 if( fd_gio )
  close(fd_gio);

 return 0;
}

int gio_read( int gio_id )
{
 int  fd_gio = 0;
 char data[5];
 int  result = 0;
 char  dev_name[25];

 if( gio_id < 0 || gio_id > GIO_MAX_ID )
 {
  printf("gio id = %d over range!!\n", gio_id);
  return -1;
 }

 if(gio_getname(dev_name,gio_id) < 0 )
 {
  printf("gio get name error!!\n");
  return -1;
 }

 fd_gio = open(dev_name, O_RDWR);

 if( !fd_gio )
 {
  printf("open device error !! gio = %d\n", gio_id);
  return -1;
 }
 result = read(fd_gio,data,1);
 if( result <= 0 )
 {
  printf("read device error !! gio = %d\n", gio_id);
  close(fd_gio);
  return -1;
 }
 close(fd_gio);
 if( data[0] == '1')
 {
  return 1;
 }else{
  return 0;
 }

 return -1;
}

 

 

/********************** 驱动   *********************************/

/*
 * TI DaVinci GPIO Support
 *
 * Copyright (c) 2006 David Brownell
 * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/kernel.h>

#include <asm/arch/irqs.h>
#include <asm/arch/hardware.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
#include <linux/proc_fs.h>


/* If a new chip is added with number of GPIO greater than 128, please
   update DAVINCI_MAX_N_GPIO in include/asm-arm/arch-davinci/irqs.h */
#define DM646x_N_GPIO 48
#define DM644x_N_GPIO 71
#define DM3xx_N_GPIO 104

#if defined(CONFIG_ARCH_DAVINCI644x) || defined(CONFIG_ARCH_DAVINCI_DM357)
static DECLARE_BITMAP(dm644x_gpio_in_use, DM644x_N_GPIO);
struct gpio_bank gpio_bank_dm6446 = {
 .base  = DAVINCI_GPIO_BASE,
 .num_gpio = DM644x_N_GPIO,
 .irq_num = IRQ_DM644X_GPIOBNK0,
 .irq_mask = 0x1f,
 .in_use  = dm644x_gpio_in_use,
};
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM355
static DECLARE_BITMAP(dm355_gpio_in_use, DM3xx_N_GPIO);
struct gpio_bank gpio_bank_dm355 = {
 .base  = DAVINCI_GPIO_BASE,
 .num_gpio = DM3xx_N_GPIO,
 .irq_num = IRQ_DM355_GPIOBNK0,
 .irq_mask = 0x7f,
 .in_use  = dm355_gpio_in_use,
};
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM365
static DECLARE_BITMAP(dm365_gpio_in_use, DM3xx_N_GPIO);
struct gpio_bank gpio_bank_dm365 = {
 .base  = DAVINCI_GPIO_BASE,
 .num_gpio = DM3xx_N_GPIO,
 .irq_num = 0,
 .irq_mask = 0x7f,
 .in_use  = dm365_gpio_in_use,
};
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM646x
static DECLARE_BITMAP(dm646x_gpio_in_use, DM646x_N_GPIO);
struct gpio_bank gpio_bank_dm646x = {
 .base  = DAVINCI_GPIO_BASE,
 .num_gpio = DM646x_N_GPIO,
 .irq_num = IRQ_DM646X_GPIOBNK0,
 .irq_mask = 0x7,
 .in_use  = dm646x_gpio_in_use,
};
#endif

void davinci_gpio_init(void)
{
 struct gpio_bank *gpio_bank;

#if defined(CONFIG_ARCH_DAVINCI644x) || defined(CONFIG_ARCH_DAVINCI_DM357)
 if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm357())
  gpio_bank = &gpio_bank_dm6446;
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM355
 if (cpu_is_davinci_dm355())
  gpio_bank = &gpio_bank_dm355;
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM365
 if (cpu_is_davinci_dm365())
  gpio_bank = &gpio_bank_dm365;
#endif
#ifdef CONFIG_ARCH_DAVINCI_DM646x
 if (cpu_is_davinci_dm6467())
  gpio_bank = &gpio_bank_dm646x;
#endif
 if (!gpio_bank)
  BUG();

 davinci_gpio_irq_setup(gpio_bank);
}
#if CONFIG_PROC_FS

#define MAX_BUF  4*1024
#define DM3xx_N_MUX 5

static struct proc_dir_entry *gio_procdir;
static struct proc_dir_entry *gio_proc[DM3xx_N_GPIO];
static struct proc_dir_entry *gio_proc_mux[DM3xx_N_MUX];


static int proc_gio(char *page, char **start, off_t off,
      int count, int *eof, void *data)
{
 int len = 0;
 char buffer[MAX_BUF];
 volatile unsigned long *reg;

 if (!count)
  return 0;

 reg = (unsigned long *)IO_ADDRESS(DAVINCI_GPIO_BASE);
 len += sprintf(&buffer[len], "GPIO Module:\n");
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x PID                \n", reg,
      (int)reg[0]);
 reg += 2;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x BINTEN             \n", reg,
      (int)reg[0]);

 //BANK 0 AND BANK 1
 len += sprintf(&buffer[len], "GPIO Bank0 and Bank1:\n");
 reg = (unsigned long *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Direction          \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Output Data        \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Data           \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Input Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Rising edge   \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Rising edge \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Falling edge  \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Falling edge\n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Interrupt Status   \n", reg,
      (int)reg[0]);

 //BANK 2 AND BANK 3
 len += sprintf(&buffer[len], "GPIO Bank2 and Bank3:\n");
 reg = (unsigned long *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Direction          \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Output Data        \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Data           \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Input Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Rising edge   \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Rising edge \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Falling edge  \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Falling edge\n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Interrupt Status   \n", reg,
      (int)reg[0]);

 //BANK 4 AND BANK 5 for DM355 and BANK 4 for DM6446
 if (cpu_is_davinci_dm355())
  len += sprintf(&buffer[len], "GPIO Bank4 and Bank5:\n");
 else
  len += sprintf(&buffer[len], "GPIO Bank4:\n");
 reg = (unsigned long *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Direction          \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Output Data        \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Data           \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Input Data         \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Rising edge   \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Rising edge \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Set Falling edge  \n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Clear Falling edge\n", reg,
      (int)reg[0]);
 reg++;
 len +=
     sprintf(&buffer[len], "  0x%p: 0x%08x Interrupt Status   \n", reg,
      (int)reg[0]);

 //BANK 6
 if (cpu_is_davinci_dm355())
 {
  len += sprintf(&buffer[len], "GPIO Bank6:\n");
  reg = (unsigned long *)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Direction          \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Output Data        \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Set Data           \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Clear Data         \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Input Data         \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Set Rising edge   \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Clear Rising edge \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Set Falling edge  \n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Clear Falling edge\n", reg,
       (int)reg[0]);
  reg++;
  len +=
      sprintf(&buffer[len], "  0x%p: 0x%08x Interrupt Status   \n", reg,
       (int)reg[0]);
 }
 if (count > len)
  count = len;
 memcpy(page, &buffer[off], count);

 *eof = 1;
 *start = NULL;
 return len;
}

static int proc_gio_read(char *page, char **start, off_t off,
    int count, int *eof, void *data)
{
 int len;

 if (count == 0)
  return 0;

 gpio_direction_input((int)data);//gpio_set_direction((int)data, GIO_DIR_INPUT);
 len = sprintf(page, "%d\n", gpio_get_value((int)data));

 *eof = 1;
 *start = 0;

 return len;
}

static int proc_gio_write(struct file *file, const char __user * buffer,
     unsigned long count, void *data)
{
 int i;

 if (!count)
  return 0;

 //gpio_set_direction((int)data, GIO_DIR_OUTPUT);

 for (i = 0; i < count; i++) {
  if (buffer[i] == '0')
  {
   gpio_direction_output((int)data,0);//gpio_set_value((int)data, 0);
  }
  if (buffer[i] == '1')
  {
   gpio_direction_output((int)data,1);//gpio_set_value((int)data, 1);
  }
 }

 return count;
}


static int proc_mux_read(char *page, char **start, off_t off,
    int count, int *eof, void *data)
{
 int len;

 if (count == 0)
  return 0;

 len = sprintf(page, "0x%x\n", davinci_readl(PINMUX0+(u32)data));

 *eof = 1;
 *start = 0;

 return len;
}

static int proc_mux_write(struct file *file, const char __user * buffer,
     unsigned long count, void *data)
{
 int i;
 unsigned long val = 0;

 if (!count)
  return 0;
 
 val = simple_strtoul(buffer, NULL, 0);

 davinci_writel(val, PINMUX0+(u32)data);

 return count;
}


int __init gio_proc_client_create(void)
{
 int i;
 char name[16];
 struct proc_dir_entry *ent;
 u32 max_gpio = 0;

 /*if (cpu_is_davinci_dm355())
  max_gpio = DM355_NUM_GIOS;
 else if (cpu_is_davinci_dm6443())
  max_gpio = DM644x_NUM_GIOS;
 */
 max_gpio = DM3xx_N_GPIO;

 gio_procdir = proc_mkdir("gio", 0);
 if (gio_procdir == NULL) {
  printk(KERN_ERR "gio: failed to register proc directory gio\n");
  return -ENOMEM;
 }

 ent = create_proc_read_entry("registers", 0, gio_procdir, proc_gio, 0);
 if (ent == NULL) {
  printk(KERN_ERR
         "gio: failed to register proc device: registers\n");
  return -ENOMEM;
 }

 for (i = 0; i < max_gpio; i++) {
  sprintf(name, "gio%d", i);
  gio_proc[i] = create_proc_entry(name, 0, gio_procdir);
  if (gio_proc[i] == NULL) {
   printk(KERN_ERR
          "gio: failed to register proc device: %s\n",
          name);
   return -ENOMEM;
  }
  gio_proc[i]->data = (void *)i;
  gio_proc[i]->read_proc = proc_gio_read;
  gio_proc[i]->write_proc = proc_gio_write;
 }

 for (i = 0; i < DM3xx_N_MUX; i++) {
  sprintf(name, "pinmux%d", i);
  gio_proc_mux[i] = create_proc_entry(name, 0, gio_procdir);
  if (gio_proc_mux[i] == NULL) {
   printk(KERN_ERR
          "gio: failed to register proc device: %s\n",
          name);
   return -ENOMEM;
  }
  gio_proc_mux[i]->data = (void *)i;
  gio_proc_mux[i]->read_proc = proc_mux_read;
  gio_proc_mux[i]->write_proc = proc_mux_write;
 }

 

 return 0;
}

#else    /* CONFIG_PROC_FS */

#define gio_proc_client_create() do {} while(0);

#endif    /* CONFIG_PROC_FS */

module_init(gio_proc_client_create);

 

方法三:写个字符设备驱动,略

 

方法四:内存映射,略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值