📄 aiptek.c
字号:
* support routines for the 'mouse_middle' file. Note that this file * both displays current setting and allows for setting changing. */static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); char *s; if (aiptek == NULL) return 0; switch (aiptek->curSetting.mouseButtonMiddle) { case AIPTEK_MOUSE_LEFT_BUTTON: s = "left"; break; case AIPTEK_MOUSE_MIDDLE_BUTTON: s = "middle"; break; case AIPTEK_MOUSE_RIGHT_BUTTON: s = "right"; break; default: s = "unknown"; break; } return snprintf(buf, PAGE_SIZE, "%s\n", s);}static ssize_tstore_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; if (strcmp(buf, "left") == 0) { aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_LEFT_BUTTON; } else if (strcmp(buf, "middle") == 0) { aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_MIDDLE_BUTTON; } else if (strcmp(buf, "right") == 0) { aiptek->newSetting.mouseButtonMiddle = AIPTEK_MOUSE_RIGHT_BUTTON; } return count;}static DEVICE_ATTR(mouse_middle, S_IRUGO | S_IWUGO, show_tabletMouseMiddle, store_tabletMouseMiddle);/*********************************************************************** * support routines for the 'mouse_right' file. Note that this file * both displays current setting and allows for setting changing. */static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); char *s; if (aiptek == NULL) return 0; switch (aiptek->curSetting.mouseButtonRight) { case AIPTEK_MOUSE_LEFT_BUTTON: s = "left"; break; case AIPTEK_MOUSE_MIDDLE_BUTTON: s = "middle"; break; case AIPTEK_MOUSE_RIGHT_BUTTON: s = "right"; break; default: s = "unknown"; break; } return snprintf(buf, PAGE_SIZE, "%s\n", s);}static ssize_tstore_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; if (strcmp(buf, "left") == 0) { aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_LEFT_BUTTON; } else if (strcmp(buf, "middle") == 0) { aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_MIDDLE_BUTTON; } else if (strcmp(buf, "right") == 0) { aiptek->newSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON; } return count;}static DEVICE_ATTR(mouse_right, S_IRUGO | S_IWUGO, show_tabletMouseRight, store_tabletMouseRight);/*********************************************************************** * support routines for the 'wheel' file. Note that this file * both displays current setting and allows for setting changing. */static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; if (aiptek->curSetting.wheel == AIPTEK_WHEEL_DISABLE) { return snprintf(buf, PAGE_SIZE, "disable\n"); } else { return snprintf(buf, PAGE_SIZE, "%d\n", aiptek->curSetting.wheel); }}static ssize_tstore_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10); return count;}static DEVICE_ATTR(wheel, S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);/*********************************************************************** * support routines for the 'execute' file. Note that this file * both displays current setting and allows for setting changing. */static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; /* There is nothing useful to display, so a one-line manual * is in order... */ return snprintf(buf, PAGE_SIZE, "Write anything to this file to program your tablet.\n");}static ssize_tstore_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; /* We do not care what you write to this file. Merely the action * of writing to this file triggers a tablet reprogramming. */ memcpy(&aiptek->curSetting, &aiptek->newSetting, sizeof(struct aiptek_settings)); if (aiptek_program_tablet(aiptek) < 0) return -EIO; return count;}static DEVICE_ATTR(execute, S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);/*********************************************************************** * support routines for the 'odm_code' file. Note that this file * only displays current setting. */static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.odmCode);}static DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL);/*********************************************************************** * support routines for the 'model_code' file. Note that this file * only displays current setting. */static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->features.modelCode);}static DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL);/*********************************************************************** * support routines for the 'firmware_code' file. Note that this file * only displays current setting. */static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf){ struct aiptek *aiptek = dev_get_drvdata(dev); if (aiptek == NULL) return 0; return snprintf(buf, PAGE_SIZE, "%04x\n", aiptek->features.firmwareCode);}static DEVICE_ATTR(firmware_code, S_IRUGO, show_firmwareCode, NULL);/*********************************************************************** * This routine removes all existing sysfs files managed by this device * driver. */static void aiptek_delete_files(struct device *dev){ device_remove_file(dev, &dev_attr_size); device_remove_file(dev, &dev_attr_product_id); device_remove_file(dev, &dev_attr_vendor_id); device_remove_file(dev, &dev_attr_vendor); device_remove_file(dev, &dev_attr_product); device_remove_file(dev, &dev_attr_pointer_mode); device_remove_file(dev, &dev_attr_coordinate_mode); device_remove_file(dev, &dev_attr_tool_mode); device_remove_file(dev, &dev_attr_xtilt); device_remove_file(dev, &dev_attr_ytilt); device_remove_file(dev, &dev_attr_jitter); device_remove_file(dev, &dev_attr_delay); device_remove_file(dev, &dev_attr_input_path); device_remove_file(dev, &dev_attr_event_count); device_remove_file(dev, &dev_attr_diagnostic); device_remove_file(dev, &dev_attr_odm_code); device_remove_file(dev, &dev_attr_model_code); device_remove_file(dev, &dev_attr_firmware_code); device_remove_file(dev, &dev_attr_stylus_lower); device_remove_file(dev, &dev_attr_stylus_upper); device_remove_file(dev, &dev_attr_mouse_left); device_remove_file(dev, &dev_attr_mouse_middle); device_remove_file(dev, &dev_attr_mouse_right); device_remove_file(dev, &dev_attr_wheel); device_remove_file(dev, &dev_attr_execute);}/*********************************************************************** * This routine creates the sysfs files managed by this device * driver. */static int aiptek_add_files(struct device *dev){ int ret; if ((ret = device_create_file(dev, &dev_attr_size)) || (ret = device_create_file(dev, &dev_attr_product_id)) || (ret = device_create_file(dev, &dev_attr_vendor_id)) || (ret = device_create_file(dev, &dev_attr_vendor)) || (ret = device_create_file(dev, &dev_attr_product)) || (ret = device_create_file(dev, &dev_attr_pointer_mode)) || (ret = device_create_file(dev, &dev_attr_coordinate_mode)) || (ret = device_create_file(dev, &dev_attr_tool_mode)) || (ret = device_create_file(dev, &dev_attr_xtilt)) || (ret = device_create_file(dev, &dev_attr_ytilt)) || (ret = device_create_file(dev, &dev_attr_jitter)) || (ret = device_create_file(dev, &dev_attr_delay)) || (ret = device_create_file(dev, &dev_attr_input_path)) || (ret = device_create_file(dev, &dev_attr_event_count)) || (ret = device_create_file(dev, &dev_attr_diagnostic)) || (ret = device_create_file(dev, &dev_attr_odm_code)) || (ret = device_create_file(dev, &dev_attr_model_code)) || (ret = device_create_file(dev, &dev_attr_firmware_code)) || (ret = device_create_file(dev, &dev_attr_stylus_lower)) || (ret = device_create_file(dev, &dev_attr_stylus_upper)) || (ret = device_create_file(dev, &dev_attr_mouse_left)) || (ret = device_create_file(dev, &dev_attr_mouse_middle)) || (ret = device_create_file(dev, &dev_attr_mouse_right)) || (ret = device_create_file(dev, &dev_attr_wheel)) || (ret = device_create_file(dev, &dev_attr_execute))) { err("aiptek: killing own sysfs device files\n"); aiptek_delete_files(dev); } return ret;}/*********************************************************************** * This routine is called when a tablet has been identified. It basically * sets up the tablet and the driver's internal structures. */static intaiptek_probe(struct usb_interface *intf, const struct usb_device_id *id){ struct usb_device *usbdev = interface_to_usbdev(intf); struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; struct input_dev *inputdev; struct input_handle *inputhandle; struct list_head *node, *next; int i; int speeds[] = { 0, AIPTEK_PROGRAMMABLE_DELAY_50, AIPTEK_PROGRAMMABLE_DELAY_400, AIPTEK_PROGRAMMABLE_DELAY_25, AIPTEK_PROGRAMMABLE_DELAY_100, AIPTEK_PROGRAMMABLE_DELAY_200, AIPTEK_PROGRAMMABLE_DELAY_300 }; /* programmableDelay is where the command-line specified * delay is kept. We make it the first element of speeds[], * so therefore, your override speed is tried first, then the * remainder. Note that the default value of 400ms will be tried * if you do not specify any command line parameter. */ speeds[0] = programmableDelay; aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL); inputdev = input_allocate_device(); if (!aiptek || !inputdev) goto fail1; aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH, SLAB_ATOMIC, &aiptek->data_dma); if (!aiptek->data) goto fail1; aiptek->urb = usb_alloc_urb(0, GFP_KERNEL); if (!aiptek->urb) goto fail2; aiptek->inputdev = inputdev; aiptek->usbdev = usbdev; aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber; aiptek->inDelay = 0; aiptek->endDelay = 0; aiptek->previousJitterable = 0; /* Set up the curSettings struct. Said struct contains the current * programmable parameters. The newSetting struct contains changes * the user makes to the settings via the sysfs interface. Those * changes are not "committed" to curSettings until the user * writes to the sysfs/.../execute file. */ aiptek->curSetting.pointerMode = AIPTEK_POINTER_EITHER_MODE; aiptek->curSetting.coordinateMode = AIPTEK_COORDINATE_ABSOLUTE_MODE; aiptek->curSetting.toolMode = AIPTEK_TOOL_BUTTON_PEN_MODE; aiptek->curSetting.xTilt = AIPTEK_TILT_DISABLE; aiptek->curSetting.yTilt = AIPTEK_TILT_DISABLE; aiptek->curSetting.mouseButtonLeft = AIPTEK_MOUSE_LEFT_BUTTON; aiptek->curSetting.mouseButtonMiddle = AIPTEK_MOUSE_MIDDLE_BUTTON; aiptek->curSetting.mouseButtonRight = AIPTEK_MOUSE_RIGHT_BUTTON; aiptek->curSetting.stylusButtonUpper = AIPTEK_STYLUS_UPPER_BUTTON; aiptek->curSetting.stylusButtonLower = AIPTEK_STYLUS_LOWER_BUTTON; aiptek->curSetting.jitterDelay = jitterDelay; aiptek->curSetting.programmableDelay = programmableDelay; /* Both structs should have equivalent settings */ aiptek->newSetting = aiptek->curSetting; /* Determine the usb devices' physical path. * Asketh not why we always pretend we're using "../input0", * but I suspect this will have to be refactored one * day if a single USB device can be a keyboard & a mouse * & a tablet, and the inputX number actually will tell * us something... */ usb_make_path(usbdev, aiptek->features.usbPath, sizeof(aiptek->features.usbPath)); strlcat(aiptek->features.usbPath, "/input0", sizeof(aiptek->features.usbPath)); /* Set up client data, pointers to open and close routines * for the input device. */ inputdev->name = "Aiptek"; inputdev->phys = aiptek->features.usbPath; usb_to_input_id(usbdev, &inputdev->id); inputdev->cdev.dev = &intf->dev; inputdev->private = aiptek; inputdev->open = aiptek_open; inputdev->close = aiptek_close; /* Now program the capacities of the tablet, in terms of being * an input device. */ inputdev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL) | BIT(EV_MSC); inputdev->absbit[0] |= BIT(ABS_MISC); inputdev->relb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -