kernel与用户层接口之proc接口
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/string.h>
#include <linux/uaccess.h> //copy_from_user
#define ENTRYNAME "n802"
static struct proc_dir_entry *proc_entry;
static char pin_name[32] = {0};
static char pin_pull[32] = {0};
/*
get pin level:
echo "g12 up" > /proc/n802
cat /proc/n802
*/
static int n802_read( char *page, char **start, off_t off, int count, int *eof, void *data )
{
int i;
char buf[64] = {0};
int len = 0;
int pin_level = 0;
int gpio_index = -1;
unsigned int pin_pull_val = GPIO_PULL_DISABLE;
gpio_index = find_mygpio(pin_name);
if ( -1 == gpio_index ) {
printk("Error: no found gpio(%s)\n", pin_name);
goto end_n802_read;
}
if ( NULL != strstr(pin_pull,"up") )
pin_pull_val = GPIO_PULLUP;
if ( NULL != strstr(pin_pull,"down") )
pin_pull_val = GPIO_PULLDOWN;
gpio_request(gpio_index,pin_name);
tcc_gpio_config(gpio_index, GPIO_FN(0)|pin_pull_val);
tcc_gpio_direction_input(gpio_index);
msleep(20);
pin_level = gpio_get_value(gpio_index);
sprintf(buf, "%s %d", pin_name, pin_level );
len = strlen(buf);
strcpy( page, (char*)buf);
printk("%s: pin_name=%s(%d) pin_level=%d\n", __FUNCTION__, pin_name, gpio_index,pin_level);
if (D>0){
printk("%s:\n", __FUNCTION__ );
for (i=0;i<len;i++)
printk("%02x ", buf[i] );
printk("\n");
printk("%s\n", buf);
}
end_n802_read:
return len;
}
/*
set pin level:
echo "g12 disable 1" > /proc/n802
echo "g12 up 1" > /proc/n802
echo "g12 down 1" > /proc/n802
*/
static int n802_write( struct file *filp, const char __user *buff, unsigned long len, void *data )
{
int i;
char *p = NULL;
char *p1 = NULL;
int pin_level = 0;
int is_set_pin_level = 0;
int gpio_index = -1;
char buf[64] = {0};
unsigned int pin_pull_val = GPIO_PULL_DISABLE;
memset( buf, 0, sizeof(buf) );
if (copy_from_user( buf, buff, len )) {
return -EFAULT;
}
if (D>0){
printk("%s: len=%d\n", __FUNCTION__, (int)len);
for (i=0;i<10;i++)
printk("%02x ", buf[i] );
printk("\n");
printk("%s\n", buf);
}
memset( pin_name, 0, sizeof(pin_name) );
memset( pin_pull, 0, sizeof(pin_pull) );
p1 = buf;
if ( NULL != (p = strchr(p1, ' ')) ) {
*p = 0;
strcpy(pin_name, p1);
p++;
p1 = p;
if ( NULL != (p = strchr(p1, ' ')) ) {
*p = 0;
strcpy(pin_pull, p1);
p++;
pin_level = simple_strtoul(p, NULL, 0);
is_set_pin_level = 1;
}else{
strcpy(pin_pull, p1);
if ( NULL != (p = strchr(pin_pull, '\n')))
*p = 0;
}
}
if ( NULL != strstr(pin_pull,"up") )
pin_pull_val = GPIO_PULLUP;
if ( NULL != strstr(pin_pull,"down") )
pin_pull_val = GPIO_PULLDOWN;
gpio_index = find_mygpio(pin_name);
if ( -1 == gpio_index ) {
printk("Error: no found gpio(%s)\n", pin_name);
goto end_n802_write;
}
if (is_set_pin_level ) {
printk("set pin_name=%s(%d) pin_pull=%s pin_level=%d\n", pin_name, gpio_index, pin_pull, pin_level);
gpio_request(gpio_index,pin_name);
tcc_gpio_config(gpio_index, GPIO_FN(0)|pin_pull_val);
gpio_direction_output(gpio_index,1);
gpio_set_value(gpio_index,pin_level);
}else{
printk("get pin_name=%s(%d) pin_pull=%s\n", pin_name, gpio_index, pin_pull);
}
end_n802_write:
return len;
}
static int __init n802_init(void)
{
printk("%s\n", __FUNCTION__);
proc_entry = create_proc_entry( ENTRYNAME, 0666, NULL );
if (proc_entry == NULL) {
printk(KERN_INFO "%s: Couldn't create proc entry\n", __FUNCTION__ );
return -ENOMEM;
}
proc_entry->write_proc = n802_write;
proc_entry->read_proc = n802_read;
}