[alsa-devel] [PATCH 2.6.34-rc5] HID: Prodikeys PC-MIDI HID Driver
Don Prince
dhprince.devel at yahoo.co.uk
Thu May 6 20:23:49 CEST 2010
On 06/05/10 07:30, Clemens Ladisch wrote:
> dhprince.devel at yahoo wrote:
>
>> A specialised HID driver for the CreativeLabs Prodikeys PC-MIDI USB
>> Keyboard.
>> ...
>>
> I cannot comment on the input stuff, but the sound stuff looks good
> overall.
>
Thanks my first linux coding.
>
>> +What: /sys/bus/hid/drivers/prodikeys/.../channel
>> +Date: April 2010
>> +KernelVersion: 2.6.34
>> +Contact: Don Prince <dhprince.devel at yahoo.co.uk>
>> +Descripts/checkpatch.plscription:
>>
> Huh?
>
>
Fixed. I am being plagued by spurious button presses due to I suspect
conflicts between
my KVM switch and PS/2 to USB keyboard/Mouse converter.
>> +What: /sys/bus/hid/drivers/prodikeys/.../sustain
>> +Description:
>> + Allows control (via software) the sustain duration of a
>> + note held by the pc-midi driver.
>>
> Why is this feature needed? Does the device report key releases
> incorrectly?
>
>
The keyboard pretends to support sustain. The driver actually does it.
> These three sysfs controls could also be implemented as mixer controls.
> This would allow them to be automatically saved and restored when the
> computer is shut down.
>
>
>> + { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS,
>> USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
>>
> Your mailer wrapped long lines and killed the tabs.
> Please see <Documentation/email-clients.txt>.
>
> And your code looks as if it does not use eight-column tabs for
> indention.
>
>
The code is written using 8 column tabs but you are right thunderbird
messed it up. I believe I fixed thunderbird now.
>> +static void pcmidi_send_note(struct pcmidi_snd *pm,
>> ...
>> + res = snd_rawmidi_receive(pm->in_substream, buffer, 3);
>>
> This return value is never used.
>
>
Fixed.
>> + if (!atomic_read(&pms->in_use)) {
>> + pms->status = status;
>> + pms->note = note;
>> + pms->velocity = velocity;
>> + atomic_set(&pms->in_use, 1);
>>
> If you're using the atomic variable to protect against some concurrently
> executing code, then you have a race condition in the time interval
> between the read and the set.
>
>
Fixed. It was me being overkill, they are actually redundant.
>> +static void pcmidi_out_tasklet(unsigned long data)
>> ...
>> + while (1) {
>> + /* just read them and drop them */
>> + u8 b;
>> + if (snd_rawmidi_transmit(pm->out_substream, &b, 1) != 1) {
>> + pm->out_active = 0;
>> + break;
>> + }
>>
> This isn't quite how output ports are supposed to be implemented. :-)
>
> I'd guess you want to remove the OUTPUT and DUPLEX flags and to drop all
> output-related functions.
>
>
I know, it was naff, but without it the I get this from "amidi"
$ amidi -l
Dir Device Name
cannot get rawmidi information 2:0: No such file or directory
Is it supposed to print this?
Although the midi still works.
$ amidi -p hw:2,0 --dump
90 2F 5C
80 2F 7F
90 30 52
80 30 7F
90 32 00
80 32 7F
The test code now looks like this
/*dhp snd_component_add(card, "MIDI");*/
err = snd_rawmidi_new(card, card->shortname, 0,
0, 1, &rwmidi);
if (err < 0) {
pk_error("failed to create pc-midi rawmidi device: error %d\n",
err);
goto fail;
}
pm->rwmidi = rwmidi;
strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name));
rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT /*dhp|
SNDRV_RAWMIDI_INFO_OUTPUT |
SNDRV_RAWMIDI_INFO_DUPLEX*/;
rwmidi->private_data = pm;
/*dhp snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
&pcmidi_out_ops);
*/ snd_rawmidi_set_ops(rwmidi, SNDRV_RAWMIDI_STREAM_INPUT,
&pcmidi_in_ops);
Other command output is printed below.
$ cat /proc/asound/cards
0 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0xdfdf8000 irq 21
1 [HDMI ]: HDA-Intel - HDA ATI HDMI
HDA ATI HDMI at 0xdffec000 irq 31
2 [PCMIDI ]: PC-MIDI - PC-MIDI
Prodikeys PC-MIDI Keyboard
$ aconnect -i
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 24: 'PC-MIDI' [type=kernel]
0 'PC-MIDI
$ aconnect -o
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 128: 'FLUID Synth (Qsynth1)' [type=user]
0 'Synth input port (Qsynth1:0)'
$ aconnect -iol
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
Connecting To: 15:0
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0'
client 24: 'PC-MIDI' [type=kernel]
0 'PC-MIDI '
Connecting To: 128:0
client 128: 'FLUID Synth (Qsynth1)' [type=user]
0 'Synth input port (Qsynth1:0)'
Connected From: 24:0
$ amidi -L
RawMIDI list:
default {
type hw
card {
@func getenv
vars {
0 ALSA_RAWMIDI_CARD
1 ALSA_CARD
}
default {
@func refer
name 'defaults.rawmidi.card'
}
}
device {
@func igetenv
vars {
0 ALSA_RAWMIDI_DEVICE
}
default {
@func refer
name 'defaults.rawmidi.device'
}
}
}
hw {
@args.0 CARD
@args.1 DEV
@args.2 SUBDEV
@args.CARD {
type string
default {
@func getenv
vars {
0 ALSA_RAWMIDI_CARD
1 ALSA_CARD
}
default {
@func refer
name 'defaults.rawmidi.card'
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars {
0 ALSA_RAWMIDI_DEVICE
}
default {
@func refer
name 'defaults.rawmidi.device'
}
}
}
@args.SUBDEV {
type integer
default -1
}
type hw
card $CARD
device $DEV
subdevice $SUBDEV
hint {
description 'Direct rawmidi driver device'
device $DEV
}
}
virtual {
@args.0 MERGE
@args.MERGE {
type string
default 1
}
type virtual
merge $MERGE
}
>> +static void pcmidi_in_trigger(struct snd_rawmidi_substream *substream,
>> int up)
>> ...
>> + if (up)
>> + set_bit(substream->number, &pm->in_triggered);
>> + else
>> + clear_bit(substream->number, &pm->in_triggered);
>>
> You have only one substream, a boolean variable would suffice.
>
Fixed.
>
>> +int pcmidi_snd_initialise(struct pcmidi_snd *pm)
>> ...
>> + int out_ports = 1;
>> + int in_ports = 1;
>>
> These variables are not variable and therefore not needed.
>
>
Fixed.
>> + snd_component_add(card, "MIDI");
>>
> This function is intended for sound cards that are composed of several
> components, and the component name is usually a chip name. I think
> you don't need to call this function at all.
>
>
Fixed.
>> + err = snd_card_register(card);
>> ...
>> + /* create sysfs variables */
>> + err = device_create_file(&pm->pk->hdev->dev,
>> + sysfs_device_attr_channel);
>> ...
>> + spin_lock_init(&pm->rawmidi_in_lock);
>> +
>> + init_sustain_timers(pm);
>>
> snd_card_register() makes all sound interfaces available to userspace.
> Initializations for any data that might be accessed from userspace must
> be done before that call.
>
>
Fixed.
> Regards,
> Clemens
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
>
___________________________________________________________
The all-new Yahoo! Mail goes wherever you go - free your email address from your Internet provider. http://uk.docs.yahoo.com/nowyoucan.html
More information about the Alsa-devel
mailing list