Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 912b24c3 authored by Sean Young's avatar Sean Young Committed by Greg Kroah-Hartman
Browse files

USB: Put phidgets driver in a sysfs class



This patch creates a device class phidget and add the phidget drivers to 
them.

Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d5176b41
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -115,9 +115,16 @@ config USB_CYTHERM
	  To compile this driver as a module, choose M here: the
	  module will be called cytherm.

config USB_PHIDGET
	tristate "USB Phidgets drivers"
	depends on USB
	help
	  Say Y here to enable the various drivers for devices from
	  Phidgets inc.

config USB_PHIDGETKIT
	tristate "USB PhidgetInterfaceKit support"
	depends on USB
	depends on USB_PHIDGET
	help
	  Say Y here if you want to connect a PhidgetInterfaceKit USB device
	  from Phidgets Inc.
@@ -127,7 +134,7 @@ config USB_PHIDGETKIT

config USB_PHIDGETMOTORCONTROL
	tristate "USB PhidgetMotorControl support"
	depends on USB
	depends on USB_PHIDGET
	help
	  Say Y here if you want to connect a PhidgetMotorControl USB device
	  from Phidgets Inc.
@@ -137,7 +144,7 @@ config USB_PHIDGETMOTORCONTROL

config USB_PHIDGETSERVO
	tristate "USB PhidgetServo support"
	depends on USB
	depends on USB_PHIDGET
	help
	  Say Y here if you want to connect an 1 or 4 Motor PhidgetServo 
	  servo controller version 2.0 or 3.0.
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ obj-$(CONFIG_USB_LCD) += usblcd.o
obj-$(CONFIG_USB_LD)		+= ldusb.o
obj-$(CONFIG_USB_LED)		+= usbled.o
obj-$(CONFIG_USB_LEGOTOWER)	+= legousbtower.o
obj-$(CONFIG_USB_PHIDGET)	+= phidget.o
obj-$(CONFIG_USB_PHIDGETKIT)	+= phidgetkit.o
obj-$(CONFIG_USB_PHIDGETMOTORCONTROL)	+= phidgetmotorcontrol.o
obj-$(CONFIG_USB_PHIDGETSERVO)	+= phidgetservo.o
+43 −0
Original line number Diff line number Diff line
/*
 * USB Phidgets class
 *
 * Copyright (C) 2006  Sean Young <sean@mess.org>
 *
 * 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.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/device.h>

struct class *phidget_class;

static int __init init_phidget(void)
{
	phidget_class = class_create(THIS_MODULE, "phidget");

	if (IS_ERR(phidget_class))
		return PTR_ERR(phidget_class);

	return 0;
}

static void __exit cleanup_phidget(void)
{
	class_destroy(phidget_class);
}

EXPORT_SYMBOL_GPL(phidget_class);

module_init(init_phidget);
module_exit(cleanup_phidget);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sean Young <sean@mess.org>");
MODULE_DESCRIPTION("Container module for phidget class");
+12 −0
Original line number Diff line number Diff line
/*
 * USB Phidgets class
 *
 * Copyright (C) 2006  Sean Young <sean@mess.org>
 *
 * 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.
 */

extern struct class *phidget_class;
+145 −113
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
#include <linux/module.h>
#include <linux/usb.h>

#include "phidget.h"

#define DRIVER_AUTHOR "Sean Young <sean@mess.org>"
#define DRIVER_DESC "USB PhidgetInterfaceKit Driver"

@@ -57,11 +59,15 @@ ifkit(8, 8, 4, 0);
ifkit(0, 8, 8, 1);
ifkit(0, 16, 16, 0);

static unsigned long device_no;

struct interfacekit {
	struct usb_device *udev;
	struct usb_interface *intf;
	struct driver_interfacekit *ifkit;
	struct device *dev;
	unsigned long outputs;
	int dev_no;
	u8 inputs[MAX_INTERFACES];
	u16 sensors[MAX_INTERFACES];
	u8 lcd_files_on;
@@ -180,10 +186,11 @@ static int change_string(struct interfacekit *kit, const char *display, unsigned
}

#define set_lcd_line(number)	\
static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
static ssize_t lcd_line_##number(struct device *dev,			\
					struct device_attribute *attr,	\
					const char *buf, size_t count)	\
{									\
	struct usb_interface *intf = to_usb_interface(dev);				\
	struct interfacekit *kit = usb_get_intfdata(intf);				\
	struct interfacekit *kit = dev_get_drvdata(dev);		\
	change_string(kit, buf, number - 1);				\
	return count;							\
}									\
@@ -193,8 +200,7 @@ set_lcd_line(2);

static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct interfacekit *kit = usb_get_intfdata(intf);
	struct interfacekit *kit = dev_get_drvdata(dev);
	int enabled;
	unsigned char *buffer;
	int retval = -ENOMEM;
@@ -232,16 +238,15 @@ static void remove_lcd_files(struct interfacekit *kit)
{
	if (kit->lcd_files_on) {
		dev_dbg(&kit->udev->dev, "Removing lcd files\n");
		device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_1);
		device_remove_file(&kit->intf->dev, &dev_attr_lcd_line_2);
		device_remove_file(&kit->intf->dev, &dev_attr_backlight);
		device_remove_file(kit->dev, &dev_attr_lcd_line_1);
		device_remove_file(kit->dev, &dev_attr_lcd_line_2);
		device_remove_file(kit->dev, &dev_attr_backlight);
	}
}

static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	struct usb_interface *intf = to_usb_interface(dev);
	struct interfacekit *kit = usb_get_intfdata(intf);
	struct interfacekit *kit = dev_get_drvdata(dev);
	int enable;
	
	if (kit->ifkit->has_lcd == 0)
@@ -253,9 +258,9 @@ static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *att
	if (enable) {
		if (!kit->lcd_files_on) {
			dev_dbg(&kit->udev->dev, "Adding lcd files\n");
			device_create_file(&kit->intf->dev, &dev_attr_lcd_line_1);
			device_create_file(&kit->intf->dev, &dev_attr_lcd_line_2);
			device_create_file(&kit->intf->dev, &dev_attr_backlight);
			device_create_file(kit->dev, &dev_attr_lcd_line_1);
			device_create_file(kit->dev, &dev_attr_lcd_line_2);
			device_create_file(kit->dev, &dev_attr_backlight);
			kit->lcd_files_on = 1;
		}
	} else {
@@ -362,24 +367,24 @@ static void do_notify(void *data)
	for (i=0; i<kit->ifkit->inputs; i++) {
		if (test_and_clear_bit(i, &kit->input_events)) {
			sprintf(sysfs_file, "input%d", i + 1);
			sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
			sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
		}
	}

	for (i=0; i<kit->ifkit->sensors; i++) {
		if (test_and_clear_bit(i, &kit->sensor_events)) {
			sprintf(sysfs_file, "sensor%d", i + 1);
			sysfs_notify(&kit->intf->dev.kobj, NULL, sysfs_file);
			sysfs_notify(&kit->dev->kobj, NULL, sysfs_file);
		}
	}
}

#define show_set_output(value)		\
static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf,	\
							size_t count)	\
static ssize_t set_output##value(struct device *dev,			\
					struct device_attribute *attr,	\
					const char *buf, size_t count)	\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct interfacekit *kit = usb_get_intfdata(intf);		\
	struct interfacekit *kit = dev_get_drvdata(dev);		\
	int enabled;							\
	int retval;							\
									\
@@ -391,10 +396,11 @@ static ssize_t set_output##value(struct device *dev, struct device_attribute *at
	return retval ? retval : count;					\
}									\
									\
static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf)	\
static ssize_t show_output##value(struct device *dev, 			\
					struct device_attribute *attr,	\
					char *buf)			\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct interfacekit *kit = usb_get_intfdata(intf);		\
	struct interfacekit *kit = dev_get_drvdata(dev);		\
									\
	return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\
}									\
@@ -420,8 +426,7 @@ show_set_output(16);
#define show_input(value)	\
static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf)	\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct interfacekit *kit = usb_get_intfdata(intf);		\
	struct interfacekit *kit = dev_get_drvdata(dev);		\
									\
	return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]);	\
}									\
@@ -445,10 +450,11 @@ show_input(15);
show_input(16);

#define show_sensor(value)	\
static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf)	\
static ssize_t show_sensor##value(struct device *dev,			\
					struct device_attribute *attr,	\
					char *buf)			\
{									\
	struct usb_interface *intf = to_usb_interface(dev);		\
	struct interfacekit *kit = usb_get_intfdata(intf);		\
	struct interfacekit *kit = dev_get_drvdata(dev);		\
									\
	return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]);	\
}									\
@@ -471,6 +477,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
	struct interfacekit *kit;
	struct driver_interfacekit *ifkit;
	int pipe, maxp, rc = -ENOMEM;
	int bit, value;

	ifkit = (struct driver_interfacekit *)id->driver_info;
	if (!ifkit)
@@ -493,6 +500,7 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
	if (!kit)
		goto out;

	kit->dev_no = -1;
	kit->ifkit = ifkit;
	kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, SLAB_ATOMIC, &kit->data_dma);
	if (!kit->data)
@@ -513,73 +521,88 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic

	usb_set_intfdata(intf, kit);

        do {
                bit = find_first_zero_bit(&device_no, sizeof(device_no));
                value = test_and_set_bit(bit, &device_no);
        } while(value);
        kit->dev_no = bit;

        kit->dev = device_create(phidget_class, &kit->udev->dev, 0,
               		"interfacekit%d", kit->dev_no);
        if (IS_ERR(kit->dev)) {
                rc = PTR_ERR(kit->dev);
                kit->dev = NULL;
                goto out;
        }
	dev_set_drvdata(kit->dev, kit);

	if (usb_submit_urb(kit->irq, GFP_KERNEL)) {
		rc = -EIO;
		goto out;
	}

	if (ifkit->outputs >= 4) {
		device_create_file(&intf->dev, &dev_attr_output1);
		device_create_file(&intf->dev, &dev_attr_output2);
		device_create_file(&intf->dev, &dev_attr_output3);
		device_create_file(&intf->dev, &dev_attr_output4);
		device_create_file(kit->dev, &dev_attr_output1);
		device_create_file(kit->dev, &dev_attr_output2);
		device_create_file(kit->dev, &dev_attr_output3);
		device_create_file(kit->dev, &dev_attr_output4);
	}
	if (ifkit->outputs >= 8) {
		device_create_file(&intf->dev, &dev_attr_output5);
		device_create_file(&intf->dev, &dev_attr_output6);
		device_create_file(&intf->dev, &dev_attr_output7);
		device_create_file(&intf->dev, &dev_attr_output8);
		device_create_file(kit->dev, &dev_attr_output5);
		device_create_file(kit->dev, &dev_attr_output6);
		device_create_file(kit->dev, &dev_attr_output7);
		device_create_file(kit->dev, &dev_attr_output8);
	} 
	if (ifkit->outputs == 16) {
		device_create_file(&intf->dev, &dev_attr_output9);
		device_create_file(&intf->dev, &dev_attr_output10);
		device_create_file(&intf->dev, &dev_attr_output11);
		device_create_file(&intf->dev, &dev_attr_output12);
		device_create_file(&intf->dev, &dev_attr_output13);
		device_create_file(&intf->dev, &dev_attr_output14);
		device_create_file(&intf->dev, &dev_attr_output15);
		device_create_file(&intf->dev, &dev_attr_output16);
		device_create_file(kit->dev, &dev_attr_output9);
		device_create_file(kit->dev, &dev_attr_output10);
		device_create_file(kit->dev, &dev_attr_output11);
		device_create_file(kit->dev, &dev_attr_output12);
		device_create_file(kit->dev, &dev_attr_output13);
		device_create_file(kit->dev, &dev_attr_output14);
		device_create_file(kit->dev, &dev_attr_output15);
		device_create_file(kit->dev, &dev_attr_output16);
	}

	if (ifkit->inputs >= 4) {
		device_create_file(&intf->dev, &dev_attr_input1);
		device_create_file(&intf->dev, &dev_attr_input2);
		device_create_file(&intf->dev, &dev_attr_input3);
		device_create_file(&intf->dev, &dev_attr_input4);
		device_create_file(kit->dev, &dev_attr_input1);
		device_create_file(kit->dev, &dev_attr_input2);
		device_create_file(kit->dev, &dev_attr_input3);
		device_create_file(kit->dev, &dev_attr_input4);
	}
	if (ifkit->inputs >= 8) {
		device_create_file(&intf->dev, &dev_attr_input5);
		device_create_file(&intf->dev, &dev_attr_input6);
		device_create_file(&intf->dev, &dev_attr_input7);
		device_create_file(&intf->dev, &dev_attr_input8);
		device_create_file(kit->dev, &dev_attr_input5);
		device_create_file(kit->dev, &dev_attr_input6);
		device_create_file(kit->dev, &dev_attr_input7);
		device_create_file(kit->dev, &dev_attr_input8);
	}
	if (ifkit->inputs == 16) {
		device_create_file(&intf->dev, &dev_attr_input9);
		device_create_file(&intf->dev, &dev_attr_input10);
		device_create_file(&intf->dev, &dev_attr_input11);
		device_create_file(&intf->dev, &dev_attr_input12);
		device_create_file(&intf->dev, &dev_attr_input13);
		device_create_file(&intf->dev, &dev_attr_input14);
		device_create_file(&intf->dev, &dev_attr_input15);
		device_create_file(&intf->dev, &dev_attr_input16);
		device_create_file(kit->dev, &dev_attr_input9);
		device_create_file(kit->dev, &dev_attr_input10);
		device_create_file(kit->dev, &dev_attr_input11);
		device_create_file(kit->dev, &dev_attr_input12);
		device_create_file(kit->dev, &dev_attr_input13);
		device_create_file(kit->dev, &dev_attr_input14);
		device_create_file(kit->dev, &dev_attr_input15);
		device_create_file(kit->dev, &dev_attr_input16);
	}

	if (ifkit->sensors >= 4) {
		device_create_file(&intf->dev, &dev_attr_sensor1);
		device_create_file(&intf->dev, &dev_attr_sensor2);
		device_create_file(&intf->dev, &dev_attr_sensor3);
		device_create_file(&intf->dev, &dev_attr_sensor4);
		device_create_file(kit->dev, &dev_attr_sensor1);
		device_create_file(kit->dev, &dev_attr_sensor2);
		device_create_file(kit->dev, &dev_attr_sensor3);
		device_create_file(kit->dev, &dev_attr_sensor4);
	}
	if (ifkit->sensors >= 7) {
		device_create_file(&intf->dev, &dev_attr_sensor5);
		device_create_file(&intf->dev, &dev_attr_sensor6);
		device_create_file(&intf->dev, &dev_attr_sensor7);
		device_create_file(kit->dev, &dev_attr_sensor5);
		device_create_file(kit->dev, &dev_attr_sensor6);
		device_create_file(kit->dev, &dev_attr_sensor7);
	}
	if (ifkit->sensors == 8)
		device_create_file(&intf->dev, &dev_attr_sensor8);
		device_create_file(kit->dev, &dev_attr_sensor8);

	if (ifkit->has_lcd)
		device_create_file(&intf->dev, &dev_attr_lcd);
		device_create_file(kit->dev, &dev_attr_lcd);

	dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n",
			ifkit->sensors, ifkit->inputs, ifkit->outputs);
@@ -592,6 +615,11 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
			usb_free_urb(kit->irq);
		if (kit->data)
			usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma);
		if (kit->dev)
			device_unregister(kit->dev);
		if (kit->dev_no >= 0)
			clear_bit(kit->dev_no, &device_no);

		kfree(kit);
	}

@@ -614,72 +642,76 @@ static void interfacekit_disconnect(struct usb_interface *interface)
	cancel_delayed_work(&kit->do_notify);

	if (kit->ifkit->outputs >= 4) {
		device_remove_file(&interface->dev, &dev_attr_output1);
		device_remove_file(&interface->dev, &dev_attr_output2);
		device_remove_file(&interface->dev, &dev_attr_output3);
		device_remove_file(&interface->dev, &dev_attr_output4);
		device_remove_file(kit->dev, &dev_attr_output1);
		device_remove_file(kit->dev, &dev_attr_output2);
		device_remove_file(kit->dev, &dev_attr_output3);
		device_remove_file(kit->dev, &dev_attr_output4);
	}
	if (kit->ifkit->outputs >= 8) {
		device_remove_file(&interface->dev, &dev_attr_output5);
		device_remove_file(&interface->dev, &dev_attr_output6);
		device_remove_file(&interface->dev, &dev_attr_output7);
		device_remove_file(&interface->dev, &dev_attr_output8);
		device_remove_file(kit->dev, &dev_attr_output5);
		device_remove_file(kit->dev, &dev_attr_output6);
		device_remove_file(kit->dev, &dev_attr_output7);
		device_remove_file(kit->dev, &dev_attr_output8);
	}
	if (kit->ifkit->outputs == 16) {
		device_remove_file(&interface->dev, &dev_attr_output9);
		device_remove_file(&interface->dev, &dev_attr_output10);
		device_remove_file(&interface->dev, &dev_attr_output11);
		device_remove_file(&interface->dev, &dev_attr_output12);
		device_remove_file(&interface->dev, &dev_attr_output13);
		device_remove_file(&interface->dev, &dev_attr_output14);
		device_remove_file(&interface->dev, &dev_attr_output15);
		device_remove_file(&interface->dev, &dev_attr_output16);
		device_remove_file(kit->dev, &dev_attr_output9);
		device_remove_file(kit->dev, &dev_attr_output10);
		device_remove_file(kit->dev, &dev_attr_output11);
		device_remove_file(kit->dev, &dev_attr_output12);
		device_remove_file(kit->dev, &dev_attr_output13);
		device_remove_file(kit->dev, &dev_attr_output14);
		device_remove_file(kit->dev, &dev_attr_output15);
		device_remove_file(kit->dev, &dev_attr_output16);
	}

	if (kit->ifkit->inputs >= 4) {
		device_remove_file(&interface->dev, &dev_attr_input1);
		device_remove_file(&interface->dev, &dev_attr_input2);
		device_remove_file(&interface->dev, &dev_attr_input3);
		device_remove_file(&interface->dev, &dev_attr_input4);
		device_remove_file(kit->dev, &dev_attr_input1);
		device_remove_file(kit->dev, &dev_attr_input2);
		device_remove_file(kit->dev, &dev_attr_input3);
		device_remove_file(kit->dev, &dev_attr_input4);
	}
	if (kit->ifkit->inputs >= 8) {
		device_remove_file(&interface->dev, &dev_attr_input5);
		device_remove_file(&interface->dev, &dev_attr_input6);
		device_remove_file(&interface->dev, &dev_attr_input7);
		device_remove_file(&interface->dev, &dev_attr_input8);
		device_remove_file(kit->dev, &dev_attr_input5);
		device_remove_file(kit->dev, &dev_attr_input6);
		device_remove_file(kit->dev, &dev_attr_input7);
		device_remove_file(kit->dev, &dev_attr_input8);
	}
	if (kit->ifkit->inputs == 16) {
		device_remove_file(&interface->dev, &dev_attr_input9);
		device_remove_file(&interface->dev, &dev_attr_input10);
		device_remove_file(&interface->dev, &dev_attr_input11);
		device_remove_file(&interface->dev, &dev_attr_input12);
		device_remove_file(&interface->dev, &dev_attr_input13);
		device_remove_file(&interface->dev, &dev_attr_input14);
		device_remove_file(&interface->dev, &dev_attr_input15);
		device_remove_file(&interface->dev, &dev_attr_input16);
		device_remove_file(kit->dev, &dev_attr_input9);
		device_remove_file(kit->dev, &dev_attr_input10);
		device_remove_file(kit->dev, &dev_attr_input11);
		device_remove_file(kit->dev, &dev_attr_input12);
		device_remove_file(kit->dev, &dev_attr_input13);
		device_remove_file(kit->dev, &dev_attr_input14);
		device_remove_file(kit->dev, &dev_attr_input15);
		device_remove_file(kit->dev, &dev_attr_input16);
	}

	if (kit->ifkit->sensors >= 4) {
		device_remove_file(&interface->dev, &dev_attr_sensor1);
		device_remove_file(&interface->dev, &dev_attr_sensor2);
		device_remove_file(&interface->dev, &dev_attr_sensor3);
		device_remove_file(&interface->dev, &dev_attr_sensor4);
		device_remove_file(kit->dev, &dev_attr_sensor1);
		device_remove_file(kit->dev, &dev_attr_sensor2);
		device_remove_file(kit->dev, &dev_attr_sensor3);
		device_remove_file(kit->dev, &dev_attr_sensor4);
	}
	if (kit->ifkit->sensors >= 7) {
		device_remove_file(&interface->dev, &dev_attr_sensor5);
		device_remove_file(&interface->dev, &dev_attr_sensor6);
		device_remove_file(&interface->dev, &dev_attr_sensor7);
		device_remove_file(kit->dev, &dev_attr_sensor5);
		device_remove_file(kit->dev, &dev_attr_sensor6);
		device_remove_file(kit->dev, &dev_attr_sensor7);
	}
	if (kit->ifkit->sensors == 8)
		device_remove_file(&interface->dev, &dev_attr_sensor8);
		device_remove_file(kit->dev, &dev_attr_sensor8);

	if (kit->ifkit->has_lcd)
		device_remove_file(&interface->dev, &dev_attr_lcd);
		device_remove_file(kit->dev, &dev_attr_lcd);

	device_unregister(kit->dev);

	dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n",
		kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs);

	usb_put_dev(kit->udev);
	clear_bit(kit->dev_no, &device_no);

	kfree(kit);
}

Loading