florianscholz icon

airsensor.c

florianscholz | PRO | 05/16/17 04:49:38 PM UTC | 0 ⭐ | 187 👁️ | Never ⏰ | []
C |

4.57 KB

|

None

|

0 👍

/

0 👎

/************************************************************************/
/* Kerneltreiber fuer den Luftqualitaetsstick                           */
/* Im Rahmen der Veranstaltung Embedded Systems bei Juergen Quade       */
/* Copyright (c) 2017 Florian Scholz                                    */
/*                                                                      */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or    */
/* (at your option) any later version.                                  */
/*                                                                      */
/* This program is distributed in the hope that it will be useful,      */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         */
/* GNU General Public License for more details.                         */
/*                                                                      */
/************************************************************************/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
 
#define USB_VENDOR_ID 0x03eb
#define USB_DEVICE_ID 0x2013
 
struct usb_device *dev;
static DEFINE_MUTEX( ulock );
 
static short airsensorfs_read_sensor_value( void );
 
static ssize_t airsensorfs_read( struct file *instanz, char *buffer,
    size_t count, loff_t *ofs )
{
    char pbuf[20];
 
    short value;
 
    value = airsensorfs_read_sensor_value();
    int cnt = snprintf(pbuf, count, "%d\n", value);
 
    
    count -= copy_to_user(buffer,pbuf,cnt);
    *ofs += count;
    return count;
}
 
 
static short airsensorfs_read_sensor_value() {
    char buf[1000];
    int rcvd_bytes, retval;
    short value;
    memcpy(buf, "\x40\x68\x2a\x54\x52\x0a\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40", 0x0000010);
    mutex_lock(&ulock);
    retval = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x2), buf, 0x10, &rcvd_bytes, 1000);
    if(retval != 0)
    {
        printk("airsensorfs: couldn't send write request inital\n");
    }
 
    retval = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x81), buf, 0x10, &rcvd_bytes, 1000);
    if(retval != 0)
    {
        printk("airsensorfs: failed to read data\n");
    }
 
 
    retval = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x81), buf, 0x10, &rcvd_bytes, 1000);
    if(retval != 0)
    {
        printk("airsensorfs: failed to read remaining data\n");
    }
    mutex_unlock(&ulock);
    memcpy(&value, buf+2,2);
 
    return value;
}
 
static int airsensorfs_open( struct inode *devicefile, struct file *instanz )
{
    return 0;
}
 
static struct file_operations usb_fops = {
    .owner = THIS_MODULE,
    .open  = airsensorfs_open,
    .read  = airsensorfs_read,
};
 
static struct usb_device_id usbid [] = {
    { USB_DEVICE(USB_VENDOR_ID, USB_DEVICE_ID), },
    { }                 /* Terminating entry */
};
 
struct usb_class_driver class_descr = {
    .name = "airsensorfs",
    .fops = &usb_fops,
    .minor_base = 16,
};
 
static int airsensorfs_probe(struct usb_interface *interface,
    const struct usb_device_id *id)
{
    dev = interface_to_usbdev(interface);
    printk("airsensorfs driver by florian scholz: 0x%4.4x|0x%4.4x, if=%p\n", dev->descriptor.idVendor,
        dev->descriptor.idProduct, interface );
    if (dev->descriptor.idVendor==USB_VENDOR_ID
        && dev->descriptor.idProduct==USB_DEVICE_ID) {
        if (usb_register_dev( interface, &class_descr )) {
            return -EIO;
        }
        printk("got minor= %d\n", interface->minor );
 
 
 
        char buf[1000];
        int rcvd_bytes;
        int retval = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x81), buf, 0x10, &rcvd_bytes, 1000);
        if(retval != 0)
        {
            printk("airsensorfs: failed to read remaining data\n");
 
            return 0;
        }
 
    }
    
 
    return -ENODEV;
}
 
static void airsensorfs_disconnect( struct usb_interface *iface )
{
    mutex_lock( &ulock );
    usb_deregister_dev( iface, &class_descr );
    mutex_unlock( &ulock );
}
 
static struct usb_driver airsensorfs = {
    .name= "airsensorfs",
    .id_table= usbid,
    .probe= airsensorfs_probe,
    .disconnect= airsensorfs_disconnect,
};
 
static int __init airsensorfs_init(void)
{
    if (usb_register(&airsensorfs) ) {
        printk("airsensorfs: unable to register usb driver\n");
        return -EIO;
    }
    else
    {
        printk("airsensorfs: registered usb driver\n");
    }
    return 0;
}
 
static void __exit airsensorfs_exit(void)
{
    usb_deregister(&airsensorfs);   
}
 
module_init(airsensorfs_init);
module_exit(airsensorfs_exit);
MODULE_LICENSE( "GPL" );

Comments