diff options
author | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-11 10:41:07 +0300 |
---|---|---|
committer | José Pekkarinen <jose.pekkarinen@nokia.com> | 2016-04-13 08:17:18 +0300 |
commit | e09b41010ba33a20a87472ee821fa407a5b8da36 (patch) | |
tree | d10dc367189862e7ca5c592f033dc3726e1df4e3 /kernel/sound/firewire/oxfw/oxfw-stream.c | |
parent | f93b97fd65072de626c074dbe099a1fff05ce060 (diff) |
These changes are the raw update to linux-4.4.6-rt14. Kernel sources
are taken from kernel.org, and rt patch from the rt wiki download page.
During the rebasing, the following patch collided:
Force tick interrupt and get rid of softirq magic(I70131fb85).
Collisions have been removed because its logic was found on the
source already.
Change-Id: I7f57a4081d9deaa0d9ccfc41a6c8daccdee3b769
Signed-off-by: José Pekkarinen <jose.pekkarinen@nokia.com>
Diffstat (limited to 'kernel/sound/firewire/oxfw/oxfw-stream.c')
-rw-r--r-- | kernel/sound/firewire/oxfw/oxfw-stream.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/kernel/sound/firewire/oxfw/oxfw-stream.c b/kernel/sound/firewire/oxfw/oxfw-stream.c index e6757cd85..7cb5743c0 100644 --- a/kernel/sound/firewire/oxfw/oxfw-stream.c +++ b/kernel/sound/firewire/oxfw/oxfw-stream.c @@ -148,14 +148,17 @@ static int start_stream(struct snd_oxfw *oxfw, struct amdtp_stream *stream, } pcm_channels = formation.pcm; - midi_ports = DIV_ROUND_UP(formation.midi, 8); + midi_ports = formation.midi * 8; /* The stream should have one pcm channels at least */ if (pcm_channels == 0) { err = -EINVAL; goto end; } - amdtp_stream_set_parameters(stream, rate, pcm_channels, midi_ports); + err = amdtp_am824_set_parameters(stream, rate, pcm_channels, midi_ports, + false); + if (err < 0) + goto end; err = cmp_connection_establish(conn, amdtp_stream_get_max_payload(stream)); @@ -225,16 +228,25 @@ int snd_oxfw_stream_init_simplex(struct snd_oxfw *oxfw, if (err < 0) goto end; - err = amdtp_stream_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING); + err = amdtp_am824_init(stream, oxfw->unit, s_dir, CIP_NONBLOCKING); if (err < 0) { amdtp_stream_destroy(stream); cmp_connection_destroy(conn); goto end; } - /* OXFW starts to transmit packets with non-zero dbc. */ - if (stream == &oxfw->tx_stream) - oxfw->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK; + /* + * OXFW starts to transmit packets with non-zero dbc. + * OXFW postpone transferring packets till handling any asynchronous + * packets. As a result, next isochronous packet includes more data + * blocks than IEC 61883-6 defines. + */ + if (stream == &oxfw->tx_stream) { + oxfw->tx_stream.flags |= CIP_SKIP_INIT_DBC_CHECK | + CIP_JUMBO_PAYLOAD; + if (oxfw->wrong_dbs) + oxfw->tx_stream.flags |= CIP_WRONG_DBS; + } end: return err; } @@ -474,8 +486,8 @@ int snd_oxfw_stream_parse_format(u8 *format, } } - if (formation->pcm > AMDTP_MAX_CHANNELS_FOR_PCM || - formation->midi > AMDTP_MAX_CHANNELS_FOR_MIDI) + if (formation->pcm > AM824_MAX_CHANNELS_FOR_PCM || + formation->midi > AM824_MAX_CHANNELS_FOR_MIDI) return -ENOSYS; return 0; @@ -506,12 +518,11 @@ assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir, if (err < 0) goto end; - formats[eid] = kmalloc(*len, GFP_KERNEL); + formats[eid] = kmemdup(buf, *len, GFP_KERNEL); if (formats[eid] == NULL) { err = -ENOMEM; goto end; } - memcpy(formats[eid], buf, *len); /* apply the format for each available sampling rate */ for (i = 0; i < ARRAY_SIZE(oxfw_rate_table); i++) { @@ -525,12 +536,11 @@ assume_stream_formats(struct snd_oxfw *oxfw, enum avc_general_plug_dir dir, continue; eid++; - formats[eid] = kmalloc(*len, GFP_KERNEL); + formats[eid] = kmemdup(buf, *len, GFP_KERNEL); if (formats[eid] == NULL) { err = -ENOMEM; goto end; } - memcpy(formats[eid], buf, *len); formats[eid][2] = avc_stream_rate_table[i]; } @@ -588,12 +598,11 @@ static int fill_stream_formats(struct snd_oxfw *oxfw, if (err < 0) break; - formats[eid] = kmalloc(len, GFP_KERNEL); + formats[eid] = kmemdup(buf, len, GFP_KERNEL); if (formats[eid] == NULL) { err = -ENOMEM; break; } - memcpy(formats[eid], buf, len); /* get next entry */ len = AVC_GENERIC_FRAME_MAXIMUM_BYTES; @@ -620,6 +629,9 @@ end: int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) { u8 plugs[AVC_PLUG_INFO_BUF_BYTES]; + struct snd_oxfw_stream_formation formation; + u8 *format; + unsigned int i; int err; /* the number of plugs for isoc in/out, ext in/out */ @@ -639,12 +651,42 @@ int snd_oxfw_stream_discover(struct snd_oxfw *oxfw) err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_OUT, 0); if (err < 0) goto end; + + for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { + format = oxfw->tx_stream_formats[i]; + if (format == NULL) + continue; + err = snd_oxfw_stream_parse_format(format, &formation); + if (err < 0) + continue; + + /* Add one MIDI port. */ + if (formation.midi > 0) + oxfw->midi_input_ports = 1; + } + oxfw->has_output = true; } /* use iPCR[0] if exists */ - if (plugs[0] > 0) + if (plugs[0] > 0) { err = fill_stream_formats(oxfw, AVC_GENERAL_PLUG_DIR_IN, 0); + if (err < 0) + goto end; + + for (i = 0; i < SND_OXFW_STREAM_FORMAT_ENTRIES; i++) { + format = oxfw->rx_stream_formats[i]; + if (format == NULL) + continue; + err = snd_oxfw_stream_parse_format(format, &formation); + if (err < 0) + continue; + + /* Add one MIDI port. */ + if (formation.midi > 0) + oxfw->midi_output_ports = 1; + } + } end: return err; } |