···494494hp_mic_detect (bool)495495 enable/disable the hp/mic shared input for a single built-in mic496496 case; default true497497+vmaster (bool)498498+ enable/disable the virtual Master control; default true497499mixer_nid (int)498500 specifies the widget NID of the analog-loopback mixer499501
···795795 return NULL;796796797797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);798798- if (! chip) {799799- snd_printk(KERN_ERR "vx_core: no memory\n");798798+ if (! chip)800799 return NULL;801801- }802800 mutex_init(&chip->lock);803801 chip->irq = -1;804802 chip->hw = hw;
+20
sound/firewire/Kconfig
···140140 To compile this driver as a module, choose M here: the module141141 will be called snd-firewire-tascam.142142143143+config SND_FIREWIRE_MOTU144144+ tristate "Mark of the unicorn FireWire series support"145145+ select SND_FIREWIRE_LIB146146+ select SND_HWDEP147147+ help148148+ Say Y here to enable support for FireWire devices which MOTU produced:149149+ * 828mk2150150+ * 828mk3151151+152152+ To compile this driver as a module, choose M here: the module153153+ will be called snd-firewire-motu.154154+155155+config SND_FIREFACE156156+ tristate "RME Fireface series support"157157+ select SND_FIREWIRE_LIB158158+ select SND_HWDEP159159+ help160160+ Say Y here to include support for RME fireface series.161161+ * Fireface 400162162+143163endif # SND_FIREWIRE
···27272828/* isochronous header parameters */2929#define ISO_DATA_LENGTH_SHIFT 163030+#define TAG_NO_CIP_HEADER 03031#define TAG_CIP 131323233/* common isochronous packet header parameters */···3837#define CIP_SID_MASK 0x3f0000003938#define CIP_DBS_MASK 0x00ff00004039#define CIP_DBS_SHIFT 164040+#define CIP_SPH_MASK 0x000004004141+#define CIP_SPH_SHIFT 104142#define CIP_DBC_MASK 0x000000ff4243#define CIP_FMT_SHIFT 244344#define CIP_FMT_MASK 0x3f000000···235232unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)236233{237234 unsigned int multiplier = 1;235235+ unsigned int header_size = 0;238236239237 if (s->flags & CIP_JUMBO_PAYLOAD)240238 multiplier = 5;239239+ if (!(s->flags & CIP_NO_HEADER))240240+ header_size = 8;241241242242- return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier;242242+ return header_size +243243+ s->syt_interval * s->data_block_quadlets * 4 * multiplier;243244}244245EXPORT_SYMBOL(amdtp_stream_get_max_payload);245246···385378 goto end;386379387380 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);388388- p.tag = TAG_CIP;381381+ p.tag = s->tag;389382 p.header_length = header_length;390383 if (payload_length > 0)391384 p.payload_length = payload_length;···412405413406static inline int queue_in_packet(struct amdtp_stream *s)414407{415415- return queue_packet(s, IN_PACKET_HEADER_SIZE,416416- amdtp_stream_get_max_payload(s));408408+ return queue_packet(s, IN_PACKET_HEADER_SIZE, s->max_payload_length);417409}418410419419-static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,411411+static int handle_out_packet(struct amdtp_stream *s,412412+ unsigned int payload_length, unsigned int cycle,420413 unsigned int index)421414{422415 __be32 *buffer;423416 unsigned int syt;424417 unsigned int data_blocks;425425- unsigned int payload_length;426418 unsigned int pcm_frames;427419 struct snd_pcm_substream *pcm;428420···430424 data_blocks = calculate_data_blocks(s, syt);431425 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);432426427427+ if (s->flags & CIP_DBC_IS_END_EVENT)428428+ s->data_block_counter =429429+ (s->data_block_counter + data_blocks) & 0xff;430430+433431 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |434432 (s->data_block_quadlets << CIP_DBS_SHIFT) |433433+ ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) |435434 s->data_block_counter);436435 buffer[1] = cpu_to_be32(CIP_EOH |437436 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |438437 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |439438 (syt & CIP_SYT_MASK));440439441441- s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;440440+ if (!(s->flags & CIP_DBC_IS_END_EVENT))441441+ s->data_block_counter =442442+ (s->data_block_counter + data_blocks) & 0xff;442443 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;443444444445 trace_out_packet(s, cycle, buffer, payload_length, index);···461448 return 0;462449}463450451451+static int handle_out_packet_without_header(struct amdtp_stream *s,452452+ unsigned int payload_length, unsigned int cycle,453453+ unsigned int index)454454+{455455+ __be32 *buffer;456456+ unsigned int syt;457457+ unsigned int data_blocks;458458+ unsigned int pcm_frames;459459+ struct snd_pcm_substream *pcm;460460+461461+ buffer = s->buffer.packets[s->packet_index].buffer;462462+ syt = calculate_syt(s, cycle);463463+ data_blocks = calculate_data_blocks(s, syt);464464+ pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt);465465+ s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;466466+467467+ payload_length = data_blocks * 4 * s->data_block_quadlets;468468+469469+ trace_out_packet_without_header(s, cycle, payload_length, data_blocks,470470+ index);471471+472472+ if (queue_out_packet(s, payload_length) < 0)473473+ return -EIO;474474+475475+ pcm = ACCESS_ONCE(s->pcm);476476+ if (pcm && pcm_frames > 0)477477+ update_pcm_pointers(s, pcm, pcm_frames);478478+479479+ /* No need to return the number of handled data blocks. */480480+ return 0;481481+}482482+464483static int handle_in_packet(struct amdtp_stream *s,465465- unsigned int payload_quadlets, unsigned int cycle,484484+ unsigned int payload_length, unsigned int cycle,466485 unsigned int index)467486{468487 __be32 *buffer;469488 u32 cip_header[2];470470- unsigned int fmt, fdf, syt;489489+ unsigned int sph, fmt, fdf, syt;471490 unsigned int data_block_quadlets, data_block_counter, dbc_interval;472491 unsigned int data_blocks;473492 struct snd_pcm_substream *pcm;···510465 cip_header[0] = be32_to_cpu(buffer[0]);511466 cip_header[1] = be32_to_cpu(buffer[1]);512467513513- trace_in_packet(s, cycle, cip_header, payload_quadlets, index);468468+ trace_in_packet(s, cycle, cip_header, payload_length, index);514469515470 /*516471 * This module supports 'Two-quadlet CIP header with SYT field'.517472 * For convenience, also check FMT field is AM824 or not.518473 */519519- if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||520520- ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) {474474+ if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||475475+ ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) &&476476+ (!(s->flags & CIP_HEADER_WITHOUT_EOH))) {521477 dev_info_ratelimited(&s->unit->device,522478 "Invalid CIP header for AMDTP: %08X:%08X\n",523479 cip_header[0], cip_header[1]);···528482 }529483530484 /* Check valid protocol or not. */485485+ sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT;531486 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;532532- if (fmt != s->fmt) {487487+ if (sph != s->sph || fmt != s->fmt) {533488 dev_info_ratelimited(&s->unit->device,534489 "Detect unexpected protocol: %08x %08x\n",535490 cip_header[0], cip_header[1]);···541494542495 /* Calculate data blocks */543496 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;544544- if (payload_quadlets < 3 ||497497+ if (payload_length < 12 ||545498 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {546499 data_blocks = 0;547500 } else {···557510 if (s->flags & CIP_WRONG_DBS)558511 data_block_quadlets = s->data_block_quadlets;559512560560- data_blocks = (payload_quadlets - 2) / data_block_quadlets;513513+ data_blocks = (payload_length / 4 - 2) /514514+ data_block_quadlets;561515 }562516563517 /* Check data block counter continuity */···599551 s->data_block_counter =600552 (data_block_counter + data_blocks) & 0xff;601553end:554554+ if (queue_in_packet(s) < 0)555555+ return -EIO;556556+557557+ pcm = ACCESS_ONCE(s->pcm);558558+ if (pcm && pcm_frames > 0)559559+ update_pcm_pointers(s, pcm, pcm_frames);560560+561561+ return 0;562562+}563563+564564+static int handle_in_packet_without_header(struct amdtp_stream *s,565565+ unsigned int payload_quadlets, unsigned int cycle,566566+ unsigned int index)567567+{568568+ __be32 *buffer;569569+ unsigned int data_blocks;570570+ struct snd_pcm_substream *pcm;571571+ unsigned int pcm_frames;572572+573573+ buffer = s->buffer.packets[s->packet_index].buffer;574574+ data_blocks = payload_quadlets / s->data_block_quadlets;575575+576576+ trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks,577577+ index);578578+579579+ pcm_frames = s->process_data_blocks(s, buffer, data_blocks, NULL);580580+ s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;581581+602582 if (queue_in_packet(s) < 0)603583 return -EIO;604584···680604681605 for (i = 0; i < packets; ++i) {682606 cycle = increment_cycle_count(cycle, 1);683683- if (handle_out_packet(s, cycle, i) < 0) {607607+ if (s->handle_packet(s, 0, cycle, i) < 0) {684608 s->packet_index = -1;685609 amdtp_stream_pcm_abort(s);686610 return;···696620{697621 struct amdtp_stream *s = private_data;698622 unsigned int i, packets;699699- unsigned int payload_quadlets, max_payload_quadlets;623623+ unsigned int payload_length, max_payload_length;700624 __be32 *headers = header;701625 u32 cycle;702626···712636 cycle = decrement_cycle_count(cycle, packets);713637714638 /* For buffer-over-run prevention. */715715- max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4;639639+ max_payload_length = s->max_payload_length;716640717641 for (i = 0; i < packets; i++) {718642 cycle = increment_cycle_count(cycle, 1);719643720720- /* The number of quadlets in this packet */721721- payload_quadlets =722722- (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT) / 4;723723- if (payload_quadlets > max_payload_quadlets) {644644+ /* The number of bytes in this packet */645645+ payload_length =646646+ (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT);647647+ if (payload_length > max_payload_length) {724648 dev_err(&s->unit->device,725725- "Detect jumbo payload: %02x %02x\n",726726- payload_quadlets, max_payload_quadlets);649649+ "Detect jumbo payload: %04x %04x\n",650650+ payload_length, max_payload_length);727651 break;728652 }729653730730- if (handle_in_packet(s, payload_quadlets, cycle, i) < 0)654654+ if (s->handle_packet(s, payload_length, cycle, i) < 0)731655 break;732656 }733657···747671 void *header, void *private_data)748672{749673 struct amdtp_stream *s = private_data;674674+ u32 cycle;675675+ unsigned int packets;676676+677677+ s->max_payload_length = amdtp_stream_get_max_payload(s);750678751679 /*752680 * For in-stream, first packet has come.···759679 s->callbacked = true;760680 wake_up(&s->callback_wait);761681762762- if (s->direction == AMDTP_IN_STREAM)682682+ cycle = compute_cycle_count(tstamp);683683+684684+ if (s->direction == AMDTP_IN_STREAM) {685685+ packets = header_length / IN_PACKET_HEADER_SIZE;686686+ cycle = decrement_cycle_count(cycle, packets);763687 context->callback.sc = in_stream_callback;764764- else688688+ if (s->flags & CIP_NO_HEADER)689689+ s->handle_packet = handle_in_packet_without_header;690690+ else691691+ s->handle_packet = handle_in_packet;692692+ } else {693693+ packets = header_length / 4;694694+ cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets);765695 context->callback.sc = out_stream_callback;696696+ if (s->flags & CIP_NO_HEADER)697697+ s->handle_packet = handle_out_packet_without_header;698698+ else699699+ s->handle_packet = handle_out_packet;700700+ }701701+702702+ s->start_cycle = cycle;766703767704 context->callback.sc(context, tstamp, header_length, header, s);768705}···856759857760 amdtp_stream_update(s);858761762762+ if (s->flags & CIP_NO_HEADER)763763+ s->tag = TAG_NO_CIP_HEADER;764764+ else765765+ s->tag = TAG_CIP;766766+859767 s->packet_index = 0;860768 do {861769 if (s->direction == AMDTP_IN_STREAM)···873771874772 /* NOTE: TAG1 matches CIP. This just affects in stream. */875773 tag = FW_ISO_CONTEXT_MATCH_TAG1;876876- if (s->flags & CIP_EMPTY_WITH_TAG0)774774+ if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))877775 tag |= FW_ISO_CONTEXT_MATCH_TAG0;878776879777 s->callbacked = false;
+14-2
sound/firewire/amdtp-stream.h
···1818 * SYT_INTERVAL samples, with these two types alternating so that1919 * the overall sample rate comes out right.2020 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.2121- * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet2222- * corresponds to the end of event in the packet. Out of IEC 61883.2121+ * @CIP_DBC_IS_END_EVENT: The value of dbc in an packet corresponds to the end2222+ * of event in the packet. Out of IEC 61883.2323 * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets.2424 * The value of data_block_quadlets is used instead of reported value.2525 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is···2929 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an3030 * packet is larger than IEC 61883-6 defines. Current implementation3131 * allows 5 times as large as IEC 61883-6 defines.3232+ * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include3333+ * valid EOH.3434+ * @CIP_NO_HEADERS: a lack of headers in packets3235 */3336enum cip_flags {3437 CIP_NONBLOCKING = 0x00,···4239 CIP_SKIP_DBC_ZERO_CHECK = 0x10,4340 CIP_EMPTY_HAS_WRONG_DBC = 0x20,4441 CIP_JUMBO_PAYLOAD = 0x40,4242+ CIP_HEADER_WITHOUT_EOH = 0x80,4343+ CIP_NO_HEADER = 0x100,4544};46454746/**···106101 struct fw_iso_context *context;107102 struct iso_packets_buffer buffer;108103 int packet_index;104104+ int tag;105105+ int (*handle_packet)(struct amdtp_stream *s,106106+ unsigned int payload_quadlets, unsigned int cycle,107107+ unsigned int index);108108+ unsigned int max_payload_length;109109110110 /* For CIP headers. */111111 unsigned int source_node_id_field;112112 unsigned int data_block_quadlets;113113 unsigned int data_block_counter;114114+ unsigned int sph;114115 unsigned int fmt;115116 unsigned int fdf;116117 /* quirk: fixed interval of dbc between previos/current packets. */···141130 /* To wait for first packet. */142131 bool callbacked;143132 wait_queue_head_t callback_wait;133133+ u32 start_cycle;144134145135 /* For backends to process data blocks. */146136 void *protocol;
···2828 */2929#define MAX_MIDI_RX_BLOCKS 830303131+/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */3232+#define MAX_MIDI_PORTS 33333+3134/*3235 * The double-oh-three algorithm was discovered by Robin Gareus and Damien3336 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.···4542 unsigned int pcm_channels;4643 struct dot_state state;47444848- unsigned int midi_ports;4949- /* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */5050- struct snd_rawmidi_substream *midi[2];5151- int midi_fifo_used[2];4545+ struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];4646+ int midi_fifo_used[MAX_MIDI_PORTS];5247 int midi_fifo_limit;53485449 void (*transfer_samples)(struct amdtp_stream *s,···125124 return -EBUSY;126125127126 /*128128- * A first data channel is for MIDI conformant data channel, the rest is129129- * Multi Bit Linear Audio data channel.127127+ * A first data channel is for MIDI messages, the rest is Multi Bit128128+ * Linear Audio data channel.130129 */131130 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);132131 if (err < 0)···135134 s->fdf = AMDTP_FDF_AM824 | s->sfc;136135137136 p->pcm_channels = pcm_channels;138138-139139- if (s->direction == AMDTP_IN_STREAM)140140- p->midi_ports = DOT_MIDI_IN_PORTS;141141- else142142- p->midi_ports = DOT_MIDI_OUT_PORTS;143137144138 /*145139 * We do not know the actual MIDI FIFO size of most devices. Just···277281 b = (u8 *)&buffer[0];278282279283 len = 0;280280- if (port < p->midi_ports &&284284+ if (port < MAX_MIDI_PORTS &&281285 midi_ratelimit_per_packet(s, port) &&282286 p->midi[port] != NULL)283287 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);284288285289 if (len > 0) {286286- b[3] = (0x10 << port) | len;290290+ /*291291+ * Upper 4 bits of LSB represent port number.292292+ * - 0000b: physical MIDI port 1.293293+ * - 0010b: physical MIDI port 2.294294+ * - 1110b: console MIDI port.295295+ */296296+ if (port == 2)297297+ b[3] = 0xe0;298298+ else if (port == 1)299299+ b[3] = 0x20;300300+ else301301+ b[3] = 0x00;302302+ b[3] |= len;287303 midi_use_bytes(s, port, len);288304 } else {289305 b[1] = 0;···317309318310 for (f = 0; f < data_blocks; f++) {319311 b = (u8 *)&buffer[0];320320- port = b[3] >> 4;321321- len = b[3] & 0x0f;322312323323- if (port < p->midi_ports && p->midi[port] && len > 0)324324- snd_rawmidi_receive(p->midi[port], b + 1, len);313313+ len = b[3] & 0x0f;314314+ if (len > 0) {315315+ /*316316+ * Upper 4 bits of LSB represent port number.317317+ * - 0000b: physical MIDI port 1. Use port 0.318318+ * - 1110b: console MIDI port. Use port 2.319319+ */320320+ if (b[3] >> 4 > 0)321321+ port = 2;322322+ else323323+ port = 0;324324+325325+ if (port < MAX_MIDI_PORTS && p->midi[port])326326+ snd_rawmidi_receive(p->midi[port], b + 1, len);327327+ }325328326329 buffer += s->data_block_quadlets;327330 }···383364{384365 struct amdtp_dot *p = s->protocol;385366386386- if (port < p->midi_ports)367367+ if (port < MAX_MIDI_PORTS)387368 ACCESS_ONCE(p->midi[port]) = midi;388369}389370
···11+/*22+ * amdtp-ff.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include <sound/pcm.h>1010+#include "ff.h"1111+1212+struct amdtp_ff {1313+ unsigned int pcm_channels;1414+};1515+1616+int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate,1717+ unsigned int pcm_channels)1818+{1919+ struct amdtp_ff *p = s->protocol;2020+ unsigned int data_channels;2121+2222+ if (amdtp_stream_running(s))2323+ return -EBUSY;2424+2525+ p->pcm_channels = pcm_channels;2626+ data_channels = pcm_channels;2727+2828+ return amdtp_stream_set_parameters(s, rate, data_channels);2929+}3030+3131+static void write_pcm_s32(struct amdtp_stream *s,3232+ struct snd_pcm_substream *pcm,3333+ __le32 *buffer, unsigned int frames)3434+{3535+ struct amdtp_ff *p = s->protocol;3636+ struct snd_pcm_runtime *runtime = pcm->runtime;3737+ unsigned int channels, remaining_frames, i, c;3838+ const u32 *src;3939+4040+ channels = p->pcm_channels;4141+ src = (void *)runtime->dma_area +4242+ frames_to_bytes(runtime, s->pcm_buffer_pointer);4343+ remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;4444+4545+ for (i = 0; i < frames; ++i) {4646+ for (c = 0; c < channels; ++c) {4747+ buffer[c] = cpu_to_le32(*src);4848+ src++;4949+ }5050+ buffer += s->data_block_quadlets;5151+ if (--remaining_frames == 0)5252+ src = (void *)runtime->dma_area;5353+ }5454+}5555+5656+static void read_pcm_s32(struct amdtp_stream *s,5757+ struct snd_pcm_substream *pcm,5858+ __le32 *buffer, unsigned int frames)5959+{6060+ struct amdtp_ff *p = s->protocol;6161+ struct snd_pcm_runtime *runtime = pcm->runtime;6262+ unsigned int channels, remaining_frames, i, c;6363+ u32 *dst;6464+6565+ channels = p->pcm_channels;6666+ dst = (void *)runtime->dma_area +6767+ frames_to_bytes(runtime, s->pcm_buffer_pointer);6868+ remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer;6969+7070+ for (i = 0; i < frames; ++i) {7171+ for (c = 0; c < channels; ++c) {7272+ *dst = le32_to_cpu(buffer[c]) & 0xffffff00;7373+ dst++;7474+ }7575+ buffer += s->data_block_quadlets;7676+ if (--remaining_frames == 0)7777+ dst = (void *)runtime->dma_area;7878+ }7979+}8080+8181+static void write_pcm_silence(struct amdtp_stream *s,8282+ __le32 *buffer, unsigned int frames)8383+{8484+ struct amdtp_ff *p = s->protocol;8585+ unsigned int i, c, channels = p->pcm_channels;8686+8787+ for (i = 0; i < frames; ++i) {8888+ for (c = 0; c < channels; ++c)8989+ buffer[c] = cpu_to_le32(0x00000000);9090+ buffer += s->data_block_quadlets;9191+ }9292+}9393+9494+int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s,9595+ struct snd_pcm_runtime *runtime)9696+{9797+ int err;9898+9999+ err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);100100+ if (err < 0)101101+ return err;102102+103103+ return amdtp_stream_add_pcm_hw_constraints(s, runtime);104104+}105105+106106+static unsigned int process_rx_data_blocks(struct amdtp_stream *s,107107+ __be32 *buffer,108108+ unsigned int data_blocks,109109+ unsigned int *syt)110110+{111111+ struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);112112+ unsigned int pcm_frames;113113+114114+ if (pcm) {115115+ write_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks);116116+ pcm_frames = data_blocks;117117+ } else {118118+ write_pcm_silence(s, (__le32 *)buffer, data_blocks);119119+ pcm_frames = 0;120120+ }121121+122122+ return pcm_frames;123123+}124124+125125+static unsigned int process_tx_data_blocks(struct amdtp_stream *s,126126+ __be32 *buffer,127127+ unsigned int data_blocks,128128+ unsigned int *syt)129129+{130130+ struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm);131131+ unsigned int pcm_frames;132132+133133+ if (pcm) {134134+ read_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks);135135+ pcm_frames = data_blocks;136136+ } else {137137+ pcm_frames = 0;138138+ }139139+140140+ return pcm_frames;141141+}142142+143143+int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit,144144+ enum amdtp_stream_direction dir)145145+{146146+ amdtp_stream_process_data_blocks_t process_data_blocks;147147+148148+ if (dir == AMDTP_IN_STREAM)149149+ process_data_blocks = process_tx_data_blocks;150150+ else151151+ process_data_blocks = process_rx_data_blocks;152152+153153+ return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0,154154+ process_data_blocks, sizeof(struct amdtp_ff));155155+}
+191
sound/firewire/fireface/ff-hwdep.c
···11+/*22+ * ff-hwdep.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+/*1010+ * This codes give three functionality.1111+ *1212+ * 1.get firewire node information1313+ * 2.get notification about starting/stopping stream1414+ * 3.lock/unlock stream1515+ */1616+1717+#include "ff.h"1818+1919+static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,2020+ loff_t *offset)2121+{2222+ struct snd_ff *ff = hwdep->private_data;2323+ DEFINE_WAIT(wait);2424+ union snd_firewire_event event;2525+2626+ spin_lock_irq(&ff->lock);2727+2828+ while (!ff->dev_lock_changed) {2929+ prepare_to_wait(&ff->hwdep_wait, &wait, TASK_INTERRUPTIBLE);3030+ spin_unlock_irq(&ff->lock);3131+ schedule();3232+ finish_wait(&ff->hwdep_wait, &wait);3333+ if (signal_pending(current))3434+ return -ERESTARTSYS;3535+ spin_lock_irq(&ff->lock);3636+ }3737+3838+ memset(&event, 0, sizeof(event));3939+ if (ff->dev_lock_changed) {4040+ event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;4141+ event.lock_status.status = (ff->dev_lock_count > 0);4242+ ff->dev_lock_changed = false;4343+4444+ count = min_t(long, count, sizeof(event.lock_status));4545+ }4646+4747+ spin_unlock_irq(&ff->lock);4848+4949+ if (copy_to_user(buf, &event, count))5050+ return -EFAULT;5151+5252+ return count;5353+}5454+5555+static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file,5656+ poll_table *wait)5757+{5858+ struct snd_ff *ff = hwdep->private_data;5959+ unsigned int events;6060+6161+ poll_wait(file, &ff->hwdep_wait, wait);6262+6363+ spin_lock_irq(&ff->lock);6464+ if (ff->dev_lock_changed)6565+ events = POLLIN | POLLRDNORM;6666+ else6767+ events = 0;6868+ spin_unlock_irq(&ff->lock);6969+7070+ return events;7171+}7272+7373+static int hwdep_get_info(struct snd_ff *ff, void __user *arg)7474+{7575+ struct fw_device *dev = fw_parent_device(ff->unit);7676+ struct snd_firewire_get_info info;7777+7878+ memset(&info, 0, sizeof(info));7979+ info.type = SNDRV_FIREWIRE_TYPE_FIREFACE;8080+ info.card = dev->card->index;8181+ *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]);8282+ *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]);8383+ strlcpy(info.device_name, dev_name(&dev->device),8484+ sizeof(info.device_name));8585+8686+ if (copy_to_user(arg, &info, sizeof(info)))8787+ return -EFAULT;8888+8989+ return 0;9090+}9191+9292+static int hwdep_lock(struct snd_ff *ff)9393+{9494+ int err;9595+9696+ spin_lock_irq(&ff->lock);9797+9898+ if (ff->dev_lock_count == 0) {9999+ ff->dev_lock_count = -1;100100+ err = 0;101101+ } else {102102+ err = -EBUSY;103103+ }104104+105105+ spin_unlock_irq(&ff->lock);106106+107107+ return err;108108+}109109+110110+static int hwdep_unlock(struct snd_ff *ff)111111+{112112+ int err;113113+114114+ spin_lock_irq(&ff->lock);115115+116116+ if (ff->dev_lock_count == -1) {117117+ ff->dev_lock_count = 0;118118+ err = 0;119119+ } else {120120+ err = -EBADFD;121121+ }122122+123123+ spin_unlock_irq(&ff->lock);124124+125125+ return err;126126+}127127+128128+static int hwdep_release(struct snd_hwdep *hwdep, struct file *file)129129+{130130+ struct snd_ff *ff = hwdep->private_data;131131+132132+ spin_lock_irq(&ff->lock);133133+ if (ff->dev_lock_count == -1)134134+ ff->dev_lock_count = 0;135135+ spin_unlock_irq(&ff->lock);136136+137137+ return 0;138138+}139139+140140+static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file,141141+ unsigned int cmd, unsigned long arg)142142+{143143+ struct snd_ff *ff = hwdep->private_data;144144+145145+ switch (cmd) {146146+ case SNDRV_FIREWIRE_IOCTL_GET_INFO:147147+ return hwdep_get_info(ff, (void __user *)arg);148148+ case SNDRV_FIREWIRE_IOCTL_LOCK:149149+ return hwdep_lock(ff);150150+ case SNDRV_FIREWIRE_IOCTL_UNLOCK:151151+ return hwdep_unlock(ff);152152+ default:153153+ return -ENOIOCTLCMD;154154+ }155155+}156156+157157+#ifdef CONFIG_COMPAT158158+static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file,159159+ unsigned int cmd, unsigned long arg)160160+{161161+ return hwdep_ioctl(hwdep, file, cmd,162162+ (unsigned long)compat_ptr(arg));163163+}164164+#else165165+#define hwdep_compat_ioctl NULL166166+#endif167167+168168+int snd_ff_create_hwdep_devices(struct snd_ff *ff)169169+{170170+ static const struct snd_hwdep_ops hwdep_ops = {171171+ .read = hwdep_read,172172+ .release = hwdep_release,173173+ .poll = hwdep_poll,174174+ .ioctl = hwdep_ioctl,175175+ .ioctl_compat = hwdep_compat_ioctl,176176+ };177177+ struct snd_hwdep *hwdep;178178+ int err;179179+180180+ err = snd_hwdep_new(ff->card, ff->card->driver, 0, &hwdep);181181+ if (err < 0)182182+ return err;183183+184184+ strcpy(hwdep->name, ff->card->driver);185185+ hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREFACE;186186+ hwdep->ops = hwdep_ops;187187+ hwdep->private_data = ff;188188+ hwdep->exclusive = true;189189+190190+ return 0;191191+}
+131
sound/firewire/fireface/ff-midi.c
···11+/*22+ * ff-midi.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "ff.h"1010+1111+static int midi_capture_open(struct snd_rawmidi_substream *substream)1212+{1313+ /* Do nothing. */1414+ return 0;1515+}1616+1717+static int midi_playback_open(struct snd_rawmidi_substream *substream)1818+{1919+ struct snd_ff *ff = substream->rmidi->private_data;2020+2121+ /* Initialize internal status. */2222+ ff->running_status[substream->number] = 0;2323+ ff->rx_midi_error[substream->number] = false;2424+2525+ ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = substream;2626+2727+ return 0;2828+}2929+3030+static int midi_capture_close(struct snd_rawmidi_substream *substream)3131+{3232+ /* Do nothing. */3333+ return 0;3434+}3535+3636+static int midi_playback_close(struct snd_rawmidi_substream *substream)3737+{3838+ struct snd_ff *ff = substream->rmidi->private_data;3939+4040+ cancel_work_sync(&ff->rx_midi_work[substream->number]);4141+ ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = NULL;4242+4343+ return 0;4444+}4545+4646+static void midi_capture_trigger(struct snd_rawmidi_substream *substream,4747+ int up)4848+{4949+ struct snd_ff *ff = substream->rmidi->private_data;5050+ unsigned long flags;5151+5252+ spin_lock_irqsave(&ff->lock, flags);5353+5454+ if (up)5555+ ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) =5656+ substream;5757+ else5858+ ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) = NULL;5959+6060+ spin_unlock_irqrestore(&ff->lock, flags);6161+}6262+6363+static void midi_playback_trigger(struct snd_rawmidi_substream *substream,6464+ int up)6565+{6666+ struct snd_ff *ff = substream->rmidi->private_data;6767+ unsigned long flags;6868+6969+ spin_lock_irqsave(&ff->lock, flags);7070+7171+ if (up || !ff->rx_midi_error[substream->number])7272+ schedule_work(&ff->rx_midi_work[substream->number]);7373+7474+ spin_unlock_irqrestore(&ff->lock, flags);7575+}7676+7777+static struct snd_rawmidi_ops midi_capture_ops = {7878+ .open = midi_capture_open,7979+ .close = midi_capture_close,8080+ .trigger = midi_capture_trigger,8181+};8282+8383+static struct snd_rawmidi_ops midi_playback_ops = {8484+ .open = midi_playback_open,8585+ .close = midi_playback_close,8686+ .trigger = midi_playback_trigger,8787+};8888+8989+static void set_midi_substream_names(struct snd_rawmidi_str *stream,9090+ const char *const name)9191+{9292+ struct snd_rawmidi_substream *substream;9393+9494+ list_for_each_entry(substream, &stream->substreams, list) {9595+ snprintf(substream->name, sizeof(substream->name),9696+ "%s MIDI %d", name, substream->number + 1);9797+ }9898+}9999+100100+int snd_ff_create_midi_devices(struct snd_ff *ff)101101+{102102+ struct snd_rawmidi *rmidi;103103+ struct snd_rawmidi_str *stream;104104+ int err;105105+106106+ err = snd_rawmidi_new(ff->card, ff->card->driver, 0,107107+ ff->spec->midi_out_ports, ff->spec->midi_in_ports,108108+ &rmidi);109109+ if (err < 0)110110+ return err;111111+112112+ snprintf(rmidi->name, sizeof(rmidi->name),113113+ "%s MIDI", ff->card->shortname);114114+ rmidi->private_data = ff;115115+116116+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;117117+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,118118+ &midi_capture_ops);119119+ stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT];120120+ set_midi_substream_names(stream, ff->card->shortname);121121+122122+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;123123+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,124124+ &midi_playback_ops);125125+ stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];126126+ set_midi_substream_names(stream, ff->card->shortname);127127+128128+ rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;129129+130130+ return 0;131131+}
+409
sound/firewire/fireface/ff-pcm.c
···11+/*22+ * ff-pcm.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "ff.h"1010+1111+static inline unsigned int get_multiplier_mode_with_index(unsigned int index)1212+{1313+ return ((int)index - 1) / 2;1414+}1515+1616+static int hw_rule_rate(struct snd_pcm_hw_params *params,1717+ struct snd_pcm_hw_rule *rule)1818+{1919+ const unsigned int *pcm_channels = rule->private;2020+ struct snd_interval *r =2121+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);2222+ const struct snd_interval *c =2323+ hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS);2424+ struct snd_interval t = {2525+ .min = UINT_MAX, .max = 0, .integer = 12626+ };2727+ unsigned int i, mode;2828+2929+ for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {3030+ mode = get_multiplier_mode_with_index(i);3131+ if (!snd_interval_test(c, pcm_channels[mode]))3232+ continue;3333+3434+ t.min = min(t.min, amdtp_rate_table[i]);3535+ t.max = max(t.max, amdtp_rate_table[i]);3636+ }3737+3838+ return snd_interval_refine(r, &t);3939+}4040+4141+static int hw_rule_channels(struct snd_pcm_hw_params *params,4242+ struct snd_pcm_hw_rule *rule)4343+{4444+ const unsigned int *pcm_channels = rule->private;4545+ struct snd_interval *c =4646+ hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);4747+ const struct snd_interval *r =4848+ hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE);4949+ struct snd_interval t = {5050+ .min = UINT_MAX, .max = 0, .integer = 15151+ };5252+ unsigned int i, mode;5353+5454+ for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {5555+ mode = get_multiplier_mode_with_index(i);5656+ if (!snd_interval_test(r, amdtp_rate_table[i]))5757+ continue;5858+5959+ t.min = min(t.min, pcm_channels[mode]);6060+ t.max = max(t.max, pcm_channels[mode]);6161+ }6262+6363+ return snd_interval_refine(c, &t);6464+}6565+6666+static void limit_channels_and_rates(struct snd_pcm_hardware *hw,6767+ const unsigned int *pcm_channels)6868+{6969+ unsigned int mode;7070+ unsigned int rate, channels;7171+ int i;7272+7373+ hw->channels_min = UINT_MAX;7474+ hw->channels_max = 0;7575+ hw->rate_min = UINT_MAX;7676+ hw->rate_max = 0;7777+7878+ for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) {7979+ mode = get_multiplier_mode_with_index(i);8080+8181+ channels = pcm_channels[mode];8282+ if (pcm_channels[mode] == 0)8383+ continue;8484+ hw->channels_min = min(hw->channels_min, channels);8585+ hw->channels_max = max(hw->channels_max, channels);8686+8787+ rate = amdtp_rate_table[i];8888+ hw->rates |= snd_pcm_rate_to_rate_bit(rate);8989+ hw->rate_min = min(hw->rate_min, rate);9090+ hw->rate_max = max(hw->rate_max, rate);9191+ }9292+}9393+9494+static void limit_period_and_buffer(struct snd_pcm_hardware *hw)9595+{9696+ hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */9797+ hw->periods_max = UINT_MAX;9898+9999+ hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */100100+101101+ /* Just to prevent from allocating much pages. */102102+ hw->period_bytes_max = hw->period_bytes_min * 2048;103103+ hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min;104104+}105105+106106+static int pcm_init_hw_params(struct snd_ff *ff,107107+ struct snd_pcm_substream *substream)108108+{109109+ struct snd_pcm_runtime *runtime = substream->runtime;110110+ struct amdtp_stream *s;111111+ const unsigned int *pcm_channels;112112+ int err;113113+114114+ runtime->hw.info = SNDRV_PCM_INFO_BATCH |115115+ SNDRV_PCM_INFO_BLOCK_TRANSFER |116116+ SNDRV_PCM_INFO_INTERLEAVED |117117+ SNDRV_PCM_INFO_JOINT_DUPLEX |118118+ SNDRV_PCM_INFO_MMAP |119119+ SNDRV_PCM_INFO_MMAP_VALID;120120+121121+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {122122+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;123123+ s = &ff->tx_stream;124124+ pcm_channels = ff->spec->pcm_capture_channels;125125+ } else {126126+ runtime->hw.formats = SNDRV_PCM_FMTBIT_S32;127127+ s = &ff->rx_stream;128128+ pcm_channels = ff->spec->pcm_playback_channels;129129+ }130130+131131+ /* limit rates */132132+ limit_channels_and_rates(&runtime->hw, pcm_channels);133133+ limit_period_and_buffer(&runtime->hw);134134+135135+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,136136+ hw_rule_channels, (void *)pcm_channels,137137+ SNDRV_PCM_HW_PARAM_RATE, -1);138138+ if (err < 0)139139+ return err;140140+141141+ err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,142142+ hw_rule_rate, (void *)pcm_channels,143143+ SNDRV_PCM_HW_PARAM_CHANNELS, -1);144144+ if (err < 0)145145+ return err;146146+147147+ return amdtp_ff_add_pcm_hw_constraints(s, runtime);148148+}149149+150150+static int pcm_open(struct snd_pcm_substream *substream)151151+{152152+ struct snd_ff *ff = substream->private_data;153153+ unsigned int rate;154154+ enum snd_ff_clock_src src;155155+ int i, err;156156+157157+ err = snd_ff_stream_lock_try(ff);158158+ if (err < 0)159159+ return err;160160+161161+ err = pcm_init_hw_params(ff, substream);162162+ if (err < 0) {163163+ snd_ff_stream_lock_release(ff);164164+ return err;165165+ }166166+167167+ err = ff->spec->protocol->get_clock(ff, &rate, &src);168168+ if (err < 0) {169169+ snd_ff_stream_lock_release(ff);170170+ return err;171171+ }172172+173173+ if (src != SND_FF_CLOCK_SRC_INTERNAL) {174174+ for (i = 0; i < CIP_SFC_COUNT; ++i) {175175+ if (amdtp_rate_table[i] == rate)176176+ break;177177+ }178178+ /*179179+ * The unit is configured at sampling frequency which packet180180+ * streaming engine can't support.181181+ */182182+ if (i >= CIP_SFC_COUNT) {183183+ snd_ff_stream_lock_release(ff);184184+ return -EIO;185185+ }186186+187187+ substream->runtime->hw.rate_min = rate;188188+ substream->runtime->hw.rate_max = rate;189189+ } else {190190+ if (amdtp_stream_pcm_running(&ff->rx_stream) ||191191+ amdtp_stream_pcm_running(&ff->tx_stream)) {192192+ rate = amdtp_rate_table[ff->rx_stream.sfc];193193+ substream->runtime->hw.rate_min = rate;194194+ substream->runtime->hw.rate_max = rate;195195+ }196196+ }197197+198198+ snd_pcm_set_sync(substream);199199+200200+ return 0;201201+}202202+203203+static int pcm_close(struct snd_pcm_substream *substream)204204+{205205+ struct snd_ff *ff = substream->private_data;206206+207207+ snd_ff_stream_lock_release(ff);208208+209209+ return 0;210210+}211211+212212+static int pcm_capture_hw_params(struct snd_pcm_substream *substream,213213+ struct snd_pcm_hw_params *hw_params)214214+{215215+ struct snd_ff *ff = substream->private_data;216216+ int err;217217+218218+ err = snd_pcm_lib_alloc_vmalloc_buffer(substream,219219+ params_buffer_bytes(hw_params));220220+ if (err < 0)221221+ return err;222222+223223+ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {224224+ mutex_lock(&ff->mutex);225225+ ff->substreams_counter++;226226+ mutex_unlock(&ff->mutex);227227+ }228228+229229+ return 0;230230+}231231+232232+static int pcm_playback_hw_params(struct snd_pcm_substream *substream,233233+ struct snd_pcm_hw_params *hw_params)234234+{235235+ struct snd_ff *ff = substream->private_data;236236+ int err;237237+238238+ err = snd_pcm_lib_alloc_vmalloc_buffer(substream,239239+ params_buffer_bytes(hw_params));240240+ if (err < 0)241241+ return err;242242+243243+ if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) {244244+ mutex_lock(&ff->mutex);245245+ ff->substreams_counter++;246246+ mutex_unlock(&ff->mutex);247247+ }248248+249249+ return 0;250250+}251251+252252+static int pcm_capture_hw_free(struct snd_pcm_substream *substream)253253+{254254+ struct snd_ff *ff = substream->private_data;255255+256256+ mutex_lock(&ff->mutex);257257+258258+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)259259+ ff->substreams_counter--;260260+261261+ snd_ff_stream_stop_duplex(ff);262262+263263+ mutex_unlock(&ff->mutex);264264+265265+ return snd_pcm_lib_free_vmalloc_buffer(substream);266266+}267267+268268+static int pcm_playback_hw_free(struct snd_pcm_substream *substream)269269+{270270+ struct snd_ff *ff = substream->private_data;271271+272272+ mutex_lock(&ff->mutex);273273+274274+ if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)275275+ ff->substreams_counter--;276276+277277+ snd_ff_stream_stop_duplex(ff);278278+279279+ mutex_unlock(&ff->mutex);280280+281281+ return snd_pcm_lib_free_vmalloc_buffer(substream);282282+}283283+284284+static int pcm_capture_prepare(struct snd_pcm_substream *substream)285285+{286286+ struct snd_ff *ff = substream->private_data;287287+ struct snd_pcm_runtime *runtime = substream->runtime;288288+ int err;289289+290290+ mutex_lock(&ff->mutex);291291+292292+ err = snd_ff_stream_start_duplex(ff, runtime->rate);293293+ if (err >= 0)294294+ amdtp_stream_pcm_prepare(&ff->tx_stream);295295+296296+ mutex_unlock(&ff->mutex);297297+298298+ return err;299299+}300300+301301+static int pcm_playback_prepare(struct snd_pcm_substream *substream)302302+{303303+ struct snd_ff *ff = substream->private_data;304304+ struct snd_pcm_runtime *runtime = substream->runtime;305305+ int err;306306+307307+ mutex_lock(&ff->mutex);308308+309309+ err = snd_ff_stream_start_duplex(ff, runtime->rate);310310+ if (err >= 0)311311+ amdtp_stream_pcm_prepare(&ff->rx_stream);312312+313313+ mutex_unlock(&ff->mutex);314314+315315+ return err;316316+}317317+318318+static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)319319+{320320+ struct snd_ff *ff = substream->private_data;321321+322322+ switch (cmd) {323323+ case SNDRV_PCM_TRIGGER_START:324324+ amdtp_stream_pcm_trigger(&ff->tx_stream, substream);325325+ break;326326+ case SNDRV_PCM_TRIGGER_STOP:327327+ amdtp_stream_pcm_trigger(&ff->tx_stream, NULL);328328+ break;329329+ default:330330+ return -EINVAL;331331+ }332332+333333+ return 0;334334+}335335+336336+static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)337337+{338338+ struct snd_ff *ff = substream->private_data;339339+340340+ switch (cmd) {341341+ case SNDRV_PCM_TRIGGER_START:342342+ amdtp_stream_pcm_trigger(&ff->rx_stream, substream);343343+ break;344344+ case SNDRV_PCM_TRIGGER_STOP:345345+ amdtp_stream_pcm_trigger(&ff->rx_stream, NULL);346346+ break;347347+ default:348348+ return -EINVAL;349349+ }350350+351351+ return 0;352352+}353353+354354+static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm)355355+{356356+ struct snd_ff *ff = sbstrm->private_data;357357+358358+ return amdtp_stream_pcm_pointer(&ff->tx_stream);359359+}360360+361361+static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm)362362+{363363+ struct snd_ff *ff = sbstrm->private_data;364364+365365+ return amdtp_stream_pcm_pointer(&ff->rx_stream);366366+}367367+368368+static struct snd_pcm_ops pcm_capture_ops = {369369+ .open = pcm_open,370370+ .close = pcm_close,371371+ .ioctl = snd_pcm_lib_ioctl,372372+ .hw_params = pcm_capture_hw_params,373373+ .hw_free = pcm_capture_hw_free,374374+ .prepare = pcm_capture_prepare,375375+ .trigger = pcm_capture_trigger,376376+ .pointer = pcm_capture_pointer,377377+ .page = snd_pcm_lib_get_vmalloc_page,378378+};379379+380380+static struct snd_pcm_ops pcm_playback_ops = {381381+ .open = pcm_open,382382+ .close = pcm_close,383383+ .ioctl = snd_pcm_lib_ioctl,384384+ .hw_params = pcm_playback_hw_params,385385+ .hw_free = pcm_playback_hw_free,386386+ .prepare = pcm_playback_prepare,387387+ .trigger = pcm_playback_trigger,388388+ .pointer = pcm_playback_pointer,389389+ .page = snd_pcm_lib_get_vmalloc_page,390390+ .mmap = snd_pcm_lib_mmap_vmalloc,391391+};392392+393393+int snd_ff_create_pcm_devices(struct snd_ff *ff)394394+{395395+ struct snd_pcm *pcm;396396+ int err;397397+398398+ err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm);399399+ if (err < 0)400400+ return err;401401+402402+ pcm->private_data = ff;403403+ snprintf(pcm->name, sizeof(pcm->name),404404+ "%s PCM", ff->card->shortname);405405+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops);406406+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops);407407+408408+ return 0;409409+}
+63
sound/firewire/fireface/ff-proc.c
···11+/*22+ * ff-proc.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "./ff.h"1010+1111+static void proc_dump_clock_config(struct snd_info_entry *entry,1212+ struct snd_info_buffer *buffer)1313+{1414+ struct snd_ff *ff = entry->private_data;1515+1616+ ff->spec->protocol->dump_clock_config(ff, buffer);1717+}1818+1919+static void proc_dump_sync_status(struct snd_info_entry *entry,2020+ struct snd_info_buffer *buffer)2121+{2222+ struct snd_ff *ff = entry->private_data;2323+2424+ ff->spec->protocol->dump_sync_status(ff, buffer);2525+}2626+2727+static void add_node(struct snd_ff *ff, struct snd_info_entry *root,2828+ const char *name,2929+ void (*op)(struct snd_info_entry *e,3030+ struct snd_info_buffer *b))3131+{3232+ struct snd_info_entry *entry;3333+3434+ entry = snd_info_create_card_entry(ff->card, name, root);3535+ if (entry == NULL)3636+ return;3737+3838+ snd_info_set_text_ops(entry, ff, op);3939+ if (snd_info_register(entry) < 0)4040+ snd_info_free_entry(entry);4141+}4242+4343+void snd_ff_proc_init(struct snd_ff *ff)4444+{4545+ struct snd_info_entry *root;4646+4747+ /*4848+ * All nodes are automatically removed at snd_card_disconnect(),4949+ * by following to link list.5050+ */5151+ root = snd_info_create_card_entry(ff->card, "firewire",5252+ ff->card->proc_root);5353+ if (root == NULL)5454+ return;5555+ root->mode = S_IFDIR | S_IRUGO | S_IXUGO;5656+ if (snd_info_register(root) < 0) {5757+ snd_info_free_entry(root);5858+ return;5959+ }6060+6161+ add_node(ff, root, "clock-config", proc_dump_clock_config);6262+ add_node(ff, root, "sync-status", proc_dump_sync_status);6363+}
+371
sound/firewire/fireface/ff-protocol-ff400.c
···11+/*22+ * ff-protocol-ff400.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include <linux/delay.h>1010+#include "ff.h"1111+1212+#define FF400_STF 0x000080100500ull1313+#define FF400_RX_PACKET_FORMAT 0x000080100504ull1414+#define FF400_ISOC_COMM_START 0x000080100508ull1515+#define FF400_TX_PACKET_FORMAT 0x00008010050cull1616+#define FF400_ISOC_COMM_STOP 0x000080100510ull1717+#define FF400_SYNC_STATUS 0x0000801c0000ull1818+#define FF400_FETCH_PCM_FRAMES 0x0000801c0000ull /* For block request. */1919+#define FF400_CLOCK_CONFIG 0x0000801c0004ull2020+2121+#define FF400_MIDI_HIGH_ADDR 0x0000801003f4ull2222+#define FF400_MIDI_RX_PORT_0 0x000080180000ull2323+#define FF400_MIDI_RX_PORT_1 0x000080190000ull2424+2525+static int ff400_get_clock(struct snd_ff *ff, unsigned int *rate,2626+ enum snd_ff_clock_src *src)2727+{2828+ __le32 reg;2929+ u32 data;3030+ int err;3131+3232+ err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,3333+ FF400_SYNC_STATUS, ®, sizeof(reg), 0);3434+ if (err < 0)3535+ return err;3636+ data = le32_to_cpu(reg);3737+3838+ /* Calculate sampling rate. */3939+ switch ((data >> 1) & 0x03) {4040+ case 0x01:4141+ *rate = 32000;4242+ break;4343+ case 0x00:4444+ *rate = 44100;4545+ break;4646+ case 0x03:4747+ *rate = 48000;4848+ break;4949+ case 0x02:5050+ default:5151+ return -EIO;5252+ }5353+5454+ if (data & 0x08)5555+ *rate *= 2;5656+ else if (data & 0x10)5757+ *rate *= 4;5858+5959+ /* Calculate source of clock. */6060+ if (data & 0x01) {6161+ *src = SND_FF_CLOCK_SRC_INTERNAL;6262+ } else {6363+ /* TODO: 0x00, 0x01, 0x02, 0x06, 0x07? */6464+ switch ((data >> 10) & 0x07) {6565+ case 0x03:6666+ *src = SND_FF_CLOCK_SRC_SPDIF;6767+ break;6868+ case 0x04:6969+ *src = SND_FF_CLOCK_SRC_WORD;7070+ break;7171+ case 0x05:7272+ *src = SND_FF_CLOCK_SRC_LTC;7373+ break;7474+ case 0x00:7575+ default:7676+ *src = SND_FF_CLOCK_SRC_ADAT;7777+ break;7878+ }7979+ }8080+8181+ return 0;8282+}8383+8484+static int ff400_begin_session(struct snd_ff *ff, unsigned int rate)8585+{8686+ __le32 reg;8787+ int i, err;8888+8989+ /* Check whether the given value is supported or not. */9090+ for (i = 0; i < CIP_SFC_COUNT; i++) {9191+ if (amdtp_rate_table[i] == rate)9292+ break;9393+ }9494+ if (i == CIP_SFC_COUNT)9595+ return -EINVAL;9696+9797+ /* Set the number of data blocks transferred in a second. */9898+ reg = cpu_to_le32(rate);9999+ err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,100100+ FF400_STF, ®, sizeof(reg), 0);101101+ if (err < 0)102102+ return err;103103+104104+ msleep(100);105105+106106+ /*107107+ * Set isochronous channel and the number of quadlets of received108108+ * packets.109109+ */110110+ reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) |111111+ ff->rx_resources.channel);112112+ err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,113113+ FF400_RX_PACKET_FORMAT, ®, sizeof(reg), 0);114114+ if (err < 0)115115+ return err;116116+117117+ /*118118+ * Set isochronous channel and the number of quadlets of transmitted119119+ * packet.120120+ */121121+ /* TODO: investigate the purpose of this 0x80. */122122+ reg = cpu_to_le32((0x80 << 24) |123123+ (ff->tx_resources.channel << 5) |124124+ (ff->tx_stream.data_block_quadlets));125125+ err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,126126+ FF400_TX_PACKET_FORMAT, ®, sizeof(reg), 0);127127+ if (err < 0)128128+ return err;129129+130130+ /* Allow to transmit packets. */131131+ reg = cpu_to_le32(0x00000001);132132+ return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,133133+ FF400_ISOC_COMM_START, ®, sizeof(reg), 0);134134+}135135+136136+static void ff400_finish_session(struct snd_ff *ff)137137+{138138+ __le32 reg;139139+140140+ reg = cpu_to_le32(0x80000000);141141+ snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,142142+ FF400_ISOC_COMM_STOP, ®, sizeof(reg), 0);143143+}144144+145145+static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable)146146+{147147+ __le32 *reg;148148+ int i;149149+150150+ reg = kzalloc(sizeof(__le32) * 18, GFP_KERNEL);151151+ if (reg == NULL)152152+ return -ENOMEM;153153+154154+ if (enable) {155155+ /*156156+ * Each quadlet is corresponding to data channels in a data157157+ * blocks in reverse order. Precisely, quadlets for available158158+ * data channels should be enabled. Here, I take second best159159+ * to fetch PCM frames from all of data channels regardless of160160+ * stf.161161+ */162162+ for (i = 0; i < 18; ++i)163163+ reg[i] = cpu_to_le32(0x00000001);164164+ }165165+166166+ return snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST,167167+ FF400_FETCH_PCM_FRAMES, reg,168168+ sizeof(__le32) * 18, 0);169169+}170170+171171+static void ff400_dump_sync_status(struct snd_ff *ff,172172+ struct snd_info_buffer *buffer)173173+{174174+ __le32 reg;175175+ u32 data;176176+ int err;177177+178178+ err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST,179179+ FF400_SYNC_STATUS, ®, sizeof(reg), 0);180180+ if (err < 0)181181+ return;182182+183183+ data = le32_to_cpu(reg);184184+185185+ snd_iprintf(buffer, "External source detection:\n");186186+187187+ snd_iprintf(buffer, "Word Clock:");188188+ if ((data >> 24) & 0x20) {189189+ if ((data >> 24) & 0x40)190190+ snd_iprintf(buffer, "sync\n");191191+ else192192+ snd_iprintf(buffer, "lock\n");193193+ } else {194194+ snd_iprintf(buffer, "none\n");195195+ }196196+197197+ snd_iprintf(buffer, "S/PDIF:");198198+ if ((data >> 16) & 0x10) {199199+ if ((data >> 16) & 0x04)200200+ snd_iprintf(buffer, "sync\n");201201+ else202202+ snd_iprintf(buffer, "lock\n");203203+ } else {204204+ snd_iprintf(buffer, "none\n");205205+ }206206+207207+ snd_iprintf(buffer, "ADAT:");208208+ if ((data >> 8) & 0x04) {209209+ if ((data >> 8) & 0x10)210210+ snd_iprintf(buffer, "sync\n");211211+ else212212+ snd_iprintf(buffer, "lock\n");213213+ } else {214214+ snd_iprintf(buffer, "none\n");215215+ }216216+217217+ snd_iprintf(buffer, "\nUsed external source:\n");218218+219219+ if (((data >> 22) & 0x07) == 0x07) {220220+ snd_iprintf(buffer, "None\n");221221+ } else {222222+ switch ((data >> 22) & 0x07) {223223+ case 0x00:224224+ snd_iprintf(buffer, "ADAT:");225225+ break;226226+ case 0x03:227227+ snd_iprintf(buffer, "S/PDIF:");228228+ break;229229+ case 0x04:230230+ snd_iprintf(buffer, "Word:");231231+ break;232232+ case 0x07:233233+ snd_iprintf(buffer, "Nothing:");234234+ break;235235+ case 0x01:236236+ case 0x02:237237+ case 0x05:238238+ case 0x06:239239+ default:240240+ snd_iprintf(buffer, "unknown:");241241+ break;242242+ }243243+244244+ if ((data >> 25) & 0x07) {245245+ switch ((data >> 25) & 0x07) {246246+ case 0x01:247247+ snd_iprintf(buffer, "32000\n");248248+ break;249249+ case 0x02:250250+ snd_iprintf(buffer, "44100\n");251251+ break;252252+ case 0x03:253253+ snd_iprintf(buffer, "48000\n");254254+ break;255255+ case 0x04:256256+ snd_iprintf(buffer, "64000\n");257257+ break;258258+ case 0x05:259259+ snd_iprintf(buffer, "88200\n");260260+ break;261261+ case 0x06:262262+ snd_iprintf(buffer, "96000\n");263263+ break;264264+ case 0x07:265265+ snd_iprintf(buffer, "128000\n");266266+ break;267267+ case 0x08:268268+ snd_iprintf(buffer, "176400\n");269269+ break;270270+ case 0x09:271271+ snd_iprintf(buffer, "192000\n");272272+ break;273273+ case 0x00:274274+ snd_iprintf(buffer, "unknown\n");275275+ break;276276+ }277277+ }278278+ }279279+280280+ snd_iprintf(buffer, "Multiplied:");281281+ snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250);282282+}283283+284284+static void ff400_dump_clock_config(struct snd_ff *ff,285285+ struct snd_info_buffer *buffer)286286+{287287+ __le32 reg;288288+ u32 data;289289+ unsigned int rate;290290+ const char *src;291291+ int err;292292+293293+ err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST,294294+ FF400_CLOCK_CONFIG, ®, sizeof(reg), 0);295295+ if (err < 0)296296+ return;297297+298298+ data = le32_to_cpu(reg);299299+300300+ snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n",301301+ (data & 0x20) ? "Professional" : "Consumer",302302+ (data & 0x40) ? "on" : "off");303303+304304+ snd_iprintf(buffer, "Optical output interface format: %s\n",305305+ ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT");306306+307307+ snd_iprintf(buffer, "Word output single speed: %s\n",308308+ ((data >> 8) & 0x20) ? "on" : "off");309309+310310+ snd_iprintf(buffer, "S/PDIF input interface: %s\n",311311+ ((data >> 8) & 0x02) ? "Optical" : "Coaxial");312312+313313+ switch ((data >> 1) & 0x03) {314314+ case 0x01:315315+ rate = 32000;316316+ break;317317+ case 0x00:318318+ rate = 44100;319319+ break;320320+ case 0x03:321321+ rate = 48000;322322+ break;323323+ case 0x02:324324+ default:325325+ return;326326+ }327327+328328+ if (data & 0x08)329329+ rate *= 2;330330+ else if (data & 0x10)331331+ rate *= 4;332332+333333+ snd_iprintf(buffer, "Sampling rate: %d\n", rate);334334+335335+ if (data & 0x01) {336336+ src = "Internal";337337+ } else {338338+ switch ((data >> 10) & 0x07) {339339+ case 0x00:340340+ src = "ADAT";341341+ break;342342+ case 0x03:343343+ src = "S/PDIF";344344+ break;345345+ case 0x04:346346+ src = "Word";347347+ break;348348+ case 0x05:349349+ src = "LTC";350350+ break;351351+ default:352352+ return;353353+ }354354+ }355355+356356+ snd_iprintf(buffer, "Sync to clock source: %s\n", src);357357+}358358+359359+struct snd_ff_protocol snd_ff_protocol_ff400 = {360360+ .get_clock = ff400_get_clock,361361+ .begin_session = ff400_begin_session,362362+ .finish_session = ff400_finish_session,363363+ .switch_fetching_mode = ff400_switch_fetching_mode,364364+365365+ .dump_sync_status = ff400_dump_sync_status,366366+ .dump_clock_config = ff400_dump_clock_config,367367+368368+ .midi_high_addr_reg = FF400_MIDI_HIGH_ADDR,369369+ .midi_rx_port_0_reg = FF400_MIDI_RX_PORT_0,370370+ .midi_rx_port_1_reg = FF400_MIDI_RX_PORT_1,371371+};
+282
sound/firewire/fireface/ff-stream.c
···11+/*22+ * ff-stream.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "ff.h"1010+1111+#define CALLBACK_TIMEOUT_MS 2001212+1313+static int get_rate_mode(unsigned int rate, unsigned int *mode)1414+{1515+ int i;1616+1717+ for (i = 0; i < CIP_SFC_COUNT; i++) {1818+ if (amdtp_rate_table[i] == rate)1919+ break;2020+ }2121+2222+ if (i == CIP_SFC_COUNT)2323+ return -EINVAL;2424+2525+ *mode = ((int)i - 1) / 2;2626+2727+ return 0;2828+}2929+3030+/*3131+ * Fireface 400 manages isochronous channel number in 3 bit field. Therefore,3232+ * we can allocate between 0 and 7 channel.3333+ */3434+static int keep_resources(struct snd_ff *ff, unsigned int rate)3535+{3636+ int mode;3737+ int err;3838+3939+ err = get_rate_mode(rate, &mode);4040+ if (err < 0)4141+ return err;4242+4343+ /* Keep resources for in-stream. */4444+ err = amdtp_ff_set_parameters(&ff->tx_stream, rate,4545+ ff->spec->pcm_capture_channels[mode]);4646+ if (err < 0)4747+ return err;4848+ ff->tx_resources.channels_mask = 0x00000000000000ffuLL;4949+ err = fw_iso_resources_allocate(&ff->tx_resources,5050+ amdtp_stream_get_max_payload(&ff->tx_stream),5151+ fw_parent_device(ff->unit)->max_speed);5252+ if (err < 0)5353+ return err;5454+5555+ /* Keep resources for out-stream. */5656+ err = amdtp_ff_set_parameters(&ff->rx_stream, rate,5757+ ff->spec->pcm_playback_channels[mode]);5858+ if (err < 0)5959+ return err;6060+ ff->rx_resources.channels_mask = 0x00000000000000ffuLL;6161+ err = fw_iso_resources_allocate(&ff->rx_resources,6262+ amdtp_stream_get_max_payload(&ff->rx_stream),6363+ fw_parent_device(ff->unit)->max_speed);6464+ if (err < 0)6565+ fw_iso_resources_free(&ff->tx_resources);6666+6767+ return err;6868+}6969+7070+static void release_resources(struct snd_ff *ff)7171+{7272+ fw_iso_resources_free(&ff->tx_resources);7373+ fw_iso_resources_free(&ff->rx_resources);7474+}7575+7676+static inline void finish_session(struct snd_ff *ff)7777+{7878+ ff->spec->protocol->finish_session(ff);7979+ ff->spec->protocol->switch_fetching_mode(ff, false);8080+}8181+8282+static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)8383+{8484+ int err;8585+ struct fw_iso_resources *resources;8686+ struct amdtp_stream *stream;8787+8888+ if (dir == AMDTP_IN_STREAM) {8989+ resources = &ff->tx_resources;9090+ stream = &ff->tx_stream;9191+ } else {9292+ resources = &ff->rx_resources;9393+ stream = &ff->rx_stream;9494+ }9595+9696+ err = fw_iso_resources_init(resources, ff->unit);9797+ if (err < 0)9898+ return err;9999+100100+ err = amdtp_ff_init(stream, ff->unit, dir);101101+ if (err < 0)102102+ fw_iso_resources_destroy(resources);103103+104104+ return err;105105+}106106+107107+static void destroy_stream(struct snd_ff *ff, enum amdtp_stream_direction dir)108108+{109109+ if (dir == AMDTP_IN_STREAM) {110110+ amdtp_stream_destroy(&ff->tx_stream);111111+ fw_iso_resources_destroy(&ff->tx_resources);112112+ } else {113113+ amdtp_stream_destroy(&ff->rx_stream);114114+ fw_iso_resources_destroy(&ff->rx_resources);115115+ }116116+}117117+118118+int snd_ff_stream_init_duplex(struct snd_ff *ff)119119+{120120+ int err;121121+122122+ err = init_stream(ff, AMDTP_OUT_STREAM);123123+ if (err < 0)124124+ goto end;125125+126126+ err = init_stream(ff, AMDTP_IN_STREAM);127127+ if (err < 0)128128+ destroy_stream(ff, AMDTP_OUT_STREAM);129129+end:130130+ return err;131131+}132132+133133+/*134134+ * This function should be called before starting streams or after stopping135135+ * streams.136136+ */137137+void snd_ff_stream_destroy_duplex(struct snd_ff *ff)138138+{139139+ destroy_stream(ff, AMDTP_IN_STREAM);140140+ destroy_stream(ff, AMDTP_OUT_STREAM);141141+}142142+143143+int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate)144144+{145145+ unsigned int curr_rate;146146+ enum snd_ff_clock_src src;147147+ int err;148148+149149+ if (ff->substreams_counter == 0)150150+ return 0;151151+152152+ err = ff->spec->protocol->get_clock(ff, &curr_rate, &src);153153+ if (err < 0)154154+ return err;155155+ if (curr_rate != rate ||156156+ amdtp_streaming_error(&ff->tx_stream) ||157157+ amdtp_streaming_error(&ff->rx_stream)) {158158+ finish_session(ff);159159+160160+ amdtp_stream_stop(&ff->tx_stream);161161+ amdtp_stream_stop(&ff->rx_stream);162162+163163+ release_resources(ff);164164+ }165165+166166+ /*167167+ * Regardless of current source of clock signal, drivers transfer some168168+ * packets. Then, the device transfers packets.169169+ */170170+ if (!amdtp_stream_running(&ff->rx_stream)) {171171+ err = keep_resources(ff, rate);172172+ if (err < 0)173173+ goto error;174174+175175+ err = ff->spec->protocol->begin_session(ff, rate);176176+ if (err < 0)177177+ goto error;178178+179179+ err = amdtp_stream_start(&ff->rx_stream,180180+ ff->rx_resources.channel,181181+ fw_parent_device(ff->unit)->max_speed);182182+ if (err < 0)183183+ goto error;184184+185185+ if (!amdtp_stream_wait_callback(&ff->rx_stream,186186+ CALLBACK_TIMEOUT_MS)) {187187+ err = -ETIMEDOUT;188188+ goto error;189189+ }190190+191191+ err = ff->spec->protocol->switch_fetching_mode(ff, true);192192+ if (err < 0)193193+ goto error;194194+ }195195+196196+ if (!amdtp_stream_running(&ff->tx_stream)) {197197+ err = amdtp_stream_start(&ff->tx_stream,198198+ ff->tx_resources.channel,199199+ fw_parent_device(ff->unit)->max_speed);200200+ if (err < 0)201201+ goto error;202202+203203+ if (!amdtp_stream_wait_callback(&ff->tx_stream,204204+ CALLBACK_TIMEOUT_MS)) {205205+ err = -ETIMEDOUT;206206+ goto error;207207+ }208208+ }209209+210210+ return 0;211211+error:212212+ amdtp_stream_stop(&ff->tx_stream);213213+ amdtp_stream_stop(&ff->rx_stream);214214+215215+ finish_session(ff);216216+ release_resources(ff);217217+218218+ return err;219219+}220220+221221+void snd_ff_stream_stop_duplex(struct snd_ff *ff)222222+{223223+ if (ff->substreams_counter > 0)224224+ return;225225+226226+ amdtp_stream_stop(&ff->tx_stream);227227+ amdtp_stream_stop(&ff->rx_stream);228228+ finish_session(ff);229229+ release_resources(ff);230230+}231231+232232+void snd_ff_stream_update_duplex(struct snd_ff *ff)233233+{234234+ /* The device discontinue to transfer packets. */235235+ amdtp_stream_pcm_abort(&ff->tx_stream);236236+ amdtp_stream_stop(&ff->tx_stream);237237+238238+ amdtp_stream_pcm_abort(&ff->rx_stream);239239+ amdtp_stream_stop(&ff->rx_stream);240240+241241+ fw_iso_resources_update(&ff->tx_resources);242242+ fw_iso_resources_update(&ff->rx_resources);243243+}244244+245245+void snd_ff_stream_lock_changed(struct snd_ff *ff)246246+{247247+ ff->dev_lock_changed = true;248248+ wake_up(&ff->hwdep_wait);249249+}250250+251251+int snd_ff_stream_lock_try(struct snd_ff *ff)252252+{253253+ int err;254254+255255+ spin_lock_irq(&ff->lock);256256+257257+ /* user land lock this */258258+ if (ff->dev_lock_count < 0) {259259+ err = -EBUSY;260260+ goto end;261261+ }262262+263263+ /* this is the first time */264264+ if (ff->dev_lock_count++ == 0)265265+ snd_ff_stream_lock_changed(ff);266266+ err = 0;267267+end:268268+ spin_unlock_irq(&ff->lock);269269+ return err;270270+}271271+272272+void snd_ff_stream_lock_release(struct snd_ff *ff)273273+{274274+ spin_lock_irq(&ff->lock);275275+276276+ if (WARN_ON(ff->dev_lock_count <= 0))277277+ goto end;278278+ if (--ff->dev_lock_count == 0)279279+ snd_ff_stream_lock_changed(ff);280280+end:281281+ spin_unlock_irq(&ff->lock);282282+}
+295
sound/firewire/fireface/ff-transaction.c
···11+/*22+ * ff-transaction.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "ff.h"1010+1111+static void finish_transmit_midi_msg(struct snd_ff *ff, unsigned int port,1212+ int rcode)1313+{1414+ struct snd_rawmidi_substream *substream =1515+ ACCESS_ONCE(ff->rx_midi_substreams[port]);1616+1717+ if (rcode_is_permanent_error(rcode)) {1818+ ff->rx_midi_error[port] = true;1919+ return;2020+ }2121+2222+ if (rcode != RCODE_COMPLETE) {2323+ /* Transfer the message again, immediately. */2424+ ff->next_ktime[port] = 0;2525+ schedule_work(&ff->rx_midi_work[port]);2626+ return;2727+ }2828+2929+ snd_rawmidi_transmit_ack(substream, ff->rx_bytes[port]);3030+ ff->rx_bytes[port] = 0;3131+3232+ if (!snd_rawmidi_transmit_empty(substream))3333+ schedule_work(&ff->rx_midi_work[port]);3434+}3535+3636+static void finish_transmit_midi0_msg(struct fw_card *card, int rcode,3737+ void *data, size_t length,3838+ void *callback_data)3939+{4040+ struct snd_ff *ff =4141+ container_of(callback_data, struct snd_ff, transactions[0]);4242+ finish_transmit_midi_msg(ff, 0, rcode);4343+}4444+4545+static void finish_transmit_midi1_msg(struct fw_card *card, int rcode,4646+ void *data, size_t length,4747+ void *callback_data)4848+{4949+ struct snd_ff *ff =5050+ container_of(callback_data, struct snd_ff, transactions[1]);5151+ finish_transmit_midi_msg(ff, 1, rcode);5252+}5353+5454+static inline void fill_midi_buf(struct snd_ff *ff, unsigned int port,5555+ unsigned int index, u8 byte)5656+{5757+ ff->msg_buf[port][index] = cpu_to_le32(byte);5858+}5959+6060+static void transmit_midi_msg(struct snd_ff *ff, unsigned int port)6161+{6262+ struct snd_rawmidi_substream *substream =6363+ ACCESS_ONCE(ff->rx_midi_substreams[port]);6464+ u8 *buf = (u8 *)ff->msg_buf[port];6565+ int i, len;6666+6767+ struct fw_device *fw_dev = fw_parent_device(ff->unit);6868+ unsigned long long addr;6969+ int generation;7070+ fw_transaction_callback_t callback;7171+7272+ if (substream == NULL || snd_rawmidi_transmit_empty(substream))7373+ return;7474+7575+ if (ff->rx_bytes[port] > 0 || ff->rx_midi_error[port])7676+ return;7777+7878+ /* Do it in next chance. */7979+ if (ktime_after(ff->next_ktime[port], ktime_get())) {8080+ schedule_work(&ff->rx_midi_work[port]);8181+ return;8282+ }8383+8484+ len = snd_rawmidi_transmit_peek(substream, buf,8585+ SND_FF_MAXIMIM_MIDI_QUADS);8686+ if (len <= 0)8787+ return;8888+8989+ for (i = len - 1; i >= 0; i--)9090+ fill_midi_buf(ff, port, i, buf[i]);9191+9292+ if (port == 0) {9393+ addr = ff->spec->protocol->midi_rx_port_0_reg;9494+ callback = finish_transmit_midi0_msg;9595+ } else {9696+ addr = ff->spec->protocol->midi_rx_port_1_reg;9797+ callback = finish_transmit_midi1_msg;9898+ }9999+100100+ /* Set interval to next transaction. */101101+ ff->next_ktime[port] = ktime_add_ns(ktime_get(),102102+ len * 8 * NSEC_PER_SEC / 31250);103103+ ff->rx_bytes[port] = len;104104+105105+ /*106106+ * In Linux FireWire core, when generation is updated with memory107107+ * barrier, node id has already been updated. In this module, After108108+ * this smp_rmb(), load/store instructions to memory are completed.109109+ * Thus, both of generation and node id are available with recent110110+ * values. This is a light-serialization solution to handle bus reset111111+ * events on IEEE 1394 bus.112112+ */113113+ generation = fw_dev->generation;114114+ smp_rmb();115115+ fw_send_request(fw_dev->card, &ff->transactions[port],116116+ TCODE_WRITE_BLOCK_REQUEST,117117+ fw_dev->node_id, generation, fw_dev->max_speed,118118+ addr, &ff->msg_buf[port], len * 4,119119+ callback, &ff->transactions[port]);120120+}121121+122122+static void transmit_midi0_msg(struct work_struct *work)123123+{124124+ struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[0]);125125+126126+ transmit_midi_msg(ff, 0);127127+}128128+129129+static void transmit_midi1_msg(struct work_struct *work)130130+{131131+ struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[1]);132132+133133+ transmit_midi_msg(ff, 1);134134+}135135+136136+static void handle_midi_msg(struct fw_card *card, struct fw_request *request,137137+ int tcode, int destination, int source,138138+ int generation, unsigned long long offset,139139+ void *data, size_t length, void *callback_data)140140+{141141+ struct snd_ff *ff = callback_data;142142+ __le32 *buf = data;143143+ u32 quad;144144+ u8 byte;145145+ unsigned int index;146146+ struct snd_rawmidi_substream *substream;147147+ int i;148148+149149+ fw_send_response(card, request, RCODE_COMPLETE);150150+151151+ for (i = 0; i < length / 4; i++) {152152+ quad = le32_to_cpu(buf[i]);153153+154154+ /* Message in first port. */155155+ /*156156+ * This value may represent the index of this unit when the same157157+ * units are on the same IEEE 1394 bus. This driver doesn't use158158+ * it.159159+ */160160+ index = (quad >> 8) & 0xff;161161+ if (index > 0) {162162+ substream = ACCESS_ONCE(ff->tx_midi_substreams[0]);163163+ if (substream != NULL) {164164+ byte = quad & 0xff;165165+ snd_rawmidi_receive(substream, &byte, 1);166166+ }167167+ }168168+169169+ /* Message in second port. */170170+ index = (quad >> 24) & 0xff;171171+ if (index > 0) {172172+ substream = ACCESS_ONCE(ff->tx_midi_substreams[1]);173173+ if (substream != NULL) {174174+ byte = (quad >> 16) & 0xff;175175+ snd_rawmidi_receive(substream, &byte, 1);176176+ }177177+ }178178+ }179179+}180180+181181+static int allocate_own_address(struct snd_ff *ff, int i)182182+{183183+ struct fw_address_region midi_msg_region;184184+ int err;185185+186186+ ff->async_handler.length = SND_FF_MAXIMIM_MIDI_QUADS * 4;187187+ ff->async_handler.address_callback = handle_midi_msg;188188+ ff->async_handler.callback_data = ff;189189+190190+ midi_msg_region.start = 0x000100000000ull * i;191191+ midi_msg_region.end = midi_msg_region.start + ff->async_handler.length;192192+193193+ err = fw_core_add_address_handler(&ff->async_handler, &midi_msg_region);194194+ if (err >= 0) {195195+ /* Controllers are allowed to register this region. */196196+ if (ff->async_handler.offset & 0x0000ffffffff) {197197+ fw_core_remove_address_handler(&ff->async_handler);198198+ err = -EAGAIN;199199+ }200200+ }201201+202202+ return err;203203+}204204+205205+/*206206+ * The configuration to start asynchronous transactions for MIDI messages is in207207+ * 0x'0000'8010'051c. This register includes the other options, thus this driver208208+ * doesn't touch it and leaves the decision to userspace. The userspace MUST add209209+ * 0x04000000 to write transactions to the register to receive any MIDI210210+ * messages.211211+ *212212+ * Here, I just describe MIDI-related offsets of the register, in little-endian213213+ * order.214214+ *215215+ * Controllers are allowed to register higher 4 bytes of address to receive216216+ * the transactions. The register is 0x'0000'8010'03f4. On the other hand, the217217+ * controllers are not allowed to register lower 4 bytes of the address. They218218+ * are forced to select from 4 options by writing corresponding bits to219219+ * 0x'0000'8010'051c.220220+ *221221+ * The 3rd-6th bits in MSB of this register are used to indicate lower 4 bytes222222+ * of address to which the device transferrs the transactions.223223+ * - 6th: 0x'....'....'0000'0180224224+ * - 5th: 0x'....'....'0000'0100225225+ * - 4th: 0x'....'....'0000'0080226226+ * - 3rd: 0x'....'....'0000'0000227227+ *228228+ * This driver configure 0x'....'....'0000'0000 for units to receive MIDI229229+ * messages. 3rd bit of the register should be configured, however this driver230230+ * deligates this task to user space applications due to a restriction that231231+ * this register is write-only and the other bits have own effects.232232+ *233233+ * The 1st and 2nd bits in LSB of this register are used to cancel transferring234234+ * asynchronous transactions. These two bits have the same effect.235235+ * - 1st/2nd: cancel transferring236236+ */237237+int snd_ff_transaction_reregister(struct snd_ff *ff)238238+{239239+ struct fw_card *fw_card = fw_parent_device(ff->unit)->card;240240+ u32 addr;241241+ __le32 reg;242242+243243+ /*244244+ * Controllers are allowed to register its node ID and upper 2 byte of245245+ * local address to listen asynchronous transactions.246246+ */247247+ addr = (fw_card->node_id << 16) | (ff->async_handler.offset >> 32);248248+ reg = cpu_to_le32(addr);249249+ return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,250250+ ff->spec->protocol->midi_high_addr_reg,251251+ ®, sizeof(reg), 0);252252+}253253+254254+int snd_ff_transaction_register(struct snd_ff *ff)255255+{256256+ int i, err;257257+258258+ /*259259+ * Allocate in Memory Space of IEC 13213, but lower 4 byte in LSB should260260+ * be zero due to device specification.261261+ */262262+ for (i = 0; i < 0xffff; i++) {263263+ err = allocate_own_address(ff, i);264264+ if (err != -EBUSY && err != -EAGAIN)265265+ break;266266+ }267267+ if (err < 0)268268+ return err;269269+270270+ err = snd_ff_transaction_reregister(ff);271271+ if (err < 0)272272+ return err;273273+274274+ INIT_WORK(&ff->rx_midi_work[0], transmit_midi0_msg);275275+ INIT_WORK(&ff->rx_midi_work[1], transmit_midi1_msg);276276+277277+ return 0;278278+}279279+280280+void snd_ff_transaction_unregister(struct snd_ff *ff)281281+{282282+ __le32 reg;283283+284284+ if (ff->async_handler.callback_data == NULL)285285+ return;286286+ ff->async_handler.callback_data = NULL;287287+288288+ /* Release higher 4 bytes of address. */289289+ reg = cpu_to_le32(0x00000000);290290+ snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,291291+ ff->spec->protocol->midi_high_addr_reg,292292+ ®, sizeof(reg), 0);293293+294294+ fw_core_remove_address_handler(&ff->async_handler);295295+}
+209
sound/firewire/fireface/ff.c
···11+/*22+ * ff.c - a part of driver for RME Fireface series33+ *44+ * Copyright (c) 2015-2017 Takashi Sakamoto55+ *66+ * Licensed under the terms of the GNU General Public License, version 2.77+ */88+99+#include "ff.h"1010+1111+#define OUI_RME 0x000a351212+1313+MODULE_DESCRIPTION("RME Fireface series Driver");1414+MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>");1515+MODULE_LICENSE("GPL v2");1616+1717+static void name_card(struct snd_ff *ff)1818+{1919+ struct fw_device *fw_dev = fw_parent_device(ff->unit);2020+2121+ strcpy(ff->card->driver, "Fireface");2222+ strcpy(ff->card->shortname, ff->spec->name);2323+ strcpy(ff->card->mixername, ff->spec->name);2424+ snprintf(ff->card->longname, sizeof(ff->card->longname),2525+ "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name,2626+ fw_dev->config_rom[3], fw_dev->config_rom[4],2727+ dev_name(&ff->unit->device), 100 << fw_dev->max_speed);2828+}2929+3030+static void ff_free(struct snd_ff *ff)3131+{3232+ snd_ff_stream_destroy_duplex(ff);3333+ snd_ff_transaction_unregister(ff);3434+3535+ fw_unit_put(ff->unit);3636+3737+ mutex_destroy(&ff->mutex);3838+ kfree(ff);3939+}4040+4141+static void ff_card_free(struct snd_card *card)4242+{4343+ ff_free(card->private_data);4444+}4545+4646+static void do_registration(struct work_struct *work)4747+{4848+ struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work);4949+ int err;5050+5151+ if (ff->registered)5252+ return;5353+5454+ err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0,5555+ &ff->card);5656+ if (err < 0)5757+ return;5858+5959+ err = snd_ff_transaction_register(ff);6060+ if (err < 0)6161+ goto error;6262+6363+ name_card(ff);6464+6565+ err = snd_ff_stream_init_duplex(ff);6666+ if (err < 0)6767+ goto error;6868+6969+ snd_ff_proc_init(ff);7070+7171+ err = snd_ff_create_midi_devices(ff);7272+ if (err < 0)7373+ goto error;7474+7575+ err = snd_ff_create_pcm_devices(ff);7676+ if (err < 0)7777+ goto error;7878+7979+ err = snd_ff_create_hwdep_devices(ff);8080+ if (err < 0)8181+ goto error;8282+8383+ err = snd_card_register(ff->card);8484+ if (err < 0)8585+ goto error;8686+8787+ ff->card->private_free = ff_card_free;8888+ ff->card->private_data = ff;8989+ ff->registered = true;9090+9191+ return;9292+error:9393+ snd_ff_transaction_unregister(ff);9494+ snd_ff_stream_destroy_duplex(ff);9595+ snd_card_free(ff->card);9696+ dev_info(&ff->unit->device,9797+ "Sound card registration failed: %d\n", err);9898+}9999+100100+static int snd_ff_probe(struct fw_unit *unit,101101+ const struct ieee1394_device_id *entry)102102+{103103+ struct snd_ff *ff;104104+105105+ ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL);106106+ if (ff == NULL)107107+ return -ENOMEM;108108+109109+ /* initialize myself */110110+ ff->unit = fw_unit_get(unit);111111+ dev_set_drvdata(&unit->device, ff);112112+113113+ mutex_init(&ff->mutex);114114+ spin_lock_init(&ff->lock);115115+ init_waitqueue_head(&ff->hwdep_wait);116116+117117+ ff->spec = (const struct snd_ff_spec *)entry->driver_data;118118+119119+ /* Register this sound card later. */120120+ INIT_DEFERRABLE_WORK(&ff->dwork, do_registration);121121+ snd_fw_schedule_registration(unit, &ff->dwork);122122+123123+ return 0;124124+}125125+126126+static void snd_ff_update(struct fw_unit *unit)127127+{128128+ struct snd_ff *ff = dev_get_drvdata(&unit->device);129129+130130+ /* Postpone a workqueue for deferred registration. */131131+ if (!ff->registered)132132+ snd_fw_schedule_registration(unit, &ff->dwork);133133+134134+ snd_ff_transaction_reregister(ff);135135+136136+ if (ff->registered)137137+ snd_ff_stream_update_duplex(ff);138138+}139139+140140+static void snd_ff_remove(struct fw_unit *unit)141141+{142142+ struct snd_ff *ff = dev_get_drvdata(&unit->device);143143+144144+ /*145145+ * Confirm to stop the work for registration before the sound card is146146+ * going to be released. The work is not scheduled again because bus147147+ * reset handler is not called anymore.148148+ */149149+ cancel_work_sync(&ff->dwork.work);150150+151151+ if (ff->registered) {152152+ /* No need to wait for releasing card object in this context. */153153+ snd_card_free_when_closed(ff->card);154154+ } else {155155+ /* Don't forget this case. */156156+ ff_free(ff);157157+ }158158+}159159+160160+static struct snd_ff_spec spec_ff400 = {161161+ .name = "Fireface400",162162+ .pcm_capture_channels = {18, 14, 10},163163+ .pcm_playback_channels = {18, 14, 10},164164+ .midi_in_ports = 2,165165+ .midi_out_ports = 2,166166+ .protocol = &snd_ff_protocol_ff400,167167+};168168+169169+static const struct ieee1394_device_id snd_ff_id_table[] = {170170+ /* Fireface 400 */171171+ {172172+ .match_flags = IEEE1394_MATCH_VENDOR_ID |173173+ IEEE1394_MATCH_SPECIFIER_ID |174174+ IEEE1394_MATCH_VERSION |175175+ IEEE1394_MATCH_MODEL_ID,176176+ .vendor_id = OUI_RME,177177+ .specifier_id = 0x000a35,178178+ .version = 0x000002,179179+ .model_id = 0x101800,180180+ .driver_data = (kernel_ulong_t)&spec_ff400,181181+ },182182+ {}183183+};184184+MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table);185185+186186+static struct fw_driver ff_driver = {187187+ .driver = {188188+ .owner = THIS_MODULE,189189+ .name = "snd-fireface",190190+ .bus = &fw_bus_type,191191+ },192192+ .probe = snd_ff_probe,193193+ .update = snd_ff_update,194194+ .remove = snd_ff_remove,195195+ .id_table = snd_ff_id_table,196196+};197197+198198+static int __init snd_ff_init(void)199199+{200200+ return driver_register(&ff_driver.driver);201201+}202202+203203+static void __exit snd_ff_exit(void)204204+{205205+ driver_unregister(&ff_driver.driver);206206+}207207+208208+module_init(snd_ff_init);209209+module_exit(snd_ff_exit);
···9999}100100EXPORT_SYMBOL(snd_fw_schedule_registration);101101102102-static void async_midi_port_callback(struct fw_card *card, int rcode,103103- void *data, size_t length,104104- void *callback_data)105105-{106106- struct snd_fw_async_midi_port *port = callback_data;107107- struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);108108-109109- /* This port is closed. */110110- if (substream == NULL)111111- return;112112-113113- if (rcode == RCODE_COMPLETE)114114- snd_rawmidi_transmit_ack(substream, port->consume_bytes);115115- else if (!rcode_is_permanent_error(rcode))116116- /* To start next transaction immediately for recovery. */117117- port->next_ktime = 0;118118- else119119- /* Don't continue processing. */120120- port->error = true;121121-122122- port->idling = true;123123-124124- if (!snd_rawmidi_transmit_empty(substream))125125- schedule_work(&port->work);126126-}127127-128128-static void midi_port_work(struct work_struct *work)129129-{130130- struct snd_fw_async_midi_port *port =131131- container_of(work, struct snd_fw_async_midi_port, work);132132- struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);133133- int generation;134134- int type;135135-136136- /* Under transacting or error state. */137137- if (!port->idling || port->error)138138- return;139139-140140- /* Nothing to do. */141141- if (substream == NULL || snd_rawmidi_transmit_empty(substream))142142- return;143143-144144- /* Do it in next chance. */145145- if (ktime_after(port->next_ktime, ktime_get())) {146146- schedule_work(&port->work);147147- return;148148- }149149-150150- /*151151- * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().152152- * Later, snd_rawmidi_transmit_ack() is called.153153- */154154- memset(port->buf, 0, port->len);155155- port->consume_bytes = port->fill(substream, port->buf);156156- if (port->consume_bytes <= 0) {157157- /* Do it in next chance, immediately. */158158- if (port->consume_bytes == 0) {159159- port->next_ktime = 0;160160- schedule_work(&port->work);161161- } else {162162- /* Fatal error. */163163- port->error = true;164164- }165165- return;166166- }167167-168168- /* Calculate type of transaction. */169169- if (port->len == 4)170170- type = TCODE_WRITE_QUADLET_REQUEST;171171- else172172- type = TCODE_WRITE_BLOCK_REQUEST;173173-174174- /* Set interval to next transaction. */175175- port->next_ktime = ktime_add_ns(ktime_get(),176176- port->consume_bytes * 8 * NSEC_PER_SEC / 31250);177177-178178- /* Start this transaction. */179179- port->idling = false;180180-181181- /*182182- * In Linux FireWire core, when generation is updated with memory183183- * barrier, node id has already been updated. In this module, After184184- * this smp_rmb(), load/store instructions to memory are completed.185185- * Thus, both of generation and node id are available with recent186186- * values. This is a light-serialization solution to handle bus reset187187- * events on IEEE 1394 bus.188188- */189189- generation = port->parent->generation;190190- smp_rmb();191191-192192- fw_send_request(port->parent->card, &port->transaction, type,193193- port->parent->node_id, generation,194194- port->parent->max_speed, port->addr,195195- port->buf, port->len, async_midi_port_callback,196196- port);197197-}198198-199199-/**200200- * snd_fw_async_midi_port_init - initialize asynchronous MIDI port structure201201- * @port: the asynchronous MIDI port to initialize202202- * @unit: the target of the asynchronous transaction203203- * @addr: the address to which transactions are transferred204204- * @len: the length of transaction205205- * @fill: the callback function to fill given buffer, and returns the206206- * number of consumed bytes for MIDI message.207207- *208208- */209209-int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,210210- struct fw_unit *unit, u64 addr, unsigned int len,211211- snd_fw_async_midi_port_fill fill)212212-{213213- port->len = DIV_ROUND_UP(len, 4) * 4;214214- port->buf = kzalloc(port->len, GFP_KERNEL);215215- if (port->buf == NULL)216216- return -ENOMEM;217217-218218- port->parent = fw_parent_device(unit);219219- port->addr = addr;220220- port->fill = fill;221221- port->idling = true;222222- port->next_ktime = 0;223223- port->error = false;224224-225225- INIT_WORK(&port->work, midi_port_work);226226-227227- return 0;228228-}229229-EXPORT_SYMBOL(snd_fw_async_midi_port_init);230230-231231-/**232232- * snd_fw_async_midi_port_destroy - free asynchronous MIDI port structure233233- * @port: the asynchronous MIDI port structure234234- */235235-void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port)236236-{237237- snd_fw_async_midi_port_finish(port);238238- cancel_work_sync(&port->work);239239- kfree(port->buf);240240-}241241-EXPORT_SYMBOL(snd_fw_async_midi_port_destroy);242242-243102MODULE_DESCRIPTION("FireWire audio helper functions");244103MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");245104MODULE_LICENSE("GPL v2");
···256256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */257257 unsigned int power_save_node:1; /* advanced PM for each widget */258258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */259259+ unsigned int force_pin_prefix:1; /* Add location prefix */259260#ifdef CONFIG_PM260261 unsigned long power_on_acct;261262 unsigned long power_off_acct;
+7-2
sound/pci/hda/hda_generic.c
···196196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");197197 if (val >= 0)198198 spec->suppress_hp_mic_detect = !val;199199+ val = snd_hda_get_bool_hint(codec, "vmaster");200200+ if (val >= 0)201201+ spec->suppress_vmaster = !val;199202200203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))201204 spec->mixer_nid = val;···1128112511291126 *index = 0;11301127 if (cfg->line_outs == 1 && !spec->multi_ios &&11281128+ !codec->force_pin_prefix &&11311129 !cfg->hp_outs && !cfg->speaker_outs)11321130 return spec->vmaster_mute.hook ? "PCM" : "Master";11331131···11361132 * use it master (or "PCM" if a vmaster hook is present)11371133 */11381134 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&11351135+ !codec->force_pin_prefix &&11391136 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])11401137 return spec->vmaster_mute.hook ? "PCM" : "Master";11411138···50365031 }5037503250385033 /* if we have no master control, let's create it */50395039- if (!spec->no_analog &&50345034+ if (!spec->no_analog && !spec->suppress_vmaster &&50405035 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {50415036 err = snd_hda_add_vmaster(codec, "Master Playback Volume",50425037 spec->vmaster_tlv, slave_pfxs,···50445039 if (err < 0)50455040 return err;50465041 }50475047- if (!spec->no_analog &&50425042+ if (!spec->no_analog && !spec->suppress_vmaster &&50485043 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {50495044 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",50505045 NULL, slave_pfxs,
+1
sound/pci/hda/hda_generic.h
···229229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */230230 unsigned int power_down_unused:1; /* power down unused widgets */231231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */232232+ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */232233233234 /* other internal flags */234235 unsigned int no_analog:1; /* digital I/O only */
+134-5
sound/pci/hda/hda_intel.c
···7777 POS_FIX_POSBUF,7878 POS_FIX_VIACOMBO,7979 POS_FIX_COMBO,8080+ POS_FIX_SKL,8081};81828283/* Defines for ATI HD Audio support in SB450 south bridge */···149148MODULE_PARM_DESC(model, "Use the given board model.");150149module_param_array(position_fix, int, NULL, 0444);151150MODULE_PARM_DESC(position_fix, "DMA pointer read method."152152- "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");151151+ "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+).");153152module_param_array(bdl_pos_adj, int, NULL, 0644);154153MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");155154module_param_array(probe_mask, int, NULL, 0444);···370369#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)371370#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)372371#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)372372+#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)373373#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \374374- IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)374374+ IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \375375+ IS_GLK(pci)375376376377static char *driver_short_names[] = {377378 [AZX_DRIVER_ICH] = "HDA Intel",···537534{538535 u32 val;539536540540- val = azx_readl(chip, SKL_EM4L);537537+ val = azx_readl(chip, VS_EM4L);541538 val &= (0x3 << 20);542542- azx_writel(chip, SKL_EM4L, val);539539+ azx_writel(chip, VS_EM4L, val);540540+}541541+542542+/*543543+ * ML_LCAP bits:544544+ * bit 0: 6 MHz Supported545545+ * bit 1: 12 MHz Supported546546+ * bit 2: 24 MHz Supported547547+ * bit 3: 48 MHz Supported548548+ * bit 4: 96 MHz Supported549549+ * bit 5: 192 MHz Supported550550+ */551551+static int intel_get_lctl_scf(struct azx *chip)552552+{553553+ struct hdac_bus *bus = azx_bus(chip);554554+ static int preferred_bits[] = { 2, 3, 1, 4, 5 };555555+ u32 val, t;556556+ int i;557557+558558+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);559559+560560+ for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {561561+ t = preferred_bits[i];562562+ if (val & (1 << t))563563+ return t;564564+ }565565+566566+ dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");567567+ return 0;568568+}569569+570570+static int intel_ml_lctl_set_power(struct azx *chip, int state)571571+{572572+ struct hdac_bus *bus = azx_bus(chip);573573+ u32 val;574574+ int timeout;575575+576576+ /*577577+ * the codecs are sharing the first link setting by default578578+ * If other links are enabled for stream, they need similar fix579579+ */580580+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);581581+ val &= ~AZX_MLCTL_SPA;582582+ val |= state << AZX_MLCTL_SPA_SHIFT;583583+ writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);584584+ /* wait for CPA */585585+ timeout = 50;586586+ while (timeout) {587587+ if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &588588+ AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))589589+ return 0;590590+ timeout--;591591+ udelay(10);592592+ }593593+594594+ return -1;595595+}596596+597597+static void intel_init_lctl(struct azx *chip)598598+{599599+ struct hdac_bus *bus = azx_bus(chip);600600+ u32 val;601601+ int ret;602602+603603+ /* 0. check lctl register value is correct or not */604604+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);605605+ /* if SCF is already set, let's use it */606606+ if ((val & ML_LCTL_SCF_MASK) != 0)607607+ return;608608+609609+ /*610610+ * Before operating on SPA, CPA must match SPA.611611+ * Any deviation may result in undefined behavior.612612+ */613613+ if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=614614+ ((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))615615+ return;616616+617617+ /* 1. turn link down: set SPA to 0 and wait CPA to 0 */618618+ ret = intel_ml_lctl_set_power(chip, 0);619619+ udelay(100);620620+ if (ret)621621+ goto set_spa;622622+623623+ /* 2. update SCF to select a properly audio clock*/624624+ val &= ~ML_LCTL_SCF_MASK;625625+ val |= intel_get_lctl_scf(chip);626626+ writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);627627+628628+set_spa:629629+ /* 4. turn link up: set SPA to 1 and wait CPA to 1 */630630+ intel_ml_lctl_set_power(chip, 1);631631+ udelay(100);543632}544633545634static void hda_intel_init_chip(struct azx *chip, bool full_reset)···659564 /* reduce dma latency to avoid noise */660565 if (IS_BXT(pci))661566 bxt_reduce_dma_latency(chip);567567+568568+ if (bus->mlcap != NULL)569569+ intel_init_lctl(chip);662570}663571664572/* calculate runtime delay from LPIB */···911813912814 /* Calculate real DMA position we want */913815 return bound_pos + mod_dma_pos;816816+}817817+818818+static unsigned int azx_skl_get_dpib_pos(struct azx *chip,819819+ struct azx_dev *azx_dev)820820+{821821+ return _snd_hdac_chip_readl(azx_bus(chip),822822+ AZX_REG_VS_SDXDPIB_XBASE +823823+ (AZX_REG_VS_SDXDPIB_XINTERVAL *824824+ azx_dev->core.index));825825+}826826+827827+/* get the current DMA position with correction on SKL+ chips */828828+static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev)829829+{830830+ /* DPIB register gives a more accurate position for playback */831831+ if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK)832832+ return azx_skl_get_dpib_pos(chip, azx_dev);833833+834834+ /* For capture, we need to read posbuf, but it requires a delay835835+ * for the possible boundary overlap; the read of DPIB fetches the836836+ * actual posbuf837837+ */838838+ udelay(20);839839+ azx_skl_get_dpib_pos(chip, azx_dev);840840+ return azx_get_pos_posbuf(chip, azx_dev);914841}915842916843#ifdef CONFIG_PM···14741351 case POS_FIX_POSBUF:14751352 case POS_FIX_VIACOMBO:14761353 case POS_FIX_COMBO:13541354+ case POS_FIX_SKL:14771355 return fix;14781356 }14791357···14951371 dev_dbg(chip->card->dev, "Using LPIB position fix\n");14961372 return POS_FIX_LPIB;14971373 }13741374+ if (IS_SKL_PLUS(chip->pci)) {13751375+ dev_dbg(chip->card->dev, "Using SKL position fix\n");13761376+ return POS_FIX_SKL;13771377+ }14981378 return POS_FIX_AUTO;14991379}15001380···15101382 [POS_FIX_POSBUF] = azx_get_pos_posbuf,15111383 [POS_FIX_VIACOMBO] = azx_via_get_position,15121384 [POS_FIX_COMBO] = azx_get_pos_lpib,13851385+ [POS_FIX_SKL] = azx_get_pos_skl,15131386 };1514138715151388 chip->get_position[0] = chip->get_position[1] = callbacks[fix];···15191390 if (fix == POS_FIX_COMBO)15201391 chip->get_position[1] = NULL;1521139215221522- if (fix == POS_FIX_POSBUF &&13931393+ if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&15231394 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {15241395 chip->get_delay[0] = chip->get_delay[1] =15251396 azx_get_delay_from_lpib;
+5-5
sound/pci/hda/patch_ca0132.c
···857857 chip_addx >> 16);858858 }859859860860- spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx;860860+ spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx;861861862862 return res;863863}···882882 /*If no error encountered, automatically increment the address883883 as per chip behaviour*/884884 spec->curr_chip_addx = (res != -EIO) ?885885- (spec->curr_chip_addx + 4) : ~0UL;885885+ (spec->curr_chip_addx + 4) : ~0U;886886 return res;887887}888888···933933 /*If no error encountered, automatically increment the address934934 as per chip behaviour*/935935 spec->curr_chip_addx = (res != -EIO) ?936936- (spec->curr_chip_addx + 4) : ~0UL;936936+ (spec->curr_chip_addx + 4) : ~0U;937937 return res;938938}939939···11681168 int status = 0;11691169 unsigned int count;1170117011711171- if ((buffer == NULL))11711171+ if (buffer == NULL)11721172 return -EINVAL;1173117311741174 count = 0;···12101210 unsigned int skip_count;12111211 unsigned int dummy;1212121212131213- if ((buffer == NULL))12131213+ if (buffer == NULL)12141214 return -1;1215121512161216 count = 0;