enum {
POD_monitor_level = 0x04,
- POD_routing = 0x05,
POD_tuner_mute = 0x13,
POD_tuner_freq = 0x15,
POD_tuner_note = 0x16,
<< 8) |
((int)buf[9] << 4) | (int)buf[10];
-#define PROCESS_SYSTEM_PARAM(x) \
- case POD_ ## x: \
- pod->x.value = value; \
- wake_up(&pod->x.wait); \
- break;
-
- switch (buf[6]) {
- case POD_monitor_level:
+ if (buf[6] == POD_monitor_level)
pod->monitor_level = value;
- break;
-
- PROCESS_SYSTEM_PARAM(routing);
- PROCESS_SYSTEM_PARAM
- (tuner_mute);
- PROCESS_SYSTEM_PARAM
- (tuner_freq);
- PROCESS_SYSTEM_PARAM
- (tuner_note);
- PROCESS_SYSTEM_PARAM
- (tuner_pitch);
-
-#undef PROCESS_SYSTEM_PARAM
-
- default:
- dev_dbg(pod->line6.ifcdev,
- "unknown tuner/system response %02X\n",
- buf[6]);
- }
-
break;
}
}
}
-/*
- Detect some cases that require a channel dump after sending a command to the
- device. Important notes:
- *) The actual dump request can not be sent here since we are not allowed to
- wait for the completion of the first message in this context, and sending
- the dump request before completion of the previous message leaves the POD
- in an undefined state. The dump request will be sent when the echoed
- commands are received.
- *) This method fails if a param change message is "chopped" after the first
- byte.
-*/
-void line6_pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data,
- int length)
-{
- int i;
-
- if (!pod->midi_postprocess)
- return;
-
- for (i = 0; i < length; ++i) {
- if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
- line6_invalidate_current(&pod->dumpreq);
- break;
- } else
- if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST))
- && (i < length - 1))
- if ((data[i + 1] == POD_amp_model_setup)
- || (data[i + 1] == POD_effect_setup)) {
- line6_invalidate_current(&pod->dumpreq);
- break;
- }
- }
-}
-
/*
Transmit PODxt Pro control parameter.
*/
line6_invalidate_current(&pod->dumpreq);
}
-/*
- Resolve value to memory location.
-*/
-static int pod_resolve(const char *buf, short block0, short block1,
- unsigned char *location)
-{
- u8 value;
- short block;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- block = (value < 0x40) ? block0 : block1;
- value &= 0x3f;
- location[0] = block >> 7;
- location[1] = value | (block & 0x7f);
- return 0;
-}
-
-/*
- Send command to store channel/effects setup/amp setup to PODxt Pro.
-*/
-static ssize_t pod_send_store_command(struct device *dev, const char *buf,
- size_t count, short block0, short block1)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int ret;
- int size = 3 + sizeof(pod->prog_data_buf);
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
-
- if (!sysex)
- return 0;
-
- /* Don't know what this is good for, but PODxt Pro transmits it, so we
- * also do... */
- sysex[SYSEX_DATA_OFS] = 5;
- ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
- if (ret) {
- kfree(sysex);
- return ret;
- }
-
- memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf,
- sizeof(pod->prog_data_buf));
-
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
- /* needs some delay here on AMD64 platform */
- return count;
-}
-
-/*
- Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
-*/
-static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf,
- size_t count, short block0,
- short block1)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int ret;
- int size = 4;
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
-
- if (!sysex)
- return 0;
-
- ret = pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
- if (ret) {
- kfree(sysex);
- return ret;
- }
- sysex[SYSEX_DATA_OFS + 2] = 0;
- sysex[SYSEX_DATA_OFS + 3] = 0;
- line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
-
- if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
- line6_dump_finished(&pod->dumpreq);
-
- kfree(sysex);
- /* needs some delay here on AMD64 platform */
- return count;
-}
-
/*
Identify system parameters related to the tuner.
*/
(code == POD_tuner_note) || (code == POD_tuner_pitch);
}
-/*
- Get system parameter (as integer).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static int pod_get_system_param_int(struct usb_line6_pod *pod, int *value,
- int code, struct ValueWait *param, int sign)
-{
- char *sysex;
- static const int size = 1;
- int retval = 0;
-
- if (((pod->prog_data.control[POD_tuner] & 0x40) == 0)
- && pod_is_tuner(code))
- return -ENODEV;
-
- /* send value request to device: */
- param->value = POD_system_invalid;
- sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
-
- if (!sysex)
- return -ENOMEM;
-
- sysex[SYSEX_DATA_OFS] = code;
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
-
- /* wait for device to respond: */
- retval =
- wait_event_interruptible(param->wait,
- param->value != POD_system_invalid);
-
- if (retval < 0)
- return retval;
-
- *value = sign ? (int)(signed short)param->value : (int)(unsigned short)
- param->value;
-
- if (*value == POD_system_invalid)
- *value = 0; /* don't report uninitialized values */
-
- return 0;
-}
-
-/*
- Get system parameter (as string).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static ssize_t pod_get_system_param_string(struct usb_line6_pod *pod, char *buf,
- int code, struct ValueWait *param,
- int sign)
-{
- int retval, value = 0;
- retval = pod_get_system_param_int(pod, &value, code, param, sign);
-
- if (retval < 0)
- return retval;
-
- return sprintf(buf, "%d\n", value);
-}
-
/*
Send system parameter (from integer).
@param tuner non-zero, if code refers to a tuner parameter
return 0;
}
-/*
- Send system parameter (from string).
- @param tuner non-zero, if code refers to a tuner parameter
-*/
-static ssize_t pod_set_system_param_string(struct usb_line6_pod *pod,
- const char *buf, int count, int code,
- unsigned short mask)
-{
- int retval;
- unsigned short value = simple_strtoul(buf, NULL, 10) & mask;
- retval = pod_set_system_param_int(pod, value, code);
- return (retval < 0) ? retval : count;
-}
-
-/*
- "write" request on "finish" special file.
-*/
-static ssize_t pod_set_finish(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- int size = 0;
- char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
- if (!sysex)
- return 0;
- line6_send_sysex_message(&pod->line6, sysex, size);
- kfree(sysex);
- return count;
-}
-
-/*
- "write" request on "store_channel" special file.
-*/
-static ssize_t pod_set_store_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
-}
-
-/*
- "write" request on "store_effects_setup" special file.
-*/
-static ssize_t pod_set_store_effects_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
-}
-
-/*
- "write" request on "store_amp_setup" special file.
-*/
-static ssize_t pod_set_store_amp_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
-}
-
-/*
- "write" request on "retrieve_channel" special file.
-*/
-static ssize_t pod_set_retrieve_channel(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
-}
-
-/*
- "write" request on "retrieve_effects_setup" special file.
-*/
-static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
-}
-
-/*
- "read" request on "midi_postprocess" special file.
-*/
-static ssize_t pod_get_midi_postprocess(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- return sprintf(buf, "%d\n", pod->midi_postprocess);
-}
-
-/*
- "write" request on "midi_postprocess" special file.
-*/
-static ssize_t pod_set_midi_postprocess(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct usb_interface *interface = to_usb_interface(dev);
- struct usb_line6_pod *pod = usb_get_intfdata(interface);
- u8 value;
- int ret;
-
- ret = kstrtou8(buf, 10, &value);
- if (ret)
- return ret;
-
- pod->midi_postprocess = value ? 1 : 0;
- return count;
-}
-
/*
"read" request on "serial_number" special file.
*/
line6->properties->device_bit, line6->ifcdev);
}
-#define POD_GET_SYSTEM_PARAM(code, sign) \
-static ssize_t pod_get_ ## code(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *interface = to_usb_interface(dev); \
- struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_get_system_param_string(pod, buf, POD_ ## code, \
- &pod->code, sign); \
-}
-
-#define POD_GET_SET_SYSTEM_PARAM(code, mask, sign) \
-POD_GET_SYSTEM_PARAM(code, sign) \
-static ssize_t pod_set_ ## code(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- struct usb_interface *interface = to_usb_interface(dev); \
- struct usb_line6_pod *pod = usb_get_intfdata(interface); \
- return pod_set_system_param_string(pod, buf, count, POD_ ## code, mask); \
-}
-
-POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 0);
-POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 0);
-POD_GET_SYSTEM_PARAM(tuner_note, 1);
-POD_GET_SYSTEM_PARAM(tuner_pitch, 1);
-
-#undef GET_SET_SYSTEM_PARAM
-#undef GET_SYSTEM_PARAM
-
/* POD special files: */
static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
-static DEVICE_ATTR(finish, S_IWUSR, line6_nop_read, pod_set_finish);
static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version,
line6_nop_write);
-static DEVICE_ATTR(midi_postprocess, S_IWUSR | S_IRUGO,
- pod_get_midi_postprocess, pod_set_midi_postprocess);
-static DEVICE_ATTR(retrieve_channel, S_IWUSR, line6_nop_read,
- pod_set_retrieve_channel);
-static DEVICE_ATTR(retrieve_effects_setup, S_IWUSR, line6_nop_read,
- pod_set_retrieve_effects_setup);
-static DEVICE_ATTR(routing, S_IWUSR | S_IRUGO, pod_get_routing,
- pod_set_routing);
static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number,
line6_nop_write);
-static DEVICE_ATTR(store_amp_setup, S_IWUSR, line6_nop_read,
- pod_set_store_amp_setup);
-static DEVICE_ATTR(store_channel, S_IWUSR, line6_nop_read,
- pod_set_store_channel);
-static DEVICE_ATTR(store_effects_setup, S_IWUSR, line6_nop_read,
- pod_set_store_effects_setup);
-static DEVICE_ATTR(tuner_freq, S_IWUSR | S_IRUGO, pod_get_tuner_freq,
- pod_set_tuner_freq);
-static DEVICE_ATTR(tuner_mute, S_IWUSR | S_IRUGO, pod_get_tuner_mute,
- pod_set_tuner_mute);
-static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
-static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
-
-#ifdef CONFIG_LINE6_USB_RAW
-static DEVICE_ATTR(raw, S_IWUSR, line6_nop_read, line6_set_raw);
-#endif
/* control info callback */
static int snd_pod_control_monitor_info(struct snd_kcontrol *kcontrol,
int err;
CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
- CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
- CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
- CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
- CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
- CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
- CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
-
-#ifdef CONFIG_LINE6_USB_RAW
- CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
-#endif
-
return 0;
}
if ((interface == NULL) || (pod == NULL))
return -ENODEV;
- /* initialize wait queues: */
- init_waitqueue_head(&pod->routing.wait);
- init_waitqueue_head(&pod->tuner_mute.wait);
- init_waitqueue_head(&pod->tuner_freq.wait);
- init_waitqueue_head(&pod->tuner_note.wait);
- init_waitqueue_head(&pod->tuner_pitch.wait);
-
/* initialize USB buffers: */
err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
sizeof(pod_request_channel));
properties->device_bit, dev);
device_remove_file(dev, &dev_attr_device_id);
- device_remove_file(dev, &dev_attr_finish);
device_remove_file(dev, &dev_attr_firmware_version);
- device_remove_file(dev, &dev_attr_midi_postprocess);
- device_remove_file(dev, &dev_attr_retrieve_channel);
- device_remove_file(dev,
- &dev_attr_retrieve_effects_setup);
- device_remove_file(dev, &dev_attr_routing);
device_remove_file(dev, &dev_attr_serial_number);
- device_remove_file(dev, &dev_attr_store_amp_setup);
- device_remove_file(dev, &dev_attr_store_channel);
- device_remove_file(dev, &dev_attr_store_effects_setup);
- device_remove_file(dev, &dev_attr_tuner_freq);
- device_remove_file(dev, &dev_attr_tuner_mute);
- device_remove_file(dev, &dev_attr_tuner_note);
- device_remove_file(dev, &dev_attr_tuner_pitch);
-
-#ifdef CONFIG_LINE6_USB_RAW
- device_remove_file(dev, &dev_attr_raw);
-#endif
}
}