Driver concept changed to use a user-space helper app

master
Stefan Krulj 14 years ago
parent 87e2b07f5a
commit 4c5e1b78d2
  1. 9
      Makefile
  2. 16
      Makefile.helper
  3. 120
      ftdi_daemon.c
  4. 35
      ftdi_daemon.h
  5. 14
      usb_gpio.c
  6. 1
      usb_gpio.h

@ -2,9 +2,11 @@ modname := usb_gpio
obj-m := $(modname).o
DEFINES := -DDEBUG
ccflags-y= $(DEFINES)
ccflags-y= $(DEFINES) -I/usr/include/
KVERSION := $(shell uname -r)
KMACHINE := $(shell uname -m)
KDIR := /lib/modules/$(KVERSION)/build
PWD := "$$(pwd)"
@ -13,8 +15,13 @@ default:
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
$(MAKE) -f Makefile.helper clean
rm -rf *~
load:
-/sbin/rmmod $(modname)
/sbin/insmod $(modname).ko
helper:
$(MAKE) -f Makefile.helper

@ -0,0 +1,16 @@
OBJS = ftdi_daemon.o
CC=gcc
CFLAGS =
LDFLAGS = -lftdi
usbgpiod: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -Wa,-a=$*.list -c -o $@ $<
clean:
rm -rf $(OBJS) usbgpiod
rm -rf *.list *~

@ -0,0 +1,120 @@
#include "ftdi_daemon.h"
struct ftdi_context ftdic;
uint8_t USB_GPIO_DDR;
uint8_t USB_GPIO_PORT;
uint8_t USB_GPIO_PIN;
volatile uint8_t main_loop=1;
static int vendor=0x0403, device=0x6001;
static int is_output(unsigned offset){
return !!((USB_GPIO_DDR)&(1<<offset));
}
static int is_high(unsigned offset){
return !!((USB_GPIO_PORT)&(1<<offset));
}
static int update_mode(void){
if( ftdi_set_bitmode(&ftdic, USB_GPIO_DDR, BITMODE_BITBANG)<0 ){
printf("%s: Can't enter FTDIs bitbang mode (%04x:%04x)!\n",MOD_NAME,vendor,device);
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
return -EIO;
}
return 0;
}
static int get_value(unsigned offset){
DEBUG_OUT("%s: GET_VALUE of pin%d ",MOD_NAME,offset);
if( !is_output(offset) ){
while( ftdic.readbuffer_remaining > 0 ){
if( ftdi_read_data(&ftdic,&USB_GPIO_PIN,1) < 0){
printf("%s: Unable to read pin%d \n",MOD_NAME,offset);
}
}
return !!((USB_GPIO_PIN) & (1<<offset));
}
return 0;
}
static void set_value(unsigned offset, int value){
DEBUG_OUT("%s: SET_VALUE of pin%d to %d",MOD_NAME,offset,value);
if( !is_output(offset) ){
if(value && !is_high(offset)){
if( ftdi_write_data(&ftdic,&USB_GPIO_PORT,1) < 0){
printf("%s: Unable to set pin%d to value %d\n",MOD_NAME,offset,value);
}
}else if(!value && is_high(offset)){
if( ftdi_write_data(&ftdic,&USB_GPIO_PORT,1) < 0){
printf("%s: Unable to set pin%d to value %d\n",MOD_NAME,offset,value);
}
}
}
}
static int set_in(unsigned offset){
DEBUG_OUT("%s: SET_INPUT of pin%d ",MOD_NAME,offset);
USB_GPIO_DDR &= ~(1<<offset);
return update_mode();
}
static int set_out(unsigned offset, int value){
DEBUG_OUT("%s: SET_OUTPUT of pin%d to %d",MOD_NAME,offset,value);
USB_GPIO_DDR |= (1<<offset);
return update_mode();
}
static int ftdi_chip_init(){
// Init FTDI lib
if( ftdi_init(&ftdic)<0 ){
printf("%s: Can't initialize FTDI-lib!\n",MOD_NAME);
return ENOMEM;
}
// Open device
if(ftdi_usb_open(&ftdic, vendor, device)<0) {
printf("%s: Can't open FTDI chip (%04x:%04x)!\n",MOD_NAME,vendor,device);
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
return ENXIO;
}
// Put device into bitbang modes
if( ftdi_set_bitmode(&ftdic, 0x00, BITMODE_BITBANG)<0 ){
printf("%s: Can't enter FTDIs bitbang mode (%04x:%04x)!\n",MOD_NAME,vendor,device);
printf("%s: %s\n",MOD_NAME,ftdi_get_error_string(&ftdic));
return EIO;
}
//All pins input
USB_GPIO_DDR = 0x00;
//No port set
USB_GPIO_PORT = 0x00;
return 0;
}
static void ftdi_chip_exit(){
if( ftdi_disable_bitbang(&ftdic)<0 ){
printf("%s: Can't reset FTDI (%04x:%04x)!\n",MOD_NAME,vendor,device);
}
}
int main(void){
int ret=ftdi_chip_init();
if(ret!=0){
return ret;
}
for(;main_loop;){
//Sleep mostly
}
ftdi_chip_exit();
return 0;
}

@ -0,0 +1,35 @@
#ifndef _FTDL_DAEMON_H
#define _FTDL_DAEMON_H
#include <ftdi.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>
#define MOD_NAME "usb_gpio"
#ifdef DEBUG
#define DEBUG_OUT(FMT,...) printk(FMT, ## __VA_ARGS__)
#else
#define DEBUG_OUT(FMT,...) {}
#endif
#define PIN_TX 0
#define PIX_RX 1
#define PIN_RTS 2
#define PIN_CTS 3
#define PIN_DTR 4
#define PIN_DSR 5
#define PIN_DCD 6
#define PIN_RI 7
#define PIN_0 0
#define PIN_1 1
#define PIN_2 2
#define PIN_3 3
#define PIN_4 4
#define PIN_5 5
#define PIN_6 6
#define PIN_7 7
#endif //_FTDL_DAEMON_H

@ -5,12 +5,20 @@ static struct gpio_chip ft232_chip;
#include "gpio_callbacks.c"
static void usb_gpio_exit(void) {
gpiochip_remove(&ft232_chip);
if( gpiochip_remove(&ft232_chip)<0 ){
printk("<1>%s: Couldn't free GPIO-pins!\n",MOD_NAME);
}
printk("<1>%s: Bye!\n",MOD_NAME);
}
static int usb_gpio_init(void) {
int ret;
// Prepare user space handler call
char *argv[] = { "/usr/bin/logger", "help!", NULL };
static char *envp[] = {
"HOME=/",
"TERM=linux",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };
printk("<1>%s: Loading... \n",MOD_NAME);
@ -35,7 +43,9 @@ static int usb_gpio_init(void) {
if (ret){
printk("<1>%s: Can't register chip!\n",MOD_NAME);
}
return ret;
//Call the user space handler
return call_usermodehelper( argv[0], argv, envp, UMH_WAIT_PROC );
}
module_init(usb_gpio_init);

@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/slab.h> /* kmalloc() */
#include <linux/gpio.h>
#include <linux/kmod.h>
#include "usb_gpio_util.h"

Loading…
Cancel
Save