Pic Usb Driver


chacali

Still Fresh
Joined
Jan 28, 2008
Messages
8
Hello :lol:

I just wrote a driver for my usb device. I tested it on fedora 3 and it works. Now I want to compile it for gp2x and I don"t know how. On my gp2x, the 2.0.0 kernel version is installed.

Here is the driver source code (It is based on Greg Kroah-Hartman source code):

#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG 1
#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>


#define DRIVER_AUTHOR "SAKALI Hadi, hsakali@ulb.ac.be"
#define DRIVER_DESC "USB PIC Driver"

#define VENDOR_ID 0x04D8
#define PRODUCT_ID 0x0004

/* Tables des peripheriques fonctionnant avec ce driver */
static struct usb_device_id id_table [] = {
{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
{ },
};
MODULE_DEVICE_TABLE (usb, id_table);

struct usb_pic {
struct usb_device* udev;
unsigned char red;
unsigned char blue;
};

#define NONE 0xAA
#define RED 0xBB
#define BLUE 0xCC
#define BOTH 0xDD

static void change_color(struct usb_pic *pic)
{
int retval;
unsigned char color = 0x00;
unsigned char *buffer;

buffer = kmalloc(2, GFP_KERNEL);
if (!buffer) {
dev_err(&pic->udev->dev, "Memoire saturee\n");
return;
}

if (!pic->red && !pic->blue)
{
color = NONE;
retval = usb_control_msg(pic->udev, //Pointeur vers le peripherique USB
usb_sndctrlpipe(pic->udev, 0), //EndPoint de destination
color, //Requete
0xc0, //Type de Requete
0x00, //Valeur
0x00, //Index
buffer, //Donnees
2, //Taille en bytes
2 * HZ); //Timeout
}
else if (pic->red && !pic->blue)
{
color = RED;
retval = usb_control_msg(pic->udev, //Pointeur vers le peripherique USB
usb_sndctrlpipe(pic->udev, 0), //EndPoint de destination
color, //Requete
0xc0, //Type de Requete
0x00, //Valeur
0x00, //Index
buffer, //Donnees
2, //Taille en bytes
2 * HZ); //Timeout
}
else if (!pic->red && pic->blue)
{
color = BLUE;
retval = usb_control_msg(pic->udev, //Pointeur vers le peripherique USB
usb_sndctrlpipe(pic->udev, 0), //EndPoint de destination
color, //Requete
0xc0, //Type de Requete
0x00, //Valeur
0x00, //Index
buffer, //Donnees
2, //Taille en bytes
2 * HZ); //Timeout
}
else if (pic->red && pic->blue)
{
color = BOTH;
retval = usb_control_msg(pic->udev, //Pointeur vers le peripherique USB
usb_sndctrlpipe(pic->udev, 0), //EndPoint de destination
color, //Requete
0xc0, //Type de Requete
0x00, //Valeur
0x00, //Index
buffer, //Donnees
2, //Taille en bytes
2 * HZ); //Timeout
}


dev_dbg(&pic->udev->dev,
"red = %d, blue = %d, color = %.2x\n",
led->red, led->blue, color);


if (retval)
dev_dbg(&pic->udev->dev, "retval = %d\n", retval);
kfree(buffer);
}

#define show_set(value) \
static ssize_t show_##value(struct device *dev, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct usb_pic *pic = usb_get_intfdata(intf); \
\
return sprintf(buf, "%d\n", pic->value); \
} \
static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \
{ \
struct usb_interface *intf = to_usb_interface(dev); \
struct usb_pic *pic = usb_get_intfdata(intf); \
int temp = simple_strtoul(buf, NULL, 10); \
\
pic->value = temp; \
change_color(pic); \
return count; \
} \
static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
show_set(red);
show_set(blue);

static int pic_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_pic *dev = NULL;
int retval = -ENOMEM;

dev = kmalloc(sizeof(struct usb_pic), GFP_KERNEL);
if (dev == NULL) {
dev_err(&interface->dev, "Out of memory\n");
goto error;
}
memset (dev, 0x00, sizeof (*dev));

dev->udev = usb_get_dev(udev);

usb_set_intfdata (interface, dev);

device_create_file(&interface->dev, &dev_attr_red);
device_create_file(&interface->dev, &dev_attr_blue);

dev_info(&interface->dev, "USB LED device now attached\n");
return 0;

error:
kfree(dev);
return retval;
}

static void pic_disconnect(struct usb_interface *interface)
{
struct usb_pic *dev;

dev = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL);

device_remove_file(&interface->dev, &dev_attr_red);
device_remove_file(&interface->dev, &dev_attr_blue);

usb_put_dev(dev->udev);

kfree(dev);

dev_info(&interface->dev, "PIC USB deconnecte\n");
}

static struct usb_driver pic_driver = {
.owner = THIS_MODULE,
.name = "usbpic",
.probe = pic_probe,
.disconnect = pic_disconnect,
.id_table = id_table,
};

static int __init usb_pic_init(void)
{
int retval = 0;

retval = usb_register(&pic_driver);
if (retval)
err("usb_register a echouee. Erreur numero %d", retval);
return retval;
}

static void __exit usb_pic_exit(void)
{
usb_deregister(&pic_driver);
};

module_init (usb_pic_init);
module_exit (usb_pic_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");




And here the makefile:


ifneq ($(KERNELRELEASE),)
obj-m := pic.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif


I can't say if the makefile will remain the same or if it ll need modifications.

Is it possible to integrate a module for a usb device using "insmod" command on the gp2x? If it is, do I have to upgrade to a newer version of the firware (3.0.0 ???)? If not, is it possible to manually compile a kernel to get it work ?

If anyone have a clue.

:lol: .: Thank you :. :lol:
 
Back
Top