Merge branch 'for-next' into for-linus

For 4.12 merge.

+6482 -744
+2
Documentation/sound/hd-audio/notes.rst
··· 494 hp_mic_detect (bool) 495 enable/disable the hp/mic shared input for a single built-in mic 496 case; default true 497 mixer_nid (int) 498 specifies the widget NID of the analog-loopback mixer 499
··· 494 hp_mic_detect (bool) 495 enable/disable the hp/mic shared input for a single built-in mic 496 case; default true 497 + vmaster (bool) 498 + enable/disable the virtual Master control; default true 499 mixer_nid (int) 500 specifies the widget NID of the analog-loopback mixer 501
+25 -5
include/sound/hda_register.h
··· 106 #define AZX_REG_HSW_EM4 0x100c 107 #define AZX_REG_HSW_EM5 0x1010 108 109 - /* Skylake/Broxton display HD-A controller Extended Mode registers */ 110 - #define AZX_REG_SKL_EM4L 0x1040 111 112 /* PCI space */ 113 #define AZX_PCIREG_TCSEL 0x44 ··· 261 #define AZX_REG_ML_LOUTPAY 0x20 262 #define AZX_REG_ML_LINPAY 0x30 263 264 - #define AZX_MLCTL_SPA (1<<16) 265 - #define AZX_MLCTL_CPA 23 266 - 267 268 /* registers for DMA Resume Capability Structure */ 269 #define AZX_DRSM_CAP_ID 0x5
··· 106 #define AZX_REG_HSW_EM4 0x100c 107 #define AZX_REG_HSW_EM5 0x1010 108 109 + /* Skylake/Broxton vendor-specific registers */ 110 + #define AZX_REG_VS_EM1 0x1000 111 + #define AZX_REG_VS_INRC 0x1004 112 + #define AZX_REG_VS_OUTRC 0x1008 113 + #define AZX_REG_VS_FIFOTRK 0x100C 114 + #define AZX_REG_VS_FIFOTRK2 0x1010 115 + #define AZX_REG_VS_EM2 0x1030 116 + #define AZX_REG_VS_EM3L 0x1038 117 + #define AZX_REG_VS_EM3U 0x103C 118 + #define AZX_REG_VS_EM4L 0x1040 119 + #define AZX_REG_VS_EM4U 0x1044 120 + #define AZX_REG_VS_LTRC 0x1048 121 + #define AZX_REG_VS_D0I3C 0x104A 122 + #define AZX_REG_VS_PCE 0x104B 123 + #define AZX_REG_VS_L2MAGC 0x1050 124 + #define AZX_REG_VS_L2LAHPT 0x1054 125 + #define AZX_REG_VS_SDXDPIB_XBASE 0x1084 126 + #define AZX_REG_VS_SDXDPIB_XINTERVAL 0x20 127 + #define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 128 + #define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 129 130 /* PCI space */ 131 #define AZX_PCIREG_TCSEL 0x44 ··· 243 #define AZX_REG_ML_LOUTPAY 0x20 244 #define AZX_REG_ML_LINPAY 0x30 245 246 + #define ML_LCTL_SCF_MASK 0xF 247 + #define AZX_MLCTL_SPA (0x1 << 16) 248 + #define AZX_MLCTL_CPA (0x1 << 23) 249 + #define AZX_MLCTL_SPA_SHIFT 16 250 + #define AZX_MLCTL_CPA_SHIFT 23 251 252 /* registers for DMA Resume Capability Structure */ 253 #define AZX_DRSM_CAP_ID 0x5
+18 -10
include/sound/hdaudio.h
··· 368 /* 369 * macros for easy use 370 */ 371 - #define _snd_hdac_chip_write(type, chip, reg, value) \ 372 - ((chip)->io_ops->reg_write ## type(value, (chip)->remap_addr + (reg))) 373 - #define _snd_hdac_chip_read(type, chip, reg) \ 374 - ((chip)->io_ops->reg_read ## type((chip)->remap_addr + (reg))) 375 376 /* read/write a register, pass without AZX_REG_ prefix */ 377 #define snd_hdac_chip_writel(chip, reg, value) \ 378 - _snd_hdac_chip_write(l, chip, AZX_REG_ ## reg, value) 379 #define snd_hdac_chip_writew(chip, reg, value) \ 380 - _snd_hdac_chip_write(w, chip, AZX_REG_ ## reg, value) 381 #define snd_hdac_chip_writeb(chip, reg, value) \ 382 - _snd_hdac_chip_write(b, chip, AZX_REG_ ## reg, value) 383 #define snd_hdac_chip_readl(chip, reg) \ 384 - _snd_hdac_chip_read(l, chip, AZX_REG_ ## reg) 385 #define snd_hdac_chip_readw(chip, reg) \ 386 - _snd_hdac_chip_read(w, chip, AZX_REG_ ## reg) 387 #define snd_hdac_chip_readb(chip, reg) \ 388 - _snd_hdac_chip_read(b, chip, AZX_REG_ ## reg) 389 390 /* update a register, pass without AZX_REG_ prefix */ 391 #define snd_hdac_chip_updatel(chip, reg, mask, val) \
··· 368 /* 369 * macros for easy use 370 */ 371 + #define _snd_hdac_chip_writeb(chip, reg, value) \ 372 + ((chip)->io_ops->reg_writeb(value, (chip)->remap_addr + (reg))) 373 + #define _snd_hdac_chip_readb(chip, reg) \ 374 + ((chip)->io_ops->reg_readb((chip)->remap_addr + (reg))) 375 + #define _snd_hdac_chip_writew(chip, reg, value) \ 376 + ((chip)->io_ops->reg_writew(value, (chip)->remap_addr + (reg))) 377 + #define _snd_hdac_chip_readw(chip, reg) \ 378 + ((chip)->io_ops->reg_readw((chip)->remap_addr + (reg))) 379 + #define _snd_hdac_chip_writel(chip, reg, value) \ 380 + ((chip)->io_ops->reg_writel(value, (chip)->remap_addr + (reg))) 381 + #define _snd_hdac_chip_readl(chip, reg) \ 382 + ((chip)->io_ops->reg_readl((chip)->remap_addr + (reg))) 383 384 /* read/write a register, pass without AZX_REG_ prefix */ 385 #define snd_hdac_chip_writel(chip, reg, value) \ 386 + _snd_hdac_chip_writel(chip, AZX_REG_ ## reg, value) 387 #define snd_hdac_chip_writew(chip, reg, value) \ 388 + _snd_hdac_chip_writew(chip, AZX_REG_ ## reg, value) 389 #define snd_hdac_chip_writeb(chip, reg, value) \ 390 + _snd_hdac_chip_writeb(chip, AZX_REG_ ## reg, value) 391 #define snd_hdac_chip_readl(chip, reg) \ 392 + _snd_hdac_chip_readl(chip, AZX_REG_ ## reg) 393 #define snd_hdac_chip_readw(chip, reg) \ 394 + _snd_hdac_chip_readw(chip, AZX_REG_ ## reg) 395 #define snd_hdac_chip_readb(chip, reg) \ 396 + _snd_hdac_chip_readb(chip, AZX_REG_ ## reg) 397 398 /* update a register, pass without AZX_REG_ prefix */ 399 #define snd_hdac_chip_updatel(chip, reg, mask, val) \
+3 -1
include/uapi/sound/asound.h
··· 107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ 108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ 109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ 110 111 /* Don't forget to change the following: */ 112 - SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_LINE6 113 }; 114 115 struct snd_hwdep_info {
··· 107 SNDRV_HWDEP_IFACE_FW_DIGI00X, /* Digidesign Digi 002/003 family */ 108 SNDRV_HWDEP_IFACE_FW_TASCAM, /* TASCAM FireWire series */ 109 SNDRV_HWDEP_IFACE_LINE6, /* Line6 USB processors */ 110 + SNDRV_HWDEP_IFACE_FW_MOTU, /* MOTU FireWire series */ 111 + SNDRV_HWDEP_IFACE_FW_FIREFACE, /* RME Fireface series */ 112 113 /* Don't forget to change the following: */ 114 + SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_FW_FIREFACE 115 }; 116 117 struct snd_hwdep_info {
+9 -1
include/uapi/sound/firewire.h
··· 10 #define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e 11 #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 12 #define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c 13 14 struct snd_firewire_event_common { 15 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ ··· 47 __u32 message; /* Digi00x-specific message */ 48 }; 49 50 union snd_firewire_event { 51 struct snd_firewire_event_common common; 52 struct snd_firewire_event_lock_status lock_status; 53 struct snd_firewire_event_dice_notification dice_notification; 54 struct snd_firewire_event_efw_response efw_response; 55 struct snd_firewire_event_digi00x_message digi00x_message; 56 }; 57 58 ··· 72 #define SNDRV_FIREWIRE_TYPE_OXFW 4 73 #define SNDRV_FIREWIRE_TYPE_DIGI00X 5 74 #define SNDRV_FIREWIRE_TYPE_TASCAM 6 75 - /* RME, MOTU, ... */ 76 77 struct snd_firewire_get_info { 78 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */
··· 10 #define SNDRV_FIREWIRE_EVENT_DICE_NOTIFICATION 0xd1ce004e 11 #define SNDRV_FIREWIRE_EVENT_EFW_RESPONSE 0x4e617475 12 #define SNDRV_FIREWIRE_EVENT_DIGI00X_MESSAGE 0x746e736c 13 + #define SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION 0x64776479 14 15 struct snd_firewire_event_common { 16 unsigned int type; /* SNDRV_FIREWIRE_EVENT_xxx */ ··· 46 __u32 message; /* Digi00x-specific message */ 47 }; 48 49 + struct snd_firewire_event_motu_notification { 50 + unsigned int type; 51 + __u32 message; /* MOTU-specific bits. */ 52 + }; 53 + 54 union snd_firewire_event { 55 struct snd_firewire_event_common common; 56 struct snd_firewire_event_lock_status lock_status; 57 struct snd_firewire_event_dice_notification dice_notification; 58 struct snd_firewire_event_efw_response efw_response; 59 struct snd_firewire_event_digi00x_message digi00x_message; 60 + struct snd_firewire_event_motu_notification motu_notification; 61 }; 62 63 ··· 65 #define SNDRV_FIREWIRE_TYPE_OXFW 4 66 #define SNDRV_FIREWIRE_TYPE_DIGI00X 5 67 #define SNDRV_FIREWIRE_TYPE_TASCAM 6 68 + #define SNDRV_FIREWIRE_TYPE_MOTU 7 69 + #define SNDRV_FIREWIRE_TYPE_FIREFACE 8 70 71 struct snd_firewire_get_info { 72 unsigned int type; /* SNDRV_FIREWIRE_TYPE_xxx */
+7 -12
sound/core/timer.c
··· 1277 struct timespec tstamp; 1278 int prev, append = 0; 1279 1280 memset(&tstamp, 0, sizeof(tstamp)); 1281 spin_lock(&tu->qlock); 1282 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | ··· 1293 } 1294 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1295 tu->last_resolution != resolution) { 1296 - memset(&r1, 0, sizeof(r1)); 1297 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1298 r1.tstamp = tstamp; 1299 r1.val = resolution; ··· 1430 if (id.card < 0) { 1431 id.card = 0; 1432 } else { 1433 - if (id.card < 0) { 1434 - id.card = 0; 1435 } else { 1436 - if (id.device < 0) { 1437 - id.device = 0; 1438 - } else { 1439 - if (id.subdevice < 0) { 1440 - id.subdevice = 0; 1441 - } else { 1442 - id.subdevice++; 1443 - } 1444 - } 1445 } 1446 } 1447 list_for_each(p, &snd_timer_list) {
··· 1277 struct timespec tstamp; 1278 int prev, append = 0; 1279 1280 + memset(&r1, 0, sizeof(r1)); 1281 memset(&tstamp, 0, sizeof(tstamp)); 1282 spin_lock(&tu->qlock); 1283 if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) | ··· 1292 } 1293 if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && 1294 tu->last_resolution != resolution) { 1295 r1.event = SNDRV_TIMER_EVENT_RESOLUTION; 1296 r1.tstamp = tstamp; 1297 r1.val = resolution; ··· 1430 if (id.card < 0) { 1431 id.card = 0; 1432 } else { 1433 + if (id.device < 0) { 1434 + id.device = 0; 1435 } else { 1436 + if (id.subdevice < 0) 1437 + id.subdevice = 0; 1438 + else 1439 + id.subdevice++; 1440 } 1441 } 1442 list_for_each(p, &snd_timer_list) {
+1 -3
sound/drivers/vx/vx_core.c
··· 795 return NULL; 796 797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL); 798 - if (! chip) { 799 - snd_printk(KERN_ERR "vx_core: no memory\n"); 800 return NULL; 801 - } 802 mutex_init(&chip->lock); 803 chip->irq = -1; 804 chip->hw = hw;
··· 795 return NULL; 796 797 chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL); 798 + if (! chip) 799 return NULL; 800 mutex_init(&chip->lock); 801 chip->irq = -1; 802 chip->hw = hw;
+20
sound/firewire/Kconfig
··· 140 To compile this driver as a module, choose M here: the module 141 will be called snd-firewire-tascam. 142 143 endif # SND_FIREWIRE
··· 140 To compile this driver as a module, choose M here: the module 141 will be called snd-firewire-tascam. 142 143 + config SND_FIREWIRE_MOTU 144 + tristate "Mark of the unicorn FireWire series support" 145 + select SND_FIREWIRE_LIB 146 + select SND_HWDEP 147 + help 148 + Say Y here to enable support for FireWire devices which MOTU produced: 149 + * 828mk2 150 + * 828mk3 151 + 152 + To compile this driver as a module, choose M here: the module 153 + will be called snd-firewire-motu. 154 + 155 + config SND_FIREFACE 156 + tristate "RME Fireface series support" 157 + select SND_FIREWIRE_LIB 158 + select SND_HWDEP 159 + help 160 + Say Y here to include support for RME fireface series. 161 + * Fireface 400 162 + 163 endif # SND_FIREWIRE
+2
sound/firewire/Makefile
··· 13 obj-$(CONFIG_SND_BEBOB) += bebob/ 14 obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/ 15 obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/
··· 13 obj-$(CONFIG_SND_BEBOB) += bebob/ 14 obj-$(CONFIG_SND_FIREWIRE_DIGI00X) += digi00x/ 15 obj-$(CONFIG_SND_FIREWIRE_TASCAM) += tascam/ 16 + obj-$(CONFIG_SND_FIREWIRE_MOTU) += motu/ 17 + obj-$(CONFIG_SND_FIREFACE) += fireface/
+91 -3
sound/firewire/amdtp-stream-trace.h
··· 14 #include <linux/tracepoint.h> 15 16 TRACE_EVENT(in_packet, 17 - TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_quadlets, unsigned int index), 18 - TP_ARGS(s, cycles, cip_header, payload_quadlets, index), 19 TP_STRUCT__entry( 20 __field(unsigned int, second) 21 __field(unsigned int, cycle) ··· 37 __entry->dest = fw_parent_device(s->unit)->card->node_id; 38 __entry->cip_header0 = cip_header[0]; 39 __entry->cip_header1 = cip_header[1]; 40 - __entry->payload_quadlets = payload_quadlets; 41 __entry->packet_index = s->packet_index; 42 __entry->irq = !!in_interrupt(); 43 __entry->index = index; ··· 96 __entry->cip_header0, 97 __entry->cip_header1, 98 __entry->payload_quadlets, 99 __entry->packet_index, 100 __entry->irq, 101 __entry->index)
··· 14 #include <linux/tracepoint.h> 15 16 TRACE_EVENT(in_packet, 17 + TP_PROTO(const struct amdtp_stream *s, u32 cycles, u32 cip_header[2], unsigned int payload_length, unsigned int index), 18 + TP_ARGS(s, cycles, cip_header, payload_length, index), 19 TP_STRUCT__entry( 20 __field(unsigned int, second) 21 __field(unsigned int, cycle) ··· 37 __entry->dest = fw_parent_device(s->unit)->card->node_id; 38 __entry->cip_header0 = cip_header[0]; 39 __entry->cip_header1 = cip_header[1]; 40 + __entry->payload_quadlets = payload_length / 4; 41 __entry->packet_index = s->packet_index; 42 __entry->irq = !!in_interrupt(); 43 __entry->index = index; ··· 96 __entry->cip_header0, 97 __entry->cip_header1, 98 __entry->payload_quadlets, 99 + __entry->packet_index, 100 + __entry->irq, 101 + __entry->index) 102 + ); 103 + 104 + TRACE_EVENT(in_packet_without_header, 105 + TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_quadlets, unsigned int data_blocks, unsigned int index), 106 + TP_ARGS(s, cycles, payload_quadlets, data_blocks, index), 107 + TP_STRUCT__entry( 108 + __field(unsigned int, second) 109 + __field(unsigned int, cycle) 110 + __field(int, channel) 111 + __field(int, src) 112 + __field(int, dest) 113 + __field(unsigned int, payload_quadlets) 114 + __field(unsigned int, data_blocks) 115 + __field(unsigned int, data_block_counter) 116 + __field(unsigned int, packet_index) 117 + __field(unsigned int, irq) 118 + __field(unsigned int, index) 119 + ), 120 + TP_fast_assign( 121 + __entry->second = cycles / CYCLES_PER_SECOND; 122 + __entry->cycle = cycles % CYCLES_PER_SECOND; 123 + __entry->channel = s->context->channel; 124 + __entry->src = fw_parent_device(s->unit)->node_id; 125 + __entry->dest = fw_parent_device(s->unit)->card->node_id; 126 + __entry->payload_quadlets = payload_quadlets; 127 + __entry->data_blocks = data_blocks, 128 + __entry->data_block_counter = s->data_block_counter, 129 + __entry->packet_index = s->packet_index; 130 + __entry->irq = !!in_interrupt(); 131 + __entry->index = index; 132 + ), 133 + TP_printk( 134 + "%02u %04u %04x %04x %02d %03u %3u %3u %02u %01u %02u", 135 + __entry->second, 136 + __entry->cycle, 137 + __entry->src, 138 + __entry->dest, 139 + __entry->channel, 140 + __entry->payload_quadlets, 141 + __entry->data_blocks, 142 + __entry->data_block_counter, 143 + __entry->packet_index, 144 + __entry->irq, 145 + __entry->index) 146 + ); 147 + 148 + TRACE_EVENT(out_packet_without_header, 149 + TP_PROTO(const struct amdtp_stream *s, u32 cycles, unsigned int payload_length, unsigned int data_blocks, unsigned int index), 150 + TP_ARGS(s, cycles, payload_length, data_blocks, index), 151 + TP_STRUCT__entry( 152 + __field(unsigned int, second) 153 + __field(unsigned int, cycle) 154 + __field(int, channel) 155 + __field(int, src) 156 + __field(int, dest) 157 + __field(unsigned int, payload_quadlets) 158 + __field(unsigned int, data_blocks) 159 + __field(unsigned int, data_block_counter) 160 + __field(unsigned int, packet_index) 161 + __field(unsigned int, irq) 162 + __field(unsigned int, index) 163 + ), 164 + TP_fast_assign( 165 + __entry->second = cycles / CYCLES_PER_SECOND; 166 + __entry->cycle = cycles % CYCLES_PER_SECOND; 167 + __entry->channel = s->context->channel; 168 + __entry->src = fw_parent_device(s->unit)->card->node_id; 169 + __entry->dest = fw_parent_device(s->unit)->node_id; 170 + __entry->payload_quadlets = payload_length / 4; 171 + __entry->data_blocks = data_blocks, 172 + __entry->data_blocks = s->data_block_counter, 173 + __entry->packet_index = s->packet_index; 174 + __entry->irq = !!in_interrupt(); 175 + __entry->index = index; 176 + ), 177 + TP_printk( 178 + "%02u %04u %04x %04x %02d %03u %02u %03u %02u %01u %02u", 179 + __entry->second, 180 + __entry->cycle, 181 + __entry->src, 182 + __entry->dest, 183 + __entry->channel, 184 + __entry->payload_quadlets, 185 + __entry->data_blocks, 186 + __entry->data_block_counter, 187 __entry->packet_index, 188 __entry->irq, 189 __entry->index)
+130 -28
sound/firewire/amdtp-stream.c
··· 27 28 /* isochronous header parameters */ 29 #define ISO_DATA_LENGTH_SHIFT 16 30 #define TAG_CIP 1 31 32 /* common isochronous packet header parameters */ ··· 38 #define CIP_SID_MASK 0x3f000000 39 #define CIP_DBS_MASK 0x00ff0000 40 #define CIP_DBS_SHIFT 16 41 #define CIP_DBC_MASK 0x000000ff 42 #define CIP_FMT_SHIFT 24 43 #define CIP_FMT_MASK 0x3f000000 ··· 235 unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 236 { 237 unsigned int multiplier = 1; 238 239 if (s->flags & CIP_JUMBO_PAYLOAD) 240 multiplier = 5; 241 242 - return 8 + s->syt_interval * s->data_block_quadlets * 4 * multiplier; 243 } 244 EXPORT_SYMBOL(amdtp_stream_get_max_payload); 245 ··· 385 goto end; 386 387 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; ··· 412 413 static 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 } 418 419 - static int handle_out_packet(struct amdtp_stream *s, unsigned int cycle, 420 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); 432 433 buffer[0] = cpu_to_be32(ACCESS_ONCE(s->source_node_id_field) | 434 (s->data_block_quadlets << CIP_DBS_SHIFT) | 435 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)); 440 441 - s->data_block_counter = (s->data_block_counter + data_blocks) & 0xff; 442 payload_length = 8 + data_blocks * 4 * s->data_block_quadlets; 443 444 trace_out_packet(s, cycle, buffer, payload_length, index); ··· 461 return 0; 462 } 463 464 static 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]); 512 513 - trace_in_packet(s, cycle, cip_header, payload_quadlets, index); 514 515 /* 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)) { 521 dev_info_ratelimited(&s->unit->device, 522 "Invalid CIP header for AMDTP: %08X:%08X\n", 523 cip_header[0], cip_header[1]); ··· 528 } 529 530 /* Check valid protocol or not. */ 531 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]); ··· 541 542 /* 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; 559 560 - data_blocks = (payload_quadlets - 2) / data_block_quadlets; 561 } 562 563 /* Check data block counter continuity */ ··· 599 s->data_block_counter = 600 (data_block_counter + data_blocks) & 0xff; 601 end: 602 if (queue_in_packet(s) < 0) 603 return -EIO; 604 ··· 680 681 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); 713 714 /* For buffer-over-run prevention. */ 715 - max_payload_quadlets = amdtp_stream_get_max_payload(s) / 4; 716 717 for (i = 0; i < packets; i++) { 718 cycle = increment_cycle_count(cycle, 1); 719 720 - /* 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 } 729 730 - 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; 750 751 /* 752 * For in-stream, first packet has come. ··· 759 s->callbacked = true; 760 wake_up(&s->callback_wait); 761 762 - if (s->direction == AMDTP_IN_STREAM) 763 context->callback.sc = in_stream_callback; 764 - else 765 context->callback.sc = out_stream_callback; 766 767 context->callback.sc(context, tstamp, header_length, header, s); 768 } ··· 856 857 amdtp_stream_update(s); 858 859 s->packet_index = 0; 860 do { 861 if (s->direction == AMDTP_IN_STREAM) ··· 873 874 /* 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; 878 879 s->callbacked = false;
··· 27 28 /* isochronous header parameters */ 29 #define ISO_DATA_LENGTH_SHIFT 16 30 + #define TAG_NO_CIP_HEADER 0 31 #define TAG_CIP 1 32 33 /* common isochronous packet header parameters */ ··· 37 #define CIP_SID_MASK 0x3f000000 38 #define CIP_DBS_MASK 0x00ff0000 39 #define CIP_DBS_SHIFT 16 40 + #define CIP_SPH_MASK 0x00000400 41 + #define CIP_SPH_SHIFT 10 42 #define CIP_DBC_MASK 0x000000ff 43 #define CIP_FMT_SHIFT 24 44 #define CIP_FMT_MASK 0x3f000000 ··· 232 unsigned int amdtp_stream_get_max_payload(struct amdtp_stream *s) 233 { 234 unsigned int multiplier = 1; 235 + unsigned int header_size = 0; 236 237 if (s->flags & CIP_JUMBO_PAYLOAD) 238 multiplier = 5; 239 + if (!(s->flags & CIP_NO_HEADER)) 240 + header_size = 8; 241 242 + return header_size + 243 + s->syt_interval * s->data_block_quadlets * 4 * multiplier; 244 } 245 EXPORT_SYMBOL(amdtp_stream_get_max_payload); 246 ··· 378 goto end; 379 380 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; ··· 405 406 static inline int queue_in_packet(struct amdtp_stream *s) 407 { 408 + return queue_packet(s, IN_PACKET_HEADER_SIZE, s->max_payload_length); 409 } 410 411 + 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; 418 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); 426 427 + 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)); 439 440 + 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; 444 445 trace_out_packet(s, cycle, buffer, payload_length, index); ··· 448 return 0; 449 } 450 451 + 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 + 483 static 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]); 467 468 + trace_in_packet(s, cycle, cip_header, payload_length, index); 469 470 /* 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 } 483 484 /* 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]); ··· 494 495 /* 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; 512 513 + data_blocks = (payload_length / 4 - 2) / 514 + data_block_quadlets; 515 } 516 517 /* Check data block counter continuity */ ··· 551 s->data_block_counter = 552 (data_block_counter + data_blocks) & 0xff; 553 end: 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 ··· 604 605 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); 637 638 /* For buffer-over-run prevention. */ 639 + max_payload_length = s->max_payload_length; 640 641 for (i = 0; i < packets; i++) { 642 cycle = increment_cycle_count(cycle, 1); 643 644 + /* 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 } 653 654 + 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); 678 679 /* 680 * For in-stream, first packet has come. ··· 679 s->callbacked = true; 680 wake_up(&s->callback_wait); 681 682 + 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 + else 691 + 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 + else 699 + s->handle_packet = handle_out_packet; 700 + } 701 + 702 + s->start_cycle = cycle; 703 704 context->callback.sc(context, tstamp, header_length, header, s); 705 } ··· 759 760 amdtp_stream_update(s); 761 762 + if (s->flags & CIP_NO_HEADER) 763 + s->tag = TAG_NO_CIP_HEADER; 764 + else 765 + s->tag = TAG_CIP; 766 + 767 s->packet_index = 0; 768 do { 769 if (s->direction == AMDTP_IN_STREAM) ··· 771 772 /* 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; 776 777 s->callbacked = false;
+14 -2
sound/firewire/amdtp-stream.h
··· 18 * SYT_INTERVAL samples, with these two types alternating so that 19 * 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-packet 22 - * 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 an 30 * packet is larger than IEC 61883-6 defines. Current implementation 31 * allows 5 times as large as IEC 61883-6 defines. 32 */ 33 enum 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, 45 }; 46 47 /** ··· 106 struct fw_iso_context *context; 107 struct iso_packets_buffer buffer; 108 int packet_index; 109 110 /* 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 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; 144 145 /* For backends to process data blocks. */ 146 void *protocol;
··· 18 * SYT_INTERVAL samples, with these two types alternating so that 19 * 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 end 22 + * 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 an 30 * packet is larger than IEC 61883-6 defines. Current implementation 31 * allows 5 times as large as IEC 61883-6 defines. 32 + * @CIP_HEADER_WITHOUT_EOH: Only for in-stream. CIP Header doesn't include 33 + * valid EOH. 34 + * @CIP_NO_HEADERS: a lack of headers in packets 35 */ 36 enum 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 }; 45 46 /** ··· 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; 109 110 /* 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; 134 135 /* For backends to process data blocks. */ 136 void *protocol;
+22 -8
sound/firewire/bebob/bebob_command.c
··· 31 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 33 BIT(6) | BIT(7) | BIT(8)); 34 - if (err > 0 && err < 9) 35 err = -EIO; 36 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 37 err = -ENOSYS; 38 else if (buf[0] == 0x0a) /* REJECTED */ 39 err = -EINVAL; 40 - else if (err > 0) 41 err = 0; 42 43 kfree(buf); ··· 69 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 70 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 71 BIT(6) | BIT(8)); 72 - if (err > 0 && err < 9) 73 err = -EIO; 74 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 75 err = -ENOSYS; ··· 124 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 125 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 126 BIT(6) | BIT(7) | BIT(9)); 127 - if ((err >= 0) && (err < 8)) 128 err = -EIO; 129 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 130 err = -ENOSYS; ··· 156 err = fcp_avc_transaction(unit, buf, 12, buf, 256, 157 BIT(1) | BIT(2) | BIT(3) | BIT(4) | 158 BIT(5) | BIT(6) | BIT(7) | BIT(9)); 159 - if ((err >= 0) && (err < 8)) 160 err = -EIO; 161 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 162 err = -ENOSYS; ··· 195 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 196 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 197 BIT(6) | BIT(7) | BIT(9) | BIT(10)); 198 - if ((err >= 0) && (err < 8)) 199 err = -EIO; 200 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 201 err = -ENOSYS; ··· 231 err = fcp_avc_transaction(unit, buf, 16, buf, 16, 232 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 233 BIT(6) | BIT(7)); 234 - if ((err >= 0) && (err < 8)) 235 err = -EIO; 236 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 237 err = -ENOSYS; ··· 272 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 273 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 274 BIT(6) | BIT(7) | BIT(10)); 275 - if ((err >= 0) && (err < 12)) 276 err = -EIO; 277 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 278 err = -ENOSYS;
··· 31 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 32 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 33 BIT(6) | BIT(7) | BIT(8)); 34 + if (err < 0) 35 + ; 36 + else if (err < 9) 37 err = -EIO; 38 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 39 err = -ENOSYS; 40 else if (buf[0] == 0x0a) /* REJECTED */ 41 err = -EINVAL; 42 + else 43 err = 0; 44 45 kfree(buf); ··· 67 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 68 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 69 BIT(6) | BIT(8)); 70 + if (err < 0) 71 + ; 72 + else if (err < 9) 73 err = -EIO; 74 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 75 err = -ENOSYS; ··· 120 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 121 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 122 BIT(6) | BIT(7) | BIT(9)); 123 + if (err < 0) 124 + ; 125 + else if (err < 11) 126 err = -EIO; 127 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 128 err = -ENOSYS; ··· 150 err = fcp_avc_transaction(unit, buf, 12, buf, 256, 151 BIT(1) | BIT(2) | BIT(3) | BIT(4) | 152 BIT(5) | BIT(6) | BIT(7) | BIT(9)); 153 + if (err < 0) 154 + ; 155 + else if (err < 11) 156 err = -EIO; 157 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 158 err = -ENOSYS; ··· 187 err = fcp_avc_transaction(unit, buf, 12, buf, 12, 188 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 189 BIT(6) | BIT(7) | BIT(9) | BIT(10)); 190 + if (err < 0) 191 + ; 192 + else if (err < 12) 193 err = -EIO; 194 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 195 err = -ENOSYS; ··· 221 err = fcp_avc_transaction(unit, buf, 16, buf, 16, 222 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 223 BIT(6) | BIT(7)); 224 + if (err < 0) 225 + ; 226 + else if (err < 16) 227 err = -EIO; 228 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 229 err = -ENOSYS; ··· 260 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 261 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 262 BIT(6) | BIT(7) | BIT(10)); 263 + if (err < 0) 264 + ; 265 + else if (err < 12) 266 err = -EIO; 267 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 268 err = -ENOSYS;
+37 -18
sound/firewire/digi00x/amdtp-dot.c
··· 28 */ 29 #define MAX_MIDI_RX_BLOCKS 8 30 31 /* 32 * The double-oh-three algorithm was discovered by Robin Gareus and Damien 33 * Zammit in 2012, with reverse-engineering for Digi 003 Rack. ··· 45 unsigned int pcm_channels; 46 struct dot_state state; 47 48 - 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; 53 54 void (*transfer_samples)(struct amdtp_stream *s, ··· 125 return -EBUSY; 126 127 /* 128 - * A first data channel is for MIDI conformant data channel, the rest is 129 - * 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; 136 137 p->pcm_channels = pcm_channels; 138 - 139 - if (s->direction == AMDTP_IN_STREAM) 140 - p->midi_ports = DOT_MIDI_IN_PORTS; 141 - else 142 - p->midi_ports = DOT_MIDI_OUT_PORTS; 143 144 /* 145 * We do not know the actual MIDI FIFO size of most devices. Just ··· 277 b = (u8 *)&buffer[0]; 278 279 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); 284 285 if (len > 0) { 286 - b[3] = (0x10 << port) | len; 287 midi_use_bytes(s, port, len); 288 } else { 289 b[1] = 0; ··· 317 318 for (f = 0; f < data_blocks; f++) { 319 b = (u8 *)&buffer[0]; 320 - port = b[3] >> 4; 321 - len = b[3] & 0x0f; 322 323 - if (port < p->midi_ports && p->midi[port] && len > 0) 324 - snd_rawmidi_receive(p->midi[port], b + 1, len); 325 326 buffer += s->data_block_quadlets; 327 } ··· 383 { 384 struct amdtp_dot *p = s->protocol; 385 386 - if (port < p->midi_ports) 387 ACCESS_ONCE(p->midi[port]) = midi; 388 } 389
··· 28 */ 29 #define MAX_MIDI_RX_BLOCKS 8 30 31 + /* 3 = MAX(DOT_MIDI_IN_PORTS, DOT_MIDI_OUT_PORTS) + 1. */ 32 + #define MAX_MIDI_PORTS 3 33 + 34 /* 35 * The double-oh-three algorithm was discovered by Robin Gareus and Damien 36 * Zammit in 2012, with reverse-engineering for Digi 003 Rack. ··· 42 unsigned int pcm_channels; 43 struct dot_state state; 44 45 + struct snd_rawmidi_substream *midi[MAX_MIDI_PORTS]; 46 + int midi_fifo_used[MAX_MIDI_PORTS]; 47 int midi_fifo_limit; 48 49 void (*transfer_samples)(struct amdtp_stream *s, ··· 124 return -EBUSY; 125 126 /* 127 + * A first data channel is for MIDI messages, the rest is Multi Bit 128 + * 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; 135 136 p->pcm_channels = pcm_channels; 137 138 /* 139 * We do not know the actual MIDI FIFO size of most devices. Just ··· 281 b = (u8 *)&buffer[0]; 282 283 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); 288 289 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 + else 301 + b[3] = 0x00; 302 + b[3] |= len; 303 midi_use_bytes(s, port, len); 304 } else { 305 b[1] = 0; ··· 309 310 for (f = 0; f < data_blocks; f++) { 311 b = (u8 *)&buffer[0]; 312 313 + 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 + else 323 + port = 0; 324 + 325 + if (port < MAX_MIDI_PORTS && p->midi[port]) 326 + snd_rawmidi_receive(p->midi[port], b + 1, len); 327 + } 328 329 buffer += s->data_block_quadlets; 330 } ··· 364 { 365 struct amdtp_dot *p = s->protocol; 366 367 + if (port < MAX_MIDI_PORTS) 368 ACCESS_ONCE(p->midi[port]) = midi; 369 } 370
+86 -136
sound/firewire/digi00x/digi00x-midi.c
··· 8 9 #include "digi00x.h" 10 11 - static int midi_phys_open(struct snd_rawmidi_substream *substream) 12 { 13 struct snd_dg00x *dg00x = substream->rmidi->private_data; 14 int err; ··· 27 return err; 28 } 29 30 - static int midi_phys_close(struct snd_rawmidi_substream *substream) 31 { 32 struct snd_dg00x *dg00x = substream->rmidi->private_data; 33 ··· 40 return 0; 41 } 42 43 - static void midi_phys_capture_trigger(struct snd_rawmidi_substream *substream, 44 - int up) 45 { 46 struct snd_dg00x *dg00x = substream->rmidi->private_data; 47 unsigned long flags; 48 49 - spin_lock_irqsave(&dg00x->lock, flags); 50 - 51 - if (up) 52 - amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, 53 - substream); 54 else 55 - amdtp_dot_midi_trigger(&dg00x->tx_stream, substream->number, 56 - NULL); 57 - 58 - spin_unlock_irqrestore(&dg00x->lock, flags); 59 - } 60 - 61 - static void midi_phys_playback_trigger(struct snd_rawmidi_substream *substream, 62 - int up) 63 - { 64 - struct snd_dg00x *dg00x = substream->rmidi->private_data; 65 - unsigned long flags; 66 67 spin_lock_irqsave(&dg00x->lock, flags); 68 69 if (up) 70 - amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 71 - substream); 72 else 73 - amdtp_dot_midi_trigger(&dg00x->rx_stream, substream->number, 74 - NULL); 75 76 spin_unlock_irqrestore(&dg00x->lock, flags); 77 } 78 79 - static int midi_ctl_open(struct snd_rawmidi_substream *substream) 80 - { 81 - /* Do nothing. */ 82 - return 0; 83 - } 84 - 85 - static int midi_ctl_capture_close(struct snd_rawmidi_substream *substream) 86 - { 87 - /* Do nothing. */ 88 - return 0; 89 - } 90 - 91 - static int midi_ctl_playback_close(struct snd_rawmidi_substream *substream) 92 { 93 struct snd_dg00x *dg00x = substream->rmidi->private_data; 94 - 95 - snd_fw_async_midi_port_finish(&dg00x->out_control); 96 - 97 - return 0; 98 - } 99 - 100 - static void midi_ctl_capture_trigger(struct snd_rawmidi_substream *substream, 101 - int up) 102 - { 103 - struct snd_dg00x *dg00x = substream->rmidi->private_data; 104 unsigned long flags; 105 106 - spin_lock_irqsave(&dg00x->lock, flags); 107 - 108 - if (up) 109 - dg00x->in_control = substream; 110 else 111 - dg00x->in_control = NULL; 112 - 113 - spin_unlock_irqrestore(&dg00x->lock, flags); 114 - } 115 - 116 - static void midi_ctl_playback_trigger(struct snd_rawmidi_substream *substream, 117 - int up) 118 - { 119 - struct snd_dg00x *dg00x = substream->rmidi->private_data; 120 - unsigned long flags; 121 122 spin_lock_irqsave(&dg00x->lock, flags); 123 124 if (up) 125 - snd_fw_async_midi_port_run(&dg00x->out_control, substream); 126 127 spin_unlock_irqrestore(&dg00x->lock, flags); 128 } 129 130 - static void set_midi_substream_names(struct snd_dg00x *dg00x, 131 - struct snd_rawmidi_str *str, 132 - bool is_ctl) 133 { 134 struct snd_rawmidi_substream *subs; 135 136 - list_for_each_entry(subs, &str->substreams, list) { 137 - if (!is_ctl) 138 - snprintf(subs->name, sizeof(subs->name), 139 - "%s MIDI %d", 140 - dg00x->card->shortname, subs->number + 1); 141 - else 142 - /* This port is for asynchronous transaction. */ 143 - snprintf(subs->name, sizeof(subs->name), 144 - "%s control", 145 - dg00x->card->shortname); 146 } 147 } 148 149 int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) 150 { 151 - static const struct snd_rawmidi_ops phys_capture_ops = { 152 - .open = midi_phys_open, 153 - .close = midi_phys_close, 154 - .trigger = midi_phys_capture_trigger, 155 - }; 156 - static const struct snd_rawmidi_ops phys_playback_ops = { 157 - .open = midi_phys_open, 158 - .close = midi_phys_close, 159 - .trigger = midi_phys_playback_trigger, 160 - }; 161 - static const struct snd_rawmidi_ops ctl_capture_ops = { 162 - .open = midi_ctl_open, 163 - .close = midi_ctl_capture_close, 164 - .trigger = midi_ctl_capture_trigger, 165 - }; 166 - static const struct snd_rawmidi_ops ctl_playback_ops = { 167 - .open = midi_ctl_open, 168 - .close = midi_ctl_playback_close, 169 - .trigger = midi_ctl_playback_trigger, 170 - }; 171 - struct snd_rawmidi *rmidi[2]; 172 - struct snd_rawmidi_str *str; 173 - unsigned int i; 174 int err; 175 176 /* Add physical midi ports. */ 177 - err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 0, 178 - DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, &rmidi[0]); 179 if (err < 0) 180 return err; 181 182 - snprintf(rmidi[0]->name, sizeof(rmidi[0]->name), 183 - "%s MIDI", dg00x->card->shortname); 184 185 - snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_INPUT, 186 - &phys_capture_ops); 187 - snd_rawmidi_set_ops(rmidi[0], SNDRV_RAWMIDI_STREAM_OUTPUT, 188 - &phys_playback_ops); 189 - 190 - /* Add a pair of control midi ports. */ 191 - err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, 1, 192 - 1, 1, &rmidi[1]); 193 - if (err < 0) 194 - return err; 195 - 196 - snprintf(rmidi[1]->name, sizeof(rmidi[1]->name), 197 - "%s control", dg00x->card->shortname); 198 - 199 - snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_INPUT, 200 - &ctl_capture_ops); 201 - snd_rawmidi_set_ops(rmidi[1], SNDRV_RAWMIDI_STREAM_OUTPUT, 202 - &ctl_playback_ops); 203 - 204 - for (i = 0; i < ARRAY_SIZE(rmidi); i++) { 205 - rmidi[i]->private_data = dg00x; 206 - 207 - rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 208 - str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_INPUT]; 209 - set_midi_substream_names(dg00x, str, i); 210 - 211 - rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 212 - str = &rmidi[i]->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; 213 - set_midi_substream_names(dg00x, str, i); 214 - 215 - rmidi[i]->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 216 - } 217 - 218 - return 0; 219 }
··· 8 9 #include "digi00x.h" 10 11 + static int midi_open(struct snd_rawmidi_substream *substream) 12 { 13 struct snd_dg00x *dg00x = substream->rmidi->private_data; 14 int err; ··· 27 return err; 28 } 29 30 + static int midi_close(struct snd_rawmidi_substream *substream) 31 { 32 struct snd_dg00x *dg00x = substream->rmidi->private_data; 33 ··· 40 return 0; 41 } 42 43 + static void midi_capture_trigger(struct snd_rawmidi_substream *substream, 44 + int up) 45 { 46 struct snd_dg00x *dg00x = substream->rmidi->private_data; 47 + unsigned int port; 48 unsigned long flags; 49 50 + if (substream->rmidi->device == 0) 51 + port = substream->number; 52 else 53 + port = 2; 54 55 spin_lock_irqsave(&dg00x->lock, flags); 56 57 if (up) 58 + amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream); 59 else 60 + amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL); 61 62 spin_unlock_irqrestore(&dg00x->lock, flags); 63 } 64 65 + static void midi_playback_trigger(struct snd_rawmidi_substream *substream, 66 + int up) 67 { 68 struct snd_dg00x *dg00x = substream->rmidi->private_data; 69 + unsigned int port; 70 unsigned long flags; 71 72 + if (substream->rmidi->device == 0) 73 + port = substream->number; 74 else 75 + port = 2; 76 77 spin_lock_irqsave(&dg00x->lock, flags); 78 79 if (up) 80 + amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream); 81 + else 82 + amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL); 83 84 spin_unlock_irqrestore(&dg00x->lock, flags); 85 } 86 87 + static void set_substream_names(struct snd_dg00x *dg00x, 88 + struct snd_rawmidi *rmidi, bool is_console) 89 { 90 struct snd_rawmidi_substream *subs; 91 + struct snd_rawmidi_str *str; 92 + int i; 93 94 + for (i = 0; i < 2; ++i) { 95 + str = &rmidi->streams[i]; 96 + 97 + list_for_each_entry(subs, &str->substreams, list) { 98 + if (!is_console) { 99 + snprintf(subs->name, sizeof(subs->name), 100 + "%s MIDI %d", 101 + dg00x->card->shortname, 102 + subs->number + 1); 103 + } else { 104 + snprintf(subs->name, sizeof(subs->name), 105 + "%s control", 106 + dg00x->card->shortname); 107 + } 108 + } 109 } 110 + } 111 + 112 + static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports, 113 + unsigned int in_ports, bool is_console) 114 + { 115 + static const struct snd_rawmidi_ops capture_ops = { 116 + .open = midi_open, 117 + .close = midi_close, 118 + .trigger = midi_capture_trigger, 119 + }; 120 + static const struct snd_rawmidi_ops playback_ops = { 121 + .open = midi_open, 122 + .close = midi_close, 123 + .trigger = midi_playback_trigger, 124 + }; 125 + const char *label; 126 + struct snd_rawmidi *rmidi; 127 + int err; 128 + 129 + /* Add physical midi ports. */ 130 + err = snd_rawmidi_new(dg00x->card, dg00x->card->driver, is_console, 131 + out_ports, in_ports, &rmidi); 132 + if (err < 0) 133 + return err; 134 + rmidi->private_data = dg00x; 135 + 136 + if (!is_console) 137 + label = "%s control"; 138 + else 139 + label = "%s MIDI"; 140 + snprintf(rmidi->name, sizeof(rmidi->name), label, 141 + dg00x->card->shortname); 142 + 143 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &playback_ops); 144 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &capture_ops); 145 + 146 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT | 147 + SNDRV_RAWMIDI_INFO_OUTPUT | 148 + SNDRV_RAWMIDI_INFO_DUPLEX; 149 + 150 + set_substream_names(dg00x, rmidi, is_console); 151 + 152 + return 0; 153 } 154 155 int snd_dg00x_create_midi_devices(struct snd_dg00x *dg00x) 156 { 157 int err; 158 159 /* Add physical midi ports. */ 160 + err = add_substream_pair(dg00x, DOT_MIDI_OUT_PORTS, DOT_MIDI_IN_PORTS, 161 + false); 162 if (err < 0) 163 return err; 164 165 + if (dg00x->is_console) 166 + err = add_substream_pair(dg00x, 1, 1, true); 167 168 + return err; 169 }
+15 -73
sound/firewire/digi00x/digi00x-transaction.c
··· 9 #include <sound/asound.h> 10 #include "digi00x.h" 11 12 - static int fill_midi_message(struct snd_rawmidi_substream *substream, u8 *buf) 13 - { 14 - int bytes; 15 - 16 - buf[0] = 0x80; 17 - bytes = snd_rawmidi_transmit_peek(substream, buf + 1, 2); 18 - if (bytes >= 0) 19 - buf[3] = 0xc0 | bytes; 20 - 21 - return bytes; 22 - } 23 - 24 - static void handle_midi_control(struct snd_dg00x *dg00x, __be32 *buf, 25 - unsigned int length) 26 - { 27 - struct snd_rawmidi_substream *substream; 28 - unsigned int i; 29 - unsigned int len; 30 - u8 *b; 31 - 32 - substream = ACCESS_ONCE(dg00x->in_control); 33 - if (substream == NULL) 34 - return; 35 - 36 - length /= 4; 37 - 38 - for (i = 0; i < length; i++) { 39 - b = (u8 *)&buf[i]; 40 - len = b[3] & 0xf; 41 - if (len > 0) 42 - snd_rawmidi_receive(dg00x->in_control, b + 1, len); 43 - } 44 - } 45 - 46 static void handle_unknown_message(struct snd_dg00x *dg00x, 47 unsigned long long offset, __be32 *buf) 48 { ··· 29 struct snd_dg00x *dg00x = callback_data; 30 __be32 *buf = (__be32 *)data; 31 32 if (offset == dg00x->async_handler.offset) 33 handle_unknown_message(dg00x, offset, buf); 34 - else if (offset == dg00x->async_handler.offset + 4) 35 - handle_midi_control(dg00x, buf, length); 36 - 37 - fw_send_response(card, request, RCODE_COMPLETE); 38 } 39 40 int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x) 41 { 42 struct fw_device *device = fw_parent_device(dg00x->unit); 43 __be32 data[2]; 44 - int err; 45 46 /* Unknown. 4bytes. */ 47 data[0] = cpu_to_be32((device->card->node_id << 16) | 48 (dg00x->async_handler.offset >> 32)); 49 data[1] = cpu_to_be32(dg00x->async_handler.offset); 50 - err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST, 51 - DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR, 52 - &data, sizeof(data), 0); 53 - if (err < 0) 54 - return err; 55 - 56 - /* Asynchronous transactions for MIDI control message. */ 57 - data[0] = cpu_to_be32((device->card->node_id << 16) | 58 - (dg00x->async_handler.offset >> 32)); 59 - data[1] = cpu_to_be32(dg00x->async_handler.offset + 4); 60 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST, 61 - DG00X_ADDR_BASE + DG00X_OFFSET_MIDI_CTL_ADDR, 62 &data, sizeof(data), 0); 63 } 64 65 int snd_dg00x_transaction_register(struct snd_dg00x *dg00x) ··· 67 }; 68 int err; 69 70 - dg00x->async_handler.length = 12; 71 dg00x->async_handler.address_callback = handle_message; 72 dg00x->async_handler.callback_data = dg00x; 73 ··· 78 79 err = snd_dg00x_transaction_reregister(dg00x); 80 if (err < 0) 81 - goto error; 82 - 83 - err = snd_fw_async_midi_port_init(&dg00x->out_control, dg00x->unit, 84 - DG00X_ADDR_BASE + DG00X_OFFSET_MMC, 85 - 4, fill_midi_message); 86 - if (err < 0) 87 - goto error; 88 89 return err; 90 - error: 91 - fw_core_remove_address_handler(&dg00x->async_handler); 92 - dg00x->async_handler.callback_data = NULL; 93 - return err; 94 - } 95 - 96 - void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x) 97 - { 98 - if (dg00x->async_handler.callback_data == NULL) 99 - return; 100 - 101 - snd_fw_async_midi_port_destroy(&dg00x->out_control); 102 - fw_core_remove_address_handler(&dg00x->async_handler); 103 - 104 - dg00x->async_handler.callback_data = NULL; 105 }
··· 9 #include <sound/asound.h> 10 #include "digi00x.h" 11 12 static void handle_unknown_message(struct snd_dg00x *dg00x, 13 unsigned long long offset, __be32 *buf) 14 { ··· 63 struct snd_dg00x *dg00x = callback_data; 64 __be32 *buf = (__be32 *)data; 65 66 + fw_send_response(card, request, RCODE_COMPLETE); 67 + 68 if (offset == dg00x->async_handler.offset) 69 handle_unknown_message(dg00x, offset, buf); 70 } 71 72 int snd_dg00x_transaction_reregister(struct snd_dg00x *dg00x) 73 { 74 struct fw_device *device = fw_parent_device(dg00x->unit); 75 __be32 data[2]; 76 77 /* Unknown. 4bytes. */ 78 data[0] = cpu_to_be32((device->card->node_id << 16) | 79 (dg00x->async_handler.offset >> 32)); 80 data[1] = cpu_to_be32(dg00x->async_handler.offset); 81 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_BLOCK_REQUEST, 82 + DG00X_ADDR_BASE + DG00X_OFFSET_MESSAGE_ADDR, 83 &data, sizeof(data), 0); 84 + } 85 + 86 + void snd_dg00x_transaction_unregister(struct snd_dg00x *dg00x) 87 + { 88 + if (dg00x->async_handler.callback_data == NULL) 89 + return; 90 + 91 + fw_core_remove_address_handler(&dg00x->async_handler); 92 + 93 + dg00x->async_handler.callback_data = NULL; 94 } 95 96 int snd_dg00x_transaction_register(struct snd_dg00x *dg00x) ··· 104 }; 105 int err; 106 107 + dg00x->async_handler.length = 4; 108 dg00x->async_handler.address_callback = handle_message; 109 dg00x->async_handler.callback_data = dg00x; 110 ··· 115 116 err = snd_dg00x_transaction_reregister(dg00x); 117 if (err < 0) 118 + snd_dg00x_transaction_unregister(dg00x); 119 120 return err; 121 }
+11 -2
sound/firewire/digi00x/digi00x.c
··· 13 MODULE_LICENSE("GPL v2"); 14 15 #define VENDOR_DIGIDESIGN 0x00a07e 16 - #define MODEL_DIGI00X 0x000002 17 18 static int name_card(struct snd_dg00x *dg00x) 19 { ··· 130 spin_lock_init(&dg00x->lock); 131 init_waitqueue_head(&dg00x->hwdep_wait); 132 133 /* Allocate and register this sound card later. */ 134 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); 135 snd_fw_schedule_registration(unit, &dg00x->dwork); ··· 186 .match_flags = IEEE1394_MATCH_VENDOR_ID | 187 IEEE1394_MATCH_MODEL_ID, 188 .vendor_id = VENDOR_DIGIDESIGN, 189 - .model_id = MODEL_DIGI00X, 190 }, 191 {} 192 };
··· 13 MODULE_LICENSE("GPL v2"); 14 15 #define VENDOR_DIGIDESIGN 0x00a07e 16 + #define MODEL_CONSOLE 0x000001 17 + #define MODEL_RACK 0x000002 18 19 static int name_card(struct snd_dg00x *dg00x) 20 { ··· 129 spin_lock_init(&dg00x->lock); 130 init_waitqueue_head(&dg00x->hwdep_wait); 131 132 + dg00x->is_console = entry->model_id == MODEL_CONSOLE; 133 + 134 /* Allocate and register this sound card later. */ 135 INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); 136 snd_fw_schedule_registration(unit, &dg00x->dwork); ··· 183 .match_flags = IEEE1394_MATCH_VENDOR_ID | 184 IEEE1394_MATCH_MODEL_ID, 185 .vendor_id = VENDOR_DIGIDESIGN, 186 + .model_id = MODEL_CONSOLE, 187 + }, 188 + { 189 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 190 + IEEE1394_MATCH_MODEL_ID, 191 + .vendor_id = VENDOR_DIGIDESIGN, 192 + .model_id = MODEL_RACK, 193 }, 194 {} 195 };
+3 -4
sound/firewire/digi00x/digi00x.h
··· 58 struct fw_address_handler async_handler; 59 u32 msg; 60 61 - /* For asynchronous MIDI controls. */ 62 - struct snd_rawmidi_substream *in_control; 63 - struct snd_fw_async_midi_port out_control; 64 }; 65 66 #define DG00X_ADDR_BASE 0xffffe0000000ull 67 68 #define DG00X_OFFSET_STREAMING_STATE 0x0000 69 #define DG00X_OFFSET_STREAMING_SET 0x0004 70 - #define DG00X_OFFSET_MIDI_CTL_ADDR 0x0008 71 /* 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; 60 61 + /* Console models have additional MIDI ports for control surface. */ 62 + bool is_console; 63 }; 64 65 #define DG00X_ADDR_BASE 0xffffe0000000ull 66 67 #define DG00X_OFFSET_STREAMING_STATE 0x0000 68 #define DG00X_OFFSET_STREAMING_SET 0x0004 69 + /* 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) 67 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) 112 err = -EIO; 113 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 114 err = -ENOSYS; ··· 158 buf[3] = 0xff & subfunction; 159 160 err = fcp_avc_transaction(unit, buf, 8, buf, 8, BIT(1) | BIT(2)); 161 - if (err >= 0 && err < 8) 162 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; 155 156 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;
+3
sound/firewire/fireface/Makefile
···
··· 1 + snd-fireface-objs := ff.o ff-transaction.o ff-midi.o ff-proc.o amdtp-ff.o \ 2 + ff-stream.o ff-pcm.o ff-hwdep.o ff-protocol-ff400.o 3 + obj-$(CONFIG_SND_FIREFACE) += snd-fireface.o
+155
sound/firewire/fireface/amdtp-ff.c
···
··· 1 + /* 2 + * amdtp-ff.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include <sound/pcm.h> 10 + #include "ff.h" 11 + 12 + struct amdtp_ff { 13 + unsigned int pcm_channels; 14 + }; 15 + 16 + int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate, 17 + unsigned int pcm_channels) 18 + { 19 + struct amdtp_ff *p = s->protocol; 20 + unsigned int data_channels; 21 + 22 + if (amdtp_stream_running(s)) 23 + return -EBUSY; 24 + 25 + p->pcm_channels = pcm_channels; 26 + data_channels = pcm_channels; 27 + 28 + return amdtp_stream_set_parameters(s, rate, data_channels); 29 + } 30 + 31 + static void write_pcm_s32(struct amdtp_stream *s, 32 + struct snd_pcm_substream *pcm, 33 + __le32 *buffer, unsigned int frames) 34 + { 35 + struct amdtp_ff *p = s->protocol; 36 + struct snd_pcm_runtime *runtime = pcm->runtime; 37 + unsigned int channels, remaining_frames, i, c; 38 + const u32 *src; 39 + 40 + channels = p->pcm_channels; 41 + src = (void *)runtime->dma_area + 42 + frames_to_bytes(runtime, s->pcm_buffer_pointer); 43 + remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 44 + 45 + for (i = 0; i < frames; ++i) { 46 + for (c = 0; c < channels; ++c) { 47 + buffer[c] = cpu_to_le32(*src); 48 + src++; 49 + } 50 + buffer += s->data_block_quadlets; 51 + if (--remaining_frames == 0) 52 + src = (void *)runtime->dma_area; 53 + } 54 + } 55 + 56 + static void read_pcm_s32(struct amdtp_stream *s, 57 + struct snd_pcm_substream *pcm, 58 + __le32 *buffer, unsigned int frames) 59 + { 60 + struct amdtp_ff *p = s->protocol; 61 + struct snd_pcm_runtime *runtime = pcm->runtime; 62 + unsigned int channels, remaining_frames, i, c; 63 + u32 *dst; 64 + 65 + channels = p->pcm_channels; 66 + dst = (void *)runtime->dma_area + 67 + frames_to_bytes(runtime, s->pcm_buffer_pointer); 68 + remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 69 + 70 + for (i = 0; i < frames; ++i) { 71 + for (c = 0; c < channels; ++c) { 72 + *dst = le32_to_cpu(buffer[c]) & 0xffffff00; 73 + dst++; 74 + } 75 + buffer += s->data_block_quadlets; 76 + if (--remaining_frames == 0) 77 + dst = (void *)runtime->dma_area; 78 + } 79 + } 80 + 81 + static void write_pcm_silence(struct amdtp_stream *s, 82 + __le32 *buffer, unsigned int frames) 83 + { 84 + struct amdtp_ff *p = s->protocol; 85 + unsigned int i, c, channels = p->pcm_channels; 86 + 87 + for (i = 0; i < frames; ++i) { 88 + for (c = 0; c < channels; ++c) 89 + buffer[c] = cpu_to_le32(0x00000000); 90 + buffer += s->data_block_quadlets; 91 + } 92 + } 93 + 94 + int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s, 95 + struct snd_pcm_runtime *runtime) 96 + { 97 + int err; 98 + 99 + err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 100 + if (err < 0) 101 + return err; 102 + 103 + return amdtp_stream_add_pcm_hw_constraints(s, runtime); 104 + } 105 + 106 + static unsigned int process_rx_data_blocks(struct amdtp_stream *s, 107 + __be32 *buffer, 108 + unsigned int data_blocks, 109 + unsigned int *syt) 110 + { 111 + struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm); 112 + unsigned int pcm_frames; 113 + 114 + if (pcm) { 115 + write_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks); 116 + pcm_frames = data_blocks; 117 + } else { 118 + write_pcm_silence(s, (__le32 *)buffer, data_blocks); 119 + pcm_frames = 0; 120 + } 121 + 122 + return pcm_frames; 123 + } 124 + 125 + static unsigned int process_tx_data_blocks(struct amdtp_stream *s, 126 + __be32 *buffer, 127 + unsigned int data_blocks, 128 + unsigned int *syt) 129 + { 130 + struct snd_pcm_substream *pcm = ACCESS_ONCE(s->pcm); 131 + unsigned int pcm_frames; 132 + 133 + if (pcm) { 134 + read_pcm_s32(s, pcm, (__le32 *)buffer, data_blocks); 135 + pcm_frames = data_blocks; 136 + } else { 137 + pcm_frames = 0; 138 + } 139 + 140 + return pcm_frames; 141 + } 142 + 143 + int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit, 144 + enum amdtp_stream_direction dir) 145 + { 146 + amdtp_stream_process_data_blocks_t process_data_blocks; 147 + 148 + if (dir == AMDTP_IN_STREAM) 149 + process_data_blocks = process_tx_data_blocks; 150 + else 151 + process_data_blocks = process_rx_data_blocks; 152 + 153 + return amdtp_stream_init(s, unit, dir, CIP_NO_HEADER, 0, 154 + process_data_blocks, sizeof(struct amdtp_ff)); 155 + }
+191
sound/firewire/fireface/ff-hwdep.c
···
··· 1 + /* 2 + * ff-hwdep.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + /* 10 + * This codes give three functionality. 11 + * 12 + * 1.get firewire node information 13 + * 2.get notification about starting/stopping stream 14 + * 3.lock/unlock stream 15 + */ 16 + 17 + #include "ff.h" 18 + 19 + static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, 20 + loff_t *offset) 21 + { 22 + struct snd_ff *ff = hwdep->private_data; 23 + DEFINE_WAIT(wait); 24 + union snd_firewire_event event; 25 + 26 + spin_lock_irq(&ff->lock); 27 + 28 + while (!ff->dev_lock_changed) { 29 + prepare_to_wait(&ff->hwdep_wait, &wait, TASK_INTERRUPTIBLE); 30 + spin_unlock_irq(&ff->lock); 31 + schedule(); 32 + finish_wait(&ff->hwdep_wait, &wait); 33 + if (signal_pending(current)) 34 + return -ERESTARTSYS; 35 + spin_lock_irq(&ff->lock); 36 + } 37 + 38 + memset(&event, 0, sizeof(event)); 39 + if (ff->dev_lock_changed) { 40 + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; 41 + event.lock_status.status = (ff->dev_lock_count > 0); 42 + ff->dev_lock_changed = false; 43 + 44 + count = min_t(long, count, sizeof(event.lock_status)); 45 + } 46 + 47 + spin_unlock_irq(&ff->lock); 48 + 49 + if (copy_to_user(buf, &event, count)) 50 + return -EFAULT; 51 + 52 + return count; 53 + } 54 + 55 + static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file, 56 + poll_table *wait) 57 + { 58 + struct snd_ff *ff = hwdep->private_data; 59 + unsigned int events; 60 + 61 + poll_wait(file, &ff->hwdep_wait, wait); 62 + 63 + spin_lock_irq(&ff->lock); 64 + if (ff->dev_lock_changed) 65 + events = POLLIN | POLLRDNORM; 66 + else 67 + events = 0; 68 + spin_unlock_irq(&ff->lock); 69 + 70 + return events; 71 + } 72 + 73 + static int hwdep_get_info(struct snd_ff *ff, void __user *arg) 74 + { 75 + struct fw_device *dev = fw_parent_device(ff->unit); 76 + struct snd_firewire_get_info info; 77 + 78 + memset(&info, 0, sizeof(info)); 79 + info.type = SNDRV_FIREWIRE_TYPE_FIREFACE; 80 + info.card = dev->card->index; 81 + *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); 82 + *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); 83 + strlcpy(info.device_name, dev_name(&dev->device), 84 + sizeof(info.device_name)); 85 + 86 + if (copy_to_user(arg, &info, sizeof(info))) 87 + return -EFAULT; 88 + 89 + return 0; 90 + } 91 + 92 + static int hwdep_lock(struct snd_ff *ff) 93 + { 94 + int err; 95 + 96 + spin_lock_irq(&ff->lock); 97 + 98 + if (ff->dev_lock_count == 0) { 99 + ff->dev_lock_count = -1; 100 + err = 0; 101 + } else { 102 + err = -EBUSY; 103 + } 104 + 105 + spin_unlock_irq(&ff->lock); 106 + 107 + return err; 108 + } 109 + 110 + static int hwdep_unlock(struct snd_ff *ff) 111 + { 112 + int err; 113 + 114 + spin_lock_irq(&ff->lock); 115 + 116 + if (ff->dev_lock_count == -1) { 117 + ff->dev_lock_count = 0; 118 + err = 0; 119 + } else { 120 + err = -EBADFD; 121 + } 122 + 123 + spin_unlock_irq(&ff->lock); 124 + 125 + return err; 126 + } 127 + 128 + static int hwdep_release(struct snd_hwdep *hwdep, struct file *file) 129 + { 130 + struct snd_ff *ff = hwdep->private_data; 131 + 132 + spin_lock_irq(&ff->lock); 133 + if (ff->dev_lock_count == -1) 134 + ff->dev_lock_count = 0; 135 + spin_unlock_irq(&ff->lock); 136 + 137 + return 0; 138 + } 139 + 140 + static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, 141 + unsigned int cmd, unsigned long arg) 142 + { 143 + struct snd_ff *ff = hwdep->private_data; 144 + 145 + switch (cmd) { 146 + case SNDRV_FIREWIRE_IOCTL_GET_INFO: 147 + return hwdep_get_info(ff, (void __user *)arg); 148 + case SNDRV_FIREWIRE_IOCTL_LOCK: 149 + return hwdep_lock(ff); 150 + case SNDRV_FIREWIRE_IOCTL_UNLOCK: 151 + return hwdep_unlock(ff); 152 + default: 153 + return -ENOIOCTLCMD; 154 + } 155 + } 156 + 157 + #ifdef CONFIG_COMPAT 158 + static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, 159 + unsigned int cmd, unsigned long arg) 160 + { 161 + return hwdep_ioctl(hwdep, file, cmd, 162 + (unsigned long)compat_ptr(arg)); 163 + } 164 + #else 165 + #define hwdep_compat_ioctl NULL 166 + #endif 167 + 168 + int snd_ff_create_hwdep_devices(struct snd_ff *ff) 169 + { 170 + static const struct snd_hwdep_ops hwdep_ops = { 171 + .read = hwdep_read, 172 + .release = hwdep_release, 173 + .poll = hwdep_poll, 174 + .ioctl = hwdep_ioctl, 175 + .ioctl_compat = hwdep_compat_ioctl, 176 + }; 177 + struct snd_hwdep *hwdep; 178 + int err; 179 + 180 + err = snd_hwdep_new(ff->card, ff->card->driver, 0, &hwdep); 181 + if (err < 0) 182 + return err; 183 + 184 + strcpy(hwdep->name, ff->card->driver); 185 + hwdep->iface = SNDRV_HWDEP_IFACE_FW_FIREFACE; 186 + hwdep->ops = hwdep_ops; 187 + hwdep->private_data = ff; 188 + hwdep->exclusive = true; 189 + 190 + return 0; 191 + }
+131
sound/firewire/fireface/ff-midi.c
···
··· 1 + /* 2 + * ff-midi.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "ff.h" 10 + 11 + static int midi_capture_open(struct snd_rawmidi_substream *substream) 12 + { 13 + /* Do nothing. */ 14 + return 0; 15 + } 16 + 17 + static int midi_playback_open(struct snd_rawmidi_substream *substream) 18 + { 19 + struct snd_ff *ff = substream->rmidi->private_data; 20 + 21 + /* Initialize internal status. */ 22 + ff->running_status[substream->number] = 0; 23 + ff->rx_midi_error[substream->number] = false; 24 + 25 + ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = substream; 26 + 27 + return 0; 28 + } 29 + 30 + static int midi_capture_close(struct snd_rawmidi_substream *substream) 31 + { 32 + /* Do nothing. */ 33 + return 0; 34 + } 35 + 36 + static int midi_playback_close(struct snd_rawmidi_substream *substream) 37 + { 38 + struct snd_ff *ff = substream->rmidi->private_data; 39 + 40 + cancel_work_sync(&ff->rx_midi_work[substream->number]); 41 + ACCESS_ONCE(ff->rx_midi_substreams[substream->number]) = NULL; 42 + 43 + return 0; 44 + } 45 + 46 + static void midi_capture_trigger(struct snd_rawmidi_substream *substream, 47 + int up) 48 + { 49 + struct snd_ff *ff = substream->rmidi->private_data; 50 + unsigned long flags; 51 + 52 + spin_lock_irqsave(&ff->lock, flags); 53 + 54 + if (up) 55 + ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) = 56 + substream; 57 + else 58 + ACCESS_ONCE(ff->tx_midi_substreams[substream->number]) = NULL; 59 + 60 + spin_unlock_irqrestore(&ff->lock, flags); 61 + } 62 + 63 + static void midi_playback_trigger(struct snd_rawmidi_substream *substream, 64 + int up) 65 + { 66 + struct snd_ff *ff = substream->rmidi->private_data; 67 + unsigned long flags; 68 + 69 + spin_lock_irqsave(&ff->lock, flags); 70 + 71 + if (up || !ff->rx_midi_error[substream->number]) 72 + schedule_work(&ff->rx_midi_work[substream->number]); 73 + 74 + spin_unlock_irqrestore(&ff->lock, flags); 75 + } 76 + 77 + static struct snd_rawmidi_ops midi_capture_ops = { 78 + .open = midi_capture_open, 79 + .close = midi_capture_close, 80 + .trigger = midi_capture_trigger, 81 + }; 82 + 83 + static struct snd_rawmidi_ops midi_playback_ops = { 84 + .open = midi_playback_open, 85 + .close = midi_playback_close, 86 + .trigger = midi_playback_trigger, 87 + }; 88 + 89 + static void set_midi_substream_names(struct snd_rawmidi_str *stream, 90 + const char *const name) 91 + { 92 + struct snd_rawmidi_substream *substream; 93 + 94 + list_for_each_entry(substream, &stream->substreams, list) { 95 + snprintf(substream->name, sizeof(substream->name), 96 + "%s MIDI %d", name, substream->number + 1); 97 + } 98 + } 99 + 100 + int snd_ff_create_midi_devices(struct snd_ff *ff) 101 + { 102 + struct snd_rawmidi *rmidi; 103 + struct snd_rawmidi_str *stream; 104 + int err; 105 + 106 + err = snd_rawmidi_new(ff->card, ff->card->driver, 0, 107 + ff->spec->midi_out_ports, ff->spec->midi_in_ports, 108 + &rmidi); 109 + if (err < 0) 110 + return err; 111 + 112 + snprintf(rmidi->name, sizeof(rmidi->name), 113 + "%s MIDI", ff->card->shortname); 114 + rmidi->private_data = ff; 115 + 116 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; 117 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 118 + &midi_capture_ops); 119 + stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; 120 + set_midi_substream_names(stream, ff->card->shortname); 121 + 122 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; 123 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 124 + &midi_playback_ops); 125 + stream = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; 126 + set_midi_substream_names(stream, ff->card->shortname); 127 + 128 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; 129 + 130 + return 0; 131 + }
+409
sound/firewire/fireface/ff-pcm.c
···
··· 1 + /* 2 + * ff-pcm.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "ff.h" 10 + 11 + static inline unsigned int get_multiplier_mode_with_index(unsigned int index) 12 + { 13 + return ((int)index - 1) / 2; 14 + } 15 + 16 + static int hw_rule_rate(struct snd_pcm_hw_params *params, 17 + struct snd_pcm_hw_rule *rule) 18 + { 19 + const unsigned int *pcm_channels = rule->private; 20 + struct snd_interval *r = 21 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 22 + const struct snd_interval *c = 23 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 24 + struct snd_interval t = { 25 + .min = UINT_MAX, .max = 0, .integer = 1 26 + }; 27 + unsigned int i, mode; 28 + 29 + for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 30 + mode = get_multiplier_mode_with_index(i); 31 + if (!snd_interval_test(c, pcm_channels[mode])) 32 + continue; 33 + 34 + t.min = min(t.min, amdtp_rate_table[i]); 35 + t.max = max(t.max, amdtp_rate_table[i]); 36 + } 37 + 38 + return snd_interval_refine(r, &t); 39 + } 40 + 41 + static int hw_rule_channels(struct snd_pcm_hw_params *params, 42 + struct snd_pcm_hw_rule *rule) 43 + { 44 + const unsigned int *pcm_channels = rule->private; 45 + struct snd_interval *c = 46 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 47 + const struct snd_interval *r = 48 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 49 + struct snd_interval t = { 50 + .min = UINT_MAX, .max = 0, .integer = 1 51 + }; 52 + unsigned int i, mode; 53 + 54 + for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 55 + mode = get_multiplier_mode_with_index(i); 56 + if (!snd_interval_test(r, amdtp_rate_table[i])) 57 + continue; 58 + 59 + t.min = min(t.min, pcm_channels[mode]); 60 + t.max = max(t.max, pcm_channels[mode]); 61 + } 62 + 63 + return snd_interval_refine(c, &t); 64 + } 65 + 66 + static void limit_channels_and_rates(struct snd_pcm_hardware *hw, 67 + const unsigned int *pcm_channels) 68 + { 69 + unsigned int mode; 70 + unsigned int rate, channels; 71 + int i; 72 + 73 + hw->channels_min = UINT_MAX; 74 + hw->channels_max = 0; 75 + hw->rate_min = UINT_MAX; 76 + hw->rate_max = 0; 77 + 78 + for (i = 0; i < ARRAY_SIZE(amdtp_rate_table); i++) { 79 + mode = get_multiplier_mode_with_index(i); 80 + 81 + channels = pcm_channels[mode]; 82 + if (pcm_channels[mode] == 0) 83 + continue; 84 + hw->channels_min = min(hw->channels_min, channels); 85 + hw->channels_max = max(hw->channels_max, channels); 86 + 87 + rate = amdtp_rate_table[i]; 88 + hw->rates |= snd_pcm_rate_to_rate_bit(rate); 89 + hw->rate_min = min(hw->rate_min, rate); 90 + hw->rate_max = max(hw->rate_max, rate); 91 + } 92 + } 93 + 94 + static void limit_period_and_buffer(struct snd_pcm_hardware *hw) 95 + { 96 + hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ 97 + hw->periods_max = UINT_MAX; 98 + 99 + hw->period_bytes_min = 4 * hw->channels_max; /* bytes for a frame */ 100 + 101 + /* Just to prevent from allocating much pages. */ 102 + hw->period_bytes_max = hw->period_bytes_min * 2048; 103 + hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 104 + } 105 + 106 + static int pcm_init_hw_params(struct snd_ff *ff, 107 + struct snd_pcm_substream *substream) 108 + { 109 + struct snd_pcm_runtime *runtime = substream->runtime; 110 + struct amdtp_stream *s; 111 + const unsigned int *pcm_channels; 112 + int err; 113 + 114 + runtime->hw.info = SNDRV_PCM_INFO_BATCH | 115 + SNDRV_PCM_INFO_BLOCK_TRANSFER | 116 + SNDRV_PCM_INFO_INTERLEAVED | 117 + SNDRV_PCM_INFO_JOINT_DUPLEX | 118 + SNDRV_PCM_INFO_MMAP | 119 + SNDRV_PCM_INFO_MMAP_VALID; 120 + 121 + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 122 + runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; 123 + s = &ff->tx_stream; 124 + pcm_channels = ff->spec->pcm_capture_channels; 125 + } else { 126 + runtime->hw.formats = SNDRV_PCM_FMTBIT_S32; 127 + s = &ff->rx_stream; 128 + pcm_channels = ff->spec->pcm_playback_channels; 129 + } 130 + 131 + /* limit rates */ 132 + limit_channels_and_rates(&runtime->hw, pcm_channels); 133 + limit_period_and_buffer(&runtime->hw); 134 + 135 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 136 + hw_rule_channels, (void *)pcm_channels, 137 + SNDRV_PCM_HW_PARAM_RATE, -1); 138 + if (err < 0) 139 + return err; 140 + 141 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 142 + hw_rule_rate, (void *)pcm_channels, 143 + SNDRV_PCM_HW_PARAM_CHANNELS, -1); 144 + if (err < 0) 145 + return err; 146 + 147 + return amdtp_ff_add_pcm_hw_constraints(s, runtime); 148 + } 149 + 150 + static int pcm_open(struct snd_pcm_substream *substream) 151 + { 152 + struct snd_ff *ff = substream->private_data; 153 + unsigned int rate; 154 + enum snd_ff_clock_src src; 155 + int i, err; 156 + 157 + err = snd_ff_stream_lock_try(ff); 158 + if (err < 0) 159 + return err; 160 + 161 + err = pcm_init_hw_params(ff, substream); 162 + if (err < 0) { 163 + snd_ff_stream_lock_release(ff); 164 + return err; 165 + } 166 + 167 + err = ff->spec->protocol->get_clock(ff, &rate, &src); 168 + if (err < 0) { 169 + snd_ff_stream_lock_release(ff); 170 + return err; 171 + } 172 + 173 + if (src != SND_FF_CLOCK_SRC_INTERNAL) { 174 + for (i = 0; i < CIP_SFC_COUNT; ++i) { 175 + if (amdtp_rate_table[i] == rate) 176 + break; 177 + } 178 + /* 179 + * The unit is configured at sampling frequency which packet 180 + * streaming engine can't support. 181 + */ 182 + if (i >= CIP_SFC_COUNT) { 183 + snd_ff_stream_lock_release(ff); 184 + return -EIO; 185 + } 186 + 187 + substream->runtime->hw.rate_min = rate; 188 + substream->runtime->hw.rate_max = rate; 189 + } else { 190 + if (amdtp_stream_pcm_running(&ff->rx_stream) || 191 + amdtp_stream_pcm_running(&ff->tx_stream)) { 192 + rate = amdtp_rate_table[ff->rx_stream.sfc]; 193 + substream->runtime->hw.rate_min = rate; 194 + substream->runtime->hw.rate_max = rate; 195 + } 196 + } 197 + 198 + snd_pcm_set_sync(substream); 199 + 200 + return 0; 201 + } 202 + 203 + static int pcm_close(struct snd_pcm_substream *substream) 204 + { 205 + struct snd_ff *ff = substream->private_data; 206 + 207 + snd_ff_stream_lock_release(ff); 208 + 209 + return 0; 210 + } 211 + 212 + static int pcm_capture_hw_params(struct snd_pcm_substream *substream, 213 + struct snd_pcm_hw_params *hw_params) 214 + { 215 + struct snd_ff *ff = substream->private_data; 216 + int err; 217 + 218 + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 219 + params_buffer_bytes(hw_params)); 220 + if (err < 0) 221 + return err; 222 + 223 + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 224 + mutex_lock(&ff->mutex); 225 + ff->substreams_counter++; 226 + mutex_unlock(&ff->mutex); 227 + } 228 + 229 + return 0; 230 + } 231 + 232 + static int pcm_playback_hw_params(struct snd_pcm_substream *substream, 233 + struct snd_pcm_hw_params *hw_params) 234 + { 235 + struct snd_ff *ff = substream->private_data; 236 + int err; 237 + 238 + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 239 + params_buffer_bytes(hw_params)); 240 + if (err < 0) 241 + return err; 242 + 243 + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 244 + mutex_lock(&ff->mutex); 245 + ff->substreams_counter++; 246 + mutex_unlock(&ff->mutex); 247 + } 248 + 249 + return 0; 250 + } 251 + 252 + static int pcm_capture_hw_free(struct snd_pcm_substream *substream) 253 + { 254 + struct snd_ff *ff = substream->private_data; 255 + 256 + mutex_lock(&ff->mutex); 257 + 258 + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 259 + ff->substreams_counter--; 260 + 261 + snd_ff_stream_stop_duplex(ff); 262 + 263 + mutex_unlock(&ff->mutex); 264 + 265 + return snd_pcm_lib_free_vmalloc_buffer(substream); 266 + } 267 + 268 + static int pcm_playback_hw_free(struct snd_pcm_substream *substream) 269 + { 270 + struct snd_ff *ff = substream->private_data; 271 + 272 + mutex_lock(&ff->mutex); 273 + 274 + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 275 + ff->substreams_counter--; 276 + 277 + snd_ff_stream_stop_duplex(ff); 278 + 279 + mutex_unlock(&ff->mutex); 280 + 281 + return snd_pcm_lib_free_vmalloc_buffer(substream); 282 + } 283 + 284 + static int pcm_capture_prepare(struct snd_pcm_substream *substream) 285 + { 286 + struct snd_ff *ff = substream->private_data; 287 + struct snd_pcm_runtime *runtime = substream->runtime; 288 + int err; 289 + 290 + mutex_lock(&ff->mutex); 291 + 292 + err = snd_ff_stream_start_duplex(ff, runtime->rate); 293 + if (err >= 0) 294 + amdtp_stream_pcm_prepare(&ff->tx_stream); 295 + 296 + mutex_unlock(&ff->mutex); 297 + 298 + return err; 299 + } 300 + 301 + static int pcm_playback_prepare(struct snd_pcm_substream *substream) 302 + { 303 + struct snd_ff *ff = substream->private_data; 304 + struct snd_pcm_runtime *runtime = substream->runtime; 305 + int err; 306 + 307 + mutex_lock(&ff->mutex); 308 + 309 + err = snd_ff_stream_start_duplex(ff, runtime->rate); 310 + if (err >= 0) 311 + amdtp_stream_pcm_prepare(&ff->rx_stream); 312 + 313 + mutex_unlock(&ff->mutex); 314 + 315 + return err; 316 + } 317 + 318 + static int pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd) 319 + { 320 + struct snd_ff *ff = substream->private_data; 321 + 322 + switch (cmd) { 323 + case SNDRV_PCM_TRIGGER_START: 324 + amdtp_stream_pcm_trigger(&ff->tx_stream, substream); 325 + break; 326 + case SNDRV_PCM_TRIGGER_STOP: 327 + amdtp_stream_pcm_trigger(&ff->tx_stream, NULL); 328 + break; 329 + default: 330 + return -EINVAL; 331 + } 332 + 333 + return 0; 334 + } 335 + 336 + static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) 337 + { 338 + struct snd_ff *ff = substream->private_data; 339 + 340 + switch (cmd) { 341 + case SNDRV_PCM_TRIGGER_START: 342 + amdtp_stream_pcm_trigger(&ff->rx_stream, substream); 343 + break; 344 + case SNDRV_PCM_TRIGGER_STOP: 345 + amdtp_stream_pcm_trigger(&ff->rx_stream, NULL); 346 + break; 347 + default: 348 + return -EINVAL; 349 + } 350 + 351 + return 0; 352 + } 353 + 354 + static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) 355 + { 356 + struct snd_ff *ff = sbstrm->private_data; 357 + 358 + return amdtp_stream_pcm_pointer(&ff->tx_stream); 359 + } 360 + 361 + static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) 362 + { 363 + struct snd_ff *ff = sbstrm->private_data; 364 + 365 + return amdtp_stream_pcm_pointer(&ff->rx_stream); 366 + } 367 + 368 + static struct snd_pcm_ops pcm_capture_ops = { 369 + .open = pcm_open, 370 + .close = pcm_close, 371 + .ioctl = snd_pcm_lib_ioctl, 372 + .hw_params = pcm_capture_hw_params, 373 + .hw_free = pcm_capture_hw_free, 374 + .prepare = pcm_capture_prepare, 375 + .trigger = pcm_capture_trigger, 376 + .pointer = pcm_capture_pointer, 377 + .page = snd_pcm_lib_get_vmalloc_page, 378 + }; 379 + 380 + static struct snd_pcm_ops pcm_playback_ops = { 381 + .open = pcm_open, 382 + .close = pcm_close, 383 + .ioctl = snd_pcm_lib_ioctl, 384 + .hw_params = pcm_playback_hw_params, 385 + .hw_free = pcm_playback_hw_free, 386 + .prepare = pcm_playback_prepare, 387 + .trigger = pcm_playback_trigger, 388 + .pointer = pcm_playback_pointer, 389 + .page = snd_pcm_lib_get_vmalloc_page, 390 + .mmap = snd_pcm_lib_mmap_vmalloc, 391 + }; 392 + 393 + int snd_ff_create_pcm_devices(struct snd_ff *ff) 394 + { 395 + struct snd_pcm *pcm; 396 + int err; 397 + 398 + err = snd_pcm_new(ff->card, ff->card->driver, 0, 1, 1, &pcm); 399 + if (err < 0) 400 + return err; 401 + 402 + pcm->private_data = ff; 403 + snprintf(pcm->name, sizeof(pcm->name), 404 + "%s PCM", ff->card->shortname); 405 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcm_playback_ops); 406 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcm_capture_ops); 407 + 408 + return 0; 409 + }
+63
sound/firewire/fireface/ff-proc.c
···
··· 1 + /* 2 + * ff-proc.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "./ff.h" 10 + 11 + static void proc_dump_clock_config(struct snd_info_entry *entry, 12 + struct snd_info_buffer *buffer) 13 + { 14 + struct snd_ff *ff = entry->private_data; 15 + 16 + ff->spec->protocol->dump_clock_config(ff, buffer); 17 + } 18 + 19 + static void proc_dump_sync_status(struct snd_info_entry *entry, 20 + struct snd_info_buffer *buffer) 21 + { 22 + struct snd_ff *ff = entry->private_data; 23 + 24 + ff->spec->protocol->dump_sync_status(ff, buffer); 25 + } 26 + 27 + static void add_node(struct snd_ff *ff, struct snd_info_entry *root, 28 + const char *name, 29 + void (*op)(struct snd_info_entry *e, 30 + struct snd_info_buffer *b)) 31 + { 32 + struct snd_info_entry *entry; 33 + 34 + entry = snd_info_create_card_entry(ff->card, name, root); 35 + if (entry == NULL) 36 + return; 37 + 38 + snd_info_set_text_ops(entry, ff, op); 39 + if (snd_info_register(entry) < 0) 40 + snd_info_free_entry(entry); 41 + } 42 + 43 + void snd_ff_proc_init(struct snd_ff *ff) 44 + { 45 + struct snd_info_entry *root; 46 + 47 + /* 48 + * All nodes are automatically removed at snd_card_disconnect(), 49 + * by following to link list. 50 + */ 51 + root = snd_info_create_card_entry(ff->card, "firewire", 52 + ff->card->proc_root); 53 + if (root == NULL) 54 + return; 55 + root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 56 + if (snd_info_register(root) < 0) { 57 + snd_info_free_entry(root); 58 + return; 59 + } 60 + 61 + add_node(ff, root, "clock-config", proc_dump_clock_config); 62 + add_node(ff, root, "sync-status", proc_dump_sync_status); 63 + }
+371
sound/firewire/fireface/ff-protocol-ff400.c
···
··· 1 + /* 2 + * ff-protocol-ff400.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include <linux/delay.h> 10 + #include "ff.h" 11 + 12 + #define FF400_STF 0x000080100500ull 13 + #define FF400_RX_PACKET_FORMAT 0x000080100504ull 14 + #define FF400_ISOC_COMM_START 0x000080100508ull 15 + #define FF400_TX_PACKET_FORMAT 0x00008010050cull 16 + #define FF400_ISOC_COMM_STOP 0x000080100510ull 17 + #define FF400_SYNC_STATUS 0x0000801c0000ull 18 + #define FF400_FETCH_PCM_FRAMES 0x0000801c0000ull /* For block request. */ 19 + #define FF400_CLOCK_CONFIG 0x0000801c0004ull 20 + 21 + #define FF400_MIDI_HIGH_ADDR 0x0000801003f4ull 22 + #define FF400_MIDI_RX_PORT_0 0x000080180000ull 23 + #define FF400_MIDI_RX_PORT_1 0x000080190000ull 24 + 25 + static int ff400_get_clock(struct snd_ff *ff, unsigned int *rate, 26 + enum snd_ff_clock_src *src) 27 + { 28 + __le32 reg; 29 + u32 data; 30 + int err; 31 + 32 + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, 33 + FF400_SYNC_STATUS, &reg, sizeof(reg), 0); 34 + if (err < 0) 35 + return err; 36 + data = le32_to_cpu(reg); 37 + 38 + /* Calculate sampling rate. */ 39 + switch ((data >> 1) & 0x03) { 40 + case 0x01: 41 + *rate = 32000; 42 + break; 43 + case 0x00: 44 + *rate = 44100; 45 + break; 46 + case 0x03: 47 + *rate = 48000; 48 + break; 49 + case 0x02: 50 + default: 51 + return -EIO; 52 + } 53 + 54 + if (data & 0x08) 55 + *rate *= 2; 56 + else if (data & 0x10) 57 + *rate *= 4; 58 + 59 + /* Calculate source of clock. */ 60 + if (data & 0x01) { 61 + *src = SND_FF_CLOCK_SRC_INTERNAL; 62 + } else { 63 + /* TODO: 0x00, 0x01, 0x02, 0x06, 0x07? */ 64 + switch ((data >> 10) & 0x07) { 65 + case 0x03: 66 + *src = SND_FF_CLOCK_SRC_SPDIF; 67 + break; 68 + case 0x04: 69 + *src = SND_FF_CLOCK_SRC_WORD; 70 + break; 71 + case 0x05: 72 + *src = SND_FF_CLOCK_SRC_LTC; 73 + break; 74 + case 0x00: 75 + default: 76 + *src = SND_FF_CLOCK_SRC_ADAT; 77 + break; 78 + } 79 + } 80 + 81 + return 0; 82 + } 83 + 84 + static int ff400_begin_session(struct snd_ff *ff, unsigned int rate) 85 + { 86 + __le32 reg; 87 + int i, err; 88 + 89 + /* Check whether the given value is supported or not. */ 90 + for (i = 0; i < CIP_SFC_COUNT; i++) { 91 + if (amdtp_rate_table[i] == rate) 92 + break; 93 + } 94 + if (i == CIP_SFC_COUNT) 95 + return -EINVAL; 96 + 97 + /* Set the number of data blocks transferred in a second. */ 98 + reg = cpu_to_le32(rate); 99 + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 100 + FF400_STF, &reg, sizeof(reg), 0); 101 + if (err < 0) 102 + return err; 103 + 104 + msleep(100); 105 + 106 + /* 107 + * Set isochronous channel and the number of quadlets of received 108 + * packets. 109 + */ 110 + reg = cpu_to_le32(((ff->rx_stream.data_block_quadlets << 3) << 8) | 111 + ff->rx_resources.channel); 112 + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 113 + FF400_RX_PACKET_FORMAT, &reg, sizeof(reg), 0); 114 + if (err < 0) 115 + return err; 116 + 117 + /* 118 + * Set isochronous channel and the number of quadlets of transmitted 119 + * packet. 120 + */ 121 + /* TODO: investigate the purpose of this 0x80. */ 122 + reg = cpu_to_le32((0x80 << 24) | 123 + (ff->tx_resources.channel << 5) | 124 + (ff->tx_stream.data_block_quadlets)); 125 + err = snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 126 + FF400_TX_PACKET_FORMAT, &reg, sizeof(reg), 0); 127 + if (err < 0) 128 + return err; 129 + 130 + /* Allow to transmit packets. */ 131 + reg = cpu_to_le32(0x00000001); 132 + return snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 133 + FF400_ISOC_COMM_START, &reg, sizeof(reg), 0); 134 + } 135 + 136 + static void ff400_finish_session(struct snd_ff *ff) 137 + { 138 + __le32 reg; 139 + 140 + reg = cpu_to_le32(0x80000000); 141 + snd_fw_transaction(ff->unit, TCODE_WRITE_QUADLET_REQUEST, 142 + FF400_ISOC_COMM_STOP, &reg, sizeof(reg), 0); 143 + } 144 + 145 + static int ff400_switch_fetching_mode(struct snd_ff *ff, bool enable) 146 + { 147 + __le32 *reg; 148 + int i; 149 + 150 + reg = kzalloc(sizeof(__le32) * 18, GFP_KERNEL); 151 + if (reg == NULL) 152 + return -ENOMEM; 153 + 154 + if (enable) { 155 + /* 156 + * Each quadlet is corresponding to data channels in a data 157 + * blocks in reverse order. Precisely, quadlets for available 158 + * data channels should be enabled. Here, I take second best 159 + * to fetch PCM frames from all of data channels regardless of 160 + * stf. 161 + */ 162 + for (i = 0; i < 18; ++i) 163 + reg[i] = cpu_to_le32(0x00000001); 164 + } 165 + 166 + return snd_fw_transaction(ff->unit, TCODE_WRITE_BLOCK_REQUEST, 167 + FF400_FETCH_PCM_FRAMES, reg, 168 + sizeof(__le32) * 18, 0); 169 + } 170 + 171 + static void ff400_dump_sync_status(struct snd_ff *ff, 172 + struct snd_info_buffer *buffer) 173 + { 174 + __le32 reg; 175 + u32 data; 176 + int err; 177 + 178 + err = snd_fw_transaction(ff->unit, TCODE_READ_QUADLET_REQUEST, 179 + FF400_SYNC_STATUS, &reg, sizeof(reg), 0); 180 + if (err < 0) 181 + return; 182 + 183 + data = le32_to_cpu(reg); 184 + 185 + snd_iprintf(buffer, "External source detection:\n"); 186 + 187 + snd_iprintf(buffer, "Word Clock:"); 188 + if ((data >> 24) & 0x20) { 189 + if ((data >> 24) & 0x40) 190 + snd_iprintf(buffer, "sync\n"); 191 + else 192 + snd_iprintf(buffer, "lock\n"); 193 + } else { 194 + snd_iprintf(buffer, "none\n"); 195 + } 196 + 197 + snd_iprintf(buffer, "S/PDIF:"); 198 + if ((data >> 16) & 0x10) { 199 + if ((data >> 16) & 0x04) 200 + snd_iprintf(buffer, "sync\n"); 201 + else 202 + snd_iprintf(buffer, "lock\n"); 203 + } else { 204 + snd_iprintf(buffer, "none\n"); 205 + } 206 + 207 + snd_iprintf(buffer, "ADAT:"); 208 + if ((data >> 8) & 0x04) { 209 + if ((data >> 8) & 0x10) 210 + snd_iprintf(buffer, "sync\n"); 211 + else 212 + snd_iprintf(buffer, "lock\n"); 213 + } else { 214 + snd_iprintf(buffer, "none\n"); 215 + } 216 + 217 + snd_iprintf(buffer, "\nUsed external source:\n"); 218 + 219 + if (((data >> 22) & 0x07) == 0x07) { 220 + snd_iprintf(buffer, "None\n"); 221 + } else { 222 + switch ((data >> 22) & 0x07) { 223 + case 0x00: 224 + snd_iprintf(buffer, "ADAT:"); 225 + break; 226 + case 0x03: 227 + snd_iprintf(buffer, "S/PDIF:"); 228 + break; 229 + case 0x04: 230 + snd_iprintf(buffer, "Word:"); 231 + break; 232 + case 0x07: 233 + snd_iprintf(buffer, "Nothing:"); 234 + break; 235 + case 0x01: 236 + case 0x02: 237 + case 0x05: 238 + case 0x06: 239 + default: 240 + snd_iprintf(buffer, "unknown:"); 241 + break; 242 + } 243 + 244 + if ((data >> 25) & 0x07) { 245 + switch ((data >> 25) & 0x07) { 246 + case 0x01: 247 + snd_iprintf(buffer, "32000\n"); 248 + break; 249 + case 0x02: 250 + snd_iprintf(buffer, "44100\n"); 251 + break; 252 + case 0x03: 253 + snd_iprintf(buffer, "48000\n"); 254 + break; 255 + case 0x04: 256 + snd_iprintf(buffer, "64000\n"); 257 + break; 258 + case 0x05: 259 + snd_iprintf(buffer, "88200\n"); 260 + break; 261 + case 0x06: 262 + snd_iprintf(buffer, "96000\n"); 263 + break; 264 + case 0x07: 265 + snd_iprintf(buffer, "128000\n"); 266 + break; 267 + case 0x08: 268 + snd_iprintf(buffer, "176400\n"); 269 + break; 270 + case 0x09: 271 + snd_iprintf(buffer, "192000\n"); 272 + break; 273 + case 0x00: 274 + snd_iprintf(buffer, "unknown\n"); 275 + break; 276 + } 277 + } 278 + } 279 + 280 + snd_iprintf(buffer, "Multiplied:"); 281 + snd_iprintf(buffer, "%d\n", (data & 0x3ff) * 250); 282 + } 283 + 284 + static void ff400_dump_clock_config(struct snd_ff *ff, 285 + struct snd_info_buffer *buffer) 286 + { 287 + __le32 reg; 288 + u32 data; 289 + unsigned int rate; 290 + const char *src; 291 + int err; 292 + 293 + err = snd_fw_transaction(ff->unit, TCODE_READ_BLOCK_REQUEST, 294 + FF400_CLOCK_CONFIG, &reg, sizeof(reg), 0); 295 + if (err < 0) 296 + return; 297 + 298 + data = le32_to_cpu(reg); 299 + 300 + snd_iprintf(buffer, "Output S/PDIF format: %s (Emphasis: %s)\n", 301 + (data & 0x20) ? "Professional" : "Consumer", 302 + (data & 0x40) ? "on" : "off"); 303 + 304 + snd_iprintf(buffer, "Optical output interface format: %s\n", 305 + ((data >> 8) & 0x01) ? "S/PDIF" : "ADAT"); 306 + 307 + snd_iprintf(buffer, "Word output single speed: %s\n", 308 + ((data >> 8) & 0x20) ? "on" : "off"); 309 + 310 + snd_iprintf(buffer, "S/PDIF input interface: %s\n", 311 + ((data >> 8) & 0x02) ? "Optical" : "Coaxial"); 312 + 313 + switch ((data >> 1) & 0x03) { 314 + case 0x01: 315 + rate = 32000; 316 + break; 317 + case 0x00: 318 + rate = 44100; 319 + break; 320 + case 0x03: 321 + rate = 48000; 322 + break; 323 + case 0x02: 324 + default: 325 + return; 326 + } 327 + 328 + if (data & 0x08) 329 + rate *= 2; 330 + else if (data & 0x10) 331 + rate *= 4; 332 + 333 + snd_iprintf(buffer, "Sampling rate: %d\n", rate); 334 + 335 + if (data & 0x01) { 336 + src = "Internal"; 337 + } else { 338 + switch ((data >> 10) & 0x07) { 339 + case 0x00: 340 + src = "ADAT"; 341 + break; 342 + case 0x03: 343 + src = "S/PDIF"; 344 + break; 345 + case 0x04: 346 + src = "Word"; 347 + break; 348 + case 0x05: 349 + src = "LTC"; 350 + break; 351 + default: 352 + return; 353 + } 354 + } 355 + 356 + snd_iprintf(buffer, "Sync to clock source: %s\n", src); 357 + } 358 + 359 + struct snd_ff_protocol snd_ff_protocol_ff400 = { 360 + .get_clock = ff400_get_clock, 361 + .begin_session = ff400_begin_session, 362 + .finish_session = ff400_finish_session, 363 + .switch_fetching_mode = ff400_switch_fetching_mode, 364 + 365 + .dump_sync_status = ff400_dump_sync_status, 366 + .dump_clock_config = ff400_dump_clock_config, 367 + 368 + .midi_high_addr_reg = FF400_MIDI_HIGH_ADDR, 369 + .midi_rx_port_0_reg = FF400_MIDI_RX_PORT_0, 370 + .midi_rx_port_1_reg = FF400_MIDI_RX_PORT_1, 371 + };
+282
sound/firewire/fireface/ff-stream.c
···
··· 1 + /* 2 + * ff-stream.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "ff.h" 10 + 11 + #define CALLBACK_TIMEOUT_MS 200 12 + 13 + static int get_rate_mode(unsigned int rate, unsigned int *mode) 14 + { 15 + int i; 16 + 17 + for (i = 0; i < CIP_SFC_COUNT; i++) { 18 + if (amdtp_rate_table[i] == rate) 19 + break; 20 + } 21 + 22 + if (i == CIP_SFC_COUNT) 23 + return -EINVAL; 24 + 25 + *mode = ((int)i - 1) / 2; 26 + 27 + return 0; 28 + } 29 + 30 + /* 31 + * Fireface 400 manages isochronous channel number in 3 bit field. Therefore, 32 + * we can allocate between 0 and 7 channel. 33 + */ 34 + static int keep_resources(struct snd_ff *ff, unsigned int rate) 35 + { 36 + int mode; 37 + int err; 38 + 39 + err = get_rate_mode(rate, &mode); 40 + if (err < 0) 41 + return err; 42 + 43 + /* Keep resources for in-stream. */ 44 + err = amdtp_ff_set_parameters(&ff->tx_stream, rate, 45 + ff->spec->pcm_capture_channels[mode]); 46 + if (err < 0) 47 + return err; 48 + ff->tx_resources.channels_mask = 0x00000000000000ffuLL; 49 + err = fw_iso_resources_allocate(&ff->tx_resources, 50 + amdtp_stream_get_max_payload(&ff->tx_stream), 51 + fw_parent_device(ff->unit)->max_speed); 52 + if (err < 0) 53 + return err; 54 + 55 + /* Keep resources for out-stream. */ 56 + err = amdtp_ff_set_parameters(&ff->rx_stream, rate, 57 + ff->spec->pcm_playback_channels[mode]); 58 + if (err < 0) 59 + return err; 60 + ff->rx_resources.channels_mask = 0x00000000000000ffuLL; 61 + err = fw_iso_resources_allocate(&ff->rx_resources, 62 + amdtp_stream_get_max_payload(&ff->rx_stream), 63 + fw_parent_device(ff->unit)->max_speed); 64 + if (err < 0) 65 + fw_iso_resources_free(&ff->tx_resources); 66 + 67 + return err; 68 + } 69 + 70 + static void release_resources(struct snd_ff *ff) 71 + { 72 + fw_iso_resources_free(&ff->tx_resources); 73 + fw_iso_resources_free(&ff->rx_resources); 74 + } 75 + 76 + static inline void finish_session(struct snd_ff *ff) 77 + { 78 + ff->spec->protocol->finish_session(ff); 79 + ff->spec->protocol->switch_fetching_mode(ff, false); 80 + } 81 + 82 + static int init_stream(struct snd_ff *ff, enum amdtp_stream_direction dir) 83 + { 84 + int err; 85 + struct fw_iso_resources *resources; 86 + struct amdtp_stream *stream; 87 + 88 + if (dir == AMDTP_IN_STREAM) { 89 + resources = &ff->tx_resources; 90 + stream = &ff->tx_stream; 91 + } else { 92 + resources = &ff->rx_resources; 93 + stream = &ff->rx_stream; 94 + } 95 + 96 + err = fw_iso_resources_init(resources, ff->unit); 97 + if (err < 0) 98 + return err; 99 + 100 + err = amdtp_ff_init(stream, ff->unit, dir); 101 + if (err < 0) 102 + fw_iso_resources_destroy(resources); 103 + 104 + return err; 105 + } 106 + 107 + static void destroy_stream(struct snd_ff *ff, enum amdtp_stream_direction dir) 108 + { 109 + if (dir == AMDTP_IN_STREAM) { 110 + amdtp_stream_destroy(&ff->tx_stream); 111 + fw_iso_resources_destroy(&ff->tx_resources); 112 + } else { 113 + amdtp_stream_destroy(&ff->rx_stream); 114 + fw_iso_resources_destroy(&ff->rx_resources); 115 + } 116 + } 117 + 118 + int snd_ff_stream_init_duplex(struct snd_ff *ff) 119 + { 120 + int err; 121 + 122 + err = init_stream(ff, AMDTP_OUT_STREAM); 123 + if (err < 0) 124 + goto end; 125 + 126 + err = init_stream(ff, AMDTP_IN_STREAM); 127 + if (err < 0) 128 + destroy_stream(ff, AMDTP_OUT_STREAM); 129 + end: 130 + return err; 131 + } 132 + 133 + /* 134 + * This function should be called before starting streams or after stopping 135 + * streams. 136 + */ 137 + void snd_ff_stream_destroy_duplex(struct snd_ff *ff) 138 + { 139 + destroy_stream(ff, AMDTP_IN_STREAM); 140 + destroy_stream(ff, AMDTP_OUT_STREAM); 141 + } 142 + 143 + int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate) 144 + { 145 + unsigned int curr_rate; 146 + enum snd_ff_clock_src src; 147 + int err; 148 + 149 + if (ff->substreams_counter == 0) 150 + return 0; 151 + 152 + err = ff->spec->protocol->get_clock(ff, &curr_rate, &src); 153 + if (err < 0) 154 + return err; 155 + if (curr_rate != rate || 156 + amdtp_streaming_error(&ff->tx_stream) || 157 + amdtp_streaming_error(&ff->rx_stream)) { 158 + finish_session(ff); 159 + 160 + amdtp_stream_stop(&ff->tx_stream); 161 + amdtp_stream_stop(&ff->rx_stream); 162 + 163 + release_resources(ff); 164 + } 165 + 166 + /* 167 + * Regardless of current source of clock signal, drivers transfer some 168 + * packets. Then, the device transfers packets. 169 + */ 170 + if (!amdtp_stream_running(&ff->rx_stream)) { 171 + err = keep_resources(ff, rate); 172 + if (err < 0) 173 + goto error; 174 + 175 + err = ff->spec->protocol->begin_session(ff, rate); 176 + if (err < 0) 177 + goto error; 178 + 179 + err = amdtp_stream_start(&ff->rx_stream, 180 + ff->rx_resources.channel, 181 + fw_parent_device(ff->unit)->max_speed); 182 + if (err < 0) 183 + goto error; 184 + 185 + if (!amdtp_stream_wait_callback(&ff->rx_stream, 186 + CALLBACK_TIMEOUT_MS)) { 187 + err = -ETIMEDOUT; 188 + goto error; 189 + } 190 + 191 + err = ff->spec->protocol->switch_fetching_mode(ff, true); 192 + if (err < 0) 193 + goto error; 194 + } 195 + 196 + if (!amdtp_stream_running(&ff->tx_stream)) { 197 + err = amdtp_stream_start(&ff->tx_stream, 198 + ff->tx_resources.channel, 199 + fw_parent_device(ff->unit)->max_speed); 200 + if (err < 0) 201 + goto error; 202 + 203 + if (!amdtp_stream_wait_callback(&ff->tx_stream, 204 + CALLBACK_TIMEOUT_MS)) { 205 + err = -ETIMEDOUT; 206 + goto error; 207 + } 208 + } 209 + 210 + return 0; 211 + error: 212 + amdtp_stream_stop(&ff->tx_stream); 213 + amdtp_stream_stop(&ff->rx_stream); 214 + 215 + finish_session(ff); 216 + release_resources(ff); 217 + 218 + return err; 219 + } 220 + 221 + void snd_ff_stream_stop_duplex(struct snd_ff *ff) 222 + { 223 + if (ff->substreams_counter > 0) 224 + return; 225 + 226 + amdtp_stream_stop(&ff->tx_stream); 227 + amdtp_stream_stop(&ff->rx_stream); 228 + finish_session(ff); 229 + release_resources(ff); 230 + } 231 + 232 + void snd_ff_stream_update_duplex(struct snd_ff *ff) 233 + { 234 + /* The device discontinue to transfer packets. */ 235 + amdtp_stream_pcm_abort(&ff->tx_stream); 236 + amdtp_stream_stop(&ff->tx_stream); 237 + 238 + amdtp_stream_pcm_abort(&ff->rx_stream); 239 + amdtp_stream_stop(&ff->rx_stream); 240 + 241 + fw_iso_resources_update(&ff->tx_resources); 242 + fw_iso_resources_update(&ff->rx_resources); 243 + } 244 + 245 + void snd_ff_stream_lock_changed(struct snd_ff *ff) 246 + { 247 + ff->dev_lock_changed = true; 248 + wake_up(&ff->hwdep_wait); 249 + } 250 + 251 + int snd_ff_stream_lock_try(struct snd_ff *ff) 252 + { 253 + int err; 254 + 255 + spin_lock_irq(&ff->lock); 256 + 257 + /* user land lock this */ 258 + if (ff->dev_lock_count < 0) { 259 + err = -EBUSY; 260 + goto end; 261 + } 262 + 263 + /* this is the first time */ 264 + if (ff->dev_lock_count++ == 0) 265 + snd_ff_stream_lock_changed(ff); 266 + err = 0; 267 + end: 268 + spin_unlock_irq(&ff->lock); 269 + return err; 270 + } 271 + 272 + void snd_ff_stream_lock_release(struct snd_ff *ff) 273 + { 274 + spin_lock_irq(&ff->lock); 275 + 276 + if (WARN_ON(ff->dev_lock_count <= 0)) 277 + goto end; 278 + if (--ff->dev_lock_count == 0) 279 + snd_ff_stream_lock_changed(ff); 280 + end: 281 + spin_unlock_irq(&ff->lock); 282 + }
+295
sound/firewire/fireface/ff-transaction.c
···
··· 1 + /* 2 + * ff-transaction.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 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 memory 107 + * barrier, node id has already been updated. In this module, After 108 + * this smp_rmb(), load/store instructions to memory are completed. 109 + * Thus, both of generation and node id are available with recent 110 + * values. This is a light-serialization solution to handle bus reset 111 + * 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 same 157 + * units are on the same IEEE 1394 bus. This driver doesn't use 158 + * 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 in 207 + * 0x'0000'8010'051c. This register includes the other options, thus this driver 208 + * doesn't touch it and leaves the decision to userspace. The userspace MUST add 209 + * 0x04000000 to write transactions to the register to receive any MIDI 210 + * messages. 211 + * 212 + * Here, I just describe MIDI-related offsets of the register, in little-endian 213 + * order. 214 + * 215 + * Controllers are allowed to register higher 4 bytes of address to receive 216 + * the transactions. The register is 0x'0000'8010'03f4. On the other hand, the 217 + * controllers are not allowed to register lower 4 bytes of the address. They 218 + * are forced to select from 4 options by writing corresponding bits to 219 + * 0x'0000'8010'051c. 220 + * 221 + * The 3rd-6th bits in MSB of this register are used to indicate lower 4 bytes 222 + * of address to which the device transferrs the transactions. 223 + * - 6th: 0x'....'....'0000'0180 224 + * - 5th: 0x'....'....'0000'0100 225 + * - 4th: 0x'....'....'0000'0080 226 + * - 3rd: 0x'....'....'0000'0000 227 + * 228 + * This driver configure 0x'....'....'0000'0000 for units to receive MIDI 229 + * messages. 3rd bit of the register should be configured, however this driver 230 + * deligates this task to user space applications due to a restriction that 231 + * 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 transferring 234 + * asynchronous transactions. These two bits have the same effect. 235 + * - 1st/2nd: cancel transferring 236 + */ 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 of 245 + * 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 + &reg, 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 should 260 + * 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 + &reg, sizeof(reg), 0); 293 + 294 + fw_core_remove_address_handler(&ff->async_handler); 295 + }
+209
sound/firewire/fireface/ff.c
···
··· 1 + /* 2 + * ff.c - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "ff.h" 10 + 11 + #define OUI_RME 0x000a35 12 + 13 + MODULE_DESCRIPTION("RME Fireface series Driver"); 14 + MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 15 + MODULE_LICENSE("GPL v2"); 16 + 17 + static void name_card(struct snd_ff *ff) 18 + { 19 + struct fw_device *fw_dev = fw_parent_device(ff->unit); 20 + 21 + strcpy(ff->card->driver, "Fireface"); 22 + strcpy(ff->card->shortname, ff->spec->name); 23 + strcpy(ff->card->mixername, ff->spec->name); 24 + snprintf(ff->card->longname, sizeof(ff->card->longname), 25 + "RME %s, GUID %08x%08x at %s, S%d", ff->spec->name, 26 + fw_dev->config_rom[3], fw_dev->config_rom[4], 27 + dev_name(&ff->unit->device), 100 << fw_dev->max_speed); 28 + } 29 + 30 + static void ff_free(struct snd_ff *ff) 31 + { 32 + snd_ff_stream_destroy_duplex(ff); 33 + snd_ff_transaction_unregister(ff); 34 + 35 + fw_unit_put(ff->unit); 36 + 37 + mutex_destroy(&ff->mutex); 38 + kfree(ff); 39 + } 40 + 41 + static void ff_card_free(struct snd_card *card) 42 + { 43 + ff_free(card->private_data); 44 + } 45 + 46 + static void do_registration(struct work_struct *work) 47 + { 48 + struct snd_ff *ff = container_of(work, struct snd_ff, dwork.work); 49 + int err; 50 + 51 + if (ff->registered) 52 + return; 53 + 54 + err = snd_card_new(&ff->unit->device, -1, NULL, THIS_MODULE, 0, 55 + &ff->card); 56 + if (err < 0) 57 + return; 58 + 59 + err = snd_ff_transaction_register(ff); 60 + if (err < 0) 61 + goto error; 62 + 63 + name_card(ff); 64 + 65 + err = snd_ff_stream_init_duplex(ff); 66 + if (err < 0) 67 + goto error; 68 + 69 + snd_ff_proc_init(ff); 70 + 71 + err = snd_ff_create_midi_devices(ff); 72 + if (err < 0) 73 + goto error; 74 + 75 + err = snd_ff_create_pcm_devices(ff); 76 + if (err < 0) 77 + goto error; 78 + 79 + err = snd_ff_create_hwdep_devices(ff); 80 + if (err < 0) 81 + goto error; 82 + 83 + err = snd_card_register(ff->card); 84 + if (err < 0) 85 + goto error; 86 + 87 + ff->card->private_free = ff_card_free; 88 + ff->card->private_data = ff; 89 + ff->registered = true; 90 + 91 + return; 92 + error: 93 + snd_ff_transaction_unregister(ff); 94 + snd_ff_stream_destroy_duplex(ff); 95 + snd_card_free(ff->card); 96 + dev_info(&ff->unit->device, 97 + "Sound card registration failed: %d\n", err); 98 + } 99 + 100 + static int snd_ff_probe(struct fw_unit *unit, 101 + const struct ieee1394_device_id *entry) 102 + { 103 + struct snd_ff *ff; 104 + 105 + ff = kzalloc(sizeof(struct snd_ff), GFP_KERNEL); 106 + if (ff == NULL) 107 + return -ENOMEM; 108 + 109 + /* initialize myself */ 110 + ff->unit = fw_unit_get(unit); 111 + dev_set_drvdata(&unit->device, ff); 112 + 113 + mutex_init(&ff->mutex); 114 + spin_lock_init(&ff->lock); 115 + init_waitqueue_head(&ff->hwdep_wait); 116 + 117 + ff->spec = (const struct snd_ff_spec *)entry->driver_data; 118 + 119 + /* Register this sound card later. */ 120 + INIT_DEFERRABLE_WORK(&ff->dwork, do_registration); 121 + snd_fw_schedule_registration(unit, &ff->dwork); 122 + 123 + return 0; 124 + } 125 + 126 + static void snd_ff_update(struct fw_unit *unit) 127 + { 128 + struct snd_ff *ff = dev_get_drvdata(&unit->device); 129 + 130 + /* Postpone a workqueue for deferred registration. */ 131 + if (!ff->registered) 132 + snd_fw_schedule_registration(unit, &ff->dwork); 133 + 134 + snd_ff_transaction_reregister(ff); 135 + 136 + if (ff->registered) 137 + snd_ff_stream_update_duplex(ff); 138 + } 139 + 140 + static void snd_ff_remove(struct fw_unit *unit) 141 + { 142 + struct snd_ff *ff = dev_get_drvdata(&unit->device); 143 + 144 + /* 145 + * Confirm to stop the work for registration before the sound card is 146 + * going to be released. The work is not scheduled again because bus 147 + * reset handler is not called anymore. 148 + */ 149 + cancel_work_sync(&ff->dwork.work); 150 + 151 + if (ff->registered) { 152 + /* No need to wait for releasing card object in this context. */ 153 + snd_card_free_when_closed(ff->card); 154 + } else { 155 + /* Don't forget this case. */ 156 + ff_free(ff); 157 + } 158 + } 159 + 160 + static struct snd_ff_spec spec_ff400 = { 161 + .name = "Fireface400", 162 + .pcm_capture_channels = {18, 14, 10}, 163 + .pcm_playback_channels = {18, 14, 10}, 164 + .midi_in_ports = 2, 165 + .midi_out_ports = 2, 166 + .protocol = &snd_ff_protocol_ff400, 167 + }; 168 + 169 + static const struct ieee1394_device_id snd_ff_id_table[] = { 170 + /* Fireface 400 */ 171 + { 172 + .match_flags = IEEE1394_MATCH_VENDOR_ID | 173 + IEEE1394_MATCH_SPECIFIER_ID | 174 + IEEE1394_MATCH_VERSION | 175 + IEEE1394_MATCH_MODEL_ID, 176 + .vendor_id = OUI_RME, 177 + .specifier_id = 0x000a35, 178 + .version = 0x000002, 179 + .model_id = 0x101800, 180 + .driver_data = (kernel_ulong_t)&spec_ff400, 181 + }, 182 + {} 183 + }; 184 + MODULE_DEVICE_TABLE(ieee1394, snd_ff_id_table); 185 + 186 + static struct fw_driver ff_driver = { 187 + .driver = { 188 + .owner = THIS_MODULE, 189 + .name = "snd-fireface", 190 + .bus = &fw_bus_type, 191 + }, 192 + .probe = snd_ff_probe, 193 + .update = snd_ff_update, 194 + .remove = snd_ff_remove, 195 + .id_table = snd_ff_id_table, 196 + }; 197 + 198 + static int __init snd_ff_init(void) 199 + { 200 + return driver_register(&ff_driver.driver); 201 + } 202 + 203 + static void __exit snd_ff_exit(void) 204 + { 205 + driver_unregister(&ff_driver.driver); 206 + } 207 + 208 + module_init(snd_ff_init); 209 + module_exit(snd_ff_exit);
+146
sound/firewire/fireface/ff.h
···
··· 1 + /* 2 + * ff.h - a part of driver for RME Fireface series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #ifndef SOUND_FIREFACE_H_INCLUDED 10 + #define SOUND_FIREFACE_H_INCLUDED 11 + 12 + #include <linux/device.h> 13 + #include <linux/firewire.h> 14 + #include <linux/firewire-constants.h> 15 + #include <linux/module.h> 16 + #include <linux/mod_devicetable.h> 17 + #include <linux/mutex.h> 18 + #include <linux/slab.h> 19 + #include <linux/compat.h> 20 + #include <linux/sched/signal.h> 21 + 22 + #include <sound/core.h> 23 + #include <sound/info.h> 24 + #include <sound/rawmidi.h> 25 + #include <sound/pcm.h> 26 + #include <sound/pcm_params.h> 27 + #include <sound/hwdep.h> 28 + #include <sound/firewire.h> 29 + 30 + #include "../lib.h" 31 + #include "../amdtp-stream.h" 32 + #include "../iso-resources.h" 33 + 34 + #define SND_FF_STREAM_MODES 3 35 + 36 + #define SND_FF_MAXIMIM_MIDI_QUADS 9 37 + #define SND_FF_IN_MIDI_PORTS 2 38 + #define SND_FF_OUT_MIDI_PORTS 2 39 + 40 + struct snd_ff_protocol; 41 + struct snd_ff_spec { 42 + const char *const name; 43 + 44 + const unsigned int pcm_capture_channels[SND_FF_STREAM_MODES]; 45 + const unsigned int pcm_playback_channels[SND_FF_STREAM_MODES]; 46 + 47 + unsigned int midi_in_ports; 48 + unsigned int midi_out_ports; 49 + 50 + struct snd_ff_protocol *protocol; 51 + }; 52 + 53 + struct snd_ff { 54 + struct snd_card *card; 55 + struct fw_unit *unit; 56 + struct mutex mutex; 57 + spinlock_t lock; 58 + 59 + bool registered; 60 + struct delayed_work dwork; 61 + 62 + const struct snd_ff_spec *spec; 63 + 64 + /* To handle MIDI tx. */ 65 + struct snd_rawmidi_substream *tx_midi_substreams[SND_FF_IN_MIDI_PORTS]; 66 + struct fw_address_handler async_handler; 67 + 68 + /* TO handle MIDI rx. */ 69 + struct snd_rawmidi_substream *rx_midi_substreams[SND_FF_OUT_MIDI_PORTS]; 70 + u8 running_status[SND_FF_OUT_MIDI_PORTS]; 71 + __le32 msg_buf[SND_FF_OUT_MIDI_PORTS][SND_FF_MAXIMIM_MIDI_QUADS]; 72 + struct work_struct rx_midi_work[SND_FF_OUT_MIDI_PORTS]; 73 + struct fw_transaction transactions[SND_FF_OUT_MIDI_PORTS]; 74 + ktime_t next_ktime[SND_FF_OUT_MIDI_PORTS]; 75 + bool rx_midi_error[SND_FF_OUT_MIDI_PORTS]; 76 + unsigned int rx_bytes[SND_FF_OUT_MIDI_PORTS]; 77 + 78 + unsigned int substreams_counter; 79 + struct amdtp_stream tx_stream; 80 + struct amdtp_stream rx_stream; 81 + struct fw_iso_resources tx_resources; 82 + struct fw_iso_resources rx_resources; 83 + 84 + int dev_lock_count; 85 + bool dev_lock_changed; 86 + wait_queue_head_t hwdep_wait; 87 + }; 88 + 89 + enum snd_ff_clock_src { 90 + SND_FF_CLOCK_SRC_INTERNAL, 91 + SND_FF_CLOCK_SRC_SPDIF, 92 + SND_FF_CLOCK_SRC_ADAT, 93 + SND_FF_CLOCK_SRC_WORD, 94 + SND_FF_CLOCK_SRC_LTC, 95 + /* TODO: perhaps ADAT2 and TCO exists. */ 96 + }; 97 + 98 + struct snd_ff_protocol { 99 + int (*get_clock)(struct snd_ff *ff, unsigned int *rate, 100 + enum snd_ff_clock_src *src); 101 + int (*begin_session)(struct snd_ff *ff, unsigned int rate); 102 + void (*finish_session)(struct snd_ff *ff); 103 + int (*switch_fetching_mode)(struct snd_ff *ff, bool enable); 104 + 105 + void (*dump_sync_status)(struct snd_ff *ff, 106 + struct snd_info_buffer *buffer); 107 + void (*dump_clock_config)(struct snd_ff *ff, 108 + struct snd_info_buffer *buffer); 109 + 110 + u64 midi_high_addr_reg; 111 + u64 midi_rx_port_0_reg; 112 + u64 midi_rx_port_1_reg; 113 + }; 114 + 115 + extern struct snd_ff_protocol snd_ff_protocol_ff400; 116 + 117 + int snd_ff_transaction_register(struct snd_ff *ff); 118 + int snd_ff_transaction_reregister(struct snd_ff *ff); 119 + void snd_ff_transaction_unregister(struct snd_ff *ff); 120 + 121 + int amdtp_ff_set_parameters(struct amdtp_stream *s, unsigned int rate, 122 + unsigned int pcm_channels); 123 + int amdtp_ff_add_pcm_hw_constraints(struct amdtp_stream *s, 124 + struct snd_pcm_runtime *runtime); 125 + int amdtp_ff_init(struct amdtp_stream *s, struct fw_unit *unit, 126 + enum amdtp_stream_direction dir); 127 + 128 + int snd_ff_stream_init_duplex(struct snd_ff *ff); 129 + void snd_ff_stream_destroy_duplex(struct snd_ff *ff); 130 + int snd_ff_stream_start_duplex(struct snd_ff *ff, unsigned int rate); 131 + void snd_ff_stream_stop_duplex(struct snd_ff *ff); 132 + void snd_ff_stream_update_duplex(struct snd_ff *ff); 133 + 134 + void snd_ff_stream_lock_changed(struct snd_ff *ff); 135 + int snd_ff_stream_lock_try(struct snd_ff *ff); 136 + void snd_ff_stream_lock_release(struct snd_ff *ff); 137 + 138 + void snd_ff_proc_init(struct snd_ff *ff); 139 + 140 + int snd_ff_create_midi_devices(struct snd_ff *ff); 141 + 142 + int snd_ff_create_pcm_devices(struct snd_ff *ff); 143 + 144 + int snd_ff_create_hwdep_devices(struct snd_ff *ff); 145 + 146 + #endif
-141
sound/firewire/lib.c
··· 99 } 100 EXPORT_SYMBOL(snd_fw_schedule_registration); 101 102 - 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 - else 119 - /* 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 - else 172 - 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 memory 183 - * barrier, node id has already been updated. In this module, After 184 - * this smp_rmb(), load/store instructions to memory are completed. 185 - * Thus, both of generation and node id are available with recent 186 - * values. This is a light-serialization solution to handle bus reset 187 - * 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 structure 201 - * @port: the asynchronous MIDI port to initialize 202 - * @unit: the target of the asynchronous transaction 203 - * @addr: the address to which transactions are transferred 204 - * @len: the length of transaction 205 - * @fill: the callback function to fill given buffer, and returns the 206 - * 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 structure 233 - * @port: the asynchronous MIDI port structure 234 - */ 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 - 243 MODULE_DESCRIPTION("FireWire audio helper functions"); 244 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 245 MODULE_LICENSE("GPL v2");
··· 99 } 100 EXPORT_SYMBOL(snd_fw_schedule_registration); 101 102 MODULE_DESCRIPTION("FireWire audio helper functions"); 103 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 104 MODULE_LICENSE("GPL v2");
-54
sound/firewire/lib.h
··· 25 void snd_fw_schedule_registration(struct fw_unit *unit, 26 struct delayed_work *dwork); 27 28 - struct snd_fw_async_midi_port; 29 - typedef int (*snd_fw_async_midi_port_fill)( 30 - struct snd_rawmidi_substream *substream, 31 - u8 *buf); 32 - 33 - struct snd_fw_async_midi_port { 34 - struct fw_device *parent; 35 - struct work_struct work; 36 - bool idling; 37 - ktime_t next_ktime; 38 - bool error; 39 - 40 - u64 addr; 41 - struct fw_transaction transaction; 42 - 43 - u8 *buf; 44 - unsigned int len; 45 - 46 - struct snd_rawmidi_substream *substream; 47 - snd_fw_async_midi_port_fill fill; 48 - int consume_bytes; 49 - }; 50 - 51 - int snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port, 52 - struct fw_unit *unit, u64 addr, unsigned int len, 53 - snd_fw_async_midi_port_fill fill); 54 - void snd_fw_async_midi_port_destroy(struct snd_fw_async_midi_port *port); 55 - 56 - /** 57 - * snd_fw_async_midi_port_run - run transactions for the async MIDI port 58 - * @port: the asynchronous MIDI port 59 - * @substream: the MIDI substream 60 - */ 61 - static inline void 62 - snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port, 63 - struct snd_rawmidi_substream *substream) 64 - { 65 - if (!port->error) { 66 - port->substream = substream; 67 - schedule_work(&port->work); 68 - } 69 - } 70 - 71 - /** 72 - * snd_fw_async_midi_port_finish - finish the asynchronous MIDI port 73 - * @port: the asynchronous MIDI port 74 - */ 75 - static inline void 76 - snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port) 77 - { 78 - port->substream = NULL; 79 - port->error = false; 80 - } 81 - 82 #endif
··· 25 void snd_fw_schedule_registration(struct fw_unit *unit, 26 struct delayed_work *dwork); 27 28 #endif
+6
sound/firewire/motu/Makefile
···
··· 1 + CFLAGS_amdtp-motu.o := -I$(src) 2 + 3 + snd-firewire-motu-objs := motu.o amdtp-motu.o motu-transaction.o motu-stream.o \ 4 + motu-proc.o motu-pcm.o motu-midi.o motu-hwdep.o \ 5 + motu-protocol-v2.o motu-protocol-v3.o 6 + obj-$(CONFIG_SND_FIREWIRE_MOTU) += snd-firewire-motu.o
+123
sound/firewire/motu/amdtp-motu-trace.h
···
··· 1 + /* 2 + * amdtp-motu-trace.h - tracepoint definitions to dump a part of packet data 3 + * 4 + * Copyright (c) 2017 Takashi Sakamoto 5 + * Licensed under the terms of the GNU General Public License, version 2. 6 + */ 7 + 8 + #undef TRACE_SYSTEM 9 + #define TRACE_SYSTEM snd_firewire_motu 10 + 11 + #if !defined(_SND_FIREWIRE_MOTU_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) 12 + #define _SND_FIREWIRE_MOTU_TRACE_H 13 + 14 + #include <linux/tracepoint.h> 15 + 16 + static void copy_sph(u32 *frame, __be32 *buffer, unsigned int data_blocks, 17 + unsigned int data_block_quadlets); 18 + static void copy_message(u64 *frames, __be32 *buffer, unsigned int data_blocks, 19 + unsigned int data_block_quadlets); 20 + 21 + TRACE_EVENT(in_data_block_sph, 22 + TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer), 23 + TP_ARGS(s, data_blocks, buffer), 24 + TP_STRUCT__entry( 25 + __field(int, src) 26 + __field(int, dst) 27 + __field(unsigned int, data_blocks) 28 + __dynamic_array(u32, tstamps, data_blocks) 29 + ), 30 + TP_fast_assign( 31 + __entry->src = fw_parent_device(s->unit)->node_id; 32 + __entry->dst = fw_parent_device(s->unit)->card->node_id; 33 + __entry->data_blocks = data_blocks; 34 + copy_sph(__get_dynamic_array(tstamps), buffer, data_blocks, s->data_block_quadlets); 35 + ), 36 + TP_printk( 37 + "%04x %04x %u %s", 38 + __entry->src, 39 + __entry->dst, 40 + __entry->data_blocks, 41 + __print_array(__get_dynamic_array(tstamps), __entry->data_blocks, 4) 42 + ) 43 + ); 44 + 45 + TRACE_EVENT(out_data_block_sph, 46 + TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer), 47 + TP_ARGS(s, data_blocks, buffer), 48 + TP_STRUCT__entry( 49 + __field(int, src) 50 + __field(int, dst) 51 + __field(unsigned int, data_blocks) 52 + __dynamic_array(u32, tstamps, data_blocks) 53 + ), 54 + TP_fast_assign( 55 + __entry->src = fw_parent_device(s->unit)->card->node_id; 56 + __entry->dst = fw_parent_device(s->unit)->node_id; 57 + __entry->data_blocks = data_blocks; 58 + copy_sph(__get_dynamic_array(tstamps), buffer, data_blocks, s->data_block_quadlets); 59 + ), 60 + TP_printk( 61 + "%04x %04x %u %s", 62 + __entry->src, 63 + __entry->dst, 64 + __entry->data_blocks, 65 + __print_array(__get_dynamic_array(tstamps), __entry->data_blocks, 4) 66 + ) 67 + ); 68 + 69 + TRACE_EVENT(in_data_block_message, 70 + TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer), 71 + TP_ARGS(s, data_blocks, buffer), 72 + TP_STRUCT__entry( 73 + __field(int, src) 74 + __field(int, dst) 75 + __field(unsigned int, data_blocks) 76 + __dynamic_array(u64, messages, data_blocks) 77 + ), 78 + TP_fast_assign( 79 + __entry->src = fw_parent_device(s->unit)->node_id; 80 + __entry->dst = fw_parent_device(s->unit)->card->node_id; 81 + __entry->data_blocks = data_blocks; 82 + copy_message(__get_dynamic_array(messages), buffer, data_blocks, s->data_block_quadlets); 83 + ), 84 + TP_printk( 85 + "%04x %04x %u %s", 86 + __entry->src, 87 + __entry->dst, 88 + __entry->data_blocks, 89 + __print_array(__get_dynamic_array(messages), __entry->data_blocks, 8) 90 + ) 91 + ); 92 + 93 + TRACE_EVENT(out_data_block_message, 94 + TP_PROTO(struct amdtp_stream *s, unsigned int data_blocks, __be32 *buffer), 95 + TP_ARGS(s, data_blocks, buffer), 96 + TP_STRUCT__entry( 97 + __field(int, src) 98 + __field(int, dst) 99 + __field(unsigned int, data_blocks) 100 + __dynamic_array(u64, messages, data_blocks) 101 + ), 102 + TP_fast_assign( 103 + __entry->src = fw_parent_device(s->unit)->card->node_id; 104 + __entry->dst = fw_parent_device(s->unit)->node_id; 105 + __entry->data_blocks = data_blocks; 106 + copy_message(__get_dynamic_array(messages), buffer, data_blocks, s->data_block_quadlets); 107 + ), 108 + TP_printk( 109 + "%04x %04x %u %s", 110 + __entry->src, 111 + __entry->dst, 112 + __entry->data_blocks, 113 + __print_array(__get_dynamic_array(messages), __entry->data_blocks, 8) 114 + ) 115 + ); 116 + 117 + #endif 118 + 119 + #undef TRACE_INCLUDE_PATH 120 + #define TRACE_INCLUDE_PATH . 121 + #undef TRACE_INCLUDE_FILE 122 + #define TRACE_INCLUDE_FILE amdtp-motu-trace 123 + #include <trace/define_trace.h>
+427
sound/firewire/motu/amdtp-motu.c
···
··· 1 + /* 2 + * amdtp-motu.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include <linux/slab.h> 10 + #include <sound/pcm.h> 11 + #include "motu.h" 12 + 13 + #define CREATE_TRACE_POINTS 14 + #include "amdtp-motu-trace.h" 15 + 16 + #define CIP_FMT_MOTU 0x02 17 + #define CIP_FMT_MOTU_TX_V3 0x22 18 + #define MOTU_FDF_AM824 0x22 19 + 20 + /* 21 + * Nominally 3125 bytes/second, but the MIDI port's clock might be 22 + * 1% too slow, and the bus clock 100 ppm too fast. 23 + */ 24 + #define MIDI_BYTES_PER_SECOND 3093 25 + 26 + struct amdtp_motu { 27 + /* For timestamp processing. */ 28 + unsigned int quotient_ticks_per_event; 29 + unsigned int remainder_ticks_per_event; 30 + unsigned int next_ticks; 31 + unsigned int next_accumulated; 32 + unsigned int next_cycles; 33 + unsigned int next_seconds; 34 + 35 + unsigned int pcm_chunks; 36 + unsigned int pcm_byte_offset; 37 + 38 + struct snd_rawmidi_substream *midi; 39 + unsigned int midi_ports; 40 + unsigned int midi_flag_offset; 41 + unsigned int midi_byte_offset; 42 + 43 + int midi_db_count; 44 + unsigned int midi_db_interval; 45 + }; 46 + 47 + int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, 48 + unsigned int midi_ports, 49 + struct snd_motu_packet_format *formats) 50 + { 51 + static const struct { 52 + unsigned int quotient_ticks_per_event; 53 + unsigned int remainder_ticks_per_event; 54 + } params[] = { 55 + [CIP_SFC_44100] = { 557, 123 }, 56 + [CIP_SFC_48000] = { 512, 0 }, 57 + [CIP_SFC_88200] = { 278, 282 }, 58 + [CIP_SFC_96000] = { 256, 0 }, 59 + [CIP_SFC_176400] = { 139, 141 }, 60 + [CIP_SFC_192000] = { 128, 0 }, 61 + }; 62 + struct amdtp_motu *p = s->protocol; 63 + unsigned int pcm_chunks, data_chunks, data_block_quadlets; 64 + unsigned int delay; 65 + unsigned int mode; 66 + int i, err; 67 + 68 + if (amdtp_stream_running(s)) 69 + return -EBUSY; 70 + 71 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 72 + if (snd_motu_clock_rates[i] == rate) { 73 + mode = i >> 1; 74 + break; 75 + } 76 + } 77 + if (i == ARRAY_SIZE(snd_motu_clock_rates)) 78 + return -EINVAL; 79 + 80 + pcm_chunks = formats->fixed_part_pcm_chunks[mode] + 81 + formats->differed_part_pcm_chunks[mode]; 82 + data_chunks = formats->msg_chunks + pcm_chunks; 83 + 84 + /* 85 + * Each data block includes SPH in its head. Data chunks follow with 86 + * 3 byte alignment. Padding follows with zero to conform to quadlet 87 + * alignment. 88 + */ 89 + data_block_quadlets = 1 + DIV_ROUND_UP(data_chunks * 3, 4); 90 + 91 + err = amdtp_stream_set_parameters(s, rate, data_block_quadlets); 92 + if (err < 0) 93 + return err; 94 + 95 + p->pcm_chunks = pcm_chunks; 96 + p->pcm_byte_offset = formats->pcm_byte_offset; 97 + 98 + p->midi_ports = midi_ports; 99 + p->midi_flag_offset = formats->midi_flag_offset; 100 + p->midi_byte_offset = formats->midi_byte_offset; 101 + 102 + p->midi_db_count = 0; 103 + p->midi_db_interval = rate / MIDI_BYTES_PER_SECOND; 104 + 105 + /* IEEE 1394 bus requires. */ 106 + delay = 0x2e00; 107 + 108 + /* For no-data or empty packets to adjust PCM sampling frequency. */ 109 + delay += 8000 * 3072 * s->syt_interval / rate; 110 + 111 + p->next_seconds = 0; 112 + p->next_cycles = delay / 3072; 113 + p->quotient_ticks_per_event = params[s->sfc].quotient_ticks_per_event; 114 + p->remainder_ticks_per_event = params[s->sfc].remainder_ticks_per_event; 115 + p->next_ticks = delay % 3072; 116 + p->next_accumulated = 0; 117 + 118 + return 0; 119 + } 120 + 121 + static void read_pcm_s32(struct amdtp_stream *s, 122 + struct snd_pcm_runtime *runtime, 123 + __be32 *buffer, unsigned int data_blocks) 124 + { 125 + struct amdtp_motu *p = s->protocol; 126 + unsigned int channels, remaining_frames, i, c; 127 + u8 *byte; 128 + u32 *dst; 129 + 130 + channels = p->pcm_chunks; 131 + dst = (void *)runtime->dma_area + 132 + frames_to_bytes(runtime, s->pcm_buffer_pointer); 133 + remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 134 + 135 + for (i = 0; i < data_blocks; ++i) { 136 + byte = (u8 *)buffer + p->pcm_byte_offset; 137 + 138 + for (c = 0; c < channels; ++c) { 139 + *dst = (byte[0] << 24) | (byte[1] << 16) | byte[2]; 140 + byte += 3; 141 + dst++; 142 + } 143 + buffer += s->data_block_quadlets; 144 + if (--remaining_frames == 0) 145 + dst = (void *)runtime->dma_area; 146 + } 147 + } 148 + 149 + static void write_pcm_s32(struct amdtp_stream *s, 150 + struct snd_pcm_runtime *runtime, 151 + __be32 *buffer, unsigned int data_blocks) 152 + { 153 + struct amdtp_motu *p = s->protocol; 154 + unsigned int channels, remaining_frames, i, c; 155 + u8 *byte; 156 + const u32 *src; 157 + 158 + channels = p->pcm_chunks; 159 + src = (void *)runtime->dma_area + 160 + frames_to_bytes(runtime, s->pcm_buffer_pointer); 161 + remaining_frames = runtime->buffer_size - s->pcm_buffer_pointer; 162 + 163 + for (i = 0; i < data_blocks; ++i) { 164 + byte = (u8 *)buffer + p->pcm_byte_offset; 165 + 166 + for (c = 0; c < channels; ++c) { 167 + byte[0] = (*src >> 24) & 0xff; 168 + byte[1] = (*src >> 16) & 0xff; 169 + byte[2] = (*src >> 8) & 0xff; 170 + byte += 3; 171 + src++; 172 + } 173 + 174 + buffer += s->data_block_quadlets; 175 + if (--remaining_frames == 0) 176 + src = (void *)runtime->dma_area; 177 + } 178 + } 179 + 180 + static void write_pcm_silence(struct amdtp_stream *s, __be32 *buffer, 181 + unsigned int data_blocks) 182 + { 183 + struct amdtp_motu *p = s->protocol; 184 + unsigned int channels, i, c; 185 + u8 *byte; 186 + 187 + channels = p->pcm_chunks; 188 + 189 + for (i = 0; i < data_blocks; ++i) { 190 + byte = (u8 *)buffer + p->pcm_byte_offset; 191 + 192 + for (c = 0; c < channels; ++c) { 193 + byte[0] = 0; 194 + byte[1] = 0; 195 + byte[2] = 0; 196 + byte += 3; 197 + } 198 + 199 + buffer += s->data_block_quadlets; 200 + } 201 + } 202 + 203 + int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s, 204 + struct snd_pcm_runtime *runtime) 205 + { 206 + int err; 207 + 208 + /* TODO: how to set an constraint for exactly 24bit PCM sample? */ 209 + err = snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); 210 + if (err < 0) 211 + return err; 212 + 213 + return amdtp_stream_add_pcm_hw_constraints(s, runtime); 214 + } 215 + 216 + void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port, 217 + struct snd_rawmidi_substream *midi) 218 + { 219 + struct amdtp_motu *p = s->protocol; 220 + 221 + if (port < p->midi_ports) 222 + WRITE_ONCE(p->midi, midi); 223 + } 224 + 225 + static void write_midi_messages(struct amdtp_stream *s, __be32 *buffer, 226 + unsigned int data_blocks) 227 + { 228 + struct amdtp_motu *p = s->protocol; 229 + struct snd_rawmidi_substream *midi = READ_ONCE(p->midi); 230 + u8 *b; 231 + int i; 232 + 233 + for (i = 0; i < data_blocks; i++) { 234 + b = (u8 *)buffer; 235 + 236 + if (midi && p->midi_db_count == 0 && 237 + snd_rawmidi_transmit(midi, b + p->midi_byte_offset, 1) == 1) { 238 + b[p->midi_flag_offset] = 0x01; 239 + } else { 240 + b[p->midi_byte_offset] = 0x00; 241 + b[p->midi_flag_offset] = 0x00; 242 + } 243 + 244 + buffer += s->data_block_quadlets; 245 + 246 + if (--p->midi_db_count < 0) 247 + p->midi_db_count = p->midi_db_interval; 248 + } 249 + } 250 + 251 + static void read_midi_messages(struct amdtp_stream *s, __be32 *buffer, 252 + unsigned int data_blocks) 253 + { 254 + struct amdtp_motu *p = s->protocol; 255 + struct snd_rawmidi_substream *midi; 256 + u8 *b; 257 + int i; 258 + 259 + for (i = 0; i < data_blocks; i++) { 260 + b = (u8 *)buffer; 261 + midi = READ_ONCE(p->midi); 262 + 263 + if (midi && (b[p->midi_flag_offset] & 0x01)) 264 + snd_rawmidi_receive(midi, b + p->midi_byte_offset, 1); 265 + 266 + buffer += s->data_block_quadlets; 267 + } 268 + } 269 + 270 + /* For tracepoints. */ 271 + static void __maybe_unused copy_sph(u32 *frames, __be32 *buffer, 272 + unsigned int data_blocks, 273 + unsigned int data_block_quadlets) 274 + { 275 + unsigned int i; 276 + 277 + for (i = 0; i < data_blocks; ++i) { 278 + *frames = be32_to_cpu(*buffer); 279 + buffer += data_block_quadlets; 280 + frames++; 281 + } 282 + } 283 + 284 + /* For tracepoints. */ 285 + static void __maybe_unused copy_message(u64 *frames, __be32 *buffer, 286 + unsigned int data_blocks, 287 + unsigned int data_block_quadlets) 288 + { 289 + unsigned int i; 290 + 291 + /* This is just for v2/v3 protocol. */ 292 + for (i = 0; i < data_blocks; ++i) { 293 + *frames = (be32_to_cpu(buffer[1]) << 16) | 294 + (be32_to_cpu(buffer[2]) >> 16); 295 + buffer += data_block_quadlets; 296 + frames++; 297 + } 298 + } 299 + 300 + static unsigned int process_tx_data_blocks(struct amdtp_stream *s, 301 + __be32 *buffer, unsigned int data_blocks, 302 + unsigned int *syt) 303 + { 304 + struct amdtp_motu *p = s->protocol; 305 + struct snd_pcm_substream *pcm; 306 + 307 + trace_in_data_block_sph(s, data_blocks, buffer); 308 + trace_in_data_block_message(s, data_blocks, buffer); 309 + 310 + if (p->midi_ports) 311 + read_midi_messages(s, buffer, data_blocks); 312 + 313 + pcm = ACCESS_ONCE(s->pcm); 314 + if (data_blocks > 0 && pcm) 315 + read_pcm_s32(s, pcm->runtime, buffer, data_blocks); 316 + 317 + return data_blocks; 318 + } 319 + 320 + static inline void compute_next_elapse_from_start(struct amdtp_motu *p) 321 + { 322 + p->next_accumulated += p->remainder_ticks_per_event; 323 + if (p->next_accumulated >= 441) { 324 + p->next_accumulated -= 441; 325 + p->next_ticks++; 326 + } 327 + 328 + p->next_ticks += p->quotient_ticks_per_event; 329 + if (p->next_ticks >= 3072) { 330 + p->next_ticks -= 3072; 331 + p->next_cycles++; 332 + } 333 + 334 + if (p->next_cycles >= 8000) { 335 + p->next_cycles -= 8000; 336 + p->next_seconds++; 337 + } 338 + 339 + if (p->next_seconds >= 128) 340 + p->next_seconds -= 128; 341 + } 342 + 343 + static void write_sph(struct amdtp_stream *s, __be32 *buffer, 344 + unsigned int data_blocks) 345 + { 346 + struct amdtp_motu *p = s->protocol; 347 + unsigned int next_cycles; 348 + unsigned int i; 349 + u32 sph; 350 + 351 + for (i = 0; i < data_blocks; i++) { 352 + next_cycles = (s->start_cycle + p->next_cycles) % 8000; 353 + sph = ((next_cycles << 12) | p->next_ticks) & 0x01ffffff; 354 + *buffer = cpu_to_be32(sph); 355 + 356 + compute_next_elapse_from_start(p); 357 + 358 + buffer += s->data_block_quadlets; 359 + } 360 + } 361 + 362 + static unsigned int process_rx_data_blocks(struct amdtp_stream *s, 363 + __be32 *buffer, unsigned int data_blocks, 364 + unsigned int *syt) 365 + { 366 + struct amdtp_motu *p = (struct amdtp_motu *)s->protocol; 367 + struct snd_pcm_substream *pcm; 368 + 369 + /* Not used. */ 370 + *syt = 0xffff; 371 + 372 + /* TODO: how to interact control messages between userspace? */ 373 + 374 + if (p->midi_ports) 375 + write_midi_messages(s, buffer, data_blocks); 376 + 377 + pcm = ACCESS_ONCE(s->pcm); 378 + if (pcm) 379 + write_pcm_s32(s, pcm->runtime, buffer, data_blocks); 380 + else 381 + write_pcm_silence(s, buffer, data_blocks); 382 + 383 + write_sph(s, buffer, data_blocks); 384 + 385 + trace_out_data_block_sph(s, data_blocks, buffer); 386 + trace_out_data_block_message(s, data_blocks, buffer); 387 + 388 + return data_blocks; 389 + } 390 + 391 + int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, 392 + enum amdtp_stream_direction dir, 393 + const struct snd_motu_protocol *const protocol) 394 + { 395 + amdtp_stream_process_data_blocks_t process_data_blocks; 396 + int fmt = CIP_FMT_MOTU; 397 + int flags = CIP_BLOCKING; 398 + int err; 399 + 400 + if (dir == AMDTP_IN_STREAM) { 401 + process_data_blocks = process_tx_data_blocks; 402 + 403 + /* 404 + * Units of version 3 transmits packets with invalid CIP header 405 + * against IEC 61883-1. 406 + */ 407 + if (protocol == &snd_motu_protocol_v3) { 408 + flags |= CIP_WRONG_DBS | 409 + CIP_SKIP_DBC_ZERO_CHECK | 410 + CIP_HEADER_WITHOUT_EOH; 411 + fmt = CIP_FMT_MOTU_TX_V3; 412 + } 413 + } else { 414 + process_data_blocks = process_rx_data_blocks; 415 + flags |= CIP_DBC_IS_END_EVENT; 416 + } 417 + 418 + err = amdtp_stream_init(s, unit, dir, flags, fmt, process_data_blocks, 419 + sizeof(struct amdtp_motu)); 420 + if (err < 0) 421 + return err; 422 + 423 + s->sph = 1; 424 + s->fdf = MOTU_FDF_AM824; 425 + 426 + return 0; 427 + }
+198
sound/firewire/motu/motu-hwdep.c
···
··· 1 + /* 2 + * motu-hwdep.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + /* 10 + * This codes have five functionalities. 11 + * 12 + * 1.get information about firewire node 13 + * 2.get notification about starting/stopping stream 14 + * 3.lock/unlock streaming 15 + * 16 + */ 17 + 18 + #include "motu.h" 19 + 20 + static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, 21 + loff_t *offset) 22 + { 23 + struct snd_motu *motu = hwdep->private_data; 24 + DEFINE_WAIT(wait); 25 + union snd_firewire_event event; 26 + 27 + spin_lock_irq(&motu->lock); 28 + 29 + while (!motu->dev_lock_changed && motu->msg == 0) { 30 + prepare_to_wait(&motu->hwdep_wait, &wait, TASK_INTERRUPTIBLE); 31 + spin_unlock_irq(&motu->lock); 32 + schedule(); 33 + finish_wait(&motu->hwdep_wait, &wait); 34 + if (signal_pending(current)) 35 + return -ERESTARTSYS; 36 + spin_lock_irq(&motu->lock); 37 + } 38 + 39 + memset(&event, 0, sizeof(event)); 40 + if (motu->dev_lock_changed) { 41 + event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; 42 + event.lock_status.status = (motu->dev_lock_count > 0); 43 + motu->dev_lock_changed = false; 44 + 45 + count = min_t(long, count, sizeof(event.lock_status)); 46 + } else { 47 + event.motu_notification.type = SNDRV_FIREWIRE_EVENT_MOTU_NOTIFICATION; 48 + event.motu_notification.message = motu->msg; 49 + motu->msg = 0; 50 + 51 + count = min_t(long, count, sizeof(event.motu_notification)); 52 + } 53 + 54 + spin_unlock_irq(&motu->lock); 55 + 56 + if (copy_to_user(buf, &event, count)) 57 + return -EFAULT; 58 + 59 + return count; 60 + } 61 + 62 + static unsigned int hwdep_poll(struct snd_hwdep *hwdep, struct file *file, 63 + poll_table *wait) 64 + { 65 + struct snd_motu *motu = hwdep->private_data; 66 + unsigned int events; 67 + 68 + poll_wait(file, &motu->hwdep_wait, wait); 69 + 70 + spin_lock_irq(&motu->lock); 71 + if (motu->dev_lock_changed || motu->msg) 72 + events = POLLIN | POLLRDNORM; 73 + else 74 + events = 0; 75 + spin_unlock_irq(&motu->lock); 76 + 77 + return events | POLLOUT; 78 + } 79 + 80 + static int hwdep_get_info(struct snd_motu *motu, void __user *arg) 81 + { 82 + struct fw_device *dev = fw_parent_device(motu->unit); 83 + struct snd_firewire_get_info info; 84 + 85 + memset(&info, 0, sizeof(info)); 86 + info.type = SNDRV_FIREWIRE_TYPE_MOTU; 87 + info.card = dev->card->index; 88 + *(__be32 *)&info.guid[0] = cpu_to_be32(dev->config_rom[3]); 89 + *(__be32 *)&info.guid[4] = cpu_to_be32(dev->config_rom[4]); 90 + strlcpy(info.device_name, dev_name(&dev->device), 91 + sizeof(info.device_name)); 92 + 93 + if (copy_to_user(arg, &info, sizeof(info))) 94 + return -EFAULT; 95 + 96 + return 0; 97 + } 98 + 99 + static int hwdep_lock(struct snd_motu *motu) 100 + { 101 + int err; 102 + 103 + spin_lock_irq(&motu->lock); 104 + 105 + if (motu->dev_lock_count == 0) { 106 + motu->dev_lock_count = -1; 107 + err = 0; 108 + } else { 109 + err = -EBUSY; 110 + } 111 + 112 + spin_unlock_irq(&motu->lock); 113 + 114 + return err; 115 + } 116 + 117 + static int hwdep_unlock(struct snd_motu *motu) 118 + { 119 + int err; 120 + 121 + spin_lock_irq(&motu->lock); 122 + 123 + if (motu->dev_lock_count == -1) { 124 + motu->dev_lock_count = 0; 125 + err = 0; 126 + } else { 127 + err = -EBADFD; 128 + } 129 + 130 + spin_unlock_irq(&motu->lock); 131 + 132 + return err; 133 + } 134 + 135 + static int hwdep_release(struct snd_hwdep *hwdep, struct file *file) 136 + { 137 + struct snd_motu *motu = hwdep->private_data; 138 + 139 + spin_lock_irq(&motu->lock); 140 + if (motu->dev_lock_count == -1) 141 + motu->dev_lock_count = 0; 142 + spin_unlock_irq(&motu->lock); 143 + 144 + return 0; 145 + } 146 + 147 + static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, 148 + unsigned int cmd, unsigned long arg) 149 + { 150 + struct snd_motu *motu = hwdep->private_data; 151 + 152 + switch (cmd) { 153 + case SNDRV_FIREWIRE_IOCTL_GET_INFO: 154 + return hwdep_get_info(motu, (void __user *)arg); 155 + case SNDRV_FIREWIRE_IOCTL_LOCK: 156 + return hwdep_lock(motu); 157 + case SNDRV_FIREWIRE_IOCTL_UNLOCK: 158 + return hwdep_unlock(motu); 159 + default: 160 + return -ENOIOCTLCMD; 161 + } 162 + } 163 + 164 + #ifdef CONFIG_COMPAT 165 + static int hwdep_compat_ioctl(struct snd_hwdep *hwdep, struct file *file, 166 + unsigned int cmd, unsigned long arg) 167 + { 168 + return hwdep_ioctl(hwdep, file, cmd, 169 + (unsigned long)compat_ptr(arg)); 170 + } 171 + #else 172 + #define hwdep_compat_ioctl NULL 173 + #endif 174 + 175 + int snd_motu_create_hwdep_device(struct snd_motu *motu) 176 + { 177 + static const struct snd_hwdep_ops ops = { 178 + .read = hwdep_read, 179 + .release = hwdep_release, 180 + .poll = hwdep_poll, 181 + .ioctl = hwdep_ioctl, 182 + .ioctl_compat = hwdep_compat_ioctl, 183 + }; 184 + struct snd_hwdep *hwdep; 185 + int err; 186 + 187 + err = snd_hwdep_new(motu->card, motu->card->driver, 0, &hwdep); 188 + if (err < 0) 189 + return err; 190 + 191 + strcpy(hwdep->name, "MOTU"); 192 + hwdep->iface = SNDRV_HWDEP_IFACE_FW_MOTU; 193 + hwdep->ops = ops; 194 + hwdep->private_data = motu; 195 + hwdep->exclusive = true; 196 + 197 + return 0; 198 + }
+169
sound/firewire/motu/motu-midi.c
···
··· 1 + /* 2 + * motu-midi.h - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + #include "motu.h" 9 + 10 + static int midi_capture_open(struct snd_rawmidi_substream *substream) 11 + { 12 + struct snd_motu *motu = substream->rmidi->private_data; 13 + int err; 14 + 15 + err = snd_motu_stream_lock_try(motu); 16 + if (err < 0) 17 + return err; 18 + 19 + mutex_lock(&motu->mutex); 20 + 21 + motu->capture_substreams++; 22 + err = snd_motu_stream_start_duplex(motu, 0); 23 + 24 + mutex_unlock(&motu->mutex); 25 + 26 + if (err < 0) 27 + snd_motu_stream_lock_release(motu); 28 + 29 + return err; 30 + } 31 + 32 + static int midi_playback_open(struct snd_rawmidi_substream *substream) 33 + { 34 + struct snd_motu *motu = substream->rmidi->private_data; 35 + int err; 36 + 37 + err = snd_motu_stream_lock_try(motu); 38 + if (err < 0) 39 + return err; 40 + 41 + mutex_lock(&motu->mutex); 42 + 43 + motu->playback_substreams++; 44 + err = snd_motu_stream_start_duplex(motu, 0); 45 + 46 + mutex_unlock(&motu->mutex); 47 + 48 + if (err < 0) 49 + snd_motu_stream_lock_release(motu); 50 + 51 + return err; 52 + } 53 + 54 + static int midi_capture_close(struct snd_rawmidi_substream *substream) 55 + { 56 + struct snd_motu *motu = substream->rmidi->private_data; 57 + 58 + mutex_lock(&motu->mutex); 59 + 60 + motu->capture_substreams--; 61 + snd_motu_stream_stop_duplex(motu); 62 + 63 + mutex_unlock(&motu->mutex); 64 + 65 + snd_motu_stream_lock_release(motu); 66 + return 0; 67 + } 68 + 69 + static int midi_playback_close(struct snd_rawmidi_substream *substream) 70 + { 71 + struct snd_motu *motu = substream->rmidi->private_data; 72 + 73 + mutex_lock(&motu->mutex); 74 + 75 + motu->playback_substreams--; 76 + snd_motu_stream_stop_duplex(motu); 77 + 78 + mutex_unlock(&motu->mutex); 79 + 80 + snd_motu_stream_lock_release(motu); 81 + return 0; 82 + } 83 + 84 + static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) 85 + { 86 + struct snd_motu *motu = substrm->rmidi->private_data; 87 + unsigned long flags; 88 + 89 + spin_lock_irqsave(&motu->lock, flags); 90 + 91 + if (up) 92 + amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number, 93 + substrm); 94 + else 95 + amdtp_motu_midi_trigger(&motu->tx_stream, substrm->number, 96 + NULL); 97 + 98 + spin_unlock_irqrestore(&motu->lock, flags); 99 + } 100 + 101 + static void midi_playback_trigger(struct snd_rawmidi_substream *substrm, int up) 102 + { 103 + struct snd_motu *motu = substrm->rmidi->private_data; 104 + unsigned long flags; 105 + 106 + spin_lock_irqsave(&motu->lock, flags); 107 + 108 + if (up) 109 + amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number, 110 + substrm); 111 + else 112 + amdtp_motu_midi_trigger(&motu->rx_stream, substrm->number, 113 + NULL); 114 + 115 + spin_unlock_irqrestore(&motu->lock, flags); 116 + } 117 + 118 + static void set_midi_substream_names(struct snd_motu *motu, 119 + struct snd_rawmidi_str *str) 120 + { 121 + struct snd_rawmidi_substream *subs; 122 + 123 + list_for_each_entry(subs, &str->substreams, list) { 124 + snprintf(subs->name, sizeof(subs->name), 125 + "%s MIDI %d", motu->card->shortname, subs->number + 1); 126 + } 127 + } 128 + 129 + int snd_motu_create_midi_devices(struct snd_motu *motu) 130 + { 131 + static struct snd_rawmidi_ops capture_ops = { 132 + .open = midi_capture_open, 133 + .close = midi_capture_close, 134 + .trigger = midi_capture_trigger, 135 + }; 136 + static struct snd_rawmidi_ops playback_ops = { 137 + .open = midi_playback_open, 138 + .close = midi_playback_close, 139 + .trigger = midi_playback_trigger, 140 + }; 141 + struct snd_rawmidi *rmidi; 142 + struct snd_rawmidi_str *str; 143 + int err; 144 + 145 + /* create midi ports */ 146 + err = snd_rawmidi_new(motu->card, motu->card->driver, 0, 1, 1, &rmidi); 147 + if (err < 0) 148 + return err; 149 + 150 + snprintf(rmidi->name, sizeof(rmidi->name), 151 + "%s MIDI", motu->card->shortname); 152 + rmidi->private_data = motu; 153 + 154 + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT | 155 + SNDRV_RAWMIDI_INFO_OUTPUT | 156 + SNDRV_RAWMIDI_INFO_DUPLEX; 157 + 158 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, 159 + &capture_ops); 160 + str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]; 161 + set_midi_substream_names(motu, str); 162 + 163 + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 164 + &playback_ops); 165 + str = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT]; 166 + set_midi_substream_names(motu, str); 167 + 168 + return 0; 169 + }
+398
sound/firewire/motu/motu-pcm.c
···
··· 1 + /* 2 + * motu-pcm.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include <sound/pcm_params.h> 10 + #include "motu.h" 11 + 12 + static int motu_rate_constraint(struct snd_pcm_hw_params *params, 13 + struct snd_pcm_hw_rule *rule) 14 + { 15 + struct snd_motu_packet_format *formats = rule->private; 16 + 17 + const struct snd_interval *c = 18 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_CHANNELS); 19 + struct snd_interval *r = 20 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 21 + struct snd_interval rates = { 22 + .min = UINT_MAX, .max = 0, .integer = 1 23 + }; 24 + unsigned int i, pcm_channels, rate, mode; 25 + 26 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 27 + rate = snd_motu_clock_rates[i]; 28 + mode = i / 2; 29 + 30 + pcm_channels = formats->fixed_part_pcm_chunks[mode] + 31 + formats->differed_part_pcm_chunks[mode]; 32 + if (!snd_interval_test(c, pcm_channels)) 33 + continue; 34 + 35 + rates.min = min(rates.min, rate); 36 + rates.max = max(rates.max, rate); 37 + } 38 + 39 + return snd_interval_refine(r, &rates); 40 + } 41 + 42 + static int motu_channels_constraint(struct snd_pcm_hw_params *params, 43 + struct snd_pcm_hw_rule *rule) 44 + { 45 + struct snd_motu_packet_format *formats = rule->private; 46 + 47 + const struct snd_interval *r = 48 + hw_param_interval_c(params, SNDRV_PCM_HW_PARAM_RATE); 49 + struct snd_interval *c = 50 + hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 51 + struct snd_interval channels = { 52 + .min = UINT_MAX, .max = 0, .integer = 1 53 + }; 54 + unsigned int i, pcm_channels, rate, mode; 55 + 56 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 57 + rate = snd_motu_clock_rates[i]; 58 + mode = i / 2; 59 + 60 + if (!snd_interval_test(r, rate)) 61 + continue; 62 + 63 + pcm_channels = formats->fixed_part_pcm_chunks[mode] + 64 + formats->differed_part_pcm_chunks[mode]; 65 + channels.min = min(channels.min, pcm_channels); 66 + channels.max = max(channels.max, pcm_channels); 67 + } 68 + 69 + return snd_interval_refine(c, &channels); 70 + } 71 + 72 + static void limit_channels_and_rates(struct snd_motu *motu, 73 + struct snd_pcm_runtime *runtime, 74 + struct snd_motu_packet_format *formats) 75 + { 76 + struct snd_pcm_hardware *hw = &runtime->hw; 77 + unsigned int i, pcm_channels, rate, mode; 78 + 79 + hw->channels_min = UINT_MAX; 80 + hw->channels_max = 0; 81 + 82 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 83 + rate = snd_motu_clock_rates[i]; 84 + mode = i / 2; 85 + 86 + pcm_channels = formats->fixed_part_pcm_chunks[mode] + 87 + formats->differed_part_pcm_chunks[mode]; 88 + if (pcm_channels == 0) 89 + continue; 90 + 91 + hw->rates |= snd_pcm_rate_to_rate_bit(rate); 92 + hw->channels_min = min(hw->channels_min, pcm_channels); 93 + hw->channels_max = max(hw->channels_max, pcm_channels); 94 + } 95 + 96 + snd_pcm_limit_hw_rates(runtime); 97 + } 98 + 99 + static void limit_period_and_buffer(struct snd_pcm_hardware *hw) 100 + { 101 + hw->periods_min = 2; /* SNDRV_PCM_INFO_BATCH */ 102 + hw->periods_max = UINT_MAX; 103 + 104 + hw->period_bytes_min = 4 * hw->channels_max; /* byte for a frame */ 105 + 106 + /* Just to prevent from allocating much pages. */ 107 + hw->period_bytes_max = hw->period_bytes_min * 2048; 108 + hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; 109 + } 110 + 111 + static int init_hw_info(struct snd_motu *motu, 112 + struct snd_pcm_substream *substream) 113 + { 114 + struct snd_pcm_runtime *runtime = substream->runtime; 115 + struct snd_pcm_hardware *hw = &runtime->hw; 116 + struct amdtp_stream *stream; 117 + struct snd_motu_packet_format *formats; 118 + int err; 119 + 120 + hw->info = SNDRV_PCM_INFO_MMAP | 121 + SNDRV_PCM_INFO_MMAP_VALID | 122 + SNDRV_PCM_INFO_BATCH | 123 + SNDRV_PCM_INFO_INTERLEAVED | 124 + SNDRV_PCM_INFO_JOINT_DUPLEX | 125 + SNDRV_PCM_INFO_BLOCK_TRANSFER; 126 + 127 + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 128 + hw->formats = SNDRV_PCM_FMTBIT_S32; 129 + stream = &motu->tx_stream; 130 + formats = &motu->tx_packet_formats; 131 + } else { 132 + hw->formats = SNDRV_PCM_FMTBIT_S32; 133 + stream = &motu->rx_stream; 134 + formats = &motu->rx_packet_formats; 135 + } 136 + 137 + limit_channels_and_rates(motu, runtime, formats); 138 + limit_period_and_buffer(hw); 139 + 140 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 141 + motu_rate_constraint, formats, 142 + SNDRV_PCM_HW_PARAM_CHANNELS, -1); 143 + if (err < 0) 144 + return err; 145 + err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 146 + motu_channels_constraint, formats, 147 + SNDRV_PCM_HW_PARAM_RATE, -1); 148 + if (err < 0) 149 + return err; 150 + 151 + return amdtp_motu_add_pcm_hw_constraints(stream, runtime); 152 + } 153 + 154 + static int pcm_open(struct snd_pcm_substream *substream) 155 + { 156 + struct snd_motu *motu = substream->private_data; 157 + const struct snd_motu_protocol *const protocol = motu->spec->protocol; 158 + enum snd_motu_clock_source src; 159 + unsigned int rate; 160 + int err; 161 + 162 + err = snd_motu_stream_lock_try(motu); 163 + if (err < 0) 164 + return err; 165 + 166 + mutex_lock(&motu->mutex); 167 + 168 + err = protocol->cache_packet_formats(motu); 169 + if (err < 0) 170 + goto err_locked; 171 + 172 + err = init_hw_info(motu, substream); 173 + if (err < 0) 174 + goto err_locked; 175 + 176 + /* 177 + * When source of clock is not internal or any PCM streams are running, 178 + * available sampling rate is limited at current sampling rate. 179 + */ 180 + err = protocol->get_clock_source(motu, &src); 181 + if (err < 0) 182 + goto err_locked; 183 + if (src != SND_MOTU_CLOCK_SOURCE_INTERNAL || 184 + amdtp_stream_pcm_running(&motu->tx_stream) || 185 + amdtp_stream_pcm_running(&motu->rx_stream)) { 186 + err = protocol->get_clock_rate(motu, &rate); 187 + if (err < 0) 188 + goto err_locked; 189 + substream->runtime->hw.rate_min = rate; 190 + substream->runtime->hw.rate_max = rate; 191 + } 192 + 193 + snd_pcm_set_sync(substream); 194 + 195 + mutex_unlock(&motu->mutex); 196 + 197 + return err; 198 + err_locked: 199 + mutex_unlock(&motu->mutex); 200 + snd_motu_stream_lock_release(motu); 201 + return err; 202 + } 203 + 204 + static int pcm_close(struct snd_pcm_substream *substream) 205 + { 206 + struct snd_motu *motu = substream->private_data; 207 + 208 + snd_motu_stream_lock_release(motu); 209 + 210 + return 0; 211 + } 212 + 213 + static int capture_hw_params(struct snd_pcm_substream *substream, 214 + struct snd_pcm_hw_params *hw_params) 215 + { 216 + struct snd_motu *motu = substream->private_data; 217 + int err; 218 + 219 + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 220 + params_buffer_bytes(hw_params)); 221 + if (err < 0) 222 + return err; 223 + 224 + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 225 + mutex_lock(&motu->mutex); 226 + motu->capture_substreams++; 227 + mutex_unlock(&motu->mutex); 228 + } 229 + 230 + return 0; 231 + } 232 + static int playback_hw_params(struct snd_pcm_substream *substream, 233 + struct snd_pcm_hw_params *hw_params) 234 + { 235 + struct snd_motu *motu = substream->private_data; 236 + int err; 237 + 238 + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, 239 + params_buffer_bytes(hw_params)); 240 + if (err < 0) 241 + return err; 242 + 243 + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 244 + mutex_lock(&motu->mutex); 245 + motu->playback_substreams++; 246 + mutex_unlock(&motu->mutex); 247 + } 248 + 249 + return 0; 250 + } 251 + 252 + static int capture_hw_free(struct snd_pcm_substream *substream) 253 + { 254 + struct snd_motu *motu = substream->private_data; 255 + 256 + mutex_lock(&motu->mutex); 257 + 258 + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 259 + motu->capture_substreams--; 260 + 261 + snd_motu_stream_stop_duplex(motu); 262 + 263 + mutex_unlock(&motu->mutex); 264 + 265 + return snd_pcm_lib_free_vmalloc_buffer(substream); 266 + } 267 + 268 + static int playback_hw_free(struct snd_pcm_substream *substream) 269 + { 270 + struct snd_motu *motu = substream->private_data; 271 + 272 + mutex_lock(&motu->mutex); 273 + 274 + if (substream->runtime->status->state != SNDRV_PCM_STATE_OPEN) 275 + motu->playback_substreams--; 276 + 277 + snd_motu_stream_stop_duplex(motu); 278 + 279 + mutex_unlock(&motu->mutex); 280 + 281 + return snd_pcm_lib_free_vmalloc_buffer(substream); 282 + } 283 + 284 + static int capture_prepare(struct snd_pcm_substream *substream) 285 + { 286 + struct snd_motu *motu = substream->private_data; 287 + int err; 288 + 289 + mutex_lock(&motu->mutex); 290 + err = snd_motu_stream_start_duplex(motu, substream->runtime->rate); 291 + mutex_unlock(&motu->mutex); 292 + if (err >= 0) 293 + amdtp_stream_pcm_prepare(&motu->tx_stream); 294 + 295 + return 0; 296 + } 297 + static int playback_prepare(struct snd_pcm_substream *substream) 298 + { 299 + struct snd_motu *motu = substream->private_data; 300 + int err; 301 + 302 + mutex_lock(&motu->mutex); 303 + err = snd_motu_stream_start_duplex(motu, substream->runtime->rate); 304 + mutex_unlock(&motu->mutex); 305 + if (err >= 0) 306 + amdtp_stream_pcm_prepare(&motu->rx_stream); 307 + 308 + return err; 309 + } 310 + 311 + static int capture_trigger(struct snd_pcm_substream *substream, int cmd) 312 + { 313 + struct snd_motu *motu = substream->private_data; 314 + 315 + switch (cmd) { 316 + case SNDRV_PCM_TRIGGER_START: 317 + amdtp_stream_pcm_trigger(&motu->tx_stream, substream); 318 + break; 319 + case SNDRV_PCM_TRIGGER_STOP: 320 + amdtp_stream_pcm_trigger(&motu->tx_stream, NULL); 321 + break; 322 + default: 323 + return -EINVAL; 324 + } 325 + 326 + return 0; 327 + } 328 + static int playback_trigger(struct snd_pcm_substream *substream, int cmd) 329 + { 330 + struct snd_motu *motu = substream->private_data; 331 + 332 + switch (cmd) { 333 + case SNDRV_PCM_TRIGGER_START: 334 + amdtp_stream_pcm_trigger(&motu->rx_stream, substream); 335 + break; 336 + case SNDRV_PCM_TRIGGER_STOP: 337 + amdtp_stream_pcm_trigger(&motu->rx_stream, NULL); 338 + break; 339 + default: 340 + return -EINVAL; 341 + } 342 + 343 + return 0; 344 + } 345 + 346 + static snd_pcm_uframes_t capture_pointer(struct snd_pcm_substream *substream) 347 + { 348 + struct snd_motu *motu = substream->private_data; 349 + 350 + return amdtp_stream_pcm_pointer(&motu->tx_stream); 351 + } 352 + static snd_pcm_uframes_t playback_pointer(struct snd_pcm_substream *substream) 353 + { 354 + struct snd_motu *motu = substream->private_data; 355 + 356 + return amdtp_stream_pcm_pointer(&motu->rx_stream); 357 + } 358 + 359 + int snd_motu_create_pcm_devices(struct snd_motu *motu) 360 + { 361 + static struct snd_pcm_ops capture_ops = { 362 + .open = pcm_open, 363 + .close = pcm_close, 364 + .ioctl = snd_pcm_lib_ioctl, 365 + .hw_params = capture_hw_params, 366 + .hw_free = capture_hw_free, 367 + .prepare = capture_prepare, 368 + .trigger = capture_trigger, 369 + .pointer = capture_pointer, 370 + .page = snd_pcm_lib_get_vmalloc_page, 371 + .mmap = snd_pcm_lib_mmap_vmalloc, 372 + }; 373 + static struct snd_pcm_ops playback_ops = { 374 + .open = pcm_open, 375 + .close = pcm_close, 376 + .ioctl = snd_pcm_lib_ioctl, 377 + .hw_params = playback_hw_params, 378 + .hw_free = playback_hw_free, 379 + .prepare = playback_prepare, 380 + .trigger = playback_trigger, 381 + .pointer = playback_pointer, 382 + .page = snd_pcm_lib_get_vmalloc_page, 383 + .mmap = snd_pcm_lib_mmap_vmalloc, 384 + }; 385 + struct snd_pcm *pcm; 386 + int err; 387 + 388 + err = snd_pcm_new(motu->card, motu->card->driver, 0, 1, 1, &pcm); 389 + if (err < 0) 390 + return err; 391 + pcm->private_data = motu; 392 + strcpy(pcm->name, motu->card->shortname); 393 + 394 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops); 395 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); 396 + 397 + return 0; 398 + }
+118
sound/firewire/motu/motu-proc.c
···
··· 1 + /* 2 + * motu-proc.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "./motu.h" 10 + 11 + static const char *const clock_names[] = { 12 + [SND_MOTU_CLOCK_SOURCE_INTERNAL] = "Internal", 13 + [SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB] = "ADAT on Dsub-9pin interface", 14 + [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT] = "ADAT on optical interface", 15 + [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A] = "ADAT on optical interface A", 16 + [SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B] = "ADAT on optical interface B", 17 + [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT] = "S/PDIF on optical interface", 18 + [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A] = "S/PDIF on optical interface A", 19 + [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B] = "S/PDIF on optical interface B", 20 + [SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX] = "S/PCIF on coaxial interface", 21 + [SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR] = "AESEBU on XLR interface", 22 + [SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC] = "Word clock on BNC interface", 23 + }; 24 + 25 + static void proc_read_clock(struct snd_info_entry *entry, 26 + struct snd_info_buffer *buffer) 27 + { 28 + 29 + struct snd_motu *motu = entry->private_data; 30 + const struct snd_motu_protocol *const protocol = motu->spec->protocol; 31 + unsigned int rate; 32 + enum snd_motu_clock_source source; 33 + 34 + if (protocol->get_clock_rate(motu, &rate) < 0) 35 + return; 36 + if (protocol->get_clock_source(motu, &source) < 0) 37 + return; 38 + 39 + snd_iprintf(buffer, "Rate:\t%d\n", rate); 40 + snd_iprintf(buffer, "Source:\t%s\n", clock_names[source]); 41 + } 42 + 43 + static void proc_read_format(struct snd_info_entry *entry, 44 + struct snd_info_buffer *buffer) 45 + { 46 + struct snd_motu *motu = entry->private_data; 47 + const struct snd_motu_protocol *const protocol = motu->spec->protocol; 48 + unsigned int mode; 49 + struct snd_motu_packet_format *formats; 50 + int i; 51 + 52 + if (protocol->cache_packet_formats(motu) < 0) 53 + return; 54 + 55 + snd_iprintf(buffer, "tx:\tmsg\tfixed\tdiffered\n"); 56 + for (i = 0; i < SND_MOTU_CLOCK_RATE_COUNT; ++i) { 57 + mode = i >> 1; 58 + 59 + formats = &motu->tx_packet_formats; 60 + snd_iprintf(buffer, 61 + "%u:\t%u\t%u\t%u\n", 62 + snd_motu_clock_rates[i], 63 + formats->msg_chunks, 64 + formats->fixed_part_pcm_chunks[mode], 65 + formats->differed_part_pcm_chunks[mode]); 66 + } 67 + 68 + snd_iprintf(buffer, "rx:\tmsg\tfixed\tdiffered\n"); 69 + for (i = 0; i < SND_MOTU_CLOCK_RATE_COUNT; ++i) { 70 + mode = i >> 1; 71 + 72 + formats = &motu->rx_packet_formats; 73 + snd_iprintf(buffer, 74 + "%u:\t%u\t%u\t%u\n", 75 + snd_motu_clock_rates[i], 76 + formats->msg_chunks, 77 + formats->fixed_part_pcm_chunks[mode], 78 + formats->differed_part_pcm_chunks[mode]); 79 + } 80 + } 81 + 82 + static void add_node(struct snd_motu *motu, struct snd_info_entry *root, 83 + const char *name, 84 + void (*op)(struct snd_info_entry *e, 85 + struct snd_info_buffer *b)) 86 + { 87 + struct snd_info_entry *entry; 88 + 89 + entry = snd_info_create_card_entry(motu->card, name, root); 90 + if (entry == NULL) 91 + return; 92 + 93 + snd_info_set_text_ops(entry, motu, op); 94 + if (snd_info_register(entry) < 0) 95 + snd_info_free_entry(entry); 96 + } 97 + 98 + void snd_motu_proc_init(struct snd_motu *motu) 99 + { 100 + struct snd_info_entry *root; 101 + 102 + /* 103 + * All nodes are automatically removed at snd_card_disconnect(), 104 + * by following to link list. 105 + */ 106 + root = snd_info_create_card_entry(motu->card, "firewire", 107 + motu->card->proc_root); 108 + if (root == NULL) 109 + return; 110 + root->mode = S_IFDIR | S_IRUGO | S_IXUGO; 111 + if (snd_info_register(root) < 0) { 112 + snd_info_free_entry(root); 113 + return; 114 + } 115 + 116 + add_node(motu, root, "clock", proc_read_clock); 117 + add_node(motu, root, "format", proc_read_format); 118 + }
+237
sound/firewire/motu/motu-protocol-v2.c
···
··· 1 + /* 2 + * motu-protocol-v2.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "motu.h" 10 + 11 + #define V2_CLOCK_STATUS_OFFSET 0x0b14 12 + #define V2_CLOCK_RATE_MASK 0x00000038 13 + #define V2_CLOCK_RATE_SHIFT 3 14 + #define V2_CLOCK_SRC_MASK 0x00000007 15 + #define V2_CLOCK_SRC_SHIFT 0 16 + 17 + #define V2_IN_OUT_CONF_OFFSET 0x0c04 18 + #define V2_OPT_OUT_IFACE_MASK 0x00000c00 19 + #define V2_OPT_OUT_IFACE_SHIFT 10 20 + #define V2_OPT_IN_IFACE_MASK 0x00000300 21 + #define V2_OPT_IN_IFACE_SHIFT 8 22 + #define V2_OPT_IFACE_MODE_NONE 0 23 + #define V2_OPT_IFACE_MODE_ADAT 1 24 + #define V2_OPT_IFACE_MODE_SPDIF 2 25 + 26 + static int v2_get_clock_rate(struct snd_motu *motu, unsigned int *rate) 27 + { 28 + __be32 reg; 29 + unsigned int index; 30 + int err; 31 + 32 + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg, 33 + sizeof(reg)); 34 + if (err < 0) 35 + return err; 36 + 37 + index = (be32_to_cpu(reg) & V2_CLOCK_RATE_MASK) >> V2_CLOCK_RATE_SHIFT; 38 + if (index >= ARRAY_SIZE(snd_motu_clock_rates)) 39 + return -EIO; 40 + 41 + *rate = snd_motu_clock_rates[index]; 42 + 43 + return 0; 44 + } 45 + 46 + static int v2_set_clock_rate(struct snd_motu *motu, unsigned int rate) 47 + { 48 + __be32 reg; 49 + u32 data; 50 + int i; 51 + int err; 52 + 53 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 54 + if (snd_motu_clock_rates[i] == rate) 55 + break; 56 + } 57 + if (i == ARRAY_SIZE(snd_motu_clock_rates)) 58 + return -EINVAL; 59 + 60 + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg, 61 + sizeof(reg)); 62 + if (err < 0) 63 + return err; 64 + data = be32_to_cpu(reg); 65 + 66 + data &= ~V2_CLOCK_RATE_MASK; 67 + data |= i << V2_CLOCK_RATE_SHIFT; 68 + 69 + reg = cpu_to_be32(data); 70 + return snd_motu_transaction_write(motu, V2_CLOCK_STATUS_OFFSET, &reg, 71 + sizeof(reg)); 72 + } 73 + 74 + static int v2_get_clock_source(struct snd_motu *motu, 75 + enum snd_motu_clock_source *src) 76 + { 77 + __be32 reg; 78 + unsigned int index; 79 + int err; 80 + 81 + err = snd_motu_transaction_read(motu, V2_CLOCK_STATUS_OFFSET, &reg, 82 + sizeof(reg)); 83 + if (err < 0) 84 + return err; 85 + 86 + index = be32_to_cpu(reg) & V2_CLOCK_SRC_MASK; 87 + if (index > 5) 88 + return -EIO; 89 + 90 + /* To check the configuration of optical interface. */ 91 + err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg, 92 + sizeof(reg)); 93 + if (err < 0) 94 + return err; 95 + 96 + switch (index) { 97 + case 0: 98 + *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; 99 + break; 100 + case 1: 101 + if (be32_to_cpu(reg) & 0x00000200) 102 + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT; 103 + else 104 + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT; 105 + break; 106 + case 2: 107 + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; 108 + break; 109 + case 4: 110 + *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; 111 + break; 112 + case 5: 113 + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB; 114 + break; 115 + default: 116 + return -EIO; 117 + } 118 + 119 + return 0; 120 + } 121 + 122 + static int v2_switch_fetching_mode(struct snd_motu *motu, bool enable) 123 + { 124 + /* V2 protocol doesn't have this feature. */ 125 + return 0; 126 + } 127 + 128 + static void calculate_fixed_part(struct snd_motu_packet_format *formats, 129 + enum amdtp_stream_direction dir, 130 + enum snd_motu_spec_flags flags, 131 + unsigned char analog_ports) 132 + { 133 + unsigned char pcm_chunks[3] = {0, 0, 0}; 134 + 135 + formats->msg_chunks = 2; 136 + 137 + pcm_chunks[0] = analog_ports; 138 + pcm_chunks[1] = analog_ports; 139 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 140 + pcm_chunks[2] = analog_ports; 141 + 142 + if (dir == AMDTP_IN_STREAM) { 143 + if (flags & SND_MOTU_SPEC_TX_MICINST_CHUNK) { 144 + pcm_chunks[0] += 2; 145 + pcm_chunks[1] += 2; 146 + } 147 + if (flags & SND_MOTU_SPEC_TX_RETURN_CHUNK) { 148 + pcm_chunks[0] += 2; 149 + pcm_chunks[1] += 2; 150 + } 151 + } else { 152 + /* 153 + * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. 154 + */ 155 + pcm_chunks[0] += 4; 156 + pcm_chunks[1] += 4; 157 + } 158 + 159 + /* 160 + * All of v2 models have a pair of coaxial interfaces for digital in/out 161 + * port. At 44.1/48.0/88.2/96.0 kHz, packets includes PCM from these 162 + * ports. 163 + */ 164 + pcm_chunks[0] += 2; 165 + pcm_chunks[1] += 2; 166 + 167 + /* This part should be multiples of 4. */ 168 + formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2; 169 + formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2; 170 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 171 + formats->fixed_part_pcm_chunks[2] = 172 + round_up(2 + pcm_chunks[2], 4) - 2; 173 + } 174 + 175 + static void calculate_differed_part(struct snd_motu_packet_format *formats, 176 + enum snd_motu_spec_flags flags, 177 + u32 data, u32 mask, u32 shift) 178 + { 179 + unsigned char pcm_chunks[3] = {0, 0}; 180 + 181 + /* 182 + * When optical interfaces are configured for S/PDIF (TOSLINK), 183 + * the above PCM frames come from them, instead of coaxial 184 + * interfaces. 185 + */ 186 + data = (data & mask) >> shift; 187 + if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_A) && 188 + data == V2_OPT_IFACE_MODE_ADAT) { 189 + pcm_chunks[0] += 8; 190 + pcm_chunks[1] += 4; 191 + } 192 + 193 + /* At mode x4, no data chunks are supported in this part. */ 194 + formats->differed_part_pcm_chunks[0] = pcm_chunks[0]; 195 + formats->differed_part_pcm_chunks[1] = pcm_chunks[1]; 196 + } 197 + 198 + static int v2_cache_packet_formats(struct snd_motu *motu) 199 + { 200 + __be32 reg; 201 + u32 data; 202 + int err; 203 + 204 + err = snd_motu_transaction_read(motu, V2_IN_OUT_CONF_OFFSET, &reg, 205 + sizeof(reg)); 206 + if (err < 0) 207 + return err; 208 + data = be32_to_cpu(reg); 209 + 210 + calculate_fixed_part(&motu->tx_packet_formats, AMDTP_IN_STREAM, 211 + motu->spec->flags, motu->spec->analog_in_ports); 212 + calculate_differed_part(&motu->tx_packet_formats, motu->spec->flags, 213 + data, V2_OPT_IN_IFACE_MASK, V2_OPT_IN_IFACE_SHIFT); 214 + 215 + calculate_fixed_part(&motu->rx_packet_formats, AMDTP_OUT_STREAM, 216 + motu->spec->flags, motu->spec->analog_out_ports); 217 + calculate_differed_part(&motu->rx_packet_formats, motu->spec->flags, 218 + data, V2_OPT_OUT_IFACE_MASK, V2_OPT_OUT_IFACE_SHIFT); 219 + 220 + motu->tx_packet_formats.midi_flag_offset = 4; 221 + motu->tx_packet_formats.midi_byte_offset = 6; 222 + motu->tx_packet_formats.pcm_byte_offset = 10; 223 + 224 + motu->rx_packet_formats.midi_flag_offset = 4; 225 + motu->rx_packet_formats.midi_byte_offset = 6; 226 + motu->rx_packet_formats.pcm_byte_offset = 10; 227 + 228 + return 0; 229 + } 230 + 231 + const struct snd_motu_protocol snd_motu_protocol_v2 = { 232 + .get_clock_rate = v2_get_clock_rate, 233 + .set_clock_rate = v2_set_clock_rate, 234 + .get_clock_source = v2_get_clock_source, 235 + .switch_fetching_mode = v2_switch_fetching_mode, 236 + .cache_packet_formats = v2_cache_packet_formats, 237 + };
+311
sound/firewire/motu/motu-protocol-v3.c
···
··· 1 + /* 2 + * motu-protocol-v3.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include <linux/delay.h> 10 + #include "motu.h" 11 + 12 + #define V3_CLOCK_STATUS_OFFSET 0x0b14 13 + #define V3_FETCH_PCM_FRAMES 0x02000000 14 + #define V3_CLOCK_RATE_MASK 0x0000ff00 15 + #define V3_CLOCK_RATE_SHIFT 8 16 + #define V3_CLOCK_SOURCE_MASK 0x000000ff 17 + 18 + #define V3_OPT_IFACE_MODE_OFFSET 0x0c94 19 + #define V3_ENABLE_OPT_IN_IFACE_A 0x00000001 20 + #define V3_ENABLE_OPT_IN_IFACE_B 0x00000002 21 + #define V3_ENABLE_OPT_OUT_IFACE_A 0x00000100 22 + #define V3_ENABLE_OPT_OUT_IFACE_B 0x00000200 23 + #define V3_NO_ADAT_OPT_IN_IFACE_A 0x00010000 24 + #define V3_NO_ADAT_OPT_IN_IFACE_B 0x00100000 25 + #define V3_NO_ADAT_OPT_OUT_IFACE_A 0x00040000 26 + #define V3_NO_ADAT_OPT_OUT_IFACE_B 0x00400000 27 + 28 + static int v3_get_clock_rate(struct snd_motu *motu, unsigned int *rate) 29 + { 30 + __be32 reg; 31 + u32 data; 32 + int err; 33 + 34 + err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg, 35 + sizeof(reg)); 36 + if (err < 0) 37 + return err; 38 + data = be32_to_cpu(reg); 39 + 40 + data = (data & V3_CLOCK_RATE_MASK) >> V3_CLOCK_RATE_SHIFT; 41 + if (data >= ARRAY_SIZE(snd_motu_clock_rates)) 42 + return -EIO; 43 + 44 + *rate = snd_motu_clock_rates[data]; 45 + 46 + return 0; 47 + } 48 + 49 + static int v3_set_clock_rate(struct snd_motu *motu, unsigned int rate) 50 + { 51 + __be32 reg; 52 + u32 data; 53 + bool need_to_wait; 54 + int i, err; 55 + 56 + for (i = 0; i < ARRAY_SIZE(snd_motu_clock_rates); ++i) { 57 + if (snd_motu_clock_rates[i] == rate) 58 + break; 59 + } 60 + if (i == ARRAY_SIZE(snd_motu_clock_rates)) 61 + return -EINVAL; 62 + 63 + err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg, 64 + sizeof(reg)); 65 + if (err < 0) 66 + return err; 67 + data = be32_to_cpu(reg); 68 + 69 + data &= ~(V3_CLOCK_RATE_MASK | V3_FETCH_PCM_FRAMES); 70 + data |= i << V3_CLOCK_RATE_SHIFT; 71 + 72 + need_to_wait = data != be32_to_cpu(reg); 73 + 74 + reg = cpu_to_be32(data); 75 + err = snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg, 76 + sizeof(reg)); 77 + if (err < 0) 78 + return err; 79 + 80 + if (need_to_wait) { 81 + /* Cost expensive. */ 82 + if (msleep_interruptible(4000) > 0) 83 + return -EINTR; 84 + } 85 + 86 + return 0; 87 + } 88 + 89 + static int v3_get_clock_source(struct snd_motu *motu, 90 + enum snd_motu_clock_source *src) 91 + { 92 + __be32 reg; 93 + u32 data; 94 + unsigned int val; 95 + int err; 96 + 97 + err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg, 98 + sizeof(reg)); 99 + if (err < 0) 100 + return err; 101 + data = be32_to_cpu(reg); 102 + 103 + val = data & V3_CLOCK_SOURCE_MASK; 104 + if (val == 0x00) { 105 + *src = SND_MOTU_CLOCK_SOURCE_INTERNAL; 106 + } else if (val == 0x01) { 107 + *src = SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC; 108 + } else if (val == 0x10) { 109 + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX; 110 + } else if (val == 0x18 || val == 0x19) { 111 + err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET, 112 + &reg, sizeof(reg)); 113 + if (err < 0) 114 + return err; 115 + data = be32_to_cpu(reg); 116 + 117 + if (val == 0x18) { 118 + if (data & V3_NO_ADAT_OPT_IN_IFACE_A) 119 + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A; 120 + else 121 + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A; 122 + } else { 123 + if (data & V3_NO_ADAT_OPT_IN_IFACE_B) 124 + *src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B; 125 + else 126 + *src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B; 127 + } 128 + } else { 129 + *src = SND_MOTU_CLOCK_SOURCE_UNKNOWN; 130 + } 131 + 132 + return 0; 133 + } 134 + 135 + static int v3_switch_fetching_mode(struct snd_motu *motu, bool enable) 136 + { 137 + __be32 reg; 138 + u32 data; 139 + int err; 140 + 141 + err = snd_motu_transaction_read(motu, V3_CLOCK_STATUS_OFFSET, &reg, 142 + sizeof(reg)); 143 + if (err < 0) 144 + return 0; 145 + data = be32_to_cpu(reg); 146 + 147 + if (enable) 148 + data |= V3_FETCH_PCM_FRAMES; 149 + else 150 + data &= ~V3_FETCH_PCM_FRAMES; 151 + 152 + reg = cpu_to_be32(data); 153 + return snd_motu_transaction_write(motu, V3_CLOCK_STATUS_OFFSET, &reg, 154 + sizeof(reg)); 155 + } 156 + 157 + static void calculate_fixed_part(struct snd_motu_packet_format *formats, 158 + enum amdtp_stream_direction dir, 159 + enum snd_motu_spec_flags flags, 160 + unsigned char analog_ports) 161 + { 162 + unsigned char pcm_chunks[3] = {0, 0, 0}; 163 + 164 + formats->msg_chunks = 2; 165 + 166 + pcm_chunks[0] = analog_ports; 167 + pcm_chunks[1] = analog_ports; 168 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 169 + pcm_chunks[2] = analog_ports; 170 + 171 + if (dir == AMDTP_IN_STREAM) { 172 + if (flags & SND_MOTU_SPEC_TX_MICINST_CHUNK) { 173 + pcm_chunks[0] += 2; 174 + pcm_chunks[1] += 2; 175 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 176 + pcm_chunks[2] += 2; 177 + } 178 + 179 + if (flags & SND_MOTU_SPEC_TX_RETURN_CHUNK) { 180 + pcm_chunks[0] += 2; 181 + pcm_chunks[1] += 2; 182 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 183 + pcm_chunks[2] += 2; 184 + } 185 + 186 + if (flags & SND_MOTU_SPEC_TX_REVERB_CHUNK) { 187 + pcm_chunks[0] += 2; 188 + pcm_chunks[1] += 2; 189 + } 190 + } else { 191 + /* 192 + * Packets to v2 units transfer main-out-1/2 and phone-out-1/2. 193 + */ 194 + pcm_chunks[0] += 4; 195 + pcm_chunks[1] += 4; 196 + } 197 + 198 + /* 199 + * At least, packets have two data chunks for S/PDIF on coaxial 200 + * interface. 201 + */ 202 + pcm_chunks[0] += 2; 203 + pcm_chunks[1] += 2; 204 + 205 + /* 206 + * Fixed part consists of PCM chunks multiple of 4, with msg chunks. As 207 + * a result, this part can includes empty data chunks. 208 + */ 209 + formats->fixed_part_pcm_chunks[0] = round_up(2 + pcm_chunks[0], 4) - 2; 210 + formats->fixed_part_pcm_chunks[1] = round_up(2 + pcm_chunks[1], 4) - 2; 211 + if (flags & SND_MOTU_SPEC_SUPPORT_CLOCK_X4) 212 + formats->fixed_part_pcm_chunks[2] = 213 + round_up(2 + pcm_chunks[2], 4) - 2; 214 + } 215 + 216 + static void calculate_differed_part(struct snd_motu_packet_format *formats, 217 + enum snd_motu_spec_flags flags, u32 data, 218 + u32 a_enable_mask, u32 a_no_adat_mask, 219 + u32 b_enable_mask, u32 b_no_adat_mask) 220 + { 221 + unsigned char pcm_chunks[3] = {0, 0, 0}; 222 + int i; 223 + 224 + if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_A) && (data & a_enable_mask)) { 225 + if (data & a_no_adat_mask) { 226 + /* 227 + * Additional two data chunks for S/PDIF on optical 228 + * interface A. This includes empty data chunks. 229 + */ 230 + pcm_chunks[0] += 4; 231 + pcm_chunks[1] += 4; 232 + } else { 233 + /* 234 + * Additional data chunks for ADAT on optical interface 235 + * A. 236 + */ 237 + pcm_chunks[0] += 8; 238 + pcm_chunks[1] += 4; 239 + } 240 + } 241 + 242 + if ((flags & SND_MOTU_SPEC_HAS_OPT_IFACE_B) && (data & b_enable_mask)) { 243 + if (data & b_no_adat_mask) { 244 + /* 245 + * Additional two data chunks for S/PDIF on optical 246 + * interface B. This includes empty data chunks. 247 + */ 248 + pcm_chunks[0] += 4; 249 + pcm_chunks[1] += 4; 250 + } else { 251 + /* 252 + * Additional data chunks for ADAT on optical interface 253 + * B. 254 + */ 255 + pcm_chunks[0] += 8; 256 + pcm_chunks[1] += 4; 257 + } 258 + } 259 + 260 + for (i = 0; i < 3; ++i) { 261 + if (pcm_chunks[i] > 0) 262 + pcm_chunks[i] = round_up(pcm_chunks[i], 4); 263 + 264 + formats->differed_part_pcm_chunks[i] = pcm_chunks[i]; 265 + } 266 + } 267 + 268 + static int v3_cache_packet_formats(struct snd_motu *motu) 269 + { 270 + __be32 reg; 271 + u32 data; 272 + int err; 273 + 274 + err = snd_motu_transaction_read(motu, V3_OPT_IFACE_MODE_OFFSET, &reg, 275 + sizeof(reg)); 276 + if (err < 0) 277 + return err; 278 + data = be32_to_cpu(reg); 279 + 280 + calculate_fixed_part(&motu->tx_packet_formats, AMDTP_IN_STREAM, 281 + motu->spec->flags, motu->spec->analog_in_ports); 282 + calculate_differed_part(&motu->tx_packet_formats, 283 + motu->spec->flags, data, 284 + V3_ENABLE_OPT_IN_IFACE_A, V3_NO_ADAT_OPT_IN_IFACE_A, 285 + V3_ENABLE_OPT_IN_IFACE_B, V3_NO_ADAT_OPT_IN_IFACE_B); 286 + 287 + calculate_fixed_part(&motu->rx_packet_formats, AMDTP_OUT_STREAM, 288 + motu->spec->flags, motu->spec->analog_out_ports); 289 + calculate_differed_part(&motu->rx_packet_formats, 290 + motu->spec->flags, data, 291 + V3_ENABLE_OPT_OUT_IFACE_A, V3_NO_ADAT_OPT_OUT_IFACE_A, 292 + V3_ENABLE_OPT_OUT_IFACE_B, V3_NO_ADAT_OPT_OUT_IFACE_B); 293 + 294 + motu->tx_packet_formats.midi_flag_offset = 8; 295 + motu->tx_packet_formats.midi_byte_offset = 7; 296 + motu->tx_packet_formats.pcm_byte_offset = 10; 297 + 298 + motu->rx_packet_formats.midi_flag_offset = 8; 299 + motu->rx_packet_formats.midi_byte_offset = 7; 300 + motu->rx_packet_formats.pcm_byte_offset = 10; 301 + 302 + return 0; 303 + } 304 + 305 + const struct snd_motu_protocol snd_motu_protocol_v3 = { 306 + .get_clock_rate = v3_get_clock_rate, 307 + .set_clock_rate = v3_set_clock_rate, 308 + .get_clock_source = v3_get_clock_source, 309 + .switch_fetching_mode = v3_switch_fetching_mode, 310 + .cache_packet_formats = v3_cache_packet_formats, 311 + };
+381
sound/firewire/motu/motu-stream.c
···
··· 1 + /* 2 + * motu-stream.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "motu.h" 10 + 11 + #define CALLBACK_TIMEOUT 200 12 + 13 + #define ISOC_COMM_CONTROL_OFFSET 0x0b00 14 + #define ISOC_COMM_CONTROL_MASK 0xffff0000 15 + #define CHANGE_RX_ISOC_COMM_STATE 0x80000000 16 + #define RX_ISOC_COMM_IS_ACTIVATED 0x40000000 17 + #define RX_ISOC_COMM_CHANNEL_MASK 0x3f000000 18 + #define RX_ISOC_COMM_CHANNEL_SHIFT 24 19 + #define CHANGE_TX_ISOC_COMM_STATE 0x00800000 20 + #define TX_ISOC_COMM_IS_ACTIVATED 0x00400000 21 + #define TX_ISOC_COMM_CHANNEL_MASK 0x003f0000 22 + #define TX_ISOC_COMM_CHANNEL_SHIFT 16 23 + 24 + #define PACKET_FORMAT_OFFSET 0x0b10 25 + #define TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000080 26 + #define RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS 0x00000040 27 + #define TX_PACKET_TRANSMISSION_SPEED_MASK 0x0000000f 28 + 29 + static int start_both_streams(struct snd_motu *motu, unsigned int rate) 30 + { 31 + unsigned int midi_ports = 0; 32 + __be32 reg; 33 + u32 data; 34 + int err; 35 + 36 + if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) 37 + midi_ports = 1; 38 + 39 + /* Set packet formation to our packet streaming engine. */ 40 + err = amdtp_motu_set_parameters(&motu->rx_stream, rate, midi_ports, 41 + &motu->rx_packet_formats); 42 + if (err < 0) 43 + return err; 44 + 45 + err = amdtp_motu_set_parameters(&motu->tx_stream, rate, midi_ports, 46 + &motu->tx_packet_formats); 47 + if (err < 0) 48 + return err; 49 + 50 + /* Get isochronous resources on the bus. */ 51 + err = fw_iso_resources_allocate(&motu->rx_resources, 52 + amdtp_stream_get_max_payload(&motu->rx_stream), 53 + fw_parent_device(motu->unit)->max_speed); 54 + if (err < 0) 55 + return err; 56 + 57 + err = fw_iso_resources_allocate(&motu->tx_resources, 58 + amdtp_stream_get_max_payload(&motu->tx_stream), 59 + fw_parent_device(motu->unit)->max_speed); 60 + if (err < 0) 61 + return err; 62 + 63 + /* Configure the unit to start isochronous communication. */ 64 + err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg, 65 + sizeof(reg)); 66 + if (err < 0) 67 + return err; 68 + data = be32_to_cpu(reg) & ~ISOC_COMM_CONTROL_MASK; 69 + 70 + data |= CHANGE_RX_ISOC_COMM_STATE | RX_ISOC_COMM_IS_ACTIVATED | 71 + (motu->rx_resources.channel << RX_ISOC_COMM_CHANNEL_SHIFT) | 72 + CHANGE_TX_ISOC_COMM_STATE | TX_ISOC_COMM_IS_ACTIVATED | 73 + (motu->tx_resources.channel << TX_ISOC_COMM_CHANNEL_SHIFT); 74 + 75 + reg = cpu_to_be32(data); 76 + return snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg, 77 + sizeof(reg)); 78 + } 79 + 80 + static void stop_both_streams(struct snd_motu *motu) 81 + { 82 + __be32 reg; 83 + u32 data; 84 + int err; 85 + 86 + err = motu->spec->protocol->switch_fetching_mode(motu, false); 87 + if (err < 0) 88 + return; 89 + 90 + err = snd_motu_transaction_read(motu, ISOC_COMM_CONTROL_OFFSET, &reg, 91 + sizeof(reg)); 92 + if (err < 0) 93 + return; 94 + data = be32_to_cpu(reg); 95 + 96 + data &= ~(RX_ISOC_COMM_IS_ACTIVATED | TX_ISOC_COMM_IS_ACTIVATED); 97 + data |= CHANGE_RX_ISOC_COMM_STATE | CHANGE_TX_ISOC_COMM_STATE; 98 + 99 + reg = cpu_to_be32(data); 100 + snd_motu_transaction_write(motu, ISOC_COMM_CONTROL_OFFSET, &reg, 101 + sizeof(reg)); 102 + 103 + fw_iso_resources_free(&motu->tx_resources); 104 + fw_iso_resources_free(&motu->rx_resources); 105 + } 106 + 107 + static int start_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream) 108 + { 109 + struct fw_iso_resources *resources; 110 + int err; 111 + 112 + if (stream == &motu->rx_stream) 113 + resources = &motu->rx_resources; 114 + else 115 + resources = &motu->tx_resources; 116 + 117 + err = amdtp_stream_start(stream, resources->channel, 118 + fw_parent_device(motu->unit)->max_speed); 119 + if (err < 0) 120 + return err; 121 + 122 + if (!amdtp_stream_wait_callback(stream, CALLBACK_TIMEOUT)) { 123 + amdtp_stream_stop(stream); 124 + fw_iso_resources_free(resources); 125 + return -ETIMEDOUT; 126 + } 127 + 128 + return 0; 129 + } 130 + 131 + static void stop_isoc_ctx(struct snd_motu *motu, struct amdtp_stream *stream) 132 + { 133 + struct fw_iso_resources *resources; 134 + 135 + if (stream == &motu->rx_stream) 136 + resources = &motu->rx_resources; 137 + else 138 + resources = &motu->tx_resources; 139 + 140 + amdtp_stream_stop(stream); 141 + fw_iso_resources_free(resources); 142 + } 143 + 144 + static int ensure_packet_formats(struct snd_motu *motu) 145 + { 146 + __be32 reg; 147 + u32 data; 148 + int err; 149 + 150 + err = snd_motu_transaction_read(motu, PACKET_FORMAT_OFFSET, &reg, 151 + sizeof(reg)); 152 + if (err < 0) 153 + return err; 154 + data = be32_to_cpu(reg); 155 + 156 + data &= ~(TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS | 157 + RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS| 158 + TX_PACKET_TRANSMISSION_SPEED_MASK); 159 + if (motu->tx_packet_formats.differed_part_pcm_chunks[0] == 0) 160 + data |= TX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS; 161 + if (motu->rx_packet_formats.differed_part_pcm_chunks[0] == 0) 162 + data |= RX_PACKET_EXCLUDE_DIFFERED_DATA_CHUNKS; 163 + data |= fw_parent_device(motu->unit)->max_speed; 164 + 165 + reg = cpu_to_be32(data); 166 + return snd_motu_transaction_write(motu, PACKET_FORMAT_OFFSET, &reg, 167 + sizeof(reg)); 168 + } 169 + 170 + int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate) 171 + { 172 + const struct snd_motu_protocol *protocol = motu->spec->protocol; 173 + unsigned int curr_rate; 174 + int err = 0; 175 + 176 + if (motu->capture_substreams == 0 && motu->playback_substreams == 0) 177 + return 0; 178 + 179 + /* Some packet queueing errors. */ 180 + if (amdtp_streaming_error(&motu->rx_stream) || 181 + amdtp_streaming_error(&motu->tx_stream)) { 182 + amdtp_stream_stop(&motu->rx_stream); 183 + amdtp_stream_stop(&motu->tx_stream); 184 + stop_both_streams(motu); 185 + } 186 + 187 + err = protocol->cache_packet_formats(motu); 188 + if (err < 0) 189 + return err; 190 + 191 + /* Stop stream if rate is different. */ 192 + err = protocol->get_clock_rate(motu, &curr_rate); 193 + if (err < 0) { 194 + dev_err(&motu->unit->device, 195 + "fail to get sampling rate: %d\n", err); 196 + return err; 197 + } 198 + if (rate == 0) 199 + rate = curr_rate; 200 + if (rate != curr_rate) { 201 + amdtp_stream_stop(&motu->rx_stream); 202 + amdtp_stream_stop(&motu->tx_stream); 203 + stop_both_streams(motu); 204 + } 205 + 206 + if (!amdtp_stream_running(&motu->rx_stream)) { 207 + err = protocol->set_clock_rate(motu, rate); 208 + if (err < 0) { 209 + dev_err(&motu->unit->device, 210 + "fail to set sampling rate: %d\n", err); 211 + return err; 212 + } 213 + 214 + err = ensure_packet_formats(motu); 215 + if (err < 0) 216 + return err; 217 + 218 + err = start_both_streams(motu, rate); 219 + if (err < 0) { 220 + dev_err(&motu->unit->device, 221 + "fail to start isochronous comm: %d\n", err); 222 + stop_both_streams(motu); 223 + return err; 224 + } 225 + 226 + err = start_isoc_ctx(motu, &motu->rx_stream); 227 + if (err < 0) { 228 + dev_err(&motu->unit->device, 229 + "fail to start IT context: %d\n", err); 230 + stop_both_streams(motu); 231 + return err; 232 + } 233 + 234 + err = protocol->switch_fetching_mode(motu, true); 235 + if (err < 0) { 236 + dev_err(&motu->unit->device, 237 + "fail to enable frame fetching: %d\n", err); 238 + stop_both_streams(motu); 239 + return err; 240 + } 241 + } 242 + 243 + if (!amdtp_stream_running(&motu->tx_stream) && 244 + motu->capture_substreams > 0) { 245 + err = start_isoc_ctx(motu, &motu->tx_stream); 246 + if (err < 0) { 247 + dev_err(&motu->unit->device, 248 + "fail to start IR context: %d", err); 249 + amdtp_stream_stop(&motu->rx_stream); 250 + stop_both_streams(motu); 251 + return err; 252 + } 253 + } 254 + 255 + return 0; 256 + } 257 + 258 + void snd_motu_stream_stop_duplex(struct snd_motu *motu) 259 + { 260 + if (motu->capture_substreams == 0) { 261 + if (amdtp_stream_running(&motu->tx_stream)) 262 + stop_isoc_ctx(motu, &motu->tx_stream); 263 + 264 + if (motu->playback_substreams == 0) { 265 + if (amdtp_stream_running(&motu->rx_stream)) 266 + stop_isoc_ctx(motu, &motu->rx_stream); 267 + stop_both_streams(motu); 268 + } 269 + } 270 + } 271 + 272 + static int init_stream(struct snd_motu *motu, enum amdtp_stream_direction dir) 273 + { 274 + int err; 275 + struct amdtp_stream *stream; 276 + struct fw_iso_resources *resources; 277 + 278 + if (dir == AMDTP_IN_STREAM) { 279 + stream = &motu->tx_stream; 280 + resources = &motu->tx_resources; 281 + } else { 282 + stream = &motu->rx_stream; 283 + resources = &motu->rx_resources; 284 + } 285 + 286 + err = fw_iso_resources_init(resources, motu->unit); 287 + if (err < 0) 288 + return err; 289 + 290 + err = amdtp_motu_init(stream, motu->unit, dir, motu->spec->protocol); 291 + if (err < 0) { 292 + amdtp_stream_destroy(stream); 293 + fw_iso_resources_destroy(resources); 294 + } 295 + 296 + return err; 297 + } 298 + 299 + static void destroy_stream(struct snd_motu *motu, 300 + enum amdtp_stream_direction dir) 301 + { 302 + struct amdtp_stream *stream; 303 + struct fw_iso_resources *resources; 304 + 305 + if (dir == AMDTP_IN_STREAM) { 306 + stream = &motu->tx_stream; 307 + resources = &motu->tx_resources; 308 + } else { 309 + stream = &motu->rx_stream; 310 + resources = &motu->rx_resources; 311 + } 312 + 313 + amdtp_stream_destroy(stream); 314 + fw_iso_resources_free(resources); 315 + } 316 + 317 + int snd_motu_stream_init_duplex(struct snd_motu *motu) 318 + { 319 + int err; 320 + 321 + err = init_stream(motu, AMDTP_IN_STREAM); 322 + if (err < 0) 323 + return err; 324 + 325 + err = init_stream(motu, AMDTP_OUT_STREAM); 326 + if (err < 0) 327 + destroy_stream(motu, AMDTP_IN_STREAM); 328 + 329 + return err; 330 + } 331 + 332 + /* 333 + * This function should be called before starting streams or after stopping 334 + * streams. 335 + */ 336 + void snd_motu_stream_destroy_duplex(struct snd_motu *motu) 337 + { 338 + destroy_stream(motu, AMDTP_IN_STREAM); 339 + destroy_stream(motu, AMDTP_OUT_STREAM); 340 + 341 + motu->playback_substreams = 0; 342 + motu->capture_substreams = 0; 343 + } 344 + 345 + static void motu_lock_changed(struct snd_motu *motu) 346 + { 347 + motu->dev_lock_changed = true; 348 + wake_up(&motu->hwdep_wait); 349 + } 350 + 351 + int snd_motu_stream_lock_try(struct snd_motu *motu) 352 + { 353 + int err; 354 + 355 + spin_lock_irq(&motu->lock); 356 + 357 + if (motu->dev_lock_count < 0) { 358 + err = -EBUSY; 359 + goto out; 360 + } 361 + 362 + if (motu->dev_lock_count++ == 0) 363 + motu_lock_changed(motu); 364 + err = 0; 365 + out: 366 + spin_unlock_irq(&motu->lock); 367 + return err; 368 + } 369 + 370 + void snd_motu_stream_lock_release(struct snd_motu *motu) 371 + { 372 + spin_lock_irq(&motu->lock); 373 + 374 + if (WARN_ON(motu->dev_lock_count <= 0)) 375 + goto out; 376 + 377 + if (--motu->dev_lock_count == 0) 378 + motu_lock_changed(motu); 379 + out: 380 + spin_unlock_irq(&motu->lock); 381 + }
+137
sound/firewire/motu/motu-transaction.c
···
··· 1 + /* 2 + * motu-transaction.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + 10 + #include "motu.h" 11 + 12 + #define SND_MOTU_ADDR_BASE 0xfffff0000000ULL 13 + #define ASYNC_ADDR_HI 0x0b04 14 + #define ASYNC_ADDR_LO 0x0b08 15 + 16 + int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg, 17 + size_t size) 18 + { 19 + int tcode; 20 + 21 + if (size % sizeof(__be32) > 0 || size <= 0) 22 + return -EINVAL; 23 + if (size == sizeof(__be32)) 24 + tcode = TCODE_READ_QUADLET_REQUEST; 25 + else 26 + tcode = TCODE_READ_BLOCK_REQUEST; 27 + 28 + return snd_fw_transaction(motu->unit, tcode, 29 + SND_MOTU_ADDR_BASE + offset, reg, size, 0); 30 + } 31 + 32 + int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg, 33 + size_t size) 34 + { 35 + int tcode; 36 + 37 + if (size % sizeof(__be32) > 0 || size <= 0) 38 + return -EINVAL; 39 + if (size == sizeof(__be32)) 40 + tcode = TCODE_WRITE_QUADLET_REQUEST; 41 + else 42 + tcode = TCODE_WRITE_BLOCK_REQUEST; 43 + 44 + return snd_fw_transaction(motu->unit, tcode, 45 + SND_MOTU_ADDR_BASE + offset, reg, size, 0); 46 + } 47 + 48 + static void handle_message(struct fw_card *card, struct fw_request *request, 49 + int tcode, int destination, int source, 50 + int generation, unsigned long long offset, 51 + void *data, size_t length, void *callback_data) 52 + { 53 + struct snd_motu *motu = callback_data; 54 + __be32 *buf = (__be32 *)data; 55 + unsigned long flags; 56 + 57 + if (tcode != TCODE_WRITE_QUADLET_REQUEST) { 58 + fw_send_response(card, request, RCODE_COMPLETE); 59 + return; 60 + } 61 + 62 + if (offset != motu->async_handler.offset || length != 4) { 63 + fw_send_response(card, request, RCODE_ADDRESS_ERROR); 64 + return; 65 + } 66 + 67 + spin_lock_irqsave(&motu->lock, flags); 68 + motu->msg = be32_to_cpu(*buf); 69 + spin_unlock_irqrestore(&motu->lock, flags); 70 + 71 + fw_send_response(card, request, RCODE_COMPLETE); 72 + 73 + wake_up(&motu->hwdep_wait); 74 + } 75 + 76 + int snd_motu_transaction_reregister(struct snd_motu *motu) 77 + { 78 + struct fw_device *device = fw_parent_device(motu->unit); 79 + __be32 data; 80 + int err; 81 + 82 + if (motu->async_handler.callback_data == NULL) 83 + return -EINVAL; 84 + 85 + /* Register messaging address. Block transaction is not allowed. */ 86 + data = cpu_to_be32((device->card->node_id << 16) | 87 + (motu->async_handler.offset >> 32)); 88 + err = snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data, 89 + sizeof(data)); 90 + if (err < 0) 91 + return err; 92 + 93 + data = cpu_to_be32(motu->async_handler.offset); 94 + return snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data, 95 + sizeof(data)); 96 + } 97 + 98 + int snd_motu_transaction_register(struct snd_motu *motu) 99 + { 100 + static const struct fw_address_region resp_register_region = { 101 + .start = 0xffffe0000000ull, 102 + .end = 0xffffe000ffffull, 103 + }; 104 + int err; 105 + 106 + /* Perhaps, 4 byte messages are transferred. */ 107 + motu->async_handler.length = 4; 108 + motu->async_handler.address_callback = handle_message; 109 + motu->async_handler.callback_data = motu; 110 + 111 + err = fw_core_add_address_handler(&motu->async_handler, 112 + &resp_register_region); 113 + if (err < 0) 114 + return err; 115 + 116 + err = snd_motu_transaction_reregister(motu); 117 + if (err < 0) { 118 + fw_core_remove_address_handler(&motu->async_handler); 119 + motu->async_handler.address_callback = NULL; 120 + } 121 + 122 + return err; 123 + } 124 + 125 + void snd_motu_transaction_unregister(struct snd_motu *motu) 126 + { 127 + __be32 data; 128 + 129 + if (motu->async_handler.address_callback != NULL) 130 + fw_core_remove_address_handler(&motu->async_handler); 131 + motu->async_handler.address_callback = NULL; 132 + 133 + /* Unregister the address. */ 134 + data = cpu_to_be32(0x00000000); 135 + snd_motu_transaction_write(motu, ASYNC_ADDR_HI, &data, sizeof(data)); 136 + snd_motu_transaction_write(motu, ASYNC_ADDR_LO, &data, sizeof(data)); 137 + }
+264
sound/firewire/motu/motu.c
···
··· 1 + /* 2 + * motu.c - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #include "motu.h" 10 + 11 + #define OUI_MOTU 0x0001f2 12 + 13 + MODULE_DESCRIPTION("MOTU FireWire driver"); 14 + MODULE_AUTHOR("Takashi Sakamoto <o-takashi@sakamocchi.jp>"); 15 + MODULE_LICENSE("GPL v2"); 16 + 17 + const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT] = { 18 + /* mode 0 */ 19 + [0] = 44100, 20 + [1] = 48000, 21 + /* mode 1 */ 22 + [2] = 88200, 23 + [3] = 96000, 24 + /* mode 2 */ 25 + [4] = 176400, 26 + [5] = 192000, 27 + }; 28 + 29 + static void name_card(struct snd_motu *motu) 30 + { 31 + struct fw_device *fw_dev = fw_parent_device(motu->unit); 32 + struct fw_csr_iterator it; 33 + int key, val; 34 + u32 version = 0; 35 + 36 + fw_csr_iterator_init(&it, motu->unit->directory); 37 + while (fw_csr_iterator_next(&it, &key, &val)) { 38 + switch (key) { 39 + case CSR_VERSION: 40 + version = val; 41 + break; 42 + } 43 + } 44 + 45 + strcpy(motu->card->driver, "FW-MOTU"); 46 + strcpy(motu->card->shortname, motu->spec->name); 47 + strcpy(motu->card->mixername, motu->spec->name); 48 + snprintf(motu->card->longname, sizeof(motu->card->longname), 49 + "MOTU %s (version:%d), GUID %08x%08x at %s, S%d", 50 + motu->spec->name, version, 51 + fw_dev->config_rom[3], fw_dev->config_rom[4], 52 + dev_name(&motu->unit->device), 100 << fw_dev->max_speed); 53 + } 54 + 55 + static void motu_free(struct snd_motu *motu) 56 + { 57 + snd_motu_transaction_unregister(motu); 58 + 59 + snd_motu_stream_destroy_duplex(motu); 60 + fw_unit_put(motu->unit); 61 + 62 + mutex_destroy(&motu->mutex); 63 + kfree(motu); 64 + } 65 + 66 + /* 67 + * This module releases the FireWire unit data after all ALSA character devices 68 + * are released by applications. This is for releasing stream data or finishing 69 + * transactions safely. Thus at returning from .remove(), this module still keep 70 + * references for the unit. 71 + */ 72 + static void motu_card_free(struct snd_card *card) 73 + { 74 + motu_free(card->private_data); 75 + } 76 + 77 + static void do_registration(struct work_struct *work) 78 + { 79 + struct snd_motu *motu = container_of(work, struct snd_motu, dwork.work); 80 + int err; 81 + 82 + if (motu->registered) 83 + return; 84 + 85 + err = snd_card_new(&motu->unit->device, -1, NULL, THIS_MODULE, 0, 86 + &motu->card); 87 + if (err < 0) 88 + return; 89 + 90 + name_card(motu); 91 + 92 + err = snd_motu_transaction_register(motu); 93 + if (err < 0) 94 + goto error; 95 + 96 + err = snd_motu_stream_init_duplex(motu); 97 + if (err < 0) 98 + goto error; 99 + 100 + snd_motu_proc_init(motu); 101 + 102 + err = snd_motu_create_pcm_devices(motu); 103 + if (err < 0) 104 + goto error; 105 + 106 + if (motu->spec->flags & SND_MOTU_SPEC_HAS_MIDI) { 107 + err = snd_motu_create_midi_devices(motu); 108 + if (err < 0) 109 + goto error; 110 + } 111 + 112 + err = snd_motu_create_hwdep_device(motu); 113 + if (err < 0) 114 + goto error; 115 + 116 + err = snd_card_register(motu->card); 117 + if (err < 0) 118 + goto error; 119 + 120 + /* 121 + * After registered, motu instance can be released corresponding to 122 + * releasing the sound card instance. 123 + */ 124 + motu->card->private_free = motu_card_free; 125 + motu->card->private_data = motu; 126 + motu->registered = true; 127 + 128 + return; 129 + error: 130 + snd_motu_transaction_unregister(motu); 131 + snd_card_free(motu->card); 132 + dev_info(&motu->unit->device, 133 + "Sound card registration failed: %d\n", err); 134 + } 135 + 136 + static int motu_probe(struct fw_unit *unit, 137 + const struct ieee1394_device_id *entry) 138 + { 139 + struct snd_motu *motu; 140 + 141 + /* Allocate this independently of sound card instance. */ 142 + motu = kzalloc(sizeof(struct snd_motu), GFP_KERNEL); 143 + if (motu == NULL) 144 + return -ENOMEM; 145 + 146 + motu->spec = (const struct snd_motu_spec *)entry->driver_data; 147 + motu->unit = fw_unit_get(unit); 148 + dev_set_drvdata(&unit->device, motu); 149 + 150 + mutex_init(&motu->mutex); 151 + spin_lock_init(&motu->lock); 152 + init_waitqueue_head(&motu->hwdep_wait); 153 + 154 + /* Allocate and register this sound card later. */ 155 + INIT_DEFERRABLE_WORK(&motu->dwork, do_registration); 156 + snd_fw_schedule_registration(unit, &motu->dwork); 157 + 158 + return 0; 159 + } 160 + 161 + static void motu_remove(struct fw_unit *unit) 162 + { 163 + struct snd_motu *motu = dev_get_drvdata(&unit->device); 164 + 165 + /* 166 + * Confirm to stop the work for registration before the sound card is 167 + * going to be released. The work is not scheduled again because bus 168 + * reset handler is not called anymore. 169 + */ 170 + cancel_delayed_work_sync(&motu->dwork); 171 + 172 + if (motu->registered) { 173 + /* No need to wait for releasing card object in this context. */ 174 + snd_card_free_when_closed(motu->card); 175 + } else { 176 + /* Don't forget this case. */ 177 + motu_free(motu); 178 + } 179 + } 180 + 181 + static void motu_bus_update(struct fw_unit *unit) 182 + { 183 + struct snd_motu *motu = dev_get_drvdata(&unit->device); 184 + 185 + /* Postpone a workqueue for deferred registration. */ 186 + if (!motu->registered) 187 + snd_fw_schedule_registration(unit, &motu->dwork); 188 + 189 + /* The handler address register becomes initialized. */ 190 + snd_motu_transaction_reregister(motu); 191 + } 192 + 193 + static struct snd_motu_spec motu_828mk2 = { 194 + .name = "828mk2", 195 + .protocol = &snd_motu_protocol_v2, 196 + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 197 + SND_MOTU_SPEC_TX_MICINST_CHUNK | 198 + SND_MOTU_SPEC_TX_RETURN_CHUNK | 199 + SND_MOTU_SPEC_HAS_OPT_IFACE_A | 200 + SND_MOTU_SPEC_HAS_MIDI, 201 + 202 + .analog_in_ports = 8, 203 + .analog_out_ports = 8, 204 + }; 205 + 206 + static struct snd_motu_spec motu_828mk3 = { 207 + .name = "828mk3", 208 + .protocol = &snd_motu_protocol_v3, 209 + .flags = SND_MOTU_SPEC_SUPPORT_CLOCK_X2 | 210 + SND_MOTU_SPEC_SUPPORT_CLOCK_X4 | 211 + SND_MOTU_SPEC_TX_MICINST_CHUNK | 212 + SND_MOTU_SPEC_TX_RETURN_CHUNK | 213 + SND_MOTU_SPEC_TX_REVERB_CHUNK | 214 + SND_MOTU_SPEC_HAS_OPT_IFACE_A | 215 + SND_MOTU_SPEC_HAS_OPT_IFACE_B | 216 + SND_MOTU_SPEC_HAS_MIDI, 217 + 218 + .analog_in_ports = 8, 219 + .analog_out_ports = 8, 220 + }; 221 + 222 + #define SND_MOTU_DEV_ENTRY(model, data) \ 223 + { \ 224 + .match_flags = IEEE1394_MATCH_VENDOR_ID | \ 225 + IEEE1394_MATCH_MODEL_ID | \ 226 + IEEE1394_MATCH_SPECIFIER_ID, \ 227 + .vendor_id = OUI_MOTU, \ 228 + .model_id = model, \ 229 + .specifier_id = OUI_MOTU, \ 230 + .driver_data = (kernel_ulong_t)data, \ 231 + } 232 + 233 + static const struct ieee1394_device_id motu_id_table[] = { 234 + SND_MOTU_DEV_ENTRY(0x101800, &motu_828mk2), 235 + SND_MOTU_DEV_ENTRY(0x106800, &motu_828mk3), /* FireWire only. */ 236 + SND_MOTU_DEV_ENTRY(0x100800, &motu_828mk3), /* Hybrid. */ 237 + { } 238 + }; 239 + MODULE_DEVICE_TABLE(ieee1394, motu_id_table); 240 + 241 + static struct fw_driver motu_driver = { 242 + .driver = { 243 + .owner = THIS_MODULE, 244 + .name = KBUILD_MODNAME, 245 + .bus = &fw_bus_type, 246 + }, 247 + .probe = motu_probe, 248 + .update = motu_bus_update, 249 + .remove = motu_remove, 250 + .id_table = motu_id_table, 251 + }; 252 + 253 + static int __init alsa_motu_init(void) 254 + { 255 + return driver_register(&motu_driver.driver); 256 + } 257 + 258 + static void __exit alsa_motu_exit(void) 259 + { 260 + driver_unregister(&motu_driver.driver); 261 + } 262 + 263 + module_init(alsa_motu_init); 264 + module_exit(alsa_motu_exit);
+161
sound/firewire/motu/motu.h
···
··· 1 + /* 2 + * motu.h - a part of driver for MOTU FireWire series 3 + * 4 + * Copyright (c) 2015-2017 Takashi Sakamoto <o-takashi@sakamocchi.jp> 5 + * 6 + * Licensed under the terms of the GNU General Public License, version 2. 7 + */ 8 + 9 + #ifndef SOUND_FIREWIRE_MOTU_H_INCLUDED 10 + #define SOUND_FIREWIRE_MOTU_H_INCLUDED 11 + 12 + #include <linux/device.h> 13 + #include <linux/firewire.h> 14 + #include <linux/firewire-constants.h> 15 + #include <linux/module.h> 16 + #include <linux/mod_devicetable.h> 17 + #include <linux/mutex.h> 18 + #include <linux/slab.h> 19 + #include <linux/compat.h> 20 + #include <linux/sched/signal.h> 21 + 22 + #include <sound/control.h> 23 + #include <sound/core.h> 24 + #include <sound/pcm.h> 25 + #include <sound/info.h> 26 + #include <sound/rawmidi.h> 27 + #include <sound/firewire.h> 28 + #include <sound/hwdep.h> 29 + 30 + #include "../lib.h" 31 + #include "../amdtp-stream.h" 32 + #include "../iso-resources.h" 33 + 34 + struct snd_motu_packet_format { 35 + unsigned char midi_flag_offset; 36 + unsigned char midi_byte_offset; 37 + unsigned char pcm_byte_offset; 38 + 39 + unsigned char msg_chunks; 40 + unsigned char fixed_part_pcm_chunks[3]; 41 + unsigned char differed_part_pcm_chunks[3]; 42 + }; 43 + 44 + struct snd_motu { 45 + struct snd_card *card; 46 + struct fw_unit *unit; 47 + struct mutex mutex; 48 + spinlock_t lock; 49 + 50 + bool registered; 51 + struct delayed_work dwork; 52 + 53 + /* Model dependent information. */ 54 + const struct snd_motu_spec *spec; 55 + 56 + /* For packet streaming */ 57 + struct snd_motu_packet_format tx_packet_formats; 58 + struct snd_motu_packet_format rx_packet_formats; 59 + struct amdtp_stream tx_stream; 60 + struct amdtp_stream rx_stream; 61 + struct fw_iso_resources tx_resources; 62 + struct fw_iso_resources rx_resources; 63 + unsigned int capture_substreams; 64 + unsigned int playback_substreams; 65 + 66 + /* For notification. */ 67 + struct fw_address_handler async_handler; 68 + u32 msg; 69 + 70 + /* For uapi */ 71 + int dev_lock_count; 72 + bool dev_lock_changed; 73 + wait_queue_head_t hwdep_wait; 74 + }; 75 + 76 + enum snd_motu_spec_flags { 77 + SND_MOTU_SPEC_SUPPORT_CLOCK_X2 = 0x0001, 78 + SND_MOTU_SPEC_SUPPORT_CLOCK_X4 = 0x0002, 79 + SND_MOTU_SPEC_TX_MICINST_CHUNK = 0x0004, 80 + SND_MOTU_SPEC_TX_RETURN_CHUNK = 0x0008, 81 + SND_MOTU_SPEC_TX_REVERB_CHUNK = 0x0010, 82 + SND_MOTU_SPEC_TX_AESEBU_CHUNK = 0x0020, 83 + SND_MOTU_SPEC_HAS_OPT_IFACE_A = 0x0040, 84 + SND_MOTU_SPEC_HAS_OPT_IFACE_B = 0x0080, 85 + SND_MOTU_SPEC_HAS_MIDI = 0x0100, 86 + }; 87 + 88 + #define SND_MOTU_CLOCK_RATE_COUNT 6 89 + extern const unsigned int snd_motu_clock_rates[SND_MOTU_CLOCK_RATE_COUNT]; 90 + 91 + enum snd_motu_clock_source { 92 + SND_MOTU_CLOCK_SOURCE_INTERNAL, 93 + SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB, 94 + SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT, 95 + SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_A, 96 + SND_MOTU_CLOCK_SOURCE_ADAT_ON_OPT_B, 97 + SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT, 98 + SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_A, 99 + SND_MOTU_CLOCK_SOURCE_SPDIF_ON_OPT_B, 100 + SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX, 101 + SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR, 102 + SND_MOTU_CLOCK_SOURCE_WORD_ON_BNC, 103 + SND_MOTU_CLOCK_SOURCE_UNKNOWN, 104 + }; 105 + 106 + struct snd_motu_protocol { 107 + int (*get_clock_rate)(struct snd_motu *motu, unsigned int *rate); 108 + int (*set_clock_rate)(struct snd_motu *motu, unsigned int rate); 109 + int (*get_clock_source)(struct snd_motu *motu, 110 + enum snd_motu_clock_source *source); 111 + int (*switch_fetching_mode)(struct snd_motu *motu, bool enable); 112 + int (*cache_packet_formats)(struct snd_motu *motu); 113 + }; 114 + 115 + struct snd_motu_spec { 116 + const char *const name; 117 + enum snd_motu_spec_flags flags; 118 + 119 + unsigned char analog_in_ports; 120 + unsigned char analog_out_ports; 121 + 122 + const struct snd_motu_protocol *const protocol; 123 + }; 124 + 125 + extern const struct snd_motu_protocol snd_motu_protocol_v2; 126 + extern const struct snd_motu_protocol snd_motu_protocol_v3; 127 + 128 + int amdtp_motu_init(struct amdtp_stream *s, struct fw_unit *unit, 129 + enum amdtp_stream_direction dir, 130 + const struct snd_motu_protocol *const protocol); 131 + int amdtp_motu_set_parameters(struct amdtp_stream *s, unsigned int rate, 132 + unsigned int midi_ports, 133 + struct snd_motu_packet_format *formats); 134 + int amdtp_motu_add_pcm_hw_constraints(struct amdtp_stream *s, 135 + struct snd_pcm_runtime *runtime); 136 + void amdtp_motu_midi_trigger(struct amdtp_stream *s, unsigned int port, 137 + struct snd_rawmidi_substream *midi); 138 + 139 + int snd_motu_transaction_read(struct snd_motu *motu, u32 offset, __be32 *reg, 140 + size_t size); 141 + int snd_motu_transaction_write(struct snd_motu *motu, u32 offset, __be32 *reg, 142 + size_t size); 143 + int snd_motu_transaction_register(struct snd_motu *motu); 144 + int snd_motu_transaction_reregister(struct snd_motu *motu); 145 + void snd_motu_transaction_unregister(struct snd_motu *motu); 146 + 147 + int snd_motu_stream_init_duplex(struct snd_motu *motu); 148 + void snd_motu_stream_destroy_duplex(struct snd_motu *motu); 149 + int snd_motu_stream_start_duplex(struct snd_motu *motu, unsigned int rate); 150 + void snd_motu_stream_stop_duplex(struct snd_motu *motu); 151 + int snd_motu_stream_lock_try(struct snd_motu *motu); 152 + void snd_motu_stream_lock_release(struct snd_motu *motu); 153 + 154 + void snd_motu_proc_init(struct snd_motu *motu); 155 + 156 + int snd_motu_create_pcm_devices(struct snd_motu *motu); 157 + 158 + int snd_motu_create_midi_devices(struct snd_motu *motu); 159 + 160 + int snd_motu_create_hwdep_device(struct snd_motu *motu); 161 + #endif
+9 -3
sound/firewire/oxfw/oxfw-command.c
··· 34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, 35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 36 BIT(6) | BIT(7) | BIT(8)); 37 - if ((err > 0) && (err < len + 10)) 38 err = -EIO; 39 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 40 err = -ENOSYS; ··· 79 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 80 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 81 BIT(6) | BIT(7)); 82 - if ((err > 0) && (err < 10)) 83 err = -EIO; 84 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 85 err = -ENOSYS; ··· 143 /* do transaction and check buf[1-5] are the same against command */ 144 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 145 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 146 - if ((err > 0) && (err < 8)) 147 err = -EIO; 148 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 149 err = -ENOSYS;
··· 34 err = fcp_avc_transaction(unit, buf, len + 10, buf, len + 10, 35 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 36 BIT(6) | BIT(7) | BIT(8)); 37 + if (err < 0) 38 + ; 39 + else if (err < len + 10) 40 err = -EIO; 41 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 42 err = -ENOSYS; ··· 77 err = fcp_avc_transaction(unit, buf, 12, buf, *len, 78 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | 79 BIT(6) | BIT(7)); 80 + if (err < 0) 81 + ; 82 + else if (err < 12) 83 err = -EIO; 84 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 85 err = -ENOSYS; ··· 139 /* do transaction and check buf[1-5] are the same against command */ 140 err = fcp_avc_transaction(unit, buf, 8, buf, 8, 141 BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5)); 142 + if (err < 0) 143 + ; 144 + else if (err < 8) 145 err = -EIO; 146 else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ 147 err = -ENOSYS;
+8 -5
sound/firewire/tascam/tascam-midi.c
··· 18 { 19 struct snd_tscm *tscm = substream->rmidi->private_data; 20 21 - /* Initialize internal status. */ 22 - tscm->running_status[substream->number] = 0; 23 - tscm->on_sysex[substream->number] = 0; 24 return 0; 25 } 26 ··· 31 32 static int midi_playback_close(struct snd_rawmidi_substream *substream) 33 { 34 struct snd_tscm *tscm = substream->rmidi->private_data; 35 36 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]); 37 - 38 - return 0; 39 } 40 41 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) ··· 80 static const struct snd_rawmidi_ops playback_ops = { 81 .open = midi_playback_open, 82 .close = midi_playback_close, 83 .trigger = midi_playback_trigger, 84 }; 85 struct snd_rawmidi *rmidi;
··· 18 { 19 struct snd_tscm *tscm = substream->rmidi->private_data; 20 21 + snd_fw_async_midi_port_init(&tscm->out_ports[substream->number]); 22 + 23 return 0; 24 } 25 ··· 32 33 static int midi_playback_close(struct snd_rawmidi_substream *substream) 34 { 35 + return 0; 36 + } 37 + 38 + static void midi_playback_drain(struct snd_rawmidi_substream *substream) 39 + { 40 struct snd_tscm *tscm = substream->rmidi->private_data; 41 42 snd_fw_async_midi_port_finish(&tscm->out_ports[substream->number]); 43 } 44 45 static void midi_capture_trigger(struct snd_rawmidi_substream *substrm, int up) ··· 78 static const struct snd_rawmidi_ops playback_ops = { 79 .open = midi_playback_open, 80 .close = midi_playback_close, 81 + .drain = midi_playback_drain, 82 .trigger = midi_playback_trigger, 83 }; 84 struct snd_rawmidi *rmidi;
+117 -25
sound/firewire/tascam/tascam-transaction.c
··· 58 return -EINVAL; 59 } 60 61 - static int fill_message(struct snd_rawmidi_substream *substream, u8 *buf) 62 { 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; 68 69 /* The first byte is used for label, the rest for MIDI bytes. */ 70 - label = buf; 71 - msg = buf + 1; 72 73 consume = snd_rawmidi_transmit_peek(substream, msg, 3); 74 if (consume == 0) 75 return 0; 76 77 /* 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 } 86 87 /* 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 else 110 status = msg[0]; 111 ··· 123 124 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; 132 133 - tscm->running_status[port] = msg[0]; 134 } 135 } 136 137 - *label = (port << 4) | (msg[0] >> 4); 138 } 139 140 if (len > 0 && len < 3) 141 memset(msg + len, 0, 3 - len); 142 143 return consume; 144 } 145 146 static void handle_midi_tx(struct fw_card *card, struct fw_request *request, ··· 318 goto error; 319 320 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 } 328 329 return err; ··· 371 void snd_tscm_transaction_unregister(struct snd_tscm *tscm) 372 { 373 __be32 reg; 374 - unsigned int i; 375 376 if (tscm->async_handler.callback_data == NULL) 377 return; ··· 397 398 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 } 60 61 + static int fill_message(struct snd_fw_async_midi_port *port, 62 + struct snd_rawmidi_substream *substream) 63 { 64 int i, len, consume; 65 u8 *label, *msg; 66 u8 status; 67 68 /* The first byte is used for label, the rest for MIDI bytes. */ 69 + label = port->buf; 70 + msg = port->buf + 1; 71 72 consume = snd_rawmidi_transmit_peek(substream, msg, 3); 73 if (consume == 0) 74 return 0; 75 76 /* 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 } 85 86 /* 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 else 111 status = msg[0]; 112 ··· 124 125 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; 133 134 + port->running_status = msg[0]; 135 } 136 } 137 138 + *label = (substream->number << 4) | (msg[0] >> 4); 139 } 140 141 if (len > 0 && len < 3) 142 memset(msg + len, 0, 3 - len); 143 144 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 + else 164 + /* 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 memory 221 + * barrier, node id has already been updated. In this module, After 222 + * this smp_rmb(), load/store instructions to memory are completed. 223 + * Thus, both of generation and node id are available with recent 224 + * values. This is a light-serialization solution to handle bus reset 225 + * 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 } 246 247 static void handle_midi_tx(struct fw_card *card, struct fw_request *request, ··· 219 goto error; 220 221 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); 225 } 226 227 return err; ··· 275 void snd_tscm_transaction_unregister(struct snd_tscm *tscm) 276 { 277 __be32 reg; 278 279 if (tscm->async_handler.callback_data == NULL) 280 return; ··· 302 303 fw_core_remove_address_handler(&tscm->async_handler); 304 tscm->async_handler.callback_data = NULL; 305 }
+37 -2
sound/firewire/tascam/tascam.h
··· 45 #define TSCM_MIDI_IN_PORT_MAX 4 46 #define TSCM_MIDI_OUT_PORT_MAX 4 47 48 struct snd_tscm { 49 struct snd_card *card; 50 struct fw_unit *unit; ··· 89 90 /* For MIDI message outgoing transactions. */ 91 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX]; 92 - u8 running_status[TSCM_MIDI_OUT_PORT_MAX]; 93 - bool on_sysex[TSCM_MIDI_OUT_PORT_MAX]; 94 }; 95 96 #define TSCM_ADDR_BASE 0xffff00000000ull ··· 145 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm); 146 int snd_tscm_stream_lock_try(struct snd_tscm *tscm); 147 void snd_tscm_stream_lock_release(struct snd_tscm *tscm); 148 149 int snd_tscm_transaction_register(struct snd_tscm *tscm); 150 int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
··· 45 #define TSCM_MIDI_IN_PORT_MAX 4 46 #define TSCM_MIDI_OUT_PORT_MAX 4 47 48 + struct snd_fw_async_midi_port { 49 + struct fw_device *parent; 50 + struct work_struct work; 51 + bool idling; 52 + ktime_t next_ktime; 53 + bool error; 54 + 55 + struct fw_transaction transaction; 56 + 57 + u8 buf[4]; 58 + u8 running_status; 59 + bool on_sysex; 60 + 61 + struct snd_rawmidi_substream *substream; 62 + int consume_bytes; 63 + }; 64 + 65 struct snd_tscm { 66 struct snd_card *card; 67 struct fw_unit *unit; ··· 72 73 /* For MIDI message outgoing transactions. */ 74 struct snd_fw_async_midi_port out_ports[TSCM_MIDI_OUT_PORT_MAX]; 75 }; 76 77 #define TSCM_ADDR_BASE 0xffff00000000ull ··· 130 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm); 131 int snd_tscm_stream_lock_try(struct snd_tscm *tscm); 132 void snd_tscm_stream_lock_release(struct snd_tscm *tscm); 133 + 134 + void snd_fw_async_midi_port_init(struct snd_fw_async_midi_port *port); 135 + 136 + static inline void 137 + snd_fw_async_midi_port_run(struct snd_fw_async_midi_port *port, 138 + struct snd_rawmidi_substream *substream) 139 + { 140 + if (!port->error) { 141 + port->substream = substream; 142 + schedule_work(&port->work); 143 + } 144 + } 145 + 146 + static inline void 147 + snd_fw_async_midi_port_finish(struct snd_fw_async_midi_port *port) 148 + { 149 + port->substream = NULL; 150 + cancel_work_sync(&port->work); 151 + port->error = false; 152 + } 153 154 int snd_tscm_transaction_register(struct snd_tscm *tscm); 155 int snd_tscm_transaction_reregister(struct snd_tscm *tscm);
+3 -3
sound/hda/ext/hdac_ext_controller.c
··· 171 { 172 int timeout; 173 u32 val; 174 - int mask = (1 << AZX_MLCTL_CPA); 175 176 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); 175 176 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
··· 272 273 /* Lets walk the linked capabilities list */ 274 do { 275 - cur_cap = _snd_hdac_chip_read(l, bus, offset); 276 277 dev_dbg(bus->dev, "Capability version: 0x%x\n", 278 (cur_cap & AZX_CAP_HDR_VER_MASK) >> AZX_CAP_HDR_VER_OFF);
··· 272 273 /* Lets walk the linked capabilities list */ 274 do { 275 + cur_cap = _snd_hdac_chip_readl(bus, offset); 276 277 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
··· 555 556 if (!reg) 557 reg = AZX_REG_SSYNC; 558 - val = _snd_hdac_chip_read(l, bus, reg); 559 if (set) 560 val |= streams; 561 else 562 val &= ~streams; 563 - _snd_hdac_chip_write(l, bus, reg, val); 564 } 565 EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger); 566
··· 555 556 if (!reg) 557 reg = AZX_REG_SSYNC; 558 + val = _snd_hdac_chip_readl(bus, reg); 559 if (set) 560 val |= streams; 561 else 562 val &= ~streams; 563 + _snd_hdac_chip_writel(bus, reg, val); 564 } 565 EXPORT_SYMBOL_GPL(snd_hdac_stream_sync_trigger); 566
+1 -1
sound/isa/es1688/es1688_lib.c
··· 742 743 pcm->private_data = chip; 744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 745 - sprintf(pcm->name, snd_es1688_chip_id(chip)); 746 chip->pcm = pcm; 747 748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
··· 742 743 pcm->private_data = chip; 744 pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX; 745 + strcpy(pcm->name, snd_es1688_chip_id(chip)); 746 chip->pcm = pcm; 747 748 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+1 -1
sound/pci/ali5451/ali5451.c
··· 1339 rate = snd_ali_get_spdif_in_rate(codec); 1340 if (rate == 0) { 1341 dev_warn(codec->card->dev, 1342 - "ali_capture_preapre: spdif rate detect err!\n"); 1343 rate = 48000; 1344 } 1345 spin_lock_irq(&codec->reg_lock);
··· 1339 rate = snd_ali_get_spdif_in_rate(codec); 1340 if (rate == 0) { 1341 dev_warn(codec->card->dev, 1342 + "ali_capture_prepare: spdif rate detect err!\n"); 1343 rate = 48000; 1344 } 1345 spin_lock_irq(&codec->reg_lock);
+1 -1
sound/pci/au88x0/au88x0_a3d.c
··· 846 return changed; 847 } 848 849 - static struct snd_kcontrol_new vortex_a3d_kcontrol = { 850 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 851 .name = "Playback PCM advanced processing", 852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
··· 846 return changed; 847 } 848 849 + static const struct snd_kcontrol_new vortex_a3d_kcontrol = { 850 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 851 .name = "Playback PCM advanced processing", 852 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+3
sound/pci/au88x0/au88x0_core.c
··· 2279 } else { 2280 int src[2], mix[2]; 2281 2282 /* 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]; 2281 2282 + 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] =
+3 -3
sound/pci/au88x0/au88x0_eq.c
··· 757 return 1; /* Allways changes */ 758 } 759 760 - static struct snd_kcontrol_new vortex_eqtoggle_kcontrol = { 761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 762 .name = "EQ Enable", 763 .index = 0, ··· 815 return changed; 816 } 817 818 - static struct snd_kcontrol_new vortex_eq_kcontrol = { 819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 820 .name = " .", 821 .index = 0, ··· 855 return 0; 856 } 857 858 - static struct snd_kcontrol_new vortex_levels_kcontrol = { 859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 860 .name = "EQ Peaks", 861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
··· 757 return 1; /* Allways changes */ 758 } 759 760 + static const struct snd_kcontrol_new vortex_eqtoggle_kcontrol = { 761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 762 .name = "EQ Enable", 763 .index = 0, ··· 815 return changed; 816 } 817 818 + static const struct snd_kcontrol_new vortex_eq_kcontrol = { 819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 820 .name = " .", 821 .index = 0, ··· 855 return 0; 856 } 857 858 + static const struct snd_kcontrol_new vortex_levels_kcontrol = { 859 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 860 .name = "EQ Peaks", 861 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+1 -1
sound/pci/au88x0/au88x0_pcm.c
··· 601 602 static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); 603 604 - static struct snd_kcontrol_new snd_vortex_pcm_vol = { 605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 606 .name = "PCM Playback Volume", 607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
··· 601 602 static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); 603 604 + static const struct snd_kcontrol_new snd_vortex_pcm_vol = { 605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 606 .name = "PCM Playback Volume", 607 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+1 -1
sound/pci/aw2/aw2-alsa.c
··· 202 .pointer = snd_aw2_pcm_pointer_capture, 203 }; 204 205 - static struct snd_kcontrol_new aw2_control = { 206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 207 .name = "PCM Capture Route", 208 .index = 0,
··· 202 .pointer = snd_aw2_pcm_pointer_capture, 203 }; 204 205 + static const struct snd_kcontrol_new aw2_control = { 206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 207 .name = "PCM Capture Route", 208 .index = 0,
+3 -3
sound/pci/bt87x.c
··· 598 return changed; 599 } 600 601 - static struct snd_kcontrol_new snd_bt87x_capture_volume = { 602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 603 .name = "Capture Volume", 604 .info = snd_bt87x_capture_volume_info, ··· 634 return changed; 635 } 636 637 - static struct snd_kcontrol_new snd_bt87x_capture_boost = { 638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 639 .name = "Capture Boost", 640 .info = snd_bt87x_capture_boost_info, ··· 676 return changed; 677 } 678 679 - static struct snd_kcontrol_new snd_bt87x_capture_source = { 680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 681 .name = "Capture Source", 682 .info = snd_bt87x_capture_source_info,
··· 598 return changed; 599 } 600 601 + static const struct snd_kcontrol_new snd_bt87x_capture_volume = { 602 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 603 .name = "Capture Volume", 604 .info = snd_bt87x_capture_volume_info, ··· 634 return changed; 635 } 636 637 + static const struct snd_kcontrol_new snd_bt87x_capture_boost = { 638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 639 .name = "Capture Boost", 640 .info = snd_bt87x_capture_boost_info, ··· 676 return changed; 677 } 678 679 + static const struct snd_kcontrol_new snd_bt87x_capture_source = { 680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 681 .name = "Capture Source", 682 .info = snd_bt87x_capture_source_info,
+2 -2
sound/pci/ca0106/ca0106_mixer.c
··· 301 return change; 302 } 303 304 - static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in = 305 { 306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 307 .name = "Shared Mic/Line in Capture Switch", ··· 310 .put = snd_ca0106_capture_mic_line_in_put 311 }; 312 313 - static struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out = 314 { 315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 316 .name = "Shared Line in/Side out Capture Switch",
··· 301 return change; 302 } 303 304 + static const struct snd_kcontrol_new snd_ca0106_capture_mic_line_in = 305 { 306 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 307 .name = "Shared Mic/Line in Capture Switch", ··· 310 .put = snd_ca0106_capture_mic_line_in_put 311 }; 312 313 + static const struct snd_kcontrol_new snd_ca0106_capture_line_in_side_out = 314 { 315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 316 .name = "Shared Line in/Side out Capture Switch",
+3 -3
sound/pci/cmipci.c
··· 1045 return change; 1046 } 1047 1048 - static struct snd_kcontrol_new snd_cmipci_spdif_default = 1049 { 1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1072 return 0; 1073 } 1074 1075 - static struct snd_kcontrol_new snd_cmipci_spdif_mask = 1076 { 1077 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1119 return change; 1120 } 1121 1122 - static struct snd_kcontrol_new snd_cmipci_spdif_stream = 1123 { 1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
··· 1045 return change; 1046 } 1047 1048 + static const struct snd_kcontrol_new snd_cmipci_spdif_default = 1049 { 1050 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1051 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1072 return 0; 1073 } 1074 1075 + static const struct snd_kcontrol_new snd_cmipci_spdif_mask = 1076 { 1077 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1078 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1119 return change; 1120 } 1121 1122 + static const struct snd_kcontrol_new snd_cmipci_spdif_stream = 1123 { 1124 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1125 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+2 -2
sound/pci/cs4281.c
··· 1055 1056 static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); 1057 1058 - static struct snd_kcontrol_new snd_cs4281_fm_vol = 1059 { 1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1061 .name = "Synth Playback Volume", ··· 1066 .tlv = { .p = db_scale_dsp }, 1067 }; 1068 1069 - static struct snd_kcontrol_new snd_cs4281_pcm_vol = 1070 { 1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1072 .name = "PCM Stream Playback Volume",
··· 1055 1056 static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); 1057 1058 + static const struct snd_kcontrol_new snd_cs4281_fm_vol = 1059 { 1060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1061 .name = "Synth Playback Volume", ··· 1066 .tlv = { .p = db_scale_dsp }, 1067 }; 1068 1069 + static const struct snd_kcontrol_new snd_cs4281_pcm_vol = 1070 { 1071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1072 .name = "PCM Stream Playback Volume",
+13 -13
sound/pci/echoaudio/echoaudio.c
··· 1039 1040 #ifdef ECHOCARD_HAS_LINE_OUT_GAIN 1041 /* On the Mia this one controls the line-out volume */ 1042 - static struct snd_kcontrol_new snd_echo_line_output_gain = { 1043 .name = "Line Playback Volume", 1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | ··· 1050 .tlv = {.p = db_scale_output_gain}, 1051 }; 1052 #else 1053 - static struct snd_kcontrol_new snd_echo_pcm_output_gain = { 1054 .name = "PCM Playback Volume", 1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 1120 1121 static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); 1122 1123 - static struct snd_kcontrol_new snd_echo_line_input_gain = { 1124 .name = "Line Capture Volume", 1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 1184 return changed; 1185 } 1186 1187 - static struct snd_kcontrol_new snd_echo_output_nominal_level = { 1188 .name = "Line Playback Switch (-10dBV)", 1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1190 .info = snd_echo_output_nominal_info, ··· 1250 return changed; 1251 } 1252 1253 - static struct snd_kcontrol_new snd_echo_intput_nominal_level = { 1254 .name = "Line Capture Switch (-10dBV)", 1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1256 .info = snd_echo_input_nominal_info, ··· 1477 return changed; 1478 } 1479 1480 - static struct snd_kcontrol_new snd_echo_digital_mode_switch = { 1481 .name = "Digital mode Switch", 1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1483 .info = snd_echo_digital_mode_info, ··· 1527 return 0; 1528 } 1529 1530 - static struct snd_kcontrol_new snd_echo_spdif_mode_switch = { 1531 .name = "S/PDIF mode Switch", 1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1533 .info = snd_echo_spdif_mode_info, ··· 1600 return changed; 1601 } 1602 1603 - static struct snd_kcontrol_new snd_echo_clock_source_switch = { 1604 .name = "Sample Clock Source", 1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1606 .info = snd_echo_clock_source_info, ··· 1643 return changed; 1644 } 1645 1646 - static struct snd_kcontrol_new snd_echo_phantom_power_switch = { 1647 .name = "Phantom power Switch", 1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1649 .info = snd_echo_phantom_power_info, ··· 1686 return changed; 1687 } 1688 1689 - static struct snd_kcontrol_new snd_echo_automute_switch = { 1690 .name = "Digital Capture Switch (automute)", 1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1692 .info = snd_echo_automute_info, ··· 1713 return 1; 1714 } 1715 1716 - static struct snd_kcontrol_new snd_echo_vumeters_switch = { 1717 .name = "VU-meters Switch", 1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE, ··· 1751 return 0; 1752 } 1753 1754 - static struct snd_kcontrol_new snd_echo_vumeters = { 1755 .name = "VU-meters", 1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ | ··· 1804 return 0; 1805 } 1806 1807 - static struct snd_kcontrol_new snd_echo_channels_info = { 1808 .name = "Channels info", 1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, 1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
··· 1039 1040 #ifdef ECHOCARD_HAS_LINE_OUT_GAIN 1041 /* On the Mia this one controls the line-out volume */ 1042 + static const struct snd_kcontrol_new snd_echo_line_output_gain = { 1043 .name = "Line Playback Volume", 1044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1045 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | ··· 1050 .tlv = {.p = db_scale_output_gain}, 1051 }; 1052 #else 1053 + static const struct snd_kcontrol_new snd_echo_pcm_output_gain = { 1054 .name = "PCM Playback Volume", 1055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1056 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 1120 1121 static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); 1122 1123 + static const struct snd_kcontrol_new snd_echo_line_input_gain = { 1124 .name = "Line Capture Volume", 1125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 1184 return changed; 1185 } 1186 1187 + static const struct snd_kcontrol_new snd_echo_output_nominal_level = { 1188 .name = "Line Playback Switch (-10dBV)", 1189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1190 .info = snd_echo_output_nominal_info, ··· 1250 return changed; 1251 } 1252 1253 + static const struct snd_kcontrol_new snd_echo_intput_nominal_level = { 1254 .name = "Line Capture Switch (-10dBV)", 1255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1256 .info = snd_echo_input_nominal_info, ··· 1477 return changed; 1478 } 1479 1480 + static const struct snd_kcontrol_new snd_echo_digital_mode_switch = { 1481 .name = "Digital mode Switch", 1482 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1483 .info = snd_echo_digital_mode_info, ··· 1527 return 0; 1528 } 1529 1530 + static const struct snd_kcontrol_new snd_echo_spdif_mode_switch = { 1531 .name = "S/PDIF mode Switch", 1532 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1533 .info = snd_echo_spdif_mode_info, ··· 1600 return changed; 1601 } 1602 1603 + static const struct snd_kcontrol_new snd_echo_clock_source_switch = { 1604 .name = "Sample Clock Source", 1605 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1606 .info = snd_echo_clock_source_info, ··· 1643 return changed; 1644 } 1645 1646 + static const struct snd_kcontrol_new snd_echo_phantom_power_switch = { 1647 .name = "Phantom power Switch", 1648 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1649 .info = snd_echo_phantom_power_info, ··· 1686 return changed; 1687 } 1688 1689 + static const struct snd_kcontrol_new snd_echo_automute_switch = { 1690 .name = "Digital Capture Switch (automute)", 1691 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1692 .info = snd_echo_automute_info, ··· 1713 return 1; 1714 } 1715 1716 + static const struct snd_kcontrol_new snd_echo_vumeters_switch = { 1717 .name = "VU-meters Switch", 1718 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1719 .access = SNDRV_CTL_ELEM_ACCESS_WRITE, ··· 1751 return 0; 1752 } 1753 1754 + static const struct snd_kcontrol_new snd_echo_vumeters = { 1755 .name = "VU-meters", 1756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ | ··· 1804 return 0; 1805 } 1806 1807 + static const struct snd_kcontrol_new snd_echo_channels_info = { 1808 .name = "Channels info", 1809 .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, 1810 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+3 -3
sound/pci/emu10k1/emu10k1x.c
··· 1112 return change; 1113 } 1114 1115 - static struct snd_kcontrol_new snd_emu10k1x_shared_spdif = 1116 { 1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1118 .name = "Analog/Digital Output Jack", ··· 1171 return change; 1172 } 1173 1174 - static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control = 1175 { 1176 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1181 .get = snd_emu10k1x_spdif_get_mask 1182 }; 1183 1184 - static struct snd_kcontrol_new snd_emu10k1x_spdif_control = 1185 { 1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
··· 1112 return change; 1113 } 1114 1115 + static const struct snd_kcontrol_new snd_emu10k1x_shared_spdif = 1116 { 1117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1118 .name = "Analog/Digital Output Jack", ··· 1171 return change; 1172 } 1173 1174 + static const struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control = 1175 { 1176 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1177 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1181 .get = snd_emu10k1x_spdif_get_mask 1182 }; 1183 1184 + static const struct snd_kcontrol_new snd_emu10k1x_spdif_control = 1185 { 1186 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1187 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+15 -15
sound/pci/emu10k1/emumixer.c
··· 795 return change; 796 } 797 798 - static struct snd_kcontrol_new snd_emu1010_internal_clock = 799 { 800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ··· 847 return change; 848 } 849 850 - static struct snd_kcontrol_new snd_emu1010_optical_out = { 851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 853 .name = "Optical Output Mode", ··· 898 return change; 899 } 900 901 - static struct snd_kcontrol_new snd_emu1010_optical_in = { 902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 904 .name = "Optical Input Mode", ··· 978 return change; 979 } 980 981 - static struct snd_kcontrol_new snd_audigy_i2c_capture_source = 982 { 983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 984 .name = "Capture Source", ··· 1177 return change; 1178 } 1179 1180 - static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = 1181 { 1182 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1187 .get = snd_emu10k1_spdif_get_mask 1188 }; 1189 1190 - static struct snd_kcontrol_new snd_emu10k1_spdif_control = 1191 { 1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1293 return change; 1294 } 1295 1296 - static struct snd_kcontrol_new snd_emu10k1_send_routing_control = 1297 { 1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1364 return change; 1365 } 1366 1367 - static struct snd_kcontrol_new snd_emu10k1_send_volume_control = 1368 { 1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1429 return change; 1430 } 1431 1432 - static struct snd_kcontrol_new snd_emu10k1_attn_control = 1433 { 1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1501 return change; 1502 } 1503 1504 - static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control = 1505 { 1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1568 } 1569 1570 1571 - static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control = 1572 { 1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1626 return change; 1627 } 1628 1629 - static struct snd_kcontrol_new snd_emu10k1_efx_attn_control = 1630 { 1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1691 return change; 1692 } 1693 1694 - static struct snd_kcontrol_new snd_emu10k1_shared_spdif = 1695 { 1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1697 .name = "SB Live Analog/Digital Output Jack", ··· 1700 .put = snd_emu10k1_shared_spdif_put 1701 }; 1702 1703 - static struct snd_kcontrol_new snd_audigy_shared_spdif = 1704 { 1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1706 .name = "Audigy Analog/Digital Output Jack", ··· 1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val); 1739 } 1740 1741 - static struct snd_kcontrol_new snd_audigy_capture_boost = 1742 { 1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1744 .name = "Mic Extra Boost",
··· 795 return change; 796 } 797 798 + static const struct snd_kcontrol_new snd_emu1010_internal_clock = 799 { 800 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 801 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, ··· 847 return change; 848 } 849 850 + static const struct snd_kcontrol_new snd_emu1010_optical_out = { 851 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 852 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 853 .name = "Optical Output Mode", ··· 898 return change; 899 } 900 901 + static const struct snd_kcontrol_new snd_emu1010_optical_in = { 902 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 904 .name = "Optical Input Mode", ··· 978 return change; 979 } 980 981 + static const struct snd_kcontrol_new snd_audigy_i2c_capture_source = 982 { 983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 984 .name = "Capture Source", ··· 1177 return change; 1178 } 1179 1180 + static const struct snd_kcontrol_new snd_emu10k1_spdif_mask_control = 1181 { 1182 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1183 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1187 .get = snd_emu10k1_spdif_get_mask 1188 }; 1189 1190 + static const struct snd_kcontrol_new snd_emu10k1_spdif_control = 1191 { 1192 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1193 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1293 return change; 1294 } 1295 1296 + static const struct snd_kcontrol_new snd_emu10k1_send_routing_control = 1297 { 1298 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1299 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1364 return change; 1365 } 1366 1367 + static const struct snd_kcontrol_new snd_emu10k1_send_volume_control = 1368 { 1369 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1370 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1429 return change; 1430 } 1431 1432 + static const struct snd_kcontrol_new snd_emu10k1_attn_control = 1433 { 1434 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1501 return change; 1502 } 1503 1504 + static const struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control = 1505 { 1506 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1507 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1568 } 1569 1570 1571 + static const struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control = 1572 { 1573 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1574 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1626 return change; 1627 } 1628 1629 + static const struct snd_kcontrol_new snd_emu10k1_efx_attn_control = 1630 { 1631 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1632 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1691 return change; 1692 } 1693 1694 + static const struct snd_kcontrol_new snd_emu10k1_shared_spdif = 1695 { 1696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1697 .name = "SB Live Analog/Digital Output Jack", ··· 1700 .put = snd_emu10k1_shared_spdif_put 1701 }; 1702 1703 + static const struct snd_kcontrol_new snd_audigy_shared_spdif = 1704 { 1705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1706 .name = "Audigy Analog/Digital Output Jack", ··· 1738 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val); 1739 } 1740 1741 + static const struct snd_kcontrol_new snd_audigy_capture_boost = 1742 { 1743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1744 .name = "Mic Extra Boost",
+1 -1
sound/pci/emu10k1/emupcm.c
··· 1542 return change; 1543 } 1544 1545 - static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = { 1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1547 .name = "Captured FX8010 Outputs", 1548 .info = snd_emu10k1_pcm_efx_voices_mask_info,
··· 1542 return change; 1543 } 1544 1545 + static const struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = { 1546 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1547 .name = "Captured FX8010 Outputs", 1548 .info = snd_emu10k1_pcm_efx_voices_mask_info,
+2 -2
sound/pci/ens1370.c
··· 1530 return change; 1531 } 1532 1533 - static struct snd_kcontrol_new snd_ens1373_rear = 1534 { 1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1536 .name = "AC97 2ch->4ch Copy Switch", ··· 1575 return changed; 1576 } 1577 1578 - static struct snd_kcontrol_new snd_ens1373_line = 1579 { 1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1581 .name = "Line In->Rear Out Switch",
··· 1530 return change; 1531 } 1532 1533 + static const struct snd_kcontrol_new snd_ens1373_rear = 1534 { 1535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1536 .name = "AC97 2ch->4ch Copy Switch", ··· 1575 return changed; 1576 } 1577 1578 + static const struct snd_kcontrol_new snd_ens1373_line = 1579 { 1580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1581 .name = "Line In->Rear Out Switch",
+1
sound/pci/hda/hda_auto_parser.c
··· 580 has_multiple_pins = 1; 581 if (has_multiple_pins && type == AUTO_PIN_MIC) 582 has_multiple_pins &= check_mic_location_need(codec, cfg, input); 583 return hda_get_input_pin_label(codec, &cfg->inputs[input], 584 cfg->inputs[input].pin, 585 has_multiple_pins);
··· 580 has_multiple_pins = 1; 581 if (has_multiple_pins && type == AUTO_PIN_MIC) 582 has_multiple_pins &= check_mic_location_need(codec, cfg, input); 583 + has_multiple_pins |= codec->force_pin_prefix; 584 return hda_get_input_pin_label(codec, &cfg->inputs[input], 585 cfg->inputs[input].pin, 586 has_multiple_pins);
+2 -2
sound/pci/hda/hda_codec.c
··· 1965 return 1; 1966 } 1967 1968 - static struct snd_kcontrol_new vmaster_mute_mode = { 1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1970 .name = "Mute-LED Mode", 1971 .info = vmaster_mute_mode_info, ··· 2705 return 0; 2706 } 2707 2708 - static struct snd_kcontrol_new spdif_share_sw = { 2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2710 .name = "IEC958 Default PCM Playback Switch", 2711 .info = snd_ctl_boolean_mono_info,
··· 1965 return 1; 1966 } 1967 1968 + static const struct snd_kcontrol_new vmaster_mute_mode = { 1969 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1970 .name = "Mute-LED Mode", 1971 .info = vmaster_mute_mode_info, ··· 2705 return 0; 2706 } 2707 2708 + static const struct snd_kcontrol_new spdif_share_sw = { 2709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2710 .name = "IEC958 Default PCM Playback Switch", 2711 .info = snd_ctl_boolean_mono_info,
+1
sound/pci/hda/hda_codec.h
··· 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 #ifdef CONFIG_PM 260 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_PM 261 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; 199 200 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) 201 spec->mixer_nid = val; ··· 1128 1129 *index = 0; 1130 if (cfg->line_outs == 1 && !spec->multi_ios && 1131 !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 && 1139 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0]) 1140 return spec->vmaster_mute.hook ? "PCM" : "Master"; 1141 ··· 5036 } 5037 5038 /* 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; 202 203 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val)) 204 spec->mixer_nid = val; ··· 1125 1126 *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 } 5032 5033 /* 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 */ 232 233 /* 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 */ 233 234 /* 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, 80 }; 81 82 /* Defines for ATI HD Audio support in SB450 south bridge */ ··· 149 MODULE_PARM_DESC(model, "Use the given board model."); 150 module_param_array(position_fix, int, NULL, 0444); 151 MODULE_PARM_DESC(position_fix, "DMA pointer read method." 152 - "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO)."); 153 module_param_array(bdl_pos_adj, int, NULL, 0644); 154 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 155 module_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) 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 376 static char *driver_short_names[] = { 377 [AZX_DRIVER_ICH] = "HDA Intel", ··· 537 { 538 u32 val; 539 540 - val = azx_readl(chip, SKL_EM4L); 541 val &= (0x3 << 20); 542 - azx_writel(chip, SKL_EM4L, val); 543 } 544 545 static 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); 662 } 663 664 /* calculate runtime delay from LPIB */ ··· 911 912 /* Calculate real DMA position we want */ 913 return bound_pos + mod_dma_pos; 914 } 915 916 #ifdef CONFIG_PM ··· 1474 case POS_FIX_POSBUF: 1475 case POS_FIX_VIACOMBO: 1476 case POS_FIX_COMBO: 1477 return fix; 1478 } 1479 ··· 1495 dev_dbg(chip->card->dev, "Using LPIB position fix\n"); 1496 return POS_FIX_LPIB; 1497 } 1498 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, 1513 }; 1514 1515 chip->get_position[0] = chip->get_position[1] = callbacks[fix]; ··· 1519 if (fix == POS_FIX_COMBO) 1520 chip->get_position[1] = NULL; 1521 1522 - 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 }; 82 83 /* Defines for ATI HD Audio support in SB450 south bridge */ ··· 148 MODULE_PARM_DESC(model, "Use the given board model."); 149 module_param_array(position_fix, int, NULL, 0444); 150 MODULE_PARM_DESC(position_fix, "DMA pointer read method." 151 + "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+)."); 152 module_param_array(bdl_pos_adj, int, NULL, 0644); 153 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 154 module_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) 376 377 static char *driver_short_names[] = { 378 [AZX_DRIVER_ICH] = "HDA Intel", ··· 534 { 535 u32 val; 536 537 + 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 Supported 545 + * bit 1: 12 MHz Supported 546 + * bit 2: 24 MHz Supported 547 + * bit 3: 48 MHz Supported 548 + * bit 4: 96 MHz Supported 549 + * bit 5: 192 MHz Supported 550 + */ 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 default 578 + * If other links are enabled for stream, they need similar fix 579 + */ 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 } 633 634 static 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 } 571 572 /* calculate runtime delay from LPIB */ ··· 813 814 /* 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 delay 835 + * for the possible boundary overlap; the read of DPIB fetches the 836 + * actual posbuf 837 + */ 838 + udelay(20); 839 + azx_skl_get_dpib_pos(chip, azx_dev); 840 + return azx_get_pos_posbuf(chip, azx_dev); 841 } 842 843 #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 }; 1387 1388 chip->get_position[0] = chip->get_position[1] = callbacks[fix]; ··· 1390 if (fix == POS_FIX_COMBO) 1391 chip->get_position[1] = NULL; 1392 1393 + 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 } 859 860 - spec->curr_chip_addx = (res < 0) ? ~0UL : chip_addx; 861 862 return res; 863 } ··· 882 /*If no error encountered, automatically increment the address 883 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 address 934 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; 1170 1171 - if ((buffer == NULL)) 1172 return -EINVAL; 1173 1174 count = 0; ··· 1210 unsigned int skip_count; 1211 unsigned int dummy; 1212 1213 - if ((buffer == NULL)) 1214 return -1; 1215 1216 count = 0;
··· 857 chip_addx >> 16); 858 } 859 860 + spec->curr_chip_addx = (res < 0) ? ~0U : chip_addx; 861 862 return res; 863 } ··· 882 /*If no error encountered, automatically increment the address 883 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 address 934 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; 1170 1171 + if (buffer == NULL) 1172 return -EINVAL; 1173 1174 count = 0; ··· 1210 unsigned int skip_count; 1211 unsigned int dummy; 1212 1213 + if (buffer == NULL) 1214 return -1; 1215 1216 count = 0;
+81
sound/pci/hda/patch_conexant.c
··· 52 bool dc_enable; 53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ 54 struct nid_path *dc_mode_path; 55 }; 56 57 ··· 270 CXT_FIXUP_HP_DOCK, 271 CXT_FIXUP_HP_SPECTRE, 272 CXT_FIXUP_HP_GATE_MIC, 273 }; 274 275 /* for hda_fixup_thinkpad_acpi() */ ··· 653 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); 654 } 655 656 /* ThinkPad X200 & co with cxt5051 */ 657 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 658 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ ··· 874 .type = HDA_FIXUP_FUNC, 875 .v.func = cxt_fixup_hp_gate_mic_jack, 876 }, 877 }; 878 879 static const struct snd_pci_quirk cxt5045_fixups[] = { ··· 930 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), 931 SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), 932 SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), 933 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 934 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 935 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), ··· 962 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, 963 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, 964 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, 965 {} 966 }; 967
··· 52 bool dc_enable; 53 unsigned int dc_input_bias; /* offset into olpc_xo_dc_bias */ 54 struct nid_path *dc_mode_path; 55 + 56 + int mute_led_polarity; 57 + unsigned int gpio_led; 58 + unsigned int gpio_mute_led_mask; 59 + unsigned int gpio_mic_led_mask; 60 + 61 }; 62 63 ··· 264 CXT_FIXUP_HP_DOCK, 265 CXT_FIXUP_HP_SPECTRE, 266 CXT_FIXUP_HP_GATE_MIC, 267 + CXT_FIXUP_MUTE_LED_GPIO, 268 }; 269 270 /* for hda_fixup_thinkpad_acpi() */ ··· 646 snd_hda_jack_set_gating_jack(codec, 0x19, 0x16); 647 } 648 649 + /* update LED status via GPIO */ 650 + static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask, 651 + bool enabled) 652 + { 653 + struct conexant_spec *spec = codec->spec; 654 + unsigned int oldval = spec->gpio_led; 655 + 656 + if (spec->mute_led_polarity) 657 + enabled = !enabled; 658 + 659 + if (enabled) 660 + spec->gpio_led &= ~mask; 661 + else 662 + spec->gpio_led |= mask; 663 + if (spec->gpio_led != oldval) 664 + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 665 + spec->gpio_led); 666 + } 667 + 668 + /* turn on/off mute LED via GPIO per vmaster hook */ 669 + static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled) 670 + { 671 + struct hda_codec *codec = private_data; 672 + struct conexant_spec *spec = codec->spec; 673 + 674 + cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled); 675 + } 676 + 677 + /* turn on/off mic-mute LED via GPIO per capture hook */ 678 + static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec, 679 + struct snd_kcontrol *kcontrol, 680 + struct snd_ctl_elem_value *ucontrol) 681 + { 682 + struct conexant_spec *spec = codec->spec; 683 + 684 + if (ucontrol) 685 + cxt_update_gpio_led(codec, spec->gpio_mic_led_mask, 686 + ucontrol->value.integer.value[0] || 687 + ucontrol->value.integer.value[1]); 688 + } 689 + 690 + 691 + static void cxt_fixup_mute_led_gpio(struct hda_codec *codec, 692 + const struct hda_fixup *fix, int action) 693 + { 694 + struct conexant_spec *spec = codec->spec; 695 + static const struct hda_verb gpio_init[] = { 696 + { 0x01, AC_VERB_SET_GPIO_MASK, 0x03 }, 697 + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 }, 698 + {} 699 + }; 700 + codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led); 701 + 702 + if (action == HDA_FIXUP_ACT_PRE_PROBE) { 703 + spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook; 704 + spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook; 705 + spec->gpio_led = 0; 706 + spec->mute_led_polarity = 0; 707 + spec->gpio_mute_led_mask = 0x01; 708 + spec->gpio_mic_led_mask = 0x02; 709 + } 710 + snd_hda_add_verbs(codec, gpio_init); 711 + if (spec->gpio_led) 712 + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 713 + spec->gpio_led); 714 + } 715 + 716 + 717 /* ThinkPad X200 & co with cxt5051 */ 718 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 719 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ ··· 799 .type = HDA_FIXUP_FUNC, 800 .v.func = cxt_fixup_hp_gate_mic_jack, 801 }, 802 + [CXT_FIXUP_MUTE_LED_GPIO] = { 803 + .type = HDA_FIXUP_FUNC, 804 + .v.func = cxt_fixup_mute_led_gpio, 805 + }, 806 }; 807 808 static const struct snd_pci_quirk cxt5045_fixups[] = { ··· 851 SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), 852 SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE), 853 SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC), 854 + SND_PCI_QUIRK(0x103c, 0x814f, "HP ZBook 15u G3", CXT_FIXUP_MUTE_LED_GPIO), 855 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 856 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO), 857 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), ··· 882 { .id = CXT_FIXUP_OLPC_XO, .name = "olpc-xo" }, 883 { .id = CXT_FIXUP_MUTE_LED_EAPD, .name = "mute-led-eapd" }, 884 { .id = CXT_FIXUP_HP_DOCK, .name = "hp-dock" }, 885 + { .id = CXT_FIXUP_MUTE_LED_GPIO, .name = "mute-led-gpio" }, 886 {} 887 }; 888
+22 -7
sound/pci/hda/patch_hdmi.c
··· 177 bool i915_bound; /* was i915 bound in this driver? */ 178 179 struct hdac_chmap chmap; 180 }; 181 182 #ifdef CONFIG_SND_HDA_I915 ··· 384 return 0; 385 } 386 387 - static struct snd_kcontrol_new eld_bytes_ctl = { 388 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 389 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 390 .name = "ELD", ··· 2373 } 2374 2375 #define INTEL_VENDOR_NID 0x08 2376 #define INTEL_GET_VENDOR_VERB 0xf81 2377 #define INTEL_SET_VENDOR_VERB 0x781 2378 #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ ··· 2383 bool update_tree) 2384 { 2385 unsigned int vendor_param; 2386 2387 - vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2388 INTEL_GET_VENDOR_VERB, 0); 2389 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) 2390 return; 2391 2392 vendor_param |= INTEL_EN_ALL_PIN_CVTS; 2393 - vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2394 INTEL_SET_VENDOR_VERB, vendor_param); 2395 if (vendor_param == -1) 2396 return; ··· 2403 static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec) 2404 { 2405 unsigned int vendor_param; 2406 2407 - vendor_param = snd_hda_codec_read(codec, INTEL_VENDOR_NID, 0, 2408 INTEL_GET_VENDOR_VERB, 0); 2409 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) 2410 return; ··· 2413 /* enable DP1.2 mode */ 2414 vendor_param |= INTEL_EN_DP12; 2415 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB); 2416 - snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0, 2417 INTEL_SET_VENDOR_VERB, vendor_param); 2418 } 2419 ··· 2507 } 2508 2509 /* Intel Haswell and onwards; audio component with eld notifier */ 2510 - static int patch_i915_hsw_hdmi(struct hda_codec *codec) 2511 { 2512 struct hdmi_spec *spec; 2513 int err; ··· 2524 spec = codec->spec; 2525 codec->dp_mst = true; 2526 spec->dyn_pcm_assign = true; 2527 2528 intel_haswell_enable_all_pins(codec, true); 2529 intel_haswell_fixup_enable_dp12(codec); ··· 2551 generic_hdmi_init_per_pins(codec); 2552 register_i915_notifier(codec); 2553 return 0; 2554 } 2555 2556 /* Intel Baytrail and Braswell; with eld notifier */ ··· 3815 HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), 3816 HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), 3817 HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), 3818 - HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_hsw_hdmi), 3819 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), 3820 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), 3821 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
··· 177 bool i915_bound; /* was i915 bound in this driver? */ 178 179 struct hdac_chmap chmap; 180 + hda_nid_t vendor_nid; 181 }; 182 183 #ifdef CONFIG_SND_HDA_I915 ··· 383 return 0; 384 } 385 386 + static const struct snd_kcontrol_new eld_bytes_ctl = { 387 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 388 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 389 .name = "ELD", ··· 2372 } 2373 2374 #define INTEL_VENDOR_NID 0x08 2375 + #define INTEL_GLK_VENDOR_NID 0x0B 2376 #define INTEL_GET_VENDOR_VERB 0xf81 2377 #define INTEL_SET_VENDOR_VERB 0x781 2378 #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ ··· 2381 bool update_tree) 2382 { 2383 unsigned int vendor_param; 2384 + struct hdmi_spec *spec = codec->spec; 2385 2386 + vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0, 2387 INTEL_GET_VENDOR_VERB, 0); 2388 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) 2389 return; 2390 2391 vendor_param |= INTEL_EN_ALL_PIN_CVTS; 2392 + vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0, 2393 INTEL_SET_VENDOR_VERB, vendor_param); 2394 if (vendor_param == -1) 2395 return; ··· 2400 static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec) 2401 { 2402 unsigned int vendor_param; 2403 + struct hdmi_spec *spec = codec->spec; 2404 2405 + vendor_param = snd_hda_codec_read(codec, spec->vendor_nid, 0, 2406 INTEL_GET_VENDOR_VERB, 0); 2407 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) 2408 return; ··· 2409 /* enable DP1.2 mode */ 2410 vendor_param |= INTEL_EN_DP12; 2411 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB); 2412 + snd_hda_codec_write_cache(codec, spec->vendor_nid, 0, 2413 INTEL_SET_VENDOR_VERB, vendor_param); 2414 } 2415 ··· 2503 } 2504 2505 /* Intel Haswell and onwards; audio component with eld notifier */ 2506 + static int intel_hsw_common_init(struct hda_codec *codec, hda_nid_t vendor_nid) 2507 { 2508 struct hdmi_spec *spec; 2509 int err; ··· 2520 spec = codec->spec; 2521 codec->dp_mst = true; 2522 spec->dyn_pcm_assign = true; 2523 + spec->vendor_nid = vendor_nid; 2524 2525 intel_haswell_enable_all_pins(codec, true); 2526 intel_haswell_fixup_enable_dp12(codec); ··· 2546 generic_hdmi_init_per_pins(codec); 2547 register_i915_notifier(codec); 2548 return 0; 2549 + } 2550 + 2551 + static int patch_i915_hsw_hdmi(struct hda_codec *codec) 2552 + { 2553 + return intel_hsw_common_init(codec, INTEL_VENDOR_NID); 2554 + } 2555 + 2556 + static int patch_i915_glk_hdmi(struct hda_codec *codec) 2557 + { 2558 + return intel_hsw_common_init(codec, INTEL_GLK_VENDOR_NID); 2559 } 2560 2561 /* Intel Baytrail and Braswell; with eld notifier */ ··· 3800 HDA_CODEC_ENTRY(0x80862809, "Skylake HDMI", patch_i915_hsw_hdmi), 3801 HDA_CODEC_ENTRY(0x8086280a, "Broxton HDMI", patch_i915_hsw_hdmi), 3802 HDA_CODEC_ENTRY(0x8086280b, "Kabylake HDMI", patch_i915_hsw_hdmi), 3803 + HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi), 3804 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi), 3805 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI", patch_i915_byt_hdmi), 3806 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI", patch_i915_byt_hdmi),
+212 -9
sound/pci/hda/patch_realtek.c
··· 1800 ALC882_FIXUP_NO_PRIMARY_HP, 1801 ALC887_FIXUP_ASUS_BASS, 1802 ALC887_FIXUP_BASS_CHMAP, 1803 }; 1804 1805 static void alc889_fixup_coef(struct hda_codec *codec, ··· 1962 1963 static void alc_fixup_bass_chmap(struct hda_codec *codec, 1964 const struct hda_fixup *fix, int action); 1965 1966 static const struct hda_fixup alc882_fixups[] = { 1967 [ALC882_FIXUP_ABIT_AW9D_MAX] = { ··· 2254 .type = HDA_FIXUP_FUNC, 2255 .v.func = alc_fixup_bass_chmap, 2256 }, 2257 }; 2258 2259 static const struct snd_pci_quirk alc882_fixup_tbl[] = { ··· 2327 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2328 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2329 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), 2330 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2331 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2332 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), ··· 4724 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4725 {} 4726 }; 4727 - struct snd_kcontrol *kctl; 4728 4729 switch (action) { 4730 case HDA_FIXUP_ACT_PRE_PROBE: ··· 4738 /* this is a bit tricky; give more sane names for the main 4739 * (tablet) speaker and the dock speaker, respectively 4740 */ 4741 - kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); 4742 - if (kctl) 4743 - strcpy(kctl->id.name, "Dock Speaker Playback Switch"); 4744 - kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); 4745 - if (kctl) 4746 - strcpy(kctl->id.name, "Speaker Playback Switch"); 4747 break; 4748 } 4749 } ··· 4824 } 4825 } 4826 4827 /* for hda_fixup_thinkpad_acpi() */ 4828 #include "thinkpad_helper.c" 4829 ··· 4915 ALC290_FIXUP_SUBWOOFER_HSJACK, 4916 ALC269_FIXUP_THINKPAD_ACPI, 4917 ALC269_FIXUP_DMIC_THINKPAD_ACPI, 4918 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4919 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4920 ALC255_FIXUP_HEADSET_MODE, ··· 4956 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, 4957 ALC269_FIXUP_ATIV_BOOK_8, 4958 ALC221_FIXUP_HP_MIC_NO_PRESENCE, 4959 }; 4960 4961 static const struct hda_fixup alc269_fixups[] = { ··· 5379 .chained = true, 5380 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5381 }, 5382 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5383 .type = HDA_FIXUP_PINS, 5384 .v.pins = (const struct hda_pintbl[]) { ··· 5687 .chained = true, 5688 .chain_id = ALC269_FIXUP_HEADSET_MODE 5689 }, 5690 }; 5691 5692 static const struct snd_pci_quirk alc269_fixup_tbl[] = { ··· 5848 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 5849 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5850 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5851 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 5852 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5853 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5854 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), 5855 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), 5856 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 5857 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 5858 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 5859 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5860 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 5861 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 5862 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), ··· 5889 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), 5890 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), 5891 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), 5892 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 5893 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 5894 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), ··· 6044 {0x21, 0x03211020} 6045 6046 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 6047 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 6048 ALC225_STANDARD_PINS, 6049 {0x12, 0xb7a60130}, ··· 6176 {0x21, 0x02211020}), 6177 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 6178 ALC256_STANDARD_PINS), 6179 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 6180 {0x12, 0x90a60130}, 6181 {0x14, 0x90170110}, ··· 6903 ALC668_FIXUP_DELL_DISABLE_AAMIX, 6904 ALC668_FIXUP_DELL_XPS13, 6905 ALC662_FIXUP_ASUS_Nx50, 6906 ALC668_FIXUP_ASUS_Nx51, 6907 ALC891_FIXUP_HEADSET_MODE, 6908 ALC891_FIXUP_DELL_MIC_NO_PRESENCE, ··· 6911 ALC892_FIXUP_ASROCK_MOBO, 6912 ALC662_FIXUP_USI_FUNC, 6913 ALC662_FIXUP_USI_HEADSET_MODE, 6914 }; 6915 6916 static const struct hda_fixup alc662_fixups[] = { ··· 7158 .chained = true, 7159 .chain_id = ALC662_FIXUP_BASS_1A 7160 }, 7161 [ALC668_FIXUP_ASUS_Nx51] = { 7162 .type = HDA_FIXUP_PINS, 7163 .v.pins = (const struct hda_pintbl[]) { 7164 - {0x1a, 0x90170151}, /* bass speaker */ 7165 {} 7166 }, 7167 .chained = true, 7168 - .chain_id = ALC662_FIXUP_BASS_CHMAP, 7169 }, 7170 [ALC891_FIXUP_HEADSET_MODE] = { 7171 .type = HDA_FIXUP_FUNC, ··· 7217 .chained = true, 7218 .chain_id = ALC662_FIXUP_USI_FUNC 7219 }, 7220 }; 7221 7222 static const struct snd_pci_quirk alc662_fixup_tbl[] = { ··· 7258 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 7259 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 7260 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 7261 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 7262 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 7263 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
··· 1800 ALC882_FIXUP_NO_PRIMARY_HP, 1801 ALC887_FIXUP_ASUS_BASS, 1802 ALC887_FIXUP_BASS_CHMAP, 1803 + ALC1220_FIXUP_GB_DUAL_CODECS, 1804 }; 1805 1806 static void alc889_fixup_coef(struct hda_codec *codec, ··· 1961 1962 static void alc_fixup_bass_chmap(struct hda_codec *codec, 1963 const struct hda_fixup *fix, int action); 1964 + 1965 + /* For dual-codec configuration, we need to disable some features to avoid 1966 + * conflicts of kctls and PCM streams 1967 + */ 1968 + static void alc_fixup_dual_codecs(struct hda_codec *codec, 1969 + const struct hda_fixup *fix, int action) 1970 + { 1971 + struct alc_spec *spec = codec->spec; 1972 + 1973 + if (action != HDA_FIXUP_ACT_PRE_PROBE) 1974 + return; 1975 + /* disable vmaster */ 1976 + spec->gen.suppress_vmaster = 1; 1977 + /* auto-mute and auto-mic switch don't work with multiple codecs */ 1978 + spec->gen.suppress_auto_mute = 1; 1979 + spec->gen.suppress_auto_mic = 1; 1980 + /* disable aamix as well */ 1981 + spec->gen.mixer_nid = 0; 1982 + /* add location prefix to avoid conflicts */ 1983 + codec->force_pin_prefix = 1; 1984 + } 1985 + 1986 + static void rename_ctl(struct hda_codec *codec, const char *oldname, 1987 + const char *newname) 1988 + { 1989 + struct snd_kcontrol *kctl; 1990 + 1991 + kctl = snd_hda_find_mixer_ctl(codec, oldname); 1992 + if (kctl) 1993 + strcpy(kctl->id.name, newname); 1994 + } 1995 + 1996 + static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, 1997 + const struct hda_fixup *fix, 1998 + int action) 1999 + { 2000 + alc_fixup_dual_codecs(codec, fix, action); 2001 + switch (action) { 2002 + case HDA_FIXUP_ACT_PRE_PROBE: 2003 + /* override card longname to provide a unique UCM profile */ 2004 + strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs"); 2005 + break; 2006 + case HDA_FIXUP_ACT_BUILD: 2007 + /* rename Capture controls depending on the codec */ 2008 + rename_ctl(codec, "Capture Volume", 2009 + codec->addr == 0 ? 2010 + "Rear-Panel Capture Volume" : 2011 + "Front-Panel Capture Volume"); 2012 + rename_ctl(codec, "Capture Switch", 2013 + codec->addr == 0 ? 2014 + "Rear-Panel Capture Switch" : 2015 + "Front-Panel Capture Switch"); 2016 + break; 2017 + } 2018 + } 2019 2020 static const struct hda_fixup alc882_fixups[] = { 2021 [ALC882_FIXUP_ABIT_AW9D_MAX] = { ··· 2198 .type = HDA_FIXUP_FUNC, 2199 .v.func = alc_fixup_bass_chmap, 2200 }, 2201 + [ALC1220_FIXUP_GB_DUAL_CODECS] = { 2202 + .type = HDA_FIXUP_FUNC, 2203 + .v.func = alc1220_fixup_gb_dual_codecs, 2204 + }, 2205 }; 2206 2207 static const struct snd_pci_quirk alc882_fixup_tbl[] = { ··· 2267 SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), 2268 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 2269 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), 2270 + SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), 2271 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), 2272 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), 2273 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), ··· 4663 { 0x1b, 0x21114000 }, /* dock speaker pin */ 4664 {} 4665 }; 4666 4667 switch (action) { 4668 case HDA_FIXUP_ACT_PRE_PROBE: ··· 4678 /* this is a bit tricky; give more sane names for the main 4679 * (tablet) speaker and the dock speaker, respectively 4680 */ 4681 + rename_ctl(codec, "Speaker Playback Switch", 4682 + "Dock Speaker Playback Switch"); 4683 + rename_ctl(codec, "Bass Speaker Playback Switch", 4684 + "Speaker Playback Switch"); 4685 break; 4686 } 4687 } ··· 4766 } 4767 } 4768 4769 + static void alc233_alc662_fixup_lenovo_dual_codecs(struct hda_codec *codec, 4770 + const struct hda_fixup *fix, 4771 + int action) 4772 + { 4773 + alc_fixup_dual_codecs(codec, fix, action); 4774 + switch (action) { 4775 + case HDA_FIXUP_ACT_PRE_PROBE: 4776 + /* override card longname to provide a unique UCM profile */ 4777 + strcpy(codec->card->longname, "HDAudio-Lenovo-DualCodecs"); 4778 + break; 4779 + case HDA_FIXUP_ACT_BUILD: 4780 + /* rename Capture controls depending on the codec */ 4781 + rename_ctl(codec, "Capture Volume", 4782 + codec->addr == 0 ? 4783 + "Rear-Panel Capture Volume" : 4784 + "Front-Panel Capture Volume"); 4785 + rename_ctl(codec, "Capture Switch", 4786 + codec->addr == 0 ? 4787 + "Rear-Panel Capture Switch" : 4788 + "Front-Panel Capture Switch"); 4789 + break; 4790 + } 4791 + } 4792 + 4793 /* for hda_fixup_thinkpad_acpi() */ 4794 #include "thinkpad_helper.c" 4795 ··· 4833 ALC290_FIXUP_SUBWOOFER_HSJACK, 4834 ALC269_FIXUP_THINKPAD_ACPI, 4835 ALC269_FIXUP_DMIC_THINKPAD_ACPI, 4836 + ALC255_FIXUP_ACER_MIC_NO_PRESENCE, 4837 + ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, 4838 ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 4839 ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, 4840 ALC255_FIXUP_HEADSET_MODE, ··· 4872 ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, 4873 ALC269_FIXUP_ATIV_BOOK_8, 4874 ALC221_FIXUP_HP_MIC_NO_PRESENCE, 4875 + ALC256_FIXUP_ASUS_HEADSET_MODE, 4876 + ALC256_FIXUP_ASUS_MIC, 4877 + ALC256_FIXUP_ASUS_AIO_GPIO2, 4878 + ALC233_FIXUP_ASUS_MIC_NO_PRESENCE, 4879 + ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE, 4880 + ALC233_FIXUP_LENOVO_MULTI_CODECS, 4881 }; 4882 4883 static const struct hda_fixup alc269_fixups[] = { ··· 5289 .chained = true, 5290 .chain_id = ALC269_FIXUP_THINKPAD_ACPI, 5291 }, 5292 + [ALC255_FIXUP_ACER_MIC_NO_PRESENCE] = { 5293 + .type = HDA_FIXUP_PINS, 5294 + .v.pins = (const struct hda_pintbl[]) { 5295 + { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5296 + { } 5297 + }, 5298 + .chained = true, 5299 + .chain_id = ALC255_FIXUP_HEADSET_MODE 5300 + }, 5301 + [ALC255_FIXUP_ASUS_MIC_NO_PRESENCE] = { 5302 + .type = HDA_FIXUP_PINS, 5303 + .v.pins = (const struct hda_pintbl[]) { 5304 + { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5305 + { } 5306 + }, 5307 + .chained = true, 5308 + .chain_id = ALC255_FIXUP_HEADSET_MODE 5309 + }, 5310 [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { 5311 .type = HDA_FIXUP_PINS, 5312 .v.pins = (const struct hda_pintbl[]) { ··· 5579 .chained = true, 5580 .chain_id = ALC269_FIXUP_HEADSET_MODE 5581 }, 5582 + [ALC256_FIXUP_ASUS_HEADSET_MODE] = { 5583 + .type = HDA_FIXUP_FUNC, 5584 + .v.func = alc_fixup_headset_mode, 5585 + }, 5586 + [ALC256_FIXUP_ASUS_MIC] = { 5587 + .type = HDA_FIXUP_PINS, 5588 + .v.pins = (const struct hda_pintbl[]) { 5589 + { 0x13, 0x90a60160 }, /* use as internal mic */ 5590 + { 0x19, 0x04a11120 }, /* use as headset mic, without its own jack detect */ 5591 + { } 5592 + }, 5593 + .chained = true, 5594 + .chain_id = ALC256_FIXUP_ASUS_HEADSET_MODE 5595 + }, 5596 + [ALC256_FIXUP_ASUS_AIO_GPIO2] = { 5597 + .type = HDA_FIXUP_VERBS, 5598 + .v.verbs = (const struct hda_verb[]) { 5599 + /* Set up GPIO2 for the speaker amp */ 5600 + { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, 5601 + { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, 5602 + { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, 5603 + {} 5604 + }, 5605 + }, 5606 + [ALC233_FIXUP_ASUS_MIC_NO_PRESENCE] = { 5607 + .type = HDA_FIXUP_PINS, 5608 + .v.pins = (const struct hda_pintbl[]) { 5609 + { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ 5610 + { } 5611 + }, 5612 + .chained = true, 5613 + .chain_id = ALC269_FIXUP_HEADSET_MIC 5614 + }, 5615 + [ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE] = { 5616 + .type = HDA_FIXUP_VERBS, 5617 + .v.verbs = (const struct hda_verb[]) { 5618 + /* Enables internal speaker */ 5619 + {0x20, AC_VERB_SET_COEF_INDEX, 0x40}, 5620 + {0x20, AC_VERB_SET_PROC_COEF, 0x8800}, 5621 + {} 5622 + }, 5623 + .chained = true, 5624 + .chain_id = ALC233_FIXUP_ASUS_MIC_NO_PRESENCE 5625 + }, 5626 + [ALC233_FIXUP_LENOVO_MULTI_CODECS] = { 5627 + .type = HDA_FIXUP_FUNC, 5628 + .v.func = alc233_alc662_fixup_lenovo_dual_codecs, 5629 + }, 5630 }; 5631 5632 static const struct snd_pci_quirk alc269_fixup_tbl[] = { ··· 5692 SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC), 5693 SND_PCI_QUIRK(0x103c, 0x82bf, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5694 SND_PCI_QUIRK(0x103c, 0x82c0, "HP", ALC221_FIXUP_HP_MIC_NO_PRESENCE), 5695 + SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), 5696 SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), 5697 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5698 + SND_PCI_QUIRK(0x1043, 0x10c0, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), 5699 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5700 + SND_PCI_QUIRK(0x1043, 0x12f0, "ASUS X541UV", ALC256_FIXUP_ASUS_MIC), 5701 + SND_PCI_QUIRK(0x1043, 0x12e0, "ASUS X541SA", ALC256_FIXUP_ASUS_MIC), 5702 + SND_PCI_QUIRK(0x1043, 0x13b0, "ASUS Z550SA", ALC256_FIXUP_ASUS_MIC), 5703 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), 5704 SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), 5705 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 5706 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 5707 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), 5708 SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 5709 + SND_PCI_QUIRK(0x1043, 0x1bbd, "ASUS Z550MA", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), 5710 + SND_PCI_QUIRK(0x1043, 0x10d0, "ASUS X540LA/X540LJ", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), 5711 + SND_PCI_QUIRK(0x1043, 0x11c0, "ASUS X556UR", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE), 5712 + SND_PCI_QUIRK(0x1043, 0x1290, "ASUS X441SA", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), 5713 + SND_PCI_QUIRK(0x1043, 0x12a0, "ASUS X441UV", ALC233_FIXUP_EAPD_COEF_AND_MIC_NO_PRESENCE), 5714 + SND_PCI_QUIRK(0x1043, 0x1ccd, "ASUS X555UB", ALC256_FIXUP_ASUS_MIC), 5715 + SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), 5716 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 5717 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 5718 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), ··· 5721 SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), 5722 SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), 5723 SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), 5724 + SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), 5725 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 5726 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 5727 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), ··· 5875 {0x21, 0x03211020} 5876 5877 static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { 5878 + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1025, "Acer", ALC255_FIXUP_ACER_MIC_NO_PRESENCE, 5879 + {0x12, 0x90a601c0}, 5880 + {0x14, 0x90171120}, 5881 + {0x21, 0x02211030}), 5882 + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, 5883 + {0x14, 0x90170110}, 5884 + {0x1b, 0x90a70130}, 5885 + {0x21, 0x03211020}), 5886 + SND_HDA_PIN_QUIRK(0x10ec0255, 0x1043, "ASUS", ALC255_FIXUP_ASUS_MIC_NO_PRESENCE, 5887 + {0x1a, 0x90a70130}, 5888 + {0x1b, 0x90170110}, 5889 + {0x21, 0x03211020}), 5890 SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE, 5891 ALC225_STANDARD_PINS, 5892 {0x12, 0xb7a60130}, ··· 5995 {0x21, 0x02211020}), 5996 SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, 5997 ALC256_STANDARD_PINS), 5998 + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, 5999 + {0x14, 0x90170110}, 6000 + {0x1b, 0x90a70130}, 6001 + {0x21, 0x04211020}), 6002 + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1043, "ASUS", ALC256_FIXUP_ASUS_MIC, 6003 + {0x14, 0x90170110}, 6004 + {0x1b, 0x90a70130}, 6005 + {0x21, 0x03211020}), 6006 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 6007 {0x12, 0x90a60130}, 6008 {0x14, 0x90170110}, ··· 6714 ALC668_FIXUP_DELL_DISABLE_AAMIX, 6715 ALC668_FIXUP_DELL_XPS13, 6716 ALC662_FIXUP_ASUS_Nx50, 6717 + ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE, 6718 ALC668_FIXUP_ASUS_Nx51, 6719 ALC891_FIXUP_HEADSET_MODE, 6720 ALC891_FIXUP_DELL_MIC_NO_PRESENCE, ··· 6721 ALC892_FIXUP_ASROCK_MOBO, 6722 ALC662_FIXUP_USI_FUNC, 6723 ALC662_FIXUP_USI_HEADSET_MODE, 6724 + ALC662_FIXUP_LENOVO_MULTI_CODECS, 6725 }; 6726 6727 static const struct hda_fixup alc662_fixups[] = { ··· 6967 .chained = true, 6968 .chain_id = ALC662_FIXUP_BASS_1A 6969 }, 6970 + [ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE] = { 6971 + .type = HDA_FIXUP_FUNC, 6972 + .v.func = alc_fixup_headset_mode_alc668, 6973 + .chain_id = ALC662_FIXUP_BASS_CHMAP 6974 + }, 6975 [ALC668_FIXUP_ASUS_Nx51] = { 6976 .type = HDA_FIXUP_PINS, 6977 .v.pins = (const struct hda_pintbl[]) { 6978 + { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 6979 + { 0x1a, 0x90170151 }, /* bass speaker */ 6980 + { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ 6981 {} 6982 }, 6983 .chained = true, 6984 + .chain_id = ALC668_FIXUP_ASUS_Nx51_HEADSET_MODE, 6985 }, 6986 [ALC891_FIXUP_HEADSET_MODE] = { 6987 .type = HDA_FIXUP_FUNC, ··· 7019 .chained = true, 7020 .chain_id = ALC662_FIXUP_USI_FUNC 7021 }, 7022 + [ALC662_FIXUP_LENOVO_MULTI_CODECS] = { 7023 + .type = HDA_FIXUP_FUNC, 7024 + .v.func = alc233_alc662_fixup_lenovo_dual_codecs, 7025 + }, 7026 }; 7027 7028 static const struct snd_pci_quirk alc662_fixup_tbl[] = { ··· 7056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 7057 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 7058 SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), 7059 + SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), 7060 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 7061 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 7062 SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+1 -1
sound/pci/ice1712/delta.c
··· 432 return 0; 433 } 434 435 - static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = 436 { 437 .access = (SNDRV_CTL_ELEM_ACCESS_READ), 438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
··· 432 return 0; 433 } 434 435 + static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status = 436 { 437 .access = (SNDRV_CTL_ELEM_ACCESS_READ), 438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+2 -2
sound/pci/ice1712/ews.c
··· 719 return ndata != data; 720 } 721 722 - static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = { 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 724 .name = "Input Sensitivity Switch", 725 .info = snd_ice1712_ewx_io_sense_info, ··· 728 .count = 8, 729 }; 730 731 - static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = { 732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 733 .name = "Output Sensitivity Switch", 734 .info = snd_ice1712_ewx_io_sense_info,
··· 719 return ndata != data; 720 } 721 722 + static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense = { 723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 724 .name = "Input Sensitivity Switch", 725 .info = snd_ice1712_ewx_io_sense_info, ··· 728 .count = 8, 729 }; 730 731 + static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense = { 732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 733 .name = "Output Sensitivity Switch", 734 .info = snd_ice1712_ewx_io_sense_info,
+15 -15
sound/pci/ice1712/ice1712.c
··· 279 return val != nval; 280 } 281 282 - static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = { 283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 284 .name = "Digital Mixer To AC97", 285 .info = snd_ice1712_digmix_route_ac97_info, ··· 1410 .private_value = 10, 1411 }; 1412 1413 - static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = { 1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), 1416 .info = snd_ice1712_pro_mixer_switch_info, ··· 1432 .tlv = { .p = db_scale_playback } 1433 }; 1434 1435 - static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = { 1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), 1438 .info = snd_ice1712_pro_mixer_volume_info, ··· 1630 return 0; 1631 } 1632 1633 - static struct snd_kcontrol_new snd_ice1712_eeprom = { 1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1635 .name = "ICE1712 EEPROM", 1636 .access = SNDRV_CTL_ELEM_ACCESS_READ, ··· 1666 return 0; 1667 } 1668 1669 - static struct snd_kcontrol_new snd_ice1712_spdif_default = 1670 { 1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), ··· 1717 return 0; 1718 } 1719 1720 - static struct snd_kcontrol_new snd_ice1712_spdif_maskc = 1721 { 1722 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1726 .get = snd_ice1712_spdif_maskc_get, 1727 }; 1728 1729 - static struct snd_kcontrol_new snd_ice1712_spdif_maskp = 1730 { 1731 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1753 return 0; 1754 } 1755 1756 - static struct snd_kcontrol_new snd_ice1712_spdif_stream = 1757 { 1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE), ··· 1878 return change; 1879 } 1880 1881 - static struct snd_kcontrol_new snd_ice1712_pro_internal_clock = { 1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1883 .name = "Multi Track Internal Clock", 1884 .info = snd_ice1712_pro_internal_clock_info, ··· 1943 return change; 1944 } 1945 1946 - static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = { 1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1948 .name = "Multi Track Internal Clock Default", 1949 .info = snd_ice1712_pro_internal_clock_default_info, ··· 1974 return change; 1975 } 1976 1977 - static struct snd_kcontrol_new snd_ice1712_pro_rate_locking = { 1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1979 .name = "Multi Track Rate Locking", 1980 .info = snd_ice1712_pro_rate_locking_info, ··· 2005 return change; 2006 } 2007 2008 - static struct snd_kcontrol_new snd_ice1712_pro_rate_reset = { 2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2010 .name = "Multi Track Rate Reset", 2011 .info = snd_ice1712_pro_rate_reset_info, ··· 2173 .put = snd_ice1712_pro_route_analog_put, 2174 }; 2175 2176 - static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = { 2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2179 .info = snd_ice1712_pro_route_info, ··· 2215 return change; 2216 } 2217 2218 - static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = { 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2220 .name = "Multi Track Volume Rate", 2221 .info = snd_ice1712_pro_volume_rate_info, ··· 2248 return 0; 2249 } 2250 2251 - static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = { 2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2253 .name = "Multi Track Peak", 2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
··· 279 return val != nval; 280 } 281 282 + static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 = { 283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 284 .name = "Digital Mixer To AC97", 285 .info = snd_ice1712_digmix_route_ac97_info, ··· 1410 .private_value = 10, 1411 }; 1412 1413 + static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch = { 1414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1415 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), 1416 .info = snd_ice1712_pro_mixer_switch_info, ··· 1432 .tlv = { .p = db_scale_playback } 1433 }; 1434 1435 + static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume = { 1436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1437 .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), 1438 .info = snd_ice1712_pro_mixer_volume_info, ··· 1630 return 0; 1631 } 1632 1633 + static const struct snd_kcontrol_new snd_ice1712_eeprom = { 1634 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1635 .name = "ICE1712 EEPROM", 1636 .access = SNDRV_CTL_ELEM_ACCESS_READ, ··· 1666 return 0; 1667 } 1668 1669 + static const struct snd_kcontrol_new snd_ice1712_spdif_default = 1670 { 1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1672 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), ··· 1717 return 0; 1718 } 1719 1720 + static const struct snd_kcontrol_new snd_ice1712_spdif_maskc = 1721 { 1722 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1723 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1726 .get = snd_ice1712_spdif_maskc_get, 1727 }; 1728 1729 + static const struct snd_kcontrol_new snd_ice1712_spdif_maskp = 1730 { 1731 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1732 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1753 return 0; 1754 } 1755 1756 + static const struct snd_kcontrol_new snd_ice1712_spdif_stream = 1757 { 1758 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1759 SNDRV_CTL_ELEM_ACCESS_INACTIVE), ··· 1878 return change; 1879 } 1880 1881 + static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock = { 1882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1883 .name = "Multi Track Internal Clock", 1884 .info = snd_ice1712_pro_internal_clock_info, ··· 1943 return change; 1944 } 1945 1946 + static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default = { 1947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1948 .name = "Multi Track Internal Clock Default", 1949 .info = snd_ice1712_pro_internal_clock_default_info, ··· 1974 return change; 1975 } 1976 1977 + static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking = { 1978 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1979 .name = "Multi Track Rate Locking", 1980 .info = snd_ice1712_pro_rate_locking_info, ··· 2005 return change; 2006 } 2007 2008 + static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset = { 2009 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2010 .name = "Multi Track Rate Reset", 2011 .info = snd_ice1712_pro_rate_reset_info, ··· 2173 .put = snd_ice1712_pro_route_analog_put, 2174 }; 2175 2176 + static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route = { 2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2178 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2179 .info = snd_ice1712_pro_route_info, ··· 2215 return change; 2216 } 2217 2218 + static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate = { 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2220 .name = "Multi Track Volume Rate", 2221 .info = snd_ice1712_pro_volume_rate_info, ··· 2248 return 0; 2249 } 2250 2251 + static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak = { 2252 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2253 .name = "Multi Track Peak", 2254 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+10 -10
sound/pci/ice1712/ice1724.c
··· 1598 return 0; 1599 } 1600 1601 - static struct snd_kcontrol_new snd_vt1724_eeprom = { 1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1603 .name = "ICE1724 EEPROM", 1604 .access = SNDRV_CTL_ELEM_ACCESS_READ, ··· 1711 return val != old; 1712 } 1713 1714 - static struct snd_kcontrol_new snd_vt1724_spdif_default = 1715 { 1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), ··· 1743 return 0; 1744 } 1745 1746 - static struct snd_kcontrol_new snd_vt1724_spdif_maskc = 1747 { 1748 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1752 .get = snd_vt1724_spdif_maskc_get, 1753 }; 1754 1755 - static struct snd_kcontrol_new snd_vt1724_spdif_maskp = 1756 { 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1789 return old != val; 1790 } 1791 1792 - static struct snd_kcontrol_new snd_vt1724_spdif_switch = 1793 { 1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1795 /* FIXME: the following conflict with IEC958 Playback Route */ ··· 1964 return old_rate != new_rate; 1965 } 1966 1967 - static struct snd_kcontrol_new snd_vt1724_pro_internal_clock = { 1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1969 .name = "Multi Track Internal Clock", 1970 .info = snd_vt1724_pro_internal_clock_info, ··· 1995 return change; 1996 } 1997 1998 - static struct snd_kcontrol_new snd_vt1724_pro_rate_locking = { 1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2000 .name = "Multi Track Rate Locking", 2001 .info = snd_vt1724_pro_rate_locking_info, ··· 2026 return change; 2027 } 2028 2029 - static struct snd_kcontrol_new snd_vt1724_pro_rate_reset = { 2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2031 .name = "Multi Track Rate Reset", 2032 .info = snd_vt1724_pro_rate_reset_info, ··· 2151 .put = snd_vt1724_pro_route_analog_put, 2152 }; 2153 2154 - static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = { 2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2157 .info = snd_vt1724_pro_route_info, ··· 2187 return 0; 2188 } 2189 2190 - static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = { 2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2192 .name = "Multi Track Peak", 2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
··· 1598 return 0; 1599 } 1600 1601 + static const struct snd_kcontrol_new snd_vt1724_eeprom = { 1602 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1603 .name = "ICE1724 EEPROM", 1604 .access = SNDRV_CTL_ELEM_ACCESS_READ, ··· 1711 return val != old; 1712 } 1713 1714 + static const struct snd_kcontrol_new snd_vt1724_spdif_default = 1715 { 1716 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1717 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), ··· 1743 return 0; 1744 } 1745 1746 + static const struct snd_kcontrol_new snd_vt1724_spdif_maskc = 1747 { 1748 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1749 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1752 .get = snd_vt1724_spdif_maskc_get, 1753 }; 1754 1755 + static const struct snd_kcontrol_new snd_vt1724_spdif_maskp = 1756 { 1757 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1758 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1789 return old != val; 1790 } 1791 1792 + static const struct snd_kcontrol_new snd_vt1724_spdif_switch = 1793 { 1794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1795 /* FIXME: the following conflict with IEC958 Playback Route */ ··· 1964 return old_rate != new_rate; 1965 } 1966 1967 + static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock = { 1968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1969 .name = "Multi Track Internal Clock", 1970 .info = snd_vt1724_pro_internal_clock_info, ··· 1995 return change; 1996 } 1997 1998 + static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking = { 1999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2000 .name = "Multi Track Rate Locking", 2001 .info = snd_vt1724_pro_rate_locking_info, ··· 2026 return change; 2027 } 2028 2029 + static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset = { 2030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2031 .name = "Multi Track Rate Reset", 2032 .info = snd_vt1724_pro_rate_reset_info, ··· 2151 .put = snd_vt1724_pro_route_analog_put, 2152 }; 2153 2154 + static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route = { 2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2156 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", 2157 .info = snd_vt1724_pro_route_info, ··· 2187 return 0; 2188 } 2189 2190 + static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak = { 2191 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2192 .name = "Multi Track Peak", 2193 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+1 -1
sound/pci/lola/lola_mixer.c
··· 645 return lola_set_src_config(chip, mask, true); 646 } 647 648 - static struct snd_kcontrol_new lola_input_src_mixer = { 649 .name = "Digital SRC Capture Switch", 650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 651 .info = lola_input_src_info,
··· 645 return lola_set_src_config(chip, mask, true); 646 } 647 648 + static const struct snd_kcontrol_new lola_input_src_mixer = { 649 .name = "Digital SRC Capture Switch", 650 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 651 .info = lola_input_src_info,
+1 -1
sound/pci/lx6464es/lx6464es.c
··· 899 return changed; 900 } 901 902 - static struct snd_kcontrol_new lx_control_playback_switch = { 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 904 .name = "PCM Playback Switch", 905 .index = 0,
··· 899 return changed; 900 } 901 902 + static const struct snd_kcontrol_new lx_control_playback_switch = { 903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 904 .name = "PCM Playback Switch", 905 .index = 0,
+3 -3
sound/pci/mixart/mixart_mixer.c
··· 448 return changed; 449 } 450 451 - static struct snd_kcontrol_new mixart_control_output_switch = { 452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 453 .name = "Master Playback Switch", 454 .info = mixart_sw_info, /* shared */ ··· 1024 return changed; 1025 } 1026 1027 - static struct snd_kcontrol_new mixart_control_monitor_vol = { 1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 1091 return (changed != 0); 1092 } 1093 1094 - static struct snd_kcontrol_new mixart_control_monitor_sw = { 1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1096 .name = "Monitoring Switch", 1097 .info = mixart_sw_info, /* shared */
··· 448 return changed; 449 } 450 451 + static const struct snd_kcontrol_new mixart_control_output_switch = { 452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 453 .name = "Master Playback Switch", 454 .info = mixart_sw_info, /* shared */ ··· 1024 return changed; 1025 } 1026 1027 + static const struct snd_kcontrol_new mixart_control_monitor_vol = { 1028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1029 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1030 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 1091 return (changed != 0); 1092 } 1093 1094 + static const struct snd_kcontrol_new mixart_control_monitor_sw = { 1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1096 .name = "Monitoring Switch", 1097 .info = mixart_sw_info, /* shared */
+2 -4
sound/pci/oxygen/oxygen.c
··· 767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia", 768 [MODEL_SERENADE] = "TempoTec HiFier Serenade", 769 [MODEL_HG2PCI] = "CMI8787-HG2PCI", 770 }; 771 772 chip->model = model_generic; ··· 831 chip->model.dac_channels_mixer = 2; 832 break; 833 case MODEL_XONAR_DG: 834 - chip->model = model_xonar_dg; 835 - chip->model.shortname = "Xonar DG"; 836 - break; 837 case MODEL_XONAR_DGX: 838 chip->model = model_xonar_dg; 839 - chip->model.shortname = "Xonar DGX"; 840 break; 841 } 842 if (id->driver_data == MODEL_MERIDIAN ||
··· 767 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia", 768 [MODEL_SERENADE] = "TempoTec HiFier Serenade", 769 [MODEL_HG2PCI] = "CMI8787-HG2PCI", 770 + [MODEL_XONAR_DG] = "Xonar DG", 771 + [MODEL_XONAR_DGX] = "Xonar DGX", 772 }; 773 774 chip->model = model_generic; ··· 829 chip->model.dac_channels_mixer = 2; 830 break; 831 case MODEL_XONAR_DG: 832 case MODEL_XONAR_DGX: 833 chip->model = model_xonar_dg; 834 break; 835 } 836 if (id->driver_data == MODEL_MERIDIAN ||
+3 -3
sound/pci/pcxhr/pcxhr_mix22.c
··· 744 return changed; 745 } 746 747 - static struct snd_kcontrol_new hr222_control_mic_level = { 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 750 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 794 return changed; 795 } 796 797 - static struct snd_kcontrol_new hr222_control_mic_boost = { 798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 800 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 836 return changed; 837 } 838 839 - static struct snd_kcontrol_new hr222_phantom_power_switch = { 840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 841 .name = "Phantom Power Switch", 842 .info = hr222_phantom_power_info,
··· 744 return changed; 745 } 746 747 + static const struct snd_kcontrol_new hr222_control_mic_level = { 748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 749 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 750 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 794 return changed; 795 } 796 797 + static const struct snd_kcontrol_new hr222_control_mic_boost = { 798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 799 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 800 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 836 return changed; 837 } 838 839 + static const struct snd_kcontrol_new hr222_phantom_power_switch = { 840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 841 .name = "Phantom Power Switch", 842 .info = hr222_phantom_power_info,
+11 -11
sound/pci/pcxhr/pcxhr_mixer.c
··· 235 return changed; 236 } 237 238 - static struct snd_kcontrol_new pcxhr_control_output_switch = { 239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 240 .name = "Master Playback Switch", 241 .info = pcxhr_sw_info, /* shared */ ··· 460 return changed; 461 } 462 463 - static struct snd_kcontrol_new pcxhr_control_pcm_switch = { 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 465 .name = "PCM Playback Switch", 466 .count = PCXHR_PLAYBACK_STREAMS, ··· 509 return changed; 510 } 511 512 - static struct snd_kcontrol_new pcxhr_control_monitor_vol = { 513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 515 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 562 return (changed != 0); 563 } 564 565 - static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 567 .name = "Monitoring Playback Switch", 568 .info = pcxhr_sw_info, /* shared */ ··· 697 return ret; 698 } 699 700 - static struct snd_kcontrol_new pcxhr_control_audio_src = { 701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 702 .name = "Capture Source", 703 .info = pcxhr_audio_src_info, ··· 798 return ret; 799 } 800 801 - static struct snd_kcontrol_new pcxhr_control_clock_type = { 802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 803 .name = "Clock Mode", 804 .info = pcxhr_clock_type_info, ··· 842 return 0; 843 } 844 845 - static struct snd_kcontrol_new pcxhr_control_clock_rate = { 846 .access = SNDRV_CTL_ELEM_ACCESS_READ, 847 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 848 .name = "Clock Rates", ··· 1017 return changed; 1018 } 1019 1020 - static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = { 1021 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 1024 .info = pcxhr_iec958_info, 1025 .get = pcxhr_iec958_mask_get 1026 }; 1027 - static struct snd_kcontrol_new pcxhr_control_playback_iec958 = { 1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1030 .info = pcxhr_iec958_info, ··· 1033 .private_value = 0 /* playback */ 1034 }; 1035 1036 - static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = { 1037 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 1040 .info = pcxhr_iec958_info, 1041 .get = pcxhr_iec958_mask_get 1042 }; 1043 - static struct snd_kcontrol_new pcxhr_control_capture_iec958 = { 1044 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
··· 235 return changed; 236 } 237 238 + static const struct snd_kcontrol_new pcxhr_control_output_switch = { 239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 240 .name = "Master Playback Switch", 241 .info = pcxhr_sw_info, /* shared */ ··· 460 return changed; 461 } 462 463 + static const struct snd_kcontrol_new pcxhr_control_pcm_switch = { 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 465 .name = "PCM Playback Switch", 466 .count = PCXHR_PLAYBACK_STREAMS, ··· 509 return changed; 510 } 511 512 + static const struct snd_kcontrol_new pcxhr_control_monitor_vol = { 513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 514 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 515 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 562 return (changed != 0); 563 } 564 565 + static const struct snd_kcontrol_new pcxhr_control_monitor_sw = { 566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 567 .name = "Monitoring Playback Switch", 568 .info = pcxhr_sw_info, /* shared */ ··· 697 return ret; 698 } 699 700 + static const struct snd_kcontrol_new pcxhr_control_audio_src = { 701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 702 .name = "Capture Source", 703 .info = pcxhr_audio_src_info, ··· 798 return ret; 799 } 800 801 + static const struct snd_kcontrol_new pcxhr_control_clock_type = { 802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 803 .name = "Clock Mode", 804 .info = pcxhr_clock_type_info, ··· 842 return 0; 843 } 844 845 + static const struct snd_kcontrol_new pcxhr_control_clock_rate = { 846 .access = SNDRV_CTL_ELEM_ACCESS_READ, 847 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 848 .name = "Clock Rates", ··· 1017 return changed; 1018 } 1019 1020 + static const struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = { 1021 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1022 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1023 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK), 1024 .info = pcxhr_iec958_info, 1025 .get = pcxhr_iec958_mask_get 1026 }; 1027 + static const struct snd_kcontrol_new pcxhr_control_playback_iec958 = { 1028 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1029 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1030 .info = pcxhr_iec958_info, ··· 1033 .private_value = 0 /* playback */ 1034 }; 1035 1036 + static const struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = { 1037 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1038 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1039 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), 1040 .info = pcxhr_iec958_info, 1041 .get = pcxhr_iec958_mask_get 1042 }; 1043 + static const struct snd_kcontrol_new pcxhr_control_capture_iec958 = { 1044 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1045 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1046 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
+11 -11
sound/pci/trident/trident_main.c
··· 2356 return change; 2357 } 2358 2359 - static struct snd_kcontrol_new snd_trident_spdif_control = 2360 { 2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), ··· 2419 return change; 2420 } 2421 2422 - static struct snd_kcontrol_new snd_trident_spdif_default = 2423 { 2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 2452 return 0; 2453 } 2454 2455 - static struct snd_kcontrol_new snd_trident_spdif_mask = 2456 { 2457 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 2514 return change; 2515 } 2516 2517 - static struct snd_kcontrol_new snd_trident_spdif_stream = 2518 { 2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 2564 return change; 2565 } 2566 2567 - static struct snd_kcontrol_new snd_trident_ac97_rear_control = 2568 { 2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2570 .name = "Rear Path", ··· 2622 return change; 2623 } 2624 2625 - static struct snd_kcontrol_new snd_trident_vol_music_control = 2626 { 2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2628 .name = "Music Playback Volume", ··· 2633 .tlv = { .p = db_scale_gvol }, 2634 }; 2635 2636 - static struct snd_kcontrol_new snd_trident_vol_wave_control = 2637 { 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2639 .name = "Wave Playback Volume", ··· 2700 return change; 2701 } 2702 2703 - static struct snd_kcontrol_new snd_trident_pcm_vol_control = 2704 { 2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2706 .name = "PCM Front Playback Volume", ··· 2764 return change; 2765 } 2766 2767 - static struct snd_kcontrol_new snd_trident_pcm_pan_control = 2768 { 2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2770 .name = "PCM Pan Playback Control", ··· 2821 2822 static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); 2823 2824 - static struct snd_kcontrol_new snd_trident_pcm_rvol_control = 2825 { 2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2827 .name = "PCM Reverb Playback Volume", ··· 2877 return change; 2878 } 2879 2880 - static struct snd_kcontrol_new snd_trident_pcm_cvol_control = 2881 { 2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2883 .name = "PCM Chorus Playback Volume",
··· 2356 return change; 2357 } 2358 2359 + static const struct snd_kcontrol_new snd_trident_spdif_control = 2360 { 2361 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2362 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), ··· 2419 return change; 2420 } 2421 2422 + static const struct snd_kcontrol_new snd_trident_spdif_default = 2423 { 2424 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 2425 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 2452 return 0; 2453 } 2454 2455 + static const struct snd_kcontrol_new snd_trident_spdif_mask = 2456 { 2457 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2458 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 2514 return change; 2515 } 2516 2517 + static const struct snd_kcontrol_new snd_trident_spdif_stream = 2518 { 2519 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 2520 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 2564 return change; 2565 } 2566 2567 + static const struct snd_kcontrol_new snd_trident_ac97_rear_control = 2568 { 2569 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2570 .name = "Rear Path", ··· 2622 return change; 2623 } 2624 2625 + static const struct snd_kcontrol_new snd_trident_vol_music_control = 2626 { 2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2628 .name = "Music Playback Volume", ··· 2633 .tlv = { .p = db_scale_gvol }, 2634 }; 2635 2636 + static const struct snd_kcontrol_new snd_trident_vol_wave_control = 2637 { 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2639 .name = "Wave Playback Volume", ··· 2700 return change; 2701 } 2702 2703 + static const struct snd_kcontrol_new snd_trident_pcm_vol_control = 2704 { 2705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2706 .name = "PCM Front Playback Volume", ··· 2764 return change; 2765 } 2766 2767 + static const struct snd_kcontrol_new snd_trident_pcm_pan_control = 2768 { 2769 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2770 .name = "PCM Pan Playback Control", ··· 2821 2822 static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); 2823 2824 + static const struct snd_kcontrol_new snd_trident_pcm_rvol_control = 2825 { 2826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2827 .name = "PCM Reverb Playback Volume", ··· 2877 return change; 2878 } 2879 2880 + static const struct snd_kcontrol_new snd_trident_pcm_cvol_control = 2881 { 2882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2883 .name = "PCM Chorus Playback Volume",
+3 -3
sound/pci/via82xx.c
··· 1683 return 0; 1684 } 1685 1686 - static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = { 1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1689 .info = snd_via8233_dxs3_spdif_info, ··· 1772 1773 static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1); 1774 1775 - static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = { 1776 .name = "PCM Playback Volume", 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | ··· 1783 .tlv = { .p = db_scale_dxs } 1784 }; 1785 1786 - static struct snd_kcontrol_new snd_via8233_dxs_volume_control = { 1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1788 .device = 0, 1789 /* .subdevice set later */
··· 1683 return 0; 1684 } 1685 1686 + static const struct snd_kcontrol_new snd_via8233_dxs3_spdif_control = { 1687 .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 1688 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1689 .info = snd_via8233_dxs3_spdif_info, ··· 1772 1773 static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -4650, 150, 1); 1774 1775 + static const struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control = { 1776 .name = "PCM Playback Volume", 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1778 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | ··· 1783 .tlv = { .p = db_scale_dxs } 1784 }; 1785 1786 + static const struct snd_kcontrol_new snd_via8233_dxs_volume_control = { 1787 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1788 .device = 0, 1789 /* .subdevice set later */
+2 -2
sound/pci/vx222/vx222_ops.c
··· 945 return 0; 946 } 947 948 - static struct snd_kcontrol_new vx_control_input_level = { 949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 951 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 956 .tlv = { .p = db_scale_mic }, 957 }; 958 959 - static struct snd_kcontrol_new vx_control_mic_level = { 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 962 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
··· 945 return 0; 946 } 947 948 + static const struct snd_kcontrol_new vx_control_input_level = { 949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 950 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 951 SNDRV_CTL_ELEM_ACCESS_TLV_READ), ··· 956 .tlv = { .p = db_scale_mic }, 957 }; 958 959 + static const struct snd_kcontrol_new vx_control_mic_level = { 960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 961 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 962 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
+7 -7
sound/pci/ymfpci/ymfpci_main.c
··· 1316 return change; 1317 } 1318 1319 - static struct snd_kcontrol_new snd_ymfpci_spdif_default = 1320 { 1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1344 return 0; 1345 } 1346 1347 - static struct snd_kcontrol_new snd_ymfpci_spdif_mask = 1348 { 1349 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1391 return change; 1392 } 1393 1394 - static struct snd_kcontrol_new snd_ymfpci_spdif_stream = 1395 { 1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1439 return reg != old_reg; 1440 } 1441 1442 - static struct snd_kcontrol_new snd_ymfpci_drec_source = { 1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1445 .name = "Direct Recording Source", ··· 1609 return change; 1610 } 1611 1612 - static struct snd_kcontrol_new snd_ymfpci_dup4ch = { 1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1614 .name = "4ch Duplication", 1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ··· 1712 return 0; 1713 } 1714 1715 - static struct snd_kcontrol_new snd_ymfpci_rear_shared = { 1716 .name = "Shared Rear/Line-In Switch", 1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1718 .info = snd_ymfpci_gpio_sw_info, ··· 1776 return 0; 1777 } 1778 1779 - static struct snd_kcontrol_new snd_ymfpci_pcm_volume = { 1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1781 .name = "PCM Playback Volume", 1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
··· 1316 return change; 1317 } 1318 1319 + static const struct snd_kcontrol_new snd_ymfpci_spdif_default = 1320 { 1321 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1322 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), ··· 1344 return 0; 1345 } 1346 1347 + static const struct snd_kcontrol_new snd_ymfpci_spdif_mask = 1348 { 1349 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1350 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1391 return change; 1392 } 1393 1394 + static const struct snd_kcontrol_new snd_ymfpci_spdif_stream = 1395 { 1396 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE, 1397 .iface = SNDRV_CTL_ELEM_IFACE_PCM, ··· 1439 return reg != old_reg; 1440 } 1441 1442 + static const struct snd_kcontrol_new snd_ymfpci_drec_source = { 1443 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 1444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1445 .name = "Direct Recording Source", ··· 1609 return change; 1610 } 1611 1612 + static const struct snd_kcontrol_new snd_ymfpci_dup4ch = { 1613 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1614 .name = "4ch Duplication", 1615 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, ··· 1712 return 0; 1713 } 1714 1715 + static const struct snd_kcontrol_new snd_ymfpci_rear_shared = { 1716 .name = "Shared Rear/Line-In Switch", 1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1718 .info = snd_ymfpci_gpio_sw_info, ··· 1776 return 0; 1777 } 1778 1779 + static const struct snd_kcontrol_new snd_ymfpci_pcm_volume = { 1780 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1781 .name = "PCM Playback Volume", 1782 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
-21
sound/soc/intel/skylake/skl.h
··· 27 28 #define SKL_SUSPEND_DELAY 2000 29 30 - /* Vendor Specific Registers */ 31 - #define AZX_REG_VS_EM1 0x1000 32 - #define AZX_REG_VS_INRC 0x1004 33 - #define AZX_REG_VS_OUTRC 0x1008 34 - #define AZX_REG_VS_FIFOTRK 0x100C 35 - #define AZX_REG_VS_FIFOTRK2 0x1010 36 - #define AZX_REG_VS_EM2 0x1030 37 - #define AZX_REG_VS_EM3L 0x1038 38 - #define AZX_REG_VS_EM3U 0x103C 39 - #define AZX_REG_VS_EM4L 0x1040 40 - #define AZX_REG_VS_EM4U 0x1044 41 - #define AZX_REG_VS_LTRC 0x1048 42 - #define AZX_REG_VS_D0I3C 0x104A 43 - #define AZX_REG_VS_PCE 0x104B 44 - #define AZX_REG_VS_L2MAGC 0x1050 45 - #define AZX_REG_VS_L2LAHPT 0x1054 46 - #define AZX_REG_VS_SDXDPIB_XBASE 0x1084 47 - #define AZX_REG_VS_SDXDPIB_XINTERVAL 0x20 48 - #define AZX_REG_VS_SDXEFIFOS_XBASE 0x1094 49 - #define AZX_REG_VS_SDXEFIFOS_XINTERVAL 0x20 50 - 51 #define AZX_PCIREG_PGCTL 0x44 52 #define AZX_PGCTL_LSRMD_MASK (1 << 4) 53 #define AZX_PCIREG_CGCTL 0x48
··· 27 28 #define SKL_SUSPEND_DELAY 2000 29 30 #define AZX_PCIREG_PGCTL 0x44 31 #define AZX_PGCTL_LSRMD_MASK (1 << 4) 32 #define AZX_PCIREG_CGCTL 0x48
+2 -2
sound/synth/emux/emux_oss.c
··· 225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { 226 struct soundfont_patch_info patch; 227 if (count < (int)sizeof(patch)) 228 - rc = -EINVAL; 229 if (copy_from_user(&patch, buf, sizeof(patch))) 230 - rc = -EFAULT; 231 if (patch.type >= SNDRV_SFNT_LOAD_INFO && 232 patch.type <= SNDRV_SFNT_PROBE_DATA) 233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
··· 225 else if (format == SNDRV_OSS_SOUNDFONT_PATCH) { 226 struct soundfont_patch_info patch; 227 if (count < (int)sizeof(patch)) 228 + return -EINVAL; 229 if (copy_from_user(&patch, buf, sizeof(patch))) 230 + return -EFAULT; 231 if (patch.type >= SNDRV_SFNT_LOAD_INFO && 232 patch.type <= SNDRV_SFNT_PROBE_DATA) 233 rc = snd_soundfont_load(emu->sflist, buf, count, SF_CLIENT_NO(p->chset.port));
+3 -3
sound/usb/card.c
··· 332 static int snd_usb_audio_create(struct usb_interface *intf, 333 struct usb_device *dev, int idx, 334 const struct snd_usb_audio_quirk *quirk, 335 struct snd_usb_audio **rchip) 336 { 337 struct snd_card *card; ··· 382 atomic_set(&chip->usage_count, 0); 383 atomic_set(&chip->shutdown, 0); 384 385 - chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), 386 - le16_to_cpu(dev->descriptor.idProduct)); 387 INIT_LIST_HEAD(&chip->pcm_list); 388 INIT_LIST_HEAD(&chip->ep_list); 389 INIT_LIST_HEAD(&chip->midi_list); ··· 569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && 570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { 571 err = snd_usb_audio_create(intf, dev, i, quirk, 572 - &chip); 573 if (err < 0) 574 goto __error; 575 chip->pm_intf = intf;
··· 332 static int snd_usb_audio_create(struct usb_interface *intf, 333 struct usb_device *dev, int idx, 334 const struct snd_usb_audio_quirk *quirk, 335 + unsigned int usb_id, 336 struct snd_usb_audio **rchip) 337 { 338 struct snd_card *card; ··· 381 atomic_set(&chip->usage_count, 0); 382 atomic_set(&chip->shutdown, 0); 383 384 + chip->usb_id = usb_id; 385 INIT_LIST_HEAD(&chip->pcm_list); 386 INIT_LIST_HEAD(&chip->ep_list); 387 INIT_LIST_HEAD(&chip->midi_list); ··· 569 (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && 570 (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { 571 err = snd_usb_audio_create(intf, dev, i, quirk, 572 + id, &chip); 573 if (err < 0) 574 goto __error; 575 chip->pm_intf = intf;
+1 -1
sound/usb/line6/pcm.c
··· 430 } 431 432 /* control definition */ 433 - static struct snd_kcontrol_new line6_controls[] = { 434 { 435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 436 .name = "PCM Playback Volume",
··· 430 } 431 432 /* control definition */ 433 + static const struct snd_kcontrol_new line6_controls[] = { 434 { 435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 436 .name = "PCM Playback Volume",
+1 -1
sound/usb/line6/pod.c
··· 380 } 381 382 /* control definition */ 383 - static struct snd_kcontrol_new pod_control_monitor = { 384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 385 .name = "Monitor Playback Volume", 386 .index = 0,
··· 380 } 381 382 /* control definition */ 383 + static const struct snd_kcontrol_new pod_control_monitor = { 384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 385 .name = "Monitor Playback Volume", 386 .index = 0,
+2 -2
sound/usb/line6/toneport.c
··· 250 } 251 252 /* control definition */ 253 - static struct snd_kcontrol_new toneport_control_monitor = { 254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 255 .name = "Monitor Playback Volume", 256 .index = 0, ··· 261 }; 262 263 /* source selector definition */ 264 - static struct snd_kcontrol_new toneport_control_source = { 265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 266 .name = "PCM Capture Source", 267 .index = 0,
··· 250 } 251 252 /* control definition */ 253 + static const struct snd_kcontrol_new toneport_control_monitor = { 254 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 255 .name = "Monitor Playback Volume", 256 .index = 0, ··· 261 }; 262 263 /* source selector definition */ 264 + static const struct snd_kcontrol_new toneport_control_source = { 265 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 266 .name = "PCM Capture Source", 267 .index = 0,
+1 -1
sound/usb/midi.c
··· 1922 return changed; 1923 } 1924 1925 - static struct snd_kcontrol_new roland_load_ctl = { 1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1927 .name = "MIDI Input Mode", 1928 .info = roland_load_info,
··· 1922 return changed; 1923 } 1924 1925 + static const struct snd_kcontrol_new roland_load_ctl = { 1926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1927 .name = "MIDI Input Mode", 1928 .info = roland_load_info,
+3 -3
sound/usb/mixer.c
··· 1172 }; 1173 1174 /* 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 } 1746 1747 /* 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 } 2034 2035 /* 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 }; 1173 1174 /* 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 } 1746 1747 /* 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 } 2034 2035 /* 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,
+6 -6
sound/usb/mixer_scarlett.c
··· 477 return 0; 478 } 479 480 - static struct snd_kcontrol_new usb_scarlett_ctl_switch = { 481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 482 .name = "", 483 .info = scarlett_ctl_switch_info, ··· 487 488 static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0); 489 490 - static struct snd_kcontrol_new usb_scarlett_ctl = { 491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 493 SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 499 .tlv = { .p = db_scale_scarlett_gain } 500 }; 501 502 - static struct snd_kcontrol_new usb_scarlett_ctl_master = { 503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 505 SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 511 .tlv = { .p = db_scale_scarlett_gain } 512 }; 513 514 - static struct snd_kcontrol_new usb_scarlett_ctl_enum = { 515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 516 .name = "", 517 .info = scarlett_ctl_enum_info, ··· 519 .put = scarlett_ctl_enum_put, 520 }; 521 522 - static struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = { 523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 524 .name = "", 525 .info = scarlett_ctl_enum_dynamic_info, ··· 527 .put = scarlett_ctl_enum_put, 528 }; 529 530 - static struct snd_kcontrol_new usb_scarlett_ctl_sync = { 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 533 .name = "",
··· 477 return 0; 478 } 479 480 + static const struct snd_kcontrol_new usb_scarlett_ctl_switch = { 481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 482 .name = "", 483 .info = scarlett_ctl_switch_info, ··· 487 488 static const DECLARE_TLV_DB_SCALE(db_scale_scarlett_gain, -12800, 100, 0); 489 490 + static const struct snd_kcontrol_new usb_scarlett_ctl = { 491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 492 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 493 SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 499 .tlv = { .p = db_scale_scarlett_gain } 500 }; 501 502 + static const struct snd_kcontrol_new usb_scarlett_ctl_master = { 503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 504 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 505 SNDRV_CTL_ELEM_ACCESS_TLV_READ, ··· 511 .tlv = { .p = db_scale_scarlett_gain } 512 }; 513 514 + static const struct snd_kcontrol_new usb_scarlett_ctl_enum = { 515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 516 .name = "", 517 .info = scarlett_ctl_enum_info, ··· 519 .put = scarlett_ctl_enum_put, 520 }; 521 522 + static const struct snd_kcontrol_new usb_scarlett_ctl_dynamic_enum = { 523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 524 .name = "", 525 .info = scarlett_ctl_enum_dynamic_info, ··· 527 .put = scarlett_ctl_enum_put, 528 }; 529 530 + static const struct snd_kcontrol_new usb_scarlett_ctl_sync = { 531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 532 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 533 .name = "",
+1 -1
sound/usb/usx2y/us122l.c
··· 472 hw->ops.mmap = usb_stream_hwdep_mmap; 473 hw->ops.poll = usb_stream_hwdep_poll; 474 475 - sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", 476 dev->bus->busnum, dev->devnum); 477 return 0; 478 }
··· 472 hw->ops.mmap = usb_stream_hwdep_mmap; 473 hw->ops.poll = usb_stream_hwdep_poll; 474 475 + sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", 476 dev->bus->busnum, dev->devnum); 477 return 0; 478 }
+1 -1
sound/usb/usx2y/usX2Yhwdep.c
··· 258 hw->ops.mmap = snd_us428ctls_mmap; 259 hw->ops.poll = snd_us428ctls_poll; 260 hw->exclusive = 1; 261 - sprintf(hw->name, "/proc/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); 262 return 0; 263 } 264
··· 258 hw->ops.mmap = snd_us428ctls_mmap; 259 hw->ops.poll = snd_us428ctls_poll; 260 hw->exclusive = 1; 261 + sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum); 262 return 0; 263 } 264
+1 -1
sound/usb/usx2y/usx2yhwdeppcm.c
··· 723 hw->ops.release = snd_usX2Y_hwdep_pcm_release; 724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap; 725 hw->exclusive = 1; 726 - sprintf(hw->name, "/proc/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum); 727 728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm); 729 if (err < 0) {
··· 723 hw->ops.release = snd_usX2Y_hwdep_pcm_release; 724 hw->ops.mmap = snd_usX2Y_hwdep_pcm_mmap; 725 hw->exclusive = 1; 726 + sprintf(hw->name, "/dev/bus/usb/%03d/%03d/hwdeppcm", dev->bus->busnum, dev->devnum); 727 728 err = snd_pcm_new(card, NAME_ALLCAPS" hwdep Audio", 2, 1, 1, &pcm); 729 if (err < 0) {