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 0D
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:
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 0D
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: