commit
5ca0397034
@ -0,0 +1,20 @@ |
||||
modname := usb_gpio
|
||||
obj-m := $(modname).o
|
||||
|
||||
DEFINES := -DDEBUG
|
||||
ccflags-y= $(DEFINES)
|
||||
|
||||
KVERSION := $(shell uname -r)
|
||||
KDIR := /lib/modules/$(KVERSION)/build
|
||||
PWD := "$$(pwd)"
|
||||
|
||||
default: |
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean: |
||||
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||
rm -rf *~
|
||||
|
||||
load: |
||||
-/sbin/rmmod $(modname)
|
||||
/sbin/insmod $(modname).ko
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,20 @@ |
||||
|
||||
static int get_value(struct gpio_chip *gc, unsigned offset){ |
||||
DEBUG_OUT("<1>%s: GET_VALUE of pin%d ",MOD_NAME,offset); |
||||
return 0; |
||||
} |
||||
|
||||
static void set_value(struct gpio_chip *chip, unsigned offset, int value){ |
||||
DEBUG_OUT("<1>%s: SET_VALUE of pin%d to %d",MOD_NAME,offset,value); |
||||
} |
||||
|
||||
static int set_in(struct gpio_chip *chip, unsigned offset){ |
||||
DEBUG_OUT("<1>%s: SET_INPUT of pin%d ",MOD_NAME,offset); |
||||
return 0; |
||||
} |
||||
|
||||
static int set_out(struct gpio_chip *chip, unsigned offset, int value){ |
||||
DEBUG_OUT("<1>%s: SET_OUTPUT of pin%d to %d",MOD_NAME,offset,value); |
||||
return 0; |
||||
} |
||||
|
||||
@ -0,0 +1,90 @@ |
||||
#!/usr/bin/python |
||||
|
||||
import os,sys |
||||
|
||||
NL='\n' |
||||
|
||||
class GPIO: |
||||
EXPORT = '/sys/class/gpio/export' |
||||
UNEXPORT = '/sys/class/gpio/unexport' |
||||
EFILE = None |
||||
IN = 1 |
||||
OUT = 0 |
||||
## The constructor |
||||
# @param num The kernel id number of the GPIO pin |
||||
def __init__(self,num): |
||||
# type checks |
||||
if type(num)!=int: |
||||
raise ValueError('num should be int') |
||||
|
||||
# assignments |
||||
self.num=num |
||||
|
||||
# Try to open the gio control file |
||||
if GPIO.EFILE==None: |
||||
if !os.path.exists(GPIO.EXPORT): |
||||
raise IOError('file "'+GPIO.EXPORT+'" does not exist') |
||||
GPIO.EFILE=open(EXPORT,'wb') |
||||
|
||||
# enable GPIO pin |
||||
EFILE.write(str(num)+NL) |
||||
|
||||
self.path = '/sys/class/gpio/gpio' + str(num) |
||||
|
||||
if !os.path.exists(self.path): |
||||
raise IOError('directory "'+self.path+'" does not exist') |
||||
|
||||
# open the GPIOs value files |
||||
# as the directory was created I imply all of them exist |
||||
self.valuef = open(self.path+'/value','rwb') |
||||
self.directionf = open(self.path+'/direction','wb') |
||||
self.active_lowf = open( +'/active_low',,'wb') |
||||
self.edgef = open(self.path+'/edge',,'wb') |
||||
|
||||
set_direction(GPIO.IN) |
||||
self.value = False |
||||
|
||||
def _read_value(self): |
||||
tmp=self.valuef.read() |
||||
self.value = tmp=="1" |
||||
|
||||
def write_value(self,v): |
||||
if self.direction != GPIO.OUT: |
||||
return |
||||
self.value = not(v==0) |
||||
if self.value==0: |
||||
self.valuef.write('0') |
||||
elif self.value==1: |
||||
self.valuef.write('1') |
||||
else: |
||||
assert 0 |
||||
|
||||
def is_high(self): |
||||
if self.direction != GPIO.IN: |
||||
return False |
||||
self._read_value() |
||||
return self.value |
||||
|
||||
def set_direction(self,d): |
||||
if d==GPIO.IN: |
||||
self.directionf.write('in'+NL) |
||||
self.direction=GPIO.IN |
||||
elif d==GPIO.OUT: |
||||
self.directionf.write('out'+NL) |
||||
self.direction=GPIO.OUT |
||||
|
||||
## the destructor |
||||
def __del__(self): |
||||
if GPIO.EFILE!=None: |
||||
# free GPIO pin |
||||
# as the export path exists I imply unexport will also exist |
||||
tmpf = open(GPIO.UNEXPORT,'wb') |
||||
tmpf.write(str(self.num)+NL) |
||||
tmpf.close() |
||||
GPIO.EFILE.close() |
||||
|
||||
self.valuef.close() |
||||
self.directionf.close() |
||||
self.active_lowf.close() |
||||
self.edgef.close() |
||||
|
||||
@ -0,0 +1,43 @@ |
||||
#include "usb_gpio.h" |
||||
|
||||
static struct gpio_chip ft232_chip; |
||||
|
||||
#include "gpio_callbacks.c" |
||||
|
||||
static void usb_gpio_exit(void) { |
||||
gpiochip_remove(&ft232_chip); |
||||
printk("<1>%s: Bye!\n",MOD_NAME); |
||||
} |
||||
|
||||
static int usb_gpio_init(void) { |
||||
int ret; |
||||
|
||||
printk("<1>%s: Loading... \n",MOD_NAME); |
||||
|
||||
ft232_chip.label = MOD_NAME; |
||||
|
||||
//Callback functions
|
||||
ft232_chip.direction_input = set_in; |
||||
ft232_chip.direction_output = set_out; |
||||
ft232_chip.get = get_value; |
||||
ft232_chip.set = set_value; |
||||
|
||||
//Automaticaly choose GPIO numbers - manual seems not to be possible
|
||||
ft232_chip.base = -1;
|
||||
//Number of GPIO pins
|
||||
ft232_chip.ngpio = NUM_OF_GPIO; |
||||
//This indicates that get and set functions can sleep
|
||||
ft232_chip.can_sleep = 1; |
||||
ft232_chip.owner = THIS_MODULE; |
||||
|
||||
ret = gpiochip_add(&ft232_chip); |
||||
DEBUG_OUT("<1>%s: gpiochip_add returned %d\n",MOD_NAME,ret); |
||||
if (ret){ |
||||
printk("<1>%s: Can't register chip!\n",MOD_NAME); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
module_init(usb_gpio_init); |
||||
module_exit(usb_gpio_exit); |
||||
MODULE_LICENSE("Dual BSD/GPL"); |
||||
@ -0,0 +1,22 @@ |
||||
|
||||
#ifndef _USB_GPIO_H |
||||
#define _USB_GPIO_H |
||||
|
||||
|
||||
#include <linux/init.h> |
||||
#include <linux/module.h> |
||||
#include <linux/kernel.h> |
||||
#include <linux/slab.h> /* kmalloc() */ |
||||
#include <linux/gpio.h> |
||||
|
||||
|
||||
#include "usb_gpio_util.h" |
||||
|
||||
#define NUM_OF_GPIO 8 |
||||
#define MOD_NAME "usb_gpio" |
||||
|
||||
#ifndef CONFIG_GENERIC_GPIO |
||||
#error This module needs generic gpio support (CONFIG_GENERIC_GPIO) |
||||
#endif |
||||
|
||||
#endif //_USB_GPIO_H
|
||||
@ -0,0 +1,11 @@ |
||||
|
||||
#ifndef _USB_GPIO_UTIL |
||||
#define _USB_GPIO_UTIL |
||||
|
||||
#ifdef DEBUG |
||||
#define DEBUG_OUT(FMT,...) printk(FMT, ## __VA_ARGS__) |
||||
#else |
||||
#define DEBUG_OUT(FMT,...) {} |
||||
#endif |
||||
|
||||
#endif //_USB_GPIO_UTIL
|
||||
Loading…
Reference in new issue