diff options
author | Dmitry Torokhov <dtor@mail.ru> | 2007-11-21 16:45:23 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:29:27 +0100 |
commit | b18b493f27bfb0d112a54ef24a1db32e898abff9 (patch) | |
tree | 1b4b69f643bb4705ffd105dfa00ac7aa987185aa | |
parent | ee6df2e1849403b5805018193a1454f6d39f9498 (diff) | |
download | linux-3.10-b18b493f27bfb0d112a54ef24a1db32e898abff9.tar.gz linux-3.10-b18b493f27bfb0d112a54ef24a1db32e898abff9.tar.bz2 linux-3.10-b18b493f27bfb0d112a54ef24a1db32e898abff9.zip |
[ALSA] caiaq - misc input handling fixes
- link input device with its parent so that it placed in proper spot
in sysfs hierarchy
- drivers that allow changing their keymaps should use private copy
of the keymap so that one instance of a device does not affect
another instance
- it is preferred for drivers to properly set up input_dev->phys to
help userspace locate devices
- drivers should use usb_to_input_id(), or perform endianess conversion,
themselves, otherwise ID is not correct on big-endian boxes
- whitespace and formatting cleanup
Acked-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | sound/usb/caiaq/caiaq-device.h | 10 | ||||
-rw-r--r-- | sound/usb/caiaq/caiaq-input.c | 126 |
2 files changed, 71 insertions, 65 deletions
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h index 79bc5be2df7..685761279f1 100644 --- a/sound/usb/caiaq/caiaq-device.h +++ b/sound/usb/caiaq/caiaq-device.h @@ -7,7 +7,7 @@ #define USB_PID_RIGKONTROL2 0x1969 #define USB_PID_RIGKONTROL3 0x1940 -#define USB_PID_KORECONTROLLER 0x4711 +#define USB_PID_KORECONTROLLER 0x4711 #define USB_PID_AK1 0x0815 #define USB_PID_AUDIO8DJ 0x1978 @@ -62,7 +62,7 @@ struct snd_usb_caiaqdev { struct urb **data_urbs_in; struct urb **data_urbs_out; struct snd_usb_caiaq_cb_info *data_cb_info; - + unsigned char ep1_in_buf[EP1_BUFSIZE]; unsigned char ep1_out_buf[EP1_BUFSIZE]; unsigned char midi_out_buf[EP1_BUFSIZE]; @@ -72,7 +72,7 @@ struct snd_usb_caiaqdev { wait_queue_head_t ep1_wait_queue; wait_queue_head_t prepare_wait_queue; int spec_received, audio_parm_answer; - + char vendor_name[CAIAQ_USB_STR_LEN]; char product_name[CAIAQ_USB_STR_LEN]; char serial[CAIAQ_USB_STR_LEN]; @@ -93,8 +93,10 @@ struct snd_usb_caiaqdev { /* Linux input */ #ifdef CONFIG_SND_USB_CAIAQ_INPUT struct input_dev *input_dev; + char phys[64]; /* physical device path */ + unsigned short keycode[10]; #endif - + /* ALSA */ struct snd_pcm *pcm; struct snd_pcm_hardware pcm_info; diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c index cd536ca20e5..03bf4c63b5e 100644 --- a/sound/usb/caiaq/caiaq-input.c +++ b/sound/usb/caiaq/caiaq-input.c @@ -21,6 +21,7 @@ #include <linux/moduleparam.h> #include <linux/input.h> #include <linux/usb.h> +#include <linux/usb/input.h> #include <linux/spinlock.h> #include <sound/driver.h> #include <sound/core.h> @@ -31,18 +32,18 @@ #ifdef CONFIG_SND_USB_CAIAQ_INPUT -static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; -static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, - KEY_5, KEY_6, KEY_7 }; -static unsigned char keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, - KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; +static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; +static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7 }; +static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; -#define DEG90 (range/2) -#define DEG180 (range) -#define DEG270 (DEG90 + DEG180) -#define DEG360 (DEG180 * 2) -#define HIGH_PEAK (268) -#define LOW_PEAK (-7) +#define DEG90 (range / 2) +#define DEG180 (range) +#define DEG270 (DEG90 + DEG180) +#define DEG360 (DEG180 * 2) +#define HIGH_PEAK (268) +#define LOW_PEAK (-7) /* some of these devices have endless rotation potentiometers * built in which use two tapers, 90 degrees phase shifted. @@ -56,8 +57,8 @@ static unsigned int decode_erp(unsigned char a, unsigned char b) int range = HIGH_PEAK - LOW_PEAK; int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; - weight_b = abs(mid_value-a) - (range/2 - 100)/2; - + weight_b = abs(mid_value - a) - (range / 2 - 100) / 2; + if (weight_b < 0) weight_b = 0; @@ -93,7 +94,7 @@ static unsigned int decode_erp(unsigned char a, unsigned char b) if (ret < 0) ret += 1000; - + if (ret >= 1000) ret -= 1000; @@ -108,76 +109,80 @@ static unsigned int decode_erp(unsigned char a, unsigned char b) #undef LOW_PEAK -static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, +static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, const unsigned char *buf, unsigned int len) { - switch(dev->input_dev->id.product) { + struct input_dev *input_dev = dev->input_dev; + + switch (input_dev->id.product) { case USB_PID_RIGKONTROL2: - input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]); - input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]); - input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]); - input_sync(dev->input_dev); + input_report_abs(input_dev, ABS_X, (buf[4] << 8) | buf[5]); + input_report_abs(input_dev, ABS_Y, (buf[0] << 8) | buf[1]); + input_report_abs(input_dev, ABS_Z, (buf[2] << 8) | buf[3]); + input_sync(input_dev); break; case USB_PID_RIGKONTROL3: - input_report_abs(dev->input_dev, ABS_X, (buf[0] << 8) |buf[1]); - input_report_abs(dev->input_dev, ABS_Y, (buf[2] << 8) |buf[3]); - input_report_abs(dev->input_dev, ABS_Z, (buf[4] << 8) |buf[5]); - input_sync(dev->input_dev); + input_report_abs(input_dev, ABS_X, (buf[0] << 8) | buf[1]); + input_report_abs(input_dev, ABS_Y, (buf[2] << 8) | buf[3]); + input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); + input_sync(input_dev); break; } } -static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, +static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, const char *buf, unsigned int len) { + struct input_dev *input_dev = dev->input_dev; int i; - switch(dev->input_dev->id.product) { + switch (input_dev->id.product) { case USB_PID_AK1: i = decode_erp(buf[0], buf[1]); - input_report_abs(dev->input_dev, ABS_X, i); - input_sync(dev->input_dev); + input_report_abs(input_dev, ABS_X, i); + input_sync(input_dev); break; } } -static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, +static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len) { + struct input_dev *input_dev = dev->input_dev; + unsigned short *keycode = input_dev->keycode; int i; - unsigned char *keycode = dev->input_dev->keycode; if (!keycode) return; - if (dev->input_dev->id.product == USB_PID_RIGKONTROL2) - for (i=0; i<len; i++) + if (input_dev->id.product == USB_PID_RIGKONTROL2) + for (i = 0; i < len; i++) buf[i] = ~buf[i]; - for (i=0; (i<dev->input_dev->keycodemax) && (i < len); i++) - input_report_key(dev->input_dev, keycode[i], - buf[i/8] & (1 << (i%8))); + for (i = 0; i < input_dev->keycodemax && i < len; i++) + input_report_key(input_dev, keycode[i], + buf[i / 8] & (1 << (i % 8))); - input_sync(dev->input_dev); + input_sync(input_dev); } -void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, - char *buf, +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, + char *buf, unsigned int len) { - if (!dev->input_dev || (len < 1)) + if (!dev->input_dev || len < 1) return; switch (buf[0]) { case EP1_CMD_READ_ANALOG: - snd_caiaq_input_read_analog(dev, buf+1, len-1); + snd_caiaq_input_read_analog(dev, buf + 1, len - 1); break; case EP1_CMD_READ_ERP: - snd_caiaq_input_read_erp(dev, buf+1, len-1); + snd_caiaq_input_read_erp(dev, buf + 1, len - 1); break; case EP1_CMD_READ_IO: - snd_caiaq_input_read_io(dev, buf+1, len-1); + snd_caiaq_input_read_io(dev, buf + 1, len - 1); break; } } @@ -192,37 +197,34 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) if (!input) return -ENOMEM; + usb_make_path(usb_dev, dev->phys, sizeof(dev->phys)); + strlcat(dev->phys, "/input0", sizeof(dev->phys)); + input->name = dev->product_name; - input->id.bustype = BUS_USB; - input->id.vendor = usb_dev->descriptor.idVendor; - input->id.product = usb_dev->descriptor.idProduct; - input->id.version = usb_dev->descriptor.bcdDevice; + input->phys = dev->phys; + usb_to_input_id(usb_dev, &input->id); + input->dev.parent = &usb_dev->dev; switch (dev->chip.usb_id) { case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_Z); - input->keycode = keycode_rk2; - input->keycodesize = sizeof(char); + BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk2)); + memcpy(dev->keycode, keycode_rk2, sizeof(keycode_rk2)); input->keycodemax = ARRAY_SIZE(keycode_rk2); - for (i=0; i<ARRAY_SIZE(keycode_rk2); i++) - set_bit(keycode_rk2[i], input->keybit); - input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); - input->keycode = keycode_rk3; - input->keycodesize = sizeof(char); + BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3)); + memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3)); input->keycodemax = ARRAY_SIZE(keycode_rk3); - for (i=0; i<ARRAY_SIZE(keycode_rk3); i++) - set_bit(keycode_rk3[i], input->keybit); - input_set_abs_params(input, ABS_X, 0, 1024, 0, 10); input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10); input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10); @@ -231,12 +233,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input->absbit[0] = BIT_MASK(ABS_X); - input->keycode = keycode_ak1; - input->keycodesize = sizeof(char); + BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1)); + memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1)); input->keycodemax = ARRAY_SIZE(keycode_ak1); - for (i=0; i<ARRAY_SIZE(keycode_ak1); i++) - set_bit(keycode_ak1[i], input->keybit); - input_set_abs_params(input, ABS_X, 0, 999, 0, 10); snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); break; @@ -246,6 +245,11 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) return 0; } + input->keycode = dev->keycode; + input->keycodesize = sizeof(unsigned short); + for (i = 0; i < input->keycodemax; i++) + __set_bit(dev->keycode[i], input->keybit); + ret = input_register_device(input); if (ret < 0) { input_free_device(input); |