···494hp_mic_detect (bool)495 enable/disable the hp/mic shared input for a single built-in mic496 case; default true00497mixer_nid (int)498 specifies the widget NID of the analog-loopback mixer499
···494hp_mic_detect (bool)495 enable/disable the hp/mic shared input for a single built-in mic496 case; default true497+vmaster (bool)498+ enable/disable the virtual Master control; default true499mixer_nid (int)500 specifies the widget NID of the analog-loopback mixer501
···140 To compile this driver as a module, choose M here: the module141 will be called snd-firewire-tascam.14200000000000000000000143endif # SND_FIREWIRE
···140 To compile this driver as a module, choose M here: the module141 will be called snd-firewire-tascam.142143+config SND_FIREWIRE_MOTU144+ tristate "Mark of the unicorn FireWire series support"145+ select SND_FIREWIRE_LIB146+ select SND_HWDEP147+ help148+ Say Y here to enable support for FireWire devices which MOTU produced:149+ * 828mk2150+ * 828mk3151+152+ To compile this driver as a module, choose M here: the module153+ will be called snd-firewire-motu.154+155+config SND_FIREFACE156+ tristate "RME Fireface series support"157+ select SND_FIREWIRE_LIB158+ select SND_HWDEP159+ help160+ Say Y here to include support for RME fireface series.161+ * Fireface 400162+163endif # SND_FIREWIRE
···2728/* isochronous header parameters */29#define ISO_DATA_LENGTH_SHIFT 16030#define TAG_CIP 13132/* common isochronous packet header parameters */···38#define CIP_SID_MASK 0x3f00000039#define CIP_DBS_MASK 0x00ff000040#define CIP_DBS_SHIFT 160041#define CIP_DBC_MASK 0x000000ff42#define CIP_FMT_SHIFT 2443#define CIP_FMT_MASK 0x3f000000···235unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)236{237 unsigned int multiplier = 1;0238239 if (s->flags & CIP_JUMBO_PAYLOAD)240 multiplier = 5;00241242- return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier;0243}244EXPORT_SYMBOL(amdtp_stream_get_max_payload);245···385 goto end;386387 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);388- p.tag = TAG_CIP;389 p.header_length = header_length;390 if (payload_length > 0)391 p.payload_length = payload_length;···412413static inline int queue_in_packet(struct amdtp_stream *s)414{415- return queue_packet(s, IN_PACKET_HEADER_SIZE,416- amdtp_stream_get_max_payload(s));417}418419-static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle,0420 unsigned int index)421{422 __be32 *buffer;423 unsigned int syt;424 unsigned int data_blocks;425- unsigned int payload_length;426 unsigned int pcm_frames;427 struct snd_pcm_substream *pcm;428···430 data_blocks = calculate_data_blocks(s, syt);431 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);4320000433 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |434 (s->data_block_quadlets << CIP_DBS_SHIFT) |0435 s->data_block_counter);436 buffer[1] = cpu_to_be32(CIP_EOH |437 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |438 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |439 (syt & CIP_SYT_MASK));440441- s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;00442 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;443444 trace_out_packet(s, cycle, buffer, payload_length, index);···461 return 0;462}46300000000000000000000000000000000464static int handle_in_packet(struct amdtp_stream *s,465- unsigned int payload_quadlets, unsigned int cycle,466 unsigned int index)467{468 __be32 *buffer;469 u32 cip_header[2];470- unsigned int fmt, fdf, syt;471 unsigned int data_block_quadlets, data_block_counter, dbc_interval;472 unsigned int data_blocks;473 struct snd_pcm_substream *pcm;···510 cip_header[0] = be32_to_cpu(buffer[0]);511 cip_header[1] = be32_to_cpu(buffer[1]);512513- trace_in_packet(s, cycle, cip_header, payload_quadlets, index);514515 /*516 * This module supports 'Two-quadlet CIP header with SYT field'.517 * For convenience, also check FMT field is AM824 or not.518 */519- if (((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||520- ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) {0521 dev_info_ratelimited(&s->unit->device,522 "Invalid CIP header for AMDTP: %08X:%08X\n",523 cip_header[0], cip_header[1]);···528 }529530 /* Check valid protocol or not. */0531 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;532- if (fmt != s->fmt) {533 dev_info_ratelimited(&s->unit->device,534 "Detect unexpected protocol: %08x %08x\n",535 cip_header[0], cip_header[1]);···541542 /* Calculate data blocks */543 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;544- if (payload_quadlets < 3 ||545 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {546 data_blocks = 0;547 } else {···557 if (s->flags & CIP_WRONG_DBS)558 data_block_quadlets = s->data_block_quadlets;559560- data_blocks = (payload_quadlets - 2) / data_block_quadlets;0561 }562563 /* Check data block counter continuity */···599 s->data_block_counter =600 (data_block_counter + data_blocks) & 0xff;601end:0000000000000000000000000000602 if (queue_in_packet(s) < 0)603 return -EIO;604···680681 for (i = 0; i < packets; ++i) {682 cycle = increment_cycle_count(cycle, 1);683- if (handle_out_packet(s, cycle, i) < 0) {684 s->packet_index = -1;685 amdtp_stream_pcm_abort(s);686 return;···696{697 struct amdtp_stream *s = private_data;698 unsigned int i, packets;699- unsigned int payload_quadlets, max_payload_quadlets;700 __be32 *headers = header;701 u32 cycle;702···712 cycle = decrement_cycle_count(cycle, packets);713714 /* For buffer-over-run prevention. */715- max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4;716717 for (i = 0; i < packets; i++) {718 cycle = increment_cycle_count(cycle, 1);719720- /* The number of quadlets in this packet */721- payload_quadlets =722- (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT) / 4;723- if (payload_quadlets > max_payload_quadlets) {724 dev_err(&s->unit->device,725- "Detect jumbo payload: %02x %02x\n",726- payload_quadlets, max_payload_quadlets);727 break;728 }729730- if (handle_in_packet(s, payload_quadlets, cycle, i) < 0)731 break;732 }733···747 void *header, void *private_data)748{749 struct amdtp_stream *s = private_data;0000750751 /*752 * For in-stream, first packet has come.···759 s->callbacked = true;760 wake_up(&s->callback_wait);761762- if (s->direction == AMDTP_IN_STREAM)0000763 context->callback.sc = in_stream_callback;764- else000000765 context->callback.sc = out_stream_callback;0000000766767 context->callback.sc(context, tstamp, header_length, header, s);768}···856857 amdtp_stream_update(s);85800000859 s->packet_index = 0;860 do {861 if (s->direction == AMDTP_IN_STREAM)···873874 /* NOTE: TAG1 matches CIP. This just affects in stream. */875 tag = FW_ISO_CONTEXT_MATCH_TAG1;876- if (s->flags & CIP_EMPTY_WITH_TAG0)877 tag |= FW_ISO_CONTEXT_MATCH_TAG0;878879 s->callbacked = false;
···2728/* isochronous header parameters */29#define ISO_DATA_LENGTH_SHIFT 1630+#define TAG_NO_CIP_HEADER 031#define TAG_CIP 13233/* common isochronous packet header parameters */···37#define CIP_SID_MASK 0x3f00000038#define CIP_DBS_MASK 0x00ff000039#define CIP_DBS_SHIFT 1640+#define CIP_SPH_MASK 0x0000040041+#define CIP_SPH_SHIFT 1042#define CIP_DBC_MASK 0x000000ff43#define CIP_FMT_SHIFT 2444#define CIP_FMT_MASK 0x3f000000···232unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s)233{234 unsigned int multiplier = 1;235+ unsigned int header_size = 0;236237 if (s->flags & CIP_JUMBO_PAYLOAD)238 multiplier = 5;239+ if (!(s->flags & CIP_NO_HEADER))240+ header_size = 8;241242+ return header_size +243+ s->syt_interval * s->data_block_quadlets * 4 * multiplier;244}245EXPORT_SYMBOL(amdtp_stream_get_max_payload);246···378 goto end;379380 p.interrupt = IS_ALIGNED(s->packet_index + 1, INTERRUPT_INTERVAL);381+ p.tag = s->tag;382 p.header_length = header_length;383 if (payload_length > 0)384 p.payload_length = payload_length;···405406static inline int queue_in_packet(struct amdtp_stream *s)407{408+ return queue_packet(s, IN_PACKET_HEADER_SIZE, s->max_payload_length);0409}410411+static int handle_out_packet(struct amdtp_stream *s,412+ unsigned int payload_length, unsigned int cycle,413 unsigned int index)414{415 __be32 *buffer;416 unsigned int syt;417 unsigned int data_blocks;0418 unsigned int pcm_frames;419 struct snd_pcm_substream *pcm;420···424 data_blocks = calculate_data_blocks(s, syt);425 pcm_frames = s->process_data_blocks(s, buffer + 2, data_blocks, &syt);426427+ if (s->flags & CIP_DBC_IS_END_EVENT)428+ s->data_block_counter =429+ (s->data_block_counter + data_blocks) & 0xff;430+431 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) |432 (s->data_block_quadlets << CIP_DBS_SHIFT) |433+ ((s->sph << CIP_SPH_SHIFT) & CIP_SPH_MASK) |434 s->data_block_counter);435 buffer[1] = cpu_to_be32(CIP_EOH |436 ((s->fmt << CIP_FMT_SHIFT) & CIP_FMT_MASK) |437 ((s->fdf << CIP_FDF_SHIFT) & CIP_FDF_MASK) |438 (syt & CIP_SYT_MASK));439440+ if (!(s->flags & CIP_DBC_IS_END_EVENT))441+ s->data_block_counter =442+ (s->data_block_counter + data_blocks) & 0xff;443 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets;444445 trace_out_packet(s, cycle, buffer, payload_length, index);···448 return 0;449}450451+static int handle_out_packet_without_header(struct amdtp_stream *s,452+ unsigned int payload_length, unsigned int cycle,453+ unsigned int index)454+{455+ __be32 *buffer;456+ unsigned int syt;457+ unsigned int data_blocks;458+ unsigned int pcm_frames;459+ struct snd_pcm_substream *pcm;460+461+ buffer = s->buffer.packets[s->packet_index].buffer;462+ syt = calculate_syt(s, cycle);463+ data_blocks = calculate_data_blocks(s, syt);464+ pcm_frames = s->process_data_blocks(s, buffer, data_blocks, &syt);465+ s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;466+467+ payload_length = data_blocks * 4 * s->data_block_quadlets;468+469+ trace_out_packet_without_header(s, cycle, payload_length, data_blocks,470+ index);471+472+ if (queue_out_packet(s, payload_length) < 0)473+ return -EIO;474+475+ pcm = ACCESS_ONCE(s->pcm);476+ if (pcm && pcm_frames > 0)477+ update_pcm_pointers(s, pcm, pcm_frames);478+479+ /* No need to return the number of handled data blocks. */480+ return 0;481+}482+483static int handle_in_packet(struct amdtp_stream *s,484+ unsigned int payload_length, unsigned int cycle,485 unsigned int index)486{487 __be32 *buffer;488 u32 cip_header[2];489+ unsigned int sph, fmt, fdf, syt;490 unsigned int data_block_quadlets, data_block_counter, dbc_interval;491 unsigned int data_blocks;492 struct snd_pcm_substream *pcm;···465 cip_header[0] = be32_to_cpu(buffer[0]);466 cip_header[1] = be32_to_cpu(buffer[1]);467468+ trace_in_packet(s, cycle, cip_header, payload_length, index);469470 /*471 * This module supports 'Two-quadlet CIP header with SYT field'.472 * For convenience, also check FMT field is AM824 or not.473 */474+ if ((((cip_header[0] & CIP_EOH_MASK) == CIP_EOH) ||475+ ((cip_header[1] & CIP_EOH_MASK) != CIP_EOH)) &&476+ (!(s->flags & CIP_HEADER_WITHOUT_EOH))) {477 dev_info_ratelimited(&s->unit->device,478 "Invalid CIP header for AMDTP: %08X:%08X\n",479 cip_header[0], cip_header[1]);···482 }483484 /* Check valid protocol or not. */485+ sph = (cip_header[0] & CIP_SPH_MASK) >> CIP_SPH_SHIFT;486 fmt = (cip_header[1] & CIP_FMT_MASK) >> CIP_FMT_SHIFT;487+ if (sph != s->sph || fmt != s->fmt) {488 dev_info_ratelimited(&s->unit->device,489 "Detect unexpected protocol: %08x %08x\n",490 cip_header[0], cip_header[1]);···494495 /* Calculate data blocks */496 fdf = (cip_header[1] & CIP_FDF_MASK) >> CIP_FDF_SHIFT;497+ if (payload_length < 12 ||498 (fmt == CIP_FMT_AM && fdf == AMDTP_FDF_NO_DATA)) {499 data_blocks = 0;500 } else {···510 if (s->flags & CIP_WRONG_DBS)511 data_block_quadlets = s->data_block_quadlets;512513+ data_blocks = (payload_length / 4 - 2) /514+ data_block_quadlets;515 }516517 /* Check data block counter continuity */···551 s->data_block_counter =552 (data_block_counter + data_blocks) & 0xff;553end:554+ if (queue_in_packet(s) < 0)555+ return -EIO;556+557+ pcm = ACCESS_ONCE(s->pcm);558+ if (pcm && pcm_frames > 0)559+ update_pcm_pointers(s, pcm, pcm_frames);560+561+ return 0;562+}563+564+static int handle_in_packet_without_header(struct amdtp_stream *s,565+ unsigned int payload_quadlets, unsigned int cycle,566+ unsigned int index)567+{568+ __be32 *buffer;569+ unsigned int data_blocks;570+ struct snd_pcm_substream *pcm;571+ unsigned int pcm_frames;572+573+ buffer = s->buffer.packets[s->packet_index].buffer;574+ data_blocks = payload_quadlets / s->data_block_quadlets;575+576+ trace_in_packet_without_header(s, cycle, payload_quadlets, data_blocks,577+ index);578+579+ pcm_frames = s->process_data_blocks(s, buffer, data_blocks, NULL);580+ s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff;581+582 if (queue_in_packet(s) < 0)583 return -EIO;584···604605 for (i = 0; i < packets; ++i) {606 cycle = increment_cycle_count(cycle, 1);607+ if (s->handle_packet(s, 0, cycle, i) < 0) {608 s->packet_index = -1;609 amdtp_stream_pcm_abort(s);610 return;···620{621 struct amdtp_stream *s = private_data;622 unsigned int i, packets;623+ unsigned int payload_length, max_payload_length;624 __be32 *headers = header;625 u32 cycle;626···636 cycle = decrement_cycle_count(cycle, packets);637638 /* For buffer-over-run prevention. */639+ max_payload_length = s->max_payload_length;640641 for (i = 0; i < packets; i++) {642 cycle = increment_cycle_count(cycle, 1);643644+ /* The number of bytes in this packet */645+ payload_length =646+ (be32_to_cpu(headers[i]) >> ISO_DATA_LENGTH_SHIFT);647+ if (payload_length > max_payload_length) {648 dev_err(&s->unit->device,649+ "Detect jumbo payload: %04x %04x\n",650+ payload_length, max_payload_length);651 break;652 }653654+ if (s->handle_packet(s, payload_length, cycle, i) < 0)655 break;656 }657···671 void *header, void *private_data)672{673 struct amdtp_stream *s = private_data;674+ u32 cycle;675+ unsigned int packets;676+677+ s->max_payload_length = amdtp_stream_get_max_payload(s);678679 /*680 * For in-stream, first packet has come.···679 s->callbacked = true;680 wake_up(&s->callback_wait);681682+ cycle = compute_cycle_count(tstamp);683+684+ if (s->direction == AMDTP_IN_STREAM) {685+ packets = header_length / IN_PACKET_HEADER_SIZE;686+ cycle = decrement_cycle_count(cycle, packets);687 context->callback.sc = in_stream_callback;688+ if (s->flags & CIP_NO_HEADER)689+ s->handle_packet = handle_in_packet_without_header;690+ else691+ s->handle_packet = handle_in_packet;692+ } else {693+ packets = header_length / 4;694+ cycle = increment_cycle_count(cycle, QUEUE_LENGTH - packets);695 context->callback.sc = out_stream_callback;696+ if (s->flags & CIP_NO_HEADER)697+ s->handle_packet = handle_out_packet_without_header;698+ else699+ s->handle_packet = handle_out_packet;700+ }701+702+ s->start_cycle = cycle;703704 context->callback.sc(context, tstamp, header_length, header, s);705}···759760 amdtp_stream_update(s);761762+ if (s->flags & CIP_NO_HEADER)763+ s->tag = TAG_NO_CIP_HEADER;764+ else765+ s->tag = TAG_CIP;766+767 s->packet_index = 0;768 do {769 if (s->direction == AMDTP_IN_STREAM)···771772 /* NOTE: TAG1 matches CIP. This just affects in stream. */773 tag = FW_ISO_CONTEXT_MATCH_TAG1;774+ if ((s->flags & CIP_EMPTY_WITH_TAG0) || (s->flags & CIP_NO_HEADER))775 tag |= FW_ISO_CONTEXT_MATCH_TAG0;776777 s->callbacked = false;
+14-2
sound/firewire/amdtp-stream.h
···18 * SYT_INTERVAL samples, with these two types alternating so that19 * the overall sample rate comes out right.20 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.21- * @CIP_DBC_IS_END_EVENT: Only for in-stream. The value of dbc in an in-packet22- * corresponds to the end of event in the packet. Out of IEC 61883.23 * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets.24 * The value of data_block_quadlets is used instead of reported value.25 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is···29 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an30 * packet is larger than IEC 61883-6 defines. Current implementation31 * allows 5 times as large as IEC 61883-6 defines.00032 */33enum cip_flags {34 CIP_NONBLOCKING = 0x00,···42 CIP_SKIP_DBC_ZERO_CHECK = 0x10,43 CIP_EMPTY_HAS_WRONG_DBC = 0x20,44 CIP_JUMBO_PAYLOAD = 0x40,0045};4647/**···106 struct fw_iso_context *context;107 struct iso_packets_buffer buffer;108 int packet_index;00000109110 /* For CIP headers. */111 unsigned int source_node_id_field;112 unsigned int data_block_quadlets;113 unsigned int data_block_counter;0114 unsigned int fmt;115 unsigned int fdf;116 /* quirk: fixed interval of dbc between previos/current packets. */···141 /* To wait for first packet. */142 bool callbacked;143 wait_queue_head_t callback_wait;0144145 /* For backends to process data blocks. */146 void *protocol;
···18 * SYT_INTERVAL samples, with these two types alternating so that19 * the overall sample rate comes out right.20 * @CIP_EMPTY_WITH_TAG0: Only for in-stream. Empty in-packets have TAG0.21+ * @CIP_DBC_IS_END_EVENT: The value of dbc in an packet corresponds to the end22+ * of event in the packet. Out of IEC 61883.23 * @CIP_WRONG_DBS: Only for in-stream. The value of dbs is wrong in in-packets.24 * The value of data_block_quadlets is used instead of reported value.25 * @CIP_SKIP_DBC_ZERO_CHECK: Only for in-stream. Packets with zero in dbc is···29 * @CIP_JUMBO_PAYLOAD: Only for in-stream. The number of data blocks in an30 * packet is larger than IEC 61883-6 defines. Current implementation31 * allows 5 times as large as IEC 61883-6 defines.32+ * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include33+ * valid EOH.34+ * @CIP_NO_HEADERS: a lack of headers in packets35 */36enum cip_flags {37 CIP_NONBLOCKING = 0x00,···39 CIP_SKIP_DBC_ZERO_CHECK = 0x10,40 CIP_EMPTY_HAS_WRONG_DBC = 0x20,41 CIP_JUMBO_PAYLOAD = 0x40,42+ CIP_HEADER_WITHOUT_EOH = 0x80,43+ CIP_NO_HEADER = 0x100,44};4546/**···101 struct fw_iso_context *context;102 struct iso_packets_buffer buffer;103 int packet_index;104+ int tag;105+ int (*handle_packet)(struct amdtp_stream *s,106+ unsigned int payload_quadlets, unsigned int cycle,107+ unsigned int index);108+ unsigned int max_payload_length;109110 /* For CIP headers. */111 unsigned int source_node_id_field;112 unsigned int data_block_quadlets;113 unsigned int data_block_counter;114+ unsigned int sph;115 unsigned int fmt;116 unsigned int fdf;117 /* quirk: fixed interval of dbc between previos/current packets. */···130 /* To wait for first packet. */131 bool callbacked;132 wait_queue_head_t callback_wait;133+ u32 start_cycle;134135 /* For backends to process data blocks. */136 void *protocol;
···28 */29#define MAX_MIDI_RX_BLOCKS 83000031/*32 * The double-oh-three algorithm was discovered by Robin Gareus and Damien33 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.···45 unsigned int pcm_channels;46 struct dot_state state;4748- unsigned int midi_ports;49- /* 2 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) */50- struct snd_rawmidi_substream *midi[2];51- int midi_fifo_used[2];52 int midi_fifo_limit;5354 void (*transfer_samples)(struct amdtp_stream *s,···125 return -EBUSY;126127 /*128- * A first data channel is for MIDI conformant data channel, the rest is129- * Multi Bit Linear Audio data channel.130 */131 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);132 if (err < 0)···135 s->fdf = AMDTP_FDF_AM824 | s->sfc;136137 p->pcm_channels = pcm_channels;138-139- if (s->direction == AMDTP_IN_STREAM)140- p->midi_ports = DOT_MIDI_IN_PORTS;141- else142- p->midi_ports = DOT_MIDI_OUT_PORTS;143144 /*145 * We do not know the actual MIDI FIFO size of most devices. Just···277 b = (u8 *)&buffer[0];278279 len = 0;280- if (port < p->midi_ports &&281 midi_ratelimit_per_packet(s, port) &&282 p->midi[port] != NULL)283 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);284285 if (len > 0) {286- b[3] = (0x10 << port) | len;000000000000287 midi_use_bytes(s, port, len);288 } else {289 b[1] = 0;···317318 for (f = 0; f < data_blocks; f++) {319 b = (u8 *)&buffer[0];320- port = b[3] >> 4;321- len = b[3] & 0x0f;322323- if (port < p->midi_ports && p->midi[port] && len > 0)324- snd_rawmidi_receive(p->midi[port], b + 1, len);0000000000000325326 buffer += s->data_block_quadlets;327 }···383{384 struct amdtp_dot *p = s->protocol;385386- if (port < p->midi_ports)387 ACCESS_ONCE(p->midi[port]) = midi;388}389
···28 */29#define MAX_MIDI_RX_BLOCKS 83031+/* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */32+#define MAX_MIDI_PORTS 333+34/*35 * The double-oh-three algorithm was discovered by Robin Gareus and Damien36 * Zammit in 2012, with reverse-engineering for Digi 003 Rack.···42 unsigned int pcm_channels;43 struct dot_state state;4445+ struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS];46+ int midi_fifo_used[MAX_MIDI_PORTS];0047 int midi_fifo_limit;4849 void (*transfer_samples)(struct amdtp_stream *s,···124 return -EBUSY;125126 /*127+ * A first data channel is for MIDI messages, the rest is Multi Bit128+ * Linear Audio data channel.129 */130 err = amdtp_stream_set_parameters(s, rate, pcm_channels + 1);131 if (err < 0)···134 s->fdf = AMDTP_FDF_AM824 | s->sfc;135136 p->pcm_channels = pcm_channels;00000137138 /*139 * We do not know the actual MIDI FIFO size of most devices. Just···281 b = (u8 *)&buffer[0];282283 len = 0;284+ if (port < MAX_MIDI_PORTS &&285 midi_ratelimit_per_packet(s, port) &&286 p->midi[port] != NULL)287 len = snd_rawmidi_transmit(p->midi[port], b + 1, 2);288289 if (len > 0) {290+ /*291+ * Upper 4 bits of LSB represent port number.292+ * - 0000b: physical MIDI port 1.293+ * - 0010b: physical MIDI port 2.294+ * - 1110b: console MIDI port.295+ */296+ if (port == 2)297+ b[3] = 0xe0;298+ else if (port == 1)299+ b[3] = 0x20;300+ else301+ b[3] = 0x00;302+ b[3] |= len;303 midi_use_bytes(s, port, len);304 } else {305 b[1] = 0;···309310 for (f = 0; f < data_blocks; f++) {311 b = (u8 *)&buffer[0];00312313+ len = b[3] & 0x0f;314+ if (len > 0) {315+ /*316+ * Upper 4 bits of LSB represent port number.317+ * - 0000b: physical MIDI port 1. Use port 0.318+ * - 1110b: console MIDI port. Use port 2.319+ */320+ if (b[3] >> 4 > 0)321+ port = 2;322+ else323+ port = 0;324+325+ if (port < MAX_MIDI_PORTS && p->midi[port])326+ snd_rawmidi_receive(p->midi[port], b + 1, len);327+ }328329 buffer += s->data_block_quadlets;330 }···364{365 struct amdtp_dot *p = s->protocol;366367+ if (port < MAX_MIDI_PORTS)368 ACCESS_ONCE(p->midi[port]) = midi;369}370
···58 struct fw_address_handler async_handler;59 u32 msg;6061- /* For asynchronous MIDI controls. */62- struct snd_rawmidi_substream *in_control;63- struct snd_fw_async_midi_port out_control;64};6566#define DG00X_ADDR_BASE 0xffffe0000000ull6768#define DG00X_OFFSET_STREAMING_STATE 0x000069#define DG00X_OFFSET_STREAMING_SET 0x000470-#define DG00X_OFFSET_MIDI_CTL_ADDR 0x000871/* For LSB of the address 0x000c */72/* unknown 0x0010 */73#define DG00X_OFFSET_MESSAGE_ADDR 0x0014
···58 struct fw_address_handler async_handler;59 u32 msg;6061+ /* Console models have additional MIDI ports for control surface. */62+ bool is_console;063};6465#define DG00X_ADDR_BASE 0xffffe0000000ull6667#define DG00X_OFFSET_STREAMING_STATE 0x000068#define DG00X_OFFSET_STREAMING_SET 0x000469+/* unknown but address in host space 0x0008 */70/* For LSB of the address 0x000c */71/* unknown 0x0010 */72#define DG00X_OFFSET_MESSAGE_ADDR 0x0014
+9-3
sound/firewire/fcp.c
···63 /* do transaction and check buf[1-5] are the same against command */64 err = fcp_avc_transaction(unit, buf, 8, buf, 8,65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));66- if (err >= 0 && err < 8)0067 err = -EIO;68 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */69 err = -ENOSYS;···108 /* do transaction and check buf[1-4] are the same against command */109 err = fcp_avc_transaction(unit, buf, 8, buf, 8,110 BIT(1) | BIT(2) | BIT(3) | BIT(4));111- if (err >= 0 && err < 8)00112 err = -EIO;113 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */114 err = -ENOSYS;···158 buf[3] = 0xff & subfunction;159160 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));161- if (err >= 0 && err < 8)00162 err = -EIO;163 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */164 err = -ENOSYS;
···63 /* do transaction and check buf[1-5] are the same against command */64 err = fcp_avc_transaction(unit, buf, 8, buf, 8,65 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5));66+ if (err < 0)67+ ;68+ else if (err < 8)69 err = -EIO;70 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */71 err = -ENOSYS;···106 /* do transaction and check buf[1-4] are the same against command */107 err = fcp_avc_transaction(unit, buf, 8, buf, 8,108 BIT(1) | BIT(2) | BIT(3) | BIT(4));109+ if (err < 0)110+ ;111+ else if (err < 8)112 err = -EIO;113 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */114 err = -ENOSYS;···154 buf[3] = 0xff & subfunction;155156 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2));157+ if (err < 0)158+ ;159+ else if (err < 8)160 err = -EIO;161 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */162 err = -ENOSYS;
···1+/*2+ * ff-transaction.c - a part of driver for RME Fireface series3+ *4+ * Copyright (c) 2015-2017 Takashi Sakamoto5+ *6+ * Licensed under the terms of the GNU General Public License, version 2.7+ */8+9+#include "ff.h"10+11+static void finish_transmit_midi_msg(struct snd_ff *ff, unsigned int port,12+ int rcode)13+{14+ struct snd_rawmidi_substream *substream =15+ ACCESS_ONCE(ff->rx_midi_substreams[port]);16+17+ if (rcode_is_permanent_error(rcode)) {18+ ff->rx_midi_error[port] = true;19+ return;20+ }21+22+ if (rcode != RCODE_COMPLETE) {23+ /* Transfer the message again, immediately. */24+ ff->next_ktime[port] = 0;25+ schedule_work(&ff->rx_midi_work[port]);26+ return;27+ }28+29+ snd_rawmidi_transmit_ack(substream, ff->rx_bytes[port]);30+ ff->rx_bytes[port] = 0;31+32+ if (!snd_rawmidi_transmit_empty(substream))33+ schedule_work(&ff->rx_midi_work[port]);34+}35+36+static void finish_transmit_midi0_msg(struct fw_card *card, int rcode,37+ void *data, size_t length,38+ void *callback_data)39+{40+ struct snd_ff *ff =41+ container_of(callback_data, struct snd_ff, transactions[0]);42+ finish_transmit_midi_msg(ff, 0, rcode);43+}44+45+static void finish_transmit_midi1_msg(struct fw_card *card, int rcode,46+ void *data, size_t length,47+ void *callback_data)48+{49+ struct snd_ff *ff =50+ container_of(callback_data, struct snd_ff, transactions[1]);51+ finish_transmit_midi_msg(ff, 1, rcode);52+}53+54+static inline void fill_midi_buf(struct snd_ff *ff, unsigned int port,55+ unsigned int index, u8 byte)56+{57+ ff->msg_buf[port][index] = cpu_to_le32(byte);58+}59+60+static void transmit_midi_msg(struct snd_ff *ff, unsigned int port)61+{62+ struct snd_rawmidi_substream *substream =63+ ACCESS_ONCE(ff->rx_midi_substreams[port]);64+ u8 *buf = (u8 *)ff->msg_buf[port];65+ int i, len;66+67+ struct fw_device *fw_dev = fw_parent_device(ff->unit);68+ unsigned long long addr;69+ int generation;70+ fw_transaction_callback_t callback;71+72+ if (substream == NULL || snd_rawmidi_transmit_empty(substream))73+ return;74+75+ if (ff->rx_bytes[port] > 0 || ff->rx_midi_error[port])76+ return;77+78+ /* Do it in next chance. */79+ if (ktime_after(ff->next_ktime[port], ktime_get())) {80+ schedule_work(&ff->rx_midi_work[port]);81+ return;82+ }83+84+ len = snd_rawmidi_transmit_peek(substream, buf,85+ SND_FF_MAXIMIM_MIDI_QUADS);86+ if (len <= 0)87+ return;88+89+ for (i = len - 1; i >= 0; i--)90+ fill_midi_buf(ff, port, i, buf[i]);91+92+ if (port == 0) {93+ addr = ff->spec->protocol->midi_rx_port_0_reg;94+ callback = finish_transmit_midi0_msg;95+ } else {96+ addr = ff->spec->protocol->midi_rx_port_1_reg;97+ callback = finish_transmit_midi1_msg;98+ }99+100+ /* Set interval to next transaction. */101+ ff->next_ktime[port] = ktime_add_ns(ktime_get(),102+ len * 8 * NSEC_PER_SEC / 31250);103+ ff->rx_bytes[port] = len;104+105+ /*106+ * In Linux FireWire core, when generation is updated with memory107+ * barrier, node id has already been updated. In this module, After108+ * this smp_rmb(), load/store instructions to memory are completed.109+ * Thus, both of generation and node id are available with recent110+ * values. This is a light-serialization solution to handle bus reset111+ * events on IEEE 1394 bus.112+ */113+ generation = fw_dev->generation;114+ smp_rmb();115+ fw_send_request(fw_dev->card, &ff->transactions[port],116+ TCODE_WRITE_BLOCK_REQUEST,117+ fw_dev->node_id, generation, fw_dev->max_speed,118+ addr, &ff->msg_buf[port], len * 4,119+ callback, &ff->transactions[port]);120+}121+122+static void transmit_midi0_msg(struct work_struct *work)123+{124+ struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[0]);125+126+ transmit_midi_msg(ff, 0);127+}128+129+static void transmit_midi1_msg(struct work_struct *work)130+{131+ struct snd_ff *ff = container_of(work, struct snd_ff, rx_midi_work[1]);132+133+ transmit_midi_msg(ff, 1);134+}135+136+static void handle_midi_msg(struct fw_card *card, struct fw_request *request,137+ int tcode, int destination, int source,138+ int generation, unsigned long long offset,139+ void *data, size_t length, void *callback_data)140+{141+ struct snd_ff *ff = callback_data;142+ __le32 *buf = data;143+ u32 quad;144+ u8 byte;145+ unsigned int index;146+ struct snd_rawmidi_substream *substream;147+ int i;148+149+ fw_send_response(card, request, RCODE_COMPLETE);150+151+ for (i = 0; i < length / 4; i++) {152+ quad = le32_to_cpu(buf[i]);153+154+ /* Message in first port. */155+ /*156+ * This value may represent the index of this unit when the same157+ * units are on the same IEEE 1394 bus. This driver doesn't use158+ * it.159+ */160+ index = (quad >> 8) & 0xff;161+ if (index > 0) {162+ substream = ACCESS_ONCE(ff->tx_midi_substreams[0]);163+ if (substream != NULL) {164+ byte = quad & 0xff;165+ snd_rawmidi_receive(substream, &byte, 1);166+ }167+ }168+169+ /* Message in second port. */170+ index = (quad >> 24) & 0xff;171+ if (index > 0) {172+ substream = ACCESS_ONCE(ff->tx_midi_substreams[1]);173+ if (substream != NULL) {174+ byte = (quad >> 16) & 0xff;175+ snd_rawmidi_receive(substream, &byte, 1);176+ }177+ }178+ }179+}180+181+static int allocate_own_address(struct snd_ff *ff, int i)182+{183+ struct fw_address_region midi_msg_region;184+ int err;185+186+ ff->async_handler.length = SND_FF_MAXIMIM_MIDI_QUADS * 4;187+ ff->async_handler.address_callback = handle_midi_msg;188+ ff->async_handler.callback_data = ff;189+190+ midi_msg_region.start = 0x000100000000ull * i;191+ midi_msg_region.end = midi_msg_region.start + ff->async_handler.length;192+193+ err = fw_core_add_address_handler(&ff->async_handler, &midi_msg_region);194+ if (err >= 0) {195+ /* Controllers are allowed to register this region. */196+ if (ff->async_handler.offset & 0x0000ffffffff) {197+ fw_core_remove_address_handler(&ff->async_handler);198+ err = -EAGAIN;199+ }200+ }201+202+ return err;203+}204+205+/*206+ * The configuration to start asynchronous transactions for MIDI messages is in207+ * 0x'0000'8010'051c. This register includes the other options, thus this driver208+ * doesn't touch it and leaves the decision to userspace. The userspace MUST add209+ * 0x04000000 to write transactions to the register to receive any MIDI210+ * messages.211+ *212+ * Here, I just describe MIDI-related offsets of the register, in little-endian213+ * order.214+ *215+ * Controllers are allowed to register higher 4 bytes of address to receive216+ * the transactions. The register is 0x'0000'8010'03f4. On the other hand, the217+ * controllers are not allowed to register lower 4 bytes of the address. They218+ * are forced to select from 4 options by writing corresponding bits to219+ * 0x'0000'8010'051c.220+ *221+ * The 3rd-6th bits in MSB of this register are used to indicate lower 4 bytes222+ * of address to which the device transferrs the transactions.223+ * - 6th: 0x'....'....'0000'0180224+ * - 5th: 0x'....'....'0000'0100225+ * - 4th: 0x'....'....'0000'0080226+ * - 3rd: 0x'....'....'0000'0000227+ *228+ * This driver configure 0x'....'....'0000'0000 for units to receive MIDI229+ * messages. 3rd bit of the register should be configured, however this driver230+ * deligates this task to user space applications due to a restriction that231+ * this register is write-only and the other bits have own effects.232+ *233+ * The 1st and 2nd bits in LSB of this register are used to cancel transferring234+ * asynchronous transactions. These two bits have the same effect.235+ * - 1st/2nd: cancel transferring236+ */237+int snd_ff_transaction_reregister(struct snd_ff *ff)238+{239+ struct fw_card *fw_card = fw_parent_device(ff->unit)->card;240+ u32 addr;241+ __le32 reg;242+243+ /*244+ * Controllers are allowed to register its node ID and upper 2 byte of245+ * local address to listen asynchronous transactions.246+ */247+ addr = (fw_card->node_id << 16) | (ff->async_handler.offset >> 32);248+ reg = cpu_to_le32(addr);249+ return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,250+ ff->spec->protocol->midi_high_addr_reg,251+ ®, sizeof(reg), 0);252+}253+254+int snd_ff_transaction_register(struct snd_ff *ff)255+{256+ int i, err;257+258+ /*259+ * Allocate in Memory Space of IEC 13213, but lower 4 byte in LSB should260+ * be zero due to device specification.261+ */262+ for (i = 0; i < 0xffff; i++) {263+ err = allocate_own_address(ff, i);264+ if (err != -EBUSY && err != -EAGAIN)265+ break;266+ }267+ if (err < 0)268+ return err;269+270+ err = snd_ff_transaction_reregister(ff);271+ if (err < 0)272+ return err;273+274+ INIT_WORK(&ff->rx_midi_work[0], transmit_midi0_msg);275+ INIT_WORK(&ff->rx_midi_work[1], transmit_midi1_msg);276+277+ return 0;278+}279+280+void snd_ff_transaction_unregister(struct snd_ff *ff)281+{282+ __le32 reg;283+284+ if (ff->async_handler.callback_data == NULL)285+ return;286+ ff->async_handler.callback_data = NULL;287+288+ /* Release higher 4 bytes of address. */289+ reg = cpu_to_le32(0x00000000);290+ snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST,291+ ff->spec->protocol->midi_high_addr_reg,292+ ®, sizeof(reg), 0);293+294+ fw_core_remove_address_handler(&ff->async_handler);295+}
···99}100EXPORT_SYMBOL(snd_fw_schedule_registration);101102-static void async_midi_port_callback(struct fw_card *card, int rcode,103- void *data, size_t length,104- void *callback_data)105-{106- struct snd_fw_async_midi_port *port = callback_data;107- struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);108-109- /* This port is closed. */110- if (substream == NULL)111- return;112-113- if (rcode == RCODE_COMPLETE)114- snd_rawmidi_transmit_ack(substream, port->consume_bytes);115- else if (!rcode_is_permanent_error(rcode))116- /* To start next transaction immediately for recovery. */117- port->next_ktime = 0;118- else119- /* Don't continue processing. */120- port->error = true;121-122- port->idling = true;123-124- if (!snd_rawmidi_transmit_empty(substream))125- schedule_work(&port->work);126-}127-128-static void midi_port_work(struct work_struct *work)129-{130- struct snd_fw_async_midi_port *port =131- container_of(work, struct snd_fw_async_midi_port, work);132- struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);133- int generation;134- int type;135-136- /* Under transacting or error state. */137- if (!port->idling || port->error)138- return;139-140- /* Nothing to do. */141- if (substream == NULL || snd_rawmidi_transmit_empty(substream))142- return;143-144- /* Do it in next chance. */145- if (ktime_after(port->next_ktime, ktime_get())) {146- schedule_work(&port->work);147- return;148- }149-150- /*151- * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().152- * Later, snd_rawmidi_transmit_ack() is called.153- */154- memset(port->buf, 0, port->len);155- port->consume_bytes = port->fill(substream, port->buf);156- if (port->consume_bytes <= 0) {157- /* Do it in next chance, immediately. */158- if (port->consume_bytes == 0) {159- port->next_ktime = 0;160- schedule_work(&port->work);161- } else {162- /* Fatal error. */163- port->error = true;164- }165- return;166- }167-168- /* Calculate type of transaction. */169- if (port->len == 4)170- type = TCODE_WRITE_QUADLET_REQUEST;171- else172- type = TCODE_WRITE_BLOCK_REQUEST;173-174- /* Set interval to next transaction. */175- port->next_ktime = ktime_add_ns(ktime_get(),176- port->consume_bytes * 8 * NSEC_PER_SEC / 31250);177-178- /* Start this transaction. */179- port->idling = false;180-181- /*182- * In Linux FireWire core, when generation is updated with memory183- * barrier, node id has already been updated. In this module, After184- * this smp_rmb(), load/store instructions to memory are completed.185- * Thus, both of generation and node id are available with recent186- * values. This is a light-serialization solution to handle bus reset187- * events on IEEE 1394 bus.188- */189- generation = port->parent->generation;190- smp_rmb();191-192- fw_send_request(port->parent->card, &port->transaction, type,193- port->parent->node_id, generation,194- port->parent->max_speed, port->addr,195- port->buf, port->len, async_midi_port_callback,196- port);197-}198-199-/**200- * snd_fw_async_midi_port_init - initialize asynchronous MIDI port structure201- * @port: the asynchronous MIDI port to initialize202- * @unit: the target of the asynchronous transaction203- * @addr: the address to which transactions are transferred204- * @len: the length of transaction205- * @fill: the callback function to fill given buffer, and returns the206- * number of consumed bytes for MIDI message.207- *208- */209-int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port,210- struct fw_unit *unit, u64 addr, unsigned int len,211- snd_fw_async_midi_port_fill fill)212-{213- port->len = DIV_ROUND_UP(len, 4) * 4;214- port->buf = kzalloc(port->len, GFP_KERNEL);215- if (port->buf == NULL)216- return -ENOMEM;217-218- port->parent = fw_parent_device(unit);219- port->addr = addr;220- port->fill = fill;221- port->idling = true;222- port->next_ktime = 0;223- port->error = false;224-225- INIT_WORK(&port->work, midi_port_work);226-227- return 0;228-}229-EXPORT_SYMBOL(snd_fw_async_midi_port_init);230-231-/**232- * snd_fw_async_midi_port_destroy - free asynchronous MIDI port structure233- * @port: the asynchronous MIDI port structure234- */235-void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port)236-{237- snd_fw_async_midi_port_finish(port);238- cancel_work_sync(&port->work);239- kfree(port->buf);240-}241-EXPORT_SYMBOL(snd_fw_async_midi_port_destroy);242-243MODULE_DESCRIPTION("FireWire audio helper functions");244MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");245MODULE_LICENSE("GPL v2");
···58 return -EINVAL;59}6061-static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf)062{63- struct snd_tscm *tscm = substream->rmidi->private_data;64- unsigned int port = substream->number;65 int i, len, consume;66 u8 *label, *msg;67 u8 status;6869 /* The first byte is used for label, the rest for MIDI bytes. */70- label = buf;71- msg = buf + 1;7273 consume = snd_rawmidi_transmit_peek(substream, msg, 3);74 if (consume == 0)75 return 0;7677 /* On exclusive message. */78- if (tscm->on_sysex[port]) {79 /* Seek the end of exclusives. */80 for (i = 0; i < consume; ++i) {81 if (msg[i] == 0xf7) {82- tscm->on_sysex[port] = false;83 break;84 }85 }8687 /* At the end of exclusive message, use label 0x07. */88- if (!tscm->on_sysex[port]) {89 consume = i + 1;90- *label = (port << 4) | 0x07;91 /* During exclusive message, use label 0x04. */92 } else if (consume == 3) {93- *label = (port << 4) | 0x04;94 /* We need to fill whole 3 bytes. Go to next change. */95 } else {96 return 0;···100 /* The beginning of exclusives. */101 if (msg[0] == 0xf0) {102 /* Transfer it in next chance in another condition. */103- tscm->on_sysex[port] = true;104 return 0;105 } else {106 /* On running-status. */107 if ((msg[0] & 0x80) != 0x80)108- status = tscm->running_status[port];109 else110 status = msg[0];111···123124 msg[2] = msg[1];125 msg[1] = msg[0];126- msg[0] = tscm->running_status[port];127 } else {128 /* Enough MIDI bytes were not retrieved. */129 if (consume < len)130 return 0;131 consume = len;132133- tscm->running_status[port] = msg[0];134 }135 }136137- *label = (port << 4) | (msg[0] >> 4);138 }139140 if (len > 0 && len < 3)141 memset(msg + len, 0, 3 - len);142143 return consume;0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000144}145146static void handle_midi_tx(struct fw_card *card, struct fw_request *request,···318 goto error;319320 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) {321- err = snd_fw_async_midi_port_init(322- &tscm->out_ports[i], tscm->unit,323- TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD,324- 4, fill_message);325- if (err < 0)326- goto error;327 }328329 return err;···371void snd_tscm_transaction_unregister(struct snd_tscm *tscm)372{373 __be32 reg;374- unsigned int i;375376 if (tscm->async_handler.callback_data == NULL)377 return;···397398 fw_core_remove_address_handler(&tscm->async_handler);399 tscm->async_handler.callback_data = NULL;400-401- for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++)402- snd_fw_async_midi_port_destroy(&tscm->out_ports[i]);403}
···58 return -EINVAL;59}6061+static int fill_message(struct snd_fw_async_midi_port *port,62+ struct snd_rawmidi_substream *substream)63{0064 int i, len, consume;65 u8 *label, *msg;66 u8 status;6768 /* The first byte is used for label, the rest for MIDI bytes. */69+ label = port->buf;70+ msg = port->buf + 1;7172 consume = snd_rawmidi_transmit_peek(substream, msg, 3);73 if (consume == 0)74 return 0;7576 /* On exclusive message. */77+ if (port->on_sysex) {78 /* Seek the end of exclusives. */79 for (i = 0; i < consume; ++i) {80 if (msg[i] == 0xf7) {81+ port->on_sysex = false;82 break;83 }84 }8586 /* At the end of exclusive message, use label 0x07. */87+ if (!port->on_sysex) {88 consume = i + 1;89+ *label = (substream->number << 4) | 0x07;90 /* During exclusive message, use label 0x04. */91 } else if (consume == 3) {92+ *label = (substream->number << 4) | 0x04;93 /* We need to fill whole 3 bytes. Go to next change. */94 } else {95 return 0;···101 /* The beginning of exclusives. */102 if (msg[0] == 0xf0) {103 /* Transfer it in next chance in another condition. */104+ port->on_sysex = true;105 return 0;106 } else {107 /* On running-status. */108 if ((msg[0] & 0x80) != 0x80)109+ status = port->running_status;110 else111 status = msg[0];112···124125 msg[2] = msg[1];126 msg[1] = msg[0];127+ msg[0] = port->running_status;128 } else {129 /* Enough MIDI bytes were not retrieved. */130 if (consume < len)131 return 0;132 consume = len;133134+ port->running_status = msg[0];135 }136 }137138+ *label = (substream->number << 4) | (msg[0] >> 4);139 }140141 if (len > 0 && len < 3)142 memset(msg + len, 0, 3 - len);143144 return consume;145+}146+147+static void async_midi_port_callback(struct fw_card *card, int rcode,148+ void *data, size_t length,149+ void *callback_data)150+{151+ struct snd_fw_async_midi_port *port = callback_data;152+ struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);153+154+ /* This port is closed. */155+ if (substream == NULL)156+ return;157+158+ if (rcode == RCODE_COMPLETE)159+ snd_rawmidi_transmit_ack(substream, port->consume_bytes);160+ else if (!rcode_is_permanent_error(rcode))161+ /* To start next transaction immediately for recovery. */162+ port->next_ktime = 0;163+ else164+ /* Don't continue processing. */165+ port->error = true;166+167+ port->idling = true;168+169+ if (!snd_rawmidi_transmit_empty(substream))170+ schedule_work(&port->work);171+}172+173+static void midi_port_work(struct work_struct *work)174+{175+ struct snd_fw_async_midi_port *port =176+ container_of(work, struct snd_fw_async_midi_port, work);177+ struct snd_rawmidi_substream *substream = ACCESS_ONCE(port->substream);178+ int generation;179+180+ /* Under transacting or error state. */181+ if (!port->idling || port->error)182+ return;183+184+ /* Nothing to do. */185+ if (substream == NULL || snd_rawmidi_transmit_empty(substream))186+ return;187+188+ /* Do it in next chance. */189+ if (ktime_after(port->next_ktime, ktime_get())) {190+ schedule_work(&port->work);191+ return;192+ }193+194+ /*195+ * Fill the buffer. The callee must use snd_rawmidi_transmit_peek().196+ * Later, snd_rawmidi_transmit_ack() is called.197+ */198+ memset(port->buf, 0, 4);199+ port->consume_bytes = fill_message(port, substream);200+ if (port->consume_bytes <= 0) {201+ /* Do it in next chance, immediately. */202+ if (port->consume_bytes == 0) {203+ port->next_ktime = 0;204+ schedule_work(&port->work);205+ } else {206+ /* Fatal error. */207+ port->error = true;208+ }209+ return;210+ }211+212+ /* Set interval to next transaction. */213+ port->next_ktime = ktime_add_ns(ktime_get(),214+ port->consume_bytes * 8 * NSEC_PER_SEC / 31250);215+216+ /* Start this transaction. */217+ port->idling = false;218+219+ /*220+ * In Linux FireWire core, when generation is updated with memory221+ * barrier, node id has already been updated. In this module, After222+ * this smp_rmb(), load/store instructions to memory are completed.223+ * Thus, both of generation and node id are available with recent224+ * values. This is a light-serialization solution to handle bus reset225+ * events on IEEE 1394 bus.226+ */227+ generation = port->parent->generation;228+ smp_rmb();229+230+ fw_send_request(port->parent->card, &port->transaction,231+ TCODE_WRITE_QUADLET_REQUEST,232+ port->parent->node_id, generation,233+ port->parent->max_speed,234+ TSCM_ADDR_BASE + TSCM_OFFSET_MIDI_RX_QUAD,235+ port->buf, 4, async_midi_port_callback,236+ port);237+}238+239+void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port)240+{241+ port->idling = true;242+ port->error = false;243+ port->running_status = 0;244+ port->on_sysex = false;245}246247static void handle_midi_tx(struct fw_card *card, struct fw_request *request,···219 goto error;220221 for (i = 0; i < TSCM_MIDI_OUT_PORT_MAX; i++) {222+ tscm->out_ports[i].parent = fw_parent_device(tscm->unit);223+ tscm->out_ports[i].next_ktime = 0;224+ INIT_WORK(&tscm->out_ports[i].work, midi_port_work);000225 }226227 return err;···275void snd_tscm_transaction_unregister(struct snd_tscm *tscm)276{277 __be32 reg;0278279 if (tscm->async_handler.callback_data == NULL)280 return;···302303 fw_core_remove_address_handler(&tscm->async_handler);304 tscm->async_handler.callback_data = NULL;000305}
···171{172 int timeout;173 u32 val;174- int mask = (1 << AZX_MLCTL_CPA);175176 udelay(3);177 timeout = 150;···179 do {180 val = readl(link->ml_addr + AZX_REG_ML_LCTL);181 if (enable) {182- if (((val & mask) >> AZX_MLCTL_CPA))183 return 0;184 } else {185- if (!((val & mask) >> AZX_MLCTL_CPA))186 return 0;187 }188 udelay(3);
···171{172 int timeout;173 u32 val;174+ int mask = (1 << AZX_MLCTL_CPA_SHIFT);175176 udelay(3);177 timeout = 150;···179 do {180 val = readl(link->ml_addr + AZX_REG_ML_LCTL);181 if (enable) {182+ if (((val & mask) >> AZX_MLCTL_CPA_SHIFT))183 return 0;184 } else {185+ if (!((val & mask) >> AZX_MLCTL_CPA_SHIFT))186 return 0;187 }188 udelay(3);
+1-1
sound/hda/hdac_controller.c
···272273 /* Lets walk the linked capabilities list */274 do {275- cur_cap = _snd_hdac_chip_read(l, bus, offset);276277 dev_dbg(bus->dev, "Capability version: 0x%x\n",278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
···272273 /* Lets walk the linked capabilities list */274 do {275+ cur_cap = _snd_hdac_chip_readl(bus, offset);276277 dev_dbg(bus->dev, "Capability version: 0x%x\n",278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
+2-2
sound/hda/hdac_stream.c
···555556 if (!reg)557 reg = AZX_REG_SSYNC;558- val = _snd_hdac_chip_read(l, bus, reg);559 if (set)560 val |= streams;561 else562 val &= ~streams;563- _snd_hdac_chip_write(l, bus, reg, val);564}565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);566
···555556 if (!reg)557 reg = AZX_REG_SSYNC;558+ val = _snd_hdac_chip_readl(bus, reg);559 if (set)560 val |= streams;561 else562 val &= ~streams;563+ _snd_hdac_chip_writel(bus, reg, val);564}565EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger);566
···2279 } else {2280 int src[2], mix[2];22810002282 /* Get SRC and MIXER hardware resources. */2283 for (i = 0; i < nr_ch; i++) {2284 if ((mix[i] =
···2279 } else {2280 int src[2], mix[2];22812282+ if (nr_ch < 1)2283+ return -EINVAL;2284+2285 /* Get SRC and MIXER hardware resources. */2286 for (i = 0; i < nr_ch; i++) {2287 if ((mix[i] =
···256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */257 unsigned int power_save_node:1; /* advanced PM for each widget */258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */0259#ifdef CONFIG_PM260 unsigned long power_on_acct;261 unsigned long power_off_acct;
···256 unsigned int dump_coef:1; /* dump processing coefs in codec proc file */257 unsigned int power_save_node:1; /* advanced PM for each widget */258 unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */259+ unsigned int force_pin_prefix:1; /* Add location prefix */260#ifdef CONFIG_PM261 unsigned long power_on_acct;262 unsigned long power_off_acct;
+7-2
sound/pci/hda/hda_generic.c
···196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");197 if (val >= 0)198 spec->suppress_hp_mic_detect = !val;000199200 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))201 spec->mixer_nid = val;···11281129 *index = 0;1130 if (cfg->line_outs == 1 && !spec->multi_ios &&01131 !cfg->hp_outs && !cfg->speaker_outs)1132 return spec->vmaster_mute.hook ? "PCM" : "Master";1133···1136 * use it master (or "PCM" if a vmaster hook is present)1137 */1138 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&01139 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])1140 return spec->vmaster_mute.hook ? "PCM" : "Master";1141···5036 }50375038 /* if we have no master control, let's create it */5039- if (!spec->no_analog &&5040 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {5041 err = snd_hda_add_vmaster(codec, "Master Playback Volume",5042 spec->vmaster_tlv, slave_pfxs,···5044 if (err < 0)5045 return err;5046 }5047- if (!spec->no_analog &&5048 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {5049 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",5050 NULL, slave_pfxs,
···196 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");197 if (val >= 0)198 spec->suppress_hp_mic_detect = !val;199+ val = snd_hda_get_bool_hint(codec, "vmaster");200+ if (val >= 0)201+ spec->suppress_vmaster = !val;202203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))204 spec->mixer_nid = val;···11251126 *index = 0;1127 if (cfg->line_outs == 1 && !spec->multi_ios &&1128+ !codec->force_pin_prefix &&1129 !cfg->hp_outs && !cfg->speaker_outs)1130 return spec->vmaster_mute.hook ? "PCM" : "Master";1131···1132 * use it master (or "PCM" if a vmaster hook is present)1133 */1134 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&1135+ !codec->force_pin_prefix &&1136 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])1137 return spec->vmaster_mute.hook ? "PCM" : "Master";1138···5031 }50325033 /* if we have no master control, let's create it */5034+ if (!spec->no_analog && !spec->suppress_vmaster &&5035 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {5036 err = snd_hda_add_vmaster(codec, "Master Playback Volume",5037 spec->vmaster_tlv, slave_pfxs,···5039 if (err < 0)5040 return err;5041 }5042+ if (!spec->no_analog && !spec->suppress_vmaster &&5043 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {5044 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",5045 NULL, slave_pfxs,
+1
sound/pci/hda/hda_generic.h
···229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */230 unsigned int power_down_unused:1; /* power down unused widgets */231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */0232233 /* other internal flags */234 unsigned int no_analog:1; /* digital I/O only */
···229 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */230 unsigned int power_down_unused:1; /* power down unused widgets */231 unsigned int dac_min_mute:1; /* minimal = mute for DACs */232+ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */233234 /* other internal flags */235 unsigned int no_analog:1; /* digital I/O only */
+134-5
sound/pci/hda/hda_intel.c
···77 POS_FIX_POSBUF,78 POS_FIX_VIACOMBO,79 POS_FIX_COMBO,080};8182/* Defines for ATI HD Audio support in SB450 south bridge */···149MODULE_PARM_DESC(model, "Use the given board model.");150module_param_array(position_fix, int, NULL, 0444);151MODULE_PARM_DESC(position_fix, "DMA pointer read method."152- "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");153module_param_array(bdl_pos_adj, int, NULL, 0644);154MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");155module_param_array(probe_mask, int, NULL, 0444);···370#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)371#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)372#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)0373#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \374- IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)0375376static char *driver_short_names[] = {377 [AZX_DRIVER_ICH] = "HDA Intel",···537{538 u32 val;539540- val = azx_readl(chip, SKL_EM4L);541 val &= (0x3 << 20);542- azx_writel(chip, SKL_EM4L, val);00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543}544545static void hda_intel_init_chip(struct azx *chip, bool full_reset)···659 /* reduce dma latency to avoid noise */660 if (IS_BXT(pci))661 bxt_reduce_dma_latency(chip);000662}663664/* calculate runtime delay from LPIB */···911912 /* Calculate real DMA position we want */913 return bound_pos + mod_dma_pos;0000000000000000000000000914}915916#ifdef CONFIG_PM···1474 case POS_FIX_POSBUF:1475 case POS_FIX_VIACOMBO:1476 case POS_FIX_COMBO:01477 return fix;1478 }1479···1495 dev_dbg(chip->card->dev, "Using LPIB position fix\n");1496 return POS_FIX_LPIB;1497 }00001498 return POS_FIX_AUTO;1499}1500···1510 [POS_FIX_POSBUF] = azx_get_pos_posbuf,1511 [POS_FIX_VIACOMBO] = azx_via_get_position,1512 [POS_FIX_COMBO] = azx_get_pos_lpib,01513 };15141515 chip->get_position[0] = chip->get_position[1] = callbacks[fix];···1519 if (fix == POS_FIX_COMBO)1520 chip->get_position[1] = NULL;15211522- if (fix == POS_FIX_POSBUF &&1523 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {1524 chip->get_delay[0] = chip->get_delay[1] =1525 azx_get_delay_from_lpib;
···77 POS_FIX_POSBUF,78 POS_FIX_VIACOMBO,79 POS_FIX_COMBO,80+ POS_FIX_SKL,81};8283/* Defines for ATI HD Audio support in SB450 south bridge */···148MODULE_PARM_DESC(model, "Use the given board model.");149module_param_array(position_fix, int, NULL, 0444);150MODULE_PARM_DESC(position_fix, "DMA pointer read method."151+ "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+).");152module_param_array(bdl_pos_adj, int, NULL, 0644);153MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");154module_param_array(probe_mask, int, NULL, 0444);···369#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)370#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)371#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)372+#define IS_GLK(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x3198)373#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \374+ IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci) || \375+ IS_GLK(pci)376377static char *driver_short_names[] = {378 [AZX_DRIVER_ICH] = "HDA Intel",···534{535 u32 val;536537+ val = azx_readl(chip, VS_EM4L);538 val &= (0x3 << 20);539+ azx_writel(chip, VS_EM4L, val);540+}541+542+/*543+ * ML_LCAP bits:544+ * bit 0: 6 MHz Supported545+ * bit 1: 12 MHz Supported546+ * bit 2: 24 MHz Supported547+ * bit 3: 48 MHz Supported548+ * bit 4: 96 MHz Supported549+ * bit 5: 192 MHz Supported550+ */551+static int intel_get_lctl_scf(struct azx *chip)552+{553+ struct hdac_bus *bus = azx_bus(chip);554+ static int preferred_bits[] = { 2, 3, 1, 4, 5 };555+ u32 val, t;556+ int i;557+558+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);559+560+ for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {561+ t = preferred_bits[i];562+ if (val & (1 << t))563+ return t;564+ }565+566+ dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");567+ return 0;568+}569+570+static int intel_ml_lctl_set_power(struct azx *chip, int state)571+{572+ struct hdac_bus *bus = azx_bus(chip);573+ u32 val;574+ int timeout;575+576+ /*577+ * the codecs are sharing the first link setting by default578+ * If other links are enabled for stream, they need similar fix579+ */580+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);581+ val &= ~AZX_MLCTL_SPA;582+ val |= state << AZX_MLCTL_SPA_SHIFT;583+ writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);584+ /* wait for CPA */585+ timeout = 50;586+ while (timeout) {587+ if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &588+ AZX_MLCTL_CPA) == (state << AZX_MLCTL_CPA_SHIFT))589+ return 0;590+ timeout--;591+ udelay(10);592+ }593+594+ return -1;595+}596+597+static void intel_init_lctl(struct azx *chip)598+{599+ struct hdac_bus *bus = azx_bus(chip);600+ u32 val;601+ int ret;602+603+ /* 0. check lctl register value is correct or not */604+ val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);605+ /* if SCF is already set, let's use it */606+ if ((val & ML_LCTL_SCF_MASK) != 0)607+ return;608+609+ /*610+ * Before operating on SPA, CPA must match SPA.611+ * Any deviation may result in undefined behavior.612+ */613+ if (((val & AZX_MLCTL_SPA) >> AZX_MLCTL_SPA_SHIFT) !=614+ ((val & AZX_MLCTL_CPA) >> AZX_MLCTL_CPA_SHIFT))615+ return;616+617+ /* 1. turn link down: set SPA to 0 and wait CPA to 0 */618+ ret = intel_ml_lctl_set_power(chip, 0);619+ udelay(100);620+ if (ret)621+ goto set_spa;622+623+ /* 2. update SCF to select a properly audio clock*/624+ val &= ~ML_LCTL_SCF_MASK;625+ val |= intel_get_lctl_scf(chip);626+ writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);627+628+set_spa:629+ /* 4. turn link up: set SPA to 1 and wait CPA to 1 */630+ intel_ml_lctl_set_power(chip, 1);631+ udelay(100);632}633634static void hda_intel_init_chip(struct azx *chip, bool full_reset)···564 /* reduce dma latency to avoid noise */565 if (IS_BXT(pci))566 bxt_reduce_dma_latency(chip);567+568+ if (bus->mlcap != NULL)569+ intel_init_lctl(chip);570}571572/* calculate runtime delay from LPIB */···813814 /* Calculate real DMA position we want */815 return bound_pos + mod_dma_pos;816+}817+818+static unsigned int azx_skl_get_dpib_pos(struct azx *chip,819+ struct azx_dev *azx_dev)820+{821+ return _snd_hdac_chip_readl(azx_bus(chip),822+ AZX_REG_VS_SDXDPIB_XBASE +823+ (AZX_REG_VS_SDXDPIB_XINTERVAL *824+ azx_dev->core.index));825+}826+827+/* get the current DMA position with correction on SKL+ chips */828+static unsigned int azx_get_pos_skl(struct azx *chip, struct azx_dev *azx_dev)829+{830+ /* DPIB register gives a more accurate position for playback */831+ if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK)832+ return azx_skl_get_dpib_pos(chip, azx_dev);833+834+ /* For capture, we need to read posbuf, but it requires a delay835+ * for the possible boundary overlap; the read of DPIB fetches the836+ * actual posbuf837+ */838+ udelay(20);839+ azx_skl_get_dpib_pos(chip, azx_dev);840+ return azx_get_pos_posbuf(chip, azx_dev);841}842843#ifdef CONFIG_PM···1351 case POS_FIX_POSBUF:1352 case POS_FIX_VIACOMBO:1353 case POS_FIX_COMBO:1354+ case POS_FIX_SKL:1355 return fix;1356 }1357···1371 dev_dbg(chip->card->dev, "Using LPIB position fix\n");1372 return POS_FIX_LPIB;1373 }1374+ if (IS_SKL_PLUS(chip->pci)) {1375+ dev_dbg(chip->card->dev, "Using SKL position fix\n");1376+ return POS_FIX_SKL;1377+ }1378 return POS_FIX_AUTO;1379}1380···1382 [POS_FIX_POSBUF] = azx_get_pos_posbuf,1383 [POS_FIX_VIACOMBO] = azx_via_get_position,1384 [POS_FIX_COMBO] = azx_get_pos_lpib,1385+ [POS_FIX_SKL] = azx_get_pos_skl,1386 };13871388 chip->get_position[0] = chip->get_position[1] = callbacks[fix];···1390 if (fix == POS_FIX_COMBO)1391 chip->get_position[1] = NULL;13921393+ if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&1394 (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {1395 chip->get_delay[0] = chip->get_delay[1] =1396 azx_get_delay_from_lpib;
+5-5
sound/pci/hda/patch_ca0132.c
···857 chip_addx >> 16);858 }859860- spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx;861862 return res;863}···882 /*If no error encountered, automatically increment the address883 as per chip behaviour*/884 spec->curr_chip_addx = (res != -EIO) ?885- (spec->curr_chip_addx + 4) : ~0UL;886 return res;887}888···933 /*If no error encountered, automatically increment the address934 as per chip behaviour*/935 spec->curr_chip_addx = (res != -EIO) ?936- (spec->curr_chip_addx + 4) : ~0UL;937 return res;938}939···1168 int status = 0;1169 unsigned int count;11701171- if ((buffer == NULL))1172 return -EINVAL;11731174 count = 0;···1210 unsigned int skip_count;1211 unsigned int dummy;12121213- if ((buffer == NULL))1214 return -1;12151216 count = 0;
···857 chip_addx >> 16);858 }859860+ spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx;861862 return res;863}···882 /*If no error encountered, automatically increment the address883 as per chip behaviour*/884 spec->curr_chip_addx = (res != -EIO) ?885+ (spec->curr_chip_addx + 4) : ~0U;886 return res;887}888···933 /*If no error encountered, automatically increment the address934 as per chip behaviour*/935 spec->curr_chip_addx = (res != -EIO) ?936+ (spec->curr_chip_addx + 4) : ~0U;937 return res;938}939···1168 int status = 0;1169 unsigned int count;11701171+ if (buffer == NULL)1172 return -EINVAL;11731174 count = 0;···1210 unsigned int skip_count;1211 unsigned int dummy;12121213+ if (buffer == NULL)1214 return -1;12151216 count = 0;
···1172};11731174/* the read-only variant */1175-static struct snd_kcontrol_new usb_feature_unit_ctl_ro = {1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1177 .name = "", /* will be filled later manually */1178 .info = mixer_ctl_feature_info,···1745}17461747/* alsa control interface for processing/extension unit */1748-static struct snd_kcontrol_new mixer_procunit_ctl = {1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1750 .name = "", /* will be filled later */1751 .info = mixer_ctl_feature_info,···2033}20342035/* alsa control interface for selector unit */2036-static struct snd_kcontrol_new mixer_selectunit_ctl = {2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,2038 .name = "", /* will be filled later */2039 .info = mixer_ctl_selector_info,
···1172};11731174/* the read-only variant */1175+static const struct snd_kcontrol_new usb_feature_unit_ctl_ro = {1176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1177 .name = "", /* will be filled later manually */1178 .info = mixer_ctl_feature_info,···1745}17461747/* alsa control interface for processing/extension unit */1748+static const struct snd_kcontrol_new mixer_procunit_ctl = {1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,1750 .name = "", /* will be filled later */1751 .info = mixer_ctl_feature_info,···2033}20342035/* alsa control interface for selector unit */2036+static const struct snd_kcontrol_new mixer_selectunit_ctl = {2037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,2038 .name = "", /* will be filled later */2039 .info = mixer_ctl_selector_info,